Added upstream from http://ftp.icm.edu.pl/pub/loglan/
[loglan.git] / sources / int / net / ip / cli.c
1 #include "sock.h"
2 #include "srv.h"
3 #include "graph.h"
4
5 msg m;
6 int sock;
7
8 char *host;
9 char *file;
10 char *dest;
11 FILE *fdest;
12
13
14 #ifndef NO_PROTOTYPES
15 int main(int argc,char **argv);
16 #endif
17
18 static int bytes_received=0;
19 static char title[100];
20
21
22 static void usage(s) char *s;{
23    printf("usage: %s [-ms] host file [dest_file]\n",s);
24    exit(0);
25 }
26
27
28 int main(argc,argv) int argc; char** argv; {
29
30    int  file_size,file_packets,size,x,y;
31
32    if( argc < 3  ||  argc > 5 )  usage(argv[0]);
33
34    if( argv[1][0]=='-' ){
35       int i;
36       set_cli_recv_timeout( atoi(argv[1]+1) );
37       printf("timeout set to %d ms\n",atoi(argv[1]+1));
38       for( i=1; i<argc-1; i++ )  argv[i]=argv[i+1];
39       argc--;
40    }
41
42    host = argv[1];
43    file = argv[2];
44
45    if( argc > 3 )
46       dest = argv[3];
47    else
48       dest = file;
49
50    do{
51
52       printf("ask for %s:%s\n",host,file);
53
54       sock = sock_open( SOCK_DGRAM, "udp", host, NULL, PORT, AS_CLIENT );
55       if( sock<0 ) exit(10);
56       m.req   = htonl( RQ_FILE_SIZE );
57       strcpy( m.data, file );
58       sock_cli_crc_send( sock, &m, HEAD+strlen(m.data)+1 );
59       size = sock_cli_crc_recv( sock, &m, sizeof(m) );
60       close( sock );
61
62       if( size>0 ){
63          file_size = ntohl(*(int *)(m.data));
64          if( file_size < 0 )
65             printf("file %s:%s not found\n",host,file),exit(0);
66       }else
67       if( size<0 )
68          printf("error in packet\n");
69       else
70          printf("timed out\n");
71
72    }while( size<=0 );
73
74    fdest = fopen(dest,"wb");
75    if( fdest==NULL ){
76       printf("can't open file %s for writing\n",dest);
77    }
78
79    file_packets = (file_size+DATA_PIECE-1)/DATA_PIECE;
80
81    {
82       int i;
83       for(i=0;i*i<file_packets;i++);
84       x=i;
85       y=i;
86       if(i*i>file_packets){
87          x=i;
88          y=i;
89          while(x*y>file_packets) y--;
90          if(x*y<file_packets) y++;
91       }
92    }
93
94    sprintf(title,"%s:%s(%d b,pkt=%d b)",host,file,file_size,DATA_PIECE);
95    graph_on(x,y,title);
96    graph_board(file_packets);
97
98    {
99       extern void *calloc();
100       char *tab=calloc(1,file_packets);
101       while( !get_part( tab , file_packets ) );
102    }
103
104    fclose(fdest);
105
106    graph_off();
107
108    printf("received %d bytes for file %s size %d\n",
109           bytes_received,file,file_size
110          );
111
112    return 0;
113 }
114
115
116
117 int get_part( file_table , file_packets ) char *file_table; int file_packets; {
118
119    int i=0,cnt=0,pos;
120    int skip_dupls=0,after_skip=0;
121
122    for( ; i<file_packets; i++ )
123       if( file_table[i]=='\0' )
124          break;
125
126    pos = i;
127
128    if( i == file_packets )  return 1;
129
130    for( ; i<file_packets; i++ )
131       if( file_table[i]!='\0' )
132          break;
133       else
134          cnt++;
135
136    after_skip = cnt;
137
138    while( i < file_packets ){
139
140       for( ; i<file_packets; i++ )
141          if( file_table[i]=='\0' )
142             break;
143          else
144             skip_dupls++;
145
146       if( i==file_packets )  break;
147
148       for( ; i<file_packets; i++ )
149          if( file_table[i]!='\0' )
150             break;
151          else
152             after_skip++;
153
154       /* if now we add skip_dupls & after_skip we will have duplicates */
155       /* but maybe with lower cost ! */
156
157       if( skip_dupls < after_skip )
158          cnt = skip_dupls + after_skip ;
159       else
160          break;
161
162    }
163
164    printf("ask for %d packets, seek from %d file %s:%s\n",cnt,pos,host,file);
165    
166    sock = sock_open(SOCK_DGRAM,"udp",host,NULL,PORT,AS_CLIENT);
167    if( sock<0 ) exit(10);
168
169    m.req   = htonl( RQ_FILE );
170    ((int *)m.data)[0] = htonl( pos );           /* seek position */
171    ((int *)m.data)[1] = htonl( cnt );           /* no of packets */
172    strcpy(m.data+2*sizeof(int),file);
173    sock_cli_crc_send(sock,&m,HEAD+2*sizeof(int)+strlen(m.data+2*sizeof(int))+1);
174
175    for(;;){
176       int packno;
177       int size=sock_cli_crc_recv( sock, &m, sizeof(m) );
178       if( size==0 ) break;  /* timeout */
179       if( size>0 ) bytes_received += size;
180       packno=ntohl(m.req);
181       if( packno<0 || packno>=file_packets )  continue;
182       if( file_table[packno]!='\0' ){
183          continue;
184       }
185       if( size>0 ){
186          size-=HEAD;
187          fseek(fdest,packno*DATA_PIECE,0L);
188          if( fwrite(m.data,size,1,fdest)!=1 ){
189             printf("can't write file %s\n",file);
190             exit(10);
191          }
192          graph_point(packno,GRAPH_COL_OK);
193          file_table[packno]='\1';
194       }else    /* error in packet */
195          graph_point(packno,GRAPH_COL_ERROR);
196    }
197
198    close( sock );
199
200    return 0;
201 }
202