diff options
author | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2007-04-10 09:37:29 +0000 |
---|---|---|
committer | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2007-04-10 09:37:29 +0000 |
commit | 7e8a53a33576b8ac6b5067ff88447936ad9d422f (patch) | |
tree | 3ebe0789461f69c10d24acaa5fa263718d54afff /networking/wget.c | |
parent | 3f3aa2a57dc648ade9083f3b3ad83cce8206b912 (diff) | |
download | busybox-w32-7e8a53a33576b8ac6b5067ff88447936ad9d422f.tar.gz busybox-w32-7e8a53a33576b8ac6b5067ff88447936ad9d422f.tar.bz2 busybox-w32-7e8a53a33576b8ac6b5067ff88447936ad9d422f.zip |
- add libbb function str_tolower to convert a string to lowercase.
- shrink wget a bit
Diffstat (limited to 'networking/wget.c')
-rw-r--r-- | networking/wget.c | 105 |
1 files changed, 49 insertions, 56 deletions
diff --git a/networking/wget.c b/networking/wget.c index 1da18ff77..026722afc 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -34,7 +34,7 @@ static off_t beg_range; /* Range at which continue begins */ | |||
34 | #if ENABLE_FEATURE_WGET_STATUSBAR | 34 | #if ENABLE_FEATURE_WGET_STATUSBAR |
35 | static off_t transferred; /* Number of bytes transferred so far */ | 35 | static off_t transferred; /* Number of bytes transferred so far */ |
36 | #endif | 36 | #endif |
37 | static int chunked; /* chunked transfer encoding */ | 37 | static bool chunked; /* chunked transfer encoding */ |
38 | #if ENABLE_FEATURE_WGET_STATUSBAR | 38 | #if ENABLE_FEATURE_WGET_STATUSBAR |
39 | static void progressmeter(int flag); | 39 | static void progressmeter(int flag); |
40 | static const char *curfile; /* Name of current file being transferred */ | 40 | static const char *curfile; /* Name of current file being transferred */ |
@@ -76,9 +76,7 @@ static char *safe_fgets(char *s, int size, FILE *stream) | |||
76 | } | 76 | } |
77 | 77 | ||
78 | #if ENABLE_FEATURE_WGET_AUTHENTICATION | 78 | #if ENABLE_FEATURE_WGET_AUTHENTICATION |
79 | /* | 79 | /* Base64-encode character string and return the string. */ |
80 | * Base64-encode character string and return the string. | ||
81 | */ | ||
82 | static char *base64enc(unsigned char *p, char *buf, int len) | 80 | static char *base64enc(unsigned char *p, char *buf, int len) |
83 | { | 81 | { |
84 | bb_uuencode(p, buf, len, bb_uuenc_tbl_base64); | 82 | bb_uuencode(p, buf, len, bb_uuenc_tbl_base64); |
@@ -96,7 +94,7 @@ int wget_main(int argc, char **argv) | |||
96 | int port; | 94 | int port; |
97 | int try = 5; | 95 | int try = 5; |
98 | unsigned opt; | 96 | unsigned opt; |
99 | char *s; | 97 | char *str; |
100 | char *proxy = 0; | 98 | char *proxy = 0; |
101 | char *dir_prefix = NULL; | 99 | char *dir_prefix = NULL; |
102 | #if ENABLE_FEATURE_WGET_LONG_OPTIONS | 100 | #if ENABLE_FEATURE_WGET_LONG_OPTIONS |
@@ -104,20 +102,20 @@ int wget_main(int argc, char **argv) | |||
104 | llist_t *headers_llist = NULL; | 102 | llist_t *headers_llist = NULL; |
105 | #endif | 103 | #endif |
106 | 104 | ||
107 | /* server.allocated = target.allocated = NULL; */ | ||
108 | |||
109 | FILE *sfp = NULL; /* socket to web/ftp server */ | 105 | FILE *sfp = NULL; /* socket to web/ftp server */ |
110 | FILE *dfp = NULL; /* socket to ftp server (data) */ | 106 | FILE *dfp = NULL; /* socket to ftp server (data) */ |
111 | char *fname_out = NULL; /* where to direct output (-O) */ | 107 | char *fname_out = NULL; /* where to direct output (-O) */ |
112 | int got_clen = 0; /* got content-length: from server */ | 108 | bool got_clen = 0; /* got content-length: from server */ |
113 | int output_fd = -1; | 109 | int output_fd = -1; |
114 | int use_proxy = 1; /* Use proxies if env vars are set */ | 110 | bool use_proxy = 1; /* Use proxies if env vars are set */ |
115 | const char *proxy_flag = "on"; /* Use proxies if env vars are set */ | 111 | const char *proxy_flag = "on"; /* Use proxies if env vars are set */ |
116 | const char *user_agent = "Wget";/* Content of the "User-Agent" header field */ | 112 | const char *user_agent = "Wget";/* "User-Agent" header field */ |
117 | 113 | static const char * const keywords[] = { | |
118 | /* | 114 | "content-length", "transfer-encoding", "chunked", "location", NULL |
119 | * Crack command line. | 115 | }; |
120 | */ | 116 | enum { |
117 | KEY_content_length = 1, KEY_transfer_encoding, KEY_chunked, KEY_location | ||
118 | }; | ||
121 | enum { | 119 | enum { |
122 | WGET_OPT_CONTINUE = 0x1, | 120 | WGET_OPT_CONTINUE = 0x1, |
123 | WGET_OPT_SPIDER = 0x2, | 121 | WGET_OPT_SPIDER = 0x2, |
@@ -131,7 +129,7 @@ int wget_main(int argc, char **argv) | |||
131 | }; | 129 | }; |
132 | #if ENABLE_FEATURE_WGET_LONG_OPTIONS | 130 | #if ENABLE_FEATURE_WGET_LONG_OPTIONS |
133 | static const struct option wget_long_options[] = { | 131 | static const struct option wget_long_options[] = { |
134 | // name, has_arg, flag, val | 132 | /* name, has_arg, flag, val */ |
135 | { "continue", no_argument, NULL, 'c' }, | 133 | { "continue", no_argument, NULL, 'c' }, |
136 | { "spider", no_argument, NULL, 's' }, | 134 | { "spider", no_argument, NULL, 's' }, |
137 | { "quiet", no_argument, NULL, 'q' }, | 135 | { "quiet", no_argument, NULL, 'q' }, |
@@ -145,6 +143,7 @@ int wget_main(int argc, char **argv) | |||
145 | }; | 143 | }; |
146 | applet_long_options = wget_long_options; | 144 | applet_long_options = wget_long_options; |
147 | #endif | 145 | #endif |
146 | /* server.allocated = target.allocated = NULL; */ | ||
148 | opt_complementary = "-1" USE_FEATURE_WGET_LONG_OPTIONS(":\xfe::"); | 147 | opt_complementary = "-1" USE_FEATURE_WGET_LONG_OPTIONS(":\xfe::"); |
149 | opt = getopt32(argc, argv, "csqO:P:Y:U:", | 148 | opt = getopt32(argc, argv, "csqO:P:Y:U:", |
150 | &fname_out, &dir_prefix, | 149 | &fname_out, &dir_prefix, |
@@ -152,7 +151,7 @@ int wget_main(int argc, char **argv) | |||
152 | USE_FEATURE_WGET_LONG_OPTIONS(, &headers_llist) | 151 | USE_FEATURE_WGET_LONG_OPTIONS(, &headers_llist) |
153 | ); | 152 | ); |
154 | if (strcmp(proxy_flag, "off") == 0) { | 153 | if (strcmp(proxy_flag, "off") == 0) { |
155 | /* Use the proxy if necessary. */ | 154 | /* Use the proxy if necessary */ |
156 | use_proxy = 0; | 155 | use_proxy = 0; |
157 | } | 156 | } |
158 | #if ENABLE_FEATURE_WGET_LONG_OPTIONS | 157 | #if ENABLE_FEATURE_WGET_LONG_OPTIONS |
@@ -176,9 +175,7 @@ int wget_main(int argc, char **argv) | |||
176 | server.host = target.host; | 175 | server.host = target.host; |
177 | server.port = target.port; | 176 | server.port = target.port; |
178 | 177 | ||
179 | /* | 178 | /* Use the proxy if necessary */ |
180 | * Use the proxy if necessary. | ||
181 | */ | ||
182 | if (use_proxy) { | 179 | if (use_proxy) { |
183 | proxy = getenv(target.is_ftp ? "ftp_proxy" : "http_proxy"); | 180 | proxy = getenv(target.is_ftp ? "ftp_proxy" : "http_proxy"); |
184 | if (proxy && *proxy) { | 181 | if (proxy && *proxy) { |
@@ -217,9 +214,7 @@ int wget_main(int argc, char **argv) | |||
217 | if ((opt & WGET_OPT_CONTINUE) && !fname_out) | 214 | if ((opt & WGET_OPT_CONTINUE) && !fname_out) |
218 | bb_error_msg_and_die("cannot specify continue (-c) without a filename (-O)"); */ | 215 | bb_error_msg_and_die("cannot specify continue (-c) without a filename (-O)"); */ |
219 | 216 | ||
220 | /* | 217 | /* Determine where to start transfer */ |
221 | * Determine where to start transfer. | ||
222 | */ | ||
223 | if (LONE_DASH(fname_out)) { | 218 | if (LONE_DASH(fname_out)) { |
224 | output_fd = 1; | 219 | output_fd = 1; |
225 | opt &= ~WGET_OPT_CONTINUE; | 220 | opt &= ~WGET_OPT_CONTINUE; |
@@ -253,15 +248,11 @@ int wget_main(int argc, char **argv) | |||
253 | if (!--try) | 248 | if (!--try) |
254 | bb_error_msg_and_die("too many redirections"); | 249 | bb_error_msg_and_die("too many redirections"); |
255 | 250 | ||
256 | /* | 251 | /* Open socket to http server */ |
257 | * Open socket to http server | ||
258 | */ | ||
259 | if (sfp) fclose(sfp); | 252 | if (sfp) fclose(sfp); |
260 | sfp = open_socket(lsa); | 253 | sfp = open_socket(lsa); |
261 | 254 | ||
262 | /* | 255 | /* Send HTTP request. */ |
263 | * Send HTTP request. | ||
264 | */ | ||
265 | if (use_proxy) { | 256 | if (use_proxy) { |
266 | fprintf(sfp, "GET %stp://%s/%s HTTP/1.1\r\n", | 257 | fprintf(sfp, "GET %stp://%s/%s HTTP/1.1\r\n", |
267 | target.is_ftp ? "f" : "ht", target.host, | 258 | target.is_ftp ? "f" : "ht", target.host, |
@@ -299,12 +290,12 @@ int wget_main(int argc, char **argv) | |||
299 | if (fgets(buf, sizeof(buf), sfp) == NULL) | 290 | if (fgets(buf, sizeof(buf), sfp) == NULL) |
300 | bb_error_msg_and_die("no response from server"); | 291 | bb_error_msg_and_die("no response from server"); |
301 | 292 | ||
302 | s = buf; | 293 | str = buf; |
303 | while (*s != '\0' && !isspace(*s)) ++s; | 294 | str = skip_non_whitespace(str); |
304 | s = skip_whitespace(s); | 295 | str = skip_whitespace(str); |
305 | // FIXME: no error check | 296 | // FIXME: no error check |
306 | // xatou wouldn't work: "200 OK" | 297 | // xatou wouldn't work: "200 OK" |
307 | status = atoi(s); | 298 | status = atoi(str); |
308 | switch (status) { | 299 | switch (status) { |
309 | case 0: | 300 | case 0: |
310 | case 100: | 301 | case 100: |
@@ -331,26 +322,28 @@ int wget_main(int argc, char **argv) | |||
331 | /* | 322 | /* |
332 | * Retrieve HTTP headers. | 323 | * Retrieve HTTP headers. |
333 | */ | 324 | */ |
334 | while ((s = gethdr(buf, sizeof(buf), sfp, &n)) != NULL) { | 325 | while ((str = gethdr(buf, sizeof(buf), sfp, &n)) != NULL) { |
335 | if (strcasecmp(buf, "content-length") == 0) { | 326 | /* gethdr did already convert the "FOO:" string to lowercase */ |
336 | content_len = BB_STRTOOFF(s, NULL, 10); | 327 | smalluint key = index_in_str_array(keywords, *&buf) + 1; |
328 | if (key == KEY_content_length) { | ||
329 | content_len = BB_STRTOOFF(str, NULL, 10); | ||
337 | if (errno || content_len < 0) { | 330 | if (errno || content_len < 0) { |
338 | bb_error_msg_and_die("content-length %s is garbage", s); | 331 | bb_error_msg_and_die("content-length %s is garbage", str); |
339 | } | 332 | } |
340 | got_clen = 1; | 333 | got_clen = 1; |
341 | continue; | 334 | continue; |
342 | } | 335 | } |
343 | if (strcasecmp(buf, "transfer-encoding") == 0) { | 336 | if (key == KEY_transfer_encoding) { |
344 | if (strcasecmp(s, "chunked") != 0) | 337 | if (index_in_str_array(keywords, str_tolower(str)) + 1 != KEY_chunked) |
345 | bb_error_msg_and_die("server wants to do %s transfer encoding", s); | 338 | bb_error_msg_and_die("server wants to do %s transfer encoding", str); |
346 | chunked = got_clen = 1; | 339 | chunked = got_clen = 1; |
347 | } | 340 | } |
348 | if (strcasecmp(buf, "location") == 0) { | 341 | if (key == KEY_location) { |
349 | if (s[0] == '/') | 342 | if (str[0] == '/') |
350 | /* free(target.allocated); */ | 343 | /* free(target.allocated); */ |
351 | target.path = /* target.allocated = */ xstrdup(s+1); | 344 | target.path = /* target.allocated = */ xstrdup(str+1); |
352 | else { | 345 | else { |
353 | parse_url(s, &target); | 346 | parse_url(str, &target); |
354 | if (use_proxy == 0) { | 347 | if (use_proxy == 0) { |
355 | server.host = target.host; | 348 | server.host = target.host; |
356 | server.port = target.port; | 349 | server.port = target.port; |
@@ -381,14 +374,14 @@ int wget_main(int argc, char **argv) | |||
381 | * Splitting username:password pair, | 374 | * Splitting username:password pair, |
382 | * trying to log in | 375 | * trying to log in |
383 | */ | 376 | */ |
384 | s = strchr(target.user, ':'); | 377 | str = strchr(target.user, ':'); |
385 | if (s) | 378 | if (str) |
386 | *(s++) = '\0'; | 379 | *(str++) = '\0'; |
387 | switch (ftpcmd("USER ", target.user, sfp, buf)) { | 380 | switch (ftpcmd("USER ", target.user, sfp, buf)) { |
388 | case 230: | 381 | case 230: |
389 | break; | 382 | break; |
390 | case 331: | 383 | case 331: |
391 | if (ftpcmd("PASS ", s, sfp, buf) == 230) | 384 | if (ftpcmd("PASS ", str, sfp, buf) == 230) |
392 | break; | 385 | break; |
393 | /* FALLTHRU (failed login) */ | 386 | /* FALLTHRU (failed login) */ |
394 | default: | 387 | default: |
@@ -418,15 +411,15 @@ int wget_main(int argc, char **argv) | |||
418 | // Response is "227 garbageN1,N2,N3,N4,P1,P2[)garbage] | 411 | // Response is "227 garbageN1,N2,N3,N4,P1,P2[)garbage] |
419 | // Server's IP is N1.N2.N3.N4 (we ignore it) | 412 | // Server's IP is N1.N2.N3.N4 (we ignore it) |
420 | // Server's port for data connection is P1*256+P2 | 413 | // Server's port for data connection is P1*256+P2 |
421 | s = strrchr(buf, ')'); | 414 | str = strrchr(buf, ')'); |
422 | if (s) s[0] = '\0'; | 415 | if (str) str[0] = '\0'; |
423 | s = strrchr(buf, ','); | 416 | str = strrchr(buf, ','); |
424 | if (!s) goto pasv_error; | 417 | if (!str) goto pasv_error; |
425 | port = xatou_range(s+1, 0, 255); | 418 | port = xatou_range(str+1, 0, 255); |
426 | *s = '\0'; | 419 | *str = '\0'; |
427 | s = strrchr(buf, ','); | 420 | str = strrchr(buf, ','); |
428 | if (!s) goto pasv_error; | 421 | if (!str) goto pasv_error; |
429 | port += xatou_range(s+1, 0, 255) * 256; | 422 | port += xatou_range(str+1, 0, 255) * 256; |
430 | set_nport(lsa, htons(port)); | 423 | set_nport(lsa, htons(port)); |
431 | dfp = open_socket(lsa); | 424 | dfp = open_socket(lsa); |
432 | 425 | ||