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