source: abuse/tags/pd/abuse/src/old.nfclient.c @ 49

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