uclient-fetch: fix inconsistencies in help text (thx, Hannu Nyman)
[project/uclient.git] / uclient-fetch.c
index 3f875c9..065742e 100644 (file)
@@ -18,6 +18,7 @@
 
 #define _GNU_SOURCE
 #include <sys/stat.h>
+#include <sys/socket.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <dlfcn.h>
@@ -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] <URL>\n"
                "Options:\n"
-               "       -q:                             Turn off status messages\n"
-               "       -O <file>:                      Redirect output to file (use \"-\" for stdout)\n"
-               "       -P <dir>:                       Set directory for output files\n"
+               "       -4                              Use IPv4 only\n"
+               "       -6                              Use IPv6 only\n"
+               "       -q                              Turn off status messages\n"
+               "       -O <file>                       Redirect output to file (use \"-\" for stdout)\n"
+               "       -P <dir>                        Set directory for output files\n"
                "       --user=<user>                   HTTP authentication username\n"
                "       --password=<password>           HTTP authentication password\n"
                "       --user-agent|-U <str>           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=<cert>:        Load CA certificates from file <cert>\n"
-               "       --no-check-certificate:         don't validate the server's certificate\n"
+               "       --ca-certificate=<cert>         Load CA certificates from file <cert>\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();