source: abuse/trunk/src/old.nfclient.cpp @ 489

Last change on this file since 489 was 481, checked in by Sam Hocevar, 10 years ago

Fuck the history, I'm renaming all .hpp files to .h for my own sanity.

File size: 7.1 KB
Line 
1/*
2 *  Abuse - dark 2D side-scrolling platform game
3 *  Copyright (c) 1995 Crack dot Com
4 *
5 *  This software was released into the Public Domain. As with most public
6 *  domain software, no warranty is made or implied by Crack dot Com or
7 *  Jonathan Clark.
8 */
9
10#include "config.h"
11
12#include <sys/types.h>
13#include <fcntl.h>
14#include <unistd.h>
15
16#include "specs.h"
17#include "nfserver.h"
18#include "dprint.h"
19#include "crc.h"
20#include "cache.h"
21
22class nfs_file : public bFILE
23{
24  jFILE *local;
25  int nfs_fd;
26  int offset;
27  public :
28  nfs_file(char *filename, char *mode);
29  virtual int open_failure();
30  virtual int unbuffered_read(void *buf, size_t count);       // returns number of bytes read
31  int new_read(void *buf, size_t count);       // returns number of bytes read
32  virtual int unbuffered_write(void *buf, size_t count);      // returns number of bytes written
33  virtual int unbuffered_seek(int32_t offset, int whence);  // whence=SEEK_SET, SEEK_CUR, SEEK_END, ret=0=success
34  virtual int unbuffered_tell();
35  virtual int file_size();
36  virtual ~nfs_file();
37} ;
38
39bFILE *open_nfs_file(char *filename,char *mode)
40{
41  return new nfs_file(filename,mode);
42}
43
44
45static out_socket *nfs_server=NULL;
46void connect_to_nfs_server(char *name, int port)
47{
48  nfs_server=create_out_socket(name,port);
49  if (!nfs_server)
50  {
51    fprintf(stderr,"%s\n",last_sock_err);
52    exit(0);
53  } else
54  {
55    set_file_opener(open_nfs_file);   // from now on all files wll go through NFS creator
56  }
57}
58
59static void nfs_disconnect()
60{
61  if (nfs_server)
62  {
63    delete nfs_server;
64    nfs_server=NULL;
65    set_file_opener(NULL);    // use local means for opening files
66  }
67}
68
69
70nfs_file::nfs_file(char *filename, char *mode)
71{
72  int local_only=0;
73  for (char *s=mode;*s;s++)    // check to see if writeable file, if so don't go through nfs
74    if (*s=='w' || *s=='W' || *s=='a' || *s=='A')
75      local_only=1;
76  if (local_only)
77  {
78    local=new jFILE(filename,mode);
79    nfs_fd=-1;
80  }
81  else
82  {
83    local=NULL;
84    nfs_fd=-1;
85    if (nfs_server)
86    {
87      packet pk;
88      int do_open=0;
89      jFILE *local_test=new jFILE(filename,mode);
90      if (local_test->open_failure())
91      {
92    delete local_test;
93    local_test=NULL;
94    pk.write_uint8(NFS_OPEN);
95      }
96      else
97      {
98    pk.write_uint8(NFS_CRC_OPEN);
99    int fail;
100    uint32_t crc=crc_manager.get_crc(crc_manager.get_filenumber(filename),fail); // skip crc calc if we can
101    if (fail) crc=crc_file(local_test);
102    pk.write_uint32(crc);
103      }
104
105      pk.write_uint8(strlen(filename)+1);
106      pk.write((uint8_t *)filename,strlen(filename)+1);
107      pk.write_uint8(strlen(mode)+1);
108      pk.write((uint8_t *)mode,strlen(mode)+1);
109      dprintf("try open %s,%s\n",filename,mode);
110      offset=0;
111      if (!nfs_server->send(pk))
112        nfs_disconnect();
113      else
114      {
115    if (!nfs_server->get(pk)) nfs_disconnect();
116    else
117    {
118      int32_t fd;
119      if (pk.read((uint8_t *)&fd,4)!=4)
120        nfs_disconnect();
121      else
122      {
123        fd=lltl(fd);
124        nfs_fd=fd;
125        if (local_test && fd==-2) // confirmed that CRCs match, use local file   
126        { local=local_test;    local_test=NULL; }
127
128      }
129    }
130      }
131      if (local_test)
132        delete local_test;
133    }
134  }
135}
136
137
138int nfs_file::open_failure() { return !local && nfs_fd==-1; }
139
140int nfs_file::unbuffered_read(void *buf, size_t count)      // returns number of bytes read
141{
142  if (local)
143    return local->read(buf,count);
144  else
145  {
146    int ret=new_read(buf,count);
147    void *comp=malloc(count);
148/*    ::read(check_fd,comp,count);
149    if (memcmp(comp,buf,count))
150    {
151      printf("bad read!\n");
152    }
153    free(comp);*/
154    return ret;
155  }
156}
157
158int nfs_file::new_read(void *buf, size_t count)      // returns number of bytes read
159{
160  if (local)
161    return local->read(buf,count);
162  else
163  {
164    packet pk;
165    pk.write_uint8(NFS_READ);
166    pk.write_uint32(nfs_fd);
167    pk.write_uint32(count);
168    dprintf("try read %d,%d\n",nfs_fd,count);
169    if (!nfs_server->send(pk))
170    {
171      nfs_disconnect();
172      return 0;
173    }
174    else
175    {
176
177      int fail=0;
178      int rtotal=0;
179      uint16_t size=1;
180      while (count>0 && !fail && size)
181      {
182    if (!nfs_server->get(pk)) fail=1;
183    else
184    {   
185      if (pk.read((uint8_t *)&size,2)!=2) fail=1;
186      else
187      {
188        size=lstl(size);
189        printf("read %d bytes\n",size);
190        if (size)
191        {
192          int need_size=size>count ? count : size;
193
194          if (pk.read((uint8_t *)buf,need_size)!=need_size) fail=1;
195          else
196          {
197        count-=need_size;   
198        rtotal+=need_size;
199        buf=(void *)(((char *)buf)+need_size);
200        offset+=need_size;
201        if (need_size<size)    // see if there are any leftovers to buffer       
202          fprintf(stderr,"Server sent to much\n");       
203          }
204          if (need_size<2048) count=0;
205        }
206      }
207    }
208      }
209      if (fail)
210      {
211    dprintf("nfs read failed\n");
212        nfs_disconnect();
213      }
214      return rtotal;
215    }
216  }
217}
218
219
220int nfs_file::unbuffered_write(void *buf, size_t count)      // returns number of bytes written
221{
222  if (local)
223    return local->write(buf,count);
224  else
225  {
226    fprintf(stderr,"write to nfs file not allowed for now!\n");
227    exit(0);
228  }
229  return 0;
230}
231
232
233int nfs_file::unbuffered_seek(int32_t off, int whence) // whence=SEEK_SET, SEEK_CUR, SEEK_END, ret=0=success
234{
235  if (local)
236    return local->seek(off,whence);
237  else
238  {
239    packet pk;
240    pk.write_uint8(NFS_SEEK);
241    pk.write_uint32(nfs_fd);
242
243    pk.write_uint32(off);
244    pk.write_uint32(whence);
245    dprintf("seek %d %d %d\n",nfs_fd,off,whence);
246    if (!nfs_server->send(pk))
247    {
248      dprintf("disconnected on seek\n");
249      nfs_disconnect();
250      return 0;
251    }
252  }
253  return 0;
254}
255
256int nfs_file::unbuffered_tell()
257{
258  if (local)
259    return local->tell();
260  else if (nfs_server)
261  {
262    packet pk;
263    pk.write_uint8(NFS_TELL);
264    pk.write_uint32(nfs_fd);
265    if (!nfs_server->send(pk))
266    {
267      nfs_disconnect();
268      return 0;
269    } else
270    {
271      if (!nfs_server->get(pk))
272      {
273    nfs_disconnect();
274    return 0;
275      } else
276      {
277    int32_t off;
278    if (pk.read((uint8_t *)&off,4)!=4)
279    {
280      dprintf("Disconnected on tell()\n");
281      nfs_disconnect();
282    } else return lltl(off);
283
284      }
285    }
286  }
287  return 0;
288}
289
290
291int nfs_file::file_size()
292{
293  if (local)
294    return local->file_size();
295  else if (nfs_server)
296  {
297    packet pk;
298    pk.write_uint8(NFS_FILESIZE);
299    pk.write_uint32(nfs_fd);
300    if (!nfs_server->send(pk))
301    {
302      nfs_disconnect();
303      return 0;
304    } else
305    {
306      if (!nfs_server->get(pk))
307      {
308    nfs_disconnect();
309    return 0;
310      } else
311      {
312    int32_t size;
313    if (pk.read((uint8_t *)&size,4)!=4)
314    {
315      dprintf("disconnected on filesize\n");
316      nfs_disconnect();
317    }
318    else return lltl(size);
319      }
320    }
321  }
322  return 0;
323}
324
325nfs_file::~nfs_file()
326{
327  flush_writes();
328  if (local) delete local;
329  else if (nfs_server && !open_failure())
330  {
331    packet pk;
332    pk.write_uint8(NFS_CLOSE);
333    pk.write_uint32(nfs_fd);
334    dprintf("close %d\n",nfs_fd);
335    if (!nfs_server->send(pk))
336    {
337      dprintf("disconnected on close\n");
338      nfs_disconnect();
339    }
340  }
341}
342
343
344
345
Note: See TracBrowser for help on using the repository browser.