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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations)
Tue Jun 6 03:41:38 2006 UTC (19 years, 9 months ago) by sysadm
CVS Tags: pvpgn_1-7-4-0_MIL
Branch point for: GNU, MAIN
Content type: text/x-csrc
Initial revision

1 sysadm 1.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