/[axel]/tags/1.0b/text.c
ViewVC logotype

Contents of /tags/1.0b/text.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5 - (show annotations) (download)
Fri Jan 11 12:06:12 2008 UTC (5 years, 4 months ago) by appaji-guest
File MIME type: text/plain
File size: 12758 byte(s)
Tagging 1.0b release
1 /********************************************************************\
2 * Axel -- A lighter download accelerator for Linux and other Unices. *
3 * *
4 * Copyright 2001 Wilmer van der Gaast *
5 \********************************************************************/
6
7 /* Text interface */
8
9 /*
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License with
21 the Debian GNU/Linux distribution in file /usr/doc/copyright/GPL;
22 if not, write to the Free Software Foundation, Inc., 59 Temple Place,
23 Suite 330, Boston, MA 02111-1307 USA
24 */
25
26 #include "axel.h"
27
28 static void stop( int signal );
29 static char *size_human( int value );
30 static char *time_human( int value );
31 static void print_commas( int bytes_done );
32 static void print_alternate_output( axel_t *axel );
33 static void print_help();
34 static void print_version();
35 static void print_messages( axel_t *axel );
36
37 int run = 1;
38
39 #ifdef NOGETOPTLONG
40 #define getopt_long( a, b, c, d, e ) getopt( a, b, c )
41 #else
42 static struct option axel_options[] =
43 {
44 /* name has_arg flag val */
45 { "max-speed", 1, NULL, 's' },
46 { "num-connections", 1, NULL, 'n' },
47 { "output", 1, NULL, 'o' },
48 { "search", 2, NULL, 'S' },
49 { "no-proxy", 0, NULL, 'N' },
50 { "quiet", 0, NULL, 'q' },
51 { "verbose", 0, NULL, 'v' },
52 { "help", 0, NULL, 'h' },
53 { "version", 0, NULL, 'V' },
54 { "alternate", 0, NULL, 'a' },
55 { NULL, 0, NULL, 0 }
56 };
57 #endif
58
59 /* For returning string values from functions */
60 static char string[MAX_STRING];
61
62
63 int main( int argc, char *argv[] )
64 {
65 char fn[MAX_STRING] = "";
66 int do_search = 0;
67 search_t *search;
68 conf_t conf[1];
69 axel_t *axel;
70 int i, j;
71 char *s;
72
73 #ifdef I18N
74 setlocale( LC_ALL, "" );
75 bindtextdomain( PACKAGE, LOCALE );
76 textdomain( PACKAGE );
77 #endif
78
79 if( !conf_init( conf ) )
80 {
81 return( 1 );
82 }
83
84 opterr = 0;
85
86 j = -1;
87 while( 1 )
88 {
89 int option;
90
91 option = getopt_long( argc, argv, "s:n:o:S::NqvhHVa", axel_options, NULL );
92 if( option == -1 )
93 break;
94
95 switch( option )
96 {
97 case 's':
98 if( !sscanf( optarg, "%i", &conf->max_speed ) )
99 {
100 print_help();
101 return( 1 );
102 }
103 break;
104 case 'n':
105 if( !sscanf( optarg, "%i", &conf->num_connections ) )
106 {
107 print_help();
108 return( 1 );
109 }
110 break;
111 case 'o':
112 strncpy( fn, optarg, MAX_STRING );
113 break;
114 case 'S':
115 do_search = 1;
116 if( optarg != NULL )
117 if( !sscanf( optarg, "%i", &conf->search_top ) )
118 {
119 print_help();
120 return( 1 );
121 }
122 break;
123 case 'a':
124 conf->alternate_output = 1;
125 break;
126 case 'N':
127 *conf->http_proxy = 0;
128 break;
129 case 'h':
130 print_help();
131 return( 0 );
132 case 'v':
133 if( j == -1 )
134 j = 1;
135 else
136 j ++;
137 break;
138 case 'V':
139 print_version();
140 return( 0 );
141 case 'q':
142 close( 1 );
143 conf->verbose = -1;
144 if( open( "/dev/null", O_WRONLY ) != 1 )
145 {
146 fprintf( stderr, _("Can't redirect stdout to /dev/null.\n") );
147 return( 1 );
148 }
149 break;
150 default:
151 print_help();
152 return( 1 );
153 }
154 }
155
156 if( j > -1 )
157 conf->verbose = j;
158
159 if( argc - optind == 0 )
160 {
161 print_help();
162 return( 1 );
163 }
164 else if( strcmp( argv[optind], "-" ) == 0 )
165 {
166 s = malloc( MAX_STRING );
167 scanf( "%127[^\n]s", s );
168 }
169 else
170 {
171 s = argv[optind];
172 }
173
174 printf( _("Initializing download: %s\n"), s );
175 if( do_search )
176 {
177 search = malloc( sizeof( search_t ) * ( conf->search_amount + 1 ) );
178 memset( search, 0, sizeof( search_t ) * ( conf->search_amount + 1 ) );
179 search[0].conf = conf;
180 if( conf->verbose )
181 printf( _("Doing search...\n") );
182 i = search_makelist( search, s );
183 if( i < 0 )
184 {
185 fprintf( stderr, _("File not found\n" ) );
186 return( 1 );
187 }
188 if( conf->verbose )
189 printf( _("Testing speeds, this can take a while...\n") );
190 j = search_getspeeds( search, i );
191 search_sortlist( search, i );
192 if( conf->verbose )
193 {
194 printf( _("%i usable servers found, will use these URLs:\n"), j );
195 j = min( j, conf->search_top );
196 printf( "%-60s %15s\n", "URL", "Speed" );
197 for( i = 0; i < j; i ++ )
198 printf( "%-70.70s %5i\n", search[i].url, search[i].speed );
199 printf( "\n" );
200 }
201 axel = axel_new( conf, j, search );
202 free( search );
203 if( axel->ready == -1 )
204 {
205 print_messages( axel );
206 axel_close( axel );
207 return( 1 );
208 }
209 }
210 else if( argc - optind == 1 )
211 {
212 axel = axel_new( conf, 0, s );
213 if( axel->ready == -1 )
214 {
215 print_messages( axel );
216 axel_close( axel );
217 return( 1 );
218 }
219 }
220 else
221 {
222 search = malloc( sizeof( search_t ) * ( argc - optind ) );
223 memset( search, 0, sizeof( search_t ) * ( argc - optind ) );
224 for( i = 0; i < ( argc - optind ); i ++ )
225 strncpy( search[i].url, argv[optind+i], MAX_STRING );
226 axel = axel_new( conf, argc - optind, search );
227 free( search );
228 if( axel->ready == -1 )
229 {
230 print_messages( axel );
231 axel_close( axel );
232 return( 1 );
233 }
234 }
235 print_messages( axel );
236 if( s != argv[optind] )
237 {
238 free( s );
239 }
240
241 if( *fn )
242 {
243 struct stat buf;
244
245 if( stat( fn, &buf ) == 0 )
246 {
247 if( S_ISDIR( buf.st_mode ) )
248 {
249 strncat( fn, "/", MAX_STRING );
250 strncat( fn, axel->filename, MAX_STRING );
251 }
252 }
253 sprintf( string, "%s.st", fn );
254 if( access( fn, F_OK ) == 0 ) if( access( string, F_OK ) != 0 )
255 {
256 fprintf( stderr, _("No state file, cannot resume!\n") );
257 return( 1 );
258 }
259 if( access( string, F_OK ) == 0 ) if( access( fn, F_OK ) != 0 )
260 {
261 printf( _("State file found, but no downloaded data. Starting from scratch.\n" ) );
262 unlink( string );
263 }
264 strcpy( axel->filename, fn );
265 }
266 else
267 {
268 /* Local file existence check */
269 i = 0;
270 s = axel->filename + strlen( axel->filename );
271 while( 1 )
272 {
273 sprintf( string, "%s.st", axel->filename );
274 if( access( axel->filename, F_OK ) == 0 )
275 {
276 if( axel->conn[0].supported )
277 {
278 if( access( string, F_OK ) == 0 )
279 break;
280 }
281 }
282 else
283 {
284 if( access( string, F_OK ) )
285 break;
286 }
287 sprintf( s, ".%i", i );
288 i ++;
289 }
290 }
291
292 if( !axel_open( axel ) )
293 {
294 print_messages( axel );
295 return( 1 );
296 }
297 print_messages( axel );
298 axel_start( axel );
299 print_messages( axel );
300
301 if( conf->alternate_output )
302 {
303 putchar('\n');
304 }
305 else
306 {
307 if( axel->bytes_done > 0 ) /* Print first dots if resuming */
308 {
309 putchar( '\n' );
310 print_commas( axel->bytes_done );
311 }
312 }
313 axel->start_byte = axel->bytes_done;
314
315 /* Install save_state signal handler for resuming support */
316 signal( SIGINT, stop );
317 signal( SIGTERM, stop );
318
319 while( !axel->ready && run )
320 {
321 int prev, done;
322
323 prev = axel->bytes_done;
324 axel_do( axel );
325
326 if( conf->alternate_output )
327 {
328 if( !axel->message && prev != axel->bytes_done )
329 print_alternate_output( axel );
330 }
331 else
332 {
333 /* The infamous wget-like 'interface'.. ;) */
334 done = ( axel->bytes_done / 1024 ) - ( prev / 1024 );
335 if( done && conf->verbose > -1 )
336 {
337 for( i = 0; i < done; i ++ )
338 {
339 i += ( prev / 1024 );
340 if( ( i % 50 ) == 0 )
341 {
342 if( prev >= 1024 )
343 printf( " [%6.1fKB/s]", (double) axel->bytes_per_second / 1024 );
344 if( axel->size < 10240000 )
345 printf( "\n[%3i%%] ", min( 100, 102400 * i / axel->size ) );
346 else
347 printf( "\n[%3i%%] ", min( 100, i / ( axel->size / 102400 ) ) );
348 }
349 else if( ( i % 10 ) == 0 )
350 {
351 putchar( ' ' );
352 }
353 putchar( '.' );
354 i -= ( prev / 1024 );
355 }
356 fflush( stdout );
357 }
358 }
359
360 if( axel->message )
361 {
362 if(conf->alternate_output==1)
363 {
364 /* clreol-simulation */
365 putchar( '\r' );
366 for( i = 0; i < 79; i++ ) /* linewidth known? */
367 putchar( ' ' );
368 putchar( '\r' );
369 }
370 else
371 {
372 putchar( '\n' );
373 }
374 print_messages( axel );
375 if( !axel->ready )
376 {
377 if(conf->alternate_output!=1)
378 print_commas( axel->bytes_done );
379 else
380 print_alternate_output(axel);
381 }
382 }
383 else if( axel->ready )
384 {
385 putchar( '\n' );
386 }
387 }
388
389 strcpy( string + MAX_STRING / 2,
390 size_human( axel->bytes_done - axel->start_byte ) );
391
392 printf( _("\nDownloaded %s in %s. (%.2f KB/s)\n"),
393 string + MAX_STRING / 2,
394 time_human( gettime() - axel->start_time ),
395 (double) axel->bytes_per_second / 1024 );
396
397 i = axel->ready ? 0 : 2;
398
399 axel_close( axel );
400
401 return( i );
402 }
403
404 /* SIGINT/SIGTERM handler */
405 void stop( int signal )
406 {
407 run = 0;
408 }
409
410 /* Convert a number of bytes to a human-readable form */
411 char *size_human( int value )
412 {
413 if( value == 1 )
414 sprintf( string, _("%i byte"), value );
415 else if( value < 1024 )
416 sprintf( string, _("%i bytes"), value );
417 else if( value < 10485760 )
418 sprintf( string, _("%.1f kilobytes"), (float) value / 1024 );
419 else
420 sprintf( string, _("%.1f megabytes"), (float) value / 1048576 );
421
422 return( string );
423 }
424
425 /* Convert a number of seconds to a human-readable form */
426 char *time_human( int value )
427 {
428 if( value == 1 )
429 sprintf( string, _("%i second"), value );
430 else if( value < 60 )
431 sprintf( string, _("%i seconds"), value );
432 else if( value < 3600 )
433 sprintf( string, _("%i:%02i seconds"), value / 60, value % 60 );
434 else
435 sprintf( string, _("%i:%02i:%02i seconds"), value / 3600, ( value / 60 ) % 60, value % 60 );
436
437 return( string );
438 }
439
440 /* Part of the infamous wget-like interface. Just put it in a function
441 because I need it quite often.. */
442 void print_commas( int bytes_done )
443 {
444 int i, j;
445
446 printf( " " );
447 j = ( bytes_done / 1024 ) % 50;
448 if( j == 0 ) j = 50;
449 for( i = 0; i < j; i ++ )
450 {
451 if( ( i % 10 ) == 0 )
452 putchar( ' ' );
453 putchar( ',' );
454 }
455 fflush( stdout );
456 }
457
458 static void print_alternate_output(axel_t *axel)
459 {
460 int done=axel->bytes_done;
461 int total=axel->size;
462 int i,j=0;
463 double now = gettime();
464
465 printf("\r[%3ld%%] [", min(100,(long)(done*100./total+.5) ) );
466
467 for(i=0;i<axel->conf->num_connections;i++)
468 {
469 for(;j<((double)axel->conn[i].currentbyte/(total+1)*50)-1;j++)
470 putchar('.');
471
472 if(axel->conn[i].currentbyte<axel->conn[i].lastbyte)
473 {
474 if(now <= axel->conn[i].last_transfer + axel->conf->connection_timeout/2 )
475 putchar(i+'0');
476 else
477 putchar('#');
478 } else
479 putchar('.');
480
481 j++;
482
483 for(;j<((double)axel->conn[i].lastbyte/(total+1)*50);j++)
484 putchar(' ');
485 }
486
487 printf( "] [%6.1fKB/s]", (double) axel->bytes_per_second / 1024 );
488
489 if(done<total)
490 {
491 int seconds,minutes,hours,days;
492 seconds=axel->finish_time - now;
493 minutes=seconds/60;seconds-=minutes*60;
494 hours=minutes/60;minutes-=hours*60;
495 days=hours/24;hours-=days*24;
496 if(days)
497 printf(" [%2dd%2d]",days,hours);
498 else if(hours)
499 printf(" [%2dh%02d]",hours,minutes);
500 else
501 printf(" [%02d:%02d]",minutes,seconds);
502 }
503
504 fflush( stdout );
505 }
506
507 void print_help()
508 {
509 #ifdef NOGETOPTLONG
510 printf( _("Usage: axel [options] url1 [url2] [url...]\n"
511 "\n"
512 "-s x\tSpecify maximum speed (bytes per second)\n"
513 "-n x\tSpecify maximum number of connections\n"
514 "-o f\tSpecify local output file\n"
515 "-S [x]\tSearch for mirrors and download from x servers\n"
516 "-N\tJust don't use any proxy server\n"
517 "-q\tLeave stdout alone\n"
518 "-v\tMore status information\n"
519 "-a\tAlternate progress indicator\n"
520 "-h\tThis information\n"
521 "-V\tVersion information\n"
522 "\n"
523 "Report bugs to lintux@lintux.cx\n") );
524 #else
525 printf( _("Usage: axel [options] url1 [url2] [url...]\n"
526 "\n"
527 "--max-speed=x\t\t-s x\tSpecify maximum speed (bytes per second)\n"
528 "--num-connections=x\t-n x\tSpecify maximum number of connections\n"
529 "--output=f\t\t-o f\tSpecify local output file\n"
530 "--search[=x]\t\t-S [x]\tSearch for mirrors and download from x servers\n"
531 "--no-proxy\t\t-N\tJust don't use any proxy server\n"
532 "--quiet\t\t\t-q\tLeave stdout alone\n"
533 "--verbose\t\t-v\tMore status information\n"
534 "--alternate\t\t-a\tAlternate progress indicator\n"
535 "--help\t\t\t-h\tThis information\n"
536 "--version\t\t-V\tVersion information\n"
537 "\n"
538 "Report bugs to lintux@lintux.cx\n") );
539 #endif
540 }
541
542 void print_version()
543 {
544 printf( _("Axel version %s (%s)\n"), AXEL_VERSION_STRING, ARCH );
545 printf( "\nCopyright 2001-2002 Wilmer van der Gaast.\n" );
546 }
547
548 /* Print any message in the axel structure */
549 void print_messages( axel_t *axel )
550 {
551 message_t *m;
552
553 while( axel->message )
554 {
555 printf( "%s\n", axel->message->text );
556 m = axel->message;
557 axel->message = axel->message->next;
558 free( m );
559 }
560 }

  ViewVC Help
Powered by ViewVC 1.1.5