~ubuntu-branches/ubuntu/trusty/wget/trusty-proposed

« back to all changes in this revision

Viewing changes to .pc/disable-SSLv2/src/main.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Langasek
  • Date: 2011-05-17 19:46:25 UTC
  • mfrom: (2.1.10 sid)
  • Revision ID: james.westby@ubuntu.com-20110517194625-awyf9lkvyohk71ni
Tags: 1.12-3.1ubuntu1
* Merge from Debian unstable, remaining changes:
  - Add wget-udeb to ship wget.gnu as alternative to busybox wget
    implementation.
  - Keep build dependencies in main:
    + debian/control: remove info2man build-dep
    + debian/patches/series: disable wget-infopod_generated_manpage
  - Depend on libssl-dev 0.9.8k-7ubuntu4 (LP: #503339)
  - Mark wget Multi-Arch: foreign, so packages that aren't of the same arch
    can depend on it.

Show diffs side-by-side

added added

removed removed

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