1 /* Reading/parsing the initialization file.
2 Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
4 This file is part of Wget.
6 This program 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 This program 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 this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
24 #include <sys/types.h>
39 # include <sys/socket.h>
40 # include <netinet/in.h>
41 # include <arpa/inet.h>
60 #define CMD_DECLARE(func) static int func \
61 PARAMS ((const char *, const char *, void *))
63 CMD_DECLARE (cmd_address);
64 CMD_DECLARE (cmd_boolean);
65 CMD_DECLARE (cmd_bytes);
66 CMD_DECLARE (cmd_directory_vector);
67 CMD_DECLARE (cmd_lockable_boolean);
68 CMD_DECLARE (cmd_number);
69 CMD_DECLARE (cmd_number_inf);
70 CMD_DECLARE (cmd_string);
71 CMD_DECLARE (cmd_time);
72 CMD_DECLARE (cmd_vector);
74 CMD_DECLARE (cmd_spec_dirstruct);
75 CMD_DECLARE (cmd_spec_dotstyle);
76 CMD_DECLARE (cmd_spec_header);
77 CMD_DECLARE (cmd_spec_htmlify);
78 CMD_DECLARE (cmd_spec_mirror);
79 CMD_DECLARE (cmd_spec_recursive);
80 CMD_DECLARE (cmd_spec_useragent);
82 /* List of recognized commands, each consisting of name, closure and function.
83 When adding a new command, simply add it to the list, but be sure to keep the
84 list sorted alphabetically, as comind() depends on it. Also, be sure to add
85 any entries that allocate memory (e.g. cmd_string and cmd_vector guys) to the
86 cleanup() function below. */
90 int (*action) PARAMS ((const char *, const char *, void *));
92 { "accept", &opt.accepts, cmd_vector },
93 { "addhostdir", &opt.add_hostdir, cmd_boolean },
94 { "alwaysrest", &opt.always_rest, cmd_boolean }, /* deprecated */
95 { "background", &opt.background, cmd_boolean },
96 { "backupconverted", &opt.backup_converted, cmd_boolean },
97 { "backups", &opt.backups, cmd_number },
98 { "base", &opt.base_href, cmd_string },
99 { "bindaddress", &opt.bind_address, cmd_address },
100 { "cache", &opt.proxy_cache, cmd_boolean },
101 { "continue", &opt.always_rest, cmd_boolean },
102 { "convertlinks", &opt.convert_links, cmd_boolean },
103 { "cutdirs", &opt.cut_dirs, cmd_number },
105 { "debug", &opt.debug, cmd_boolean },
107 { "deleteafter", &opt.delete_after, cmd_boolean },
108 { "dirprefix", &opt.dir_prefix, cmd_string },
109 { "dirstruct", NULL, cmd_spec_dirstruct },
110 { "domains", &opt.domains, cmd_vector },
111 { "dotbytes", &opt.dot_bytes, cmd_bytes },
112 { "dotsinline", &opt.dots_in_line, cmd_number },
113 { "dotspacing", &opt.dot_spacing, cmd_number },
114 { "dotstyle", NULL, cmd_spec_dotstyle },
115 { "excludedirectories", &opt.excludes, cmd_directory_vector },
116 { "excludedomains", &opt.exclude_domains, cmd_vector },
117 { "followftp", &opt.follow_ftp, cmd_boolean },
118 { "followtags", &opt.follow_tags, cmd_vector },
119 { "forcehtml", &opt.force_html, cmd_boolean },
120 { "ftpproxy", &opt.ftp_proxy, cmd_string },
121 { "glob", &opt.ftp_glob, cmd_boolean },
122 { "header", NULL, cmd_spec_header },
123 { "htmlextension", &opt.html_extension, cmd_boolean },
124 { "htmlify", NULL, cmd_spec_htmlify },
125 { "httpkeepalive", &opt.http_keep_alive, cmd_boolean },
126 { "httppasswd", &opt.http_passwd, cmd_string },
127 { "httpproxy", &opt.http_proxy, cmd_string },
128 { "httpuser", &opt.http_user, cmd_string },
129 { "httpsproxy", &opt.https_proxy, cmd_string },
130 { "ignorelength", &opt.ignore_length, cmd_boolean },
131 { "ignoretags", &opt.ignore_tags, cmd_vector },
132 { "includedirectories", &opt.includes, cmd_directory_vector },
133 { "input", &opt.input_filename, cmd_string },
134 { "killlonger", &opt.kill_longer, cmd_boolean },
135 { "logfile", &opt.lfilename, cmd_string },
136 { "login", &opt.ftp_acc, cmd_string },
137 { "mirror", NULL, cmd_spec_mirror },
138 { "netrc", &opt.netrc, cmd_boolean },
139 { "noclobber", &opt.noclobber, cmd_boolean },
140 { "noparent", &opt.no_parent, cmd_boolean },
141 { "noproxy", &opt.no_proxy, cmd_vector },
142 { "numtries", &opt.ntry, cmd_number_inf },/* deprecated*/
143 { "outputdocument", &opt.output_document, cmd_string },
144 { "pagerequisites", &opt.page_requisites, cmd_boolean },
145 { "passiveftp", &opt.ftp_pasv, cmd_lockable_boolean },
146 { "passwd", &opt.ftp_pass, cmd_string },
147 { "proxypasswd", &opt.proxy_passwd, cmd_string },
148 { "proxyuser", &opt.proxy_user, cmd_string },
149 { "quiet", &opt.quiet, cmd_boolean },
150 { "quota", &opt.quota, cmd_bytes },
151 { "reclevel", &opt.reclevel, cmd_number_inf },
152 { "recursive", NULL, cmd_spec_recursive },
153 { "referer", &opt.referer, cmd_string },
154 { "reject", &opt.rejects, cmd_vector },
155 { "relativeonly", &opt.relative_only, cmd_boolean },
156 { "removelisting", &opt.remove_listing, cmd_boolean },
157 { "retrsymlinks", &opt.retr_symlinks, cmd_boolean },
158 { "robots", &opt.use_robots, cmd_boolean },
159 { "saveheaders", &opt.save_headers, cmd_boolean },
160 { "serverresponse", &opt.server_response, cmd_boolean },
161 { "simplehostcheck", &opt.simple_check, cmd_boolean },
162 { "spanhosts", &opt.spanhost, cmd_boolean },
163 { "spider", &opt.spider, cmd_boolean },
165 { "sslcertfile", &opt.sslcertfile, cmd_string },
166 { "sslcertkey", &opt.sslcertkey, cmd_string },
167 #endif /* HAVE_SSL */
168 { "timeout", &opt.timeout, cmd_time },
169 { "timestamping", &opt.timestamping, cmd_boolean },
170 { "tries", &opt.ntry, cmd_number_inf },
171 { "useproxy", &opt.use_proxy, cmd_boolean },
172 { "useragent", NULL, cmd_spec_useragent },
173 { "verbose", &opt.verbose, cmd_boolean },
174 { "wait", &opt.wait, cmd_time },
175 { "waitretry", &opt.waitretry, cmd_time }
178 /* Return index of COM if it is a valid command, or -1 otherwise. COM
179 is looked up in `commands' using binary search algorithm. */
181 comind (const char *com)
183 int min = 0, max = ARRAY_SIZE (commands) - 1;
187 int i = (min + max) / 2;
188 int cmp = strcasecmp (com, commands[i].name);
200 /* Reset the variables to default values. */
206 /* Most of the default values are 0. Just reset everything, and
207 fill in the non-zero values. Note that initializing pointers to
208 NULL this way is technically illegal, but porting Wget to a
209 machine where NULL is not all-zero bit pattern will be the least
210 of the implementors' worries. */
211 memset (&opt, 0, sizeof (opt));
214 opt.dir_prefix = xstrdup (".");
218 opt.ftp_acc = xstrdup ("anonymous");
219 /*opt.ftp_pass = xstrdup (ftp_getaddress ());*/
223 opt.http_keep_alive = 1;
225 tmp = getenv ("no_proxy");
227 opt.no_proxy = sepstring (tmp);
235 opt.remove_listing = 1;
237 opt.dot_bytes = 1024;
238 opt.dot_spacing = 10;
239 opt.dots_in_line = 50;
242 /* Return the user's home directory (strdup-ed), or NULL if none is
247 char *home = getenv ("HOME");
252 /* If HOME is not defined, try getting it from the password
254 struct passwd *pwd = getpwuid (getuid ());
255 if (!pwd || !pwd->pw_dir)
260 /* #### Maybe I should grab home_dir from registry, but the best
261 that I could get from there is user's Start menu. It sucks! */
265 return home ? xstrdup (home) : NULL;
268 /* Return the path to the user's .wgetrc. This is either the value of
269 `WGETRC' environment variable, or `$HOME/.wgetrc'.
271 If the `WGETRC' variable exists but the file does not exist, the
272 function will exit(). */
274 wgetrc_file_name (void)
279 /* Try the environment. */
280 env = getenv ("WGETRC");
283 if (!file_exists_p (env))
285 fprintf (stderr, "%s: %s: %s.\n", exec_name, file, strerror (errno));
288 return xstrdup (env);
292 /* If that failed, try $HOME/.wgetrc. */
296 file = (char *)xmalloc (strlen (home) + 1 + strlen (".wgetrc") + 1);
297 sprintf (file, "%s/.wgetrc", home);
301 /* Under Windows, "home" is (for the purposes of this function) the
302 directory where `wget.exe' resides, and `wget.ini' will be used
303 as file name. SYSTEM_WGETRC should not be defined under WINDOWS.
305 It is not as trivial as I assumed, because on 95 argv[0] is full
306 path, but on NT you get what you typed in command line. --dbudor */
310 file = (char *)xmalloc (strlen (home) + strlen ("wget.ini") + 1);
311 sprintf (file, "%swget.ini", home);
317 if (!file_exists_p (file))
325 /* Initialize variables from a wgetrc file */
327 run_wgetrc (const char *file)
333 fp = fopen (file, "rb");
336 fprintf (stderr, _("%s: Cannot read %s (%s).\n"), exec_name,
337 file, strerror (errno));
340 /* Reset line number. */
342 while ((line = read_whole_line (fp)))
347 /* Parse the line. */
348 status = parse_line (line, &com, &val);
350 /* If everything is OK, set the value. */
353 if (!setval (com, val))
354 fprintf (stderr, _("%s: Error in %s at line %d.\n"), exec_name,
359 else if (status == 0)
360 fprintf (stderr, _("%s: Error in %s at line %d.\n"), exec_name,
367 /* Initialize the defaults and run the system wgetrc and user's own
374 /* Load the hard-coded defaults. */
377 /* If SYSTEM_WGETRC is defined, use it. */
379 if (file_exists_p (SYSTEM_WGETRC))
380 run_wgetrc (SYSTEM_WGETRC);
382 /* Override it with your own, if one exists. */
383 file = wgetrc_file_name ();
386 /* #### We should somehow canonicalize `file' and SYSTEM_WGETRC,
389 if (!strcmp (file, SYSTEM_WGETRC))
391 fprintf (stderr, _("\
392 %s: Warning: Both system and user wgetrc point to `%s'.\n"),
402 /* Parse the line pointed by line, with the syntax:
403 <sp>* command <sp>* = <sp>* value <newline>
404 Uses malloc to allocate space for command and value.
405 If the line is invalid, data is freed and 0 is returned.
412 parse_line (const char *line, char **com, char **val)
414 const char *p = line;
415 const char *orig_comptr, *end;
418 /* Skip whitespace. */
419 while (*p && ISSPACE (*p))
422 /* Don't process empty lines. */
423 if (!*p || *p == '#')
426 for (orig_comptr = p; ISALPHA (*p) || *p == '_' || *p == '-'; p++)
428 /* The next char should be space or '='. */
429 if (!ISSPACE (*p) && (*p != '='))
431 /* Here we cannot use strdupdelim() as we normally would because we
432 want to skip the `-' and `_' characters in the input string. */
433 *com = (char *)xmalloc (p - orig_comptr + 1);
434 for (new_comptr = *com; orig_comptr < p; orig_comptr++)
436 if (*orig_comptr == '_' || *orig_comptr == '-')
438 *new_comptr++ = *orig_comptr;
441 /* If the command is invalid, exit now. */
442 if (comind (*com) == -1)
448 /* Skip spaces before '='. */
449 for (; ISSPACE (*p); p++);
450 /* If '=' not found, bail out. */
456 /* Skip spaces after '='. */
457 for (++p; ISSPACE (*p); p++);
458 /* Get the ending position for VAL by starting with the end of the
459 line and skipping whitespace. */
460 end = line + strlen (line) - 1;
461 while (end > p && ISSPACE (*end))
463 *val = strdupdelim (p, end + 1);
467 /* Set COM to VAL. This is the meat behind processing `.wgetrc'. No
468 fatals -- error signal prints a warning and resets to default
469 value. All error messages are printed to stderr, *not* to
470 opt.lfile, since opt.lfile wasn't even generated yet. */
472 setval (const char *com, const char *val)
481 /* #### Should I just abort()? */
483 fprintf (stderr, _("%s: BUG: unknown command `%s', value `%s'.\n"),
484 exec_name, com, val);
488 return ((*commands[ind].action) (com, val, commands[ind].closure));
491 /* Generic helper functions, for use with `commands'. */
493 static int myatoi PARAMS ((const char *s));
495 /* Store the address (specified as hostname or dotted-quad IP address) from VAL
496 to CLOSURE. COM is ignored, except for error messages. */
498 cmd_address (const char *com, const char *val, void *closure)
500 struct sockaddr_in sin;
502 if (!store_hostaddress ((unsigned char *)&sin.sin_addr, val))
504 fprintf (stderr, _("%s: %s: Cannot convert `%s' to an IP address.\n"),
505 exec_name, com, val);
509 sin.sin_family = AF_INET;
512 memcpy (closure, &sin, sizeof (sin));
517 /* Store the boolean value from VAL to CLOSURE. COM is ignored,
518 except for error messages. */
520 cmd_boolean (const char *com, const char *val, void *closure)
524 if (!strcasecmp (val, "on")
525 || (*val == '1' && !*(val + 1)))
527 else if (!strcasecmp (val, "off")
528 || (*val == '0' && !*(val + 1)))
532 fprintf (stderr, _("%s: %s: Please specify on or off.\n"),
537 *(int *)closure = bool_value;
541 /* Store the lockable_boolean {2, 1, 0, -1} value from VAL to CLOSURE. COM is
542 ignored, except for error messages. Values 2 and -1 indicate that once
543 defined, the value may not be changed by successive wgetrc files or
544 command-line arguments.
546 Values: 2 - Enable a particular option for good ("always")
547 1 - Enable an option ("on")
548 0 - Disable an option ("off")
549 -1 - Disable an option for good ("never") */
551 cmd_lockable_boolean (const char *com, const char *val, void *closure)
553 int lockable_boolean_value;
556 * If a config file said "always" or "never", don't allow command line
557 * arguments to override the config file.
559 if (*(int *)closure == -1 || *(int *)closure == 2)
562 if (!strcasecmp (val, "always")
563 || (*val == '2' && !*(val + 1)))
564 lockable_boolean_value = 2;
565 else if (!strcasecmp (val, "on")
566 || (*val == '1' && !*(val + 1)))
567 lockable_boolean_value = 1;
568 else if (!strcasecmp (val, "off")
569 || (*val == '0' && !*(val + 1)))
570 lockable_boolean_value = 0;
571 else if (!strcasecmp (val, "never")
572 || (*val == '-' && *(val + 1) == '1' && !*(val + 2)))
573 lockable_boolean_value = -1;
576 fprintf (stderr, _("%s: %s: Please specify always, on, off, "
582 *(int *)closure = lockable_boolean_value;
586 /* Set the non-negative integer value from VAL to CLOSURE. With
587 incorrect specification, the number remains unchanged. */
589 cmd_number (const char *com, const char *val, void *closure)
591 int num = myatoi (val);
595 fprintf (stderr, _("%s: %s: Invalid specification `%s'.\n"),
596 exec_name, com, val);
599 *(int *)closure = num;
603 /* Similar to cmd_number(), only accepts `inf' as a synonym for 0. */
605 cmd_number_inf (const char *com, const char *val, void *closure)
607 if (!strcasecmp (val, "inf"))
612 return cmd_number (com, val, closure);
615 /* Copy (strdup) the string at COM to a new location and place a
616 pointer to *CLOSURE. */
618 cmd_string (const char *com, const char *val, void *closure)
620 char **pstring = (char **)closure;
622 FREE_MAYBE (*pstring);
623 *pstring = xstrdup (val);
627 /* Merge the vector (array of strings separated with `,') in COM with
628 the vector (NULL-terminated array of strings) pointed to by
631 cmd_vector (const char *com, const char *val, void *closure)
633 char ***pvec = (char ***)closure;
636 *pvec = merge_vecs (*pvec, sepstring (val));
646 cmd_directory_vector (const char *com, const char *val, void *closure)
648 char ***pvec = (char ***)closure;
652 /* Strip the trailing slashes from directories. */
655 seps = sepstring (val);
656 for (t = seps; t && *t; t++)
658 int len = strlen (*t);
659 /* Skip degenerate case of root directory. */
662 if ((*t)[len - 1] == '/')
663 (*t)[len - 1] = '\0';
666 *pvec = merge_vecs (*pvec, seps);
676 /* Set the value stored in VAL to CLOSURE (which should point to a
677 long int), allowing several postfixes, with the following syntax
681 [0-9]+[kK] -> bytes * 1024
682 [0-9]+[mM] -> bytes * 1024 * 1024
685 Anything else is flagged as incorrect, and CLOSURE is unchanged. */
687 cmd_bytes (const char *com, const char *val, void *closure)
690 long *out = (long *)closure;
695 /* Check for "inf". */
696 if (p[0] == 'i' && p[1] == 'n' && p[2] == 'f' && p[3] == '\0')
701 /* Search for digits and construct result. */
702 for (; *p && ISDIGIT (*p); p++)
703 result = (10 * result) + (*p - '0');
704 /* If no digits were found, or more than one character is following
706 if (p == val || (*p != '\0' && *(p + 1) != '\0'))
708 printf (_("%s: Invalid specification `%s'\n"), com, val);
711 /* Search for a designator. */
712 switch (TOLOWER (*p))
723 result *= (long)1024 * 1024;
727 result *= (long)1024 * 1024 * 1024;
730 printf (_("%s: Invalid specification `%s'\n"), com, val);
737 /* Store the value of VAL to *OUT, allowing suffixes for minutes and
740 cmd_time (const char *com, const char *val, void *closure)
745 /* Search for digits and construct result. */
746 for (; *p && ISDIGIT (*p); p++)
747 result = (10 * result) + (*p - '0');
748 /* If no digits were found, or more than one character is following
750 if (p == val || (*p != '\0' && *(p + 1) != '\0'))
752 printf (_("%s: Invalid specification `%s'\n"), com, val);
755 /* Search for a suffix. */
756 switch (TOLOWER (*p))
770 /* Days (overflow on 16bit machines) */
778 printf (_("%s: Invalid specification `%s'\n"), com, val);
781 *(long *)closure = result;
785 /* Specialized helper functions, used by `commands' to handle some
786 options specially. */
788 static int check_user_specified_header PARAMS ((const char *));
791 cmd_spec_dirstruct (const char *com, const char *val, void *closure)
793 if (!cmd_boolean (com, val, &opt.dirstruct))
795 /* Since dirstruct behaviour is explicitly changed, no_dirstruct
796 must be affected inversely. */
798 opt.no_dirstruct = 0;
800 opt.no_dirstruct = 1;
805 cmd_spec_dotstyle (const char *com, const char *val, void *closure)
807 /* Retrieval styles. */
808 if (!strcasecmp (val, "default"))
810 /* Default style: 1K dots, 10 dots in a cluster, 50 dots in a
812 opt.dot_bytes = 1024;
813 opt.dot_spacing = 10;
814 opt.dots_in_line = 50;
816 else if (!strcasecmp (val, "binary"))
818 /* "Binary" retrieval: 8K dots, 16 dots in a cluster, 48 dots
820 opt.dot_bytes = 8192;
821 opt.dot_spacing = 16;
822 opt.dots_in_line = 48;
824 else if (!strcasecmp (val, "mega"))
826 /* "Mega" retrieval, for retrieving very long files; each dot is
827 64K, 8 dots in a cluster, 6 clusters (3M) in a line. */
828 opt.dot_bytes = 65536L;
830 opt.dots_in_line = 48;
832 else if (!strcasecmp (val, "giga"))
834 /* "Giga" retrieval, for retrieving very very *very* long files;
835 each dot is 1M, 8 dots in a cluster, 4 clusters (32M) in a
837 opt.dot_bytes = (1L << 20);
839 opt.dots_in_line = 32;
841 else if (!strcasecmp (val, "micro"))
843 /* "Micro" retrieval, for retrieving very small files (and/or
844 slow connections); each dot is 128 bytes, 8 dots in a
845 cluster, 6 clusters (6K) in a line. */
848 opt.dots_in_line = 48;
852 fprintf (stderr, _("%s: %s: Invalid specification `%s'.\n"),
853 exec_name, com, val);
860 cmd_spec_header (const char *com, const char *val, void *closure)
864 /* Empty header means reset headers. */
865 FREE_MAYBE (opt.user_header);
866 opt.user_header = NULL;
872 if (!check_user_specified_header (val))
874 fprintf (stderr, _("%s: %s: Invalid specification `%s'.\n"),
875 exec_name, com, val);
878 i = opt.user_header ? strlen (opt.user_header) : 0;
879 opt.user_header = (char *)xrealloc (opt.user_header, i + strlen (val)
881 strcpy (opt.user_header + i, val);
883 opt.user_header[i++] = '\r';
884 opt.user_header[i++] = '\n';
885 opt.user_header[i] = '\0';
891 cmd_spec_htmlify (const char *com, const char *val, void *closure)
893 int flag = cmd_boolean (com, val, &opt.htmlify);
894 if (flag && !opt.htmlify)
895 opt.remove_listing = 0;
900 cmd_spec_mirror (const char *com, const char *val, void *closure)
904 if (!cmd_boolean (com, val, &mirror))
909 if (!opt.no_dirstruct)
911 opt.timestamping = 1;
912 opt.reclevel = INFINITE_RECURSION;
913 opt.remove_listing = 0;
919 cmd_spec_recursive (const char *com, const char *val, void *closure)
921 if (!cmd_boolean (com, val, &opt.recursive))
925 if (opt.recursive && !opt.no_dirstruct)
932 cmd_spec_useragent (const char *com, const char *val, void *closure)
934 /* Just check for empty string and newline, so we don't throw total
935 junk to the server. */
936 if (!*val || strchr (val, '\n'))
938 fprintf (stderr, _("%s: %s: Invalid specification `%s'.\n"),
939 exec_name, com, val);
942 opt.useragent = xstrdup (val);
946 /* Miscellaneous useful routines. */
948 /* Return the integer value of a positive integer written in S, or -1
949 if an error was encountered. */
951 myatoi (const char *s)
954 const char *orig = s;
956 for (res = 0; *s && ISDIGIT (*s); s++)
957 res = 10 * res + (*s - '0');
964 #define ISODIGIT(x) ((x) >= '0' && (x) <= '7')
967 check_user_specified_header (const char *s)
971 for (p = s; *p && *p != ':' && !ISSPACE (*p); p++);
972 /* The header MUST contain `:' preceded by at least one
973 non-whitespace character. */
974 if (*p != ':' || p == s)
976 /* The header MUST NOT contain newlines. */
977 if (strchr (s, '\n'))
982 void cleanup_html_url PARAMS ((void));
983 void downloaded_files_free PARAMS ((void));
986 /* Free the memory allocated by global variables. */
990 extern acc_t *netrc_list;
992 recursive_cleanup ();
994 free_netrc (netrc_list);
998 downloaded_files_free ();
999 FREE_MAYBE (opt.lfilename);
1000 xfree (opt.dir_prefix);
1001 FREE_MAYBE (opt.input_filename);
1002 FREE_MAYBE (opt.output_document);
1003 free_vec (opt.accepts);
1004 free_vec (opt.rejects);
1005 free_vec (opt.excludes);
1006 free_vec (opt.includes);
1007 free_vec (opt.domains);
1008 free_vec (opt.follow_tags);
1009 free_vec (opt.ignore_tags);
1010 xfree (opt.ftp_acc);
1011 FREE_MAYBE (opt.ftp_pass);
1012 FREE_MAYBE (opt.ftp_proxy);
1013 FREE_MAYBE (opt.https_proxy);
1014 FREE_MAYBE (opt.http_proxy);
1015 free_vec (opt.no_proxy);
1016 FREE_MAYBE (opt.useragent);
1017 FREE_MAYBE (opt.referer);
1018 FREE_MAYBE (opt.http_user);
1019 FREE_MAYBE (opt.http_passwd);
1020 FREE_MAYBE (opt.user_header);
1022 FREE_MAYBE (opt.sslcertkey);
1023 FREE_MAYBE (opt.sslcertfile);
1024 #endif /* HAVE_SSL */