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

Last change on this file since 682 was 555, checked in by Sam Hocevar, 9 years ago

ps3: make everything compile on the PS3. Of course, nothing links yet
because so much support is missing.

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