X-Git-Url: http://sjero.net/git/?p=wget;a=blobdiff_plain;f=src%2Fmain.c;h=81277c35742b63c474937b00e43f528f68d814db;hp=02ecb1d68034b224085a4ca97c6903b1ff66bed0;hb=2f6aa1d7417df1dfc58597777686fbd77179b9fd;hpb=f33c27562106ccbd12f7fcdeb6f38aa153183463 diff --git a/src/main.c b/src/main.c index 02ecb1d6..81277c35 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,7 @@ /* Command line parsing. - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, + 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, + Inc. This file is part of GNU Wget. @@ -32,9 +33,7 @@ as that of the covered work. */ #include #include -#ifdef HAVE_UNISTD_H -# include -#endif /* HAVE_UNISTD_H */ +#include #include #include #ifdef ENABLE_NLS @@ -44,6 +43,7 @@ as that of the covered work. */ #include #include +#include "exits.h" #include "utils.h" #include "init.h" #include "retr.h" @@ -54,11 +54,16 @@ as that of the covered work. */ #include "convert.h" #include "spider.h" #include "http.h" /* for save_cookies */ +#include "ptimer.h" #include #include #include +#ifdef __VMS +#include "vms.h" +#endif /* __VMS */ + #ifndef PATH_SEPARATOR # define PATH_SEPARATOR '/' #endif @@ -71,9 +76,10 @@ extern char *compilation_string; extern char *system_getrc; extern char *link_string; /* defined in build_info.c */ -extern char *compiled_features[]; +extern const char *compiled_features[]; /* Used for --version output in print_version */ -static const int max_chars_per_line = 72; +#define MAX_CHARS_PER_LINE 72 +#define TABULATION 4 #if defined(SIGHUP) || defined(SIGUSR1) static void redirect_output_signal (int); @@ -142,6 +148,7 @@ struct cmdline_option { static struct cmdline_option option_data[] = { { "accept", 'A', OPT_VALUE, "accept", -1 }, + { "adjust-extension", 'E', OPT_BOOLEAN, "adjustextension", -1 }, { "append-output", 'a', OPT__APPEND_OUTPUT, NULL, required_argument }, { "ask-password", 0, OPT_BOOLEAN, "askpassword", -1 }, { "auth-no-challenge", 0, OPT_BOOLEAN, "authnochallenge", -1 }, @@ -157,6 +164,7 @@ static struct cmdline_option option_data[] = { IF_SSL ("certificate-type"), 0, OPT_VALUE, "certificatetype", -1 }, { IF_SSL ("check-certificate"), 0, OPT_BOOLEAN, "checkcertificate", -1 }, { "clobber", 0, OPT__CLOBBER, NULL, optional_argument }, + { "config", 0, OPT_VALUE, "chooseconfig", -1 }, { "connect-timeout", 0, OPT_VALUE, "connecttimeout", -1 }, { "continue", 'c', OPT_BOOLEAN, "continue", -1 }, { "convert-links", 'k', OPT_BOOLEAN, "convertlinks", -1 }, @@ -172,7 +180,7 @@ static struct cmdline_option option_data[] = { "dns-timeout", 0, OPT_VALUE, "dnstimeout", -1 }, { "domains", 'D', OPT_VALUE, "domains", -1 }, { "dont-remove-listing", 0, OPT__DONT_REMOVE_LISTING, NULL, no_argument }, - { "dot-style", 0, OPT_VALUE, "dotstyle", -1 }, + { "dot-style", 0, OPT_VALUE, "dotstyle", -1 }, /* deprecated */ { "egd-file", 0, OPT_VALUE, "egdfile", -1 }, { "exclude-directories", 'X', OPT_VALUE, "excludedirectories", -1 }, { "exclude-domains", 0, OPT_VALUE, "excludedomains", -1 }, @@ -182,12 +190,15 @@ static struct cmdline_option option_data[] = { "force-directories", 'x', OPT_BOOLEAN, "dirstruct", -1 }, { "force-html", 'F', OPT_BOOLEAN, "forcehtml", -1 }, { "ftp-password", 0, OPT_VALUE, "ftppassword", -1 }, +#ifdef __VMS + { "ftp-stmlf", 0, OPT_BOOLEAN, "ftpstmlf", -1 }, +#endif /* def __VMS */ { "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 }, { "host-directories", 0, OPT_BOOLEAN, "addhostdir", -1 }, - { "html-extension", 'E', OPT_BOOLEAN, "htmlextension", -1 }, + { "html-extension", 'E', OPT_BOOLEAN, "adjustextension", -1 }, /* deprecated */ { "htmlify", 0, OPT_BOOLEAN, "htmlify", -1 }, { "http-keep-alive", 0, OPT_BOOLEAN, "httpkeepalive", -1 }, { "http-passwd", 0, OPT_VALUE, "httppassword", -1 }, /* deprecated */ @@ -202,10 +213,12 @@ static struct cmdline_option option_data[] = { "inet6-only", '6', OPT_BOOLEAN, "inet6only", -1 }, #endif { "input-file", 'i', OPT_VALUE, "input", -1 }, + { "iri", 0, OPT_BOOLEAN, "iri", -1 }, { "keep-session-cookies", 0, OPT_BOOLEAN, "keepsessioncookies", -1 }, { "level", 'l', OPT_VALUE, "reclevel", -1 }, { "limit-rate", 0, OPT_VALUE, "limitrate", -1 }, { "load-cookies", 0, OPT_VALUE, "loadcookies", -1 }, + { "local-encoding", 0, OPT_VALUE, "localencoding", -1 }, { "max-redirect", 0, OPT_VALUE, "maxredirect", -1 }, { "mirror", 'm', OPT_BOOLEAN, "mirror", -1 }, { "no", 'n', OPT__NO, NULL, required_argument }, @@ -220,7 +233,7 @@ static struct cmdline_option option_data[] = { "post-data", 0, OPT_VALUE, "postdata", -1 }, { "post-file", 0, OPT_VALUE, "postfile", -1 }, { "prefer-family", 0, OPT_VALUE, "preferfamily", -1 }, - { "preserve-permissions", 0, OPT_BOOLEAN, "preservepermissions", -1 }, + { "preserve-permissions", 0, OPT_BOOLEAN, "preservepermissions", -1 }, /* deprecated */ { IF_SSL ("private-key"), 0, OPT_VALUE, "privatekey", -1 }, { IF_SSL ("private-key-type"), 0, OPT_VALUE, "privatekeytype", -1 }, { "progress", 0, OPT_VALUE, "progress", -1 }, @@ -239,6 +252,7 @@ static struct cmdline_option option_data[] = { "referer", 0, OPT_VALUE, "referer", -1 }, { "reject", 'R', OPT_VALUE, "reject", -1 }, { "relative", 'L', OPT_BOOLEAN, "relativeonly", -1 }, + { "remote-encoding", 0, OPT_VALUE, "remoteencoding", -1 }, { "remove-listing", 0, OPT_BOOLEAN, "removelisting", -1 }, { "restrict-file-names", 0, OPT_BOOLEAN, "restrictfilenames", -1 }, { "retr-symlinks", 0, OPT_BOOLEAN, "retrsymlinks", -1 }, @@ -253,6 +267,9 @@ static struct cmdline_option option_data[] = { "timeout", 'T', OPT_VALUE, "timeout", -1 }, { "timestamping", 'N', OPT_BOOLEAN, "timestamping", -1 }, { "tries", 't', OPT_VALUE, "tries", -1 }, + { "unlink", 0, OPT_BOOLEAN, "unlink", -1 }, + { "trust-server-names", 0, OPT_BOOLEAN, "trustservernames", -1 }, + { "use-server-timestamps", 0, OPT_BOOLEAN, "useservertimestamps", -1 }, { "user", 0, OPT_VALUE, "user", -1 }, { "user-agent", 'U', OPT_VALUE, "useragent", -1 }, { "verbose", 'v', OPT_BOOLEAN, "verbose", -1 }, @@ -260,7 +277,7 @@ static struct cmdline_option option_data[] = { "version", 'V', OPT_FUNCALL, (void *) print_version, no_argument }, { "wait", 'w', OPT_VALUE, "wait", -1 }, { "waitretry", 0, OPT_VALUE, "waitretry", -1 }, -#ifdef MSDOS +#ifdef USE_WATT32 { "wdebug", 0, OPT_BOOLEAN, "wdebug", -1 }, #endif }; @@ -368,9 +385,10 @@ init_switches (void) /* Print the usage message. */ static void -print_usage (void) +print_usage (int error) { - printf (_("Usage: %s [OPTION]... [URL]...\n"), exec_name); + fprintf (error ? stderr : stdout, _("Usage: %s [OPTION]... [URL]...\n"), + exec_name); } /* Print the help message, describing all the available options. If @@ -406,7 +424,7 @@ Logging and input file:\n"), N_("\ -d, --debug print lots of debugging information.\n"), #endif -#ifdef MSDOS +#ifdef USE_WATT32 N_("\ --wdebug print Watt-32 debug output.\n"), #endif @@ -421,7 +439,10 @@ Logging and input file:\n"), N_("\ -F, --force-html treat input file as HTML.\n"), N_("\ - -B, --base=URL prepends URL to relative links in -F -i file.\n"), + -B, --base=URL resolves HTML input-file links (-i -F)\n\ + relative to URL.\n"), + N_("\ + --config=FILE Specify config file to use.\n"), "\n", N_("\ @@ -434,7 +455,7 @@ Download:\n"), -O, --output-document=FILE write documents to FILE.\n"), N_("\ -nc, --no-clobber skip downloads that would download to\n\ - existing files.\n"), + existing files (overwriting them).\n"), N_("\ -c, --continue resume getting a partially-downloaded file.\n"), N_("\ @@ -443,6 +464,9 @@ Download:\n"), -N, --timestamping don't re-retrieve files unless newer than\n\ local.\n"), N_("\ + --no-use-server-timestamps don't set the local file's timestamp by\n\ + the one on the server.\n"), + N_("\ -S, --server-response print server response.\n"), N_("\ --spider don't download anything.\n"), @@ -459,7 +483,7 @@ Download:\n"), N_("\ --waitretry=SECONDS wait 1..SECONDS between retries of a retrieval.\n"), N_("\ - --random-wait wait from 0...2*WAIT secs between retrievals.\n"), + --random-wait wait from 0.5*WAIT...1.5*WAIT secs between retrievals.\n"), N_("\ --no-proxy explicitly turn off proxy.\n"), N_("\ @@ -489,6 +513,14 @@ Download:\n"), --password=PASS set both ftp and http password to PASS.\n"), N_("\ --ask-password prompt for passwords.\n"), + N_("\ + --no-iri turn off IRI support.\n"), + N_("\ + --local-encoding=ENC use ENC as the local encoding for IRIs.\n"), + N_("\ + --remote-encoding=ENC use ENC as the default remote encoding.\n"), + N_("\ + --unlink remove file before clobber.\n"), "\n", N_("\ @@ -519,7 +551,7 @@ HTTP options:\n"), --default-page=NAME Change the default page name (normally\n\ this is `index.html'.).\n"), N_("\ - -E, --html-extension save HTML documents with `.html' extension.\n"), + -E, --adjust-extension save HTML/CSS documents with proper extensions.\n"), N_("\ --ignore-length ignore `Content-Length' header field.\n"), N_("\ @@ -554,7 +586,7 @@ HTTP options:\n"), --content-disposition honor the Content-Disposition header when\n\ choosing local file names (EXPERIMENTAL).\n"), N_("\ - --auth-no-challenge Send Basic HTTP authentication information\n\ + --auth-no-challenge send Basic HTTP authentication information\n\ without first waiting for the server's\n\ challenge.\n"), "\n", @@ -588,6 +620,10 @@ HTTPS (SSL/TLS) options:\n"), N_("\ FTP options:\n"), +#ifdef __VMS + N_("\ + --ftp-stmlf Use Stream_LF format for all binary FTP files.\n"), +#endif /* def __VMS */ N_("\ --ftp-user=USER set ftp user to USER.\n"), N_("\ @@ -600,8 +636,6 @@ FTP options:\n"), --no-passive-ftp disable the \"passive\" transfer mode.\n"), N_("\ --retr-symlinks when recursing, get linked-to files (not dir).\n"), - N_("\ - --preserve-permissions preserve remote file permissions.\n"), "\n", N_("\ @@ -615,8 +649,13 @@ Recursive download:\n"), N_("\ -k, --convert-links make links in downloaded HTML or CSS point to\n\ local files.\n"), +#ifdef __VMS + N_("\ + -K, --backup-converted before converting file X, back up as X_orig.\n"), +#else /* def __VMS */ N_("\ -K, --backup-converted before converting file X, back up as X.orig.\n"), +#endif /* def __VMS [else] */ N_("\ -m, --mirror shortcut for -N -r -l inf --no-remove-listing.\n"), N_("\ @@ -648,6 +687,9 @@ Recursive accept/reject:\n"), N_("\ -I, --include-directories=LIST list of allowed directories.\n"), N_("\ + --trust-server-names use the name specified by the redirection\n\ + url last component.\n"), + N_("\ -X, --exclude-directories=LIST list of excluded directories.\n"), N_("\ -np, --no-parent don't ascend to the parent directory.\n"), @@ -660,7 +702,7 @@ Recursive accept/reject:\n"), printf (_("GNU Wget %s, a non-interactive network retriever.\n"), version_string); - print_usage (); + print_usage (0); for (i = 0; i < countof (help); i++) fputs (_(help[i]), stdout); @@ -710,37 +752,35 @@ prompt_for_password (void) lines.*/ static void format_and_print_line (const char *prefix, const char *line, - int line_length) + int line_length) { - int leading_spaces; int remaining_chars; char *line_dup, *token; - + assert (prefix != NULL); assert (line != NULL); line_dup = xstrdup (line); if (line_length <= 0) - line_length = max_chars_per_line; + line_length = MAX_CHARS_PER_LINE - TABULATION; - leading_spaces = strlen (prefix); printf ("%s", prefix); - remaining_chars = line_length - leading_spaces; + remaining_chars = line_length; /* We break on spaces. */ token = strtok (line_dup, " "); - while (token != NULL) + while (token != NULL) { /* If however a token is much larger than the maximum line length, all bets are off and we simply print the token on the next line. */ - if (remaining_chars <= strlen (token)) + if (remaining_chars <= strlen (token)) { - printf ("\n%*c", leading_spaces, ' '); - remaining_chars = line_length - leading_spaces; + printf ("\n%*c", TABULATION, ' '); + remaining_chars = line_length - TABULATION; } printf ("%s ", token); - remaining_chars -= strlen (token) + 1; // account for " " + remaining_chars -= strlen (token) + 1; /* account for " " */ token = strtok (NULL, " "); } @@ -752,75 +792,68 @@ format_and_print_line (const char *prefix, const char *line, static void print_version (void) { - const char *options_title = "Options : "; - const char *wgetrc_title = "Wgetrc : "; - const char *locale_title = "Locale : "; - const char *compile_title = "Compile : "; - const char *link_title = "Link : "; - const char *prefix_spaces = " "; - const int prefix_space_length = strlen (prefix_spaces); - char *line; + const char *wgetrc_title = _("Wgetrc: "); + const char *locale_title = _("Locale: "); + const char *compile_title = _("Compile: "); + const char *link_title = _("Link: "); char *env_wgetrc, *user_wgetrc; int i; - printf ("GNU Wget %s\n", version_string); - printf (options_title); - /* compiled_features is a char*[]. We limit the characters per - line to max_chars_per_line and prefix each line with a constant - number of spaces for proper alignment. */ - for (i = 0; compiled_features[i] != NULL; ) + printf (_("GNU Wget %s built on %s.\n\n"), version_string, OS_TYPE); + + for (i = 0; compiled_features[i] != NULL; ) { - int line_length = max_chars_per_line - prefix_space_length; - while ((line_length > 0) && (compiled_features[i] != NULL)) + int line_length = MAX_CHARS_PER_LINE; + while ((line_length > 0) && (compiled_features[i] != NULL)) { printf ("%s ", compiled_features[i]); line_length -= strlen (compiled_features[i]) + 2; i++; } printf ("\n"); - if (compiled_features[i] != NULL) - { - printf (prefix_spaces); - } } - /* Handle the case when $WGETRC is unset and $HOME/.wgetrc is + printf ("\n"); + + /* Handle the case when $WGETRC is unset and $HOME/.wgetrc is absent. */ - printf (wgetrc_title); + printf ("%s\n", wgetrc_title); env_wgetrc = wgetrc_env_file_name (); - if (env_wgetrc && *env_wgetrc) + if (env_wgetrc && *env_wgetrc) { - printf ("%s (env)\n%s", env_wgetrc, prefix_spaces); + printf (_(" %s (env)\n"), env_wgetrc); xfree (env_wgetrc); } user_wgetrc = wgetrc_user_file_name (); - if (user_wgetrc) + if (user_wgetrc) { - printf ("%s (user)\n%s", user_wgetrc, prefix_spaces); + printf (_(" %s (user)\n"), user_wgetrc); xfree (user_wgetrc); } #ifdef SYSTEM_WGETRC - printf ("%s (system)\n", SYSTEM_WGETRC); -#else - putchar ('\n'); + printf (_(" %s (system)\n"), SYSTEM_WGETRC); #endif +#ifdef ENABLE_NLS format_and_print_line (locale_title, - LOCALEDIR, - max_chars_per_line); - - format_and_print_line (compile_title, - compilation_string, - max_chars_per_line); + LOCALEDIR, + MAX_CHARS_PER_LINE); +#endif /* def ENABLE_NLS */ - format_and_print_line (link_title, - link_string, - max_chars_per_line); + if (compilation_string != NULL) + format_and_print_line (compile_title, + compilation_string, + MAX_CHARS_PER_LINE); + + if (link_string != NULL) + format_and_print_line (link_title, + link_string, + MAX_CHARS_PER_LINE); printf ("\n"); /* TRANSLATORS: When available, an actual copyright character (cirle-c) should be used in preference to "(C)". */ fputs (_("\ -Copyright (C) 2008 Free Software Foundation, Inc.\n"), stdout); +Copyright (C) 2009 Free Software Foundation, Inc.\n"), stdout); fputs (_("\ License GPLv3+: GNU GPL version 3 or later\n\ .\n\ @@ -830,8 +863,6 @@ There is NO WARRANTY, to the extent permitted by law.\n"), stdout); names such as this one. See en_US.po for reference. */ fputs (_("\nOriginally written by Hrvoje Niksic .\n"), stdout); - fputs (_("Currently maintained by Micah Cowan .\n"), - stdout); fputs (_("Please send bug reports and questions to .\n"), stdout); exit (0); @@ -844,29 +875,75 @@ main (int argc, char **argv) { char **url, **t; int i, ret, longindex; - int nurl, status; + int nurl; bool append_to_log = false; + total_downloaded_bytes = 0; + program_name = argv[0]; + struct ptimer *timer = ptimer_new (); + double start_time = ptimer_measure (timer); + i18n_initialize (); /* Construct the name of the executable, without the directory part. */ +#ifdef __VMS + /* On VMS, lose the "dev:[dir]" prefix and the ".EXE;nnn" suffix. */ + exec_name = vms_basename (argv[0]); +#else /* def __VMS */ exec_name = strrchr (argv[0], PATH_SEPARATOR); if (!exec_name) exec_name = argv[0]; else ++exec_name; +#endif /* def __VMS [else] */ #ifdef WINDOWS /* Drop extension (typically .EXE) from executable filename. */ windows_main ((char **) &exec_name); #endif - /* Set option defaults; read the system wgetrc and ~/.wgetrc. */ - initialize (); + /* Load the hard-coded defaults. */ + defaults (); init_switches (); + + /* This seperate getopt_long is needed to find the user config + and parse it before the other user options. */ + longindex = -1; + int retconf; + bool use_userconfig = false; + + while ((retconf = getopt_long (argc, argv, + short_options, long_options, &longindex)) != -1) + { + int confval; + bool userrc_ret = true; + struct cmdline_option *config_opt; + confval = long_options[longindex].val; + config_opt = &option_data[confval & ~BOOLEAN_NEG_MARKER]; + if (strcmp (config_opt->long_name, "config") == 0) + { + userrc_ret &= run_wgetrc (optarg); + use_userconfig = true; + } + if (!userrc_ret) + { + printf ("Exiting due to error in %s\n", optarg); + exit (2); + } + else + break; + } + + /* If the user did not specify a config, read the system wgetrc and ~/.wgetrc. */ + if (use_userconfig == false) + initialize (); + + opterr = 0; + optind = 0; + longindex = -1; while ((ret = getopt_long (argc, argv, short_options, long_options, &longindex)) != -1) @@ -880,7 +957,7 @@ main (int argc, char **argv) { if (ret == '?') { - print_usage (); + print_usage (0); printf ("\n"); printf (_("Try `%s --help' for more options.\n"), exec_name); exit (2); @@ -929,7 +1006,7 @@ main (int argc, char **argv) short options for convenience and backward compatibility. */ char *p; - for (p = optarg; *p; p++) + for (p = optarg; p && *p; p++) switch (*p) { case 'v': @@ -948,10 +1025,12 @@ main (int argc, char **argv) setoptval ("noparent", "1", opt->long_name); break; default: - printf (_("%s: illegal option -- `-n%c'\n"), exec_name, *p); - print_usage (); - printf ("\n"); - printf (_("Try `%s --help' for more options.\n"), exec_name); + fprintf (stderr, _("%s: illegal option -- `-n%c'\n"), + exec_name, *p); + print_usage (1); + fprintf (stderr, "\n"); + fprintf (stderr, _("Try `%s --help' for more options.\n"), + exec_name); exit (1); } break; @@ -984,6 +1063,14 @@ main (int argc, char **argv) /* All user options have now been processed, so it's now safe to do interoption dependency checks. */ + if (opt.noclobber && opt.convert_links) + { + fprintf (stderr, + _("Both --no-clobber and --convert-links were specified," + "only --convert-links will be used.\n")); + opt.noclobber = false; + } + if (opt.reclevel == 0) opt.reclevel = INFINITE_RECURSION; /* see recur.h for commentary */ @@ -1006,34 +1093,35 @@ main (int argc, char **argv) /* Sanity checks. */ if (opt.verbose && opt.quiet) { - printf (_("Can't be verbose and quiet at the same time.\n")); - print_usage (); + fprintf (stderr, _("Can't be verbose and quiet at the same time.\n")); + print_usage (1); exit (1); } if (opt.timestamping && opt.noclobber) { - printf (_("\ + fprintf (stderr, _("\ Can't timestamp and not clobber old files at the same time.\n")); - print_usage (); + print_usage (1); exit (1); } #ifdef ENABLE_IPV6 if (opt.ipv4_only && opt.ipv6_only) { - printf (_("Cannot specify both --inet4-only and --inet6-only.\n")); - print_usage (); + fprintf (stderr, + _("Cannot specify both --inet4-only and --inet6-only.\n")); + print_usage (1); exit (1); } #endif if (opt.output_document) { - if (opt.convert_links + if (opt.convert_links && (nurl > 1 || opt.page_requisites || opt.recursive)) { fputs (_("\ Cannot specify both -k and -O if multiple URLs are given, or in combination\n\ -with -p or -r. See the manual for details.\n\n"), stdout); - print_usage (); +with -p or -r. See the manual for details.\n\n"), stderr); + print_usage (1); exit (1); } if (opt.page_requisites @@ -1050,33 +1138,57 @@ WARNING: timestamping does nothing in combination with -O. See the manual\n\ for details.\n\n")); opt.timestamping = false; } - if (opt.noclobber && file_exists_p(opt.output_document)) - { + if (opt.noclobber && file_exists_p(opt.output_document)) + { /* Check if output file exists; if it does, exit. */ - logprintf (LOG_VERBOSE, _("File `%s' already there; not retrieving.\n"), opt.output_document); + logprintf (LOG_VERBOSE, + _("File `%s' already there; not retrieving.\n"), + opt.output_document); exit(1); - } + } } if (opt.ask_passwd && opt.passwd) { - printf (_("Cannot specify both --ask-password and --password.\n")); - print_usage (); + fprintf (stderr, + _("Cannot specify both --ask-password and --password.\n")); + print_usage (1); exit (1); } if (!nurl && !opt.input_filename) { /* No URL specified. */ - printf (_("%s: missing URL\n"), exec_name); - print_usage (); + fprintf (stderr, _("%s: missing URL\n"), exec_name); + print_usage (1); printf ("\n"); /* #### Something nicer should be printed here -- similar to the pre-1.5 `--help' page. */ - printf (_("Try `%s --help' for more options.\n"), exec_name); + fprintf (stderr, _("Try `%s --help' for more options.\n"), exec_name); exit (1); } +#ifdef ENABLE_IRI + if (opt.enable_iri) + { + if (opt.locale && !check_encoding_name (opt.locale)) + opt.locale = NULL; + + if (!opt.locale) + opt.locale = find_locale (); + + if (opt.encoding_remote && !check_encoding_name (opt.encoding_remote)) + opt.encoding_remote = NULL; + } +#else + if (opt.enable_iri || opt.locale || opt.encoding_remote) + { + /* sXXXav : be more specific... */ + fprintf (stderr, _("This version does not have support for IRIs\n")); + exit(1); + } +#endif + if (opt.ask_passwd) { opt.passwd = prompt_for_password (); @@ -1085,7 +1197,7 @@ for details.\n\n")); exit (1); } -#ifdef MSDOS +#ifdef USE_WATT32 if (opt.wdebug) dbug_init(); sock_init(); @@ -1114,17 +1226,26 @@ for details.\n\n")); /* Initialize logging. */ log_init (opt.lfilename, append_to_log); - DEBUGP (("DEBUG output created by Wget %s on %s.\n\n", version_string, - OS_TYPE)); + DEBUGP (("DEBUG output created by Wget %s on %s.\n\n", + version_string, OS_TYPE)); /* Open the output filename if necessary. */ + +/* 2005-04-17 SMS. + Note that having the output_stream ("-O") file opened here for an FTP + URL rather than in getftp() (ftp.c) (and the http equivalent) rather + limits the ability in VMS to open the file differently for ASCII + versus binary FTP there. (Of course, doing it here allows a open + failure to be detected immediately, without first connecting to the + server.) +*/ if (opt.output_document) { if (HYPHENP (opt.output_document)) { #ifdef WINDOWS FILE *result; - result = freopen (NULL, "wb", stdout); + result = freopen ("CONOUT$", "wb", stdout); if (result == NULL) { logputs (LOG_NOTQUIET, _("\ @@ -1137,8 +1258,20 @@ WARNING: Can't reopen standard output in binary mode;\n\ else { struct_fstat st; + +#ifdef __VMS +/* Common fopen() optional arguments: + sequential access only, access callback function. +*/ +# define FOPEN_OPT_ARGS , "fop=sqo", "acc", acc_cb, &open_id + int open_id = 7; +#else /* def __VMS */ +# define FOPEN_OPT_ARGS +#endif /* def __VMS [else] */ + output_stream = fopen (opt.output_document, - opt.always_rest ? "ab" : "wb"); + opt.always_rest ? "ab" : "wb" + FOPEN_OPT_ARGS); if (output_stream == NULL) { perror (opt.output_document); @@ -1147,8 +1280,25 @@ WARNING: Can't reopen standard output in binary mode;\n\ if (fstat (fileno (output_stream), &st) == 0 && S_ISREG (st.st_mode)) output_stream_regular = true; } + if (!output_stream_regular && opt.convert_links) + { + fprintf (stderr, _("-k can be used together with -O only if \ +outputting to a regular file.\n")); + print_usage (1); + exit(1); + } } +#ifdef __VMS + /* Set global ODS5 flag according to the specified destination (if + any), otherwise according to the current default device. + */ + if (output_stream == NULL) + set_ods5_dest( "SYS$DISK"); + else if (output_stream != stdout) + set_ods5_dest( opt.output_document); +#endif /* def __VMS */ + #ifdef WINDOWS ws_startup (); #endif @@ -1173,46 +1323,66 @@ WARNING: Can't reopen standard output in binary mode;\n\ signal (SIGWINCH, progress_handle_sigwinch); #endif - status = RETROK; /* initialize it, just-in-case */ /* Retrieve the URLs from argument list. */ for (t = url; *t; t++) { char *filename = NULL, *redirected_URL = NULL; - int dt; - - if ((opt.recursive || opt.page_requisites) - && (url_scheme (*t) != SCHEME_FTP || url_uses_proxy (*t))) - { - int old_follow_ftp = opt.follow_ftp; + int dt, url_err; + /* Need to do a new struct iri every time, because + * retrieve_url may modify it in some circumstances, + * currently. */ + struct iri *iri = iri_new (); + struct url *url_parsed; - /* Turn opt.follow_ftp on in case of recursive FTP retrieval */ - if (url_scheme (*t) == SCHEME_FTP) - opt.follow_ftp = 1; - - status = retrieve_tree (*t); + set_uri_encoding (iri, opt.locale, true); + url_parsed = url_parse (*t, &url_err, iri, true); - opt.follow_ftp = old_follow_ftp; + if (!url_parsed) + { + char *error = url_error (*t, url_err); + logprintf (LOG_NOTQUIET, "%s: %s.\n",*t, error); + xfree (error); } else - status = retrieve_url (*t, &filename, &redirected_URL, NULL, &dt, opt.recursive); - - if (opt.delete_after && file_exists_p(filename)) { - DEBUGP (("Removing file due to --delete-after in main():\n")); - logprintf (LOG_VERBOSE, _("Removing %s.\n"), filename); - if (unlink (filename)) - logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno)); - } + if ((opt.recursive || opt.page_requisites) + && (url_scheme (*t) != SCHEME_FTP || url_uses_proxy (url_parsed))) + { + int old_follow_ftp = opt.follow_ftp; + + /* Turn opt.follow_ftp on in case of recursive FTP retrieval */ + if (url_scheme (*t) == SCHEME_FTP) + opt.follow_ftp = 1; + + retrieve_tree (url_parsed, NULL); + + opt.follow_ftp = old_follow_ftp; + } + else + { + retrieve_url (url_parsed, *t, &filename, &redirected_URL, NULL, + &dt, opt.recursive, iri, true); + } - xfree_null (redirected_URL); - xfree_null (filename); + if (opt.delete_after && file_exists_p(filename)) + { + DEBUGP (("Removing file due to --delete-after in main():\n")); + logprintf (LOG_VERBOSE, _("Removing %s.\n"), filename); + if (unlink (filename)) + logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno)); + } + xfree_null (redirected_URL); + xfree_null (filename); + url_free (url_parsed); + } + iri_free (iri); } /* And then from the input file, if any. */ if (opt.input_filename) { int count; - status = retrieve_from_file (opt.input_filename, opt.force_html, &count); + retrieve_from_file (opt.input_filename, opt.force_html, &count); if (!count) logprintf (LOG_NOTQUIET, _("No URLs found in %s.\n"), opt.input_filename); @@ -1220,10 +1390,8 @@ WARNING: Can't reopen standard output in binary mode;\n\ /* Print broken links. */ if (opt.recursive && opt.spider) - { - print_broken_links(); - } - + print_broken_links (); + /* Print the downloaded sum. */ if ((opt.recursive || opt.page_requisites || nurl > 1 @@ -1231,13 +1399,23 @@ WARNING: Can't reopen standard output in binary mode;\n\ && total_downloaded_bytes != 0) { + double end_time = ptimer_measure (timer); + ptimer_destroy (timer); + + char *wall_time = xstrdup (secs_to_human_time (end_time - start_time)); + char *download_time = xstrdup (secs_to_human_time (total_download_time)); logprintf (LOG_NOTQUIET, - _("FINISHED --%s--\nDownloaded: %d files, %s in %s (%s)\n"), - datetime_str (time (NULL)), - numurls, - human_readable (total_downloaded_bytes), - secs_to_human_time (total_download_time), - retr_rate (total_downloaded_bytes, total_download_time)); + _("FINISHED --%s--\nTotal wall clock time: %s\n" + "Downloaded: %d files, %s in %s (%s)\n"), + datetime_str (time (NULL)), + wall_time, + numurls, + human_readable (total_downloaded_bytes), + download_time, + retr_rate (total_downloaded_bytes, total_download_time)); + xfree (wall_time); + xfree (download_time); + /* Print quota warning, if exceeded. */ if (opt.quota && total_downloaded_bytes > opt.quota) logprintf (LOG_NOTQUIET, @@ -1256,10 +1434,7 @@ WARNING: Can't reopen standard output in binary mode;\n\ xfree (url[i]); cleanup (); - if (status == RETROK) - return 0; - else - return 1; + return get_exit_status (); } #endif /* TESTING */