aboutsummaryrefslogtreecommitdiff
path: root/networking/wget.c
diff options
context:
space:
mode:
authorBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2007-04-10 09:37:29 +0000
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2007-04-10 09:37:29 +0000
commit7e8a53a33576b8ac6b5067ff88447936ad9d422f (patch)
tree3ebe0789461f69c10d24acaa5fa263718d54afff /networking/wget.c
parent3f3aa2a57dc648ade9083f3b3ad83cce8206b912 (diff)
downloadbusybox-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.c105
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
35static off_t transferred; /* Number of bytes transferred so far */ 35static off_t transferred; /* Number of bytes transferred so far */
36#endif 36#endif
37static int chunked; /* chunked transfer encoding */ 37static bool chunked; /* chunked transfer encoding */
38#if ENABLE_FEATURE_WGET_STATUSBAR 38#if ENABLE_FEATURE_WGET_STATUSBAR
39static void progressmeter(int flag); 39static void progressmeter(int flag);
40static const char *curfile; /* Name of current file being transferred */ 40static 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 */
82static char *base64enc(unsigned char *p, char *buf, int len) 80static 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