source: abuse/branches/lol/src/old.nfclient.cpp @ 732

Last change on this file since 732 was 732, checked in by Sam Hocevar, 8 years ago

build: SDL2 compilation fixes.

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