source: abuse/trunk/src/old.nfserver.cpp @ 494

Last change on this file since 494 was 494, checked in by Sam Hocevar, 11 years ago

style: remove trailing spaces, fix copyright statements.

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