X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fuclient.git;a=blobdiff_plain;f=uclient-fetch.c;h=065742eeed3378167b234cb664efb19750af26e0;hp=3f875c9aea0a87feb380caa5aa11e8ccba1c83b4;hb=f0754619b9ee216b0cb5fc7484f861e876781984;hpb=8e6590cb48c611f480a5817d0cd5c7d7e6c5794d diff --git a/uclient-fetch.c b/uclient-fetch.c index 3f875c9..065742e 100644 --- a/uclient-fetch.c +++ b/uclient-fetch.c @@ -18,6 +18,7 @@ #define _GNU_SOURCE #include +#include #include #include #include @@ -103,7 +104,10 @@ static int open_output_file(const char *path, uint64_t resume_offset) if (cur_resume) flags = O_RDWR; else - flags = O_WRONLY | O_EXCL; + flags = O_WRONLY | O_TRUNC; + + if (!cur_resume && !output_file) + flags |= O_EXCL; flags |= O_CREAT; @@ -112,7 +116,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"); @@ -136,6 +141,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; @@ -162,12 +168,22 @@ static void header_done_cb(struct uclient *cl) uint64_t resume_offset = 0, resume_end, resume_size; static int retries; - if (retries < 10 && uclient_http_redirect(cl)) { - if (!quiet) - fprintf(stderr, "Redirected to %s on %s\n", cl->url->location, cl->url->host); + if (retries < 10) { + int ret = uclient_http_redirect(cl); + if (ret < 0) { + if (!quiet) + fprintf(stderr, "Failed to redirect to %s on %s\n", cl->url->location, cl->url->host); + error_ret = 8; + request_done(cl); + return; + } + if (ret > 0) { + if (!quiet) + fprintf(stderr, "Redirected to %s on %s\n", cl->url->location, cl->url->host); - retries++; - return; + retries++; + return; + } } if (cl->status_code == 204 && cur_resume) { @@ -361,6 +377,7 @@ static void eof_cb(struct uclient *cl) if (!quiet) { pmt_update(&pmt_timer); uloop_timeout_cancel(&pmt_timer); + fprintf(stderr, "\n"); } if (!cl->data_eof) { @@ -423,9 +440,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" @@ -435,8 +454,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; } @@ -514,11 +533,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:qsU: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) { @@ -568,6 +588,12 @@ int main(int argc, char **argv) return usage(progname); } break; + case '4': + af = AF_INET; + break; + case '6': + af = AF_INET6; + break; case 'c': resume = true; break; @@ -636,7 +662,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); } @@ -644,6 +671,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();