/[axel]/branches/2.x/text.c
ViewVC logotype

Contents of /branches/2.x/text.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 20 - (hide annotations) (download)
Thu Jan 17 13:14:01 2008 UTC (5 years, 4 months ago) by appaji-guest
Original Path: trunk/text.c
File MIME type: text/plain
File size: 12935 byte(s)
Correct Wilmer's Email ID and change bug reporting location
1 appaji-guest 2 /********************************************************************\
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 appaji-guest 7 scanf( "%1024[^\n]s", s );
168 appaji-guest 2 }
169     else
170     {
171     s = argv[optind];
172 appaji-guest 7 if( strlen( s ) > MAX_STRING )
173     {
174     fprintf( stderr, _("Can't handle URLs of length over %d\n" ), MAX_STRING );
175     return( 1 );
176     }
177 appaji-guest 2 }
178    
179     printf( _("Initializing download: %s\n"), s );
180     if( do_search )
181     {
182     search = malloc( sizeof( search_t ) * ( conf->search_amount + 1 ) );
183     memset( search, 0, sizeof( search_t ) * ( conf->search_amount + 1 ) );
184     search[0].conf = conf;
185     if( conf->verbose )
186     printf( _("Doing search...\n") );
187     i = search_makelist( search, s );
188     if( i < 0 )
189     {
190     fprintf( stderr, _("File not found\n" ) );
191     return( 1 );
192     }
193     if( conf->verbose )
194     printf( _("Testing speeds, this can take a while...\n") );
195     j = search_getspeeds( search, i );
196     search_sortlist( search, i );
197     if( conf->verbose )
198     {
199     printf( _("%i usable servers found, will use these URLs:\n"), j );
200     j = min( j, conf->search_top );
201     printf( "%-60s %15s\n", "URL", "Speed" );
202     for( i = 0; i < j; i ++ )
203     printf( "%-70.70s %5i\n", search[i].url, search[i].speed );
204     printf( "\n" );
205     }
206     axel = axel_new( conf, j, search );
207     free( search );
208     if( axel->ready == -1 )
209     {
210     print_messages( axel );
211     axel_close( axel );
212     return( 1 );
213     }
214     }
215     else if( argc - optind == 1 )
216     {
217     axel = axel_new( conf, 0, s );
218     if( axel->ready == -1 )
219     {
220     print_messages( axel );
221     axel_close( axel );
222     return( 1 );
223     }
224     }
225     else
226     {
227     search = malloc( sizeof( search_t ) * ( argc - optind ) );
228     memset( search, 0, sizeof( search_t ) * ( argc - optind ) );
229     for( i = 0; i < ( argc - optind ); i ++ )
230     strncpy( search[i].url, argv[optind+i], MAX_STRING );
231     axel = axel_new( conf, argc - optind, search );
232     free( search );
233     if( axel->ready == -1 )
234     {
235     print_messages( axel );
236     axel_close( axel );
237     return( 1 );
238     }
239     }
240     print_messages( axel );
241     if( s != argv[optind] )
242     {
243     free( s );
244     }
245    
246     if( *fn )
247     {
248     struct stat buf;
249    
250     if( stat( fn, &buf ) == 0 )
251     {
252     if( S_ISDIR( buf.st_mode ) )
253     {
254     strncat( fn, "/", MAX_STRING );
255     strncat( fn, axel->filename, MAX_STRING );
256     }
257     }
258     sprintf( string, "%s.st", fn );
259     if( access( fn, F_OK ) == 0 ) if( access( string, F_OK ) != 0 )
260     {
261     fprintf( stderr, _("No state file, cannot resume!\n") );
262     return( 1 );
263     }
264     if( access( string, F_OK ) == 0 ) if( access( fn, F_OK ) != 0 )
265     {
266     printf( _("State file found, but no downloaded data. Starting from scratch.\n" ) );
267     unlink( string );
268     }
269     strcpy( axel->filename, fn );
270     }
271     else
272     {
273     /* Local file existence check */
274     i = 0;
275     s = axel->filename + strlen( axel->filename );
276     while( 1 )
277     {
278     sprintf( string, "%s.st", axel->filename );
279     if( access( axel->filename, F_OK ) == 0 )
280     {
281     if( axel->conn[0].supported )
282     {
283     if( access( string, F_OK ) == 0 )
284     break;
285     }
286     }
287     else
288     {
289     if( access( string, F_OK ) )
290     break;
291     }
292     sprintf( s, ".%i", i );
293     i ++;
294     }
295     }
296    
297     if( !axel_open( axel ) )
298     {
299     print_messages( axel );
300     return( 1 );
301     }
302     print_messages( axel );
303     axel_start( axel );
304     print_messages( axel );
305    
306     if( conf->alternate_output )
307     {
308     putchar('\n');
309     }
310     else
311     {
312     if( axel->bytes_done > 0 ) /* Print first dots if resuming */
313     {
314     putchar( '\n' );
315     print_commas( axel->bytes_done );
316     }
317     }
318     axel->start_byte = axel->bytes_done;
319    
320     /* Install save_state signal handler for resuming support */
321     signal( SIGINT, stop );
322     signal( SIGTERM, stop );
323    
324     while( !axel->ready && run )
325     {
326     int prev, done;
327    
328     prev = axel->bytes_done;
329     axel_do( axel );
330    
331     if( conf->alternate_output )
332     {
333     if( !axel->message && prev != axel->bytes_done )
334     print_alternate_output( axel );
335     }
336     else
337     {
338     /* The infamous wget-like 'interface'.. ;) */
339     done = ( axel->bytes_done / 1024 ) - ( prev / 1024 );
340     if( done && conf->verbose > -1 )
341     {
342     for( i = 0; i < done; i ++ )
343     {
344     i += ( prev / 1024 );
345     if( ( i % 50 ) == 0 )
346     {
347     if( prev >= 1024 )
348     printf( " [%6.1fKB/s]", (double) axel->bytes_per_second / 1024 );
349     if( axel->size < 10240000 )
350     printf( "\n[%3i%%] ", min( 100, 102400 * i / axel->size ) );
351     else
352     printf( "\n[%3i%%] ", min( 100, i / ( axel->size / 102400 ) ) );
353     }
354     else if( ( i % 10 ) == 0 )
355     {
356     putchar( ' ' );
357     }
358     putchar( '.' );
359     i -= ( prev / 1024 );
360     }
361     fflush( stdout );
362     }
363     }
364    
365     if( axel->message )
366     {
367     if(conf->alternate_output==1)
368     {
369     /* clreol-simulation */
370     putchar( '\r' );
371     for( i = 0; i < 79; i++ ) /* linewidth known? */
372     putchar( ' ' );
373     putchar( '\r' );
374     }
375     else
376     {
377     putchar( '\n' );
378     }
379     print_messages( axel );
380     if( !axel->ready )
381     {
382     if(conf->alternate_output!=1)
383     print_commas( axel->bytes_done );
384     else
385     print_alternate_output(axel);
386     }
387     }
388     else if( axel->ready )
389     {
390     putchar( '\n' );
391     }
392     }
393    
394     strcpy( string + MAX_STRING / 2,
395     size_human( axel->bytes_done - axel->start_byte ) );
396    
397     printf( _("\nDownloaded %s in %s. (%.2f KB/s)\n"),
398     string + MAX_STRING / 2,
399     time_human( gettime() - axel->start_time ),
400     (double) axel->bytes_per_second / 1024 );
401    
402     i = axel->ready ? 0 : 2;
403    
404     axel_close( axel );
405    
406     return( i );
407     }
408    
409     /* SIGINT/SIGTERM handler */
410     void stop( int signal )
411     {
412     run = 0;
413     }
414    
415     /* Convert a number of bytes to a human-readable form */
416     char *size_human( int value )
417     {
418     if( value == 1 )
419     sprintf( string, _("%i byte"), value );
420     else if( value < 1024 )
421     sprintf( string, _("%i bytes"), value );
422     else if( value < 10485760 )
423     sprintf( string, _("%.1f kilobytes"), (float) value / 1024 );
424     else
425     sprintf( string, _("%.1f megabytes"), (float) value / 1048576 );
426    
427     return( string );
428     }
429    
430     /* Convert a number of seconds to a human-readable form */
431     char *time_human( int value )
432     {
433     if( value == 1 )
434     sprintf( string, _("%i second"), value );
435     else if( value < 60 )
436     sprintf( string, _("%i seconds"), value );
437     else if( value < 3600 )
438     sprintf( string, _("%i:%02i seconds"), value / 60, value % 60 );
439     else
440     sprintf( string, _("%i:%02i:%02i seconds"), value / 3600, ( value / 60 ) % 60, value % 60 );
441    
442     return( string );
443     }
444    
445     /* Part of the infamous wget-like interface. Just put it in a function
446     because I need it quite often.. */
447     void print_commas( int bytes_done )
448     {
449     int i, j;
450    
451     printf( " " );
452     j = ( bytes_done / 1024 ) % 50;
453     if( j == 0 ) j = 50;
454     for( i = 0; i < j; i ++ )
455     {
456     if( ( i % 10 ) == 0 )
457     putchar( ' ' );
458     putchar( ',' );
459     }
460     fflush( stdout );
461     }
462    
463     static void print_alternate_output(axel_t *axel)
464     {
465     int done=axel->bytes_done;
466     int total=axel->size;
467     int i,j=0;
468     double now = gettime();
469    
470     printf("\r[%3ld%%] [", min(100,(long)(done*100./total+.5) ) );
471    
472     for(i=0;i<axel->conf->num_connections;i++)
473     {
474     for(;j<((double)axel->conn[i].currentbyte/(total+1)*50)-1;j++)
475     putchar('.');
476    
477     if(axel->conn[i].currentbyte<axel->conn[i].lastbyte)
478     {
479     if(now <= axel->conn[i].last_transfer + axel->conf->connection_timeout/2 )
480     putchar(i+'0');
481     else
482     putchar('#');
483     } else
484     putchar('.');
485    
486     j++;
487    
488     for(;j<((double)axel->conn[i].lastbyte/(total+1)*50);j++)
489     putchar(' ');
490     }
491    
492     printf( "] [%6.1fKB/s]", (double) axel->bytes_per_second / 1024 );
493    
494     if(done<total)
495     {
496     int seconds,minutes,hours,days;
497     seconds=axel->finish_time - now;
498     minutes=seconds/60;seconds-=minutes*60;
499     hours=minutes/60;minutes-=hours*60;
500     days=hours/24;hours-=days*24;
501     if(days)
502     printf(" [%2dd%2d]",days,hours);
503     else if(hours)
504     printf(" [%2dh%02d]",hours,minutes);
505     else
506     printf(" [%02d:%02d]",minutes,seconds);
507     }
508    
509     fflush( stdout );
510     }
511    
512     void print_help()
513     {
514     #ifdef NOGETOPTLONG
515     printf( _("Usage: axel [options] url1 [url2] [url...]\n"
516     "\n"
517     "-s x\tSpecify maximum speed (bytes per second)\n"
518     "-n x\tSpecify maximum number of connections\n"
519     "-o f\tSpecify local output file\n"
520     "-S [x]\tSearch for mirrors and download from x servers\n"
521     "-N\tJust don't use any proxy server\n"
522     "-q\tLeave stdout alone\n"
523     "-v\tMore status information\n"
524     "-a\tAlternate progress indicator\n"
525     "-h\tThis information\n"
526     "-V\tVersion information\n"
527     "\n"
528 appaji-guest 20 "Visit http://axel.alioth.debian.org/ to report bugs\n") );
529 appaji-guest 2 #else
530     printf( _("Usage: axel [options] url1 [url2] [url...]\n"
531     "\n"
532     "--max-speed=x\t\t-s x\tSpecify maximum speed (bytes per second)\n"
533     "--num-connections=x\t-n x\tSpecify maximum number of connections\n"
534     "--output=f\t\t-o f\tSpecify local output file\n"
535     "--search[=x]\t\t-S [x]\tSearch for mirrors and download from x servers\n"
536     "--no-proxy\t\t-N\tJust don't use any proxy server\n"
537     "--quiet\t\t\t-q\tLeave stdout alone\n"
538     "--verbose\t\t-v\tMore status information\n"
539     "--alternate\t\t-a\tAlternate progress indicator\n"
540     "--help\t\t\t-h\tThis information\n"
541     "--version\t\t-V\tVersion information\n"
542     "\n"
543 appaji-guest 20 "Visit http://axel.alioth.debian.org/ to report bugs\n") );
544 appaji-guest 2 #endif
545     }
546    
547     void print_version()
548     {
549     printf( _("Axel version %s (%s)\n"), AXEL_VERSION_STRING, ARCH );
550     printf( "\nCopyright 2001-2002 Wilmer van der Gaast.\n" );
551     }
552    
553     /* Print any message in the axel structure */
554     void print_messages( axel_t *axel )
555     {
556     message_t *m;
557    
558     while( axel->message )
559     {
560     printf( "%s\n", axel->message->text );
561     m = axel->message;
562     axel->message = axel->message->next;
563     free( m );
564     }
565     }

  ViewVC Help
Powered by ViewVC 1.1.5