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 777static void 778print_version (void) 779{ 780 const char *wgetrc_title = _("Wgetrc: "); 781 const char *locale_title = _("Locale: "); 782 const char *compile_title = _("Compile: "); 783 const char *link_title = _("Link: "); 784 char *line; 785 char *env_wgetrc, *user_wgetrc; 786 int i; 787 788#ifdef __VMS 789 printf (_("GNU Wget %s built on VMS %s %s.\n\n"), 790 version_string, vms_arch(), vms_vers()); 791#else /* def __VMS */ 792 printf (_("GNU Wget %s built on %s.\n\n"), version_string, OS_TYPE); 793#endif /* def __VMS */ 794 /* compiled_features is a char*[]. We limit the characters per 795 line to MAX_CHARS_PER_LINE and prefix each line with a constant 796 number of spaces for proper alignment. */ 797 for (i = 0; compiled_features[i] != NULL; ) 798 { 799 int line_length = MAX_CHARS_PER_LINE; 800 while ((line_length > 0) && (compiled_features[i] != NULL)) 801 { 802 printf ("%s ", compiled_features[i]); 803 line_length -= strlen (compiled_features[i]) + 2; 804 i++; 805 } 806 printf ("\n"); 807 } 808 printf ("\n"); 809 /* Handle the case when $WGETRC is unset and $HOME/.wgetrc is 810 absent. */ 811 printf ("%s\n", wgetrc_title); 812 env_wgetrc = wgetrc_env_file_name (); 813 if (env_wgetrc && *env_wgetrc) 814 { 815 printf (_(" %s (env)\n"), env_wgetrc); 816 xfree (env_wgetrc); 817 } 818 user_wgetrc = wgetrc_user_file_name (); 819 if (user_wgetrc) 820 { 821 printf (_(" %s (user)\n"), user_wgetrc); 822 xfree (user_wgetrc); 823 } 824#ifdef SYSTEM_WGETRC 825 printf (_(" %s (system)\n"), SYSTEM_WGETRC); 826#endif 827 828#ifdef ENABLE_NLS 829 format_and_print_line (locale_title, 830 LOCALEDIR, 831 MAX_CHARS_PER_LINE); 832#endif /* def ENABLE_NLS */ 833 834 format_and_print_line (compile_title, 835 compilation_string, 836 MAX_CHARS_PER_LINE); 837 838 format_and_print_line (link_title, 839 link_string, 840 MAX_CHARS_PER_LINE); 841 842 printf ("\n"); 843 /* TRANSLATORS: When available, an actual copyright character 844 (cirle-c) should be used in preference to "(C)". */ 845 fputs (_("\ 846Copyright (C) 2009 Free Software Foundation, Inc.\n"), stdout); 847 fputs (_("\ 848License GPLv3+: GNU GPL version 3 or later\n\ 849<http://www.gnu.org/licenses/gpl.html>.\n\ 850This is free software: you are free to change and redistribute it.\n\ 851There is NO WARRANTY, to the extent permitted by law.\n"), stdout); 852 /* TRANSLATORS: When available, please use the proper diacritics for 853 names such as this one. See en_US.po for reference. */ 854 fputs (_("\nOriginally written by Hrvoje Niksic <hniksic@xemacs.org>.\n"), 855 stdout); 856 fputs (_("Currently maintained by Micah Cowan <micah@cowan.name>.\n"), 857 stdout); 858 fputs (_("Please send bug reports and questions to <bug-wget@gnu.org>.\n"), 859 stdout); 860 exit (0); 861} 862 863char *program_name; /* Needed by lib/error.c. */ 864 865int 866main (int argc, char **argv) 867{ 868 char **url, **t; 869 int i, ret, longindex; 870 int nurl, status; 871 bool append_to_log = false; 872 873 program_name = argv[0]; 874 875 i18n_initialize (); 876 877 /* Construct the name of the executable, without the directory part. */ 878 exec_name = strrchr (argv[0], PATH_SEPARATOR); 879 if (!exec_name) 880 exec_name = argv[0]; 881 else 882 ++exec_name; 883 884#ifdef WINDOWS 885 /* Drop extension (typically .EXE) from executable filename. */ 886 windows_main ((char **) &exec_name); 887#endif 888 889 /* Set option defaults; read the system wgetrc and ~/.wgetrc. */ 890 initialize (); 891 892 init_switches (); 893 longindex = -1; 894 while ((ret = getopt_long (argc, argv, 895 short_options, long_options, &longindex)) != -1) 896 { 897 int val; 898 struct cmdline_option *opt; 899 900 /* If LONGINDEX is unchanged, it means RET is referring a short 901 option. */ 902 if (longindex == -1) 903 { 904 if (ret == '?') 905 { 906 print_usage (); 907 printf ("\n"); 908 printf (_("Try `%s --help' for more options.\n"), exec_name); 909 exit (2); 910 } 911 /* Find the short option character in the mapping. */ 912 longindex = optmap[ret - 32]; 913 } 914 val = long_options[longindex].val; 915 916 /* Use the retrieved value to locate the option in the 917 option_data array, and to see if we're dealing with the 918 negated "--no-FOO" variant of the boolean option "--foo". */ 919 opt = &option_data[val & ~BOOLEAN_NEG_MARKER]; 920 switch (opt->type) 921 { 922 case OPT_VALUE: 923 setoptval (opt->data, optarg, opt->long_name); 924 break; 925 case OPT_BOOLEAN: 926 if (optarg) 927 /* The user has specified a value -- use it. */ 928 setoptval (opt->data, optarg, opt->long_name); 929 else 930 { 931 /* NEG is true for `--no-FOO' style boolean options. */ 932 bool neg = !!(val & BOOLEAN_NEG_MARKER); 933 setoptval (opt->data, neg ? "0" : "1", opt->long_name); 934 } 935 break; 936 case OPT_FUNCALL: 937 { 938 void (*func) (void) = (void (*) (void)) opt->data; 939 func (); 940 } 941 break; 942 case OPT__APPEND_OUTPUT: 943 setoptval ("logfile", optarg, opt->long_name); 944 append_to_log = true; 945 break; 946 case OPT__EXECUTE: 947 run_command (optarg); 948 break; 949 case OPT__NO: 950 { 951 /* We support real --no-FOO flags now, but keep these 952 short options for convenience and backward 953 compatibility. */ 954 char *p; 955 for (p = optarg; *p; p++) 956 switch (*p) 957 { 958 case 'v': 959 setoptval ("verbose", "0", opt->long_name); 960 break; 961 case 'H': 962 setoptval ("addhostdir", "0", opt->long_name); 963 break; 964 case 'd': 965 setoptval ("dirstruct", "0", opt->long_name); 966 break; 967 case 'c': 968 setoptval ("noclobber", "1", opt->long_name); 969 break; 970 case 'p': 971 setoptval ("noparent", "1", opt->long_name); 972 break; 973 default: 974 printf (_("%s: illegal option -- `-n%c'\n"), exec_name, *p); 975 print_usage (); 976 printf ("\n"); 977 printf (_("Try `%s --help' for more options.\n"), exec_name); 978 exit (1); 979 } 980 break; 981 } 982 case OPT__PARENT: 983 case OPT__CLOBBER: 984 { 985 /* The wgetrc commands are named noparent and noclobber, 986 so we must revert the meaning of the cmdline options 987 before passing the value to setoptval. */ 988 bool flag = true; 989 if (optarg) 990 flag = (*optarg == '1' || c_tolower (*optarg) == 'y' 991 || (c_tolower (optarg[0]) == 'o' 992 && c_tolower (optarg[1]) == 'n')); 993 setoptval (opt->type == OPT__PARENT ? "noparent" : "noclobber", 994 flag ? "0" : "1", opt->long_name); 995 break; 996 } 997 case OPT__DONT_REMOVE_LISTING: 998 setoptval ("removelisting", "0", opt->long_name); 999 break; 1000 } 1001 1002 longindex = -1; 1003 } 1004 1005 nurl = argc - optind; 1006 1007 /* All user options have now been processed, so it's now safe to do 1008 interoption dependency checks. */ 1009 1010 if (opt.reclevel == 0) 1011 opt.reclevel = INFINITE_RECURSION; /* see recur.h for commentary */ 1012 1013 if (opt.spider || opt.delete_after) 1014 opt.no_dirstruct = true; 1015 1016 if (opt.page_requisites && !opt.recursive) 1017 { 1018 /* Don't set opt.recursive here because it would confuse the FTP 1019 code. Instead, call retrieve_tree below when either 1020 page_requisites or recursive is requested. */ 1021 opt.reclevel = 0; 1022 if (!opt.no_dirstruct) 1023 opt.dirstruct = 1; /* normally handled by cmd_spec_recursive() */ 1024 } 1025 1026 if (opt.verbose == -1) 1027 opt.verbose = !opt.quiet; 1028 1029 /* Sanity checks. */ 1030 if (opt.verbose && opt.quiet) 1031 { 1032 printf (_("Can't be verbose and quiet at the same time.\n")); 1033 print_usage (); 1034 exit (1); 1035 } 1036 if (opt.timestamping && opt.noclobber) 1037 { 1038 printf (_("\ 1039Can't timestamp and not clobber old files at the same time.\n")); 1040 print_usage (); 1041 exit (1); 1042 } 1043#ifdef ENABLE_IPV6 1044 if (opt.ipv4_only && opt.ipv6_only) 1045 { 1046 printf (_("Cannot specify both --inet4-only and --inet6-only.\n")); 1047 print_usage (); 1048 exit (1); 1049 } 1050#endif 1051 if (opt.output_document) 1052 { 1053 if (opt.convert_links 1054 && (nurl > 1 || opt.page_requisites || opt.recursive)) 1055 { 1056 fputs (_("\ 1057Cannot specify both -k and -O if multiple URLs are given, or in combination\n\ 1058with -p or -r. See the manual for details.\n\n"), stdout); 1059 print_usage (); 1060 exit (1); 1061 } 1062 if (opt.page_requisites 1063 || opt.recursive) 1064 { 1065 logprintf (LOG_NOTQUIET, "%s", _("\ 1066WARNING: combining -O with -r or -p will mean that all downloaded content\n\ 1067will be placed in the single file you specified.\n\n")); 1068 } 1069 if (opt.timestamping) 1070 { 1071 logprintf (LOG_NOTQUIET, "%s", _("\ 1072WARNING: timestamping does nothing in combination with -O. See the manual\n\ 1073for details.\n\n")); 1074 opt.timestamping = false; 1075 } 1076 if (opt.noclobber && file_exists_p(opt.output_document)) 1077 { 1078 /* Check if output file exists; if it does, exit. */ 1079 logprintf (LOG_VERBOSE, _("File `%s' already there; not retrieving.\n"), opt.output_document); 1080 exit(1); 1081 } 1082 } 1083 1084 if (opt.ask_passwd && opt.passwd) 1085 { 1086 printf (_("Cannot specify both --ask-password and --password.\n")); 1087 print_usage (); 1088 exit (1); 1089 } 1090 1091 if (!nurl && !opt.input_filename) 1092 { 1093 /* No URL specified. */ 1094 printf (_("%s: missing URL\n"), exec_name); 1095 print_usage (); 1096 printf ("\n"); 1097 /* #### Something nicer should be printed here -- similar to the 1098 pre-1.5 `--help' page. */ 1099 printf (_("Try `%s --help' for more options.\n"), exec_name); 1100 exit (1); 1101 } 1102 1103#ifdef ENABLE_IRI 1104 if (opt.enable_iri) 1105 { 1106 if (opt.locale && !check_encoding_name (opt.locale)) 1107 opt.locale = NULL; 1108 1109 if (!opt.locale) 1110 opt.locale = find_locale (); 1111 1112 if (opt.encoding_remote && !check_encoding_name (opt.encoding_remote)) 1113 opt.encoding_remote = NULL; 1114 } 1115#else 1116 if (opt.enable_iri || opt.locale || opt.encoding_remote) 1117 { 1118 /* sXXXav : be more specific... */ 1119 printf(_("This version does not have support for IRIs\n")); 1120 exit(1); 1121 } 1122#endif 1123 1124 if (opt.ask_passwd) 1125 { 1126 opt.passwd = prompt_for_password (); 1127 1128 if (opt.passwd == NULL || opt.passwd[0] == '\0') 1129 exit (1); 1130 } 1131 1132#ifdef USE_WATT32 1133 if (opt.wdebug) 1134 dbug_init(); 1135 sock_init(); 1136#else 1137 if (opt.background) 1138 fork_to_background (); 1139#endif 1140 1141 /* Initialize progress. Have to do this after the options are 1142 processed so we know where the log file is. */ 1143 if (opt.verbose) 1144 set_progress_implementation (opt.progress_type); 1145 1146 /* Fill in the arguments. */ 1147 url = alloca_array (char *, nurl + 1); 1148 for (i = 0; i < nurl; i++, optind++) 1149 { 1150 char *rewritten = rewrite_shorthand_url (argv[optind]); 1151 if (rewritten) 1152 url[i] = rewritten; 1153 else 1154 url[i] = xstrdup (argv[optind]); 1155 } 1156 url[i] = NULL; 1157 1158 /* Initialize logging. */ 1159 log_init (opt.lfilename, append_to_log); 1160 1161 DEBUGP (("DEBUG output created by Wget %s on %s.\n\n", 1162 version_string, OS_TYPE)); 1163 1164 /* Open the output filename if necessary. */ 1165 1166/* 2005-04-17 SMS. 1167 Note that having the output_stream ("-O") file opened here for an FTP 1168 URL rather than in getftp() (ftp.c) (and the http equivalent) rather 1169 limits the ability in VMS to open the file differently for ASCII 1170 versus binary FTP there. (Of course, doing it here allows a open 1171 failure to be detected immediately, without first connecting to the 1172 server.) 1173*/ 1174 if (opt.output_document) 1175 { 1176 if (HYPHENP (opt.output_document)) 1177 { 1178#ifdef WINDOWS 1179 FILE *result; 1180 result = freopen ("CONOUT$", "wb", stdout); 1181 if (result == NULL) 1182 { 1183 logputs (LOG_NOTQUIET, _("\ 1184WARNING: Can't reopen standard output in binary mode;\n\ 1185 downloaded file may contain inappropriate line endings.\n")); 1186 } 1187#endif 1188 output_stream = stdout; 1189 } 1190 else 1191 { 1192 struct_fstat st; 1193 1194#ifdef __VMS 1195/* Common fopen() optional arguments: 1196 sequential access only, access callback function. 1197*/ 1198# define FOPEN_OPT_ARGS , "fop=sqo", "acc", acc_cb, &open_id 1199 int open_id = 7; 1200#else /* def __VMS */ 1201# define FOPEN_OPT_ARGS 1202#endif /* def __VMS [else] */ 1203 1204 output_stream = fopen (opt.output_document, 1205 opt.always_rest ? "ab" : "wb" 1206 FOPEN_OPT_ARGS); 1207 if (output_stream == NULL) 1208 { 1209 perror (opt.output_document); 1210 exit (1); 1211 } 1212 if (fstat (fileno (output_stream), &st) == 0 && S_ISREG (st.st_mode)) 1213 output_stream_regular = true; 1214 } 1215 } 1216 1217#ifdef __VMS 1218 /* Set global ODS5 flag according to the specified destination (if 1219 any), otherwise according to the current default device. 1220 */ 1221 if (output_stream == NULL) 1222 { 1223 set_ods5_dest( "SYS$DISK"); 1224 } 1225 else if (output_stream != stdout) 1226 { 1227 set_ods5_dest( opt.output_document); 1228 } 1229#endif /* def __VMS */ 1230 1231#ifdef WINDOWS 1232 ws_startup (); 1233#endif 1234 1235#ifdef SIGHUP 1236 /* Setup the signal handler to redirect output when hangup is 1237 received. */ 1238 if (signal(SIGHUP, SIG_IGN) != SIG_IGN) 1239 signal(SIGHUP, redirect_output_signal); 1240#endif 1241 /* ...and do the same for SIGUSR1. */ 1242#ifdef SIGUSR1 1243 signal (SIGUSR1, redirect_output_signal); 1244#endif 1245#ifdef SIGPIPE 1246 /* Writing to a closed socket normally signals SIGPIPE, and the 1247 process exits. What we want is to ignore SIGPIPE and just check 1248 for the return value of write(). */ 1249 signal (SIGPIPE, SIG_IGN); 1250#endif 1251#ifdef SIGWINCH 1252 signal (SIGWINCH, progress_handle_sigwinch); 1253#endif 1254 1255 status = RETROK; /* initialize it, just-in-case */ 1256 /* Retrieve the URLs from argument list. */ 1257 for (t = url; *t; t++) 1258 { 1259 char *filename = NULL, *redirected_URL = NULL; 1260 int dt, url_err; 1261 /* Need to do a new struct iri every time, because 1262 * retrieve_url may modify it in some circumstances, 1263 * currently. */ 1264 struct iri *iri = iri_new (); 1265 struct url *url_parsed; 1266 1267 set_uri_encoding (iri, opt.locale, true); 1268 url_parsed = url_parse (*t, &url_err, iri, true); 1269 1270 if (!url_parsed) 1271 { 1272 char *error = url_error (*t, url_err); 1273 logprintf (LOG_NOTQUIET, "%s: %s.\n",*t, error); 1274 xfree (error); 1275 status = URLERROR; 1276 } 1277 else 1278 { 1279 if ((opt.recursive || opt.page_requisites) 1280 && (url_scheme (*t) != SCHEME_FTP || url_uses_proxy (url_parsed))) 1281 { 1282 int old_follow_ftp = opt.follow_ftp; 1283 1284 /* Turn opt.follow_ftp on in case of recursive FTP retrieval */ 1285 if (url_scheme (*t) == SCHEME_FTP) 1286 opt.follow_ftp = 1; 1287 1288 status = retrieve_tree (url_parsed, NULL); 1289 1290 opt.follow_ftp = old_follow_ftp; 1291 } 1292 else 1293 { 1294 status = retrieve_url (url_parsed, *t, &filename, &redirected_URL, 1295 NULL, &dt, opt.recursive, iri, true); 1296 } 1297 1298 if (opt.delete_after && file_exists_p(filename)) 1299 { 1300 DEBUGP (("Removing file due to --delete-after in main():\n")); 1301 logprintf (LOG_VERBOSE, _("Removing %s.\n"), filename); 1302 if (unlink (filename)) 1303 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno)); 1304 } 1305 xfree_null (redirected_URL); 1306 xfree_null (filename); 1307 url_free (url_parsed); 1308 } 1309 iri_free (iri); 1310 } 1311 1312 /* And then from the input file, if any. */ 1313 if (opt.input_filename) 1314 { 1315 int count; 1316 status = retrieve_from_file (opt.input_filename, opt.force_html, &count); 1317 if (!count) 1318 logprintf (LOG_NOTQUIET, _("No URLs found in %s.\n"), 1319 opt.input_filename); 1320 } 1321 1322 /* Print broken links. */ 1323 if (opt.recursive && opt.spider) 1324 { 1325 print_broken_links(); 1326 } 1327 1328 /* Print the downloaded sum. */ 1329 if ((opt.recursive || opt.page_requisites 1330 || nurl > 1 1331 || (opt.input_filename && total_downloaded_bytes != 0)) 1332 && 1333 total_downloaded_bytes != 0) 1334 { 1335 logprintf (LOG_NOTQUIET, 1336 _("FINISHED --%s--\nDownloaded: %d files, %s in %s (%s)\n"), 1337 datetime_str (time (NULL)), 1338 numurls, 1339 human_readable (total_downloaded_bytes), 1340 secs_to_human_time (total_download_time), 1341 retr_rate (total_downloaded_bytes, total_download_time)); 1342 /* Print quota warning, if exceeded. */ 1343 if (opt.quota && total_downloaded_bytes > opt.quota) 1344 logprintf (LOG_NOTQUIET, 1345 _("Download quota of %s EXCEEDED!\n"), 1346 human_readable (opt.quota)); 1347 } 1348 1349 if (opt.cookies_output) 1350 save_cookies (); 1351 1352 if (opt.convert_links && !opt.delete_after) 1353 convert_all_links (); 1354 1355 log_close (); 1356 for (i = 0; i < nurl; i++) 1357 xfree (url[i]); 1358 cleanup (); 1359 1360 return get_exit_status (); 1361} 1362#endif /* TESTING */ 1363 1364#if defined(SIGHUP) || defined(SIGUSR1) 1365 1366/* So the signal_name check doesn't blow when only one is available. */ 1367#ifndef SIGHUP 1368# define SIGHUP -1 1369#endif 1370#ifndef SIGUSR1 1371# define SIGUSR1 -1 1372#endif 1373 1374/* Hangup signal handler. When wget receives SIGHUP or SIGUSR1, it 1375 will proceed operation as usual, trying to write into a log file. 1376 If that is impossible, the output will be turned off. */ 1377 1378static void 1379redirect_output_signal (int sig) 1380{ 1381 const char *signal_name = (sig == SIGHUP ? "SIGHUP" : 1382 (sig == SIGUSR1 ? "SIGUSR1" : 1383 "WTF?!")); 1384 log_request_redirect_output (signal_name); 1385 progress_schedule_redirect (); 1386 signal (sig, redirect_output_signal); 1387} 1388#endif 1389 1390/* 1391 * vim: et ts=2 sw=2 1392 */ 1393