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

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