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 { "ignorelength", &opt.ignore_length, cmd_boolean },
130 { "ignoretags", &opt.ignore_tags, cmd_vector },
131 { "includedirectories", &opt.includes, cmd_directory_vector },
132 { "input", &opt.input_filename, cmd_string },
133 { "killlonger", &opt.kill_longer, cmd_boolean },
134 { "logfile", &opt.lfilename, cmd_string },
135 { "login", &opt.ftp_acc, cmd_string },
136 { "mirror", NULL, cmd_spec_mirror },
137 { "netrc", &opt.netrc, cmd_boolean },
138 { "noclobber", &opt.noclobber, cmd_boolean },
139 { "noparent", &opt.no_parent, cmd_boolean },
140 { "noproxy", &opt.no_proxy, cmd_vector },
141 { "numtries", &opt.ntry, cmd_number_inf },/* deprecated*/
142 { "outputdocument", &opt.output_document, cmd_string },
143 { "pagerequisites", &opt.page_requisites, cmd_boolean },
144 { "passiveftp", &opt.ftp_pasv, cmd_lockable_boolean },
145 { "passwd", &opt.ftp_pass, cmd_string },
146 { "proxypasswd", &opt.proxy_passwd, cmd_string },
147 { "proxyuser", &opt.proxy_user, cmd_string },
148 { "quiet", &opt.quiet, cmd_boolean },
149 { "quota", &opt.quota, cmd_bytes },
150 { "reclevel", &opt.reclevel, cmd_number_inf },
151 { "recursive", NULL, cmd_spec_recursive },
152 { "referer", &opt.referer, cmd_string },
153 { "reject", &opt.rejects, cmd_vector },
154 { "relativeonly", &opt.relative_only, cmd_boolean },
155 { "removelisting", &opt.remove_listing, cmd_boolean },
156 { "retrsymlinks", &opt.retr_symlinks, cmd_boolean },
157 { "robots", &opt.use_robots, cmd_boolean },
158 { "saveheaders", &opt.save_headers, cmd_boolean },
159 { "serverresponse", &opt.server_response, cmd_boolean },
160 { "simplehostcheck", &opt.simple_check, cmd_boolean },
161 { "spanhosts", &opt.spanhost, cmd_boolean },
162 { "spider", &opt.spider, cmd_boolean },
163 { "timeout", &opt.timeout, cmd_time },
164 { "timestamping", &opt.timestamping, cmd_boolean },
165 { "tries", &opt.ntry, cmd_number_inf },
166 { "useproxy", &opt.use_proxy, cmd_boolean },
167 { "useragent", NULL, cmd_spec_useragent },
168 { "verbose", &opt.verbose, cmd_boolean },
169 { "wait", &opt.wait, cmd_time },
170 { "waitretry", &opt.waitretry, cmd_time }
173 /* Return index of COM if it is a valid command, or -1 otherwise. COM
174 is looked up in `commands' using binary search algorithm. */
176 comind (const char *com)
178 int min = 0, max = ARRAY_SIZE (commands) - 1;
182 int i = (min + max) / 2;
183 int cmp = strcasecmp (com, commands[i].name);
195 /* Reset the variables to default values. */
201 /* Most of the default values are 0. Just reset everything, and
202 fill in the non-zero values. Note that initializing pointers to
203 NULL this way is technically illegal, but porting Wget to a
204 machine where NULL is not all-zero bit pattern will be the least
205 of the implementors' worries. */
206 memset (&opt, 0, sizeof (opt));
209 opt.dir_prefix = xstrdup (".");
213 opt.ftp_acc = xstrdup ("anonymous");
214 /*opt.ftp_pass = xstrdup (ftp_getaddress ());*/
218 opt.http_keep_alive = 1;
220 tmp = getenv ("no_proxy");
222 opt.no_proxy = sepstring (tmp);
230 opt.remove_listing = 1;
232 opt.dot_bytes = 1024;
233 opt.dot_spacing = 10;
234 opt.dots_in_line = 50;
237 /* Return the user's home directory (strdup-ed), or NULL if none is
242 char *home = getenv ("HOME");
247 /* If HOME is not defined, try getting it from the password
249 struct passwd *pwd = getpwuid (getuid ());
250 if (!pwd || !pwd->pw_dir)
255 /* #### Maybe I should grab home_dir from registry, but the best
256 that I could get from there is user's Start menu. It sucks! */
260 return home ? xstrdup (home) : NULL;
263 /* Return the path to the user's .wgetrc. This is either the value of
264 `WGETRC' environment variable, or `$HOME/.wgetrc'.
266 If the `WGETRC' variable exists but the file does not exist, the
267 function will exit(). */
269 wgetrc_file_name (void)
274 /* Try the environment. */
275 env = getenv ("WGETRC");
278 if (!file_exists_p (env))
280 fprintf (stderr, "%s: %s: %s.\n", exec_name, file, strerror (errno));
283 return xstrdup (env);
287 /* If that failed, try $HOME/.wgetrc. */
291 file = (char *)xmalloc (strlen (home) + 1 + strlen (".wgetrc") + 1);
292 sprintf (file, "%s/.wgetrc", home);
296 /* Under Windows, "home" is (for the purposes of this function) the
297 directory where `wget.exe' resides, and `wget.ini' will be used
298 as file name. SYSTEM_WGETRC should not be defined under WINDOWS.
300 It is not as trivial as I assumed, because on 95 argv[0] is full
301 path, but on NT you get what you typed in command line. --dbudor */
305 file = (char *)xmalloc (strlen (home) + strlen ("wget.ini") + 1);
306 sprintf (file, "%swget.ini", home);
312 if (!file_exists_p (file))
320 /* Initialize variables from a wgetrc file */
322 run_wgetrc (const char *file)
328 fp = fopen (file, "rb");
331 fprintf (stderr, _("%s: Cannot read %s (%s).\n"), exec_name,
332 file, strerror (errno));
335 /* Reset line number. */
337 while ((line = read_whole_line (fp)))
342 /* Parse the line. */
343 status = parse_line (line, &com, &val);
345 /* If everything is OK, set the value. */
348 if (!setval (com, val))
349 fprintf (stderr, _("%s: Error in %s at line %d.\n"), exec_name,
354 else if (status == 0)
355 fprintf (stderr, _("%s: Error in %s at line %d.\n"), exec_name,
362 /* Initialize the defaults and run the system wgetrc and user's own
369 /* Load the hard-coded defaults. */
372 /* If SYSTEM_WGETRC is defined, use it. */
374 if (file_exists_p (SYSTEM_WGETRC))
375 run_wgetrc (SYSTEM_WGETRC);
377 /* Override it with your own, if one exists. */
378 file = wgetrc_file_name ();
381 /* #### We should somehow canonicalize `file' and SYSTEM_WGETRC,
384 if (!strcmp (file, SYSTEM_WGETRC))
386 fprintf (stderr, _("\
387 %s: Warning: Both system and user wgetrc point to `%s'.\n"),
397 /* Parse the line pointed by line, with the syntax:
398 <sp>* command <sp>* = <sp>* value <newline>
399 Uses malloc to allocate space for command and value.
400 If the line is invalid, data is freed and 0 is returned.
407 parse_line (const char *line, char **com, char **val)
409 const char *p = line;
410 const char *orig_comptr, *end;
413 /* Skip whitespace. */
414 while (*p && ISSPACE (*p))
417 /* Don't process empty lines. */
418 if (!*p || *p == '#')
421 for (orig_comptr = p; ISALPHA (*p) || *p == '_' || *p == '-'; p++)
423 /* The next char should be space or '='. */
424 if (!ISSPACE (*p) && (*p != '='))
426 /* Here we cannot use strdupdelim() as we normally would because we
427 want to skip the `-' and `_' characters in the input string. */
428 *com = (char *)xmalloc (p - orig_comptr + 1);
429 for (new_comptr = *com; orig_comptr < p; orig_comptr++)
431 if (*orig_comptr == '_' || *orig_comptr == '-')
433 *new_comptr++ = *orig_comptr;
436 /* If the command is invalid, exit now. */
437 if (comind (*com) == -1)
443 /* Skip spaces before '='. */
444 for (; ISSPACE (*p); p++);
445 /* If '=' not found, bail out. */
451 /* Skip spaces after '='. */
452 for (++p; ISSPACE (*p); p++);
453 /* Get the ending position for VAL by starting with the end of the
454 line and skipping whitespace. */
455 end = line + strlen (line) - 1;
456 while (end > p && ISSPACE (*end))
458 *val = strdupdelim (p, end + 1);
462 /* Set COM to VAL. This is the meat behind processing `.wgetrc'. No
463 fatals -- error signal prints a warning and resets to default
464 value. All error messages are printed to stderr, *not* to
465 opt.lfile, since opt.lfile wasn't even generated yet. */
467 setval (const char *com, const char *val)
476 /* #### Should I just abort()? */
478 fprintf (stderr, _("%s: BUG: unknown command `%s', value `%s'.\n"),
479 exec_name, com, val);
483 return ((*commands[ind].action) (com, val, commands[ind].closure));
486 /* Generic helper functions, for use with `commands'. */
488 static int myatoi PARAMS ((const char *s));
490 /* Store the address (specified as hostname or dotted-quad IP address) from VAL
491 to CLOSURE. COM is ignored, except for error messages. */
493 cmd_address (const char *com, const char *val, void *closure)
495 struct sockaddr_in *sin;
497 sin = (struct sockaddr_in *) malloc(sizeof *sin);
500 fprintf (stderr, _("%s: Out of memory.\n"), exec_name);
504 if (!store_hostaddress ((unsigned char *)&sin->sin_addr, val))
506 fprintf (stderr, _("%s: %s: Cannot convert `%s' to an IP address.\n"),
507 exec_name, com, val);
511 sin->sin_family = AF_INET;
514 * (struct sockaddr_in **) closure = sin;
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 /* Merge the vector (array of strings separated with `,') in COM with
630 the vector (NULL-terminated array of strings) pointed to by
633 cmd_vector (const char *com, const char *val, void *closure)
635 char ***pvec = (char ***)closure;
638 *pvec = merge_vecs (*pvec, sepstring (val));
648 cmd_directory_vector (const char *com, const char *val, void *closure)
650 char ***pvec = (char ***)closure;
654 /* Strip the trailing slashes from directories. */
657 seps = sepstring (val);
658 for (t = seps; t && *t; t++)
660 int len = strlen (*t);
661 /* Skip degenerate case of root directory. */
664 if ((*t)[len - 1] == '/')
665 (*t)[len - 1] = '\0';
668 *pvec = merge_vecs (*pvec, seps);
678 /* Set the value stored in VAL to CLOSURE (which should point to a
679 long int), allowing several postfixes, with the following syntax
683 [0-9]+[kK] -> bytes * 1024
684 [0-9]+[mM] -> bytes * 1024 * 1024
687 Anything else is flagged as incorrect, and CLOSURE is unchanged. */
689 cmd_bytes (const char *com, const char *val, void *closure)
692 long *out = (long *)closure;
697 /* Check for "inf". */
698 if (p[0] == 'i' && p[1] == 'n' && p[2] == 'f' && p[3] == '\0')
703 /* Search for digits and construct result. */
704 for (; *p && ISDIGIT (*p); p++)
705 result = (10 * result) + (*p - '0');
706 /* If no digits were found, or more than one character is following
708 if (p == val || (*p != '\0' && *(p + 1) != '\0'))
710 printf (_("%s: Invalid specification `%s'\n"), com, val);
713 /* Search for a designator. */
714 switch (TOLOWER (*p))
725 result *= (long)1024 * 1024;
729 result *= (long)1024 * 1024 * 1024;
732 printf (_("%s: Invalid specification `%s'\n"), com, val);
739 /* Store the value of VAL to *OUT, allowing suffixes for minutes and
742 cmd_time (const char *com, const char *val, void *closure)
747 /* Search for digits and construct result. */
748 for (; *p && ISDIGIT (*p); p++)
749 result = (10 * result) + (*p - '0');
750 /* If no digits were found, or more than one character is following
752 if (p == val || (*p != '\0' && *(p + 1) != '\0'))
754 printf (_("%s: Invalid specification `%s'\n"), com, val);
757 /* Search for a suffix. */
758 switch (TOLOWER (*p))
772 /* Days (overflow on 16bit machines) */
780 printf (_("%s: Invalid specification `%s'\n"), com, val);
783 *(long *)closure = result;
787 /* Specialized helper functions, used by `commands' to handle some
788 options specially. */
790 static int check_user_specified_header PARAMS ((const char *));
793 cmd_spec_dirstruct (const char *com, const char *val, void *closure)
795 if (!cmd_boolean (com, val, &opt.dirstruct))
797 /* Since dirstruct behaviour is explicitly changed, no_dirstruct
798 must be affected inversely. */
800 opt.no_dirstruct = 0;
802 opt.no_dirstruct = 1;
807 cmd_spec_dotstyle (const char *com, const char *val, void *closure)
809 /* Retrieval styles. */
810 if (!strcasecmp (val, "default"))
812 /* Default style: 1K dots, 10 dots in a cluster, 50 dots in a
814 opt.dot_bytes = 1024;
815 opt.dot_spacing = 10;
816 opt.dots_in_line = 50;
818 else if (!strcasecmp (val, "binary"))
820 /* "Binary" retrieval: 8K dots, 16 dots in a cluster, 48 dots
822 opt.dot_bytes = 8192;
823 opt.dot_spacing = 16;
824 opt.dots_in_line = 48;
826 else if (!strcasecmp (val, "mega"))
828 /* "Mega" retrieval, for retrieving very long files; each dot is
829 64K, 8 dots in a cluster, 6 clusters (3M) in a line. */
830 opt.dot_bytes = 65536L;
832 opt.dots_in_line = 48;
834 else if (!strcasecmp (val, "giga"))
836 /* "Giga" retrieval, for retrieving very very *very* long files;
837 each dot is 1M, 8 dots in a cluster, 4 clusters (32M) in a
839 opt.dot_bytes = (1L << 20);
841 opt.dots_in_line = 32;
843 else if (!strcasecmp (val, "micro"))
845 /* "Micro" retrieval, for retrieving very small files (and/or
846 slow connections); each dot is 128 bytes, 8 dots in a
847 cluster, 6 clusters (6K) in a line. */
850 opt.dots_in_line = 48;
854 fprintf (stderr, _("%s: %s: Invalid specification `%s'.\n"),
855 exec_name, com, val);
862 cmd_spec_header (const char *com, const char *val, void *closure)
866 /* Empty header means reset headers. */
867 FREE_MAYBE (opt.user_header);
868 opt.user_header = NULL;
874 if (!check_user_specified_header (val))
876 fprintf (stderr, _("%s: %s: Invalid specification `%s'.\n"),
877 exec_name, com, val);
880 i = opt.user_header ? strlen (opt.user_header) : 0;
881 opt.user_header = (char *)xrealloc (opt.user_header, i + strlen (val)
883 strcpy (opt.user_header + i, val);
885 opt.user_header[i++] = '\r';
886 opt.user_header[i++] = '\n';
887 opt.user_header[i] = '\0';
893 cmd_spec_htmlify (const char *com, const char *val, void *closure)
895 int flag = cmd_boolean (com, val, &opt.htmlify);
896 if (flag && !opt.htmlify)
897 opt.remove_listing = 0;
902 cmd_spec_mirror (const char *com, const char *val, void *closure)
906 if (!cmd_boolean (com, val, &mirror))
911 if (!opt.no_dirstruct)
913 opt.timestamping = 1;
914 opt.reclevel = INFINITE_RECURSION;
915 opt.remove_listing = 0;
921 cmd_spec_recursive (const char *com, const char *val, void *closure)
923 if (!cmd_boolean (com, val, &opt.recursive))
927 if (opt.recursive && !opt.no_dirstruct)
934 cmd_spec_useragent (const char *com, const char *val, void *closure)
936 /* Just check for empty string and newline, so we don't throw total
937 junk to the server. */
938 if (!*val || strchr (val, '\n'))
940 fprintf (stderr, _("%s: %s: Invalid specification `%s'.\n"),
941 exec_name, com, val);
944 opt.useragent = xstrdup (val);
948 /* Miscellaneous useful routines. */
950 /* Return the integer value of a positive integer written in S, or -1
951 if an error was encountered. */
953 myatoi (const char *s)
956 const char *orig = s;
958 for (res = 0; *s && ISDIGIT (*s); s++)
959 res = 10 * res + (*s - '0');
966 #define ISODIGIT(x) ((x) >= '0' && (x) <= '7')
969 check_user_specified_header (const char *s)
973 for (p = s; *p && *p != ':' && !ISSPACE (*p); p++);
974 /* The header MUST contain `:' preceded by at least one
975 non-whitespace character. */
976 if (*p != ':' || p == s)
978 /* The header MUST NOT contain newlines. */
979 if (strchr (s, '\n'))
984 void cleanup_html_url PARAMS ((void));
985 void downloaded_files_free PARAMS ((void));
988 /* Free the memory allocated by global variables. */
992 extern acc_t *netrc_list;
994 recursive_cleanup ();
996 free_netrc (netrc_list);
1000 downloaded_files_free ();
1001 FREE_MAYBE (opt.lfilename);
1002 xfree (opt.dir_prefix);
1003 FREE_MAYBE (opt.input_filename);
1004 FREE_MAYBE (opt.output_document);
1005 free_vec (opt.accepts);
1006 free_vec (opt.rejects);
1007 free_vec (opt.excludes);
1008 free_vec (opt.includes);
1009 free_vec (opt.domains);
1010 free_vec (opt.follow_tags);
1011 free_vec (opt.ignore_tags);
1012 xfree (opt.ftp_acc);
1013 FREE_MAYBE (opt.ftp_pass);
1014 FREE_MAYBE (opt.ftp_proxy);
1015 FREE_MAYBE (opt.http_proxy);
1016 free_vec (opt.no_proxy);
1017 FREE_MAYBE (opt.useragent);
1018 FREE_MAYBE (opt.referer);
1019 FREE_MAYBE (opt.http_user);
1020 FREE_MAYBE (opt.http_passwd);
1021 FREE_MAYBE (opt.user_header);