wget: check for close success; fix chunked; do not bother to send QUIT to ftp
Also, random fixes to use %u for unsigned quantities. -14 bytes in wget. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
4662de0511
commit
a3aa3e3095
@ -336,7 +336,7 @@ static int writeTarHeader(struct TarBallInfo *tbInfo,
|
|||||||
&& statbuf->st_size > (off_t)0777777777777LL
|
&& statbuf->st_size > (off_t)0777777777777LL
|
||||||
) {
|
) {
|
||||||
bb_error_msg_and_die("can't store file '%s' "
|
bb_error_msg_and_die("can't store file '%s' "
|
||||||
"of size %"OFF_FMT"d, aborting",
|
"of size %"OFF_FMT"u, aborting",
|
||||||
fileName, statbuf->st_size);
|
fileName, statbuf->st_size);
|
||||||
}
|
}
|
||||||
header.typeflag = REGTYPE;
|
header.typeflag = REGTYPE;
|
||||||
|
@ -24,9 +24,9 @@
|
|||||||
#include "libbb.h"
|
#include "libbb.h"
|
||||||
|
|
||||||
static const char fmt_eof[] ALIGN1 = "cmp: EOF on %s\n";
|
static const char fmt_eof[] ALIGN1 = "cmp: EOF on %s\n";
|
||||||
static const char fmt_differ[] ALIGN1 = "%s %s differ: char %"OFF_FMT"d, line %d\n";
|
static const char fmt_differ[] ALIGN1 = "%s %s differ: char %"OFF_FMT"u, line %u\n";
|
||||||
// This fmt_l_opt uses gnu-isms. SUSv3 would be "%.0s%.0s%"OFF_FMT"d %o %o\n"
|
// This fmt_l_opt uses gnu-isms. SUSv3 would be "%.0s%.0s%"OFF_FMT"u %o %o\n"
|
||||||
static const char fmt_l_opt[] ALIGN1 = "%.0s%.0s%"OFF_FMT"d %3o %3o\n";
|
static const char fmt_l_opt[] ALIGN1 = "%.0s%.0s%"OFF_FMT"u %3o %3o\n";
|
||||||
|
|
||||||
static const char opt_chars[] ALIGN1 = "sl";
|
static const char opt_chars[] ALIGN1 = "sl";
|
||||||
#define CMP_OPT_s (1<<0)
|
#define CMP_OPT_s (1<<0)
|
||||||
|
@ -212,7 +212,7 @@ int ftp_receive(const char *local_path, char *server_path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (do_continue) {
|
if (do_continue) {
|
||||||
sprintf(buf, "REST %"OFF_FMT"d", beg_range);
|
sprintf(buf, "REST %"OFF_FMT"u", beg_range);
|
||||||
if (ftpcmd(buf, NULL) != 350) {
|
if (ftpcmd(buf, NULL) != 350) {
|
||||||
do_continue = 0;
|
do_continue = 0;
|
||||||
}
|
}
|
||||||
|
@ -1021,7 +1021,7 @@ static void send_headers(int responseNum)
|
|||||||
strftime(tmp_str, sizeof(tmp_str), RFC1123FMT, gmtime(&last_mod));
|
strftime(tmp_str, sizeof(tmp_str), RFC1123FMT, gmtime(&last_mod));
|
||||||
#if ENABLE_FEATURE_HTTPD_RANGES
|
#if ENABLE_FEATURE_HTTPD_RANGES
|
||||||
if (responseNum == HTTP_PARTIAL_CONTENT) {
|
if (responseNum == HTTP_PARTIAL_CONTENT) {
|
||||||
len += sprintf(iobuf + len, "Content-Range: bytes %"OFF_FMT"d-%"OFF_FMT"d/%"OFF_FMT"d\r\n",
|
len += sprintf(iobuf + len, "Content-Range: bytes %"OFF_FMT"u-%"OFF_FMT"u/%"OFF_FMT"u\r\n",
|
||||||
range_start,
|
range_start,
|
||||||
range_end,
|
range_end,
|
||||||
file_size);
|
file_size);
|
||||||
@ -1032,7 +1032,7 @@ static void send_headers(int responseNum)
|
|||||||
#if ENABLE_FEATURE_HTTPD_RANGES
|
#if ENABLE_FEATURE_HTTPD_RANGES
|
||||||
"Accept-Ranges: bytes\r\n"
|
"Accept-Ranges: bytes\r\n"
|
||||||
#endif
|
#endif
|
||||||
"Last-Modified: %s\r\n%s %"OFF_FMT"d\r\n",
|
"Last-Modified: %s\r\n%s %"OFF_FMT"u\r\n",
|
||||||
tmp_str,
|
tmp_str,
|
||||||
"Content-length:",
|
"Content-length:",
|
||||||
file_size
|
file_size
|
||||||
|
@ -35,10 +35,6 @@ struct globals {
|
|||||||
struct BUG_G_too_big {
|
struct BUG_G_too_big {
|
||||||
char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1];
|
char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1];
|
||||||
};
|
};
|
||||||
#define content_len (G.content_len )
|
|
||||||
#define beg_range (G.beg_range )
|
|
||||||
#define transferred (G.transferred )
|
|
||||||
#define curfile (G.curfile )
|
|
||||||
#define INIT_G() do { } while (0)
|
#define INIT_G() do { } while (0)
|
||||||
|
|
||||||
|
|
||||||
@ -53,14 +49,14 @@ static void progress_meter(int flag)
|
|||||||
bb_progress_init(&G.pmt);
|
bb_progress_init(&G.pmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
bb_progress_update(&G.pmt, curfile, beg_range, transferred,
|
bb_progress_update(&G.pmt, G.curfile, G.beg_range, G.transferred,
|
||||||
G.chunked ? 0 : content_len + beg_range);
|
G.chunked ? 0 : G.content_len + G.beg_range);
|
||||||
|
|
||||||
if (flag == 0) {
|
if (flag == 0) {
|
||||||
/* last call to progress_meter */
|
/* last call to progress_meter */
|
||||||
alarm(0);
|
alarm(0);
|
||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
transferred = 0;
|
G.transferred = 0;
|
||||||
} else {
|
} else {
|
||||||
if (flag == -1) { /* first call to progress_meter */
|
if (flag == -1) { /* first call to progress_meter */
|
||||||
signal_SA_RESTART_empty_mask(SIGALRM, progress_meter);
|
signal_SA_RESTART_empty_mask(SIGALRM, progress_meter);
|
||||||
@ -390,8 +386,8 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_
|
|||||||
* Querying file size
|
* Querying file size
|
||||||
*/
|
*/
|
||||||
if (ftpcmd("SIZE ", target->path, sfp, buf) == 213) {
|
if (ftpcmd("SIZE ", target->path, sfp, buf) == 213) {
|
||||||
content_len = BB_STRTOOFF(buf+4, NULL, 10);
|
G.content_len = BB_STRTOOFF(buf+4, NULL, 10);
|
||||||
if (errno || content_len < 0) {
|
if (G.content_len < 0 || errno) {
|
||||||
bb_error_msg_and_die("SIZE value is garbage");
|
bb_error_msg_and_die("SIZE value is garbage");
|
||||||
}
|
}
|
||||||
G.got_clen = 1;
|
G.got_clen = 1;
|
||||||
@ -420,10 +416,10 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_
|
|||||||
|
|
||||||
*dfpp = open_socket(lsa);
|
*dfpp = open_socket(lsa);
|
||||||
|
|
||||||
if (beg_range) {
|
if (G.beg_range) {
|
||||||
sprintf(buf, "REST %"OFF_FMT"d", beg_range);
|
sprintf(buf, "REST %"OFF_FMT"u", G.beg_range);
|
||||||
if (ftpcmd(buf, NULL, sfp, buf) == 350)
|
if (ftpcmd(buf, NULL, sfp, buf) == 350)
|
||||||
content_len -= beg_range;
|
G.content_len -= G.beg_range;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ftpcmd("RETR ", target->path, sfp, buf) > 150)
|
if (ftpcmd("RETR ", target->path, sfp, buf) > 150)
|
||||||
@ -460,12 +456,18 @@ static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd)
|
|||||||
|
|
||||||
/* Loops only if chunked */
|
/* Loops only if chunked */
|
||||||
while (1) {
|
while (1) {
|
||||||
while (content_len > 0 || !G.got_clen) {
|
while (1) {
|
||||||
int n;
|
int n;
|
||||||
unsigned rdsz = sizeof(buf);
|
unsigned rdsz;
|
||||||
|
|
||||||
if (content_len < sizeof(buf) && (G.chunked || G.got_clen))
|
rdsz = sizeof(buf);
|
||||||
rdsz = (unsigned)content_len;
|
if (G.got_clen) {
|
||||||
|
if (G.content_len < sizeof(buf)) {
|
||||||
|
if ((int)G.content_len <= 0)
|
||||||
|
break;
|
||||||
|
rdsz = (unsigned)G.content_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
n = safe_fread(buf, rdsz, dfp);
|
n = safe_fread(buf, rdsz, dfp);
|
||||||
if (n <= 0) {
|
if (n <= 0) {
|
||||||
if (ferror(dfp)) {
|
if (ferror(dfp)) {
|
||||||
@ -476,10 +478,10 @@ static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd)
|
|||||||
}
|
}
|
||||||
xwrite(output_fd, buf, n);
|
xwrite(output_fd, buf, n);
|
||||||
#if ENABLE_FEATURE_WGET_STATUSBAR
|
#if ENABLE_FEATURE_WGET_STATUSBAR
|
||||||
transferred += n;
|
G.transferred += n;
|
||||||
#endif
|
#endif
|
||||||
if (G.got_clen)
|
if (G.got_clen)
|
||||||
content_len -= n;
|
G.content_len -= n;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!G.chunked)
|
if (!G.chunked)
|
||||||
@ -488,10 +490,11 @@ static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd)
|
|||||||
safe_fgets(buf, sizeof(buf), dfp); /* This is a newline */
|
safe_fgets(buf, sizeof(buf), dfp); /* This is a newline */
|
||||||
get_clen:
|
get_clen:
|
||||||
safe_fgets(buf, sizeof(buf), dfp);
|
safe_fgets(buf, sizeof(buf), dfp);
|
||||||
content_len = STRTOOFF(buf, NULL, 16);
|
G.content_len = STRTOOFF(buf, NULL, 16);
|
||||||
/* FIXME: error check? */
|
/* FIXME: error check? */
|
||||||
if (content_len == 0)
|
if (G.content_len == 0)
|
||||||
break; /* all done! */
|
break; /* all done! */
|
||||||
|
G.got_clen = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(option_mask32 & WGET_OPT_QUIET))
|
if (!(option_mask32 & WGET_OPT_QUIET))
|
||||||
@ -621,7 +624,7 @@ int wget_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if ENABLE_FEATURE_WGET_STATUSBAR
|
#if ENABLE_FEATURE_WGET_STATUSBAR
|
||||||
curfile = bb_get_last_path_component_nostrip(fname_out);
|
G.curfile = bb_get_last_path_component_nostrip(fname_out);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Impossible?
|
/* Impossible?
|
||||||
@ -633,7 +636,7 @@ int wget_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
if (opt & WGET_OPT_CONTINUE) {
|
if (opt & WGET_OPT_CONTINUE) {
|
||||||
output_fd = open(fname_out, O_WRONLY);
|
output_fd = open(fname_out, O_WRONLY);
|
||||||
if (output_fd >= 0) {
|
if (output_fd >= 0) {
|
||||||
beg_range = xlseek(output_fd, 0, SEEK_END);
|
G.beg_range = xlseek(output_fd, 0, SEEK_END);
|
||||||
}
|
}
|
||||||
/* File doesn't exist. We do not create file here yet.
|
/* File doesn't exist. We do not create file here yet.
|
||||||
* We are not sure it exists on remove side */
|
* We are not sure it exists on remove side */
|
||||||
@ -684,8 +687,8 @@ int wget_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (beg_range)
|
if (G.beg_range)
|
||||||
fprintf(sfp, "Range: bytes=%"OFF_FMT"d-\r\n", beg_range);
|
fprintf(sfp, "Range: bytes=%"OFF_FMT"u-\r\n", G.beg_range);
|
||||||
#if ENABLE_FEATURE_WGET_LONG_OPTIONS
|
#if ENABLE_FEATURE_WGET_LONG_OPTIONS
|
||||||
if (extra_headers)
|
if (extra_headers)
|
||||||
fputs(extra_headers, sfp);
|
fputs(extra_headers, sfp);
|
||||||
@ -756,7 +759,7 @@ However, in real world it was observed that some web servers
|
|||||||
case 303:
|
case 303:
|
||||||
break;
|
break;
|
||||||
case 206:
|
case 206:
|
||||||
if (beg_range)
|
if (G.beg_range)
|
||||||
break;
|
break;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
default:
|
default:
|
||||||
@ -777,8 +780,8 @@ However, in real world it was observed that some web servers
|
|||||||
}
|
}
|
||||||
key = index_in_strings(keywords, buf) + 1;
|
key = index_in_strings(keywords, buf) + 1;
|
||||||
if (key == KEY_content_length) {
|
if (key == KEY_content_length) {
|
||||||
content_len = BB_STRTOOFF(str, NULL, 10);
|
G.content_len = BB_STRTOOFF(str, NULL, 10);
|
||||||
if (errno || content_len < 0) {
|
if (G.content_len < 0 || errno) {
|
||||||
bb_error_msg_and_die("content-length %s is garbage", sanitize_string(str));
|
bb_error_msg_and_die("content-length %s is garbage", sanitize_string(str));
|
||||||
}
|
}
|
||||||
G.got_clen = 1;
|
G.got_clen = 1;
|
||||||
@ -841,13 +844,14 @@ However, in real world it was observed that some web servers
|
|||||||
}
|
}
|
||||||
|
|
||||||
retrieve_file_data(dfp, output_fd);
|
retrieve_file_data(dfp, output_fd);
|
||||||
|
xclose(output_fd);
|
||||||
|
|
||||||
if (dfp != sfp) {
|
if (dfp != sfp) {
|
||||||
/* It's ftp. Close it properly */
|
/* It's ftp. Close it properly */
|
||||||
fclose(dfp);
|
fclose(dfp);
|
||||||
if (ftpcmd(NULL, NULL, sfp, buf) != 226)
|
if (ftpcmd(NULL, NULL, sfp, buf) != 226)
|
||||||
bb_error_msg_and_die("ftp error: %s", sanitize_string(buf+4));
|
bb_error_msg_and_die("ftp error: %s", sanitize_string(buf+4));
|
||||||
ftpcmd("QUIT", NULL, sfp, buf);
|
/* ftpcmd("QUIT", NULL, sfp, buf); - why bother? */
|
||||||
}
|
}
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
@ -110,7 +110,7 @@ int more_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
if (input != 'r' && please_display_more_prompt) {
|
if (input != 'r' && please_display_more_prompt) {
|
||||||
len = printf("--More-- ");
|
len = printf("--More-- ");
|
||||||
if (st.st_size > 0) {
|
if (st.st_size > 0) {
|
||||||
len += printf("(%d%% of %"OFF_FMT"d bytes)",
|
len += printf("(%u%% of %"OFF_FMT"u bytes)",
|
||||||
(int) (ftello(file)*100 / st.st_size),
|
(int) (ftello(file)*100 / st.st_size),
|
||||||
st.st_size);
|
st.st_size);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user