Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/networking/wget.c
- Timestamp:
- Dec 20, 2016, 4:07:32 PM (7 years ago)
- Location:
- branches/3.3
- Files:
-
- 1 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/3.3/mindi-busybox/networking/wget.c
r3232 r3621 10 10 */ 11 11 12 //config:config WGET 13 //config: bool "wget" 14 //config: default y 15 //config: help 16 //config: wget is a utility for non-interactive download of files from HTTP 17 //config: and FTP servers. 18 //config: 19 //config:config FEATURE_WGET_STATUSBAR 20 //config: bool "Enable a nifty process meter (+2k)" 21 //config: default y 22 //config: depends on WGET 23 //config: help 24 //config: Enable the transfer progress bar for wget transfers. 25 //config: 26 //config:config FEATURE_WGET_AUTHENTICATION 27 //config: bool "Enable HTTP authentication" 28 //config: default y 29 //config: depends on WGET 30 //config: help 31 //config: Support authenticated HTTP transfers. 32 //config: 33 //config:config FEATURE_WGET_LONG_OPTIONS 34 //config: bool "Enable long options" 35 //config: default y 36 //config: depends on WGET && LONG_OPTS 37 //config: help 38 //config: Support long options for the wget applet. 39 //config: 40 //config:config FEATURE_WGET_TIMEOUT 41 //config: bool "Enable timeout option -T SEC" 42 //config: default y 43 //config: depends on WGET 44 //config: help 45 //config: Supports network read and connect timeouts for wget, 46 //config: so that wget will give up and timeout, through the -T 47 //config: command line option. 48 //config: 49 //config: Currently only connect and network data read timeout are 50 //config: supported (i.e., timeout is not applied to the DNS query). When 51 //config: FEATURE_WGET_LONG_OPTIONS is also enabled, the --timeout option 52 //config: will work in addition to -T. 53 //config: 54 //config:config FEATURE_WGET_OPENSSL 55 //config: bool "Try to connect to HTTPS using openssl" 56 //config: default y 57 //config: depends on WGET 58 //config: help 59 //config: Choose how wget establishes SSL connection for https:// URLs. 60 //config: 61 //config: Busybox itself contains no SSL code. wget will spawn 62 //config: a helper program to talk over HTTPS. 63 //config: 64 //config: OpenSSL has a simple SSL client for debug purposes. 65 //config: If you select "openssl" helper, wget will effectively call 66 //config: "openssl s_client -quiet -connect IP:443 2>/dev/null" 67 //config: and pipe its data through it. 68 //config: Note inconvenient API: host resolution is done twice, 69 //config: and there is no guarantee openssl's idea of IPv6 address 70 //config: format is the same as ours. 71 //config: Another problem is that s_client prints debug information 72 //config: to stderr, and it needs to be suppressed. This means 73 //config: all error messages get suppressed too. 74 //config: openssl is also a big binary, often dynamically linked 75 //config: against ~15 libraries. 76 //config: 77 //config:config FEATURE_WGET_SSL_HELPER 78 //config: bool "Try to connect to HTTPS using ssl_helper" 79 //config: default y 80 //config: depends on WGET 81 //config: help 82 //config: Choose how wget establishes SSL connection for https:// URLs. 83 //config: 84 //config: Busybox itself contains no SSL code. wget will spawn 85 //config: a helper program to talk over HTTPS. 86 //config: 87 //config: ssl_helper is a tool which can be built statically 88 //config: from busybox sources against a small embedded SSL library. 89 //config: Please see networking/ssl_helper/README. 90 //config: It does not require double host resolution and emits 91 //config: error messages to stderr. 92 //config: 93 //config: Precompiled static binary may be available at 94 //config: http://busybox.net/downloads/binaries/ 95 96 //applet:IF_WGET(APPLET(wget, BB_DIR_USR_BIN, BB_SUID_DROP)) 97 98 //kbuild:lib-$(CONFIG_WGET) += wget.o 99 12 100 //usage:#define wget_trivial_usage 13 101 //usage: IF_FEATURE_WGET_LONG_OPTIONS( … … 15 103 //usage: " [--header 'header: value'] [-Y|--proxy on/off] [-P DIR]\n" 16 104 /* Since we ignore these opts, we don't show them in --help */ 17 /* //usage: " [--no-check-certificate] [--no-cache]" */ 105 /* //usage: " [--no-check-certificate] [--no-cache] [--passive-ftp] [-t TRIES]" */ 106 /* //usage: " [-nv] [-nc] [-nH] [-np]" */ 18 107 //usage: " [-U|--user-agent AGENT]" IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..." 19 108 //usage: ) … … 39 128 #if 0 40 129 # define log_io(...) bb_error_msg(__VA_ARGS__) 130 # define SENDFMT(fp, fmt, ...) \ 131 do { \ 132 log_io("> " fmt, ##__VA_ARGS__); \ 133 fprintf(fp, fmt, ##__VA_ARGS__); \ 134 } while (0); 41 135 #else 42 136 # define log_io(...) ((void)0) 137 # define SENDFMT(fp, fmt, ...) fprintf(fp, fmt, ##__VA_ARGS__) 43 138 #endif 44 139 … … 47 142 char *allocated; 48 143 const char *path; 49 const char *user; 144 char *user; 145 const char *protocol; 50 146 char *host; 51 147 int port; 52 smallint is_ftp;53 148 }; 54 149 static const char P_FTP[] ALIGN1 = "ftp"; 150 static const char P_HTTP[] ALIGN1 = "http"; 151 #if ENABLE_FEATURE_WGET_OPENSSL || ENABLE_FEATURE_WGET_SSL_HELPER 152 static const char P_HTTPS[] ALIGN1 = "https"; 153 #endif 154 155 #if ENABLE_FEATURE_WGET_LONG_OPTIONS 156 /* User-specified headers prevent using our corresponding built-in headers. */ 157 enum { 158 HDR_HOST = (1<<0), 159 HDR_USER_AGENT = (1<<1), 160 HDR_RANGE = (1<<2), 161 HDR_AUTH = (1<<3) * ENABLE_FEATURE_WGET_AUTHENTICATION, 162 HDR_PROXY_AUTH = (1<<4) * ENABLE_FEATURE_WGET_AUTHENTICATION, 163 }; 164 static const char wget_user_headers[] ALIGN1 = 165 "Host:\0" 166 "User-Agent:\0" 167 "Range:\0" 168 # if ENABLE_FEATURE_WGET_AUTHENTICATION 169 "Authorization:\0" 170 "Proxy-Authorization:\0" 171 # endif 172 ; 173 # define USR_HEADER_HOST (G.user_headers & HDR_HOST) 174 # define USR_HEADER_USER_AGENT (G.user_headers & HDR_USER_AGENT) 175 # define USR_HEADER_RANGE (G.user_headers & HDR_RANGE) 176 # define USR_HEADER_AUTH (G.user_headers & HDR_AUTH) 177 # define USR_HEADER_PROXY_AUTH (G.user_headers & HDR_PROXY_AUTH) 178 #else /* No long options, no user-headers :( */ 179 # define USR_HEADER_HOST 0 180 # define USR_HEADER_USER_AGENT 0 181 # define USR_HEADER_RANGE 0 182 # define USR_HEADER_AUTH 0 183 # define USR_HEADER_PROXY_AUTH 0 184 #endif 55 185 56 186 /* Globals */ … … 63 193 bb_progress_t pmt; 64 194 #endif 65 195 char *dir_prefix; 66 196 #if ENABLE_FEATURE_WGET_LONG_OPTIONS 67 char *post_data; 68 char *extra_headers; 69 #endif 70 char *fname_out; /* where to direct output (-O) */ 71 const char *proxy_flag; /* Use proxies if env vars are set */ 72 const char *user_agent; /* "User-Agent" header field */ 197 char *post_data; 198 char *extra_headers; 199 unsigned char user_headers; /* Headers mentioned by the user */ 200 #endif 201 char *fname_out; /* where to direct output (-O) */ 202 const char *proxy_flag; /* Use proxies if env vars are set */ 203 const char *user_agent; /* "User-Agent" header field */ 73 204 #if ENABLE_FEATURE_WGET_TIMEOUT 74 205 unsigned timeout_seconds; 206 bool die_if_timed_out; 75 207 #endif 76 208 int output_fd; … … 87 219 #define G (*ptr_to_globals) 88 220 #define INIT_G() do { \ 89 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 90 IF_FEATURE_WGET_TIMEOUT(G.timeout_seconds = 900;) \ 221 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 222 } while (0) 223 #define FINI_G() do { \ 224 FREE_PTR_TO_GLOBALS(); \ 91 225 } while (0) 92 226 … … 196 330 } 197 331 332 #if ENABLE_FEATURE_WGET_TIMEOUT 333 static void alarm_handler(int sig UNUSED_PARAM) 334 { 335 /* This is theoretically unsafe (uses stdio and malloc in signal handler) */ 336 if (G.die_if_timed_out) 337 bb_error_msg_and_die("download timed out"); 338 } 339 static void set_alarm(void) 340 { 341 if (G.timeout_seconds) { 342 alarm(G.timeout_seconds); 343 G.die_if_timed_out = 1; 344 } 345 } 346 # define clear_alarm() ((void)(G.die_if_timed_out = 0)) 347 #else 348 # define set_alarm() ((void)0) 349 # define clear_alarm() ((void)0) 350 #endif 351 198 352 static FILE *open_socket(len_and_sockaddr *lsa) 199 353 { 354 int fd; 200 355 FILE *fp; 356 357 set_alarm(); 358 fd = xconnect_stream(lsa); 359 clear_alarm(); 201 360 202 361 /* glibc 2.4 seems to try seeking on it - ??! */ 203 362 /* hopefully it understands what ESPIPE means... */ 204 fp = fdopen( xconnect_stream(lsa), "r+");205 if ( fp == NULL)363 fp = fdopen(fd, "r+"); 364 if (!fp) 206 365 bb_perror_msg_and_die(bb_msg_memory_exhausted); 207 366 … … 215 374 char *buf_ptr; 216 375 376 set_alarm(); 217 377 if (fgets(G.wget_buf, sizeof(G.wget_buf) - 1, fp) == NULL) 218 378 bb_perror_msg_and_die("error getting response"); 379 clear_alarm(); 219 380 220 381 buf_ptr = strchrnul(G.wget_buf, '\n'); … … 257 418 h->allocated = url = xstrdup(src_url); 258 419 259 if (strncmp(url, "http://", 7) == 0) { 260 h->port = bb_lookup_port("http", "tcp", 80); 261 h->host = url + 7; 262 h->is_ftp = 0; 263 } else if (strncmp(url, "ftp://", 6) == 0) { 264 h->port = bb_lookup_port("ftp", "tcp", 21); 265 h->host = url + 6; 266 h->is_ftp = 1; 267 } else 268 bb_error_msg_and_die("not an http or ftp url: %s", sanitize_string(url)); 420 h->protocol = P_FTP; 421 p = strstr(url, "://"); 422 if (p) { 423 *p = '\0'; 424 h->host = p + 3; 425 if (strcmp(url, P_FTP) == 0) { 426 h->port = bb_lookup_port(P_FTP, "tcp", 21); 427 } else 428 #if ENABLE_FEATURE_WGET_OPENSSL || ENABLE_FEATURE_WGET_SSL_HELPER 429 if (strcmp(url, P_HTTPS) == 0) { 430 h->port = bb_lookup_port(P_HTTPS, "tcp", 443); 431 h->protocol = P_HTTPS; 432 } else 433 #endif 434 if (strcmp(url, P_HTTP) == 0) { 435 http: 436 h->port = bb_lookup_port(P_HTTP, "tcp", 80); 437 h->protocol = P_HTTP; 438 } else { 439 *p = ':'; 440 bb_error_msg_and_die("not an http or ftp url: %s", sanitize_string(url)); 441 } 442 } else { 443 // GNU wget is user-friendly and falls back to http:// 444 h->host = url; 445 goto http; 446 } 269 447 270 448 // FYI: … … 298 476 } 299 477 300 // We used to set h->user to NULL here, but this interferes301 // with handling of code 302 ("object was moved")302 303 478 sp = strrchr(h->host, '@'); 304 479 if (sp != NULL) { … … 309 484 // Standard wget and curl do this too. 310 485 *sp = '\0'; 311 h->user = percent_decode_in_place(h->host, /*strict:*/ 0); 486 free(h->user); 487 h->user = xstrdup(percent_decode_in_place(h->host, /*strict:*/ 0)); 312 488 h->host = sp + 1; 313 489 } 314 315 sp = h->host; 490 /* else: h->user remains NULL, or as set by original request 491 * before redirect (if we are here after a redirect). 492 */ 316 493 } 317 494 … … 329 506 330 507 /* convert the header name to lower case */ 331 for (s = G.wget_buf; isalnum(*s) || *s == '-' || *s == '.'; ++s) { 332 /* tolower for "A-Z", no-op for "0-9a-z-." */ 508 for (s = G.wget_buf; isalnum(*s) || *s == '-' || *s == '.' || *s == '_'; ++s) { 509 /* 510 * No-op for 20-3f and 60-7f. "0-9a-z-." are in these ranges. 511 * 40-5f range ("@A-Z[\]^_") maps to 60-7f. 512 * "A-Z" maps to "a-z". 513 * "@[\]" can't occur in header names. 514 * "^_" maps to "~,DEL" (which is wrong). 515 * "^" was never seen yet, "_" was seen from web.archive.org 516 * (x-archive-orig-x_commoncrawl_Signature: HEXSTRING). 517 */ 333 518 *s |= 0x20; 334 519 } … … 441 626 } 442 627 628 #if ENABLE_FEATURE_WGET_OPENSSL 629 static int spawn_https_helper_openssl(const char *host, unsigned port) 630 { 631 char *allocated = NULL; 632 int sp[2]; 633 int pid; 634 IF_FEATURE_WGET_SSL_HELPER(volatile int child_failed = 0;) 635 636 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) 637 /* Kernel can have AF_UNIX support disabled */ 638 bb_perror_msg_and_die("socketpair"); 639 640 if (!strchr(host, ':')) 641 host = allocated = xasprintf("%s:%u", host, port); 642 643 fflush_all(); 644 pid = xvfork(); 645 if (pid == 0) { 646 /* Child */ 647 char *argv[6]; 648 649 close(sp[0]); 650 xmove_fd(sp[1], 0); 651 xdup2(0, 1); 652 /* 653 * openssl s_client -quiet -connect www.kernel.org:443 2>/dev/null 654 * It prints some debug stuff on stderr, don't know how to suppress it. 655 * Work around by dev-nulling stderr. We lose all error messages :( 656 */ 657 xmove_fd(2, 3); 658 xopen("/dev/null", O_RDWR); 659 argv[0] = (char*)"openssl"; 660 argv[1] = (char*)"s_client"; 661 argv[2] = (char*)"-quiet"; 662 argv[3] = (char*)"-connect"; 663 argv[4] = (char*)host; 664 argv[5] = NULL; 665 BB_EXECVP(argv[0], argv); 666 xmove_fd(3, 2); 667 # if ENABLE_FEATURE_WGET_SSL_HELPER 668 child_failed = 1; 669 xfunc_die(); 670 # else 671 bb_perror_msg_and_die("can't execute '%s'", argv[0]); 672 # endif 673 /* notreached */ 674 } 675 676 /* Parent */ 677 free(allocated); 678 close(sp[1]); 679 # if ENABLE_FEATURE_WGET_SSL_HELPER 680 if (child_failed) { 681 close(sp[0]); 682 return -1; 683 } 684 # endif 685 return sp[0]; 686 } 687 #endif 688 689 /* See networking/ssl_helper/README how to build one */ 690 #if ENABLE_FEATURE_WGET_SSL_HELPER 691 static void spawn_https_helper_small(int network_fd) 692 { 693 int sp[2]; 694 int pid; 695 696 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) 697 /* Kernel can have AF_UNIX support disabled */ 698 bb_perror_msg_and_die("socketpair"); 699 700 pid = BB_MMU ? xfork() : xvfork(); 701 if (pid == 0) { 702 /* Child */ 703 char *argv[3]; 704 705 close(sp[0]); 706 xmove_fd(sp[1], 0); 707 xdup2(0, 1); 708 xmove_fd(network_fd, 3); 709 /* 710 * A simple ssl/tls helper 711 */ 712 argv[0] = (char*)"ssl_helper"; 713 argv[1] = (char*)"-d3"; 714 argv[2] = NULL; 715 BB_EXECVP(argv[0], argv); 716 bb_perror_msg_and_die("can't execute '%s'", argv[0]); 717 /* notreached */ 718 } 719 720 /* Parent */ 721 close(sp[1]); 722 xmove_fd(sp[0], network_fd); 723 } 724 #endif 725 443 726 static void NOINLINE retrieve_file_data(FILE *dfp) 444 727 { … … 509 792 second_cnt = G.timeout_seconds; 510 793 #endif 511 continue;794 goto bump; 512 795 } 513 796 … … 542 825 */ 543 826 } 827 #endif 828 bump: 544 829 /* Need to do it _every_ second for "stalled" indicator 545 830 * to be shown properly. 546 831 */ 547 832 progress_meter(PROGRESS_BUMP); 548 #endif549 833 } /* while (reading data) */ 550 834 … … 613 897 use_proxy = (strcmp(G.proxy_flag, "off") != 0); 614 898 if (use_proxy) { 615 proxy = getenv(target.is_ftp ? "ftp_proxy" : "http_proxy"); 899 proxy = getenv(target.protocol == P_FTP ? "ftp_proxy" : "http_proxy"); 900 //FIXME: what if protocol is https? Ok to use http_proxy? 616 901 use_proxy = (proxy && proxy[0]); 617 902 if (use_proxy) … … 673 958 G.got_clen = 0; 674 959 G.chunked = 0; 675 if (use_proxy || !target.is_ftp) {960 if (use_proxy || target.protocol != P_FTP) { 676 961 /* 677 962 * HTTP session … … 680 965 int status; 681 966 682 683 /* Open socket to http server */ 967 /* Open socket to http(s) server */ 968 #if ENABLE_FEATURE_WGET_OPENSSL 969 /* openssl (and maybe ssl_helper) support is configured */ 970 if (target.protocol == P_HTTPS) { 971 /* openssl-based helper 972 * Inconvenient API since we can't give it an open fd 973 */ 974 int fd = spawn_https_helper_openssl(server.host, server.port); 975 # if ENABLE_FEATURE_WGET_SSL_HELPER 976 if (fd < 0) { /* no openssl? try ssl_helper */ 977 sfp = open_socket(lsa); 978 spawn_https_helper_small(fileno(sfp)); 979 goto socket_opened; 980 } 981 # else 982 /* We don't check for exec("openssl") failure in this case */ 983 # endif 984 sfp = fdopen(fd, "r+"); 985 if (!sfp) 986 bb_perror_msg_and_die(bb_msg_memory_exhausted); 987 goto socket_opened; 988 } 684 989 sfp = open_socket(lsa); 685 990 socket_opened: 991 #elif ENABLE_FEATURE_WGET_SSL_HELPER 992 /* Only ssl_helper support is configured */ 993 sfp = open_socket(lsa); 994 if (target.protocol == P_HTTPS) 995 spawn_https_helper_small(fileno(sfp)); 996 #else 997 /* ssl (https) support is not configured */ 998 sfp = open_socket(lsa); 999 #endif 686 1000 /* Send HTTP request */ 687 1001 if (use_proxy) { 688 fprintf(sfp, "GET %stp://%s/%s HTTP/1.1\r\n",689 target. is_ftp ? "f" : "ht", target.host,1002 SENDFMT(sfp, "GET %s://%s/%s HTTP/1.1\r\n", 1003 target.protocol, target.host, 690 1004 target.path); 691 1005 } else { 692 if (option_mask32 & WGET_OPT_POST_DATA)693 fprintf(sfp, "POST /%s HTTP/1.1\r\n", target.path);694 else695 fprintf(sfp, "GET /%s HTTP/1.1\r\n", target.path);696 }697 698 fprintf(sfp, "Host: %s\r\nUser-Agent: %s\r\n",699 target.host, G.user_agent);1006 SENDFMT(sfp, "%s /%s HTTP/1.1\r\n", 1007 (option_mask32 & WGET_OPT_POST_DATA) ? "POST" : "GET", 1008 target.path); 1009 } 1010 if (!USR_HEADER_HOST) 1011 SENDFMT(sfp, "Host: %s\r\n", target.host); 1012 if (!USR_HEADER_USER_AGENT) 1013 SENDFMT(sfp, "User-Agent: %s\r\n", G.user_agent); 700 1014 701 1015 /* Ask server to close the connection as soon as we are done 702 1016 * (IOW: we do not intend to send more requests) 703 1017 */ 704 fprintf(sfp, "Connection: close\r\n");1018 SENDFMT(sfp, "Connection: close\r\n"); 705 1019 706 1020 #if ENABLE_FEATURE_WGET_AUTHENTICATION 707 if (target.user ) {708 fprintf(sfp, "Proxy-Authorization: Basic %s\r\n"+6,1021 if (target.user && !USR_HEADER_AUTH) { 1022 SENDFMT(sfp, "Proxy-Authorization: Basic %s\r\n"+6, 709 1023 base64enc(target.user)); 710 1024 } 711 if (use_proxy && server.user ) {712 fprintf(sfp, "Proxy-Authorization: Basic %s\r\n",1025 if (use_proxy && server.user && !USR_HEADER_PROXY_AUTH) { 1026 SENDFMT(sfp, "Proxy-Authorization: Basic %s\r\n", 713 1027 base64enc(server.user)); 714 1028 } 715 1029 #endif 716 1030 717 if (G.beg_range != 0 )718 fprintf(sfp, "Range: bytes=%"OFF_FMT"u-\r\n", G.beg_range);1031 if (G.beg_range != 0 && !USR_HEADER_RANGE) 1032 SENDFMT(sfp, "Range: bytes=%"OFF_FMT"u-\r\n", G.beg_range); 719 1033 720 1034 #if ENABLE_FEATURE_WGET_LONG_OPTIONS 721 if (G.extra_headers) 1035 if (G.extra_headers) { 1036 log_io(G.extra_headers); 722 1037 fputs(G.extra_headers, sfp); 1038 } 723 1039 724 1040 if (option_mask32 & WGET_OPT_POST_DATA) { 725 fprintf(sfp,1041 SENDFMT(sfp, 726 1042 "Content-Type: application/x-www-form-urlencoded\r\n" 727 1043 "Content-Length: %u\r\n" … … 733 1049 #endif 734 1050 { 735 fprintf(sfp, "\r\n");1051 SENDFMT(sfp, "\r\n"); 736 1052 } 737 1053 … … 848 1164 parse_url(str, &target); 849 1165 if (!use_proxy) { 1166 /* server.user remains untouched */ 850 1167 free(server.allocated); 851 1168 server.allocated = NULL; … … 866 1183 /* For HTTP, data is pumped over the same connection */ 867 1184 dfp = sfp; 868 869 1185 } else { 870 1186 /* … … 897 1213 free(server.allocated); 898 1214 free(target.allocated); 1215 free(server.user); 1216 free(target.user); 899 1217 free(fname_out_alloc); 900 1218 free(redirected_path); … … 915 1233 "proxy\0" Required_argument "Y" 916 1234 "user-agent\0" Required_argument "U" 917 #if ENABLE_FEATURE_WGET_TIMEOUT 918 "timeout\0" Required_argument "T" 919 #endif 1235 IF_FEATURE_WGET_TIMEOUT( 1236 "timeout\0" Required_argument "T") 920 1237 /* Ignored: */ 921 // "tries\0" Required_argument "t" 1238 IF_DESKTOP( "tries\0" Required_argument "t") 1239 "header\0" Required_argument "\xff" 1240 "post-data\0" Required_argument "\xfe" 922 1241 /* Ignored (we always use PASV): */ 923 "passive-ftp\0" No_argument "\xff" 924 "header\0" Required_argument "\xfe" 925 "post-data\0" Required_argument "\xfd" 1242 IF_DESKTOP( "passive-ftp\0" No_argument "\xf0") 926 1243 /* Ignored (we don't do ssl) */ 927 "no-check-certificate\0" No_argument "\xfc" 1244 IF_DESKTOP( "no-check-certificate\0" No_argument "\xf0") 928 1245 /* Ignored (we don't support caching) */ 929 "no-cache\0" No_argument "\xfb" 1246 IF_DESKTOP( "no-cache\0" No_argument "\xf0") 1247 IF_DESKTOP( "no-verbose\0" No_argument "\xf0") 1248 IF_DESKTOP( "no-clobber\0" No_argument "\xf0") 1249 IF_DESKTOP( "no-host-directories\0" No_argument "\xf0") 1250 IF_DESKTOP( "no-parent\0" No_argument "\xf0") 930 1251 ; 931 1252 #endif … … 937 1258 INIT_G(); 938 1259 939 IF_FEATURE_WGET_TIMEOUT(G.timeout_seconds = 900;) 1260 #if ENABLE_FEATURE_WGET_TIMEOUT 1261 G.timeout_seconds = 900; 1262 signal(SIGALRM, alarm_handler); 1263 #endif 940 1264 G.proxy_flag = "on"; /* use proxies if env vars are set */ 941 1265 G.user_agent = "Wget"; /* "User-Agent" header field */ … … 944 1268 applet_long_options = wget_longopts; 945 1269 #endif 946 opt_complementary = "-1" IF_FEATURE_WGET_TIMEOUT(":T+") IF_FEATURE_WGET_LONG_OPTIONS(":\xfe::"); 947 getopt32(argv, "csqO:P:Y:U:T:" /*ignored:*/ "t:", 948 &G.fname_out, &G.dir_prefix, 1270 opt_complementary = "-1" /* at least one URL */ 1271 IF_FEATURE_WGET_TIMEOUT(":T+") /* -T NUM */ 1272 IF_FEATURE_WGET_LONG_OPTIONS(":\xff::"); /* --header is a list */ 1273 getopt32(argv, "csqO:P:Y:U:T:" 1274 /*ignored:*/ "t:" 1275 /*ignored:*/ "n::" 1276 /* wget has exactly four -n<letter> opts, all of which we can ignore: 1277 * -nv --no-verbose: be moderately quiet (-q is full quiet) 1278 * -nc --no-clobber: abort if exists, neither download to FILE.n nor overwrite FILE 1279 * -nH --no-host-directories: wget -r http://host/ won't create host/ 1280 * -np --no-parent 1281 * "n::" above says that we accept -n[ARG]. 1282 * Specifying "n:" would be a bug: "-n ARG" would eat ARG! 1283 */ 1284 , &G.fname_out, &G.dir_prefix, 949 1285 &G.proxy_flag, &G.user_agent, 950 1286 IF_FEATURE_WGET_TIMEOUT(&G.timeout_seconds) IF_NOT_FEATURE_WGET_TIMEOUT(NULL), 951 NULL /* -t RETRIES */ 1287 NULL, /* -t RETRIES */ 1288 NULL /* -n[ARG] */ 952 1289 IF_FEATURE_WGET_LONG_OPTIONS(, &headers_llist) 953 1290 IF_FEATURE_WGET_LONG_OPTIONS(, &G.post_data) … … 957 1294 #if ENABLE_FEATURE_WGET_LONG_OPTIONS 958 1295 if (headers_llist) { 959 int size = 1;960 char * cp;1296 int size = 0; 1297 char *hdr; 961 1298 llist_t *ll = headers_llist; 962 1299 while (ll) { … … 964 1301 ll = ll->link; 965 1302 } 966 G.extra_headers = cp = xmalloc(size);1303 G.extra_headers = hdr = xmalloc(size + 1); 967 1304 while (headers_llist) { 968 cp += sprintf(cp, "%s\r\n", (char*)llist_pop(&headers_llist)); 1305 int bit; 1306 const char *words; 1307 1308 size = sprintf(hdr, "%s\r\n", 1309 (char*)llist_pop(&headers_llist)); 1310 /* a bit like index_in_substrings but don't match full key */ 1311 bit = 1; 1312 words = wget_user_headers; 1313 while (*words) { 1314 if (strstr(hdr, words) == hdr) { 1315 G.user_headers |= bit; 1316 break; 1317 } 1318 bit <<= 1; 1319 words += strlen(words) + 1; 1320 } 1321 hdr += size; 969 1322 } 970 1323 } … … 988 1341 xclose(G.output_fd); 989 1342 1343 #if ENABLE_FEATURE_CLEAN_UP && ENABLE_FEATURE_WGET_LONG_OPTIONS 1344 free(G.extra_headers); 1345 #endif 1346 FINI_G(); 1347 990 1348 return EXIT_SUCCESS; 991 1349 }
Note:
See TracChangeset
for help on using the changeset viewer.