/* * cancel, remove, etc. downloads */ void xtp_handle_dl(struct tab *t, uint8_t cmd, int id) { struct download find, *d = NULL; DNPRINTF(XT_D_DOWNLOAD, "download control: cmd %d, id %d\n", cmd, id); /* some commands require a valid download id */ if (cmd != XT_XTP_DL_LIST) { /* lookup download in question */ find.id = id; d = RB_FIND(download_list, &downloads, &find); if (d == NULL) { show_oops(t, "%s: no such download", __func__); return; } } /* decide what to do */ switch (cmd) { case XT_XTP_DL_START: /* our downloads always needs to be * restarted if called from here */ download_start(t, d, XT_DL_RESTART); break; case XT_XTP_DL_CANCEL: webkit_download_cancel(d->download); g_object_unref(d->download); RB_REMOVE(download_list, &downloads, d); break; case XT_XTP_DL_UNLINK: #ifdef __MINGW32__ unlink(webkit_download_get_destination_uri(d->download)); #else unlink(webkit_download_get_destination_uri(d->download) + strlen("file://")); #endif /* FALLTHROUGH */ case XT_XTP_DL_REMOVE: webkit_download_cancel(d->download); /* just incase */ g_object_unref(d->download); RB_REMOVE(download_list, &downloads, d); break; case XT_XTP_DL_LIST: /* Nothing */ break; default: show_oops(t, "%s: unknown command", __func__); break; }; xtp_page_dl(t, NULL); }
int download( int argc, char *argv[] ) { char fn[MAX_STRING] = ""; int do_search = 0; search_t *search; conf_t conf[1]; download_t *download; int i, j, cur_head = 0; char *s; #ifdef I18N setlocale( LC_ALL, "" ); bindtextdomain( PACKAGE, LOCALE ); textdomain( PACKAGE ); #endif if( !conf_init( conf ) ) { return( 1 ); } opterr = 0; j = -1; while( 1 ) { int option; option = getopt_long( argc, argv, "s:n:o:S::NqvhVaH:U:", download_options, NULL ); if( option == -1 ) break; switch( option ) { case 'U': strncpy( conf->user_agent, optarg, MAX_STRING); break; case 'H': strncpy( conf->add_header[cur_head++], optarg, MAX_STRING ); break; case 's': if( !sscanf( optarg, "%i", &conf->max_speed ) ) { print_help(); return( 1 ); } break; case 'n': if( !sscanf( optarg, "%i", &conf->num_connections ) ) { print_help(); return( 1 ); } break; case 'o': strncpy( fn, optarg, MAX_STRING ); break; case 'S': do_search = 1; if( optarg != NULL ) if( !sscanf( optarg, "%i", &conf->search_top ) ) { print_help(); return( 1 ); } break; case 'a': conf->alternate_output = 1; break; case 'N': *conf->http_proxy = 0; break; case 'h': print_help(); return( 0 ); case 'v': if( j == -1 ) j = 1; else j ++; break; case 'V': print_version(); return( 0 ); case 'q': close( 1 ); conf->verbose = -1; if( open( "/dev/null", O_WRONLY ) != 1 ) { fprintf( stderr, _("Can't redirect stdout to /dev/null.\n") ); return( 1 ); } break; default: print_help(); return( 1 ); } } conf->add_header_count = cur_head; if( j > -1 ) conf->verbose = j; if( argc - optind == 0 ) { print_help(); return( 1 ); } else if( strcmp( argv[optind], "-" ) == 0 ) { s = (char *)malloc( MAX_STRING ); if (scanf( "%1024[^\n]s", s) != 1) { fprintf( stderr, _("Error when trying to read URL (Too long?).\n") ); return( 1 ); } } else { s = argv[optind]; if( strlen( s ) > MAX_STRING ) { fprintf( stderr, _("Can't handle URLs of length over %d\n" ), MAX_STRING ); return( 1 ); } } printf( _("Initializing download: %s\n"), s ); if( do_search ) { search = (search_t*)malloc( sizeof( search_t ) * ( conf->search_amount + 1 ) ); memset( search, 0, sizeof( search_t ) * ( conf->search_amount + 1 ) ); search[0].conf = conf; if( conf->verbose ) printf( _("Doing search...\n") ); i = search_makelist( search, s ); if( i < 0 ) { fprintf( stderr, _("File not found\n" ) ); return( 1 ); } if( conf->verbose ) printf( _("Testing speeds, this can take a while...\n") ); j = search_getspeeds( search, i ); search_sortlist( search, i ); if( conf->verbose ) { printf( _("%i usable servers found, will use these URLs:\n"), j ); j = min( j, conf->search_top ); printf( "%-60s %15s\n", "URL", "Speed" ); for( i = 0; i < j; i ++ ) printf( "%-70.70s %5i\n", search[i].url, search[i].speed ); printf( "\n" ); } download = download_new( conf, j, search ); free( search ); if( download->ready == -1 ) { print_messages( download ); download_close( download ); return( 1 ); } } else if( argc - optind == 1 ) { download = download_new( conf, 0, s ); if( download->ready == -1 ) { print_messages( download ); download_close( download ); return( 1 ); } } else { search = (search_t*)malloc( sizeof( search_t ) * ( argc - optind ) ); memset( search, 0, sizeof( search_t ) * ( argc - optind ) ); for( i = 0; i < ( argc - optind ); i ++ ) strncpy( search[i].url, argv[optind+i], MAX_STRING ); download = download_new( conf, argc - optind, search ); free( search ); if( download->ready == -1 ) { print_messages( download ); download_close( download ); return( 1 ); } } print_messages( download ); if( s != argv[optind] ) { free( s ); } if( *fn ) { struct stat buf; if( stat( fn, &buf ) == 0 ) { if( S_ISDIR( buf.st_mode ) ) { size_t fnlen = strlen(fn); size_t downloadfnlen = strlen(download->filename); if (fnlen + 1 + downloadfnlen + 1 > MAX_STRING) { fprintf( stderr, _("Filename too long!\n")); return ( 1 ); } fn[fnlen] = '/'; memcpy(fn+fnlen+1, download->filename, downloadfnlen); fn[fnlen + 1 + downloadfnlen] = '\0'; } } sprintf( string, "%s.st", fn ); if( access( fn, F_OK ) == 0 ) if( access( string, F_OK ) != 0 ) { fprintf( stderr, _("No state file, cannot resume!\n") ); return( 1 ); } if( access( string, F_OK ) == 0 ) if( access( fn, F_OK ) != 0 ) { printf( _("State file found, but no downloaded data. Starting from scratch.\n" ) ); unlink( string ); } strcpy( download->filename, fn ); } else { /* Local file existence check */ i = 0; s = download->filename + strlen( download->filename ); while( 1 ) { sprintf( string, "%s.st", download->filename ); if( access( download->filename, F_OK ) == 0 ) { if( download->conn[0].supported ) { if( access( string, F_OK ) == 0 ) break; } } else { if( access( string, F_OK ) ) break; } sprintf( s, ".%i", i ); i ++; } } if( !download_open( download ) ) { print_messages( download ); return( 1 ); } print_messages( download ); download_start( download ); print_messages( download ); if( conf->alternate_output ) { putchar('\n'); } else { if( download->bytes_done > 0 ) /* Print first dots if resuming */ { putchar( '\n' ); print_commas( download->bytes_done ); } } download->start_byte = download->bytes_done; /* Install save_state signal handler for resuming support */ //signal( SIGINT, stop ); //signal( SIGTERM, stop ); while( !download->ready && run ) { long long int prev, done; prev = download->bytes_done; download_do( download ); total = download->size; if( conf->alternate_output ) { if( !download->message && prev != download->bytes_done ) print_alternate_output( download ); } else { /* The infamous wget-like 'interface'.. ;) */ done = ( download->bytes_done / 1024 ) - ( prev / 1024 ); if( done && conf->verbose > -1 ) { for( i = 0; i < done; i ++ ) { i += ( prev / 1024 ); if( ( i % 50 ) == 0 ) { if( prev >= 1024 ) { speed= download->bytes_per_second; printf( " [%6.1fKB/s]", (double) download->bytes_per_second / 1024 ); } if( download->size < 10240000 ) percent=min( 100, 102400 * (float)i / download->size ); //printf( "\n[%3lld%%] ", min( 100, 102400 * i / download->size ) ); else percent=min( 100, (float)i / ( download->size / 102400 ) ); printf( "\n[%.2f%%] ", percent); } else if( ( i % 10 ) == 0 ) { putchar( ' ' ); } putchar( '.' ); i -= ( prev / 1024 ); show->setDownValue(percent,speed,total); } fflush( stdout ); } } if( download->message ) { if(conf->alternate_output==1) { /* clreol-simulation */ putchar( '\r' ); for( i = 0; i < 79; i++ ) /* linewidth known? */ putchar( ' ' ); putchar( '\r' ); } else { putchar( '\n' ); } print_messages( download ); if( !download->ready ) { if(conf->alternate_output!=1) print_commas( download->bytes_done ); else print_alternate_output(download); } } else if( download->ready ) { putchar( '\n' ); } } if(!run) { download_close( download ); close( 1 ); conf->verbose = -1; return( 0 ); } strcpy( string + MAX_STRING / 2, size_human( download->bytes_done - download->start_byte ) ); printf( _("\nDownloaded %s in %s. (%.2f KB/s)\n"), string + MAX_STRING / 2, time_human( gettime() - download->start_time ), (double) download->bytes_per_second / 1024 ); i = download->ready ? 0 : 2; download_close( download ); return( i ); }