X-Git-Url: http://sjero.net/git/?p=wget;a=blobdiff_plain;f=src%2Fmain.c;h=cfcdbbe3ad52f9e72fefbbaa31fb4505231d62a7;hp=1b85b0b35a9226bd72fe10a0ab987337312ddb1b;hb=30ac043b0a4a9a983dd1b50ce1c89ed953019292;hpb=62994ffc8c14188f4a61ef96514fe849ba2cc87d diff --git a/src/main.c b/src/main.c index 1b85b0b3..cfcdbbe3 100644 --- a/src/main.c +++ b/src/main.c @@ -1,27 +1,37 @@ /* Command line parsing. - Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002 + Free Software Foundation, Inc. -This file is part of Wget. +This file is part of GNU Wget. -This program is free software; you can redistribute it and/or modify +GNU Wget is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. -This program is distributed in the hope that it will be useful, +GNU Wget is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +along with Wget; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +In addition, as a special exception, the Free Software Foundation +gives permission to link the code of its release of Wget with the +OpenSSL project's "OpenSSL" library (or with modified versions of it +that use the same license as the "OpenSSL" library), and distribute +the linked executables. You must obey the GNU General Public License +in all respects for all of the code used other than "OpenSSL". If you +modify this file, you may extend this exception to your version of the +file, but you are not obligated to do so. If you do not wish to do +so, delete this exception statement from your version. */ #include #include #include -#include #ifdef HAVE_UNISTD_H # include #endif /* HAVE_UNISTD_H */ @@ -39,16 +49,24 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ # include #endif /* HAVE_LOCALE_H */ #endif /* HAVE_NLS */ - -#define OPTIONS_DEFINED_HERE /* for options.h */ +#include #include "wget.h" #include "utils.h" -#include "getopt.h" #include "init.h" #include "retr.h" #include "recur.h" #include "host.h" +#include "cookies.h" +#include "url.h" +#include "progress.h" /* for progress_handle_sigwinch */ + +#ifdef HAVE_SSL +# include "gen_sslfunc.h" +#endif + +/* On GNU system this will include system-wide getopt.h. */ +#include "getopt.h" #ifndef PATH_SEPARATOR # define PATH_SEPARATOR '/' @@ -62,10 +80,12 @@ extern int errno; struct options opt; +extern struct cookie_jar *wget_cookie_jar; + /* From log.c. */ void log_init PARAMS ((const char *, int)); void log_close PARAMS ((void)); -void redirect_output PARAMS ((const char *)); +void log_request_redirect_output PARAMS ((const char *)); static RETSIGTYPE redirect_output_signal PARAMS ((int)); @@ -89,6 +109,7 @@ i18n_initialize (void) makes http_atotm() malfunction. */ #ifdef LC_MESSAGES setlocale (LC_MESSAGES, ""); + setlocale (LC_CTYPE, ""); #else setlocale (LC_ALL, ""); #endif @@ -97,20 +118,6 @@ i18n_initialize (void) textdomain ("wget"); #endif /* HAVE_NLS */ } - -/* It's kosher to declare these here because their interface _has_ to - be void foo(void). */ -void url_init PARAMS ((void)); -void host_init PARAMS ((void)); - -/* This just calls the various initialization functions from the - modules that need one-time initialization. */ -static void -private_initialize (void) -{ - url_init (); - host_init (); -} /* Print the usage message. */ static void @@ -129,16 +136,18 @@ print_help (void) print_usage (); /* Had to split this in parts, so the #@@#%# Ultrix compiler and cpp don't bitch. Also, it makes translation much easier. */ - printf ("%s%s%s%s%s%s%s%s%s%s", _("\ + fputs (_("\ \n\ Mandatory arguments to long options are mandatory for short options too.\n\ -\n"), _("\ +\n"), stdout); + fputs (_("\ Startup:\n\ -V, --version display the version of Wget and exit.\n\ -h, --help print this help.\n\ -b, --background go to background after startup.\n\ -e, --execute=COMMAND execute a `.wgetrc\'-style command.\n\ -\n"), _("\ +\n"), stdout); + fputs (_("\ Logging and input file:\n\ -o, --output-file=FILE log messages to FILE.\n\ -a, --append-output=FILE append messages to FILE.\n\ @@ -149,30 +158,36 @@ Logging and input file:\n\ -i, --input-file=FILE download URLs found in FILE.\n\ -F, --force-html treat input file as HTML.\n\ -B, --base=URL prepends URL to relative links in -F -i file.\n\ -\n"), _("\ +\n"),stdout); + fputs (_("\ Download:\n\ - --bind-address=ADDRESS bind to ADDRESS (hostname or IP) on local host.\n\ -t, --tries=NUMBER set number of retries to NUMBER (0 unlimits).\n\ + --retry-connrefused retry even if connection is refused.\n\ -O --output-document=FILE write documents to FILE.\n\ -nc, --no-clobber don\'t clobber existing files or use .# suffixes.\n\ - -c, --continue restart getting an existing file.\n\ - --dot-style=STYLE set retrieval display style.\n\ - -N, --timestamping don\'t retrieve files if older than local.\n\ + -c, --continue resume getting a partially-downloaded file.\n\ + --progress=TYPE select progress gauge type.\n\ + -N, --timestamping don\'t re-retrieve files unless newer than local.\n\ -S, --server-response print server response.\n\ --spider don\'t download anything.\n\ -T, --timeout=SECONDS set the read timeout to SECONDS.\n\ -w, --wait=SECONDS wait SECONDS between retrievals.\n\ --waitretry=SECONDS wait 1...SECONDS between retries of a retrieval.\n\ + --random-wait wait from 0...2*WAIT secs between retrievals.\n\ -Y, --proxy=on/off turn proxy on or off.\n\ -Q, --quota=NUMBER set retrieval quota to NUMBER.\n\ -\n"), _("\ + --bind-address=ADDRESS bind to ADDRESS (hostname or IP) on local host.\n\ + --limit-rate=RATE limit download rate to RATE.\n\ +\n"), stdout); + fputs (_("\ Directories:\n\ -nd --no-directories don\'t create directories.\n\ -x, --force-directories force creation of directories.\n\ -nH, --no-host-directories don\'t create host directories.\n\ -P, --directory-prefix=PREFIX save files to PREFIX/...\n\ --cut-dirs=NUMBER ignore NUMBER remote directory components.\n\ -\n"), _("\ +\n"), stdout); + fputs (_("\ HTTP options:\n\ --http-user=USER set http user to USER.\n\ --http-passwd=PASS set http password to PASS.\n\ @@ -185,22 +200,45 @@ HTTP options:\n\ --referer=URL include `Referer: URL\' header in HTTP request.\n\ -s, --save-headers save the HTTP headers to file.\n\ -U, --user-agent=AGENT identify as AGENT instead of Wget/VERSION.\n\ -\n"), _("\ + --no-http-keep-alive disable HTTP keep-alive (persistent connections).\n\ + --cookies=off don't use cookies.\n\ + --load-cookies=FILE load cookies from FILE before session.\n\ + --save-cookies=FILE save cookies to FILE after session.\n\ + --post-data=STRING use the POST method; send STRING as the data.\n\ + --post-file=FILE use the POST method; send contents of FILE.\n\ +\n"), stdout); +#ifdef HAVE_SSL + fputs (_("\ +HTTPS (SSL) options:\n\ + --sslcertfile=FILE optional client certificate.\n\ + --sslcertkey=KEYFILE optional keyfile for this certificate.\n\ + --egd-file=FILE file name of the EGD socket.\n\ + --sslcadir=DIR dir where hash list of CA's are stured.\n\ + --sslcafile=FILE file with bundle of CA's\n\ + --sslcerttype=0/1 Client-Cert type 0=PEM (default) / 1=ASN1 (DER)\n\ + --sslcheckcert=0/1 Check the server cert agenst given CA\n\ + --sslprotocol=0-3 choose SSL protocol; 0=automatic,\n\ + 1=SSLv2 2=SSLv3 3=TLSv1\n\ +\n"), stdout); +#endif + fputs (_("\ FTP options:\n\ - --retr-symlinks when recursing, retrieve linked-to files (not dirs).\n\ - -g, --glob=on/off turn file name globbing on or off.\n\ - --passive-ftp use the \"passive\" transfer mode.\n\ -\n"), _("\ -Recursive retrieval:\n\ - -r, --recursive recursive web-suck -- use with care!.\n\ - -l, --level=NUMBER maximum recursion depth (inf or 0 for infinite).\n\ - --delete-after delete files locally after downloading them.\n\ - -k, --convert-links convert non-relative links to relative.\n\ - -K, --backup-converted before converting file X, back up as X.orig.\n\ - -m, --mirror shortcut option equivalent to -r -N -l inf -nr.\n\ -nr, --dont-remove-listing don\'t remove `.listing\' files.\n\ - -p, --page-requisites get all images, etc. needed to display HTML page.\n\ -\n"), _("\ + -g, --glob=on/off turn file name globbing on or off.\n\ + --passive-ftp use the \"passive\" transfer mode.\n\ + --retr-symlinks when recursing, get linked-to files (not dirs).\n\ +\n"), stdout); + fputs (_("\ +Recursive retrieval:\n\ + -r, --recursive recursive download.\n\ + -l, --level=NUMBER maximum recursion depth (inf or 0 for infinite).\n\ + --delete-after delete files locally after downloading them.\n\ + -k, --convert-links convert non-relative links to relative.\n\ + -K, --backup-converted before converting file X, back up as X.orig.\n\ + -m, --mirror shortcut option equivalent to -r -N -l inf -nr.\n\ + -p, --page-requisites get all images, etc. needed to display HTML page.\n\ +\n"), stdout); + fputs (_("\ Recursive accept/reject:\n\ -A, --accept=LIST comma-separated list of accepted extensions.\n\ -R, --reject=LIST comma-separated list of rejected extensions.\n\ @@ -213,9 +251,10 @@ Recursive accept/reject:\n\ -L, --relative follow relative links only.\n\ -I, --include-directories=LIST list of allowed directories.\n\ -X, --exclude-directories=LIST list of excluded directories.\n\ - -nh, --no-host-lookup don\'t DNS-lookup hosts.\n\ -np, --no-parent don\'t ascend to the parent directory.\n\ -\n"), _("Mail bug reports and suggestions to .\n")); +\n"), stdout); + fputs (_("Mail bug reports and suggestions to .\n"), + stdout); } int @@ -223,43 +262,44 @@ main (int argc, char *const *argv) { char **url, **t; int i, c, nurl, status, append_to_log; - int wr = 0; static struct option long_options[] = { /* Options without arguments: */ { "background", no_argument, NULL, 'b' }, + { "backup-converted", no_argument, NULL, 'K' }, { "continue", no_argument, NULL, 'c' }, { "convert-links", no_argument, NULL, 'k' }, - { "backup-converted", no_argument, NULL, 'K' }, { "debug", no_argument, NULL, 'd' }, - { "dont-remove-listing", no_argument, NULL, 21 }, - { "email-address", no_argument, NULL, 26 }, /* undocumented (debug) */ - { "follow-ftp", no_argument, NULL, 14 }, + { "delete-after", no_argument, NULL, 136 }, + { "dont-remove-listing", no_argument, NULL, 149 }, + { "follow-ftp", no_argument, NULL, 142 }, { "force-directories", no_argument, NULL, 'x' }, { "force-hier", no_argument, NULL, 'x' }, /* obsolete */ { "force-html", no_argument, NULL, 'F'}, { "help", no_argument, NULL, 'h' }, { "html-extension", no_argument, NULL, 'E' }, - { "ignore-length", no_argument, NULL, 10 }, + { "ignore-length", no_argument, NULL, 138 }, { "mirror", no_argument, NULL, 'm' }, - { "no-clobber", no_argument, NULL, 13 }, - { "no-directories", no_argument, NULL, 19 }, - { "no-host-directories", no_argument, NULL, 20 }, - { "no-host-lookup", no_argument, NULL, 22 }, - { "no-http-keep-alive", no_argument, NULL, 28 }, - { "no-parent", no_argument, NULL, 5 }, - { "non-verbose", no_argument, NULL, 18 }, - { "passive-ftp", no_argument, NULL, 11 }, + { "no-clobber", no_argument, NULL, 141 }, + { "no-directories", no_argument, NULL, 147 }, + { "no-host-directories", no_argument, NULL, 148 }, + { "no-host-lookup", no_argument, NULL, 150 }, + { "no-http-keep-alive", no_argument, NULL, 156 }, + { "no-parent", no_argument, NULL, 133 }, + { "non-verbose", no_argument, NULL, 146 }, + { "passive-ftp", no_argument, NULL, 139 }, { "page-requisites", no_argument, NULL, 'p' }, { "quiet", no_argument, NULL, 'q' }, + { "random-wait", no_argument, NULL, 165 }, { "recursive", no_argument, NULL, 'r' }, { "relative", no_argument, NULL, 'L' }, - { "retr-symlinks", no_argument, NULL, 9 }, + { "retr-symlinks", no_argument, NULL, 137 }, + { "retry-connrefused", no_argument, NULL, 174 }, { "save-headers", no_argument, NULL, 's' }, { "server-response", no_argument, NULL, 'S' }, { "span-hosts", no_argument, NULL, 'H' }, - { "spider", no_argument, NULL, 4 }, + { "spider", no_argument, NULL, 132 }, { "timestamping", no_argument, NULL, 'N' }, { "verbose", no_argument, NULL, 'v' }, { "version", no_argument, NULL, 'V' }, @@ -267,48 +307,63 @@ main (int argc, char *const *argv) /* Options accepting an argument: */ { "accept", required_argument, NULL, 'A' }, { "append-output", required_argument, NULL, 'a' }, - { "backups", required_argument, NULL, 23 }, /* undocumented */ + { "backups", required_argument, NULL, 151 }, /* undocumented */ { "base", required_argument, NULL, 'B' }, - { "bind-address", required_argument, NULL, 27 }, + { "bind-address", required_argument, NULL, 155 }, { "cache", required_argument, NULL, 'C' }, - { "cut-dirs", required_argument, NULL, 17 }, - { "delete-after", no_argument, NULL, 8 }, + { "cookies", required_argument, NULL, 160 }, + { "cut-dirs", required_argument, NULL, 145 }, { "directory-prefix", required_argument, NULL, 'P' }, { "domains", required_argument, NULL, 'D' }, - { "dot-style", required_argument, NULL, 6 }, + { "dot-style", required_argument, NULL, 134 }, { "execute", required_argument, NULL, 'e' }, { "exclude-directories", required_argument, NULL, 'X' }, - { "exclude-domains", required_argument, NULL, 12 }, - { "follow-tags", required_argument, NULL, 25 }, + { "exclude-domains", required_argument, NULL, 140 }, + { "follow-tags", required_argument, NULL, 153 }, { "glob", required_argument, NULL, 'g' }, - { "header", required_argument, NULL, 3 }, - { "htmlify", required_argument, NULL, 7 }, - { "http-passwd", required_argument, NULL, 2 }, - { "http-user", required_argument, NULL, 1 }, + { "header", required_argument, NULL, 131 }, + { "htmlify", required_argument, NULL, 135 }, + { "http-passwd", required_argument, NULL, 130 }, + { "http-user", required_argument, NULL, 129 }, { "ignore-tags", required_argument, NULL, 'G' }, { "include-directories", required_argument, NULL, 'I' }, { "input-file", required_argument, NULL, 'i' }, { "level", required_argument, NULL, 'l' }, + { "limit-rate", required_argument, NULL, 164 }, + { "load-cookies", required_argument, NULL, 161 }, { "no", required_argument, NULL, 'n' }, { "output-document", required_argument, NULL, 'O' }, { "output-file", required_argument, NULL, 'o' }, + { "post-data", required_argument, NULL, 167 }, + { "post-file", required_argument, NULL, 168 }, + { "progress", required_argument, NULL, 163 }, { "proxy", required_argument, NULL, 'Y' }, - { "proxy-passwd", required_argument, NULL, 16 }, - { "proxy-user", required_argument, NULL, 15 }, + { "proxy-passwd", required_argument, NULL, 144 }, + { "proxy-user", required_argument, NULL, 143 }, { "quota", required_argument, NULL, 'Q' }, { "reject", required_argument, NULL, 'R' }, + { "save-cookies", required_argument, NULL, 162 }, { "timeout", required_argument, NULL, 'T' }, { "tries", required_argument, NULL, 't' }, { "user-agent", required_argument, NULL, 'U' }, - { "referer", required_argument, NULL, 129 }, + { "referer", required_argument, NULL, 157 }, { "use-proxy", required_argument, NULL, 'Y' }, +#ifdef HAVE_SSL + { "sslcertfile", required_argument, NULL, 158 }, + { "sslcertkey", required_argument, NULL, 159 }, + { "egd-file", required_argument, NULL, 166 }, + { "sslcadir", required_argument, NULL, 169}, + { "sslcafile", required_argument, NULL, 170}, + { "sslcerttype", required_argument, NULL, 171}, + { "sslcheckcert", required_argument, NULL, 172}, + { "sslprotocol", required_argument, NULL, 173}, +#endif /* HAVE_SSL */ { "wait", required_argument, NULL, 'w' }, - { "waitretry", required_argument, NULL, 24 }, + { "waitretry", required_argument, NULL, 152 }, { 0, 0, 0, 0 } }; i18n_initialize (); - private_initialize (); append_to_log = 0; @@ -328,67 +383,62 @@ main (int argc, char *const *argv) /* [Is the order of the option letters significant? If not, they should be alphabetized, like the long_options. The only thing I know for sure is that the options with required arguments must be followed by a ':'. - -- Dan Harkless ] */ + -- Dan Harkless ] */ while ((c = getopt_long (argc, argv, "\ -hpVqvdkKsxmNWrHSLcFbEY:G:g:T:U:O:l:n:i:o:a:t:D:A:R:P:B:e:Q:X:I:w:", +hpVqvdkKsxmNWrHSLcFbEY:G:g:T:U:O:l:n:i:o:a:t:D:A:R:P:B:e:Q:X:I:w:C:", long_options, (int *)0)) != EOF) { switch (c) { /* Options without arguments: */ - case 4: + case 132: setval ("spider", "on"); break; - case 5: + case 133: setval ("noparent", "on"); break; - case 8: + case 136: setval ("deleteafter", "on"); break; - case 9: + case 137: setval ("retrsymlinks", "on"); break; - case 10: + case 138: setval ("ignorelength", "on"); break; - case 11: + case 139: setval ("passiveftp", "on"); break; - case 13: + case 141: setval ("noclobber", "on"); break; - case 14: + case 142: setval ("followftp", "on"); break; - case 17: + case 145: setval ("cutdirs", optarg); break; - case 18: + case 146: setval ("verbose", "off"); break; - case 19: + case 147: setval ("dirstruct", "off"); break; - case 20: + case 148: setval ("addhostdir", "off"); break; - case 21: + case 149: setval ("removelisting", "off"); break; - case 22: - setval ("simplehostcheck", "on"); - break; - case 26: - /* For debugging purposes. */ - printf ("%s\n", ftp_getaddress ()); - exit (0); - break; - case 27: + case 155: setval ("bindaddress", optarg); break; - case 28: + case 156: setval ("httpkeepalive", "off"); break; + case 165: + setval ("randomwait", "on"); + break; case 'b': setval ("background", "on"); break; @@ -452,7 +502,8 @@ hpVqvdkKsxmNWrHSLcFbEY:G:g:T:U:O:l:n:i:o:a:t:D:A:R:P:B:e:Q:X:I:w:", case 'V': printf ("GNU Wget %s\n\n", version_string); printf ("%s", _("\ -Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.\n\ +Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001 Free Software Foundation, Inc.\n")); + printf ("%s", _("\ This program is distributed in the hope that it will be useful,\n\ but WITHOUT ANY WARRANTY; without even the implied warranty of\n\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\ @@ -466,45 +517,94 @@ GNU General Public License for more details.\n")); case 'x': setval ("dirstruct", "on"); break; + case 174: + setval ("retryconnrefused", "on"); + break; /* Options accepting an argument: */ - case 1: + case 129: setval ("httpuser", optarg); break; - case 2: + case 130: setval ("httppasswd", optarg); break; - case 3: + case 131: setval ("header", optarg); break; - case 6: + case 134: setval ("dotstyle", optarg); break; - case 7: + case 135: setval ("htmlify", optarg); break; - case 12: + case 140: setval ("excludedomains", optarg); break; - case 15: + case 143: setval ("proxyuser", optarg); break; - case 16: + case 144: setval ("proxypasswd", optarg); break; - case 23: + case 151: setval ("backups", optarg); break; - case 24: + case 152: setval ("waitretry", optarg); - wr = 1; break; - case 25: + case 153: setval ("followtags", optarg); break; - case 129: + case 160: + setval ("cookies", optarg); + break; + case 161: + setval ("loadcookies", optarg); + break; + case 162: + setval ("savecookies", optarg); + break; + case 163: + setval ("progress", optarg); + break; + case 164: + setval ("limitrate", optarg); + break; + case 157: setval ("referer", optarg); break; +#ifdef HAVE_SSL + case 158: + setval ("sslcertfile", optarg); + break; + case 159: + setval ("sslcertkey", optarg); + break; + case 166: + setval ("egdfile", optarg); + break; + case 169: + setval ("sslcadir", optarg); + break; + case 170: + setval ("sslcafile", optarg); + break; + case 171: + setval ("sslcerttype", optarg); + break; + case 172: + setval ("sslcheckcert", optarg); + break; + case 173: + setval ("sslprotocol", optarg); + break; +#endif /* HAVE_SSL */ + case 167: + setval ("postdata", optarg); + break; + case 168: + setval ("postfile", optarg); + break; case 'A': setval ("accept", optarg); break; @@ -556,7 +656,7 @@ GNU General Public License for more details.\n")); break; case 'n': { - /* #### The n? options are utter crock! */ + /* #### What we really want here is --no-foo. */ char *p; for (p = optarg; *p; p++) @@ -565,9 +665,6 @@ GNU General Public License for more details.\n")); case 'v': setval ("verbose", "off"); break; - case 'h': - setval ("simplehostcheck", "on"); - break; case 'H': setval ("addhostdir", "off"); break; @@ -655,18 +752,6 @@ GNU General Public License for more details.\n")); if (opt.verbose == -1) opt.verbose = !opt.quiet; - /* Retain compatibility with previous scripts. - if wait has been set, but waitretry has not, give it the wait value. - A simple check on the values is not enough, I could have set - wait to n>0 and waitretry to 0 - HEH */ - if (opt.wait && !wr) - { - char opt_wait_str[256]; /* bigger than needed buf to prevent overflow */ - - sprintf(opt_wait_str, "%ld", opt.wait); - setval ("waitretry", opt_wait_str); - } - /* Sanity checks. */ if (opt.verbose && opt.quiet) { @@ -697,14 +782,21 @@ Can't timestamp and not clobber old files at the same time.\n")); if (opt.background) fork_to_background (); + /* Initialize progress. Have to do this after the options are + processed so we know where the log file is. */ + if (opt.verbose) + set_progress_implementation (opt.progress_type); + /* Allocate basic pointer. */ url = ALLOCA_ARRAY (char *, nurl + 1); /* Fill in the arguments. */ for (i = 0; i < nurl; i++, optind++) { - char *irix4_cc_needs_this; - STRDUP_ALLOCA (irix4_cc_needs_this, argv[optind]); - url[i] = irix4_cc_needs_this; + char *rewritten = rewrite_shorthand_url (argv[optind]); + if (rewritten) + url[i] = rewritten; + else + url[i] = xstrdup (argv[optind]); } url[i] = NULL; @@ -719,6 +811,7 @@ Can't timestamp and not clobber old files at the same time.\n")); DEBUGP (("DEBUG output created by Wget %s on %s.\n\n", version_string, OS_TYPE)); + /* Open the output filename if necessary. */ if (opt.output_document) { @@ -726,12 +819,15 @@ Can't timestamp and not clobber old files at the same time.\n")); opt.dfp = stdout; else { - opt.dfp = fopen (opt.output_document, "wb"); + struct stat st; + opt.dfp = fopen (opt.output_document, opt.always_rest ? "ab" : "wb"); if (opt.dfp == NULL) { perror (opt.output_document); exit (1); } + if (fstat (fileno (opt.dfp), &st) == 0 && S_ISREG (st.st_mode)) + opt.od_known_regular = 1; } } @@ -750,20 +846,28 @@ Can't timestamp and not clobber old files at the same time.\n")); process exits. What we want is to ignore SIGPIPE and just check for the return value of write(). */ signal (SIGPIPE, SIG_IGN); +#ifdef SIGWINCH + signal (SIGWINCH, progress_handle_sigwinch); +#endif #endif /* HAVE_SIGNAL */ +#ifdef HAVE_SSL + /* Must call this before resolving any URLs because it has the power + to disable `https'. */ + ssl_init_prng (); +#endif + status = RETROK; /* initialize it, just-in-case */ - recursive_reset (); /* Retrieve the URLs from argument list. */ for (t = url; *t; t++) { - char *filename, *redirected_URL; + char *filename = NULL, *redirected_URL = NULL; int dt; - status = retrieve_url (*t, &filename, &redirected_URL, NULL, &dt); - if (opt.recursive && status == RETROK && (dt & TEXTHTML)) - status = recursive_retrieve (filename, - redirected_URL ? redirected_URL : *t); + if (opt.recursive && url_scheme (*t) != SCHEME_FTP) + status = retrieve_tree (*t); + else + status = retrieve_url (*t, &filename, &redirected_URL, NULL, &dt); if (opt.delete_after && file_exists_p(filename)) { @@ -803,12 +907,20 @@ Can't timestamp and not clobber old files at the same time.\n")); _("Download quota (%s bytes) EXCEEDED!\n"), legible (opt.quota)); } - if (opt.convert_links & !opt.delete_after) + + if (opt.cookies_output && wget_cookie_jar) + cookie_jar_save (wget_cookie_jar, opt.cookies_output); + + if (opt.convert_links && !opt.delete_after) { convert_all_links (); } + log_close (); + for (i = 0; i < nurl; i++) + xfree (url[i]); cleanup (); + #ifdef DEBUG_MALLOC print_malloc_debug_stats (); #endif @@ -818,22 +930,23 @@ Can't timestamp and not clobber old files at the same time.\n")); return 1; } +#ifdef HAVE_SIGNAL /* 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. */ -#ifdef HAVE_SIGNAL static RETSIGTYPE redirect_output_signal (int sig) { - char tmp[100]; + char *signal_name = (sig == SIGHUP ? "SIGHUP" : + (sig == SIGUSR1 ? "SIGUSR1" : + "WTF?!")); + log_request_redirect_output (signal_name); + progress_schedule_redirect (); signal (sig, redirect_output_signal); - /* Please note that the double `%' in `%%s' is intentional, because - redirect_output passes tmp through printf. */ - sprintf (tmp, _("%s received, redirecting output to `%%s'.\n"), - (sig == SIGHUP ? "SIGHUP" : - (sig == SIGUSR1 ? "SIGUSR1" : - "WTF?!"))); - redirect_output (tmp); } #endif /* HAVE_SIGNAL */