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

Last change on this file since 528 was 494, checked in by Sam Hocevar, 11 years ago

style: remove trailing spaces, fix copyright statements.

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