wget: xatoi's were oversealous ("200 OK" isn't a number)

This commit is contained in:
Denis Vlasenko 2006-10-15 17:05:55 +00:00
parent efeed5ed28
commit 023b57d935

View File

@ -290,33 +290,36 @@ int wget_main(int argc, char **argv)
/* /*
* Retrieve HTTP response line and check for "200" status code. * Retrieve HTTP response line and check for "200" status code.
*/ */
read_response: read_response:
if (fgets(buf, sizeof(buf), sfp) == NULL) if (fgets(buf, sizeof(buf), sfp) == NULL)
bb_error_msg_and_die("no response from server"); bb_error_msg_and_die("no response from server");
s = buf; s = buf;
while (*s != '\0' && !isspace(*s)) ++s; while (*s != '\0' && !isspace(*s)) ++s;
while (isspace(*s)) ++s; while (isspace(*s)) ++s;
switch (status = xatoi(s)) { // FIXME: no error check
case 0: // xatou wouldn't work: "200 OK"
case 100: status = atoi(s);
while (gethdr(buf, sizeof(buf), sfp, &n) != NULL) switch (status) {
/* eat all remaining headers */; case 0:
goto read_response; case 100:
case 200: while (gethdr(buf, sizeof(buf), sfp, &n) != NULL)
/* eat all remaining headers */;
goto read_response;
case 200:
break;
case 300: /* redirection */
case 301:
case 302:
case 303:
break;
case 206:
if (beg_range)
break; break;
case 300: /* redirection */ /*FALLTHRU*/
case 301: default:
case 302: chomp(buf);
case 303: bb_error_msg_and_die("server returned error %s: %s", s, buf);
break;
case 206:
if (beg_range)
break;
/*FALLTHRU*/
default:
chomp(buf);
bb_error_msg_and_die("server returned error %s: %s", s, buf);
} }
/* /*
@ -331,11 +334,9 @@ read_response:
continue; continue;
} }
if (strcasecmp(buf, "transfer-encoding") == 0) { if (strcasecmp(buf, "transfer-encoding") == 0) {
if (strcasecmp(s, "chunked") == 0) { if (strcasecmp(s, "chunked") != 0)
chunked = got_clen = 1;
} else {
bb_error_msg_and_die("server wants to do %s transfer encoding", s); bb_error_msg_and_die("server wants to do %s transfer encoding", s);
} chunked = got_clen = 1;
} }
if (strcasecmp(buf, "location") == 0) { if (strcasecmp(buf, "location") == 0) {
if (s[0] == '/') if (s[0] == '/')
@ -377,14 +378,14 @@ read_response:
if (s) if (s)
*(s++) = '\0'; *(s++) = '\0';
switch (ftpcmd("USER ", target.user, sfp, buf)) { switch (ftpcmd("USER ", target.user, sfp, buf)) {
case 230: case 230:
break;
case 331:
if (ftpcmd("PASS ", s, sfp, buf) == 230)
break; break;
case 331: /* FALLTHRU (failed login) */
if (ftpcmd("PASS ", s, sfp, buf) == 230) default:
break; bb_error_msg_and_die("ftp login: %s", buf+4);
/* FALLTHRU (failed login) */
default:
bb_error_msg_and_die("ftp login: %s", buf+4);
} }
ftpcmd("TYPE I", NULL, sfp, buf); ftpcmd("TYPE I", NULL, sfp, buf);
@ -402,12 +403,19 @@ read_response:
/* /*
* Entering passive mode * Entering passive mode
*/ */
if (ftpcmd("PASV", NULL, sfp, buf) != 227) if (ftpcmd("PASV", NULL, sfp, buf) != 227) {
bb_error_msg_and_die("PASV: %s", buf+4); pasv_error:
bb_error_msg_and_die("bad response to %s: %s", "PASV", buf);
}
// Response is "227 garbageN1,N2,N3,N4,P1,P2
// Server's IP is N1.N2.N3.N4 (we ignore it)
// Server's port for data connection is P1*256+P2
s = strrchr(buf, ','); s = strrchr(buf, ',');
*s = 0; if (!s) goto pasv_error;
port = xatol_range(s+1, 0, 255); port = xatol_range(s+1, 0, 255);
*s = '\0';
s = strrchr(buf, ','); s = strrchr(buf, ',');
if (!s) goto pasv_error;
port += xatol_range(s+1, 0, 255) * 256; port += xatol_range(s+1, 0, 255) * 256;
s_in.sin_port = htons(port); s_in.sin_port = htons(port);
dfp = open_socket(&s_in); dfp = open_socket(&s_in);
@ -419,7 +427,7 @@ read_response:
} }
if (ftpcmd("RETR ", target.path, sfp, buf) > 150) if (ftpcmd("RETR ", target.path, sfp, buf) > 150)
bb_error_msg_and_die("RETR: %s", buf+4); bb_error_msg_and_die("bad response to %s: %s", "RETR", buf);
} }
@ -510,7 +518,7 @@ static void parse_url(char *src_url, struct host_info *h)
// and saves 'index.html?var=a%2Fb' (we save 'b') // and saves 'index.html?var=a%2Fb' (we save 'b')
// wget 'http://busybox.net?login=john@doe': // wget 'http://busybox.net?login=john@doe':
// request: 'GET /?login=john@doe HTTP/1.0' // request: 'GET /?login=john@doe HTTP/1.0'
// saves: 'index.html?login=john@doe' (we save ?login=john@doe) // saves: 'index.html?login=john@doe' (we save '?login=john@doe')
// wget 'http://busybox.net#test/test': // wget 'http://busybox.net#test/test':
// request: 'GET / HTTP/1.0' // request: 'GET / HTTP/1.0'
// saves: 'index.html' (we save 'test') // saves: 'index.html' (we save 'test')
@ -628,8 +636,9 @@ static char *gethdr(char *buf, size_t bufsiz, FILE *fp, int *istrunc)
static int ftpcmd(char *s1, char *s2, FILE *fp, char *buf) static int ftpcmd(char *s1, char *s2, FILE *fp, char *buf)
{ {
int result;
if (s1) { if (s1) {
if (!s2) s2=""; if (!s2) s2 = "";
fprintf(fp, "%s%s\r\n", s1, s2); fprintf(fp, "%s%s\r\n", s1, s2);
fflush(fp); fflush(fp);
} }
@ -638,7 +647,7 @@ static int ftpcmd(char *s1, char *s2, FILE *fp, char *buf)
char *buf_ptr; char *buf_ptr;
if (fgets(buf, 510, fp) == NULL) { if (fgets(buf, 510, fp) == NULL) {
bb_perror_msg_and_die("fgets"); bb_perror_msg_and_die("error getting response");
} }
buf_ptr = strstr(buf, "\r\n"); buf_ptr = strstr(buf, "\r\n");
if (buf_ptr) { if (buf_ptr) {
@ -646,7 +655,10 @@ static int ftpcmd(char *s1, char *s2, FILE *fp, char *buf)
} }
} while (!isdigit(buf[0]) || buf[3] != ' '); } while (!isdigit(buf[0]) || buf[3] != ' ');
return xatoi(buf); buf[3] = '\0';
result = xatoi_u(buf);
buf[3] = ' ';
return result;
} }
#ifdef CONFIG_FEATURE_WGET_STATUSBAR #ifdef CONFIG_FEATURE_WGET_STATUSBAR