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

Last change on this file since 123 was 123, checked in by Sam Hocevar, 12 years ago
  • Cleaned up cache.cpp.
  • Renamed stupid "cash" variable into "cache".
  • Rename cache_list and crc_manager into CacheList? and CrcManager?.
File size: 6.9 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.hpp"
17#include "nfserver.hpp"
18#include "dprint.hpp"
19#include "crc.hpp"
20#include "cache.hpp"
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=jmalloc(count,"compare");
148/*    ::read(check_fd,comp,count);
149    if (memcmp(comp,buf,count))
150    {
151      printf("bad read!\n");
152    }
153    jfree(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.