X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fuclient.git;a=blobdiff_plain;f=uclient-fetch.c;h=6961d94b12408203bc6ce6bb35d5700082dd9717;hp=d2ffde3f89423d975d38a730023d59db645c9217;hb=f2573da7f508a916177af41efc56233a4985c498;hpb=4924411cff2e74d835b819151513367d08c9e524 diff --git a/uclient-fetch.c b/uclient-fetch.c index d2ffde3..6961d94 100644 --- a/uclient-fetch.c +++ b/uclient-fetch.c @@ -18,6 +18,7 @@ #define _GNU_SOURCE #include +#include #include #include #include @@ -49,7 +50,7 @@ static bool verify = true; static bool proxy = true; static bool default_certs = false; static bool no_output; -static const char *output_file; +static const char *opt_output_file; static int output_fd = -1; static int error_ret; static off_t out_offset; @@ -96,6 +97,7 @@ get_proxy_url(char *url) static int open_output_file(const char *path, uint64_t resume_offset) { + const char *output_file = opt_output_file; char *filename = NULL; int flags; int ret; @@ -103,7 +105,7 @@ static int open_output_file(const char *path, uint64_t resume_offset) if (cur_resume) flags = O_RDWR; else - flags = O_WRONLY; + flags = O_WRONLY | O_TRUNC; if (!cur_resume && !output_file) flags |= O_EXCL; @@ -115,7 +117,8 @@ static int open_output_file(const char *path, uint64_t resume_offset) if (!quiet) fprintf(stderr, "Writing to stdout\n"); - return STDOUT_FILENO; + ret = STDOUT_FILENO; + goto done; } } else { filename = uclient_get_url_filename(path, "index.html"); @@ -139,6 +142,7 @@ static int open_output_file(const char *path, uint64_t resume_offset) out_offset = resume_offset; out_bytes += resume_offset; +done: if (!quiet) { progress_init(&pmt, output_file); pmt_timer.cb = pmt_update; @@ -251,6 +255,7 @@ static void header_done_cb(struct uclient *cl) static void read_data_cb(struct uclient *cl) { char buf[256]; + ssize_t n; int len; if (!no_output && output_fd < 0) @@ -258,12 +263,15 @@ static void read_data_cb(struct uclient *cl) while (1) { len = uclient_read(cl, buf, sizeof(buf)); - if (!len) + if (len <= 0) return; out_bytes += len; - if (!no_output) - write(output_fd, buf, len); + if (!no_output) { + n = write(output_fd, buf, len); + if (n < 0) + return; + } } } @@ -360,7 +368,7 @@ static void request_done(struct uclient *cl) return; } - if (output_fd >= 0 && !output_file) { + if (output_fd >= 0 && !opt_output_file) { close(output_fd); output_fd = -1; } @@ -437,9 +445,11 @@ static int usage(const char *progname) fprintf(stderr, "Usage: %s [options] \n" "Options:\n" - " -q: Turn off status messages\n" - " -O : Redirect output to file (use \"-\" for stdout)\n" - " -P : Set directory for output files\n" + " -4 Use IPv4 only\n" + " -6 Use IPv6 only\n" + " -q Turn off status messages\n" + " -O Redirect output to file (use \"-\" for stdout)\n" + " -P Set directory for output files\n" " --user= HTTP authentication username\n" " --password= HTTP authentication password\n" " --user-agent|-U Set HTTP user agent\n" @@ -449,8 +459,8 @@ static int usage(const char *progname) " --proxy=on|off|-Y on|off Enable/disable env var configured proxy\n" "\n" "HTTPS options:\n" - " --ca-certificate=: Load CA certificates from file \n" - " --no-check-certificate: don't validate the server's certificate\n" + " --ca-certificate= Load CA certificates from file \n" + " --no-check-certificate don't validate the server's certificate\n" "\n", progname); return 1; } @@ -482,7 +492,12 @@ static void init_ustream_ssl(void) static int no_ssl(const char *progname) { - fprintf(stderr, "%s: SSL support not available, please install ustream-ssl\n", progname); + fprintf(stderr, + "%s: SSL support not available, please install one of the " + "libustream-.*[ssl|tls] packages as well as the ca-bundle and " + "ca-certificates packages.\n", + progname); + return 1; } @@ -498,6 +513,7 @@ enum { L_CONTINUE, L_PROXY, L_NO_PROXY, + L_QUIET, }; static const struct option longopts[] = { @@ -512,6 +528,7 @@ static const struct option longopts[] = { [L_CONTINUE] = { "continue", no_argument }, [L_PROXY] = { "proxy", required_argument }, [L_NO_PROXY] = { "no-proxy", no_argument }, + [L_QUIET] = { "quiet", no_argument }, {} }; @@ -528,11 +545,12 @@ int main(int argc, char **argv) bool has_cert = false; int i, ch; int rc; + int af = -1; signal(SIGPIPE, SIG_IGN); init_ustream_ssl(); - while ((ch = getopt_long(argc, argv, "cO:P:qsT:U:Y:", longopts, &longopt_idx)) != -1) { + while ((ch = getopt_long(argc, argv, "46cO:P:qsT:U:Y:", longopts, &longopt_idx)) != -1) { switch(ch) { case 0: switch (longopt_idx) { @@ -578,10 +596,19 @@ int main(int argc, char **argv) case L_NO_PROXY: proxy = false; break; + case L_QUIET: + quiet = true; + break; default: return usage(progname); } break; + case '4': + af = AF_INET; + break; + case '6': + af = AF_INET6; + break; case 'c': resume = true; break; @@ -589,7 +616,7 @@ int main(int argc, char **argv) user_agent = optarg; break; case 'O': - output_file = optarg; + opt_output_file = optarg; break; case 'P': if (chdir(optarg)) { @@ -638,9 +665,11 @@ int main(int argc, char **argv) uloop_init(); if (username) { - if (password) - asprintf(&auth_str, "%s:%s", username, password); - else + if (password) { + rc = asprintf(&auth_str, "%s:%s", username, password); + if (rc < 0) + return rc; + } else auth_str = username; } @@ -650,7 +679,8 @@ int main(int argc, char **argv) proxy_url = get_proxy_url(argv[0]); if (proxy_url) { cl = uclient_new(proxy_url, auth_str, &cb); - uclient_set_proxy_url(cl, argv[0], NULL); + if (cl) + uclient_set_proxy_url(cl, argv[0], NULL); } else { cl = uclient_new(argv[0], auth_str, &cb); } @@ -658,6 +688,8 @@ int main(int argc, char **argv) fprintf(stderr, "Failed to allocate uclient context\n"); return 1; } + if (af >= 0) + uclient_http_set_address_family(cl, af); if (ssl_ctx && default_certs) init_ca_cert();