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

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

ps3: make everything compile on the PS3. Of course, nothing links yet
because so much support is missing.

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