/[LeafOK_CVS]/pvpgn-1.7.4/src/client/bnftp.c
ViewVC logotype

Contents of /pvpgn-1.7.4/src/client/bnftp.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (show annotations) (vendor branch)
Tue Jun 6 03:41:38 2006 UTC (19 years, 9 months ago) by sysadm
Branch: GNU, MAIN
CVS Tags: arelease, HEAD
Changes since 1.1: +0 -0 lines
Content type: text/x-csrc
no message

1 /*
2 * Copyright (C) 1999,2001 Ross Combs (rocombs@cs.nmsu.edu)
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18 #include "common/setup_before.h"
19 #include <stdio.h>
20 #ifdef HAVE_STDDEF_H
21 # include <stddef.h>
22 #else
23 # ifndef NULL
24 # define NULL ((void *)0)
25 # endif
26 #endif
27 #ifdef STDC_HEADERS
28 # include <stdlib.h>
29 #endif
30 #include "compat/exitstatus.h"
31 #ifdef HAVE_STRING_H
32 # include <string.h>
33 #else
34 # ifdef HAVE_STRINGS_H
35 # include <strings.h>
36 # endif
37 #endif
38 #ifdef HAVE_MEMORY_H
39 # include <memory.h>
40 #endif
41 #include "compat/memset.h"
42 #include "compat/memcpy.h"
43 #include <ctype.h>
44 #include <errno.h>
45 #include "compat/strerror.h"
46 #ifdef TIME_WITH_SYS_TIME
47 # include <sys/time.h>
48 # include <time.h>
49 #else
50 # ifdef HAVE_SYS_TIME_H
51 # include <sys/time.h>
52 # else
53 # include <time.h>
54 # endif
55 #endif
56 #include "compat/strftime.h"
57 #ifdef HAVE_UNISTD_H
58 # include <unistd.h>
59 #endif
60 #ifdef HAVE_TERMIOS_H
61 # include <termios.h>
62 #endif
63 #include "compat/termios.h"
64 #ifdef HAVE_SYS_TYPES_H
65 # include <sys/types.h>
66 #endif
67 #ifdef HAVE_SYS_SOCKET_H
68 # include <sys/socket.h>
69 #endif
70 #include "compat/socket.h"
71 #include "compat/send.h"
72 #ifdef HAVE_SYS_PARAM_H
73 # include <sys/param.h>
74 #endif
75 #ifdef HAVE_NETINET_IN_H
76 # include <netinet/in.h>
77 #endif
78 #include "compat/netinet_in.h"
79 #ifdef HAVE_ARPA_INET_H
80 # include <arpa/inet.h>
81 #endif
82 #include "compat/inet_ntoa.h"
83 #ifdef HAVE_NETDB_H
84 # include <netdb.h>
85 #endif
86 #ifdef HAVE_SYS_STAT_H
87 # include <sys/stat.h>
88 #endif
89 #include "compat/psock.h"
90 #include "common/packet.h"
91 #include "common/init_protocol.h"
92 #include "common/file_protocol.h"
93 #include "common/tag.h"
94 #include "common/bn_type.h"
95 #include "common/field_sizes.h"
96 #include "common/network.h"
97 #include "common/version.h"
98 #include "common/util.h"
99 #include "common/bnettime.h"
100 #ifdef CLIENTDEBUG
101 #include "common/eventlog.h"
102 #endif
103 #include "common/hexdump.h"
104 #include "client.h"
105 #include "common/xalloc.h"
106 #include "common/setup_after.h"
107
108
109 static void usage(char const * progname);
110
111
112 static void usage(char const * progname)
113 {
114 fprintf(stderr,"usage: %s [<options>] [<servername> [<TCP portnumber>]]\n",progname);
115 fprintf(stderr,
116 " -b, --client=SEXP report client as Brood Wars\n"
117 " -d, --client=DRTL report client as Diablo Retail\n"
118 " --client=DSHR report client as Diablo Shareware\n"
119 " -s, --client=STAR report client as Starcraft (default)\n");
120 fprintf(stderr,
121 " --client=SSHR report client as Starcraft Shareware\n"
122 " -w, --client=W2BN report client as Warcraft II BNE\n"
123 " --client=D2DV report client as Diablo II\n"
124 " --client=D2XP report client as Diablo II: LoD\n"
125 " --client=WAR3 report client as Warcraft III\n"
126 " --client=W3XP report client as Warcraft III: FT\n"
127 " --hexdump=FILE do hex dump of packets into FILE\n");
128 fprintf(stderr,
129 " --arch=IX86 report architecture as Windows (x86)\n"
130 " --arch=PMAC report architecture as Macintosh\n"
131 " --arch=XMAC report architecture as Macintosh OSX\n"
132 );
133 fprintf(stderr,
134 " --startoffset=OFFSET force offset to be OFFSET\n"
135 " --exists=ACTION Ask/Overwrite/Backup/Resume if the file exists\n"
136 " --file=FILENAME use FILENAME instead of asking\n"
137 " -h, --help, --usage show this information and exit\n"
138 " -v, --version print version number and exit\n");
139 exit(STATUS_FAILURE);
140 }
141
142
143 extern int main(int argc, char * argv[])
144 {
145 int a;
146 int sd;
147 struct sockaddr_in saddr;
148 t_packet * packet;
149 t_packet * rpacket;
150 t_packet * fpacket;
151 char const * clienttag=NULL;
152 char const * archtag=NULL;
153 char const * servname=NULL;
154 unsigned short servport=0;
155 char const * hexfile=NULL;
156 char text[MAX_MESSAGE_LEN];
157 char const * reqfile=NULL;
158 struct hostent * host;
159 unsigned int commpos;
160 struct termios in_attr_old;
161 struct termios in_attr_new;
162 int changed_in;
163 unsigned int currsize;
164 unsigned int filelen;
165 unsigned int startoffset;
166 int startoffsetoverride=0;
167 #define EXIST_ACTION_UNSPEC -1
168 #define EXIST_ACTION_ASK 0
169 #define EXIST_ACTION_OVERWRITE 1
170 #define EXIST_ACTION_BACKUP 2
171 #define EXIST_ACTION_RESUME 3
172 int exist_action=EXIST_ACTION_UNSPEC;
173 struct stat exist_buf;
174 char const * filename;
175 FILE * fp;
176 FILE * hexstrm=NULL;
177 int fd_stdin;
178 t_bnettime bntime;
179 time_t tm;
180 char timestr[FILE_TIME_MAXLEN];
181 unsigned int screen_width,screen_height;
182 int munged;
183 unsigned int newproto = 0;
184
185 if (argc<1 || !argv || !argv[0])
186 {
187 fprintf(stderr,"bad arguments\n");
188 return STATUS_FAILURE;
189 }
190
191 for (a=1; a<argc; a++)
192 if (servname && isdigit((int)argv[a][0]) && a+1>=argc)
193 {
194 if (str_to_ushort(argv[a],&servport)<0)
195 {
196 fprintf(stderr,"%s: \"%s\" should be a positive integer\n",argv[0],argv[a]);
197 usage(argv[0]);
198 }
199 }
200 else if (!servname && argv[a][0]!='-' && a+2>=argc)
201 servname = argv[a];
202 else if (strcmp(argv[a],"-b")==0 || strcmp(argv[a],"--client=SEXP")==0)
203 {
204 if (clienttag)
205 {
206 fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
207 usage(argv[0]);
208 }
209 clienttag = CLIENTTAG_BROODWARS;
210 }
211 else if (strcmp(argv[a],"-d")==0 || strcmp(argv[a],"--client=DRTL")==0)
212 {
213 if (clienttag)
214 {
215 fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
216 usage(argv[0]);
217 }
218 clienttag = CLIENTTAG_DIABLORTL;
219 }
220 else if (strcmp(argv[a],"--client=DSHR")==0)
221 {
222 if (clienttag)
223 {
224 fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
225 usage(argv[0]);
226 }
227 clienttag = CLIENTTAG_DIABLOSHR;
228 }
229 else if (strcmp(argv[a],"-s")==0 || strcmp(argv[a],"--client=STAR")==0)
230 {
231 if (clienttag)
232 {
233 fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
234 usage(argv[0]);
235 }
236 clienttag = CLIENTTAG_STARCRAFT;
237 }
238 else if (strcmp(argv[a],"--client=SSHR")==0)
239 {
240 if (clienttag)
241 {
242 fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
243 usage(argv[0]);
244 }
245 clienttag = CLIENTTAG_SHAREWARE;
246 }
247 else if (strcmp(argv[a],"-w")==0 || strcmp(argv[a],"--client=W2BN")==0)
248 {
249 if (clienttag)
250 {
251 fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
252 usage(argv[0]);
253 }
254 clienttag = CLIENTTAG_WARCIIBNE;
255 }
256 else if (strcmp(argv[a],"--client=D2DV")==0)
257 {
258 if (clienttag)
259 {
260 fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
261 usage(argv[0]);
262 }
263 clienttag = CLIENTTAG_DIABLO2DV;
264 }
265 else if (strcmp(argv[a],"--client=D2XP")==0)
266 {
267 if (clienttag)
268 {
269 fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
270 usage(argv[0]);
271 }
272 clienttag = CLIENTTAG_DIABLO2XP;
273 }
274 else if (strcmp(argv[a],"--client=WAR3")==0)
275 {
276 if (clienttag)
277 {
278 fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
279 usage(argv[0]);
280 }
281 clienttag = CLIENTTAG_WARCRAFT3;
282 newproto = 1;
283 }
284 else if (strcmp(argv[a],"--client=W3XP")==0)
285 {
286 if (clienttag)
287 {
288 fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
289 usage(argv[0]);
290 }
291 clienttag = CLIENTTAG_WAR3XP;
292 newproto = 1;
293 }
294 else if (strncmp(argv[a],"--client=",9)==0)
295 {
296 fprintf(stderr,"%s: unknown client tag \"%s\"\n",argv[0],&argv[a][9]);
297 usage(argv[0]);
298 }
299 else if (strcmp(argv[a],"--arch=IX86")==0)
300 {
301 if (archtag)
302 {
303 fprintf(stderr,"%s: architecture type was already specified as \"%s\"\n",argv[0],archtag);
304 usage(argv[0]);
305 }
306 archtag = ARCHTAG_WINX86;
307 }
308 else if (strcmp(argv[a],"--arch=PMAC")==0)
309 {
310 if (archtag)
311 {
312 fprintf(stderr,"%s: architecture type was already specified as \"%s\"\n",argv[0],archtag);
313 usage(argv[0]);
314 }
315 archtag = ARCHTAG_MACPPC;
316 }
317 else if (strcmp(argv[a],"--arch=XMAC")==0)
318 {
319 if (archtag)
320 {
321 fprintf(stderr,"%s: architecture type was already specified as \"%s\"\n",argv[0],archtag);
322 usage(argv[0]);
323 }
324 archtag = ARCHTAG_OSXPPC;
325 }
326 else if (strncmp(argv[a],"--arch=",9)==0)
327 {
328 fprintf(stderr,"%s: unknown architecture tag \"%s\"\n",argv[0],&argv[a][9]);
329 usage(argv[0]);
330 }
331 else if (strncmp(argv[a],"--hexdump=",10)==0)
332 {
333 if (hexfile)
334 {
335 fprintf(stderr,"%s: hexdump file was already specified as \"%s\"\n",argv[0],hexfile);
336 usage(argv[0]);
337 }
338 hexfile = &argv[a][10];
339 }
340 else if (strncmp(argv[a],"--startoffset=",14)==0)
341 {
342 if (startoffsetoverride)
343 {
344 fprintf(stderr,"%s: startoffset was already specified as %u\n",argv[0],startoffset);
345 usage(argv[0]);
346 }
347 if (str_to_uint(&argv[a][14],&startoffset)<0)
348 {
349 fprintf(stderr,"%s: startoffset \"%s\" should be a positive integer\n",argv[0],&argv[a][14]);
350 usage(argv[0]);
351 }
352 startoffsetoverride = 1;
353 }
354 else if (strncmp(argv[a],"--exists=",9)==0)
355 {
356 if (exist_action!=EXIST_ACTION_UNSPEC)
357 {
358 fprintf(stderr,"%s: exists was already specified\n",argv[0]);
359 usage(argv[0]);
360 }
361 if (argv[a][9]=='o' || argv[a][9]=='O')
362 exist_action = EXIST_ACTION_OVERWRITE;
363 else if (argv[a][9]=='a' || argv[a][9]=='A')
364 exist_action = EXIST_ACTION_ASK;
365 else if (argv[a][9]=='b' || argv[a][9]=='B')
366 exist_action = EXIST_ACTION_BACKUP;
367 else if (argv[a][9]=='r' || argv[a][9]=='R')
368 exist_action = EXIST_ACTION_RESUME;
369 else {
370 fprintf(stderr,"%s: exists must begin with a,A,o,O,b,B,r or R",argv[0]);
371 usage(argv[0]);
372 }
373 }
374 else if (strncmp(argv[a],"--file=",7)==0)
375 {
376 if (reqfile)
377 {
378 fprintf(stderr,"%s: file was already specified as \"%s\"\n",argv[0],reqfile);
379 usage(argv[0]);
380 }
381 reqfile = &argv[a][7];
382 }
383 else if (strcmp(argv[a],"-v")==0 || strcmp(argv[a],"--version")==0)
384 {
385 printf("version "PVPGN_VERSION"\n");
386 return 0;
387 }
388 else if (strcmp(argv[a],"-h")==0 || strcmp(argv[a],"--help")==0 || strcmp(argv[a],"--usage")==0)
389 usage(argv[0]);
390 else if (strcmp(argv[a],"--client")==0 || strcmp(argv[a],"--hexdump")==0)
391 {
392 fprintf(stderr,"%s: option \"%s\" requires an argument\n",argv[0],argv[a]);
393 usage(argv[0]);
394 }
395 else
396 {
397 fprintf(stderr,"%s: unknown option \"%s\"\n",argv[0],argv[a]);
398 usage(argv[0]);
399 }
400
401 if (servport==0)
402 servport = BNETD_SERV_PORT;
403 if (!clienttag)
404 clienttag = CLIENTTAG_STARCRAFT;
405 if (!archtag)
406 archtag = ARCHTAG_WINX86;
407 if (!servname)
408 servname = BNETD_DEFAULT_HOST;
409 if (exist_action==EXIST_ACTION_UNSPEC)
410 exist_action = EXIST_ACTION_ASK;
411
412 if (hexfile)
413 {
414 if (!(hexstrm = fopen(hexfile,"w")))
415 fprintf(stderr,"%s: could not open file \"%s\" for writing the hexdump (fopen: %s)",argv[0],hexfile,pstrerror(errno));
416 else
417 { fprintf(hexstrm,"# dump generated by bnftp version "PVPGN_VERSION"\n"); }
418 }
419
420 if (psock_init()<0)
421 {
422 fprintf(stderr,"%s: could not inialialize socket functions\n",argv[0]);
423 return STATUS_FAILURE;
424 }
425
426 if (!(host = gethostbyname(servname)))
427 {
428 fprintf(stderr,"%s: unknown host \"%s\"\n",argv[0],servname);
429 return STATUS_FAILURE;
430 }
431
432 fd_stdin = fileno(stdin);
433 if (tcgetattr(fd_stdin,&in_attr_old)>=0)
434 {
435 in_attr_new = in_attr_old;
436 in_attr_new.c_lflag &= ~(ECHO | ICANON); /* turn off ECHO and ICANON */
437 in_attr_new.c_cc[VMIN] = 1; /* require reads to return at least one byte */
438 in_attr_new.c_cc[VTIME] = 0; /* no timeout */
439 tcsetattr(fd_stdin,TCSANOW,&in_attr_new);
440 changed_in = 1;
441 }
442 else
443 {
444 fprintf(stderr,"%s: could not get terminal attributes for stdin\n",argv[0]);
445 changed_in = 0;
446 }
447
448 if (client_get_termsize(fd_stdin,&screen_width,&screen_height)<0)
449 {
450 fprintf(stderr,"%s: could not determine screen size\n",argv[0]);
451 if (changed_in)
452 tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
453 return STATUS_FAILURE;
454 }
455
456 if ((sd = psock_socket(PSOCK_PF_INET,PSOCK_SOCK_STREAM,PSOCK_IPPROTO_TCP))<0)
457 {
458 fprintf(stderr,"%s: could not create socket (psock_socket: %s)\n",argv[0],pstrerror(psock_errno()));
459 if (changed_in)
460 tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
461 return STATUS_FAILURE;
462 }
463
464 memset(&saddr,0,sizeof(saddr));
465 saddr.sin_family = PSOCK_AF_INET;
466 saddr.sin_port = htons(servport);
467 memcpy(&saddr.sin_addr.s_addr,host->h_addr_list[0],host->h_length);
468 if (psock_connect(sd,(struct sockaddr *)&saddr,sizeof(saddr))<0)
469 {
470 fprintf(stderr,"%s: could not connect to server \"%s\" port %hu (psock_connect: %s)\n",argv[0],servname,servport,pstrerror(psock_errno()));
471 if (changed_in)
472 tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
473 return STATUS_FAILURE;
474 }
475
476 printf("Connected to %s:%hu.\n",inet_ntoa(saddr.sin_addr),servport);
477
478 #ifdef CLIENTDEBUG
479 eventlog_set(stderr);
480 #endif
481
482 if (!(packet = packet_create(packet_class_init)))
483 {
484 fprintf(stderr,"%s: could not create packet\n",argv[0]);
485 if (changed_in)
486 tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
487 return STATUS_FAILURE;
488 }
489 bn_byte_set(&packet->u.client_initconn.class,CLIENT_INITCONN_CLASS_FILE);
490 if (hexstrm)
491 {
492 fprintf(hexstrm,"%d: send class=%s[0x%02hx] type=%s[0x%04hx] length=%u\n",
493 sd,
494 packet_get_class_str(packet),(unsigned int)packet_get_class(packet),
495 packet_get_type_str(packet,packet_dir_from_client),packet_get_type(packet),
496 packet_get_size(packet));
497 hexdump(hexstrm,packet_get_raw_data(packet,0),packet_get_size(packet));
498 }
499 client_blocksend_packet(sd,packet);
500 packet_del_ref(packet);
501
502 if (!(rpacket = packet_create(packet_class_file)))
503 {
504 fprintf(stderr,"%s: could not create packet\n",argv[0]);
505 if (changed_in)
506 tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
507 return STATUS_FAILURE;
508 }
509
510 if (!(fpacket = packet_create(packet_class_raw)))
511 {
512 fprintf(stderr,"%s: could not create packet\n",argv[0]);
513 if (changed_in)
514 tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
515 packet_del_ref(rpacket);
516 return STATUS_FAILURE;
517 }
518
519 if (!reqfile) /* if not specified on the command line then prompt for it */
520 {
521 munged = 1;
522 commpos = 0;
523 text[0] = '\0';
524
525 for (;;)
526 {
527 switch (client_get_comm("filename: ",text,sizeof(text),&commpos,1,munged,screen_width))
528 {
529 case -1: /* cancel or error */
530 printf("\n");
531 if (changed_in)
532 tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
533 packet_del_ref(fpacket);
534 packet_del_ref(rpacket);
535 return STATUS_FAILURE;
536
537 case 0: /* timeout */
538 munged = 0;
539 continue;
540
541 case 1:
542 munged = 0;
543 if (text[0]=='\0')
544 continue;
545 printf("\n");
546 }
547 break;
548 }
549 reqfile = text;
550 }
551
552 if (stat(reqfile,&exist_buf)==0) /* check if the file exists */
553 {
554 char text2[MAX_MESSAGE_LEN];
555
556 munged = 1;
557 commpos = 0;
558 text2[0] = '\0';
559
560 while (exist_action==EXIST_ACTION_ASK)
561 {
562 switch (client_get_comm("File exists [O]verwrite, [B]ackup or [R]esume?: ",text2,sizeof(text2),&commpos,1,munged,screen_width))
563 {
564 case -1: /* cancel or error */
565 printf("\n");
566 if (changed_in)
567 tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
568 packet_del_ref(fpacket);
569 packet_del_ref(rpacket);
570 return STATUS_FAILURE;
571
572 case 0: /* timeout */
573 munged = 0;
574 continue;
575
576 case 1:
577 munged = 0;
578 if (text2[0]=='\0')
579 continue;
580 printf("\n");
581 break;
582 }
583
584 switch (text2[0])
585 {
586 case 'o':
587 case 'O':
588 exist_action = EXIST_ACTION_OVERWRITE;
589 break;
590 case 'b':
591 case 'B':
592 exist_action = EXIST_ACTION_BACKUP;
593 break;
594 case 'r':
595 case 'R':
596 exist_action = EXIST_ACTION_RESUME;
597 break;
598 default:
599 printf("Please answer with o,O,b,B,r or R.\n");
600 munged = 1;
601 continue;
602 }
603 break;
604 }
605
606 switch (exist_action)
607 {
608 case EXIST_ACTION_OVERWRITE:
609 if (!startoffsetoverride)
610 startoffset = 0;
611 break;
612 case EXIST_ACTION_BACKUP:
613 {
614 char * bakfile;
615 unsigned int bnr;
616 int renamed=0;
617
618 bakfile = xmalloc(strlen(reqfile)+1+2+1); /* assuming we go up to bnr 99 we need reqfile+'.'+'99'+'\0' */
619 for (bnr=0; bnr<100; bnr++)
620 {
621 sprintf(bakfile,"%s.%d",reqfile,bnr);
622 if (stat(bakfile,&exist_buf)==0)
623 continue; /* backup exists */
624 /* backup does not exist */
625 if (rename(reqfile,bakfile)<0) /* just rename the existing file to the backup */
626 fprintf(stderr,"%s: could not create backup file \"%s\" (rename: %s)\n",argv[0],bakfile,pstrerror(errno));
627 else
628 {
629 renamed = 1;
630 printf("Renaming \"%s\" to \"%s\".\n",reqfile,bakfile);
631 }
632 break;
633 }
634 xfree(bakfile);
635 if (!renamed)
636 {
637 fprintf(stderr,"%s: could not create backup for \"%s\".\n",argv[0],reqfile);
638 if (changed_in)
639 tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
640 packet_del_ref(fpacket);
641 packet_del_ref(rpacket);
642 return STATUS_FAILURE;
643 }
644 if (!startoffsetoverride)
645 startoffset = 0;
646 }
647 break;
648 case EXIST_ACTION_RESUME:
649 if (!startoffsetoverride)
650 startoffset = exist_buf.st_size;
651 break;
652 }
653 }
654 else
655 if (!startoffsetoverride)
656 startoffset = 0;
657
658 if (changed_in)
659 tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
660
661 if (!(packet = packet_create(packet_class_file)))
662 {
663 fprintf(stderr,"%s: could not create packet\n",argv[0]);
664 packet_del_ref(fpacket);
665 packet_del_ref(rpacket);
666 return STATUS_FAILURE;
667 }
668 if (newproto) {
669 /* first send ARCH/CTAG */
670 packet_set_size(packet, sizeof(t_client_file_req2));
671 packet_set_type(packet, CLIENT_FILE_REQ2);
672 bn_int_tag_set(&packet->u.client_file_req2.archtag,archtag);
673 bn_int_tag_set(&packet->u.client_file_req2.clienttag,clienttag);
674 bn_long_set_a_b(&packet->u.client_file_req2.unknown1,0,0);
675 } else {
676 packet_set_size(packet,sizeof(t_client_file_req));
677 packet_set_type(packet, CLIENT_FILE_REQ);
678 bn_int_tag_set(&packet->u.client_file_req.archtag,archtag);
679 bn_int_tag_set(&packet->u.client_file_req.clienttag,clienttag);
680 bn_int_set(&packet->u.client_file_req.adid,0);
681 bn_int_set(&packet->u.client_file_req.extensiontag,0);
682 bn_int_set(&packet->u.client_file_req.startoffset,startoffset);
683 bn_long_set_a_b(&packet->u.client_file_req.timestamp,0x00000000,0x00000000);
684 packet_append_string(packet,reqfile);
685 }
686 if (hexstrm)
687 {
688 fprintf(hexstrm,"%d: send class=%s[0x%02hx] type=%s[0x%04hx] length=%u\n",
689 sd,
690 packet_get_class_str(packet),(unsigned int)packet_get_class(packet),
691 packet_get_type_str(packet,packet_dir_from_client),packet_get_type(packet),
692 packet_get_size(packet));
693 hexdump(hexstrm,packet_get_raw_data(packet,0),packet_get_size(packet));
694 }
695 if (newproto) printf("\nSending ARCH/CTAG info...");
696 else printf("\nRequesting info...");
697 fflush(stdout);
698 client_blocksend_packet(sd,packet);
699 packet_del_ref(packet);
700
701 if (newproto) {
702 /* received the stupid 4 bytes unknown "packet" */
703 packet_set_size(fpacket, sizeof(t_server_file_unknown1));
704 if (client_blockrecv_packet(sd,fpacket)<0)
705 {
706 fprintf(stderr,"%s: server closed connection\n",argv[0]);
707 packet_del_ref(fpacket);
708 packet_del_ref(rpacket);
709 return STATUS_FAILURE;
710 }
711 if (hexstrm)
712 {
713 fprintf(hexstrm,"%d: recv class=%s[0x%02hx] type=%s[0x%04hx] length=%u\n",
714 sd,
715 packet_get_class_str(fpacket),(unsigned int)packet_get_class(fpacket),
716 packet_get_type_str(fpacket,packet_dir_from_server),packet_get_type(fpacket),
717 packet_get_size(fpacket));
718 hexdump(hexstrm,packet_get_raw_data(fpacket,0),packet_get_size(fpacket));
719 }
720
721 /* send file info request */
722 packet_set_size(fpacket, sizeof(t_client_file_req3));
723 bn_int_set(&fpacket->u.client_file_req3.unknown1, 0);
724 bn_long_set_a_b(&fpacket->u.client_file_req3.timestamp, 0, 0);
725 bn_long_set_a_b(&fpacket->u.client_file_req3.unknown2, 0, 0);
726 bn_long_set_a_b(&fpacket->u.client_file_req3.unknown3, 0, 0);
727 bn_long_set_a_b(&fpacket->u.client_file_req3.unknown4, 0, 0);
728 bn_long_set_a_b(&fpacket->u.client_file_req3.unknown5, 0, 0);
729 bn_long_set_a_b(&fpacket->u.client_file_req3.unknown6, 0, 0);
730 packet_append_string(fpacket, reqfile);
731 printf("\nRequesting info...");
732 fflush(stdout);
733 client_blocksend_packet(sd,fpacket);
734 if (hexstrm)
735 {
736 fprintf(hexstrm,"%d: send class=%s[0x%02hx] type=%s[0x%04hx] length=%u\n",
737 sd,
738 packet_get_class_str(fpacket),(unsigned int)packet_get_class(fpacket),
739 packet_get_type_str(fpacket,packet_dir_from_client),packet_get_type(fpacket),
740 packet_get_size(fpacket));
741 hexdump(hexstrm,packet_get_raw_data(fpacket,0),packet_get_size(fpacket));
742 }
743 }
744 do
745 {
746 if (client_blockrecv_packet(sd,rpacket)<0)
747 {
748 fprintf(stderr,"%s: server closed connection\n",argv[0]);
749 packet_del_ref(fpacket);
750 packet_del_ref(rpacket);
751 return STATUS_FAILURE;
752 }
753 if (hexstrm)
754 {
755 fprintf(hexstrm,"%d: recv class=%s[0x%02hx] type=%s[0x%04hx] length=%u\n",
756 sd,
757 packet_get_class_str(rpacket),(unsigned int)packet_get_class(rpacket),
758 packet_get_type_str(rpacket,packet_dir_from_server),packet_get_type(rpacket),
759 packet_get_size(rpacket));
760 hexdump(hexstrm,packet_get_raw_data(rpacket,0),packet_get_size(rpacket));
761 }
762 }
763 while (packet_get_type(rpacket)!=SERVER_FILE_REPLY);
764
765 filelen = bn_int_get(rpacket->u.server_file_reply.filelen);
766 bn_long_to_bnettime(rpacket->u.server_file_reply.timestamp,&bntime);
767 tm = bnettime_to_time(bntime);
768 strftime(timestr,FILE_TIME_MAXLEN,FILE_TIME_FORMAT,localtime(&tm));
769 filename = packet_get_str_const(rpacket,sizeof(t_server_file_reply),MAX_FILENAME_STR);
770
771 if (exist_action==EXIST_ACTION_RESUME)
772 {
773 if (!(fp = fopen(reqfile,"ab")))
774 {
775 fprintf(stderr,"%s: could not open file \"%s\" for appending (fopen: %s)\n",argv[0],reqfile,pstrerror(errno));
776 packet_del_ref(fpacket);
777 packet_del_ref(rpacket);
778 return STATUS_FAILURE;
779 }
780 }
781 else
782 {
783 if (!(fp = fopen(reqfile,"wb")))
784 {
785 fprintf(stderr,"%s: could not open file \"%s\" for writing (fopen: %s)\n",argv[0],reqfile,pstrerror(errno));
786 packet_del_ref(fpacket);
787 packet_del_ref(rpacket);
788 return STATUS_FAILURE;
789 }
790 }
791
792 printf("\n name: \"");
793 str_print_term(stdout,filename,0,0);
794 printf("\"\n changed: %s\n length: %u bytes\n",timestr,filelen);
795 fflush(stdout);
796
797 if (startoffset>0) {
798 filelen -= startoffset; /* for resuming files */
799 printf("Resuming at position %u (%u bytes remaining).\n",startoffset,filelen);
800 }
801
802 printf("\nSaving to \"%s\"...",reqfile);
803
804 for (currsize=0; currsize+MAX_PACKET_SIZE<=filelen; currsize+=MAX_PACKET_SIZE)
805 {
806 printf(".");
807 fflush(stdout);
808
809 if (client_blockrecv_raw_packet(sd,fpacket,MAX_PACKET_SIZE)<0)
810 {
811 printf("error\n");
812 fprintf(stderr,"%s: server closed connection\n",argv[0]);
813 if (fclose(fp)<0)
814 fprintf(stderr,"%s: could not close file \"%s\" after writing (fclose: %s)\n",argv[0],reqfile,pstrerror(errno));
815 packet_del_ref(fpacket);
816 packet_del_ref(rpacket);
817 return STATUS_FAILURE;
818 }
819 if (hexstrm)
820 {
821 fprintf(hexstrm,"%d: recv class=%s[0x%02hx] type=%s[0x%04hx] length=%u\n",
822 sd,
823 packet_get_class_str(fpacket),(unsigned int)packet_get_class(fpacket),
824 packet_get_type_str(fpacket,packet_dir_from_server),packet_get_type(fpacket),
825 packet_get_size(fpacket));
826 hexdump(hexstrm,packet_get_raw_data(fpacket,0),packet_get_size(fpacket));
827 }
828 if (fwrite(packet_get_raw_data_const(fpacket,0),1,MAX_PACKET_SIZE,fp)<MAX_PACKET_SIZE)
829 {
830 printf("error\n");
831 fprintf(stderr,"%s: could not write to file \"%s\" (fwrite: %s)\n",argv[0],reqfile,pstrerror(errno));
832 if (fclose(fp)<0)
833 fprintf(stderr,"%s: could not close file \"%s\" after writing (fclose: %s)\n",argv[0],reqfile,pstrerror(errno));
834 packet_del_ref(fpacket);
835 packet_del_ref(rpacket);
836 return STATUS_FAILURE;
837 }
838 }
839 filelen -= currsize;
840 if (filelen)
841 {
842 printf(".");
843 fflush(stdout);
844
845 if (client_blockrecv_raw_packet(sd,fpacket,filelen)<0)
846 {
847 printf("error\n");
848 fprintf(stderr,"%s: server closed connection\n",argv[0]);
849 if (fclose(fp)<0)
850 fprintf(stderr,"%s: could not close file \"%s\" after writing (fclose: %s)\n",argv[0],reqfile,pstrerror(errno));
851 packet_del_ref(fpacket);
852 packet_del_ref(rpacket);
853 return STATUS_FAILURE;
854 }
855 if (hexstrm)
856 {
857 fprintf(hexstrm,"%d: recv class=%s[0x%02hx] type=%s[0x%04hx] length=%u\n",
858 sd,
859 packet_get_class_str(fpacket),(unsigned int)packet_get_class(fpacket),
860 packet_get_type_str(fpacket,packet_dir_from_server),packet_get_type(fpacket),
861 packet_get_size(fpacket));
862 hexdump(hexstrm,packet_get_raw_data(fpacket,0),packet_get_size(fpacket));
863 }
864 if (fwrite(packet_get_raw_data_const(fpacket,0),1,filelen,fp)<filelen)
865 {
866 printf("error\n");
867 fprintf(stderr,"%s: could not write to file \"%s\"\n",argv[0],reqfile);
868 if (fclose(fp)<0)
869 fprintf(stderr,"%s: could not close file \"%s\" after writing (fclose: %s)\n",argv[0],reqfile,pstrerror(errno));
870 packet_del_ref(fpacket);
871 packet_del_ref(rpacket);
872 return STATUS_FAILURE;
873 }
874 }
875
876 packet_del_ref(fpacket);
877 packet_del_ref(rpacket);
878
879 if (hexstrm)
880 {
881 fprintf(hexstrm,"# end of dump\n");
882 if (fclose(hexstrm)<0)
883 fprintf(stderr,"%s: could not close hexdump file \"%s\" after writing (fclose: %s)",argv[0],hexfile,pstrerror(errno));
884 }
885
886 if (fclose(fp)<0)
887 {
888 fprintf(stderr,"%s: could not close file \"%s\" after writing (fclose: %s)\n",argv[0],reqfile,pstrerror(errno));
889 return STATUS_FAILURE;
890 }
891
892 printf("done\n");
893 return STATUS_FAILURE;
894 }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1