X-Git-Url: http://git.openwrt.org/?p=project%2Fuclient.git;a=blobdiff_plain;f=uclient-fetch.c;h=282092e2f556a54c9a74366840231c57450c1428;hp=5f7ac6200bb867690d91468433225820562ad8b3;hb=HEAD;hpb=e6b5b8a98ce21d4b8374370b5d7592ead4b351e5 diff --git a/uclient-fetch.c b/uclient-fetch.c index 5f7ac62..b2b8d0d 100644 --- a/uclient-fetch.c +++ b/uclient-fetch.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -35,10 +34,8 @@ #include "uclient.h" #include "uclient-utils.h" -#ifdef __APPLE__ -#define LIB_EXT "dylib" -#else -#define LIB_EXT "so" +#ifndef strdupa +#define strdupa(x) strcpy(alloca(strlen(x)+1),x) #endif static const char *user_agent = "uclient-fetch"; @@ -233,6 +230,7 @@ static void header_done_cb(struct uclient *cl) error_ret = 8; break; } + /* fall through */ case 204: case 200: if (no_output) @@ -422,6 +420,23 @@ static void eof_cb(struct uclient *cl) request_done(cl); } +static void +handle_uclient_log_msg(struct uclient *cl, enum uclient_log_type type, const char *msg) +{ + static const char * const type_str_list[] = { + [UCLIENT_LOG_SSL_ERROR] = "SSL error", + [UCLIENT_LOG_SSL_VERIFY_ERROR] = "SSL verify error", + }; + const char *type_str = NULL; + + if (type < ARRAY_SIZE(type_str_list)) + type_str = type_str_list[type]; + if (!type_str) + type_str = "Unknown"; + + fprintf(stderr, "%s: %s\n", type_str, msg); +} + static void handle_uclient_error(struct uclient *cl, int code) { const char *type = "Unknown error"; @@ -465,6 +480,7 @@ static const struct uclient_cb cb = { .data_read = read_data_cb, .data_eof = eof_cb, .error = handle_uclient_error, + .log_msg = handle_uclient_log_msg, }; static int usage(const char *progname) @@ -474,17 +490,20 @@ static int usage(const char *progname) "Options:\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" + " --quiet | -q Turn off status messages\n" + " --continue | -c Continue a partially-downloaded file\n" " --user= HTTP authentication username\n" " --password= HTTP authentication password\n" - " --user-agent|-U Set HTTP user agent\n" + " --user-agent | -U Set HTTP user agent\n" " --post-data=STRING use the POST method; send STRING as the data\n" " --post-file=FILE use the POST method; send FILE as the data\n" - " --spider|-s Spider mode - only check file existence\n" - " --timeout=N|-T N Set connect/request timeout to N seconds\n" - " --proxy=on|off|-Y on|off Enable/disable env var configured proxy\n" + " --spider | -s Spider mode - only check file existence\n" + " --timeout=N | -T N Set connect/request timeout to N seconds\n" + " --proxy=on | -Y on Enable interpretation of proxy env vars (default)\n" + " --proxy=off | -Y off |\n" + " --no-proxy Disable interpretation of proxy env vars\n" "\n" "HTTPS options:\n" " --ca-certificate= Load CA certificates from file \n" @@ -502,21 +521,7 @@ static void init_ca_cert(void) glob("/etc/ssl/certs/*.crt", 0, NULL, &gl); for (i = 0; i < gl.gl_pathc; i++) ssl_ops->context_add_ca_crt_file(ssl_ctx, gl.gl_pathv[i]); -} - -static void init_ustream_ssl(void) -{ - void *dlh; - - dlh = dlopen("libustream-ssl." LIB_EXT, RTLD_LAZY | RTLD_LOCAL); - if (!dlh) - return; - - ssl_ops = dlsym(dlh, "ustream_ssl_ops"); - if (!ssl_ops) - return; - - ssl_ctx = ssl_ops->context_new(false); + globfree(&gl); } static int no_ssl(const char *progname) @@ -530,6 +535,11 @@ static int no_ssl(const char *progname) return 1; } +static void debug_cb(void *priv, int level, const char *msg) +{ + fprintf(stderr, "%s\n", msg); +} + enum { L_NO_CHECK_CERTIFICATE, L_CA_CERTIFICATE, @@ -545,6 +555,7 @@ enum { L_PROXY, L_NO_PROXY, L_QUIET, + L_VERBOSE, }; static const struct option longopts[] = { @@ -562,6 +573,7 @@ static const struct option longopts[] = { [L_PROXY] = { "proxy", required_argument, NULL, 0 }, [L_NO_PROXY] = { "no-proxy", no_argument, NULL, 0 }, [L_QUIET] = { "quiet", no_argument, NULL, 0 }, + [L_VERBOSE] = { "verbose", no_argument, NULL, 0 }, {} }; @@ -579,16 +591,19 @@ int main(int argc, char **argv) int i, ch; int rc; int af = -1; + int debug_level = 0; signal(SIGPIPE, SIG_IGN); - init_ustream_ssl(); + ssl_ctx = uclient_new_ssl_context(&ssl_ops); - while ((ch = getopt_long(argc, argv, "46cO:P:qsT:U:Y:", longopts, &longopt_idx)) != -1) { + while ((ch = getopt_long(argc, argv, "46cO:P:qsT:U:vY:", longopts, &longopt_idx)) != -1) { switch(ch) { case 0: switch (longopt_idx) { case L_NO_CHECK_CERTIFICATE: verify = false; + if (ssl_ctx) + ssl_ops->context_set_require_validation(ssl_ctx, verify); break; case L_CA_CERTIFICATE: has_cert = true; @@ -607,13 +622,13 @@ int main(int argc, char **argv) case L_USER: if (!strlen(optarg)) break; - username = strdup(optarg); + username = strdupa(optarg); memset(optarg, '*', strlen(optarg)); break; case L_PASSWORD: if (!strlen(optarg)) break; - password = strdup(optarg); + password = strdupa(optarg); memset(optarg, '*', strlen(optarg)); break; case L_USER_AGENT: @@ -644,6 +659,9 @@ int main(int argc, char **argv) case L_QUIET: quiet = true; break; + case L_VERBOSE: + debug_level++; + break; default: return usage(progname); } @@ -679,6 +697,9 @@ int main(int argc, char **argv) case 'T': timeout = atoi(optarg); break; + case 'v': + debug_level++; + break; case 'Y': if (strcmp(optarg, "on") != 0) proxy = false; @@ -691,6 +712,9 @@ int main(int argc, char **argv) argv += optind; argc -= optind; + if (debug_level) + ssl_ops->context_set_debug(ssl_ctx, debug_level, debug_cb, NULL); + if (verify && !has_cert) default_certs = true;