X-Git-Url: http://sjero.net/git/?a=blobdiff_plain;f=src%2Fmain.c;h=96d93589253a118bf008c553030bd7a2e364a08e;hb=319f52d756238aca0ba7c671f529d336757806c5;hp=0be2c90c49e5e643a51bff330ab6554bf19fdfa1;hpb=8f935cf74ce95a631788fb8a4cce4114df935a78;p=wget diff --git a/src/main.c b/src/main.c index 0be2c90c..96d93589 100644 --- a/src/main.c +++ b/src/main.c @@ -34,26 +34,13 @@ so, delete this exception statement from your version. */ #ifdef HAVE_UNISTD_H # include #endif /* HAVE_UNISTD_H */ -#include -#ifdef HAVE_STRING_H -# include -#else -# include -#endif /* HAVE_STRING_H */ -#ifdef HAVE_SIGNAL_H -# include -#endif -#ifdef HAVE_NLS -#ifdef HAVE_LOCALE_H +#include +#include +#if defined(HAVE_NLS) && defined(HAVE_LOCALE_H) # include -#endif /* HAVE_LOCALE_H */ -#endif /* HAVE_NLS */ +#endif #include - #include -#ifndef errno -extern int errno; -#endif #include "wget.h" #include "utils.h" @@ -74,34 +61,35 @@ extern int errno; struct options opt; -extern LARGE_INT total_downloaded_bytes; extern char *version_string; extern struct cookie_jar *wget_cookie_jar; -static RETSIGTYPE redirect_output_signal PARAMS ((int)); +static void redirect_output_signal (int); const char *exec_name; -/* Initialize I18N. The initialization amounts to invoking - setlocale(), bindtextdomain() and textdomain(). - Does nothing if NLS is disabled or missing. */ +/* Initialize I18N/L10N. That amounts to invoking setlocale, and + setting up gettext's message catalog using bindtextdomain and + textdomain. Does nothing if NLS is disabled or missing. */ + static void i18n_initialize (void) { - /* If HAVE_NLS is defined, assume the existence of the three - functions invoked here. */ + /* HAVE_NLS implies existence of functions invoked here. */ #ifdef HAVE_NLS /* Set the current locale. */ - /* Here we use LC_MESSAGES instead of LC_ALL, for two reasons. - First, message catalogs are all of I18N Wget uses anyway. - Second, setting LC_ALL has a dangerous potential of messing - things up. For example, when in a foreign locale, Solaris - strptime() fails to handle international dates correctly, which - makes http_atotm() malfunction. */ -#ifdef LC_MESSAGES + /* Where possible, sets only LC_MESSAGES and LC_CTYPE. Other + categories, such as numeric, time, or collation, break code that + parses data received from the network and relies on C-locale + behavior of libc functions. For example, Solaris strptime fails + to recognize English month names in non-English locales, which + breaks http_atotm. Some implementations of fnmatch perform + unwanted case folding in non-C locales. ctype macros, while they + were used, provided another example against LC_ALL. */ +#if defined(LC_MESSAGES) && defined(LC_CTYPE) setlocale (LC_MESSAGES, ""); - setlocale (LC_CTYPE, ""); + setlocale (LC_CTYPE, ""); /* safe because we use safe-ctype */ #else setlocale (LC_ALL, ""); #endif @@ -113,8 +101,8 @@ i18n_initialize (void) /* Definition of command-line options. */ -static void print_help PARAMS ((void)); -static void print_version PARAMS ((void)); +static void print_help (void); +static void print_version (void); #ifdef HAVE_SSL # define IF_SSL(x) x @@ -123,9 +111,9 @@ static void print_version PARAMS ((void)); #endif #ifdef ENABLE_DEBUG -# define IF_DEBUG(x) x +# define WHEN_DEBUG(x) x #else -# define IF_DEBUG(x) NULL +# define WHEN_DEBUG(x) NULL #endif struct cmdline_option { @@ -142,7 +130,7 @@ struct cmdline_option { OPT__DONT_REMOVE_LISTING, OPT__EXECUTE, OPT__NO, - OPT__PARENT, + OPT__PARENT } type; const void *data; /* for standard options */ int argtype; /* for non-standard options */ @@ -169,7 +157,7 @@ struct cmdline_option option_data[] = { "convert-links", 'k', OPT_BOOLEAN, "convertlinks", -1 }, { "cookies", 0, OPT_BOOLEAN, "cookies", -1 }, { "cut-dirs", 0, OPT_VALUE, "cutdirs", -1 }, - { IF_DEBUG ("debug"), 'd', OPT_BOOLEAN, "debug", -1 }, + { WHEN_DEBUG ("debug"), 'd', OPT_BOOLEAN, "debug", -1 }, { "delete-after", 0, OPT_BOOLEAN, "deleteafter", -1 }, { "directories", 0, OPT_BOOLEAN, "dirstruct", -1 }, { "directory-prefix", 'P', OPT_VALUE, "dirprefix", -1 }, @@ -186,7 +174,8 @@ struct cmdline_option option_data[] = { "follow-tags", 0, OPT_VALUE, "followtags", -1 }, { "force-directories", 'x', OPT_BOOLEAN, "dirstruct", -1 }, { "force-html", 'F', OPT_BOOLEAN, "forcehtml", -1 }, - { "ftp-passwd", 0, OPT_VALUE, "ftppasswd", -1 }, + { "ftp-password", 0, OPT_VALUE, "ftppassword", -1 }, + { "ftp-user", 0, OPT_VALUE, "ftpuser", -1 }, { "glob", 0, OPT_BOOLEAN, "glob", -1 }, { "header", 0, OPT_VALUE, "header", -1 }, { "help", 'h', OPT_FUNCALL, (void *)print_help, no_argument }, @@ -194,7 +183,8 @@ struct cmdline_option option_data[] = { "html-extension", 'E', OPT_BOOLEAN, "htmlextension", -1 }, { "htmlify", 0, OPT_BOOLEAN, "htmlify", -1 }, { "http-keep-alive", 0, OPT_BOOLEAN, "httpkeepalive", -1 }, - { "http-passwd", 0, OPT_VALUE, "httppasswd", -1 }, + { "http-passwd", 0, OPT_VALUE, "httppassword", -1 }, /* deprecated */ + { "http-password", 0, OPT_VALUE, "httppassword", -1 }, { "http-user", 0, OPT_VALUE, "httpuser", -1 }, { "ignore-length", 0, OPT_BOOLEAN, "ignorelength", -1 }, { "ignore-tags", 0, OPT_VALUE, "ignoretags", -1 }, @@ -217,6 +207,7 @@ struct cmdline_option option_data[] = { "page-requisites", 'p', OPT_BOOLEAN, "pagerequisites", -1 }, { "parent", 0, OPT__PARENT, NULL, optional_argument }, { "passive-ftp", 0, OPT_BOOLEAN, "passiveftp", -1 }, + { "password", 0, OPT_VALUE, "password", -1 }, { "post-data", 0, OPT_VALUE, "postdata", -1 }, { "post-file", 0, OPT_VALUE, "postfile", -1 }, { "prefer-family", 0, OPT_VALUE, "preferfamily", -1 }, @@ -227,7 +218,8 @@ struct cmdline_option option_data[] = { "protocol-directories", 0, OPT_BOOLEAN, "protocoldirectories", -1 }, { "proxy", 0, OPT_BOOLEAN, "useproxy", -1 }, { "proxy__compat", 'Y', OPT_VALUE, "useproxy", -1 }, /* back-compatible */ - { "proxy-passwd", 0, OPT_VALUE, "proxypasswd", -1 }, + { "proxy-passwd", 0, OPT_VALUE, "proxypassword", -1 }, /* deprecated */ + { "proxy-password", 0, OPT_VALUE, "proxypassword", -1 }, { "proxy-user", 0, OPT_VALUE, "proxyuser", -1 }, { "quiet", 'q', OPT_BOOLEAN, "quiet", -1 }, { "quota", 'Q', OPT_VALUE, "quota", -1 }, @@ -252,6 +244,7 @@ struct cmdline_option option_data[] = { "timeout", 'T', OPT_VALUE, "timeout", -1 }, { "timestamping", 'N', OPT_BOOLEAN, "timestamping", -1 }, { "tries", 't', OPT_VALUE, "tries", -1 }, + { "user", 0, OPT_VALUE, "user", -1 }, { "user-agent", 'U', OPT_VALUE, "useragent", -1 }, { "verbose", 'v', OPT_BOOLEAN, "verbose", -1 }, { "verbose", 0, OPT_BOOLEAN, "verbose", -1 }, @@ -260,7 +253,7 @@ struct cmdline_option option_data[] = { "waitretry", 0, OPT_VALUE, "waitretry", -1 }, }; -#undef IF_DEBUG +#undef WHEN_DEBUG #undef IF_SSL /* Return a string that contains S with "no-" prepended. The string @@ -474,6 +467,10 @@ Download:\n"), --prefer-family=FAMILY connect first to addresses of specified family,\n\ one of IPv6, IPv4, or none.\n"), #endif + N_("\ + --user=USER set both ftp and http user to USER.\n"), + N_("\ + --password=PASS set both ftp and http password to PASS.\n"), "\n", N_("\ @@ -497,7 +494,7 @@ HTTP options:\n"), N_("\ --http-user=USER set http user to USER.\n"), N_("\ - --http-passwd=PASS set http password to PASS.\n"), + --http-password=PASS set http password to PASS.\n"), N_("\ --no-cache disallow server-cached data.\n"), N_("\ @@ -509,7 +506,7 @@ HTTP options:\n"), N_("\ --proxy-user=USER set USER as proxy username.\n"), N_("\ - --proxy-passwd=PASS set PASS as proxy password.\n"), + --proxy-password=PASS set PASS as proxy password.\n"), N_("\ --referer=URL include `Referer: URL' header in HTTP request.\n"), N_("\ @@ -536,18 +533,18 @@ HTTP options:\n"), N_("\ HTTPS (SSL/TLS) options:\n"), N_("\ - --secure-protocol=PR choose SSL protocol, one of auto, SSLv2, SSLv3,\n\ - and TLSv1.\n"), + --secure-protocol=PR choose secure protocol, one of auto, SSLv2,\n\ + SSLv3, and TLSv1.\n"), N_("\ --no-check-certificate don't validate the server's certificate.\n"), N_("\ --certificate=FILE client certificate file.\n"), N_("\ - --certificate-type=TYPE client certificate type, PEM or ASN1.\n"), + --certificate-type=TYPE client certificate type, PEM or DER.\n"), N_("\ --private-key=FILE private key file.\n"), N_("\ - --private-key-type=TYPE private key type, PEM or ASN1.\n"), + --private-key-type=TYPE private key type, PEM or DER.\n"), N_("\ --ca-certificate=FILE file with the bundle of CA's.\n"), N_("\ @@ -561,6 +558,10 @@ HTTPS (SSL/TLS) options:\n"), N_("\ FTP options:\n"), + N_("\ + --ftp-user=USER set ftp user to USER.\n"), + N_("\ + --ftp-password=PASS set ftp password to PASS.\n"), N_("\ --no-remove-listing don't remove `.listing' files.\n"), N_("\ @@ -636,6 +637,31 @@ Recursive accept/reject:\n"), exit (0); } +static char * +secs_to_human_time (double secs_decimal) +{ + static char buf[32]; + int secs = (int) (secs_decimal + 0.5); + int hours, mins, days; + + days = secs / 86400, secs %= 86400; + hours = secs / 3600, secs %= 3600; + mins = secs / 60, secs %= 60; + + if (days) + sprintf (buf, _("%dd %dh %dm %ds"), days, hours, mins, secs); + else if (hours) + sprintf (buf, _("%dh %dm %ds"), hours, mins, secs); + else if (mins) + sprintf (buf, _("%dm %ds"), mins, secs); + else if (secs_decimal >= 1) + sprintf (buf, _("%ds"), secs); + else + sprintf (buf, _("%.2fs"), secs_decimal); + + return buf; +} + static void print_version (void) { @@ -658,7 +684,7 @@ main (int argc, char *const *argv) char **url, **t; int i, ret, longindex; int nurl, status; - int append_to_log = 0; + bool append_to_log = false; i18n_initialize (); @@ -708,28 +734,28 @@ main (int argc, char *const *argv) switch (opt->type) { case OPT_VALUE: - setoptval (opt->data, optarg); + setoptval (opt->data, optarg, opt->long_name); break; case OPT_BOOLEAN: if (optarg) /* The user has specified a value -- use it. */ - setoptval (opt->data, optarg); + setoptval (opt->data, optarg, opt->long_name); else { /* NEG is true for `--no-FOO' style boolean options. */ - int neg = val & BOOLEAN_NEG_MARKER; - setoptval (opt->data, neg ? "0" : "1"); + bool neg = !!(val & BOOLEAN_NEG_MARKER); + setoptval (opt->data, neg ? "0" : "1", opt->long_name); } break; case OPT_FUNCALL: { - void (*func) PARAMS ((void)) = (void (*) PARAMS ((void))) opt->data; + void (*func) (void) = (void (*) (void)) opt->data; func (); } break; case OPT__APPEND_OUTPUT: - setoptval ("logfile", optarg); - append_to_log = 1; + setoptval ("logfile", optarg, opt->long_name); + append_to_log = true; break; case OPT__EXECUTE: run_command (optarg); @@ -744,19 +770,19 @@ main (int argc, char *const *argv) switch (*p) { case 'v': - setoptval ("verbose", "0"); + setoptval ("verbose", "0", opt->long_name); break; case 'H': - setoptval ("addhostdir", "0"); + setoptval ("addhostdir", "0", opt->long_name); break; case 'd': - setoptval ("dirstruct", "0"); + setoptval ("dirstruct", "0", opt->long_name); break; case 'c': - setoptval ("noclobber", "1"); + setoptval ("noclobber", "1", opt->long_name); break; case 'p': - setoptval ("noparent", "1"); + setoptval ("noparent", "1", opt->long_name); break; default: printf (_("%s: illegal option -- `-n%c'\n"), exec_name, *p); @@ -773,17 +799,17 @@ main (int argc, char *const *argv) /* The wgetrc commands are named noparent and noclobber, so we must revert the meaning of the cmdline options before passing the value to setoptval. */ - int flag = 1; + bool flag = true; if (optarg) flag = (*optarg == '1' || TOLOWER (*optarg) == 'y' || (TOLOWER (optarg[0]) == 'o' && TOLOWER (optarg[1]) == 'n')); setoptval (opt->type == OPT__PARENT ? "noparent" : "noclobber", - flag ? "0" : "1"); + flag ? "0" : "1", opt->long_name); break; } case OPT__DONT_REMOVE_LISTING: - setoptval ("removelisting", "0"); + setoptval ("removelisting", "0", opt->long_name); break; } @@ -875,13 +901,13 @@ Can't timestamp and not clobber old files at the same time.\n")); if (opt.output_document) { extern FILE *output_stream; - extern int output_stream_regular; + extern bool output_stream_regular; if (HYPHENP (opt.output_document)) output_stream = stdout; else { - struct_stat st; + struct_fstat st; output_stream = fopen (opt.output_document, opt.always_rest ? "ab" : "wb"); if (output_stream == NULL) @@ -890,7 +916,7 @@ Can't timestamp and not clobber old files at the same time.\n")); exit (1); } if (fstat (fileno (output_stream), &st) == 0 && S_ISREG (st.st_mode)) - output_stream_regular = 1; + output_stream_regular = true; } } @@ -898,21 +924,25 @@ Can't timestamp and not clobber old files at the same time.\n")); ws_startup (); #endif +#ifdef SIGHUP /* Setup the signal handler to redirect output when hangup is received. */ -#ifdef HAVE_SIGNAL if (signal(SIGHUP, SIG_IGN) != SIG_IGN) signal(SIGHUP, redirect_output_signal); +#endif /* ...and do the same for SIGUSR1. */ +#ifdef SIGUSR1 signal (SIGUSR1, redirect_output_signal); +#endif +#ifdef SIGPIPE /* Writing to a closed socket normally signals SIGPIPE, and the process exits. What we want is to ignore SIGPIPE and just check for the return value of write(). */ signal (SIGPIPE, SIG_IGN); +#endif #ifdef SIGWINCH signal (SIGWINCH, progress_handle_sigwinch); #endif -#endif /* HAVE_SIGNAL */ status = RETROK; /* initialize it, just-in-case */ /* Retrieve the URLs from argument list. */ @@ -954,14 +984,17 @@ Can't timestamp and not clobber old files at the same time.\n")); || (opt.input_filename && total_downloaded_bytes != 0)) { logprintf (LOG_NOTQUIET, - _("\nFINISHED --%s--\nDownloaded: %s bytes in %d files\n"), - time_str (NULL), with_thousand_seps_large (total_downloaded_bytes), - opt.numurls); + _("FINISHED --%s--\nDownloaded: %d files, %s in %s (%s)\n"), + time_str (NULL), + opt.numurls, + human_readable (total_downloaded_bytes), + secs_to_human_time (total_download_time / 1000), + retr_rate (total_downloaded_bytes, total_download_time)); /* Print quota warning, if exceeded. */ if (opt.quota && total_downloaded_bytes > opt.quota) logprintf (LOG_NOTQUIET, - _("Download quota (%s bytes) EXCEEDED!\n"), - with_thousand_seps_large (opt.quota)); + _("Download quota of %s EXCEEDED!\n"), + human_readable (opt.quota)); } if (opt.cookies_output) @@ -984,16 +1017,12 @@ Can't timestamp and not clobber old files at the same time.\n")); return 1; } -#ifdef HAVE_SIGNAL +#if defined(SIGHUP) || defined(SIGUSR1) /* Hangup signal handler. When wget receives SIGHUP or SIGUSR1, it will proceed operation as usual, trying to write into a log file. - If that is impossible, the output will be turned off. + If that is impossible, the output will be turned off. */ - #### It is unsafe to do call libc functions from a signal handler. - What we should do is, set a global variable, and have the code in - log.c pick it up. */ - -static RETSIGTYPE +static void redirect_output_signal (int sig) { const char *signal_name = (sig == SIGHUP ? "SIGHUP" : @@ -1003,4 +1032,4 @@ redirect_output_signal (int sig) progress_schedule_redirect (); signal (sig, redirect_output_signal); } -#endif /* HAVE_SIGNAL */ +#endif