X-Git-Url: http://sjero.net/git/?p=wget;a=blobdiff_plain;f=src%2Fmain.c;h=5898a1989058995a619b3d244037f853c4f4684d;hp=3e32c40967e342c4874ece4901095f07e0f8486b;hb=d5e283b1a75c5f8249300b465b4e7b55130bec49;hpb=7a54d852bfa09c828bbc4907adddee7e4beb1715 diff --git a/src/main.c b/src/main.c index 3e32c409..5898a198 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,6 @@ /* Command line parsing. Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GNU Wget. @@ -56,6 +56,8 @@ as that of the covered work. */ #include "http.h" /* for save_cookies */ #include +#include +#include #ifdef __VMS #include "vms.h" @@ -69,13 +71,25 @@ as that of the covered work. */ struct options opt; +/* defined in version.c */ extern char *version_string; +extern char *compilation_string; +extern char *system_getrc; +extern char *link_string; +/* defined in build_info.c */ +extern char *compiled_features[]; +/* Used for --version output in print_version */ +#define MAX_CHARS_PER_LINE 72 +#define TABULATION 4 #if defined(SIGHUP) || defined(SIGUSR1) static void redirect_output_signal (int); #endif const char *exec_name; + +/* Number of successfully downloaded URLs */ +int numurls = 0; #ifndef TESTING /* Initialize I18N/L10N. That amounts to invoking setlocale, and @@ -136,6 +150,7 @@ static struct cmdline_option option_data[] = { { "accept", 'A', OPT_VALUE, "accept", -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 }, { "background", 'b', OPT_BOOLEAN, "background", -1 }, { "backup-converted", 'K', OPT_BOOLEAN, "backupconverted", -1 }, @@ -156,6 +171,7 @@ static struct cmdline_option option_data[] = { "cookies", 0, OPT_BOOLEAN, "cookies", -1 }, { "cut-dirs", 0, OPT_VALUE, "cutdirs", -1 }, { WHEN_DEBUG ("debug"), 'd', OPT_BOOLEAN, "debug", -1 }, + { "default-page", 0, OPT_VALUE, "defaultpage", -1 }, { "delete-after", 0, OPT_BOOLEAN, "deleteafter", -1 }, { "directories", 0, OPT_BOOLEAN, "dirstruct", -1 }, { "directory-prefix", 'P', OPT_VALUE, "dirprefix", -1 }, @@ -196,10 +212,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 }, + { "locale", 0, OPT_VALUE, "locale", -1 }, { "max-redirect", 0, OPT_VALUE, "maxredirect", -1 }, { "mirror", 'm', OPT_BOOLEAN, "mirror", -1 }, { "no", 'n', OPT__NO, NULL, required_argument }, @@ -233,6 +251,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 }, @@ -300,7 +319,7 @@ static void init_switches (void) { char *p = short_options; - int i, o = 0; + size_t i, o = 0; for (i = 0; i < countof (option_data); i++) { struct cmdline_option *opt = &option_data[i]; @@ -411,7 +430,7 @@ Logging and input file:\n"), N_("\ -nv, --no-verbose turn off verboseness, without being quiet.\n"), N_("\ - -i, --input-file=FILE download URLs found in FILE.\n"), + -i, --input-file=FILE download URLs found in local or external FILE.\n"), N_("\ -F, --force-html treat input file as HTML.\n"), N_("\ @@ -481,6 +500,8 @@ Download:\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_("\ + --ask-password prompt for passwords.\n"), "\n", N_("\ @@ -507,6 +528,9 @@ HTTP options:\n"), --http-password=PASS set http password to PASS.\n"), N_("\ --no-cache disallow server-cached data.\n"), + 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"), N_("\ @@ -606,7 +630,8 @@ Recursive download:\n"), N_("\ --delete-after delete files locally after downloading them.\n"), N_("\ - -k, --convert-links make links in downloaded HTML point to local files.\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"), @@ -653,7 +678,7 @@ Recursive accept/reject:\n"), N_("Mail bug reports and suggestions to .\n") }; - int i; + size_t i; printf (_("GNU Wget %s, a non-interactive network retriever.\n"), VERSION_STRING); @@ -691,15 +716,124 @@ secs_to_human_time (double interval) return buf; } +static char * +prompt_for_password (void) +{ + if (opt.user) + printf (_("Password for user %s: "), quote (opt.user)); + else + printf (_("Password: ")); + return getpass(""); +} + +/* Function that prints the line argument while limiting it + to at most line_length. prefix is printed on the first line + and an appropriate number of spaces are added on subsequent + lines.*/ +static void +format_and_print_line (const char *prefix, const char *line, + int line_length) +{ + 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 - TABULATION; + + printf ("%s", prefix); + remaining_chars = line_length; + /* We break on spaces. */ + token = strtok (line_dup, " "); + 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)) + { + printf ("\n%*c", TABULATION, ' '); + remaining_chars = line_length - TABULATION; + } + printf ("%s ", token); + remaining_chars -= strlen (token) + 1; /* account for " " */ + token = strtok (NULL, " "); + } + + printf ("\n"); + + xfree (line_dup); +} + static void print_version (void) { + const char *wgetrc_title = _("Wgetrc: "); + const char *locale_title = _("Locale: "); + const char *compile_title = _("Compile: "); + const char *link_title = _("Link: "); + char *line; + char *env_wgetrc, *user_wgetrc; + int i; + + printf (_("GNU Wget %s\n\n"), version_string); #ifdef __VMS printf ("GNU Wget %s built on VMS %s %s.\n\n", VERSION_STRING, vms_arch(), vms_vers()); #else /* def __VMS */ - printf ("GNU Wget %s built on %s.\n\n", VERSION_STRING, OS_TYPE); + printf ("GNU Wget %s built on %s.\n\n", version_string, OS_TYPE); #endif /* def __VMS */ + /* 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; ) + { + 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"); + } + printf ("\n"); + /* Handle the case when $WGETRC is unset and $HOME/.wgetrc is + absent. */ + printf ("%s\n", wgetrc_title); + env_wgetrc = wgetrc_env_file_name (); + if (env_wgetrc && *env_wgetrc) + { + printf (" %s (env)\n", env_wgetrc); + xfree (env_wgetrc); + } + user_wgetrc = wgetrc_user_file_name (); + if (user_wgetrc) + { + printf (" %s (user)\n", user_wgetrc); + xfree (user_wgetrc); + } +#ifdef SYSTEM_WGETRC + printf (" %s (system)\n", SYSTEM_WGETRC); +#endif + + format_and_print_line (locale_title, + LOCALEDIR, + MAX_CHARS_PER_LINE); + + format_and_print_line (compile_title, + compilation_string, + MAX_CHARS_PER_LINE); + + 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 (_("\ @@ -715,9 +849,12 @@ There is NO WARRANTY, to the extent permitted by law.\n"), stdout); stdout); fputs (_("Currently maintained by Micah Cowan .\n"), stdout); + fputs (_("Please send bug reports and questions to .\n"), + stdout); exit (0); } - + +char *program_name; /* Needed by lib/error.c. */ int main (int argc, char **argv) @@ -727,6 +864,8 @@ main (int argc, char **argv) int nurl, status; bool append_to_log = false; + program_name = argv[0]; + i18n_initialize (); /* Construct the name of the executable, without the directory part. */ @@ -903,22 +1042,44 @@ Can't timestamp and not clobber old files at the same time.\n")); exit (1); } #endif - if (opt.output_document - && (opt.page_requisites - || opt.recursive - || opt.timestamping)) + if (opt.output_document) { - printf (_("Cannot specify -r, -p or -N if -O is given.\n")); + 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 (); exit (1); + } + if (opt.page_requisites + || opt.recursive) + { + logprintf (LOG_NOTQUIET, "%s", _("\ +WARNING: combining -O with -r or -p will mean that all downloaded content\n\ +will be placed in the single file you specified.\n\n")); + } + if (opt.timestamping) + { + logprintf (LOG_NOTQUIET, "%s", _("\ +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)) + { + /* Check if output file exists; if it does, exit. */ + logprintf (LOG_VERBOSE, _("File `%s' already there; not retrieving.\n"), opt.output_document); + exit(1); + } } - if (opt.output_document - && opt.convert_links - && nurl > 1) + + if (opt.ask_passwd && opt.passwd) { - printf (_("Cannot specify both -k and -O if multiple URLs are given.\n")); - print_usage (); - exit (1); + printf (_("Cannot specify both --ask-password and --password.\n")); + print_usage (); + exit (1); } if (!nurl && !opt.input_filename) @@ -933,6 +1094,35 @@ Can't timestamp and not clobber old files at the same time.\n")); 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... */ + printf(_("This version does not have support for IRIs\n")); + exit(1); + } +#endif + + if (opt.ask_passwd) + { + opt.passwd = prompt_for_password (); + + if (opt.passwd == NULL || opt.passwd[0] == '\0') + exit (1); + } + #ifdef MSDOS if (opt.wdebug) dbug_init(); @@ -978,7 +1168,19 @@ Can't timestamp and not clobber old files at the same time.\n")); if (opt.output_document) { if (HYPHENP (opt.output_document)) - output_stream = stdout; + { +#ifdef WINDOWS + FILE *result; + result = freopen ("CONOUT$", "wb", stdout); + if (result == NULL) + { + logputs (LOG_NOTQUIET, _("\ +WARNING: Can't reopen standard output in binary mode;\n\ + downloaded file may contain inappropriate line endings.\n")); + } +#endif + output_stream = stdout; + } else { struct_fstat st; @@ -1049,34 +1251,56 @@ Can't timestamp and not clobber old files at the same time.\n")); for (t = url; *t; t++) { char *filename = NULL, *redirected_URL = NULL; - int dt; + 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; - if ((opt.recursive || opt.page_requisites) - && (url_scheme (*t) != SCHEME_FTP || url_uses_proxy (*t))) + set_uri_encoding (iri, opt.locale, true); + url_parsed = url_parse (*t, &url_err, iri, true); + + if (!url_parsed) { - int old_follow_ftp = opt.follow_ftp; + char *error = url_error (*t, url_err); + logprintf (LOG_NOTQUIET, "%s: %s.\n",*t, error); + xfree (error); + status = URLERROR; + } + else + { + 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; + /* 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); + status = retrieve_tree (url_parsed, NULL); - opt.follow_ftp = old_follow_ftp; - } - else - status = retrieve_url (*t, &filename, &redirected_URL, NULL, &dt, opt.recursive); + opt.follow_ftp = old_follow_ftp; + } + else + { + status = retrieve_url (url_parsed, *t, &filename, &redirected_URL, + NULL, &dt, opt.recursive, iri); + } - 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.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); } - - xfree_null (redirected_URL); - xfree_null (filename); + iri_free (iri); } /* And then from the input file, if any. */ @@ -1105,7 +1329,7 @@ Can't timestamp and not clobber old files at the same time.\n")); logprintf (LOG_NOTQUIET, _("FINISHED --%s--\nDownloaded: %d files, %s in %s (%s)\n"), datetime_str (time (NULL)), - opt.numurls, + numurls, human_readable (total_downloaded_bytes), secs_to_human_time (total_download_time), retr_rate (total_downloaded_bytes, total_download_time)); @@ -1127,9 +1351,6 @@ Can't timestamp and not clobber old files at the same time.\n")); xfree (url[i]); cleanup (); -#ifdef DEBUG_MALLOC - print_malloc_debug_stats (); -#endif if (status == RETROK) return 0; else