1 /* Reading/parsing the initialization file.
2 Copyright (C) 2005 Free Software Foundation, Inc.
4 This file is part of GNU Wget.
6 GNU Wget is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 GNU Wget is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with Wget; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 In addition, as a special exception, the Free Software Foundation
21 gives permission to link the code of its release of Wget with the
22 OpenSSL project's "OpenSSL" library (or with modified versions of it
23 that use the same license as the "OpenSSL" library), and distribute
24 the linked executables. You must obey the GNU General Public License
25 in all respects for all of the code used other than "OpenSSL". If you
26 modify this file, you may extend this exception to your version of the
27 file, but you are not obligated to do so. If you do not wish to do
28 so, delete this exception statement from your version. */
33 #include <sys/types.h>
56 #include "recur.h" /* for INFINITE_RECURSION */
57 #include "convert.h" /* for convert_cleanup */
58 #include "res.h" /* for res_cleanup */
64 /* We want tilde expansion enabled only when reading `.wgetrc' lines;
65 otherwise, it will be performed by the shell. This variable will
66 be set by the wgetrc-reading function. */
68 static int enable_tilde_expansion;
71 #define CMD_DECLARE(func) static int func \
72 PARAMS ((const char *, const char *, void *))
74 CMD_DECLARE (cmd_boolean);
75 CMD_DECLARE (cmd_bytes);
76 CMD_DECLARE (cmd_bytes_large);
78 CMD_DECLARE (cmd_cert_type);
80 CMD_DECLARE (cmd_directory_vector);
81 CMD_DECLARE (cmd_lockable_boolean);
82 CMD_DECLARE (cmd_number);
83 CMD_DECLARE (cmd_number_inf);
84 CMD_DECLARE (cmd_string);
85 CMD_DECLARE (cmd_file);
86 CMD_DECLARE (cmd_directory);
87 CMD_DECLARE (cmd_time);
88 CMD_DECLARE (cmd_vector);
90 CMD_DECLARE (cmd_spec_dirstruct);
91 CMD_DECLARE (cmd_spec_header);
92 CMD_DECLARE (cmd_spec_htmlify);
93 CMD_DECLARE (cmd_spec_mirror);
94 CMD_DECLARE (cmd_spec_prefer_family);
95 CMD_DECLARE (cmd_spec_progress);
96 CMD_DECLARE (cmd_spec_recursive);
97 CMD_DECLARE (cmd_spec_restrict_file_names);
99 CMD_DECLARE (cmd_spec_secure_protocol);
101 CMD_DECLARE (cmd_spec_timeout);
102 CMD_DECLARE (cmd_spec_useragent);
104 /* List of recognized commands, each consisting of name, place and
105 function. When adding a new command, simply add it to the list,
106 but be sure to keep the list sorted alphabetically, as
107 command_by_name depends on it. Also, be sure to add any entries
108 that allocate memory (e.g. cmd_string and cmd_vector guys) to the
109 cleanup() function below. */
114 int (*action) PARAMS ((const char *, const char *, void *));
116 { "accept", &opt.accepts, cmd_vector },
117 { "addhostdir", &opt.add_hostdir, cmd_boolean },
118 { "alwaysrest", &opt.always_rest, cmd_boolean }, /* deprecated */
119 { "background", &opt.background, cmd_boolean },
120 { "backupconverted", &opt.backup_converted, cmd_boolean },
121 { "backups", &opt.backups, cmd_number },
122 { "base", &opt.base_href, cmd_string },
123 { "bindaddress", &opt.bind_address, cmd_string },
125 { "cacertificate", &opt.ca_cert, cmd_file },
127 { "cache", &opt.allow_cache, cmd_boolean },
129 { "cadirectory", &opt.ca_directory, cmd_directory },
130 { "certificate", &opt.cert_file, cmd_file },
131 { "certificatetype", &opt.cert_type, cmd_cert_type },
132 { "checkcertificate", &opt.check_cert, cmd_boolean },
134 { "connecttimeout", &opt.connect_timeout, cmd_time },
135 { "continue", &opt.always_rest, cmd_boolean },
136 { "convertlinks", &opt.convert_links, cmd_boolean },
137 { "cookies", &opt.cookies, cmd_boolean },
138 { "cutdirs", &opt.cut_dirs, cmd_number },
140 { "debug", &opt.debug, cmd_boolean },
142 { "deleteafter", &opt.delete_after, cmd_boolean },
143 { "dirprefix", &opt.dir_prefix, cmd_directory },
144 { "dirstruct", NULL, cmd_spec_dirstruct },
145 { "dnscache", &opt.dns_cache, cmd_boolean },
146 { "dnstimeout", &opt.dns_timeout, cmd_time },
147 { "domains", &opt.domains, cmd_vector },
148 { "dotbytes", &opt.dot_bytes, cmd_bytes },
149 { "dotsinline", &opt.dots_in_line, cmd_number },
150 { "dotspacing", &opt.dot_spacing, cmd_number },
151 { "dotstyle", &opt.dot_style, cmd_string },
153 { "egdfile", &opt.egd_file, cmd_file },
155 { "excludedirectories", &opt.excludes, cmd_directory_vector },
156 { "excludedomains", &opt.exclude_domains, cmd_vector },
157 { "followftp", &opt.follow_ftp, cmd_boolean },
158 { "followtags", &opt.follow_tags, cmd_vector },
159 { "forcehtml", &opt.force_html, cmd_boolean },
160 { "ftppasswd", &opt.ftp_pass, cmd_string },
161 { "ftpproxy", &opt.ftp_proxy, cmd_string },
162 { "glob", &opt.ftp_glob, cmd_boolean },
163 { "header", &opt.user_headers, cmd_spec_header },
164 { "htmlextension", &opt.html_extension, cmd_boolean },
165 { "htmlify", NULL, cmd_spec_htmlify },
166 { "httpkeepalive", &opt.http_keep_alive, cmd_boolean },
167 { "httppasswd", &opt.http_passwd, cmd_string },
168 { "httpproxy", &opt.http_proxy, cmd_string },
169 { "httpsproxy", &opt.https_proxy, cmd_string },
170 { "httpuser", &opt.http_user, cmd_string },
171 { "ignorelength", &opt.ignore_length, cmd_boolean },
172 { "ignoretags", &opt.ignore_tags, cmd_vector },
173 { "includedirectories", &opt.includes, cmd_directory_vector },
175 { "inet4only", &opt.ipv4_only, cmd_boolean },
176 { "inet6only", &opt.ipv6_only, cmd_boolean },
178 { "input", &opt.input_filename, cmd_file },
179 { "keepsessioncookies", &opt.keep_session_cookies, cmd_boolean },
180 { "killlonger", &opt.kill_longer, cmd_boolean },
181 { "limitrate", &opt.limit_rate, cmd_bytes },
182 { "loadcookies", &opt.cookies_input, cmd_file },
183 { "logfile", &opt.lfilename, cmd_file },
184 { "login", &opt.ftp_acc, cmd_string },
185 { "mirror", NULL, cmd_spec_mirror },
186 { "netrc", &opt.netrc, cmd_boolean },
187 { "noclobber", &opt.noclobber, cmd_boolean },
188 { "noparent", &opt.no_parent, cmd_boolean },
189 { "noproxy", &opt.no_proxy, cmd_vector },
190 { "numtries", &opt.ntry, cmd_number_inf },/* deprecated*/
191 { "outputdocument", &opt.output_document, cmd_file },
192 { "pagerequisites", &opt.page_requisites, cmd_boolean },
193 { "passiveftp", &opt.ftp_pasv, cmd_lockable_boolean },
194 { "postdata", &opt.post_data, cmd_string },
195 { "postfile", &opt.post_file_name, cmd_file },
196 { "preferfamily", NULL, cmd_spec_prefer_family },
197 { "preservepermissions", &opt.preserve_perm, cmd_boolean },
198 { "privatekey", &opt.private_key, cmd_file },
199 { "privatekeytype", &opt.private_key_type, cmd_cert_type },
200 { "progress", &opt.progress_type, cmd_spec_progress },
201 { "protocoldirectories", &opt.protocol_directories, cmd_boolean },
202 { "proxypasswd", &opt.proxy_passwd, cmd_string },
203 { "proxyuser", &opt.proxy_user, cmd_string },
204 { "quiet", &opt.quiet, cmd_boolean },
205 { "quota", &opt.quota, cmd_bytes_large },
206 { "randomwait", &opt.random_wait, cmd_boolean },
207 { "readtimeout", &opt.read_timeout, cmd_time },
208 { "reclevel", &opt.reclevel, cmd_number_inf },
209 { "recursive", NULL, cmd_spec_recursive },
210 { "referer", &opt.referer, cmd_string },
211 { "reject", &opt.rejects, cmd_vector },
212 { "relativeonly", &opt.relative_only, cmd_boolean },
213 { "removelisting", &opt.remove_listing, cmd_boolean },
214 { "restrictfilenames", NULL, cmd_spec_restrict_file_names },
215 { "retrsymlinks", &opt.retr_symlinks, cmd_boolean },
216 { "retryconnrefused", &opt.retry_connrefused, cmd_boolean },
217 { "robots", &opt.use_robots, cmd_boolean },
218 { "savecookies", &opt.cookies_output, cmd_file },
219 { "saveheaders", &opt.save_headers, cmd_boolean },
221 { "secureprotocol", &opt.secure_protocol, cmd_spec_secure_protocol },
223 { "serverresponse", &opt.server_response, cmd_boolean },
224 { "spanhosts", &opt.spanhost, cmd_boolean },
225 { "spider", &opt.spider, cmd_boolean },
226 { "strictcomments", &opt.strict_comments, cmd_boolean },
227 { "timeout", NULL, cmd_spec_timeout },
228 { "timestamping", &opt.timestamping, cmd_boolean },
229 { "tries", &opt.ntry, cmd_number_inf },
230 { "useproxy", &opt.use_proxy, cmd_boolean },
231 { "useragent", NULL, cmd_spec_useragent },
232 { "verbose", &opt.verbose, cmd_boolean },
233 { "wait", &opt.wait, cmd_time },
234 { "waitretry", &opt.waitretry, cmd_time }
237 /* Look up CMDNAME in the commands[] and return its position in the
238 array. If CMDNAME is not found, return -1. */
241 command_by_name (const char *cmdname)
243 /* Use binary search for speed. Wget has ~100 commands, which
244 guarantees a worst case performance of 7 string comparisons. */
245 int lo = 0, hi = countof (commands) - 1;
249 int mid = (lo + hi) >> 1;
250 int cmp = strcasecmp (cmdname, commands[mid].name);
261 /* Reset the variables to default values. */
267 /* Most of the default values are 0. Just reset everything, and
268 fill in the non-zero values. Note that initializing pointers to
269 NULL this way is technically illegal, but porting Wget to a
270 machine where NULL is not all-zero bit pattern will be the least
271 of the implementors' worries. */
279 opt.ftp_acc = xstrdup ("anonymous");
280 opt.ftp_pass = xstrdup ("-wget@");
284 opt.http_keep_alive = 1;
286 tmp = getenv ("no_proxy");
288 opt.no_proxy = sepstring (tmp);
291 opt.read_timeout = 900;
294 opt.remove_listing = 1;
296 opt.dot_bytes = 1024;
297 opt.dot_spacing = 10;
298 opt.dots_in_line = 50;
307 /* The default for file name restriction defaults to the OS type. */
308 #if !defined(WINDOWS) && !defined(__CYGWIN__)
309 opt.restrict_files_os = restrict_unix;
311 opt.restrict_files_os = restrict_windows;
313 opt.restrict_files_ctrl = 1;
316 /* Return the user's home directory (strdup-ed), or NULL if none is
321 char *home = getenv ("HOME");
326 /* If HOME is not defined, try getting it from the password
328 struct passwd *pwd = getpwuid (getuid ());
329 if (!pwd || !pwd->pw_dir)
333 /* Under Windows, if $HOME isn't defined, use the directory where
334 `wget.exe' resides. */
339 return home ? xstrdup (home) : NULL;
342 /* Return the path to the user's .wgetrc. This is either the value of
343 `WGETRC' environment variable, or `$HOME/.wgetrc'.
345 If the `WGETRC' variable exists but the file does not exist, the
346 function will exit(). */
348 wgetrc_file_name (void)
353 /* Try the environment. */
354 env = getenv ("WGETRC");
357 if (!file_exists_p (env))
359 fprintf (stderr, _("%s: WGETRC points to %s, which doesn't exist.\n"),
363 return xstrdup (env);
366 /* If that failed, try $HOME/.wgetrc. */
369 file = aprintf ("%s/.wgetrc", home);
373 /* Under Windows, if we still haven't found .wgetrc, look for the file
374 `wget.ini' in the directory where `wget.exe' resides; we do this for
375 backward compatibility with previous versions of Wget.
376 SYSTEM_WGETRC should not be defined under WINDOWS. */
377 if (!file || !file_exists_p (file))
383 file = aprintf ("%s/wget.ini", home);
389 if (!file_exists_p (file))
397 static int parse_line PARAMS ((const char *, char **, char **, int *));
398 static int setval_internal PARAMS ((int, const char *, const char *));
400 /* Initialize variables from a wgetrc file. */
403 run_wgetrc (const char *file)
409 fp = fopen (file, "rb");
412 fprintf (stderr, _("%s: Cannot read %s (%s).\n"), exec_name,
413 file, strerror (errno));
416 enable_tilde_expansion = 1;
418 while ((line = read_whole_line (fp)) != NULL)
423 /* Parse the line. */
424 status = parse_line (line, &com, &val, &comind);
426 /* If everything is OK, set the value. */
429 if (!setval_internal (comind, com, val))
430 fprintf (stderr, _("%s: Error in %s at line %d.\n"), exec_name,
435 else if (status == 0)
436 fprintf (stderr, _("%s: Error in %s at line %d.\n"), exec_name,
440 enable_tilde_expansion = 0;
444 /* Initialize the defaults and run the system wgetrc and user's own
451 /* Load the hard-coded defaults. */
454 /* If SYSTEM_WGETRC is defined, use it. */
456 if (file_exists_p (SYSTEM_WGETRC))
457 run_wgetrc (SYSTEM_WGETRC);
459 /* Override it with your own, if one exists. */
460 file = wgetrc_file_name ();
463 /* #### We should canonicalize `file' and SYSTEM_WGETRC with
464 something like realpath() before comparing them with `strcmp' */
466 if (!strcmp (file, SYSTEM_WGETRC))
468 fprintf (stderr, _("\
469 %s: Warning: Both system and user wgetrc point to `%s'.\n"),
479 /* Remove dashes and underscores from S, modifying S in the
485 char *t = s; /* t - tortoise */
486 char *h = s; /* h - hare */
488 if (*h == '_' || *h == '-')
495 /* Parse the line pointed by line, with the syntax:
496 <sp>* command <sp>* = <sp>* value <sp>*
497 Uses malloc to allocate space for command and value.
498 If the line is invalid, data is freed and 0 is returned.
505 In case of success, *COM and *VAL point to freshly allocated
506 strings, and *COMIND points to com's index. In case of error or
507 empty line, those values are unaffected. */
510 parse_line (const char *line, char **com, char **val, int *comind)
513 const char *end = line + strlen (line);
514 const char *cmdstart, *cmdend;
515 const char *valstart, *valend;
520 /* Skip leading and trailing whitespace. */
521 while (*line && ISSPACE (*line))
523 while (end > line && ISSPACE (end[-1]))
526 /* Skip empty lines and comments. */
527 if (!*line || *line == '#')
533 while (p < end && (ISALPHA (*p) || *p == '_' || *p == '-'))
537 /* Skip '=', as well as any space before or after it. */
538 while (p < end && ISSPACE (*p))
540 if (p == end || *p != '=')
543 while (p < end && ISSPACE (*p))
549 /* The line now known to be syntactically correct. Check whether
550 the command is valid. */
551 BOUNDED_TO_ALLOCA (cmdstart, cmdend, cmdcopy);
553 ind = command_by_name (cmdcopy);
557 /* The command is valid. Now fill in the values and report success
560 *com = strdupdelim (cmdstart, cmdend);
561 *val = strdupdelim (valstart, valend);
565 /* Run commands[comind].action. */
568 setval_internal (int comind, const char *com, const char *val)
570 assert (0 <= comind && comind < countof (commands));
571 DEBUGP (("Setting %s (%d) to %s\n", com, comind, val));
572 return ((*commands[comind].action) (com, val, commands[comind].place));
575 /* Run command COM with value VAL. If running the command produces an
576 error, report the error and exit.
578 This is intended to be called from main() to modify Wget's behavior
579 through command-line switches. Since COM is hard-coded in main(),
580 it is not canonicalized, and this aborts when COM is not found.
582 If COMIND's are exported to init.h, this function will be changed
583 to accept COMIND directly. */
586 setoptval (const char *com, const char *val)
588 assert (val != NULL);
589 if (!setval_internal (command_by_name (com), com, val))
593 /* Parse OPT into command and value and run it. For example,
594 run_command("foo=bar") is equivalent to setoptval("foo", "bar").
595 This is used by the `--execute' flag in main.c. */
598 run_command (const char *opt)
602 int status = parse_line (opt, &com, &val, &comind);
605 if (!setval_internal (comind, com, val))
610 else if (status == 0)
612 fprintf (stderr, _("%s: Invalid --execute command `%s'\n"),
618 /* Generic helper functions, for use with `commands'. */
620 /* Forward declarations: */
625 static int decode_string PARAMS ((const char *, const struct decode_item *,
627 static int simple_atoi PARAMS ((const char *, const char *, int *));
628 static int simple_atof PARAMS ((const char *, const char *, double *));
630 #define CMP1(p, c0) (TOLOWER((p)[0]) == (c0) && (p)[1] == '\0')
632 #define CMP2(p, c0, c1) (TOLOWER((p)[0]) == (c0) \
633 && TOLOWER((p)[1]) == (c1) \
636 #define CMP3(p, c0, c1, c2) (TOLOWER((p)[0]) == (c0) \
637 && TOLOWER((p)[1]) == (c1) \
638 && TOLOWER((p)[2]) == (c2) \
642 /* Store the boolean value from VAL to PLACE. COM is ignored,
643 except for error messages. */
645 cmd_boolean (const char *com, const char *val, void *place)
649 if (CMP2 (val, 'o', 'n') || CMP3 (val, 'y', 'e', 's') || CMP1 (val, '1'))
650 /* "on", "yes" and "1" mean true. */
652 else if (CMP3 (val, 'o', 'f', 'f') || CMP2 (val, 'n', 'o') || CMP1 (val, '0'))
653 /* "off", "no" and "0" mean false. */
658 _("%s: %s: Invalid boolean `%s', use `on' or `off'.\n"),
659 exec_name, com, val);
663 *(int *)place = bool_value;
667 /* Store the lockable_boolean {2, 1, 0, -1} value from VAL to PLACE.
668 COM is ignored, except for error messages. Values 2 and -1
669 indicate that once defined, the value may not be changed by
670 successive wgetrc files or command-line arguments.
672 Values: 2 - Enable a particular option for good ("always")
673 1 - Enable an option ("on")
674 0 - Disable an option ("off")
675 -1 - Disable an option for good ("never") */
677 cmd_lockable_boolean (const char *com, const char *val, void *place)
679 int lockable_boolean_value;
681 int oldval = *(int *)place;
684 * If a config file said "always" or "never", don't allow command line
685 * arguments to override the config file.
687 if (oldval == -1 || oldval == 2)
690 if (0 == strcasecmp (val, "always") || CMP1 (val, '2'))
691 lockable_boolean_value = 2;
692 else if (CMP2 (val, 'o', 'n') || CMP3 (val, 'y', 'e', 's') || CMP1 (val, '1'))
693 lockable_boolean_value = 1;
694 else if (CMP3 (val, 'o', 'f', 'f') || CMP2 (val, 'n', 'o') || CMP1 (val, '0'))
695 lockable_boolean_value = 0;
696 else if (0 == strcasecmp (val, "never") || CMP2 (val, '-', '1'))
697 lockable_boolean_value = -1;
701 _("%s: %s: Invalid boolean `%s', use always, on, off, or never.\n"),
702 exec_name, com, val);
706 *(int *)place = lockable_boolean_value;
710 /* Set the non-negative integer value from VAL to PLACE. With
711 incorrect specification, the number remains unchanged. */
713 cmd_number (const char *com, const char *val, void *place)
715 if (!simple_atoi (val, val + strlen (val), place)
716 || *(int *) place < 0)
718 fprintf (stderr, _("%s: %s: Invalid number `%s'.\n"),
719 exec_name, com, val);
725 /* Similar to cmd_number(), only accepts `inf' as a synonym for 0. */
727 cmd_number_inf (const char *com, const char *val, void *place)
729 if (!strcasecmp (val, "inf"))
734 return cmd_number (com, val, place);
737 /* Copy (strdup) the string at COM to a new location and place a
738 pointer to *PLACE. */
740 cmd_string (const char *com, const char *val, void *place)
742 char **pstring = (char **)place;
744 xfree_null (*pstring);
745 *pstring = xstrdup (val);
750 # define ISSEP(c) ((c) == '/')
752 # define ISSEP(c) ((c) == '/' || (c) == '\\')
755 /* Like the above, but handles tilde-expansion when reading a user's
756 `.wgetrc'. In that case, and if VAL begins with `~', the tilde
757 gets expanded to the user's home directory. */
759 cmd_file (const char *com, const char *val, void *place)
761 char **pstring = (char **)place;
763 xfree_null (*pstring);
765 /* #### If VAL is empty, perhaps should set *PLACE to NULL. */
767 if (!enable_tilde_expansion || !(*val == '~' && ISSEP (val[1])))
770 *pstring = xstrdup (val);
775 char *home = home_dir ();
779 homelen = strlen (home);
780 while (homelen && ISSEP (home[homelen - 1]))
781 home[--homelen] = '\0';
783 /* Skip the leading "~/". */
784 for (++val; ISSEP (*val); val++)
787 *pstring = concat_strings (home, "/", val, (char *) 0);
791 /* Convert "\" to "/". */
794 for (s = *pstring; *s; s++)
802 /* Like cmd_file, but strips trailing '/' characters. */
804 cmd_directory (const char *com, const char *val, void *place)
808 /* Call cmd_file() for tilde expansion and separator
809 canonicalization (backslash -> slash under Windows). These
810 things should perhaps be in a separate function. */
811 if (!cmd_file (com, val, place))
816 while (t > s && *--t == '/')
822 /* Split VAL by space to a vector of values, and append those values
823 to vector pointed to by the PLACE argument. If VAL is empty, the
824 PLACE vector is cleared instead. */
827 cmd_vector (const char *com, const char *val, void *place)
829 char ***pvec = (char ***)place;
832 *pvec = merge_vecs (*pvec, sepstring (val));
842 cmd_directory_vector (const char *com, const char *val, void *place)
844 char ***pvec = (char ***)place;
848 /* Strip the trailing slashes from directories. */
851 seps = sepstring (val);
852 for (t = seps; t && *t; t++)
854 int len = strlen (*t);
855 /* Skip degenerate case of root directory. */
858 if ((*t)[len - 1] == '/')
859 (*t)[len - 1] = '\0';
862 *pvec = merge_vecs (*pvec, seps);
872 /* Engine for cmd_bytes and cmd_bytes_large: converts a string such as
873 "100k" or "2.5G" to a floating point number. */
876 parse_bytes_helper (const char *val, double *result)
879 const char *end = val + strlen (val);
881 /* Check for "inf". */
882 if (0 == strcmp (val, "inf"))
888 /* Strip trailing whitespace. */
889 while (val < end && ISSPACE (end[-1]))
894 switch (TOLOWER (end[-1]))
897 --end, mult = 1024.0;
900 --end, mult = 1048576.0;
903 --end, mult = 1073741824.0;
906 --end, mult = 1099511627776.0;
909 /* Not a recognized suffix: assume it's a digit. (If not,
910 simple_atof will raise an error.) */
914 /* Skip leading and trailing whitespace. */
915 while (val < end && ISSPACE (*val))
917 while (val < end && ISSPACE (end[-1]))
922 if (!simple_atof (val, end, &number) || number < 0)
925 *result = number * mult;
929 /* Parse VAL as a number and set its value to PLACE (which should
932 By default, the value is assumed to be in bytes. If "K", "M", or
933 "G" are appended, the value is multiplied with 1<<10, 1<<20, or
934 1<<30, respectively. Floating point values are allowed and are
935 cast to integer before use. The idea is to be able to use things
936 like 1.5k instead of "1536".
938 The string "inf" is returned as 0.
940 In case of error, 0 is returned and memory pointed to by PLACE
941 remains unmodified. */
944 cmd_bytes (const char *com, const char *val, void *place)
947 if (!parse_bytes_helper (val, &byte_value))
949 fprintf (stderr, _("%s: %s: Invalid byte value `%s'\n"),
950 exec_name, com, val);
953 *(wgint *)place = (wgint)byte_value;
957 /* Like cmd_bytes, but PLACE is interpreted as a pointer to
958 LARGE_INT. It works by converting the string to double, therefore
959 working with values up to 2^53-1 without loss of precision. This
960 value (8192 TB) is large enough to serve for a while. */
963 cmd_bytes_large (const char *com, const char *val, void *place)
966 if (!parse_bytes_helper (val, &byte_value))
968 fprintf (stderr, _("%s: %s: Invalid byte value `%s'\n"),
969 exec_name, com, val);
972 *(LARGE_INT *)place = (LARGE_INT)byte_value;
976 /* Store the value of VAL to *OUT. The value is a time period, by
977 default expressed in seconds, but also accepting suffixes "m", "h",
978 "d", and "w" for minutes, hours, days, and weeks respectively. */
981 cmd_time (const char *com, const char *val, void *place)
984 const char *end = val + strlen (val);
986 /* Strip trailing whitespace. */
987 while (val < end && ISSPACE (end[-1]))
993 fprintf (stderr, _("%s: %s: Invalid time period `%s'\n"),
994 exec_name, com, val);
998 switch (TOLOWER (end[-1]))
1001 --end, mult = 1; /* seconds */
1004 --end, mult = 60; /* minutes */
1007 --end, mult = 3600; /* hours */
1010 --end, mult = 86400.0; /* days */
1013 --end, mult = 604800.0; /* weeks */
1016 /* Not a recognized suffix: assume it belongs to the number.
1017 (If not, simple_atof will raise an error.) */
1021 /* Skip leading and trailing whitespace. */
1022 while (val < end && ISSPACE (*val))
1024 while (val < end && ISSPACE (end[-1]))
1029 if (!simple_atof (val, end, &number))
1032 *(double *)place = number * mult;
1038 cmd_cert_type (const char *com, const char *val, void *place)
1040 static const struct decode_item choices[] = {
1041 { "pem", keyfile_pem },
1042 { "der", keyfile_asn1 },
1043 { "asn1", keyfile_asn1 },
1045 int ok = decode_string (val, choices, countof (choices), place);
1047 fprintf (stderr, _("%s: %s: Invalid value `%s'.\n"), exec_name, com, val);
1052 /* Specialized helper functions, used by `commands' to handle some
1053 options specially. */
1055 static int check_user_specified_header PARAMS ((const char *));
1058 cmd_spec_dirstruct (const char *com, const char *val, void *place_ignored)
1060 if (!cmd_boolean (com, val, &opt.dirstruct))
1062 /* Since dirstruct behaviour is explicitly changed, no_dirstruct
1063 must be affected inversely. */
1065 opt.no_dirstruct = 0;
1067 opt.no_dirstruct = 1;
1072 cmd_spec_header (const char *com, const char *val, void *place)
1074 if (!check_user_specified_header (val))
1076 fprintf (stderr, _("%s: %s: Invalid header `%s'.\n"),
1077 exec_name, com, val);
1080 return cmd_vector (com, val, place);
1084 cmd_spec_htmlify (const char *com, const char *val, void *place_ignored)
1086 int flag = cmd_boolean (com, val, &opt.htmlify);
1087 if (flag && !opt.htmlify)
1088 opt.remove_listing = 0;
1092 /* Set the "mirror" mode. It means: recursive download, timestamping,
1093 no limit on max. recursion depth, and don't remove listings. */
1096 cmd_spec_mirror (const char *com, const char *val, void *place_ignored)
1100 if (!cmd_boolean (com, val, &mirror))
1105 if (!opt.no_dirstruct)
1107 opt.timestamping = 1;
1108 opt.reclevel = INFINITE_RECURSION;
1109 opt.remove_listing = 0;
1114 /* Validate --prefer-family and set the choice. Allowed values are
1115 "IPv4", "IPv6", and "none". */
1118 cmd_spec_prefer_family (const char *com, const char *val, void *place_ignored)
1120 static const struct decode_item choices[] = {
1121 { "IPv4", prefer_ipv4 },
1122 { "IPv6", prefer_ipv6 },
1123 { "none", prefer_none },
1125 int ok = decode_string (val, choices, countof (choices),
1126 (int *) &opt.prefer_family);
1128 fprintf (stderr, _("%s: %s: Invalid value `%s'.\n"), exec_name, com, val);
1132 /* Set progress.type to VAL, but verify that it's a valid progress
1133 implementation before that. */
1136 cmd_spec_progress (const char *com, const char *val, void *place_ignored)
1138 if (!valid_progress_implementation_p (val))
1140 fprintf (stderr, _("%s: %s: Invalid progress type `%s'.\n"),
1141 exec_name, com, val);
1144 xfree_null (opt.progress_type);
1146 /* Don't call set_progress_implementation here. It will be called
1147 in main() when it becomes clear what the log output is. */
1148 opt.progress_type = xstrdup (val);
1152 /* Set opt.recursive to VAL as with cmd_boolean. If opt.recursive is
1153 set to true, also set opt.dirstruct to 1, unless opt.no_dirstruct
1157 cmd_spec_recursive (const char *com, const char *val, void *place_ignored)
1159 if (!cmd_boolean (com, val, &opt.recursive))
1163 if (opt.recursive && !opt.no_dirstruct)
1170 cmd_spec_restrict_file_names (const char *com, const char *val, void *place_ignored)
1172 int restrict_os = opt.restrict_files_os;
1173 int restrict_ctrl = opt.restrict_files_ctrl;
1175 const char *end = strchr (val, ',');
1177 end = val + strlen (val);
1179 #define VAL_IS(string_literal) BOUNDED_EQUAL (val, end, string_literal)
1181 if (VAL_IS ("unix"))
1182 restrict_os = restrict_unix;
1183 else if (VAL_IS ("windows"))
1184 restrict_os = restrict_windows;
1185 else if (VAL_IS ("nocontrol"))
1191 _("%s: %s: Invalid restriction `%s', use `unix' or `windows'.\n"),
1192 exec_name, com, val);
1200 if (!strcmp (end + 1, "nocontrol"))
1206 opt.restrict_files_os = restrict_os;
1207 opt.restrict_files_ctrl = restrict_ctrl;
1213 cmd_spec_secure_protocol (const char *com, const char *val, void *place)
1215 static const struct decode_item choices[] = {
1216 { "auto", secure_protocol_auto },
1217 { "sslv2", secure_protocol_sslv2 },
1218 { "sslv3", secure_protocol_sslv3 },
1219 { "tlsv1", secure_protocol_tlsv1 },
1221 int ok = decode_string (val, choices, countof (choices), place);
1223 fprintf (stderr, _("%s: %s: Invalid value `%s'.\n"), exec_name, com, val);
1228 /* Set all three timeout values. */
1231 cmd_spec_timeout (const char *com, const char *val, void *place_ignored)
1234 if (!cmd_time (com, val, &value))
1236 opt.read_timeout = value;
1237 opt.connect_timeout = value;
1238 opt.dns_timeout = value;
1243 cmd_spec_useragent (const char *com, const char *val, void *place_ignored)
1245 /* Just check for empty string and newline, so we don't throw total
1246 junk to the server. */
1247 if (!*val || strchr (val, '\n'))
1249 fprintf (stderr, _("%s: %s: Invalid value `%s'.\n"),
1250 exec_name, com, val);
1253 opt.useragent = xstrdup (val);
1257 /* Miscellaneous useful routines. */
1259 /* A very simple atoi clone, more useful than atoi because it works on
1260 delimited strings, and has error reportage. Returns 1 on success,
1261 0 on failure. If successful, stores result to *DEST. */
1264 simple_atoi (const char *beg, const char *end, int *dest)
1268 const char *p = beg;
1270 while (p < end && ISSPACE (*p))
1272 if (p < end && (*p == '-' || *p == '+'))
1274 negative = (*p == '-');
1280 /* Read negative numbers in a separate loop because the most
1281 negative integer cannot be represented as a positive number. */
1284 for (; p < end && ISDIGIT (*p); p++)
1286 int next = (10 * result) + (*p - '0');
1288 return 0; /* overflow */
1292 for (; p < end && ISDIGIT (*p); p++)
1294 int next = (10 * result) - (*p - '0');
1296 return 0; /* underflow */
1307 /* Trivial atof, with error reporting. Handles "<digits>[.<digits>]",
1308 doesn't handle exponential notation. Returns 1 on success, 0 on
1309 failure. In case of success, stores its result to *DEST. */
1312 simple_atof (const char *beg, const char *end, double *dest)
1321 const char *p = beg;
1323 while (p < end && ISSPACE (*p))
1325 if (p < end && (*p == '-' || *p == '+'))
1327 negative = (*p == '-');
1331 for (; p < end; p++)
1337 result = (10 * result) + (ch - '0');
1339 result += (ch - '0') / (divider *= 10);
1361 /* Verify that the user-specified header in S is valid. It must
1362 contain a colon preceded by non-white-space characters and must not
1363 contain newlines. */
1366 check_user_specified_header (const char *s)
1370 for (p = s; *p && *p != ':' && !ISSPACE (*p); p++);
1371 /* The header MUST contain `:' preceded by at least one
1372 non-whitespace character. */
1373 if (*p != ':' || p == s)
1375 /* The header MUST NOT contain newlines. */
1376 if (strchr (s, '\n'))
1381 /* Decode VAL into a number, according to ITEMS. */
1384 decode_string (const char *val, const struct decode_item *items, int itemcount,
1388 for (i = 0; i < itemcount; i++)
1389 if (0 == strcasecmp (val, items[i].name))
1391 *place = items[i].code;
1398 void cleanup_html_url PARAMS ((void));
1399 void http_cleanup PARAMS ((void));
1402 /* Free the memory allocated by global variables. */
1406 /* Free external resources, close files, etc. */
1409 extern FILE *output_stream;
1411 fclose (output_stream);
1412 /* No need to check for error because Wget flushes its output (and
1413 checks for errors) after any data arrives. */
1416 /* We're exiting anyway so there's no real need to call free()
1417 hundreds of times. Skipping the frees will make Wget exit
1420 However, when detecting leaks, it's crucial to free() everything
1421 because then you can find the real leaks, i.e. the allocated
1422 memory which grows with the size of the program. */
1428 cleanup_html_url ();
1433 extern acc_t *netrc_list;
1434 free_netrc (netrc_list);
1436 xfree_null (opt.lfilename);
1437 xfree_null (opt.dir_prefix);
1438 xfree_null (opt.input_filename);
1439 xfree_null (opt.output_document);
1440 free_vec (opt.accepts);
1441 free_vec (opt.rejects);
1442 free_vec (opt.excludes);
1443 free_vec (opt.includes);
1444 free_vec (opt.domains);
1445 free_vec (opt.follow_tags);
1446 free_vec (opt.ignore_tags);
1447 xfree_null (opt.progress_type);
1448 xfree (opt.ftp_acc);
1449 xfree_null (opt.ftp_pass);
1450 xfree_null (opt.ftp_proxy);
1451 xfree_null (opt.https_proxy);
1452 xfree_null (opt.http_proxy);
1453 free_vec (opt.no_proxy);
1454 xfree_null (opt.useragent);
1455 xfree_null (opt.referer);
1456 xfree_null (opt.http_user);
1457 xfree_null (opt.http_passwd);
1458 free_vec (opt.user_headers);
1460 xfree_null (opt.cert_file);
1461 xfree_null (opt.private_key);
1463 xfree_null (opt.bind_address);
1464 xfree_null (opt.cookies_input);
1465 xfree_null (opt.cookies_output);
1466 #endif /* DEBUG_MALLOC */