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 | #if HAVE_NETWORK |
---|
16 | |
---|
17 | #include <stdio.h> |
---|
18 | #include <stdlib.h> |
---|
19 | #include <fcntl.h> |
---|
20 | #include <unistd.h> |
---|
21 | #include <sys/ioctl.h> |
---|
22 | #include <sys/stat.h> |
---|
23 | #include <sys/types.h> |
---|
24 | #include <sys/time.h> |
---|
25 | #include <string.h> |
---|
26 | #include <signal.h> |
---|
27 | #include <sys/socket.h> |
---|
28 | #include <netinet/in.h> |
---|
29 | #include <sys/types.h> |
---|
30 | #include <sys/ipc.h> |
---|
31 | #include <sys/shm.h> |
---|
32 | #include <bstring.h> |
---|
33 | #include <netdb.h> |
---|
34 | |
---|
35 | #include "fileman.h" |
---|
36 | #include "netdrv.h" |
---|
37 | #include "gserver.h" |
---|
38 | #include "gclient.h" |
---|
39 | #include "undrv.h" |
---|
40 | #include "tcpip.h" |
---|
41 | |
---|
42 | #define real2shm(type,ptr) (ptr==NULL ? NULL : ((type *)((uint8_t *)(ptr)-(uint8_t *)base))) |
---|
43 | #define shm2real(type,ptr) (ptr==NULL ? NULL : ((type *)((intptr_t)(ptr)+(intptr_t)(base)))) |
---|
44 | |
---|
45 | net_driver *driver=NULL; |
---|
46 | |
---|
47 | #ifdef __sgi |
---|
48 | #define next_process() sginap(0) |
---|
49 | #else |
---|
50 | #define next_process() usleep(10) |
---|
51 | #endif |
---|
52 | |
---|
53 | |
---|
54 | #ifdef __sgi |
---|
55 | void die(...) |
---|
56 | #else |
---|
57 | void die(int why) |
---|
58 | #endif |
---|
59 | { |
---|
60 | fprintf(stderr,"dieing\n"); |
---|
61 | if (driver) { delete driver; driver=NULL; } |
---|
62 | exit(0); |
---|
63 | } |
---|
64 | |
---|
65 | |
---|
66 | void mdie(char *reason) |
---|
67 | { |
---|
68 | fprintf(stderr,"net driver : %s\n",reason); |
---|
69 | if (driver) { driver->cleanup(); } |
---|
70 | exit(0); |
---|
71 | } |
---|
72 | |
---|
73 | void comm_failed() // general communication failure with engine |
---|
74 | { |
---|
75 | fprintf(stderr,"net driver : Error occurred while trying to communicate with the engine\n"); |
---|
76 | if (driver) { delete driver; driver=NULL; } |
---|
77 | exit(0); |
---|
78 | } |
---|
79 | |
---|
80 | int net_driver::add_joiner(int client_id, char *name) |
---|
81 | { |
---|
82 | join_array[client_id].next=base->join_list; |
---|
83 | base->join_list=real2shm(join_struct,&join_array[client_id]); |
---|
84 | join_array[client_id].client_id=client_id; |
---|
85 | strcpy(join_array[client_id].name,name); |
---|
86 | } |
---|
87 | |
---|
88 | |
---|
89 | void net_driver::cleanup() |
---|
90 | { |
---|
91 | base->input_state=INPUT_NET_DEAD; |
---|
92 | fprintf(stderr,"net driver : cleaning up\n"); |
---|
93 | if (shm_seg_id!=-1) |
---|
94 | shmctl(shm_seg_id,IPC_RMID,NULL); |
---|
95 | if (shm_addr!=(void *)-1) |
---|
96 | { |
---|
97 | shmdt((char *)shm_addr); |
---|
98 | shm_addr=(void *)-1; |
---|
99 | } |
---|
100 | |
---|
101 | undrv_cleanup(); |
---|
102 | unlink(DLOCK_NAME); |
---|
103 | } |
---|
104 | |
---|
105 | net_driver::~net_driver() |
---|
106 | { |
---|
107 | cleanup(); |
---|
108 | } |
---|
109 | |
---|
110 | int net_driver::setup_shm() |
---|
111 | { |
---|
112 | shm_addr=(void *)-1; // shmat returns -1 on failure |
---|
113 | shm_seg_id=-1; |
---|
114 | |
---|
115 | driver=this; |
---|
116 | int catch_sigs[]={ SIGHUP,SIGINT,SIGQUIT,SIGILL,SIGABRT, |
---|
117 | SIGIOT,SIGFPE,SIGKILL,SIGUSR1,SIGSEGV, |
---|
118 | SIGUSR2,SIGPIPE,SIGTERM,SIGCHLD, |
---|
119 | SIGCONT,SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU,-1}; |
---|
120 | |
---|
121 | int i; |
---|
122 | for (i=0; catch_sigs[i]!=-1; i++) // catch all signals in case we get |
---|
123 | signal(catch_sigs[i],die); // interrupted before we remove shmid |
---|
124 | |
---|
125 | |
---|
126 | int alloc_size=sizeof(join_struct)*MAX_JOINERS+sizeof(base_memory_struct); |
---|
127 | |
---|
128 | shm_seg_id=shmget(IPC_PRIVATE,alloc_size,IPC_CREAT | 0777); |
---|
129 | |
---|
130 | |
---|
131 | if (shm_seg_id==-1) mdie("Unable to allocate shared memory"); |
---|
132 | |
---|
133 | |
---|
134 | shm_addr=shmat(shm_seg_id,NULL,0); // attach as read/write |
---|
135 | if (shm_addr==(void *)-1) |
---|
136 | mdie("could not attach shm seg"); |
---|
137 | |
---|
138 | base=(base_memory_struct *)shm_addr; |
---|
139 | |
---|
140 | base->join_list=real2shm(join_struct,NULL); |
---|
141 | base->mem_lock=0; |
---|
142 | base->calc_crcs=0; |
---|
143 | base->get_lsf=0; |
---|
144 | base->wait_reload=0; |
---|
145 | base->need_reload=0; |
---|
146 | base->input_state=INPUT_COLLECTING; |
---|
147 | base->current_tick=0; |
---|
148 | base->packet.packet_reset(); |
---|
149 | join_array=(join_struct *) (base+1); |
---|
150 | |
---|
151 | // see if we can attach this memory with the abuse engine |
---|
152 | if (out->write(&shm_seg_id,sizeof(shm_seg_id))!=sizeof(shm_seg_id)) |
---|
153 | comm_failed(); |
---|
154 | |
---|
155 | // wait for engine to ack it has attached |
---|
156 | uint8_t ack=0; |
---|
157 | if (in->read(&ack,1)!=1 || ack!=1) |
---|
158 | comm_failed(); |
---|
159 | |
---|
160 | |
---|
161 | if (shmctl(shm_seg_id,IPC_RMID,NULL)) // remove the shm id |
---|
162 | mdie("could not remove shm id"); |
---|
163 | |
---|
164 | shm_seg_id=-1; // mark id as not allocated |
---|
165 | return 1; |
---|
166 | |
---|
167 | } |
---|
168 | |
---|
169 | int net_driver::connect_to_engine(int argc, char **argv) |
---|
170 | { |
---|
171 | if (mkfifo(DIN_NAME,S_IRWXU | S_IRWXG | S_IRWXO)) |
---|
172 | { perror("Net driver : unable to make fifo in /tmp"); |
---|
173 | return 0; |
---|
174 | } |
---|
175 | chmod(DIN_NAME,S_IRWXU | S_IRWXG | S_IRWXO); // just to be sure umask doesn't screw us |
---|
176 | |
---|
177 | if (mkfifo(DOUT_NAME,S_IRWXU | S_IRWXG | S_IRWXO)) |
---|
178 | { perror("Net driver : unable to make fifo in /tmp"); |
---|
179 | return 0; |
---|
180 | } |
---|
181 | chmod(DOUT_NAME,S_IRWXU | S_IRWXG | S_IRWXO); |
---|
182 | |
---|
183 | int driver_out_fd=open(DOUT_NAME,O_RDWR); // open the pipe |
---|
184 | if (driver_out_fd<0) |
---|
185 | { perror(DOUT_NAME); |
---|
186 | exit(1); |
---|
187 | } |
---|
188 | |
---|
189 | int driver_in_fd=open(DIN_NAME,O_RDWR); |
---|
190 | if (driver_in_fd<0) |
---|
191 | { |
---|
192 | close(driver_out_fd); |
---|
193 | perror(DIN_NAME); |
---|
194 | exit(1); |
---|
195 | } |
---|
196 | |
---|
197 | in=new unix_fd(driver_in_fd); |
---|
198 | in->read_selectable(); |
---|
199 | out=new unix_fd(driver_out_fd); |
---|
200 | |
---|
201 | if (in->read(®,sizeof(reg))!=sizeof(reg)) |
---|
202 | mdie("unable to registration from engine"); |
---|
203 | } |
---|
204 | |
---|
205 | net_driver::net_driver(int argc, char **argv, int comm_port, int game_port, net_protocol *proto) : |
---|
206 | comm_port(comm_port), game_port(game_port), proto(proto) |
---|
207 | { |
---|
208 | debug=0; |
---|
209 | lsf_wait_list=NULL; |
---|
210 | crc_wait_list=NULL; |
---|
211 | |
---|
212 | base=NULL; |
---|
213 | in=out=NULL; |
---|
214 | game_face=new game_handler(); |
---|
215 | |
---|
216 | connect_to_engine(argc,argv); |
---|
217 | setup_shm(); |
---|
218 | int i; |
---|
219 | for (i=1; i<argc; i++) if (!strcmp(argv[i],"-debug")) debug=1; |
---|
220 | } |
---|
221 | |
---|
222 | int net_driver::become_server() |
---|
223 | { |
---|
224 | delete game_face; |
---|
225 | game_face=new game_server; |
---|
226 | return 1; |
---|
227 | } |
---|
228 | |
---|
229 | int net_driver::check_commands() |
---|
230 | { |
---|
231 | int ret=0; |
---|
232 | if (in->ready_to_read()) // commands from engine? |
---|
233 | { |
---|
234 | uint8_t cmd; |
---|
235 | if (in->read(&cmd,1)!=1) return 0; |
---|
236 | |
---|
237 | if (debug) |
---|
238 | { |
---|
239 | if (cmd<=EGCMD_DIE) |
---|
240 | { |
---|
241 | char *cmds[]={ "open","close","read","write","seek","size","tell","setfs","crc_calced","process_lsf","request_lfs", |
---|
242 | "equest_entry","become_server","block","reload_start","reload_end","send_input","input_missing", |
---|
243 | "kill_slackers","die"}; |
---|
244 | fprintf(stderr,"engine cmd : %s\n",cmds[cmd]); |
---|
245 | } |
---|
246 | } |
---|
247 | |
---|
248 | switch (cmd) |
---|
249 | { |
---|
250 | case EGCMD_DIE : |
---|
251 | { |
---|
252 | cmd=game_face->quit(); |
---|
253 | if (!out->write(&cmd,1)) { mdie("could not write block ack1"); } // send something to unblock engine |
---|
254 | mdie("received die command"); |
---|
255 | } break; |
---|
256 | |
---|
257 | case NFCMD_RELOAD_START : |
---|
258 | { |
---|
259 | cmd=game_face->start_reload(); |
---|
260 | if (!out->write(&cmd,1)) { mdie("could not write start reload ack"); } // send something to unblock engine |
---|
261 | } break; |
---|
262 | |
---|
263 | case NFCMD_RELOAD_END : |
---|
264 | { |
---|
265 | cmd=game_face->end_reload(); |
---|
266 | if (!out->write(&cmd,1)) { mdie("could not write end reload ack"); } // send something to unblock engine |
---|
267 | } break; |
---|
268 | |
---|
269 | case NFCMD_BLOCK : |
---|
270 | { |
---|
271 | if (!out->write(&cmd,1)) { mdie("could not write block ack1"); } // send something to unblock engine |
---|
272 | if (!in->read(&cmd,1)) { mdie("could not read block ack1"); } // send something to block ourself |
---|
273 | } break; |
---|
274 | |
---|
275 | case NFCMD_INPUT_MISSING : // try to fetch the input via a loss-less net protocol |
---|
276 | { |
---|
277 | game_face->input_missing(); |
---|
278 | if (out->write(&cmd,1)!=1) { mdie("could not write block ack1"); } // send something to unblock engine |
---|
279 | } break; |
---|
280 | |
---|
281 | case NFCMD_KILL_SLACKERS : |
---|
282 | { |
---|
283 | if (!game_face->kill_slackers()) |
---|
284 | { |
---|
285 | delete game_face; |
---|
286 | game_face=new game_handler(); |
---|
287 | } |
---|
288 | if (out->write(&cmd,1)!=1) { mdie("could not write block ack1"); } // send something to unblock engine |
---|
289 | } break; |
---|
290 | case NFCMD_SEND_INPUT : |
---|
291 | { |
---|
292 | game_face->add_engine_input(); |
---|
293 | if (out->write(&cmd,1)!=1) { mdie("could not write send ack1"); } // send something to unblock engine |
---|
294 | if (in->read(&cmd,1)!=1) { mdie("could not read send ack2"); } // read something to block ourselves for engine |
---|
295 | } break; |
---|
296 | |
---|
297 | case NFCMD_REQUEST_ENTRY : |
---|
298 | { |
---|
299 | uint8_t len; |
---|
300 | char name[256]; |
---|
301 | if (in->read(&len,1)!=1) { mdie("could not read server name length"); } |
---|
302 | if (in->read(name,len)!=len) { mdie("could not read server name"); } |
---|
303 | uint16_t success=join_server(name); |
---|
304 | if (out->write(&success,2)!=2) mdie("cound not send lsf read failure"); |
---|
305 | } break; |
---|
306 | |
---|
307 | case NFCMD_BECOME_SERVER : |
---|
308 | { |
---|
309 | cmd=become_server(); |
---|
310 | if (out->write(&cmd,1)!=1) mdie("cound not send ok"); |
---|
311 | } break; |
---|
312 | |
---|
313 | case NFCMD_REQUEST_LSF : |
---|
314 | { |
---|
315 | uint8_t len; |
---|
316 | char name[256]; |
---|
317 | if (in->read(&len,1)!=1) { mdie("could not read lsf name length"); } |
---|
318 | if (in->read(name,len)!=len) { mdie("could not read lsf name"); } |
---|
319 | if (!get_lsf(name)) |
---|
320 | { |
---|
321 | len=0; |
---|
322 | if (out->write(&len,1)!=1) mdie("cound not send lsf read failure"); |
---|
323 | } else |
---|
324 | { |
---|
325 | len=strlen(name)+1; |
---|
326 | if (out->write(&len,1)!=1) mdie("cound not send lsf name len"); |
---|
327 | if (out->write(name,len)!=len) mdie("cound not send lsf name"); |
---|
328 | } |
---|
329 | } break; |
---|
330 | |
---|
331 | case NFCMD_PROCESS_LSF : |
---|
332 | { |
---|
333 | uint8_t len,name[256]; |
---|
334 | if (in->read(&len,1)!=1) { mdie("could not read lsf name length"); } |
---|
335 | if (in->read(name,len)!=len) { mdie("could not read lsf name"); } |
---|
336 | |
---|
337 | while (lsf_wait_list) |
---|
338 | { |
---|
339 | lsf_waiter *c=lsf_wait_list; |
---|
340 | lsf_wait_list=lsf_wait_list->next; |
---|
341 | uint8_t status=1; |
---|
342 | c->sock->write(&len,1); |
---|
343 | c->sock->write(name,len); |
---|
344 | delete c; |
---|
345 | } |
---|
346 | } break; |
---|
347 | |
---|
348 | case NFCMD_CRCS_CALCED : |
---|
349 | { |
---|
350 | while (crc_wait_list) |
---|
351 | { |
---|
352 | crc_waiter *c=crc_wait_list; |
---|
353 | crc_wait_list=crc_wait_list->next; |
---|
354 | uint8_t status=1; |
---|
355 | c->sock->write(&status,1); |
---|
356 | delete c; |
---|
357 | } |
---|
358 | } break; |
---|
359 | |
---|
360 | case NFCMD_SET_FS : |
---|
361 | { |
---|
362 | uint8_t size; |
---|
363 | char sn[256]; |
---|
364 | if (in->read(&size,1)!=1) mdie("could not read filename length"); |
---|
365 | if (in->read(sn,size)!=size) mdie("could not read server name"); |
---|
366 | fman->set_default_fs_name(sn); |
---|
367 | |
---|
368 | size=fetch_crcs(sn); // return success |
---|
369 | if (out->write(&size,1)!=1) mdie("could not send ok to engine"); |
---|
370 | } break; |
---|
371 | |
---|
372 | case NFCMD_OPEN : |
---|
373 | { |
---|
374 | uint8_t size[2]; |
---|
375 | char filename[300],mode[20],*fn; |
---|
376 | fn=filename; |
---|
377 | if (in->read(size,2)!=2 || |
---|
378 | in->read(filename,size[0])!=size[0] || |
---|
379 | in->read(mode,size[1])!=size[1]) |
---|
380 | mdie("incomplete open command from engine"); |
---|
381 | |
---|
382 | int fd=fman->rf_open_file(fn,mode); |
---|
383 | if (fd==-2) |
---|
384 | { |
---|
385 | uint8_t st[2]; |
---|
386 | st[0]=NF_OPEN_LOCAL_FILE; |
---|
387 | st[1]=strlen(fn)+1; |
---|
388 | if (out->write(st,2)!=2) comm_failed(); |
---|
389 | if (out->write(fn,st[1])!=st[1]) comm_failed(); |
---|
390 | } else if (fd==-1) |
---|
391 | { |
---|
392 | uint8_t st=NF_OPEN_FAILED; |
---|
393 | if (out->write(&st,1)!=1) comm_failed(); |
---|
394 | } else |
---|
395 | { |
---|
396 | uint8_t st=NF_OPEN_REMOTE_FILE; |
---|
397 | if (out->write(&st,1)!=1) comm_failed(); |
---|
398 | if (out->write(&fd,sizeof(fd))!=sizeof(fd)) comm_failed(); |
---|
399 | } |
---|
400 | } break; |
---|
401 | case NFCMD_CLOSE : |
---|
402 | case NFCMD_SIZE : |
---|
403 | case NFCMD_TELL : |
---|
404 | case NFCMD_SEEK : |
---|
405 | case NFCMD_READ : |
---|
406 | { |
---|
407 | int fd; |
---|
408 | if (in->read(&fd,sizeof(fd))!=sizeof(fd)) comm_failed(); |
---|
409 | |
---|
410 | switch (cmd) |
---|
411 | { |
---|
412 | case NFCMD_CLOSE : |
---|
413 | { |
---|
414 | fman->rf_close(fd); |
---|
415 | uint8_t st=1; |
---|
416 | if (out->write(&st,1)!=1) comm_failed(); |
---|
417 | } break; |
---|
418 | case NFCMD_SIZE : |
---|
419 | { |
---|
420 | int32_t x=fman->rf_file_size(fd); |
---|
421 | if (out->write(&x,sizeof(x))!=sizeof(x)) comm_failed(); |
---|
422 | } break; |
---|
423 | case NFCMD_TELL : |
---|
424 | { |
---|
425 | int32_t offset=fman->rf_tell(fd); |
---|
426 | if (out->write(&offset,sizeof(offset))!=sizeof(offset)) comm_failed(); |
---|
427 | } break; |
---|
428 | case NFCMD_SEEK : |
---|
429 | { |
---|
430 | int32_t offset; |
---|
431 | if (in->read(&offset,sizeof(offset))!=sizeof(offset)) comm_failed(); |
---|
432 | offset=fman->rf_seek(fd,offset); |
---|
433 | if (out->write(&offset,sizeof(offset))!=sizeof(offset)) comm_failed(); |
---|
434 | } break; |
---|
435 | case NFCMD_READ : |
---|
436 | { |
---|
437 | int32_t size; |
---|
438 | if (in->read(&size,sizeof(size))!=sizeof(size)) comm_failed(); |
---|
439 | fman->rf_read(fd,out,size); |
---|
440 | } break; |
---|
441 | } |
---|
442 | } break; |
---|
443 | default : |
---|
444 | { fprintf(stderr,"net driver : unknown net command %d\n",cmd); die(0); } |
---|
445 | } |
---|
446 | ret=1; |
---|
447 | } |
---|
448 | |
---|
449 | ret|=game_face->process_net(); |
---|
450 | return ret; |
---|
451 | } |
---|
452 | |
---|
453 | |
---|
454 | int net_driver::join_server(char *server_name) // ask remote server for entry into game |
---|
455 | { |
---|
456 | char sn_start[256]; |
---|
457 | strcpy(sn_start,server_name); |
---|
458 | |
---|
459 | net_socket *sock=connect_to_server(server_name, DEFAULT_COMM_PORT, 0); |
---|
460 | if (!sock) |
---|
461 | { |
---|
462 | fprintf(stderr,"unable to connect\n"); |
---|
463 | return 0; |
---|
464 | } |
---|
465 | |
---|
466 | uint8_t ctype=CLIENT_ABUSE; |
---|
467 | uint16_t port=lstl(game_port),cnum; |
---|
468 | |
---|
469 | uint8_t reg; |
---|
470 | if (sock->write(&ctype,1)!=1 || // send server out game port |
---|
471 | sock->read(®,1)!=1) // is remote engine registered? |
---|
472 | { delete sock; return 0; } |
---|
473 | |
---|
474 | |
---|
475 | // maker sure the two games are both registered or unregistered or sync problems |
---|
476 | // will occur. |
---|
477 | |
---|
478 | if (!reg) |
---|
479 | { |
---|
480 | fprintf(stderr, |
---|
481 | "This server is not running the registered version of abuse, and\n" |
---|
482 | "you are (thanks!). So that there are no conflict between the two games\n" |
---|
483 | "please start with the -share option when connecting to this server\n" |
---|
484 | "example : abuse -net somewhere.someplace.net -share\n"); |
---|
485 | delete sock; |
---|
486 | return 0; |
---|
487 | } |
---|
488 | |
---|
489 | char uname[256]; |
---|
490 | if (getlogin()) |
---|
491 | strcpy(uname,getlogin()); |
---|
492 | else strcpy(uname,"unknown"); |
---|
493 | uint8_t len=strlen(uname)+1; |
---|
494 | |
---|
495 | if (sock->write(&len,1)!=1 || |
---|
496 | sock->write(uname,len)!=len || |
---|
497 | sock->write(&port,2)!=2 || // send server out game port |
---|
498 | sock->read(&port,2)!=2 || // read server's game port |
---|
499 | sock->read(&cnum,2)!=2 || cnum==0 // read player number (cannot be 0 because 0 is server) |
---|
500 | ) |
---|
501 | { delete sock; return 0; } |
---|
502 | |
---|
503 | port=lstl(port); |
---|
504 | cnum=lstl(cnum); |
---|
505 | |
---|
506 | server_name=sn_start; |
---|
507 | net_socket *data_sock=connect_to_server(server_name,port,1,net_socket::SOCKET_FAST); |
---|
508 | if (!data_sock) { delete sock; return 0; } |
---|
509 | |
---|
510 | delete game_face; |
---|
511 | game_face=new game_client(sn_start,sock,data_sock); |
---|
512 | return cnum; |
---|
513 | } |
---|
514 | |
---|
515 | |
---|
516 | net_socket *net_driver::connect_to_server(char *&name, int port, int force_port, |
---|
517 | net_socket::socket_type sock_type) |
---|
518 | { |
---|
519 | char *oname=name; |
---|
520 | net_address *addr=proto->get_node_address(name, port, force_port); |
---|
521 | if (!addr) |
---|
522 | { |
---|
523 | if (debug) fprintf(stderr,"No IP address for name %s\n",oname); |
---|
524 | return NULL; |
---|
525 | } |
---|
526 | |
---|
527 | if (debug) |
---|
528 | fprintf(stderr,"connecting to server %s\n",oname); |
---|
529 | net_socket *sock=proto->connect_to_server(addr,sock_type); |
---|
530 | delete addr; |
---|
531 | return sock; |
---|
532 | } |
---|
533 | |
---|
534 | |
---|
535 | int net_driver::get_lsf(char *name) // contact remot host and ask for lisp startup file filename |
---|
536 | { |
---|
537 | char *name_start=name; |
---|
538 | net_socket *sock=connect_to_server(name); |
---|
539 | if (!sock) return 0; |
---|
540 | |
---|
541 | uint8_t ctype=CLIENT_LSF_WAITER; |
---|
542 | uint8_t len; |
---|
543 | |
---|
544 | if (sock->write(&ctype,1)!=1 || |
---|
545 | sock->read(&len,1)!=1 || len==0 || |
---|
546 | sock->read(name_start,len)!=len) |
---|
547 | { |
---|
548 | delete sock; |
---|
549 | return 0; |
---|
550 | } |
---|
551 | |
---|
552 | delete sock; |
---|
553 | return 1; |
---|
554 | } |
---|
555 | |
---|
556 | |
---|
557 | |
---|
558 | int net_driver::fetch_crcs(char *server) |
---|
559 | { |
---|
560 | net_socket *sock=connect_to_server(server); |
---|
561 | if (!sock) return 0; |
---|
562 | uint8_t cmd=CLIENT_CRC_WAITER; |
---|
563 | if (sock->write(&cmd,1)!=1 || |
---|
564 | sock->read(&cmd,1)!=1) |
---|
565 | { delete sock; return 0; } |
---|
566 | delete sock; |
---|
567 | return cmd; |
---|
568 | } |
---|
569 | |
---|
570 | |
---|
571 | int net_driver::add_client(int type, net_socket *sock, net_address *from) |
---|
572 | { |
---|
573 | switch (type) |
---|
574 | { |
---|
575 | case CLIENT_CRC_WAITER : |
---|
576 | { |
---|
577 | if (debug) |
---|
578 | fprintf(stderr,"add crc waiter\n"); |
---|
579 | |
---|
580 | crc_wait_list=new crc_waiter(sock,crc_wait_list); |
---|
581 | base->calc_crcs=1; |
---|
582 | return 1; |
---|
583 | } break; |
---|
584 | case CLIENT_LSF_WAITER : |
---|
585 | { |
---|
586 | if (debug) |
---|
587 | fprintf(stderr,"add lsf waiter\n"); |
---|
588 | lsf_wait_list=new lsf_waiter(sock,lsf_wait_list); |
---|
589 | base->get_lsf=1; |
---|
590 | return 1; |
---|
591 | } break; |
---|
592 | default : |
---|
593 | { |
---|
594 | int ret=game_face->add_client(type,sock,from); |
---|
595 | if (!ret && debug) |
---|
596 | fprintf(stderr,"unknown client type %d\n",type); |
---|
597 | return ret; |
---|
598 | } |
---|
599 | |
---|
600 | } |
---|
601 | return 0; |
---|
602 | } |
---|
603 | |
---|
604 | #endif // HAVE_NETWORK |
---|
605 | |
---|