#define _GNU_SOURCE
#include <sys/stat.h>
+#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <dlfcn.h>
if (cur_resume)
flags = O_RDWR;
else
- flags = O_WRONLY;
+ flags = O_WRONLY | O_TRUNC;
if (!cur_resume && !output_file)
flags |= O_EXCL;
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");
out_offset = resume_offset;
out_bytes += resume_offset;
+done:
if (!quiet) {
progress_init(&pmt, output_file);
pmt_timer.cb = pmt_update;
static void read_data_cb(struct uclient *cl)
{
char buf[256];
+ ssize_t n;
int len;
if (!no_output && output_fd < 0)
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;
+ }
}
}
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"
" --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;
}
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-* libraries as well as the ca-bundle and "
+ "ca-certificates packages.\n",
+ progname);
+
return 1;
}
L_CONTINUE,
L_PROXY,
L_NO_PROXY,
+ L_QUIET,
};
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 },
{}
};
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) {
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;
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;
}
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);
}
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();