1 /* Reading/parsing the initialization file.
2 Copyright (C) 1995, 1996, 1997, 1998 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_outputdocument);
80 CMD_DECLARE (cmd_spec_recursive);
81 CMD_DECLARE (cmd_spec_useragent);
83 /* List of recognized commands, each consisting of name, closure and function.
84 When adding a new command, simply add it to the list, but be sure to keep the
85 list sorted alphabetically, as comind() depends on it. Also, be sure to add
86 any entries that allocate memory (e.g. cmd_string and cmd_vector guys) to the
87 cleanup() function below. */
91 int (*action) PARAMS ((const char *, const char *, void *));
93 { "accept", &opt.accepts, cmd_vector },
94 { "addhostdir", &opt.add_hostdir, cmd_boolean },
95 { "alwaysrest", &opt.always_rest, cmd_boolean }, /* deprecated */
96 { "background", &opt.background, cmd_boolean },
97 { "backupconverted", &opt.backup_converted, cmd_boolean },
98 { "backups", &opt.backups, cmd_number },
99 { "bindaddress", &opt.bind_address, cmd_address },
100 { "base", &opt.base_href, cmd_string },
101 { "cache", &opt.proxy_cache, cmd_boolean },
102 { "continue", &opt.always_rest, cmd_boolean },
103 { "convertlinks", &opt.convert_links, cmd_boolean },
104 { "cutdirs", &opt.cut_dirs, cmd_number },
106 { "debug", &opt.debug, cmd_boolean },
108 { "deleteafter", &opt.delete_after, cmd_boolean },
109 { "dirprefix", &opt.dir_prefix, cmd_string },
110 { "dirstruct", NULL, cmd_spec_dirstruct },
111 { "domains", &opt.domains, cmd_vector },
112 { "dotbytes", &opt.dot_bytes, cmd_bytes },
113 { "dotsinline", &opt.dots_in_line, cmd_number },
114 { "dotspacing", &opt.dot_spacing, cmd_number },
115 { "dotstyle", NULL, cmd_spec_dotstyle },
116 { "excludedirectories", &opt.excludes, cmd_directory_vector },
117 { "excludedomains", &opt.exclude_domains, cmd_vector },
118 { "followftp", &opt.follow_ftp, cmd_boolean },
119 { "followtags", &opt.follow_tags, cmd_vector },
120 { "forcehtml", &opt.force_html, cmd_boolean },
121 { "ftpproxy", &opt.ftp_proxy, cmd_string },
122 { "glob", &opt.ftp_glob, cmd_boolean },
123 { "header", NULL, cmd_spec_header },
124 { "htmlextension", &opt.html_extension, cmd_boolean },
125 { "htmlify", NULL, cmd_spec_htmlify },
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", NULL, cmd_spec_outputdocument },
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);
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 ());*/
219 tmp = getenv ("no_proxy");
221 opt.no_proxy = sepstring (tmp);
229 opt.remove_listing = 1;
231 opt.dot_bytes = 1024;
232 opt.dot_spacing = 10;
233 opt.dots_in_line = 50;
236 /* Return the user's home directory (strdup-ed), or NULL if none is
241 char *home = getenv ("HOME");
246 /* If HOME is not defined, try getting it from the password
248 struct passwd *pwd = getpwuid (getuid ());
249 if (!pwd || !pwd->pw_dir)
254 /* #### Maybe I should grab home_dir from registry, but the best
255 that I could get from there is user's Start menu. It sucks! */
259 return home ? xstrdup (home) : NULL;
262 /* Return the path to the user's .wgetrc. This is either the value of
263 `WGETRC' environment variable, or `$HOME/.wgetrc'.
265 If the `WGETRC' variable exists but the file does not exist, the
266 function will exit(). */
268 wgetrc_file_name (void)
273 /* Try the environment. */
274 env = getenv ("WGETRC");
277 if (!file_exists_p (env))
279 fprintf (stderr, "%s: %s: %s.\n", exec_name, file, strerror (errno));
282 return xstrdup (env);
286 /* If that failed, try $HOME/.wgetrc. */
290 file = (char *)xmalloc (strlen (home) + 1 + strlen (".wgetrc") + 1);
291 sprintf (file, "%s/.wgetrc", home);
295 /* Under Windows, "home" is (for the purposes of this function) the
296 directory where `wget.exe' resides, and `wget.ini' will be used
297 as file name. SYSTEM_WGETRC should not be defined under WINDOWS.
299 It is not as trivial as I assumed, because on 95 argv[0] is full
300 path, but on NT you get what you typed in command line. --dbudor */
304 file = (char *)xmalloc (strlen (home) + strlen ("wget.ini") + 1);
305 sprintf (file, "%swget.ini", home);
311 if (!file_exists_p (file))
319 /* Initialize variables from a wgetrc file */
321 run_wgetrc (const char *file)
327 fp = fopen (file, "rb");
330 fprintf (stderr, _("%s: Cannot read %s (%s).\n"), exec_name,
331 file, strerror (errno));
334 /* Reset line number. */
336 while ((line = read_whole_line (fp)))
340 int length = strlen (line);
342 if (length && line[length - 1] == '\r')
343 line[length - 1] = '\0';
344 /* Parse the line. */
345 status = parse_line (line, &com, &val);
347 /* If everything is OK, set the value. */
350 if (!setval (com, val))
351 fprintf (stderr, _("%s: Error in %s at line %d.\n"), exec_name,
356 else if (status == 0)
357 fprintf (stderr, _("%s: Error in %s at line %d.\n"), exec_name,
364 /* Initialize the defaults and run the system wgetrc and user's own
371 /* Load the hard-coded defaults. */
374 /* If SYSTEM_WGETRC is defined, use it. */
376 if (file_exists_p (SYSTEM_WGETRC))
377 run_wgetrc (SYSTEM_WGETRC);
379 /* Override it with your own, if one exists. */
380 file = wgetrc_file_name ();
383 /* #### We should somehow canonicalize `file' and SYSTEM_WGETRC,
386 if (!strcmp (file, SYSTEM_WGETRC))
388 fprintf (stderr, _("\
389 %s: Warning: Both system and user wgetrc point to `%s'.\n"),
399 /* Parse the line pointed by line, with the syntax:
400 <sp>* command <sp>* = <sp>* value <newline>
401 Uses malloc to allocate space for command and value.
402 If the line is invalid, data is freed and 0 is returned.
409 parse_line (const char *line, char **com, char **val)
411 const char *p = line;
412 const char *orig_comptr, *end;
416 while (*p == ' ' || *p == '\t')
419 /* Don't process empty lines. */
420 if (!*p || *p == '\n' || *p == '#')
423 for (orig_comptr = p; ISALPHA (*p) || *p == '_' || *p == '-'; p++)
425 /* The next char should be space or '='. */
426 if (!ISSPACE (*p) && (*p != '='))
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. */
454 for (end = p; *end && *end != '\n'; end++);
455 /* Allocate *val, and copy from line. */
456 *val = strdupdelim (p, end);
460 /* Set COM to VAL. This is the meat behind processing `.wgetrc'. No
461 fatals -- error signal prints a warning and resets to default
462 value. All error messages are printed to stderr, *not* to
463 opt.lfile, since opt.lfile wasn't even generated yet. */
465 setval (const char *com, const char *val)
474 /* #### Should I just abort()? */
476 fprintf (stderr, _("%s: BUG: unknown command `%s', value `%s'.\n"),
477 exec_name, com, val);
481 return ((*commands[ind].action) (com, val, commands[ind].closure));
484 /* Generic helper functions, for use with `commands'. */
486 static int myatoi PARAMS ((const char *s));
488 /* Store the address (specified as hostname or dotted-quad IP address) from VAL
489 to CLOSURE. COM is ignored, except for error messages. */
491 cmd_address (const char *com, const char *val, void *closure)
493 struct sockaddr_in *sin;
495 sin = (struct sockaddr_in *) malloc(sizeof *sin);
498 fprintf (stderr, _("%s: Out of memory.\n"), exec_name);
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 * (struct sockaddr_in **) closure = 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_outputdocument (const char *com, const char *val, void *closure)
921 FREE_MAYBE (opt.output_document);
922 opt.output_document = xstrdup (val);
928 cmd_spec_recursive (const char *com, const char *val, void *closure)
930 if (!cmd_boolean (com, val, &opt.recursive))
934 if (opt.recursive && !opt.no_dirstruct)
941 cmd_spec_useragent (const char *com, const char *val, void *closure)
943 /* Just check for empty string and newline, so we don't throw total
944 junk to the server. */
945 if (!*val || strchr (val, '\n'))
947 fprintf (stderr, _("%s: %s: Invalid specification `%s'.\n"),
948 exec_name, com, val);
951 opt.useragent = xstrdup (val);
955 /* Miscellaneous useful routines. */
957 /* Return the integer value of a positive integer written in S, or -1
958 if an error was encountered. */
960 myatoi (const char *s)
963 const char *orig = s;
965 for (res = 0; *s && ISDIGIT (*s); s++)
966 res = 10 * res + (*s - '0');
973 #define ISODIGIT(x) ((x) >= '0' && (x) <= '7')
976 check_user_specified_header (const char *s)
980 for (p = s; *p && *p != ':' && !ISSPACE (*p); p++);
981 /* The header MUST contain `:' preceded by at least one
982 non-whitespace character. */
983 if (*p != ':' || p == s)
985 /* The header MUST NOT contain newlines. */
986 if (strchr (s, '\n'))
991 /* Free the memory allocated by global variables. */
995 extern acc_t *netrc_list;
997 recursive_cleanup ();
999 free_netrc (netrc_list);
1002 FREE_MAYBE (opt.lfilename);
1003 free (opt.dir_prefix);
1004 FREE_MAYBE (opt.input_filename);
1005 FREE_MAYBE (opt.output_document);
1006 free_vec (opt.accepts);
1007 free_vec (opt.rejects);
1008 free_vec (opt.excludes);
1009 free_vec (opt.includes);
1010 free_vec (opt.domains);
1011 free_vec (opt.follow_tags);
1012 free_vec (opt.ignore_tags);
1014 free (opt.ftp_pass);
1015 FREE_MAYBE (opt.ftp_proxy);
1016 FREE_MAYBE (opt.http_proxy);
1017 free_vec (opt.no_proxy);
1018 FREE_MAYBE (opt.useragent);
1019 FREE_MAYBE (opt.referer);
1020 FREE_MAYBE (opt.http_user);
1021 FREE_MAYBE (opt.http_passwd);
1022 FREE_MAYBE (opt.user_header);