1 /* Reading/parsing the initialization file.
2 Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001
3 Free Software Foundation, Inc.
5 This file is part of GNU Wget.
7 GNU Wget is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GNU Wget is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Wget; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
24 #include <sys/types.h>
39 # include <sys/socket.h>
40 # include <netinet/in.h>
42 # include <arpa/inet.h>
56 #include "cookies.h" /* for cookies_cleanup */
63 /* We want tilde expansion enabled only when reading `.wgetrc' lines;
64 otherwise, it will be performed by the shell. This variable will
65 be set by the wgetrc-reading function. */
67 static int enable_tilde_expansion;
70 #define CMD_DECLARE(func) static int func \
71 PARAMS ((const char *, const char *, void *))
73 CMD_DECLARE (cmd_boolean);
74 CMD_DECLARE (cmd_bytes);
75 CMD_DECLARE (cmd_directory_vector);
76 CMD_DECLARE (cmd_lockable_boolean);
77 CMD_DECLARE (cmd_number);
78 CMD_DECLARE (cmd_number_inf);
79 CMD_DECLARE (cmd_string);
80 CMD_DECLARE (cmd_file);
81 CMD_DECLARE (cmd_directory);
82 CMD_DECLARE (cmd_time);
83 CMD_DECLARE (cmd_vector);
85 CMD_DECLARE (cmd_spec_dirstruct);
86 CMD_DECLARE (cmd_spec_header);
87 CMD_DECLARE (cmd_spec_htmlify);
88 CMD_DECLARE (cmd_spec_mirror);
89 CMD_DECLARE (cmd_spec_progress);
90 CMD_DECLARE (cmd_spec_recursive);
91 CMD_DECLARE (cmd_spec_useragent);
93 /* List of recognized commands, each consisting of name, closure and function.
94 When adding a new command, simply add it to the list, but be sure to keep the
95 list sorted alphabetically, as comind() depends on it. Also, be sure to add
96 any entries that allocate memory (e.g. cmd_string and cmd_vector guys) to the
97 cleanup() function below. */
101 int (*action) PARAMS ((const char *, const char *, void *));
103 { "accept", &opt.accepts, cmd_vector },
104 { "addhostdir", &opt.add_hostdir, cmd_boolean },
105 { "alwaysrest", &opt.always_rest, cmd_boolean }, /* deprecated */
106 { "background", &opt.background, cmd_boolean },
107 { "backupconverted", &opt.backup_converted, cmd_boolean },
108 { "backups", &opt.backups, cmd_number },
109 { "base", &opt.base_href, cmd_string },
110 { "bindaddress", &opt.bind_address, cmd_string },
111 { "cache", &opt.allow_cache, cmd_boolean },
112 { "continue", &opt.always_rest, cmd_boolean },
113 { "convertlinks", &opt.convert_links, cmd_boolean },
114 { "cookies", &opt.cookies, cmd_boolean },
115 { "cutdirs", &opt.cut_dirs, cmd_number },
117 { "debug", &opt.debug, cmd_boolean },
119 { "deleteafter", &opt.delete_after, cmd_boolean },
120 { "dirprefix", &opt.dir_prefix, cmd_directory },
121 { "dirstruct", NULL, cmd_spec_dirstruct },
122 { "domains", &opt.domains, cmd_vector },
123 { "dotbytes", &opt.dot_bytes, cmd_bytes },
124 { "dotsinline", &opt.dots_in_line, cmd_number },
125 { "dotspacing", &opt.dot_spacing, cmd_number },
126 { "dotstyle", &opt.dot_style, cmd_string },
128 { "egdfile", &opt.sslegdsock, cmd_file },
130 { "excludedirectories", &opt.excludes, cmd_directory_vector },
131 { "excludedomains", &opt.exclude_domains, cmd_vector },
132 { "followftp", &opt.follow_ftp, cmd_boolean },
133 { "followtags", &opt.follow_tags, cmd_vector },
134 { "forcehtml", &opt.force_html, cmd_boolean },
135 { "ftpproxy", &opt.ftp_proxy, cmd_string },
136 { "glob", &opt.ftp_glob, cmd_boolean },
137 { "header", NULL, cmd_spec_header },
138 { "htmlextension", &opt.html_extension, cmd_boolean },
139 { "htmlify", NULL, cmd_spec_htmlify },
140 { "httpkeepalive", &opt.http_keep_alive, cmd_boolean },
141 { "httppasswd", &opt.http_passwd, cmd_string },
142 { "httpproxy", &opt.http_proxy, cmd_string },
143 { "httpsproxy", &opt.https_proxy, cmd_string },
144 { "httpuser", &opt.http_user, cmd_string },
145 { "ignorelength", &opt.ignore_length, cmd_boolean },
146 { "ignoretags", &opt.ignore_tags, cmd_vector },
147 { "includedirectories", &opt.includes, cmd_directory_vector },
148 { "input", &opt.input_filename, cmd_file },
149 { "killlonger", &opt.kill_longer, cmd_boolean },
150 { "limitrate", &opt.limit_rate, cmd_bytes },
151 { "loadcookies", &opt.cookies_input, cmd_file },
152 { "logfile", &opt.lfilename, cmd_file },
153 { "login", &opt.ftp_acc, cmd_string },
154 { "mirror", NULL, cmd_spec_mirror },
155 { "netrc", &opt.netrc, cmd_boolean },
156 { "noclobber", &opt.noclobber, cmd_boolean },
157 { "noparent", &opt.no_parent, cmd_boolean },
158 { "noproxy", &opt.no_proxy, cmd_vector },
159 { "numtries", &opt.ntry, cmd_number_inf },/* deprecated*/
160 { "outputdocument", &opt.output_document, cmd_file },
161 { "pagerequisites", &opt.page_requisites, cmd_boolean },
162 { "passiveftp", &opt.ftp_pasv, cmd_lockable_boolean },
163 { "passwd", &opt.ftp_pass, cmd_string },
164 { "postdata", &opt.post_data, cmd_string },
165 { "postfile", &opt.post_file_name, cmd_file },
166 { "progress", &opt.progress_type, cmd_spec_progress },
167 { "proxypasswd", &opt.proxy_passwd, cmd_string },
168 { "proxyuser", &opt.proxy_user, cmd_string },
169 { "quiet", &opt.quiet, cmd_boolean },
170 { "quota", &opt.quota, cmd_bytes },
171 { "randomwait", &opt.random_wait, cmd_boolean },
172 { "reclevel", &opt.reclevel, cmd_number_inf },
173 { "recursive", NULL, cmd_spec_recursive },
174 { "referer", &opt.referer, cmd_string },
175 { "reject", &opt.rejects, cmd_vector },
176 { "relativeonly", &opt.relative_only, cmd_boolean },
177 { "removelisting", &opt.remove_listing, cmd_boolean },
178 { "retrsymlinks", &opt.retr_symlinks, cmd_boolean },
179 { "robots", &opt.use_robots, cmd_boolean },
180 { "savecookies", &opt.cookies_output, cmd_file },
181 { "saveheaders", &opt.save_headers, cmd_boolean },
182 { "serverresponse", &opt.server_response, cmd_boolean },
183 { "spanhosts", &opt.spanhost, cmd_boolean },
184 { "spider", &opt.spider, cmd_boolean },
186 { "sslcertfile", &opt.sslcertfile, cmd_file },
187 { "sslcertkey", &opt.sslcertkey, cmd_file },
188 #endif /* HAVE_SSL */
189 { "timeout", &opt.timeout, cmd_time },
190 { "timestamping", &opt.timestamping, cmd_boolean },
191 { "tries", &opt.ntry, cmd_number_inf },
192 { "useproxy", &opt.use_proxy, cmd_boolean },
193 { "useragent", NULL, cmd_spec_useragent },
194 { "verbose", &opt.verbose, cmd_boolean },
195 { "wait", &opt.wait, cmd_time },
196 { "waitretry", &opt.waitretry, cmd_time }
199 /* Look up COM in the commands[] array and return its index. If COM
200 is not found, -1 is returned. This function uses binary search. */
203 comind (const char *com)
205 int lo = 0, hi = ARRAY_SIZE (commands) - 1;
209 int mid = (lo + hi) >> 1;
210 int cmp = strcasecmp (com, commands[mid].name);
221 /* Reset the variables to default values. */
227 /* Most of the default values are 0. Just reset everything, and
228 fill in the non-zero values. Note that initializing pointers to
229 NULL this way is technically illegal, but porting Wget to a
230 machine where NULL is not all-zero bit pattern will be the least
231 of the implementors' worries. */
232 memset (&opt, 0, sizeof (opt));
237 opt.dir_prefix = xstrdup (".");
241 opt.ftp_acc = xstrdup ("anonymous");
242 opt.ftp_pass = xstrdup ("-wget@");
246 opt.http_keep_alive = 1;
248 tmp = getenv ("no_proxy");
250 opt.no_proxy = sepstring (tmp);
258 opt.remove_listing = 1;
260 opt.dot_bytes = 1024;
261 opt.dot_spacing = 10;
262 opt.dots_in_line = 50;
265 /* Return the user's home directory (strdup-ed), or NULL if none is
270 char *home = getenv ("HOME");
275 /* If HOME is not defined, try getting it from the password
277 struct passwd *pwd = getpwuid (getuid ());
278 if (!pwd || !pwd->pw_dir)
283 /* #### Maybe I should grab home_dir from registry, but the best
284 that I could get from there is user's Start menu. It sucks! */
288 return home ? xstrdup (home) : NULL;
291 /* Return the path to the user's .wgetrc. This is either the value of
292 `WGETRC' environment variable, or `$HOME/.wgetrc'.
294 If the `WGETRC' variable exists but the file does not exist, the
295 function will exit(). */
297 wgetrc_file_name (void)
302 /* Try the environment. */
303 env = getenv ("WGETRC");
306 if (!file_exists_p (env))
308 fprintf (stderr, "%s: %s: %s.\n", exec_name, env, strerror (errno));
311 return xstrdup (env);
315 /* If that failed, try $HOME/.wgetrc. */
319 file = (char *)xmalloc (strlen (home) + 1 + strlen (".wgetrc") + 1);
320 sprintf (file, "%s/.wgetrc", home);
324 /* Under Windows, "home" is (for the purposes of this function) the
325 directory where `wget.exe' resides, and `wget.ini' will be used
326 as file name. SYSTEM_WGETRC should not be defined under WINDOWS.
328 It is not as trivial as I assumed, because on 95 argv[0] is full
329 path, but on NT you get what you typed in command line. --dbudor */
333 file = (char *)xmalloc (strlen (home) + strlen ("wget.ini") + 1);
334 sprintf (file, "%swget.ini", home);
340 if (!file_exists_p (file))
348 /* Initialize variables from a wgetrc file */
350 run_wgetrc (const char *file)
356 fp = fopen (file, "rb");
359 fprintf (stderr, _("%s: Cannot read %s (%s).\n"), exec_name,
360 file, strerror (errno));
363 enable_tilde_expansion = 1;
365 while ((line = read_whole_line (fp)))
370 /* Parse the line. */
371 status = parse_line (line, &com, &val);
373 /* If everything is OK, set the value. */
376 if (!setval (com, val))
377 fprintf (stderr, _("%s: Error in %s at line %d.\n"), exec_name,
382 else if (status == 0)
383 fprintf (stderr, _("%s: Error in %s at line %d.\n"), exec_name,
387 enable_tilde_expansion = 0;
391 /* Initialize the defaults and run the system wgetrc and user's own
398 /* Load the hard-coded defaults. */
401 /* If SYSTEM_WGETRC is defined, use it. */
403 if (file_exists_p (SYSTEM_WGETRC))
404 run_wgetrc (SYSTEM_WGETRC);
406 /* Override it with your own, if one exists. */
407 file = wgetrc_file_name ();
410 /* #### We should somehow canonicalize `file' and SYSTEM_WGETRC,
413 if (!strcmp (file, SYSTEM_WGETRC))
415 fprintf (stderr, _("\
416 %s: Warning: Both system and user wgetrc point to `%s'.\n"),
426 /* Parse the line pointed by line, with the syntax:
427 <sp>* command <sp>* = <sp>* value <newline>
428 Uses malloc to allocate space for command and value.
429 If the line is invalid, data is freed and 0 is returned.
436 parse_line (const char *line, char **com, char **val)
438 const char *p = line;
439 const char *orig_comptr, *end;
442 /* Skip whitespace. */
443 while (*p && ISSPACE (*p))
446 /* Don't process empty lines. */
447 if (!*p || *p == '#')
450 for (orig_comptr = p; ISALPHA (*p) || *p == '_' || *p == '-'; p++)
452 /* The next char should be space or '='. */
453 if (!ISSPACE (*p) && (*p != '='))
455 /* Here we cannot use strdupdelim() as we normally would because we
456 want to skip the `-' and `_' characters in the input string. */
457 *com = (char *)xmalloc (p - orig_comptr + 1);
458 for (new_comptr = *com; orig_comptr < p; orig_comptr++)
460 if (*orig_comptr == '_' || *orig_comptr == '-')
462 *new_comptr++ = *orig_comptr;
465 /* If the command is invalid, exit now. */
466 if (comind (*com) == -1)
472 /* Skip spaces before '='. */
473 for (; ISSPACE (*p); p++);
474 /* If '=' not found, bail out. */
480 /* Skip spaces after '='. */
481 for (++p; ISSPACE (*p); p++);
482 /* Get the ending position for VAL by starting with the end of the
483 line and skipping whitespace. */
484 end = line + strlen (line) - 1;
485 while (end > p && ISSPACE (*end))
487 *val = strdupdelim (p, end + 1);
491 /* Set COM to VAL. This is the meat behind processing `.wgetrc'. No
492 fatals -- error signal prints a warning and resets to default
493 value. All error messages are printed to stderr, *not* to
494 opt.lfile, since opt.lfile wasn't even generated yet. */
496 setval (const char *com, const char *val)
505 /* #### Should I just abort()? */
507 fprintf (stderr, _("%s: BUG: unknown command `%s', value `%s'.\n"),
508 exec_name, com, val);
512 return ((*commands[ind].action) (com, val, commands[ind].closure));
515 /* Generic helper functions, for use with `commands'. */
517 static int myatoi PARAMS ((const char *s));
519 /* Store the boolean value from VAL to CLOSURE. COM is ignored,
520 except for error messages. */
522 cmd_boolean (const char *com, const char *val, void *closure)
526 if (!strcasecmp (val, "on")
527 || (*val == '1' && !*(val + 1)))
529 else if (!strcasecmp (val, "off")
530 || (*val == '0' && !*(val + 1)))
534 fprintf (stderr, _("%s: %s: Please specify on or off.\n"),
539 *(int *)closure = bool_value;
543 /* Store the lockable_boolean {2, 1, 0, -1} value from VAL to CLOSURE. COM is
544 ignored, except for error messages. Values 2 and -1 indicate that once
545 defined, the value may not be changed by successive wgetrc files or
546 command-line arguments.
548 Values: 2 - Enable a particular option for good ("always")
549 1 - Enable an option ("on")
550 0 - Disable an option ("off")
551 -1 - Disable an option for good ("never") */
553 cmd_lockable_boolean (const char *com, const char *val, void *closure)
555 int lockable_boolean_value;
558 * If a config file said "always" or "never", don't allow command line
559 * arguments to override the config file.
561 if (*(int *)closure == -1 || *(int *)closure == 2)
564 if (!strcasecmp (val, "always")
565 || (*val == '2' && !*(val + 1)))
566 lockable_boolean_value = 2;
567 else if (!strcasecmp (val, "on")
568 || (*val == '1' && !*(val + 1)))
569 lockable_boolean_value = 1;
570 else if (!strcasecmp (val, "off")
571 || (*val == '0' && !*(val + 1)))
572 lockable_boolean_value = 0;
573 else if (!strcasecmp (val, "never")
574 || (*val == '-' && *(val + 1) == '1' && !*(val + 2)))
575 lockable_boolean_value = -1;
578 fprintf (stderr, _("%s: %s: Please specify always, on, off, "
584 *(int *)closure = lockable_boolean_value;
588 /* Set the non-negative integer value from VAL to CLOSURE. With
589 incorrect specification, the number remains unchanged. */
591 cmd_number (const char *com, const char *val, void *closure)
593 int num = myatoi (val);
597 fprintf (stderr, _("%s: %s: Invalid specification `%s'.\n"),
598 exec_name, com, val);
601 *(int *)closure = num;
605 /* Similar to cmd_number(), only accepts `inf' as a synonym for 0. */
607 cmd_number_inf (const char *com, const char *val, void *closure)
609 if (!strcasecmp (val, "inf"))
614 return cmd_number (com, val, closure);
617 /* Copy (strdup) the string at COM to a new location and place a
618 pointer to *CLOSURE. */
620 cmd_string (const char *com, const char *val, void *closure)
622 char **pstring = (char **)closure;
624 FREE_MAYBE (*pstring);
625 *pstring = xstrdup (val);
629 /* Like the above, but handles tilde-expansion when reading a user's
630 `.wgetrc'. In that case, and if VAL begins with `~', the tilde
631 gets expanded to the user's home directory. */
633 cmd_file (const char *com, const char *val, void *closure)
635 char **pstring = (char **)closure;
637 FREE_MAYBE (*pstring);
639 /* #### If VAL is empty, perhaps should set *CLOSURE to NULL. */
641 if (!enable_tilde_expansion || !(*val == '~' && (*(val + 1) == '/'
643 || *(val + 1) == '\\'
648 *pstring = xstrdup (val);
654 char *home = home_dir ();
658 homelen = strlen (home);
659 while (homelen && (home[homelen - 1] == '/'
661 || home[homelen - 1] == '\\'
664 home[--homelen] = '\0';
666 /* Skip the leading "~/". */
668 for (++val; *val == '/' || *val == '\\'; val++)
671 for (++val; *val == '/'; val++)
675 result = xmalloc (homelen + 1 + strlen (val));
676 memcpy (result, home, homelen);
677 result[homelen] = '/';
678 strcpy (result + homelen + 1, val);
683 /* Convert "\" to "/". */
686 for (s = *pstring; *s; s++)
694 /* Like cmd_file, but strips trailing '/' characters. */
696 cmd_directory (const char *com, const char *val, void *closure)
700 /* Call cmd_file() for tilde expansion and separator
701 canonicalization (backslash -> slash under Windows). These
702 things should perhaps be in a separate function. */
703 if (!cmd_file (com, val, closure))
706 s = *(char **)closure;
708 while (t > s && *--t == '/')
714 /* Merge the vector (array of strings separated with `,') in COM with
715 the vector (NULL-terminated array of strings) pointed to by
718 cmd_vector (const char *com, const char *val, void *closure)
720 char ***pvec = (char ***)closure;
723 *pvec = merge_vecs (*pvec, sepstring (val));
733 cmd_directory_vector (const char *com, const char *val, void *closure)
735 char ***pvec = (char ***)closure;
739 /* Strip the trailing slashes from directories. */
742 seps = sepstring (val);
743 for (t = seps; t && *t; t++)
745 int len = strlen (*t);
746 /* Skip degenerate case of root directory. */
749 if ((*t)[len - 1] == '/')
750 (*t)[len - 1] = '\0';
753 *pvec = merge_vecs (*pvec, seps);
763 /* Set the value stored in VAL to CLOSURE (which should point to a
764 long int), allowing several postfixes, with the following syntax
768 [0-9]+[kK] -> bytes * 1024
769 [0-9]+[mM] -> bytes * 1024 * 1024
772 Anything else is flagged as incorrect, and CLOSURE is unchanged. */
774 cmd_bytes (const char *com, const char *val, void *closure)
777 long *out = (long *)closure;
782 /* Check for "inf". */
783 if (p[0] == 'i' && p[1] == 'n' && p[2] == 'f' && p[3] == '\0')
788 /* Search for digits and construct result. */
789 for (; *p && ISDIGIT (*p); p++)
790 result = (10 * result) + (*p - '0');
791 /* If no digits were found, or more than one character is following
793 if (p == val || (*p != '\0' && *(p + 1) != '\0'))
795 printf (_("%s: Invalid specification `%s'\n"), com, val);
798 /* Search for a designator. */
799 switch (TOLOWER (*p))
810 result *= (long)1024 * 1024;
814 result *= (long)1024 * 1024 * 1024;
817 printf (_("%s: Invalid specification `%s'\n"), com, val);
824 /* Store the value of VAL to *OUT, allowing suffixes for minutes and
827 cmd_time (const char *com, const char *val, void *closure)
832 /* Search for digits and construct result. */
833 for (; *p && ISDIGIT (*p); p++)
834 result = (10 * result) + (*p - '0');
835 /* If no digits were found, or more than one character is following
837 if (p == val || (*p != '\0' && *(p + 1) != '\0'))
839 printf (_("%s: Invalid specification `%s'\n"), com, val);
842 /* Search for a suffix. */
843 switch (TOLOWER (*p))
857 /* Days (overflow on 16bit machines) */
865 printf (_("%s: Invalid specification `%s'\n"), com, val);
868 *(long *)closure = result;
872 /* Specialized helper functions, used by `commands' to handle some
873 options specially. */
875 static int check_user_specified_header PARAMS ((const char *));
878 cmd_spec_dirstruct (const char *com, const char *val, void *closure)
880 if (!cmd_boolean (com, val, &opt.dirstruct))
882 /* Since dirstruct behaviour is explicitly changed, no_dirstruct
883 must be affected inversely. */
885 opt.no_dirstruct = 0;
887 opt.no_dirstruct = 1;
892 cmd_spec_header (const char *com, const char *val, void *closure)
896 /* Empty header means reset headers. */
897 FREE_MAYBE (opt.user_header);
898 opt.user_header = NULL;
904 if (!check_user_specified_header (val))
906 fprintf (stderr, _("%s: %s: Invalid specification `%s'.\n"),
907 exec_name, com, val);
910 i = opt.user_header ? strlen (opt.user_header) : 0;
911 opt.user_header = (char *)xrealloc (opt.user_header, i + strlen (val)
913 strcpy (opt.user_header + i, val);
915 opt.user_header[i++] = '\r';
916 opt.user_header[i++] = '\n';
917 opt.user_header[i] = '\0';
923 cmd_spec_htmlify (const char *com, const char *val, void *closure)
925 int flag = cmd_boolean (com, val, &opt.htmlify);
926 if (flag && !opt.htmlify)
927 opt.remove_listing = 0;
932 cmd_spec_mirror (const char *com, const char *val, void *closure)
936 if (!cmd_boolean (com, val, &mirror))
941 if (!opt.no_dirstruct)
943 opt.timestamping = 1;
944 opt.reclevel = INFINITE_RECURSION;
945 opt.remove_listing = 0;
951 cmd_spec_progress (const char *com, const char *val, void *closure)
953 if (!valid_progress_implementation_p (val))
955 fprintf (stderr, _("%s: %s: Invalid progress type `%s'.\n"),
956 exec_name, com, val);
959 FREE_MAYBE (opt.progress_type);
961 /* Don't call set_progress_implementation here. It will be called
962 in main() when it becomes clear what the log output is. */
963 opt.progress_type = xstrdup (val);
968 cmd_spec_recursive (const char *com, const char *val, void *closure)
970 if (!cmd_boolean (com, val, &opt.recursive))
974 if (opt.recursive && !opt.no_dirstruct)
981 cmd_spec_useragent (const char *com, const char *val, void *closure)
983 /* Just check for empty string and newline, so we don't throw total
984 junk to the server. */
985 if (!*val || strchr (val, '\n'))
987 fprintf (stderr, _("%s: %s: Invalid specification `%s'.\n"),
988 exec_name, com, val);
991 opt.useragent = xstrdup (val);
995 /* Miscellaneous useful routines. */
997 /* Return the integer value of a positive integer written in S, or -1
998 if an error was encountered. */
1000 myatoi (const char *s)
1003 const char *orig = s;
1005 for (res = 0; *s && ISDIGIT (*s); s++)
1006 res = 10 * res + (*s - '0');
1007 if (*s || orig == s)
1013 #define ISODIGIT(x) ((x) >= '0' && (x) <= '7')
1016 check_user_specified_header (const char *s)
1020 for (p = s; *p && *p != ':' && !ISSPACE (*p); p++);
1021 /* The header MUST contain `:' preceded by at least one
1022 non-whitespace character. */
1023 if (*p != ':' || p == s)
1025 /* The header MUST NOT contain newlines. */
1026 if (strchr (s, '\n'))
1031 void cleanup_html_url PARAMS ((void));
1032 void res_cleanup PARAMS ((void));
1033 void downloaded_files_free PARAMS ((void));
1034 void http_cleanup PARAMS ((void));
1037 /* Free the memory allocated by global variables. */
1041 /* Free external resources, close files, etc. */
1046 /* We're exiting anyway so there's no real need to call free()
1047 hundreds of times. Skipping the frees will make Wget exit
1050 However, when detecting leaks, it's crucial to free() everything
1051 because then you can find the real leaks, i.e. the allocated
1052 memory which grows with the size of the program. */
1055 recursive_cleanup ();
1058 cleanup_html_url ();
1059 downloaded_files_free ();
1064 extern acc_t *netrc_list;
1065 free_netrc (netrc_list);
1067 FREE_MAYBE (opt.lfilename);
1068 xfree (opt.dir_prefix);
1069 FREE_MAYBE (opt.input_filename);
1070 FREE_MAYBE (opt.output_document);
1071 free_vec (opt.accepts);
1072 free_vec (opt.rejects);
1073 free_vec (opt.excludes);
1074 free_vec (opt.includes);
1075 free_vec (opt.domains);
1076 free_vec (opt.follow_tags);
1077 free_vec (opt.ignore_tags);
1078 FREE_MAYBE (opt.progress_type);
1079 xfree (opt.ftp_acc);
1080 FREE_MAYBE (opt.ftp_pass);
1081 FREE_MAYBE (opt.ftp_proxy);
1082 FREE_MAYBE (opt.https_proxy);
1083 FREE_MAYBE (opt.http_proxy);
1084 free_vec (opt.no_proxy);
1085 FREE_MAYBE (opt.useragent);
1086 FREE_MAYBE (opt.referer);
1087 FREE_MAYBE (opt.http_user);
1088 FREE_MAYBE (opt.http_passwd);
1089 FREE_MAYBE (opt.user_header);
1091 FREE_MAYBE (opt.sslcertkey);
1092 FREE_MAYBE (opt.sslcertfile);
1093 #endif /* HAVE_SSL */
1094 FREE_MAYBE (opt.bind_address);
1095 FREE_MAYBE (opt.cookies_input);
1096 FREE_MAYBE (opt.cookies_output);