]> sjero.net Git - wget/blob - src/main.c
Follow RFC 2616 and httpbis specifications when handling redirects
[wget] / src / main.c
1 /* Command line parsing.
2    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3    2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation,
4    Inc.
5
6 This file is part of GNU Wget.
7
8 GNU Wget is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 GNU Wget is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Wget.  If not, see <http://www.gnu.org/licenses/>.
20
21 Additional permission under GNU GPL version 3 section 7
22
23 If you modify this program, or any covered work, by linking or
24 combining it with the OpenSSL project's OpenSSL library (or a
25 modified version of that library), containing parts covered by the
26 terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
27 grants you additional permission to convey the resulting work.
28 Corresponding Source for a non-source form of such a combination
29 shall include the source code for the parts of OpenSSL used as well
30 as that of the covered work.  */
31
32 #include "wget.h"
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <unistd.h>
37 #include <string.h>
38 #include <signal.h>
39 #ifdef ENABLE_NLS
40 # include <locale.h>
41 #endif
42 #include <assert.h>
43 #include <errno.h>
44 #include <time.h>
45
46 #include "exits.h"
47 #include "utils.h"
48 #include "init.h"
49 #include "retr.h"
50 #include "recur.h"
51 #include "host.h"
52 #include "url.h"
53 #include "progress.h"           /* for progress_handle_sigwinch */
54 #include "convert.h"
55 #include "spider.h"
56 #include "http.h"               /* for save_cookies */
57 #include "ptimer.h"
58 #include "warc.h"
59 #include <getopt.h>
60 #include <getpass.h>
61 #include <quote.h>
62
63 #ifdef WINDOWS
64 # include <io.h>
65 # include <fcntl.h>
66 #endif
67
68 #ifdef __VMS
69 # include "vms.h"
70 #endif /* __VMS */
71
72 #ifndef PATH_SEPARATOR
73 # define PATH_SEPARATOR '/'
74 #endif
75
76 #ifndef ENABLE_IRI
77 struct iri dummy_iri;
78 #endif
79
80 struct options opt;
81
82 /* defined in version.c */
83 extern char *version_string;
84 extern char *compilation_string;
85 extern char *system_getrc;
86 extern char *link_string;
87 /* defined in build_info.c */
88 extern const char *compiled_features[];
89 /* Used for --version output in print_version */
90 #define MAX_CHARS_PER_LINE      72
91 #define TABULATION              4
92
93 #if defined(SIGHUP) || defined(SIGUSR1)
94 static void redirect_output_signal (int);
95 #endif
96
97 const char *exec_name;
98
99 /* Number of successfully downloaded URLs */
100 int numurls = 0;
101 \f
102 #ifndef TESTING
103 /* Initialize I18N/L10N.  That amounts to invoking setlocale, and
104    setting up gettext's message catalog using bindtextdomain and
105    textdomain.  Does nothing if NLS is disabled or missing.  */
106
107 static void
108 i18n_initialize (void)
109 {
110   /* ENABLE_NLS implies existence of functions invoked here.  */
111 #ifdef ENABLE_NLS
112   /* Set the current locale.  */
113   setlocale (LC_ALL, "");
114   /* Set the text message domain.  */
115   bindtextdomain ("wget", LOCALEDIR);
116   textdomain ("wget");
117 #endif /* ENABLE_NLS */
118 }
119 \f
120 /* Definition of command-line options. */
121
122 static void print_help (void);
123 static void print_version (void);
124
125 #ifdef HAVE_SSL
126 # define IF_SSL(x) x
127 #else
128 # define IF_SSL(x) NULL
129 #endif
130
131 #ifdef ENABLE_DEBUG
132 # define WHEN_DEBUG(x) x
133 #else
134 # define WHEN_DEBUG(x) NULL
135 #endif
136
137 struct cmdline_option {
138   const char *long_name;
139   char short_name;
140   enum {
141     OPT_VALUE,
142     OPT_BOOLEAN,
143     OPT_FUNCALL,
144     /* Non-standard options that have to be handled specially in
145        main().  */
146     OPT__APPEND_OUTPUT,
147     OPT__CLOBBER,
148     OPT__DONT_REMOVE_LISTING,
149     OPT__EXECUTE,
150     OPT__NO,
151     OPT__PARENT
152   } type;
153   const void *data;             /* for standard options */
154   int argtype;                  /* for non-standard options */
155 };
156
157 static struct cmdline_option option_data[] =
158   {
159     { "accept", 'A', OPT_VALUE, "accept", -1 },
160     { "accept-regex", 0, OPT_VALUE, "acceptregex", -1 },
161     { "adjust-extension", 'E', OPT_BOOLEAN, "adjustextension", -1 },
162     { "append-output", 'a', OPT__APPEND_OUTPUT, NULL, required_argument },
163     { "ask-password", 0, OPT_BOOLEAN, "askpassword", -1 },
164     { "auth-no-challenge", 0, OPT_BOOLEAN, "authnochallenge", -1 },
165     { "background", 'b', OPT_BOOLEAN, "background", -1 },
166     { "backup-converted", 'K', OPT_BOOLEAN, "backupconverted", -1 },
167     { "backups", 0, OPT_BOOLEAN, "backups", -1 },
168     { "base", 'B', OPT_VALUE, "base", -1 },
169     { "bind-address", 0, OPT_VALUE, "bindaddress", -1 },
170     { "body-data", 0, OPT_VALUE, "bodydata", -1 },
171     { "body-file", 0, OPT_VALUE, "bodyfile", -1 },
172     { IF_SSL ("ca-certificate"), 0, OPT_VALUE, "cacertificate", -1 },
173     { IF_SSL ("ca-directory"), 0, OPT_VALUE, "cadirectory", -1 },
174     { "cache", 0, OPT_BOOLEAN, "cache", -1 },
175     { IF_SSL ("certificate"), 0, OPT_VALUE, "certificate", -1 },
176     { IF_SSL ("certificate-type"), 0, OPT_VALUE, "certificatetype", -1 },
177     { IF_SSL ("check-certificate"), 0, OPT_BOOLEAN, "checkcertificate", -1 },
178     { "clobber", 0, OPT__CLOBBER, NULL, optional_argument },
179     { "config", 0, OPT_VALUE, "chooseconfig", -1 },
180     { "connect-timeout", 0, OPT_VALUE, "connecttimeout", -1 },
181     { "continue", 'c', OPT_BOOLEAN, "continue", -1 },
182     { "convert-links", 'k', OPT_BOOLEAN, "convertlinks", -1 },
183     { "content-disposition", 0, OPT_BOOLEAN, "contentdisposition", -1 },
184     { "content-on-error", 0, OPT_BOOLEAN, "contentonerror", -1 },
185     { "cookies", 0, OPT_BOOLEAN, "cookies", -1 },
186     { "cut-dirs", 0, OPT_VALUE, "cutdirs", -1 },
187     { WHEN_DEBUG ("debug"), 'd', OPT_BOOLEAN, "debug", -1 },
188     { "default-page", 0, OPT_VALUE, "defaultpage", -1 },
189     { "delete-after", 0, OPT_BOOLEAN, "deleteafter", -1 },
190     { "directories", 0, OPT_BOOLEAN, "dirstruct", -1 },
191     { "directory-prefix", 'P', OPT_VALUE, "dirprefix", -1 },
192     { "dns-cache", 0, OPT_BOOLEAN, "dnscache", -1 },
193     { "dns-timeout", 0, OPT_VALUE, "dnstimeout", -1 },
194     { "domains", 'D', OPT_VALUE, "domains", -1 },
195     { "dont-remove-listing", 0, OPT__DONT_REMOVE_LISTING, NULL, no_argument },
196     { "dot-style", 0, OPT_VALUE, "dotstyle", -1 }, /* deprecated */
197     { "egd-file", 0, OPT_VALUE, "egdfile", -1 },
198     { "exclude-directories", 'X', OPT_VALUE, "excludedirectories", -1 },
199     { "exclude-domains", 0, OPT_VALUE, "excludedomains", -1 },
200     { "execute", 'e', OPT__EXECUTE, NULL, required_argument },
201     { "follow-ftp", 0, OPT_BOOLEAN, "followftp", -1 },
202     { "follow-tags", 0, OPT_VALUE, "followtags", -1 },
203     { "force-directories", 'x', OPT_BOOLEAN, "dirstruct", -1 },
204     { "force-html", 'F', OPT_BOOLEAN, "forcehtml", -1 },
205     { "ftp-password", 0, OPT_VALUE, "ftppassword", -1 },
206 #ifdef __VMS
207     { "ftp-stmlf", 0, OPT_BOOLEAN, "ftpstmlf", -1 },
208 #endif /* def __VMS */
209     { "ftp-user", 0, OPT_VALUE, "ftpuser", -1 },
210     { "glob", 0, OPT_BOOLEAN, "glob", -1 },
211     { "header", 0, OPT_VALUE, "header", -1 },
212     { "help", 'h', OPT_FUNCALL, (void *)print_help, no_argument },
213     { "host-directories", 0, OPT_BOOLEAN, "addhostdir", -1 },
214     { "html-extension", 'E', OPT_BOOLEAN, "adjustextension", -1 }, /* deprecated */
215     { "htmlify", 0, OPT_BOOLEAN, "htmlify", -1 },
216     { "http-keep-alive", 0, OPT_BOOLEAN, "httpkeepalive", -1 },
217     { "http-passwd", 0, OPT_VALUE, "httppassword", -1 }, /* deprecated */
218     { "http-password", 0, OPT_VALUE, "httppassword", -1 },
219     { "http-user", 0, OPT_VALUE, "httpuser", -1 },
220     { "ignore-case", 0, OPT_BOOLEAN, "ignorecase", -1 },
221     { "ignore-length", 0, OPT_BOOLEAN, "ignorelength", -1 },
222     { "ignore-tags", 0, OPT_VALUE, "ignoretags", -1 },
223     { "include-directories", 'I', OPT_VALUE, "includedirectories", -1 },
224 #ifdef ENABLE_IPV6
225     { "inet4-only", '4', OPT_BOOLEAN, "inet4only", -1 },
226     { "inet6-only", '6', OPT_BOOLEAN, "inet6only", -1 },
227 #endif
228     { "input-file", 'i', OPT_VALUE, "input", -1 },
229     { "iri", 0, OPT_BOOLEAN, "iri", -1 },
230     { "keep-session-cookies", 0, OPT_BOOLEAN, "keepsessioncookies", -1 },
231     { "level", 'l', OPT_VALUE, "reclevel", -1 },
232     { "limit-rate", 0, OPT_VALUE, "limitrate", -1 },
233     { "load-cookies", 0, OPT_VALUE, "loadcookies", -1 },
234     { "local-encoding", 0, OPT_VALUE, "localencoding", -1 },
235     { "max-redirect", 0, OPT_VALUE, "maxredirect", -1 },
236     { "method", 0, OPT_VALUE, "method", -1 },
237     { "mirror", 'm', OPT_BOOLEAN, "mirror", -1 },
238     { "no", 'n', OPT__NO, NULL, required_argument },
239     { "no-clobber", 0, OPT_BOOLEAN, "noclobber", -1 },
240     { "no-parent", 0, OPT_BOOLEAN, "noparent", -1 },
241     { "output-document", 'O', OPT_VALUE, "outputdocument", -1 },
242     { "output-file", 'o', OPT_VALUE, "logfile", -1 },
243     { "page-requisites", 'p', OPT_BOOLEAN, "pagerequisites", -1 },
244     { "parent", 0, OPT__PARENT, NULL, optional_argument },
245     { "passive-ftp", 0, OPT_BOOLEAN, "passiveftp", -1 },
246     { "password", 0, OPT_VALUE, "password", -1 },
247     { "post-data", 0, OPT_VALUE, "postdata", -1 },
248     { "post-file", 0, OPT_VALUE, "postfile", -1 },
249     { "prefer-family", 0, OPT_VALUE, "preferfamily", -1 },
250     { "preserve-permissions", 0, OPT_BOOLEAN, "preservepermissions", -1 },
251     { IF_SSL ("private-key"), 0, OPT_VALUE, "privatekey", -1 },
252     { IF_SSL ("private-key-type"), 0, OPT_VALUE, "privatekeytype", -1 },
253     { "progress", 0, OPT_VALUE, "progress", -1 },
254     { "protocol-directories", 0, OPT_BOOLEAN, "protocoldirectories", -1 },
255     { "proxy", 0, OPT_BOOLEAN, "useproxy", -1 },
256     { "proxy__compat", 'Y', OPT_VALUE, "useproxy", -1 }, /* back-compatible */
257     { "proxy-passwd", 0, OPT_VALUE, "proxypassword", -1 }, /* deprecated */
258     { "proxy-password", 0, OPT_VALUE, "proxypassword", -1 },
259     { "proxy-user", 0, OPT_VALUE, "proxyuser", -1 },
260     { "quiet", 'q', OPT_BOOLEAN, "quiet", -1 },
261     { "quota", 'Q', OPT_VALUE, "quota", -1 },
262     { "random-file", 0, OPT_VALUE, "randomfile", -1 },
263     { "random-wait", 0, OPT_BOOLEAN, "randomwait", -1 },
264     { "read-timeout", 0, OPT_VALUE, "readtimeout", -1 },
265     { "recursive", 'r', OPT_BOOLEAN, "recursive", -1 },
266     { "referer", 0, OPT_VALUE, "referer", -1 },
267     { "regex-type", 0, OPT_VALUE, "regextype", -1 },
268     { "reject", 'R', OPT_VALUE, "reject", -1 },
269     { "reject-regex", 0, OPT_VALUE, "rejectregex", -1 },
270     { "relative", 'L', OPT_BOOLEAN, "relativeonly", -1 },
271     { "remote-encoding", 0, OPT_VALUE, "remoteencoding", -1 },
272     { "remove-listing", 0, OPT_BOOLEAN, "removelisting", -1 },
273     { "report-speed", 0, OPT_BOOLEAN, "reportspeed", -1 },
274     { "restrict-file-names", 0, OPT_BOOLEAN, "restrictfilenames", -1 },
275     { "retr-symlinks", 0, OPT_BOOLEAN, "retrsymlinks", -1 },
276     { "retry-connrefused", 0, OPT_BOOLEAN, "retryconnrefused", -1 },
277     { "save-cookies", 0, OPT_VALUE, "savecookies", -1 },
278     { "save-headers", 0, OPT_BOOLEAN, "saveheaders", -1 },
279     { IF_SSL ("secure-protocol"), 0, OPT_VALUE, "secureprotocol", -1 },
280     { "server-response", 'S', OPT_BOOLEAN, "serverresponse", -1 },
281     { "span-hosts", 'H', OPT_BOOLEAN, "spanhosts", -1 },
282     { "spider", 0, OPT_BOOLEAN, "spider", -1 },
283     { "strict-comments", 0, OPT_BOOLEAN, "strictcomments", -1 },
284     { "timeout", 'T', OPT_VALUE, "timeout", -1 },
285     { "timestamping", 'N', OPT_BOOLEAN, "timestamping", -1 },
286     { "tries", 't', OPT_VALUE, "tries", -1 },
287     { "unlink", 0, OPT_BOOLEAN, "unlink", -1 },
288     { "trust-server-names", 0, OPT_BOOLEAN, "trustservernames", -1 },
289     { "use-server-timestamps", 0, OPT_BOOLEAN, "useservertimestamps", -1 },
290     { "user", 0, OPT_VALUE, "user", -1 },
291     { "user-agent", 'U', OPT_VALUE, "useragent", -1 },
292     { "verbose", 'v', OPT_BOOLEAN, "verbose", -1 },
293     { "verbose", 0, OPT_BOOLEAN, "verbose", -1 },
294     { "version", 'V', OPT_FUNCALL, (void *) print_version, no_argument },
295     { "wait", 'w', OPT_VALUE, "wait", -1 },
296     { "waitretry", 0, OPT_VALUE, "waitretry", -1 },
297     { "warc-cdx", 0, OPT_BOOLEAN, "warccdx", -1 },
298 #ifdef HAVE_LIBZ
299     { "warc-compression", 0, OPT_BOOLEAN, "warccompression", -1 },
300 #endif
301     { "warc-dedup", 0, OPT_VALUE, "warccdxdedup", -1 },
302     { "warc-digests", 0, OPT_BOOLEAN, "warcdigests", -1 },
303     { "warc-file", 0, OPT_VALUE, "warcfile", -1 },
304     { "warc-header", 0, OPT_VALUE, "warcheader", -1 },
305     { "warc-keep-log", 0, OPT_BOOLEAN, "warckeeplog", -1 },
306     { "warc-max-size", 0, OPT_VALUE, "warcmaxsize", -1 },
307     { "warc-tempdir", 0, OPT_VALUE, "warctempdir", -1 },
308 #ifdef USE_WATT32
309     { "wdebug", 0, OPT_BOOLEAN, "wdebug", -1 },
310 #endif
311   };
312
313 #undef WHEN_DEBUG
314 #undef IF_SSL
315
316 /* Return a string that contains S with "no-" prepended.  The string
317    is NUL-terminated and allocated off static storage at Wget
318    startup.  */
319
320 static char *
321 no_prefix (const char *s)
322 {
323   static char buffer[1024];
324   static char *p = buffer;
325
326   char *cp = p;
327   int size = 3 + strlen (s) + 1;  /* "no-STRING\0" */
328   if (p + size >= buffer + sizeof (buffer))
329     abort ();
330
331   cp[0] = 'n', cp[1] = 'o', cp[2] = '-';
332   strcpy (cp + 3, s);
333   p += size;
334   return cp;
335 }
336
337 /* The arguments that that main passes to getopt_long. */
338 static struct option long_options[2 * countof (option_data) + 1];
339 static char short_options[128];
340
341 /* Mapping between short option chars and option_data indices. */
342 static unsigned char optmap[96];
343
344 /* Marker for `--no-FOO' values in long_options.  */
345 #define BOOLEAN_NEG_MARKER 1024
346
347 /* Initialize the long_options array used by getopt_long from the data
348    in option_data.  */
349
350 static void
351 init_switches (void)
352 {
353   char *p = short_options;
354   size_t i, o = 0;
355   for (i = 0; i < countof (option_data); i++)
356     {
357       struct cmdline_option *opt = &option_data[i];
358       struct option *longopt;
359
360       if (!opt->long_name)
361         /* The option is disabled. */
362         continue;
363
364       longopt = &long_options[o++];
365       longopt->name = opt->long_name;
366       longopt->val = i;
367       if (opt->short_name)
368         {
369           *p++ = opt->short_name;
370           optmap[opt->short_name - 32] = longopt - long_options;
371         }
372       switch (opt->type)
373         {
374         case OPT_VALUE:
375           longopt->has_arg = required_argument;
376           if (opt->short_name)
377             *p++ = ':';
378           break;
379         case OPT_BOOLEAN:
380           /* Specify an optional argument for long options, so that
381              --option=off works the same as --no-option, for
382              compatibility with pre-1.10 Wget.  However, don't specify
383              optional arguments short-option booleans because they
384              prevent combining of short options.  */
385           longopt->has_arg = optional_argument;
386           /* For Boolean options, add the "--no-FOO" variant, which is
387              identical to "--foo", except it has opposite meaning and
388              it doesn't allow an argument.  */
389           longopt = &long_options[o++];
390           longopt->name = no_prefix (opt->long_name);
391           longopt->has_arg = no_argument;
392           /* Mask the value so we'll be able to recognize that we're
393              dealing with the false value.  */
394           longopt->val = i | BOOLEAN_NEG_MARKER;
395           break;
396         default:
397           assert (opt->argtype != -1);
398           longopt->has_arg = opt->argtype;
399           if (opt->short_name)
400             {
401               if (longopt->has_arg == required_argument)
402                 *p++ = ':';
403               /* Don't handle optional_argument */
404             }
405         }
406     }
407   /* Terminate short_options. */
408   *p = '\0';
409   /* No need for xzero(long_options[o]) because its storage is static
410      and it will be zeroed by default.  */
411   assert (o <= countof (long_options));
412 }
413
414 /* Print the usage message.  */
415 static int
416 print_usage (int error)
417 {
418   return fprintf (error ? stderr : stdout,
419                   _("Usage: %s [OPTION]... [URL]...\n"), exec_name);
420 }
421
422 /* Print the help message, describing all the available options.  If
423    you add an option, be sure to update this list.  */
424 static void
425 print_help (void)
426 {
427   /* We split the help text this way to ease translation of individual
428      entries.  */
429   static const char *help[] = {
430     "\n",
431     N_("\
432 Mandatory arguments to long options are mandatory for short options too.\n\n"),
433     N_("\
434 Startup:\n"),
435     N_("\
436   -V,  --version           display the version of Wget and exit.\n"),
437     N_("\
438   -h,  --help              print this help.\n"),
439     N_("\
440   -b,  --background        go to background after startup.\n"),
441     N_("\
442   -e,  --execute=COMMAND   execute a `.wgetrc'-style command.\n"),
443     "\n",
444
445     N_("\
446 Logging and input file:\n"),
447     N_("\
448   -o,  --output-file=FILE    log messages to FILE.\n"),
449     N_("\
450   -a,  --append-output=FILE  append messages to FILE.\n"),
451 #ifdef ENABLE_DEBUG
452     N_("\
453   -d,  --debug               print lots of debugging information.\n"),
454 #endif
455 #ifdef USE_WATT32
456     N_("\
457        --wdebug              print Watt-32 debug output.\n"),
458 #endif
459     N_("\
460   -q,  --quiet               quiet (no output).\n"),
461     N_("\
462   -v,  --verbose             be verbose (this is the default).\n"),
463     N_("\
464   -nv, --no-verbose          turn off verboseness, without being quiet.\n"),
465     N_("\
466        --report-speed=TYPE   Output bandwidth as TYPE.  TYPE can be bits.\n"),
467     N_("\
468   -i,  --input-file=FILE     download URLs found in local or external FILE.\n"),
469     N_("\
470   -F,  --force-html          treat input file as HTML.\n"),
471     N_("\
472   -B,  --base=URL            resolves HTML input-file links (-i -F)\n\
473                              relative to URL.\n"),
474     N_("\
475        --config=FILE         Specify config file to use.\n"), 
476     "\n",
477
478     N_("\
479 Download:\n"),
480     N_("\
481   -t,  --tries=NUMBER            set number of retries to NUMBER (0 unlimits).\n"),
482     N_("\
483        --retry-connrefused       retry even if connection is refused.\n"),
484     N_("\
485   -O,  --output-document=FILE    write documents to FILE.\n"),
486     N_("\
487   -nc, --no-clobber              skip downloads that would download to\n\
488                                  existing files (overwriting them).\n"),
489     N_("\
490   -c,  --continue                resume getting a partially-downloaded file.\n"),
491     N_("\
492        --progress=TYPE           select progress gauge type.\n"),
493     N_("\
494   -N,  --timestamping            don't re-retrieve files unless newer than\n\
495                                  local.\n"),
496     N_("\
497   --no-use-server-timestamps     don't set the local file's timestamp by\n\
498                                  the one on the server.\n"),
499     N_("\
500   -S,  --server-response         print server response.\n"),
501     N_("\
502        --spider                  don't download anything.\n"),
503     N_("\
504   -T,  --timeout=SECONDS         set all timeout values to SECONDS.\n"),
505     N_("\
506        --dns-timeout=SECS        set the DNS lookup timeout to SECS.\n"),
507     N_("\
508        --connect-timeout=SECS    set the connect timeout to SECS.\n"),
509     N_("\
510        --read-timeout=SECS       set the read timeout to SECS.\n"),
511     N_("\
512   -w,  --wait=SECONDS            wait SECONDS between retrievals.\n"),
513     N_("\
514        --waitretry=SECONDS       wait 1..SECONDS between retries of a retrieval.\n"),
515     N_("\
516        --random-wait             wait from 0.5*WAIT...1.5*WAIT secs between retrievals.\n"),
517     N_("\
518        --no-proxy                explicitly turn off proxy.\n"),
519     N_("\
520   -Q,  --quota=NUMBER            set retrieval quota to NUMBER.\n"),
521     N_("\
522        --bind-address=ADDRESS    bind to ADDRESS (hostname or IP) on local host.\n"),
523     N_("\
524        --limit-rate=RATE         limit download rate to RATE.\n"),
525     N_("\
526        --no-dns-cache            disable caching DNS lookups.\n"),
527     N_("\
528        --restrict-file-names=OS  restrict chars in file names to ones OS allows.\n"),
529     N_("\
530        --ignore-case             ignore case when matching files/directories.\n"),
531 #ifdef ENABLE_IPV6
532     N_("\
533   -4,  --inet4-only              connect only to IPv4 addresses.\n"),
534     N_("\
535   -6,  --inet6-only              connect only to IPv6 addresses.\n"),
536     N_("\
537        --prefer-family=FAMILY    connect first to addresses of specified family,\n\
538                                  one of IPv6, IPv4, or none.\n"),
539 #endif
540     N_("\
541        --user=USER               set both ftp and http user to USER.\n"),
542     N_("\
543        --password=PASS           set both ftp and http password to PASS.\n"),
544     N_("\
545        --ask-password            prompt for passwords.\n"),
546     N_("\
547        --no-iri                  turn off IRI support.\n"),
548     N_("\
549        --local-encoding=ENC      use ENC as the local encoding for IRIs.\n"),
550     N_("\
551        --remote-encoding=ENC     use ENC as the default remote encoding.\n"),
552     N_("\
553        --unlink                  remove file before clobber.\n"),
554     "\n",
555
556     N_("\
557 Directories:\n"),
558     N_("\
559   -nd, --no-directories           don't create directories.\n"),
560     N_("\
561   -x,  --force-directories        force creation of directories.\n"),
562     N_("\
563   -nH, --no-host-directories      don't create host directories.\n"),
564     N_("\
565        --protocol-directories     use protocol name in directories.\n"),
566     N_("\
567   -P,  --directory-prefix=PREFIX  save files to PREFIX/...\n"),
568     N_("\
569        --cut-dirs=NUMBER          ignore NUMBER remote directory components.\n"),
570     "\n",
571
572     N_("\
573 HTTP options:\n"),
574     N_("\
575        --http-user=USER        set http user to USER.\n"),
576     N_("\
577        --http-password=PASS    set http password to PASS.\n"),
578     N_("\
579        --no-cache              disallow server-cached data.\n"),
580     N_ ("\
581        --default-page=NAME     Change the default page name (normally\n\
582                                this is `index.html'.).\n"),
583     N_("\
584   -E,  --adjust-extension      save HTML/CSS documents with proper extensions.\n"),
585     N_("\
586        --ignore-length         ignore `Content-Length' header field.\n"),
587     N_("\
588        --header=STRING         insert STRING among the headers.\n"),
589     N_("\
590        --max-redirect          maximum redirections allowed per page.\n"),
591     N_("\
592        --proxy-user=USER       set USER as proxy username.\n"),
593     N_("\
594        --proxy-password=PASS   set PASS as proxy password.\n"),
595     N_("\
596        --referer=URL           include `Referer: URL' header in HTTP request.\n"),
597     N_("\
598        --save-headers          save the HTTP headers to file.\n"),
599     N_("\
600   -U,  --user-agent=AGENT      identify as AGENT instead of Wget/VERSION.\n"),
601     N_("\
602        --no-http-keep-alive    disable HTTP keep-alive (persistent connections).\n"),
603     N_("\
604        --no-cookies            don't use cookies.\n"),
605     N_("\
606        --load-cookies=FILE     load cookies from FILE before session.\n"),
607     N_("\
608        --save-cookies=FILE     save cookies to FILE after session.\n"),
609     N_("\
610        --keep-session-cookies  load and save session (non-permanent) cookies.\n"),
611     N_("\
612        --post-data=STRING      use the POST method; send STRING as the data.\n"),
613     N_("\
614        --post-file=FILE        use the POST method; send contents of FILE.\n"),
615     N_("\
616        --method=HTTPMethod     use method \"HTTPMethod\" in the header.\n"),
617     N_("\
618        --body-data=STRING      Send STRING as data. --method MUST be set.\n"),
619     N_("\
620        --body-file=FILE        Send contents of FILE. --method MUST be set.\n"),
621     N_("\
622        --content-disposition   honor the Content-Disposition header when\n\
623                                choosing local file names (EXPERIMENTAL).\n"),
624     N_("\
625        --content-on-error      output the received content on server errors.\n"),
626     N_("\
627        --auth-no-challenge     send Basic HTTP authentication information\n\
628                                without first waiting for the server's\n\
629                                challenge.\n"),
630     "\n",
631
632 #ifdef HAVE_SSL
633     N_("\
634 HTTPS (SSL/TLS) options:\n"),
635     N_("\
636        --secure-protocol=PR     choose secure protocol, one of auto, SSLv2,\n\
637                                 SSLv3, and TLSv1.\n"),
638     N_("\
639        --no-check-certificate   don't validate the server's certificate.\n"),
640     N_("\
641        --certificate=FILE       client certificate file.\n"),
642     N_("\
643        --certificate-type=TYPE  client certificate type, PEM or DER.\n"),
644     N_("\
645        --private-key=FILE       private key file.\n"),
646     N_("\
647        --private-key-type=TYPE  private key type, PEM or DER.\n"),
648     N_("\
649        --ca-certificate=FILE    file with the bundle of CA's.\n"),
650     N_("\
651        --ca-directory=DIR       directory where hash list of CA's is stored.\n"),
652     N_("\
653        --random-file=FILE       file with random data for seeding the SSL PRNG.\n"),
654     N_("\
655        --egd-file=FILE          file naming the EGD socket with random data.\n"),
656     "\n",
657 #endif /* HAVE_SSL */
658
659     N_("\
660 FTP options:\n"),
661 #ifdef __VMS
662     N_("\
663        --ftp-stmlf             Use Stream_LF format for all binary FTP files.\n"),
664 #endif /* def __VMS */
665     N_("\
666        --ftp-user=USER         set ftp user to USER.\n"),
667     N_("\
668        --ftp-password=PASS     set ftp password to PASS.\n"),
669     N_("\
670        --no-remove-listing     don't remove `.listing' files.\n"),
671     N_("\
672        --no-glob               turn off FTP file name globbing.\n"),
673     N_("\
674        --no-passive-ftp        disable the \"passive\" transfer mode.\n"),
675     N_("\
676        --preserve-permissions  preserve remote file permissions.\n"),
677     N_("\
678        --retr-symlinks         when recursing, get linked-to files (not dir).\n"),
679     "\n",
680
681     N_("\
682 WARC options:\n"),
683     N_("\
684        --warc-file=FILENAME      save request/response data to a .warc.gz file.\n"),
685     N_("\
686        --warc-header=STRING      insert STRING into the warcinfo record.\n"),
687     N_("\
688        --warc-max-size=NUMBER    set maximum size of WARC files to NUMBER.\n"),
689     N_("\
690        --warc-cdx                write CDX index files.\n"),
691     N_("\
692        --warc-dedup=FILENAME     do not store records listed in this CDX file.\n"),
693 #ifdef HAVE_LIBZ
694     N_("\
695        --no-warc-compression     do not compress WARC files with GZIP.\n"),
696 #endif
697     N_("\
698        --no-warc-digests         do not calculate SHA1 digests.\n"),
699     N_("\
700        --no-warc-keep-log        do not store the log file in a WARC record.\n"),
701     N_("\
702        --warc-tempdir=DIRECTORY  location for temporary files created by the\n\
703                                  WARC writer.\n"),
704     "\n",
705
706     N_("\
707 Recursive download:\n"),
708     N_("\
709   -r,  --recursive          specify recursive download.\n"),
710     N_("\
711   -l,  --level=NUMBER       maximum recursion depth (inf or 0 for infinite).\n"),
712     N_("\
713        --delete-after       delete files locally after downloading them.\n"),
714     N_("\
715   -k,  --convert-links      make links in downloaded HTML or CSS point to\n\
716                             local files.\n"),
717 #ifdef __VMS
718     N_("\
719   -K,  --backup-converted   before converting file X, back up as X_orig.\n"),
720 #else /* def __VMS */
721     N_("\
722   -K,  --backup-converted   before converting file X, back up as X.orig.\n"),
723 #endif /* def __VMS [else] */
724     N_("\
725   -m,  --mirror             shortcut for -N -r -l inf --no-remove-listing.\n"),
726     N_("\
727   -p,  --page-requisites    get all images, etc. needed to display HTML page.\n"),
728     N_("\
729        --strict-comments    turn on strict (SGML) handling of HTML comments.\n"),
730     "\n",
731
732     N_("\
733 Recursive accept/reject:\n"),
734     N_("\
735   -A,  --accept=LIST               comma-separated list of accepted extensions.\n"),
736     N_("\
737   -R,  --reject=LIST               comma-separated list of rejected extensions.\n"),
738     N_("\
739        --accept-regex=REGEX        regex matching accepted URLs.\n"),
740     N_("\
741        --reject-regex=REGEX        regex matching rejected URLs.\n"),
742 #ifdef HAVE_LIBPCRE
743     N_("\
744        --regex-type=TYPE           regex type (posix|pcre).\n"),
745 #else
746     N_("\
747        --regex-type=TYPE           regex type (posix).\n"),
748 #endif
749     N_("\
750   -D,  --domains=LIST              comma-separated list of accepted domains.\n"),
751     N_("\
752        --exclude-domains=LIST      comma-separated list of rejected domains.\n"),
753     N_("\
754        --follow-ftp                follow FTP links from HTML documents.\n"),
755     N_("\
756        --follow-tags=LIST          comma-separated list of followed HTML tags.\n"),
757     N_("\
758        --ignore-tags=LIST          comma-separated list of ignored HTML tags.\n"),
759     N_("\
760   -H,  --span-hosts                go to foreign hosts when recursive.\n"),
761     N_("\
762   -L,  --relative                  follow relative links only.\n"),
763     N_("\
764   -I,  --include-directories=LIST  list of allowed directories.\n"),
765     N_("\
766   --trust-server-names             use the name specified by the redirection\n\
767                                    url last component.\n"),
768     N_("\
769   -X,  --exclude-directories=LIST  list of excluded directories.\n"),
770     N_("\
771   -np, --no-parent                 don't ascend to the parent directory.\n"),
772     "\n",
773     N_("Mail bug reports and suggestions to <bug-wget@gnu.org>.\n")
774   };
775
776   size_t i;
777
778   if (printf (_("GNU Wget %s, a non-interactive network retriever.\n"),
779               version_string) < 0)
780     exit (3);
781   if (print_usage (0) < 0)
782     exit (3);
783
784   for (i = 0; i < countof (help); i++)
785     if (fputs (_(help[i]), stdout) < 0)
786       exit (3);
787
788   exit (0);
789 }
790
791 /* Return a human-readable printed representation of INTERVAL,
792    measured in seconds.  */
793
794 static char *
795 secs_to_human_time (double interval)
796 {
797   static char buf[32];
798   int secs = (int) (interval + 0.5);
799   int hours, mins, days;
800
801   days = secs / 86400, secs %= 86400;
802   hours = secs / 3600, secs %= 3600;
803   mins = secs / 60, secs %= 60;
804
805   if (days)
806     sprintf (buf, "%dd %dh %dm %ds", days, hours, mins, secs);
807   else if (hours)
808     sprintf (buf, "%dh %dm %ds", hours, mins, secs);
809   else if (mins)
810     sprintf (buf, "%dm %ds", mins, secs);
811   else
812     sprintf (buf, "%ss", print_decimal (interval));
813
814   return buf;
815 }
816
817 static char *
818 prompt_for_password (void)
819 {
820   if (opt.user)
821     fprintf (stderr, _("Password for user %s: "), quote (opt.user));
822   else
823     fprintf (stderr, _("Password: "));
824   return getpass("");
825 }
826
827 /* Function that prints the line argument while limiting it
828    to at most line_length. prefix is printed on the first line
829    and an appropriate number of spaces are added on subsequent
830    lines.*/
831 static int
832 format_and_print_line (const char *prefix, const char *line,
833                        int line_length)
834 {
835   int remaining_chars;
836   char *line_dup, *token;
837
838   assert (prefix != NULL);
839   assert (line != NULL);
840
841   line_dup = xstrdup (line);
842
843   if (line_length <= 0)
844     line_length = MAX_CHARS_PER_LINE - TABULATION;
845
846   if (printf ("%s", prefix) < 0)
847     return -1;
848   remaining_chars = line_length;
849   /* We break on spaces. */
850   token = strtok (line_dup, " ");
851   while (token != NULL)
852     {
853       /* If however a token is much larger than the maximum
854          line length, all bets are off and we simply print the
855          token on the next line. */
856       if (remaining_chars <= strlen (token))
857         {
858           if (printf ("\n%*c", TABULATION, ' ') < 0)
859             return -1;
860           remaining_chars = line_length - TABULATION;
861         }
862       if (printf ("%s ", token) < 0)
863         return -1;
864       remaining_chars -= strlen (token) + 1;  /* account for " " */
865       token = strtok (NULL, " ");
866     }
867
868   if (printf ("\n") < 0)
869     return -1;
870
871   xfree (line_dup);
872   return 0;
873 }
874
875 static void
876 print_version (void)
877 {
878   const char *wgetrc_title  = _("Wgetrc: ");
879   const char *locale_title  = _("Locale: ");
880   const char *compile_title = _("Compile: ");
881   const char *link_title    = _("Link: ");
882   char *env_wgetrc, *user_wgetrc;
883   int i;
884
885   if (printf (_("GNU Wget %s built on %s.\n\n"), version_string, OS_TYPE) < 0)
886     exit (3);
887
888   for (i = 0; compiled_features[i] != NULL; )
889     {
890       int line_length = MAX_CHARS_PER_LINE;
891       while ((line_length > 0) && (compiled_features[i] != NULL))
892         {
893           if (printf ("%s ", compiled_features[i]) < 0)
894             exit (3);
895           line_length -= strlen (compiled_features[i]) + 2;
896           i++;
897         }
898       if (printf ("\n") < 0)
899         exit (3);
900     }
901   if (printf ("\n") < 0)
902     exit (3);
903
904   /* Handle the case when $WGETRC is unset and $HOME/.wgetrc is
905      absent. */
906   if (printf ("%s\n", wgetrc_title) < 0)
907     exit (3);
908
909   env_wgetrc = wgetrc_env_file_name ();
910   if (env_wgetrc && *env_wgetrc)
911     {
912       if (printf (_("    %s (env)\n"), env_wgetrc) < 0)
913         exit (3);
914       xfree (env_wgetrc);
915     }
916   user_wgetrc = wgetrc_user_file_name ();
917   if (user_wgetrc)
918     {
919       if (printf (_("    %s (user)\n"), user_wgetrc) < 0)
920         exit (3);
921       xfree (user_wgetrc);
922     }
923 #ifdef SYSTEM_WGETRC
924   if (printf (_("    %s (system)\n"), SYSTEM_WGETRC) < 0)
925     exit (3);
926 #endif
927
928 #ifdef ENABLE_NLS
929   if (format_and_print_line (locale_title,
930                         LOCALEDIR,
931                              MAX_CHARS_PER_LINE) < 0)
932     exit (3);
933 #endif /* def ENABLE_NLS */
934
935   if (compilation_string != NULL)
936     if (format_and_print_line (compile_title,
937                                compilation_string,
938                                MAX_CHARS_PER_LINE) < 0)
939       exit (3);
940
941   if (link_string != NULL)
942     if (format_and_print_line (link_title,
943                                link_string,
944                                MAX_CHARS_PER_LINE) < 0)
945       exit (3);
946
947   if (printf ("\n") < 0)
948     exit (3);
949
950   /* TRANSLATORS: When available, an actual copyright character
951      (circle-c) should be used in preference to "(C)". */
952   if (fputs (_("\
953 Copyright (C) 2011 Free Software Foundation, Inc.\n"), stdout) < 0)
954     exit (3);
955   if (fputs (_("\
956 License GPLv3+: GNU GPL version 3 or later\n\
957 <http://www.gnu.org/licenses/gpl.html>.\n\
958 This is free software: you are free to change and redistribute it.\n\
959 There is NO WARRANTY, to the extent permitted by law.\n"), stdout) < 0)
960     exit (3);
961   /* TRANSLATORS: When available, please use the proper diacritics for
962      names such as this one. See en_US.po for reference. */
963   if (fputs (_("\nOriginally written by Hrvoje Niksic <hniksic@xemacs.org>.\n"),
964              stdout) < 0)
965     exit (3);
966   if (fputs (_("Please send bug reports and questions to <bug-wget@gnu.org>.\n"),
967              stdout) < 0)
968     exit (3);
969
970   exit (0);
971 }
972
973 char *program_name; /* Needed by lib/error.c. */
974 char *program_argstring; /* Needed by wget_warc.c. */
975
976 int
977 main (int argc, char **argv)
978 {
979   char **url, **t;
980   int i, ret, longindex;
981   int nurl;
982   bool append_to_log = false;
983
984   total_downloaded_bytes = 0;
985
986   program_name = argv[0];
987
988   struct ptimer *timer = ptimer_new ();
989   double start_time = ptimer_measure (timer);
990
991   i18n_initialize ();
992
993   /* Construct the name of the executable, without the directory part.  */
994 #ifdef __VMS
995   /* On VMS, lose the "dev:[dir]" prefix and the ".EXE;nnn" suffix. */
996   exec_name = vms_basename (argv[0]);
997 #else /* def __VMS */
998   exec_name = strrchr (argv[0], PATH_SEPARATOR);
999   if (!exec_name)
1000     exec_name = argv[0];
1001   else
1002     ++exec_name;
1003 #endif /* def __VMS [else] */
1004
1005 #ifdef WINDOWS
1006   /* Drop extension (typically .EXE) from executable filename. */
1007   windows_main ((char **) &exec_name);
1008 #endif
1009
1010   /* Construct the arguments string. */
1011   int argstring_length = 1;
1012   for (i = 1; i < argc; i++)
1013     argstring_length += strlen (argv[i]) + 2 + 1;
1014   char *p = program_argstring = malloc (argstring_length * sizeof (char));
1015   if (p == NULL)
1016     {
1017       fprintf (stderr, _("Memory allocation problem\n"));
1018       exit (2);
1019     }
1020   for (i = 1; i < argc; i++)
1021     {
1022       *p++ = '"';
1023       int arglen = strlen (argv[i]);
1024       memcpy (p, argv[i], arglen);
1025       p += arglen;
1026       *p++ = '"';
1027       *p++ = ' ';
1028     }
1029   *p = '\0';
1030
1031   /* Load the hard-coded defaults.  */
1032   defaults ();
1033
1034   init_switches ();
1035
1036   /* This separate getopt_long is needed to find the user config file
1037      option ("--config") and parse it before the other user options. */
1038   longindex = -1;
1039   int retconf;
1040   bool use_userconfig = false;
1041
1042   while ((retconf = getopt_long (argc, argv,
1043                                 short_options, long_options, &longindex)) != -1)
1044     {
1045       int confval;
1046       struct cmdline_option *config_opt;
1047
1048       /* There is no short option for "--config". */
1049       if (longindex >= 0)
1050         {
1051           confval = long_options[longindex].val;
1052           config_opt = &option_data[confval & ~BOOLEAN_NEG_MARKER];
1053           if (strcmp (config_opt->long_name, "config") == 0)
1054             {
1055               bool userrc_ret = true;
1056               userrc_ret &= run_wgetrc (optarg);
1057               use_userconfig = true;
1058               if (userrc_ret)
1059                 break;
1060               else
1061                 {
1062                   fprintf (stderr, _("Exiting due to error in %s\n"), optarg);
1063                   exit (2);
1064                 }
1065             }
1066         }
1067     }
1068
1069   /* If the user did not specify a config, read the system wgetrc and ~/.wgetrc. */
1070   if (use_userconfig == false)
1071     initialize ();
1072
1073   opterr = 0;
1074   optind = 0;
1075
1076   longindex = -1;
1077   while ((ret = getopt_long (argc, argv,
1078                              short_options, long_options, &longindex)) != -1)
1079     {
1080       int val;
1081       struct cmdline_option *opt;
1082
1083       /* If LONGINDEX is unchanged, it means RET is referring a short
1084          option.  */
1085       if (longindex == -1)
1086         {
1087           if (ret == '?')
1088             {
1089               print_usage (1);
1090               fprintf (stderr, "\n");
1091               fprintf (stderr, _("Try `%s --help' for more options.\n"),
1092                        exec_name);
1093               exit (2);
1094             }
1095           /* Find the short option character in the mapping.  */
1096           longindex = optmap[ret - 32];
1097         }
1098       val = long_options[longindex].val;
1099
1100       /* Use the retrieved value to locate the option in the
1101          option_data array, and to see if we're dealing with the
1102          negated "--no-FOO" variant of the boolean option "--foo".  */
1103       opt = &option_data[val & ~BOOLEAN_NEG_MARKER];
1104       switch (opt->type)
1105         {
1106         case OPT_VALUE:
1107           setoptval (opt->data, optarg, opt->long_name);
1108           break;
1109         case OPT_BOOLEAN:
1110           if (optarg)
1111             /* The user has specified a value -- use it. */
1112             setoptval (opt->data, optarg, opt->long_name);
1113           else
1114             {
1115               /* NEG is true for `--no-FOO' style boolean options. */
1116               bool neg = !!(val & BOOLEAN_NEG_MARKER);
1117               setoptval (opt->data, neg ? "0" : "1", opt->long_name);
1118             }
1119           break;
1120         case OPT_FUNCALL:
1121           {
1122             void (*func) (void) = (void (*) (void)) opt->data;
1123             func ();
1124           }
1125           break;
1126         case OPT__APPEND_OUTPUT:
1127           setoptval ("logfile", optarg, opt->long_name);
1128           append_to_log = true;
1129           break;
1130         case OPT__EXECUTE:
1131           run_command (optarg);
1132           break;
1133         case OPT__NO:
1134           {
1135             /* We support real --no-FOO flags now, but keep these
1136                short options for convenience and backward
1137                compatibility.  */
1138             char *p;
1139             for (p = optarg; p && *p; p++)
1140               switch (*p)
1141                 {
1142                 case 'v':
1143                   setoptval ("verbose", "0", opt->long_name);
1144                   break;
1145                 case 'H':
1146                   setoptval ("addhostdir", "0", opt->long_name);
1147                   break;
1148                 case 'd':
1149                   setoptval ("dirstruct", "0", opt->long_name);
1150                   break;
1151                 case 'c':
1152                   setoptval ("noclobber", "1", opt->long_name);
1153                   break;
1154                 case 'p':
1155                   setoptval ("noparent", "1", opt->long_name);
1156                   break;
1157                 default:
1158                   fprintf (stderr, _("%s: illegal option -- `-n%c'\n"),
1159                            exec_name, *p);
1160                   print_usage (1);
1161                   fprintf (stderr, "\n");
1162                   fprintf (stderr, _("Try `%s --help' for more options.\n"),
1163                            exec_name);
1164                   exit (1);
1165                 }
1166             break;
1167           }
1168         case OPT__PARENT:
1169         case OPT__CLOBBER:
1170           {
1171             /* The wgetrc commands are named noparent and noclobber,
1172                so we must revert the meaning of the cmdline options
1173                before passing the value to setoptval.  */
1174             bool flag = true;
1175             if (optarg)
1176               flag = (*optarg == '1' || c_tolower (*optarg) == 'y'
1177                       || (c_tolower (optarg[0]) == 'o'
1178                           && c_tolower (optarg[1]) == 'n'));
1179             setoptval (opt->type == OPT__PARENT ? "noparent" : "noclobber",
1180                        flag ? "0" : "1", opt->long_name);
1181             break;
1182           }
1183         case OPT__DONT_REMOVE_LISTING:
1184           setoptval ("removelisting", "0", opt->long_name);
1185           break;
1186         }
1187
1188       longindex = -1;
1189     }
1190
1191   nurl = argc - optind;
1192
1193   /* All user options have now been processed, so it's now safe to do
1194      interoption dependency checks. */
1195
1196   if (opt.noclobber && opt.convert_links)
1197     {
1198       fprintf (stderr,
1199                _("Both --no-clobber and --convert-links were specified,"
1200                  " only --convert-links will be used.\n"));
1201       opt.noclobber = false;
1202     }
1203
1204   if (opt.reclevel == 0)
1205       opt.reclevel = INFINITE_RECURSION; /* see recur.h for commentary */
1206
1207   if (opt.spider || opt.delete_after)
1208       opt.no_dirstruct = true;
1209
1210   if (opt.page_requisites && !opt.recursive)
1211     {
1212       /* Don't set opt.recursive here because it would confuse the FTP
1213          code.  Instead, call retrieve_tree below when either
1214          page_requisites or recursive is requested.  */
1215       opt.reclevel = 0;
1216       if (!opt.no_dirstruct)
1217         opt.dirstruct = 1;      /* normally handled by cmd_spec_recursive() */
1218     }
1219
1220   if (opt.verbose == -1)
1221     opt.verbose = !opt.quiet;
1222
1223
1224   /* Sanity checks.  */
1225   if (opt.verbose && opt.quiet)
1226     {
1227       fprintf (stderr, _("Can't be verbose and quiet at the same time.\n"));
1228       print_usage (1);
1229       exit (1);
1230     }
1231   if (opt.timestamping && opt.noclobber)
1232     {
1233       fprintf (stderr, _("\
1234 Can't timestamp and not clobber old files at the same time.\n"));
1235       print_usage (1);
1236       exit (1);
1237     }
1238 #ifdef ENABLE_IPV6
1239   if (opt.ipv4_only && opt.ipv6_only)
1240     {
1241       fprintf (stderr,
1242                _("Cannot specify both --inet4-only and --inet6-only.\n"));
1243       print_usage (1);
1244       exit (1);
1245     }
1246 #endif
1247   if (opt.output_document)
1248     {
1249       if (opt.convert_links
1250           && (nurl > 1 || opt.page_requisites || opt.recursive))
1251         {
1252           fputs (_("\
1253 Cannot specify both -k and -O if multiple URLs are given, or in combination\n\
1254 with -p or -r. See the manual for details.\n\n"), stderr);
1255           print_usage (1);
1256           exit (1);
1257         }
1258       if (opt.page_requisites
1259           || opt.recursive)
1260         {
1261           logprintf (LOG_NOTQUIET, "%s", _("\
1262 WARNING: combining -O with -r or -p will mean that all downloaded content\n\
1263 will be placed in the single file you specified.\n\n"));
1264         }
1265       if (opt.timestamping)
1266         {
1267           logprintf (LOG_NOTQUIET, "%s", _("\
1268 WARNING: timestamping does nothing in combination with -O. See the manual\n\
1269 for details.\n\n"));
1270           opt.timestamping = false;
1271         }
1272       if (opt.noclobber && file_exists_p(opt.output_document))
1273            {
1274               /* Check if output file exists; if it does, exit. */
1275               logprintf (LOG_VERBOSE,
1276                          _("File `%s' already there; not retrieving.\n"),
1277                          opt.output_document);
1278               exit(1);
1279            }
1280     }
1281
1282   if (opt.warc_filename != 0)
1283     {
1284       if (opt.noclobber)
1285         {
1286           fprintf (stderr,
1287                    _("WARC output does not work with --no-clobber, "
1288                      "--no-clobber will be disabled.\n"));
1289           opt.noclobber = false;
1290         }
1291       if (opt.timestamping)
1292         {
1293           fprintf (stderr,
1294                    _("WARC output does not work with timestamping, "
1295                      "timestamping will be disabled.\n"));
1296           opt.timestamping = false;
1297         }
1298       if (opt.spider)
1299         {
1300           fprintf (stderr,
1301                    _("WARC output does not work with --spider.\n"));
1302           exit (1);
1303         }
1304       if (opt.always_rest)
1305         {
1306           fprintf (stderr,
1307                    _("WARC output does not work with --continue, "
1308                      "--continue will be disabled.\n"));
1309           opt.always_rest = false;
1310         }
1311       if (opt.warc_cdx_dedup_filename != 0 && !opt.warc_digests_enabled)
1312         {
1313           fprintf (stderr,
1314                    _("Digests are disabled; WARC deduplication will "
1315                      "not find duplicate records.\n"));
1316         }
1317       if (opt.warc_keep_log)
1318         {
1319           opt.progress_type = xstrdup ("dot");
1320         }
1321     }
1322
1323   if (opt.ask_passwd && opt.passwd)
1324     {
1325       fprintf (stderr,
1326                _("Cannot specify both --ask-password and --password.\n"));
1327       print_usage (1);
1328       exit (1);
1329     }
1330
1331   if (!nurl && !opt.input_filename)
1332     {
1333       /* No URL specified.  */
1334       fprintf (stderr, _("%s: missing URL\n"), exec_name);
1335       print_usage (1);
1336       fprintf (stderr, "\n");
1337       /* #### Something nicer should be printed here -- similar to the
1338          pre-1.5 `--help' page.  */
1339       fprintf (stderr, _("Try `%s --help' for more options.\n"), exec_name);
1340       exit (1);
1341     }
1342
1343   /* Compile the regular expressions.  */
1344   switch (opt.regex_type)
1345     {
1346 #ifdef HAVE_LIBPCRE
1347       case regex_type_pcre:
1348         opt.regex_compile_fun = compile_pcre_regex;
1349         opt.regex_match_fun = match_pcre_regex;
1350         break;
1351 #endif
1352
1353       case regex_type_posix:
1354       default:
1355         opt.regex_compile_fun = compile_posix_regex;
1356         opt.regex_match_fun = match_posix_regex;
1357         break;
1358     }
1359   if (opt.acceptregex_s)
1360     {
1361       opt.acceptregex = opt.regex_compile_fun (opt.acceptregex_s);
1362       if (!opt.acceptregex)
1363         exit (1);
1364     }
1365   if (opt.rejectregex_s)
1366     {
1367       opt.rejectregex = opt.regex_compile_fun (opt.rejectregex_s);
1368       if (!opt.rejectregex)
1369         exit (1);
1370     }
1371   if (opt.post_data || opt.post_file_name)
1372     {
1373       if (opt.post_data && opt.post_file_name)
1374         {
1375           fprintf (stderr, _("You cannot specify both --post-data and --post-file.\n"));
1376           exit (1);
1377         }
1378       else if (opt.method)
1379         {
1380           fprintf (stderr, _("You cannot use --post-data or --post-file along with --method. "
1381                              "--method expects data through --body-data and --body-file options"));
1382           exit (1);
1383         }
1384     }
1385   if (opt.body_data || opt.body_file)
1386     {
1387       if (!opt.method)
1388         {
1389           fprintf (stderr, _("You must specify a method through --method=HTTPMethod "
1390                               "to use with --body-data or --body-file.\n"));
1391           exit (1);
1392         }
1393       else if (opt.body_data && opt.body_file)
1394         {
1395           fprintf (stderr, _("You cannot specify both --body-data and --body-file.\n"));
1396           exit (1);
1397         }
1398     }
1399
1400   /* Set various options as required for opt.method.  */
1401
1402   /* When user specifies HEAD as the method, we do not wish to download any
1403      files. Hence, set wget to run in spider mode.  */
1404   if (opt.method && strcasecmp (opt.method, "HEAD") == 0)
1405     setoptval ("spider", "1", "spider");
1406
1407   /* Convert post_data to body-data and post_file_name to body-file options.
1408      This is required so as to remove redundant code later on in gethttp().
1409      The --post-data and --post-file options may also be removed in
1410      the future hence it makes sense to convert them to aliases for
1411      the more generic --method options.
1412      This MUST occur only after the sanity checks so as to prevent the
1413      user from setting both post and body options simultaneously.
1414   */
1415   if (opt.post_data || opt.post_file_name)
1416     {
1417         setoptval ("method", "POST", "method");
1418         if (opt.post_data)
1419           {
1420             setoptval ("bodydata", opt.post_data, "body-data");
1421             opt.post_data = NULL;
1422           }
1423         else
1424           {
1425             setoptval ("bodyfile", opt.post_file_name, "body-file");
1426             opt.post_file_name = NULL;
1427           }
1428     }
1429
1430 #ifdef ENABLE_IRI
1431   if (opt.enable_iri)
1432     {
1433       if (opt.locale && !check_encoding_name (opt.locale))
1434         opt.locale = NULL;
1435
1436       if (!opt.locale)
1437         opt.locale = find_locale ();
1438
1439       if (opt.encoding_remote && !check_encoding_name (opt.encoding_remote))
1440         opt.encoding_remote = NULL;
1441     }
1442 #else
1443   memset (&dummy_iri, 0, sizeof (dummy_iri));
1444   if (opt.enable_iri || opt.locale || opt.encoding_remote)
1445     {
1446       /* sXXXav : be more specific... */
1447       fprintf (stderr, _("This version does not have support for IRIs\n"));
1448       exit(1);
1449     }
1450 #endif
1451
1452   if (opt.ask_passwd)
1453     {
1454       opt.passwd = prompt_for_password ();
1455
1456       if (opt.passwd == NULL || opt.passwd[0] == '\0')
1457         exit (1);
1458     }
1459
1460 #ifdef USE_WATT32
1461   if (opt.wdebug)
1462      dbug_init();
1463   sock_init();
1464 #else
1465   if (opt.background)
1466     fork_to_background ();
1467 #endif
1468
1469   /* Initialize progress.  Have to do this after the options are
1470      processed so we know where the log file is.  */
1471   if (opt.verbose)
1472     set_progress_implementation (opt.progress_type);
1473
1474   /* Fill in the arguments.  */
1475   url = alloca_array (char *, nurl + 1);
1476   if (url == NULL)
1477     {
1478       fprintf (stderr, _("Memory allocation problem\n"));
1479       exit (2);
1480     }
1481   for (i = 0; i < nurl; i++, optind++)
1482     {
1483       char *rewritten = rewrite_shorthand_url (argv[optind]);
1484       if (rewritten)
1485         url[i] = rewritten;
1486       else
1487         url[i] = xstrdup (argv[optind]);
1488     }
1489   url[i] = NULL;
1490
1491   /* Initialize logging.  */
1492   log_init (opt.lfilename, append_to_log);
1493
1494   /* Open WARC file. */
1495   if (opt.warc_filename != 0)
1496     warc_init ();
1497
1498   DEBUGP (("DEBUG output created by Wget %s on %s.\n\n",
1499            version_string, OS_TYPE));
1500
1501   /* Open the output filename if necessary.  */
1502
1503 /* 2005-04-17 SMS.
1504    Note that having the output_stream ("-O") file opened here for an FTP
1505    URL rather than in getftp() (ftp.c) (and the http equivalent) rather
1506    limits the ability in VMS to open the file differently for ASCII
1507    versus binary FTP there.  (Of course, doing it here allows a open
1508    failure to be detected immediately, without first connecting to the
1509    server.)
1510 */
1511   if (opt.output_document)
1512     {
1513       if (HYPHENP (opt.output_document))
1514         {
1515 #ifdef WINDOWS
1516           _setmode (_fileno (stdout), _O_BINARY);
1517 #endif
1518           output_stream = stdout;
1519         }
1520       else
1521         {
1522           struct_fstat st;
1523
1524 #ifdef __VMS
1525 /* Common fopen() optional arguments:
1526    sequential access only, access callback function.
1527 */
1528 # define FOPEN_OPT_ARGS , "fop=sqo", "acc", acc_cb, &open_id
1529           int open_id = 7;
1530 #else /* def __VMS */
1531 # define FOPEN_OPT_ARGS
1532 #endif /* def __VMS [else] */
1533
1534           output_stream = fopen (opt.output_document,
1535                                  opt.always_rest ? "ab" : "wb"
1536                                  FOPEN_OPT_ARGS);
1537           if (output_stream == NULL)
1538             {
1539               perror (opt.output_document);
1540               exit (1);
1541             }
1542           if (fstat (fileno (output_stream), &st) == 0 && S_ISREG (st.st_mode))
1543             output_stream_regular = true;
1544         }
1545       if (!output_stream_regular && opt.convert_links)
1546         {
1547           fprintf (stderr, _("-k can be used together with -O only if \
1548 outputting to a regular file.\n"));
1549           print_usage (1);
1550           exit(1);
1551         }
1552     }
1553
1554 #ifdef __VMS
1555   /* Set global ODS5 flag according to the specified destination (if
1556      any), otherwise according to the current default device.
1557   */
1558   if (output_stream == NULL)
1559     set_ods5_dest( "SYS$DISK");
1560   else if (output_stream != stdout)
1561     set_ods5_dest( opt.output_document);
1562 #endif /* def __VMS */
1563
1564 #ifdef WINDOWS
1565   ws_startup ();
1566 #endif
1567
1568 #ifdef SIGHUP
1569   /* Setup the signal handler to redirect output when hangup is
1570      received.  */
1571   if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
1572     signal(SIGHUP, redirect_output_signal);
1573 #endif
1574   /* ...and do the same for SIGUSR1.  */
1575 #ifdef SIGUSR1
1576   signal (SIGUSR1, redirect_output_signal);
1577 #endif
1578 #ifdef SIGPIPE
1579   /* Writing to a closed socket normally signals SIGPIPE, and the
1580      process exits.  What we want is to ignore SIGPIPE and just check
1581      for the return value of write().  */
1582   signal (SIGPIPE, SIG_IGN);
1583 #endif
1584 #ifdef SIGWINCH
1585   signal (SIGWINCH, progress_handle_sigwinch);
1586 #endif
1587
1588   /* Retrieve the URLs from argument list.  */
1589   for (t = url; *t; t++)
1590     {
1591       char *filename = NULL, *redirected_URL = NULL;
1592       int dt, url_err;
1593       /* Need to do a new struct iri every time, because
1594        * retrieve_url may modify it in some circumstances,
1595        * currently. */
1596       struct iri *iri = iri_new ();
1597       struct url *url_parsed;
1598
1599       set_uri_encoding (iri, opt.locale, true);
1600       url_parsed = url_parse (*t, &url_err, iri, true);
1601
1602       if (!url_parsed)
1603         {
1604           char *error = url_error (*t, url_err);
1605           logprintf (LOG_NOTQUIET, "%s: %s.\n",*t, error);
1606           xfree (error);
1607           inform_exit_status (URLERROR);
1608         }
1609       else
1610         {
1611           if ((opt.recursive || opt.page_requisites)
1612               && (url_scheme (*t) != SCHEME_FTP || url_uses_proxy (url_parsed)))
1613             {
1614               int old_follow_ftp = opt.follow_ftp;
1615
1616               /* Turn opt.follow_ftp on in case of recursive FTP retrieval */
1617               if (url_scheme (*t) == SCHEME_FTP)
1618                 opt.follow_ftp = 1;
1619
1620               retrieve_tree (url_parsed, NULL);
1621
1622               opt.follow_ftp = old_follow_ftp;
1623             }
1624           else
1625           {
1626             retrieve_url (url_parsed, *t, &filename, &redirected_URL, NULL,
1627                           &dt, opt.recursive, iri, true);
1628           }
1629
1630           if (opt.delete_after && filename != NULL && file_exists_p (filename))
1631             {
1632               DEBUGP (("Removing file due to --delete-after in main():\n"));
1633               logprintf (LOG_VERBOSE, _("Removing %s.\n"), filename);
1634               if (unlink (filename))
1635                 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1636             }
1637           xfree_null (redirected_URL);
1638           xfree_null (filename);
1639           url_free (url_parsed);
1640         }
1641       iri_free (iri);
1642     }
1643
1644   /* And then from the input file, if any.  */
1645   if (opt.input_filename)
1646     {
1647       int count;
1648       int status;
1649       status = retrieve_from_file (opt.input_filename, opt.force_html, &count);
1650       inform_exit_status (status);
1651       if (!count)
1652         logprintf (LOG_NOTQUIET, _("No URLs found in %s.\n"),
1653                    opt.input_filename);
1654     }
1655
1656   /* Print broken links. */
1657   if (opt.recursive && opt.spider)
1658     print_broken_links ();
1659
1660   /* Print the downloaded sum.  */
1661   if ((opt.recursive || opt.page_requisites
1662        || nurl > 1
1663        || (opt.input_filename && total_downloaded_bytes != 0))
1664       &&
1665       total_downloaded_bytes != 0)
1666     {
1667       double end_time = ptimer_measure (timer);
1668       ptimer_destroy (timer);
1669
1670       char *wall_time = xstrdup (secs_to_human_time (end_time - start_time));
1671       char *download_time = xstrdup (secs_to_human_time (total_download_time));
1672       logprintf (LOG_NOTQUIET,
1673                  _("FINISHED --%s--\nTotal wall clock time: %s\n"
1674                    "Downloaded: %d files, %s in %s (%s)\n"),
1675                  datetime_str (time (NULL)),
1676                  wall_time,
1677                  numurls,
1678                  human_readable (total_downloaded_bytes),
1679                  download_time,
1680                  retr_rate (total_downloaded_bytes, total_download_time));
1681       xfree (wall_time);
1682       xfree (download_time);
1683
1684       /* Print quota warning, if exceeded.  */
1685       if (opt.quota && total_downloaded_bytes > opt.quota)
1686         logprintf (LOG_NOTQUIET,
1687                    _("Download quota of %s EXCEEDED!\n"),
1688                    human_readable (opt.quota));
1689     }
1690
1691   if (opt.cookies_output)
1692     save_cookies ();
1693
1694   if (opt.convert_links && !opt.delete_after)
1695     convert_all_links ();
1696
1697   cleanup ();
1698
1699   exit (get_exit_status ());
1700 }
1701 #endif /* TESTING */
1702 \f
1703 #if defined(SIGHUP) || defined(SIGUSR1)
1704
1705 /* So the signal_name check doesn't blow when only one is available. */
1706 #ifndef SIGHUP
1707 # define SIGHUP -1
1708 #endif
1709 #ifndef SIGUSR1
1710 # define SIGUSR1 -1
1711 #endif
1712
1713 /* Hangup signal handler.  When wget receives SIGHUP or SIGUSR1, it
1714    will proceed operation as usual, trying to write into a log file.
1715    If that is impossible, the output will be turned off.  */
1716
1717 static void
1718 redirect_output_signal (int sig)
1719 {
1720   const char *signal_name = (sig == SIGHUP ? "SIGHUP" :
1721                              (sig == SIGUSR1 ? "SIGUSR1" :
1722                               "WTF?!"));
1723   log_request_redirect_output (signal_name);
1724   progress_schedule_redirect ();
1725   signal (sig, redirect_output_signal);
1726 }
1727 #endif
1728
1729 /*
1730  * vim: et ts=2 sw=2
1731  */