source: abuse/branches/pd/macabuse/src/old.nfserver.c @ 534

Last change on this file since 534 was 49, checked in by Sam Hocevar, 15 years ago
  • Imported original public domain release, for future reference.
  • Property svn:keywords set to Id
File size: 7.4 KB
Line 
1#include "jnet.hpp"
2#include "specs.hpp"
3#include "nfserver.hpp"
4#include "dprint.hpp"
5#include "timing.hpp"
6#include "cache.hpp"
7#include "crc.hpp"
8
9nfs_server *file_server=NULL;
10
11class nfs_server_client_node
12{
13  public :
14  out_socket *nd;
15  nfs_server_client_node *next;
16  bFILE **file_list;
17  int file_list_size;
18
19
20  nfs_server_client_node(out_socket *descriptor, nfs_server_client_node *Next)
21  { nd=descriptor; next=Next;
22    file_list_size=0;
23    file_list=NULL;
24  }
25  int add_file(bFILE *fp);  // returns id for jFILE
26  bFILE *get_file(int id);
27  int delete_file(int id);  // returns 1=success
28
29  ~nfs_server_client_node();
30
31} ;
32
33nfs_server_client_node::~nfs_server_client_node()
34{
35  delete nd;
36  for (int i=0;i<file_list_size;i++)
37    if (file_list[i])
38     delete file_list[i];
39  if (file_list)
40    jfree(file_list);
41}
42
43int nfs_server_client_node::add_file(bFILE *fp)  // returns id for bFILE
44{
45  for (int i=0;i<file_list_size;i++)   // search for a free spot
46  {
47    if (!file_list[i])
48    {
49      file_list[i]=fp;
50      return i;
51    }
52  }
53  // we need to enlarge the file_list
54  file_list_size++;
55  file_list=(bFILE **)jrealloc(file_list,sizeof(bFILE *)*file_list_size,"client file list");
56  file_list[file_list_size-1]=fp;
57  return file_list_size-1;
58}
59
60bFILE *nfs_server_client_node::get_file(int id)
61{
62  if (id<file_list_size)
63    return file_list[id];
64  else return NULL;
65}
66
67int nfs_server_client_node::delete_file(int id)
68{
69  if (id<file_list_size && file_list[id])
70  {
71    delete file_list[id];
72    file_list[id]=NULL;
73    return 1;
74  }
75  return 0;
76}
77
78char *squash_path(char *path, char *buffer)
79{
80  strcpy(buffer,path);
81  return buffer;
82}
83
84int nfs_server::process_packet(packet &pk, nfs_server_client_node *c)
85{
86  uchar cmd;
87  if (pk.read(&cmd,1)!=1)
88  {
89    dprintf("Could not read command from nfs packet\n");
90    return 0;
91  }
92  dprintf("cmd : %d\n",cmd);
93  switch (cmd)
94  {
95    case NFS_CLOSE_CONNECTION :
96    { return 0; } break;
97    case NFS_CRC_OPEN :
98    {
99      uchar fn_len;
100      char fn[255],newfn[255],perm[255];
101      ulong crc;
102      if (pk.read((uchar *)&crc,4)!=4) return 0; crc=lltl(crc);
103      if (pk.read(&fn_len,1)!=1) return 0;
104      if (pk.read((uchar *)fn,fn_len)!=fn_len) return 0;     
105      if (pk.read((uchar *)&fn_len,1)!=1) return 0;
106      if (pk.read((uchar *)perm,fn_len)!=fn_len) return 0;      // read permission string
107      dprintf("nfs open %s,%s\n",fn,perm);
108      packet opk;
109      int fail;
110      ulong my_crc=crc_man.get_crc(crc_man.get_filenumber(fn),fail);
111      if (fail)
112      {
113        jFILE *fp=new jFILE(squash_path(fn,newfn),perm);
114        if (fp->open_failure())
115        {
116          delete fp;
117          opk.write_long((long)-1);
118          if (!c->nd->send(opk)) return 0;
119          return 1;
120        } else     
121        {
122          my_crc=crc_file(fp);
123          crc_man.set_crc(crc_man.get_filenumber(fn),my_crc);
124          delete fp;
125        }       
126      }
127
128      if (my_crc==crc)
129      {
130        opk.write_long((long)-2);
131        if (!c->nd->send(opk)) return 0;
132        return 1;
133      }
134
135      jFILE *fp=new jFILE(squash_path(fn,newfn),perm);
136      if (fp->open_failure())
137      {
138        delete fp;
139        opk.write_long((long)-1);
140      } else     
141        opk.write_long(c->add_file(fp));     
142      if (!c->nd->send(opk)) return 0;
143      return 1;
144    } break;
145    case NFS_OPEN :
146    {
147      uchar fn_len;
148      char fn[255],newfn[255],perm[255];
149      if (pk.read(&fn_len,1)!=1) return 0;
150      if (pk.read((uchar *)fn,fn_len)!=fn_len) return 0;     
151      if (pk.read((uchar *)&fn_len,1)!=1) return 0;
152      if (pk.read((uchar *)perm,fn_len)!=fn_len) return 0;      // read permission string
153      dprintf("nfs open %s,%s\n",fn,perm);
154      packet opk;
155      jFILE *fp=new jFILE(squash_path(fn,newfn),perm);
156      if (fp->open_failure())
157      {
158        delete fp;
159        opk.write_long((long)-1);
160      } else     
161        opk.write_long(c->add_file(fp));     
162      if (!c->nd->send(opk)) return 0;
163      return 1;
164    } break;
165    case NFS_CLOSE :
166    {
167      long fd;
168      if (pk.read((uchar *)&fd,4)!=4) return 0;  fd=lltl(fd);
169      dprintf("nfs close %d\n",fd);
170      if (!c->delete_file(fd))
171      {
172        dprintf("nfs : bad fd for close\n");
173        return 0;
174      }
175      return 1;
176    } break;
177    case NFS_READ :
178    {
179      long fd,size;
180      if (pk.read((uchar *)&fd,4)!=4) return 0;    fd=lltl(fd);
181      if (pk.read((uchar *)&size,4)!=4) return 0;  size=lltl(size);
182      dprintf("nfs read %d,%d\n",fd,size);
183      bFILE *fp=c->get_file(fd);
184      uchar buf[NFSFILE_BUFFER_SIZE];
185      packet opk;
186      if (!fp) return 0;
187      int total;
188      do
189      {
190        opk.reset();
191        int to_read=NFSFILE_BUFFER_SIZE < size ? NFSFILE_BUFFER_SIZE : size;
192        total=fp->read(buf,to_read);
193        opk.write_short(total);
194        opk.write(buf,total);
195        printf("sending %d bytes\n",total);
196        if (!c->nd->send(opk))
197        {
198          dprintf("failed on write to client\n");
199          return 0;
200        }
201        if (total<to_read) size=0;
202        else size-=total;
203      } while (size>0 && total);               
204      return 1;
205    } break;
206
207    case NFS_WRITE : // not supported
208    { dprintf("got write command..., not good\n");
209      return 0;
210    } break;
211    case NFS_SEEK :
212    {
213      long fd,off,type;
214      if (pk.read((uchar *)&fd,4)!=4) return 0;   fd=lltl(fd);
215      if (pk.read((uchar *)&off,4)!=4) return 0;  off=lltl(off);   
216      if (pk.read((uchar *)&type,4)!=4) return 0; type=lltl(type);
217      dprintf("seek %d %d %d\n",fd,off,type);
218      bFILE *fp=c->get_file(fd);
219      if (!fp) { dprintf("bad fd for seek\n"); return 0; }
220      fp->seek(off,type);
221      return 1;
222    } break;
223    case NFS_FILESIZE :
224    {
225      long fd,off,type;
226      if (pk.read((uchar *)&fd,4)!=4) return 0;   fd=lltl(fd);
227      bFILE *fp=c->get_file(fd);
228      if (!fp) return 0;     
229      packet opk;
230      opk.write_long(fp->file_size());
231      if (!c->nd->send(opk)) return 0;
232      return 1;
233    } break;
234    case NFS_TELL :
235    {
236      long fd,off,type;
237      if (pk.read((uchar *)&fd,4)!=4) return 0;   fd=lltl(fd);
238      bFILE *fp=c->get_file(fd);
239      if (!fp) return 0;     
240      packet opk;
241      opk.write_long(fp->tell());
242      if (!c->nd->send(opk)) return 0;
243      return 1;
244    } break;
245
246  }
247  return 0;   // bad command,  all above return 1 when complete
248}
249
250int nfs_server::service_request()
251{
252  int ret=0;
253  out_socket *c=listen->check_for_connect();   // check for new clients
254  if (c) 
255  {
256    nodes=new nfs_server_client_node(c,nodes);
257    ret=1;
258  }
259
260  nfs_server_client_node *last=NULL;
261  for (nfs_server_client_node *nc=nodes;nc;)    // loop through all clients and check for request
262  {
263    if (nc->nd->ready_to_read())  // request pending?
264    {
265      packet pk;
266      int kill=0;
267      do
268      {
269        int ret;
270        if (!nc->nd->get(pk))
271          kill=1;
272        else if (!process_packet(pk,nc))
273          kill=1;
274      } while (!kill && nc->nd->ready_to_read());
275
276
277      if (kill)
278      {
279        nfs_server_client_node *p=nc;
280        nc=nc->next;
281        if (last)
282          last->next=nc;
283        else
284          nodes=NULL;
285        delete p;
286      } else nc=nc->next;     
287    } else nc=nc->next;
288    last=nc;
289  } 
290  return ret;
291}
292
293nfs_server::nfs_server(int Port)
294{
295  nodes=NULL;
296  port=Port;
297  listen=NULL;
298  int i=0;
299  do
300  {
301    current_sock_err=-1;
302    listen=create_in_socket(port);
303    if (current_sock_err!=-1)
304    {
305      dprintf("Port %d already in use, trying next up\n",port);
306      port++;
307      i++;
308      delete listen;
309    }
310  } while (current_sock_err!=-1 && i<10);
311  if (current_sock_err!=-1)
312  {
313    dprintf("Could not create a listening socket!\n");
314    exit(0);
315  }
316
317}
318
319
320
321nfs_server::~nfs_server()
322{
323  nfs_server_client_node *p;
324  while (nodes)
325  {
326    p=nodes;
327    nodes=nodes->next;
328    delete p;
329  }
330  delete listen;
331}
332
333
334
Note: See TracBrowser for help on using the repository browser.