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