X-Git-Url: http://sjero.net/git/?p=wget;a=blobdiff_plain;f=src%2Finit.c;h=d3d0f9b3efba8c33a7e74fdcbeb00961fab58829;hp=c0bbee525eb16367ceb94444f3d434964a76951f;hb=e911bc29434b7da90446d2ca5304106724d05680;hpb=e815fe81a05f6cec2a684b10567f116e4d721689 diff --git a/src/init.c b/src/init.c index c0bbee52..d3d0f9b3 100644 --- a/src/init.c +++ b/src/init.c @@ -30,16 +30,11 @@ so, delete this exception statement from your version. */ #include #include -#include #include #ifdef HAVE_UNISTD_H # include #endif -#ifdef HAVE_STRING_H -# include -#else -# include -#endif +#include #include #ifdef HAVE_PWD_H @@ -57,10 +52,6 @@ so, delete this exception statement from your version. */ #include "convert.h" /* for convert_cleanup */ #include "res.h" /* for res_cleanup */ -#ifndef errno -extern int errno; -#endif - /* We want tilde expansion enabled only when reading `.wgetrc' lines; otherwise, it will be performed by the shell. This variable will be set by the wgetrc-reading function. */ @@ -68,8 +59,7 @@ extern int errno; static int enable_tilde_expansion; -#define CMD_DECLARE(func) static int func \ - PARAMS ((const char *, const char *, void *)) +#define CMD_DECLARE(func) static int func (const char *, const char *, void *) CMD_DECLARE (cmd_boolean); CMD_DECLARE (cmd_bytes); @@ -78,7 +68,6 @@ CMD_DECLARE (cmd_bytes_large); CMD_DECLARE (cmd_cert_type); #endif CMD_DECLARE (cmd_directory_vector); -CMD_DECLARE (cmd_lockable_boolean); CMD_DECLARE (cmd_number); CMD_DECLARE (cmd_number_inf); CMD_DECLARE (cmd_string); @@ -105,13 +94,13 @@ CMD_DECLARE (cmd_spec_useragent); function. When adding a new command, simply add it to the list, but be sure to keep the list sorted alphabetically, as command_by_name depends on it. Also, be sure to add any entries - that allocate memory (e.g. cmd_string and cmd_vector guys) to the + that allocate memory (e.g. cmd_string and cmd_vector) to the cleanup() function below. */ static struct { const char *name; void *place; - int (*action) PARAMS ((const char *, const char *, void *)); + int (*action) (const char *, const char *, void *); } commands[] = { { "accept", &opt.accepts, cmd_vector }, { "addhostdir", &opt.add_hostdir, cmd_boolean }, @@ -159,10 +148,10 @@ static struct { { "forcehtml", &opt.force_html, cmd_boolean }, { "ftppasswd", &opt.ftp_passwd, cmd_string }, /* deprecated */ { "ftppassword", &opt.ftp_passwd, cmd_string }, - { "ftpuser", &opt.ftp_user, cmd_string }, { "ftpproxy", &opt.ftp_proxy, cmd_string }, + { "ftpuser", &opt.ftp_user, cmd_string }, { "glob", &opt.ftp_glob, cmd_boolean }, - { "header", &opt.user_headers, cmd_spec_header }, + { "header", NULL, cmd_spec_header }, { "htmlextension", &opt.html_extension, cmd_boolean }, { "htmlify", NULL, cmd_spec_htmlify }, { "httpkeepalive", &opt.http_keep_alive, cmd_boolean }, @@ -193,7 +182,7 @@ static struct { { "numtries", &opt.ntry, cmd_number_inf },/* deprecated*/ { "outputdocument", &opt.output_document, cmd_file }, { "pagerequisites", &opt.page_requisites, cmd_boolean }, - { "passiveftp", &opt.ftp_pasv, cmd_lockable_boolean }, + { "passiveftp", &opt.ftp_pasv, cmd_boolean }, { "passwd", &opt.ftp_passwd, cmd_string },/* deprecated*/ { "password", &opt.passwd, cmd_string }, { "postdata", &opt.post_data, cmd_string }, @@ -211,7 +200,9 @@ static struct { { "proxyuser", &opt.proxy_user, cmd_string }, { "quiet", &opt.quiet, cmd_boolean }, { "quota", &opt.quota, cmd_bytes_large }, +#ifdef HAVE_SSL { "randomfile", &opt.random_file, cmd_file }, +#endif { "randomwait", &opt.random_wait, cmd_boolean }, { "readtimeout", &opt.read_timeout, cmd_time }, { "reclevel", &opt.reclevel, cmd_number_inf }, @@ -402,51 +393,78 @@ wgetrc_file_name (void) return file; } -static int parse_line PARAMS ((const char *, char **, char **, int *)); -static int setval_internal PARAMS ((int, const char *, const char *)); +/* Return values of parse_line. */ +enum parse_line { + line_ok, + line_empty, + line_syntax_error, + line_unknown_command +}; -/* Initialize variables from a wgetrc file. */ +static enum parse_line parse_line (const char *, char **, char **, int *); +static int setval_internal (int, const char *, const char *); -static void +/* Initialize variables from a wgetrc file. Returns zero (failure) if + there were errors in the file. */ + +static int run_wgetrc (const char *file) { FILE *fp; char *line; int ln; + int errcnt = 0; fp = fopen (file, "rb"); if (!fp) { fprintf (stderr, _("%s: Cannot read %s (%s).\n"), exec_name, file, strerror (errno)); - return; + return 1; /* not a fatal error */ } enable_tilde_expansion = 1; ln = 1; while ((line = read_whole_line (fp)) != NULL) { - char *com, *val; - int comind, status; + char *com = NULL, *val = NULL; + int comind; /* Parse the line. */ - status = parse_line (line, &com, &val, &comind); - xfree (line); - /* If everything is OK, set the value. */ - if (status == 1) + switch (parse_line (line, &com, &val, &comind)) { + case line_ok: + /* If everything is OK, set the value. */ if (!setval_internal (comind, com, val)) - fprintf (stderr, _("%s: Error in %s at line %d.\n"), exec_name, - file, ln); - xfree (com); - xfree (val); + { + fprintf (stderr, _("%s: Error in %s at line %d.\n"), + exec_name, file, ln); + ++errcnt; + } + break; + case line_syntax_error: + fprintf (stderr, _("%s: Syntax error in %s at line %d.\n"), + exec_name, file, ln); + ++errcnt; + break; + case line_unknown_command: + fprintf (stderr, _("%s: Unknown command `%s' in %s at line %d.\n"), + exec_name, com, file, ln); + ++errcnt; + break; + case line_empty: + break; + default: + abort (); } - else if (status == 0) - fprintf (stderr, _("%s: Error in %s at line %d.\n"), exec_name, - file, ln); + xfree_null (com); + xfree_null (val); + xfree (line); ++ln; } enable_tilde_expansion = 0; fclose (fp); + + return errcnt == 0; } /* Initialize the defaults and run the system wgetrc and user's own @@ -455,6 +473,7 @@ void initialize (void) { char *file; + int ok = 1; /* Load the hard-coded defaults. */ defaults (); @@ -462,7 +481,7 @@ initialize (void) /* If SYSTEM_WGETRC is defined, use it. */ #ifdef SYSTEM_WGETRC if (file_exists_p (SYSTEM_WGETRC)) - run_wgetrc (SYSTEM_WGETRC); + ok &= run_wgetrc (SYSTEM_WGETRC); #endif /* Override it with your own, if one exists. */ file = wgetrc_file_name (); @@ -479,7 +498,12 @@ initialize (void) } else #endif - run_wgetrc (file); + ok &= run_wgetrc (file); + + /* If there were errors processing either `.wgetrc', abort. */ + if (!ok) + exit (2); + xfree (file); return; } @@ -505,16 +529,14 @@ dehyphen (char *s) Uses malloc to allocate space for command and value. If the line is invalid, data is freed and 0 is returned. - Return values: - 1 - success - 0 - error - -1 - empty + Returns one of line_ok, line_empty, line_syntax_error, or + line_unknown_command. - In case of success, *COM and *VAL point to freshly allocated + In case of line_ok, *COM and *VAL point to freshly allocated strings, and *COMIND points to com's index. In case of error or - empty line, those values are unaffected. */ + empty line, their values are unmodified. */ -static int +static enum parse_line parse_line (const char *line, char **com, char **val, int *comind) { const char *p; @@ -533,7 +555,7 @@ parse_line (const char *line, char **com, char **val, int *comind) /* Skip empty lines and comments. */ if (!*line || *line == '#') - return -1; + return line_empty; p = line; @@ -546,7 +568,7 @@ parse_line (const char *line, char **com, char **val, int *comind) while (p < end && ISSPACE (*p)) ++p; if (p == end || *p != '=') - return 0; + return line_syntax_error; ++p; while (p < end && ISSPACE (*p)) ++p; @@ -554,20 +576,22 @@ parse_line (const char *line, char **com, char **val, int *comind) valstart = p; valend = end; + /* The syntax is valid (even though the command might not be). Fill + in the command name and value. */ + *com = strdupdelim (cmdstart, cmdend); + *val = strdupdelim (valstart, valend); + /* The line now known to be syntactically correct. Check whether the command is valid. */ BOUNDED_TO_ALLOCA (cmdstart, cmdend, cmdcopy); dehyphen (cmdcopy); ind = command_by_name (cmdcopy); if (ind == -1) - return 0; + return line_unknown_command; - /* The command is valid. Now fill in the values and report success - to the caller. */ + /* Report success to the caller. */ *comind = ind; - *com = strdupdelim (cmdstart, cmdend); - *val = strdupdelim (valstart, valend); - return 1; + return line_ok; } /* Run commands[comind].action. */ @@ -576,8 +600,8 @@ static int setval_internal (int comind, const char *com, const char *val) { assert (0 <= comind && comind < countof (commands)); - DEBUGP (("Setting %s (%d) to %s\n", com, comind, val)); - return ((*commands[comind].action) (com, val, commands[comind].place)); + DEBUGP (("Setting %s (%s) to %s\n", com, commands[comind].name, val)); + return commands[comind].action (com, val, commands[comind].place); } /* Run command COM with value VAL. If running the command produces an @@ -591,10 +615,16 @@ setval_internal (int comind, const char *com, const char *val) to accept COMIND directly. */ void -setoptval (const char *com, const char *val) +setoptval (const char *com, const char *val, const char *optname) { + /* Prepend "--" to OPTNAME. */ + char *dd_optname = (char *) alloca (2 + strlen (optname) + 1); + dd_optname[0] = '-'; + dd_optname[1] = '-'; + strcpy (dd_optname + 2, optname); + assert (val != NULL); - if (!setval_internal (command_by_name (com), com, val)) + if (!setval_internal (command_by_name (com), dd_optname, val)) exit (2); } @@ -607,16 +637,15 @@ run_command (const char *opt) { char *com, *val; int comind; - int status = parse_line (opt, &com, &val, &comind); - if (status == 1) + switch (parse_line (opt, &com, &val, &comind)) { + case line_ok: if (!setval_internal (comind, com, val)) exit (2); xfree (com); xfree (val); - } - else if (status == 0) - { + break; + default: fprintf (stderr, _("%s: Invalid --execute command `%s'\n"), exec_name, opt); exit (2); @@ -630,10 +659,9 @@ struct decode_item { const char *name; int code; }; -static int decode_string PARAMS ((const char *, const struct decode_item *, - int, int *)); -static int simple_atoi PARAMS ((const char *, const char *, int *)); -static int simple_atof PARAMS ((const char *, const char *, double *)); +static int decode_string (const char *, const struct decode_item *, int, int *); +static int simple_atoi (const char *, const char *, int *); +static int simple_atof (const char *, const char *, double *); #define CMP1(p, c0) (TOLOWER((p)[0]) == (c0) && (p)[1] == '\0') @@ -663,7 +691,7 @@ cmd_boolean (const char *com, const char *val, void *place) else { fprintf (stderr, - _("%s: %s: Invalid boolean `%s', use `on' or `off'.\n"), + _("%s: %s: Invalid boolean `%s'; use `on' or `off'.\n"), exec_name, com, val); return 0; } @@ -672,49 +700,6 @@ cmd_boolean (const char *com, const char *val, void *place) return 1; } -/* Store the lockable_boolean {2, 1, 0, -1} value from VAL to PLACE. - COM is ignored, except for error messages. Values 2 and -1 - indicate that once defined, the value may not be changed by - successive wgetrc files or command-line arguments. - - Values: 2 - Enable a particular option for good ("always") - 1 - Enable an option ("on") - 0 - Disable an option ("off") - -1 - Disable an option for good ("never") */ -static int -cmd_lockable_boolean (const char *com, const char *val, void *place) -{ - int lockable_boolean_value; - - int oldval = *(int *)place; - - /* - * If a config file said "always" or "never", don't allow command line - * arguments to override the config file. - */ - if (oldval == -1 || oldval == 2) - return 1; - - if (0 == strcasecmp (val, "always") || CMP1 (val, '2')) - lockable_boolean_value = 2; - else if (CMP2 (val, 'o', 'n') || CMP3 (val, 'y', 'e', 's') || CMP1 (val, '1')) - lockable_boolean_value = 1; - else if (CMP3 (val, 'o', 'f', 'f') || CMP2 (val, 'n', 'o') || CMP1 (val, '0')) - lockable_boolean_value = 0; - else if (0 == strcasecmp (val, "never") || CMP2 (val, '-', '1')) - lockable_boolean_value = -1; - else - { - fprintf (stderr, - _("%s: %s: Invalid boolean `%s', use always, on, off, or never.\n"), - exec_name, com, val); - return 0; - } - - *(int *)place = lockable_boolean_value; - return 1; -} - /* Set the non-negative integer value from VAL to PLACE. With incorrect specification, the number remains unchanged. */ static int @@ -1060,7 +1045,7 @@ cmd_cert_type (const char *com, const char *val, void *place) /* Specialized helper functions, used by `commands' to handle some options specially. */ -static int check_user_specified_header PARAMS ((const char *)); +static int check_user_specified_header (const char *); static int cmd_spec_dirstruct (const char *com, const char *val, void *place_ignored) @@ -1077,15 +1062,24 @@ cmd_spec_dirstruct (const char *com, const char *val, void *place_ignored) } static int -cmd_spec_header (const char *com, const char *val, void *place) +cmd_spec_header (const char *com, const char *val, void *place_ignored) { + /* Empty value means reset the list of headers. */ + if (*val == '\0') + { + free_vec (opt.user_headers); + opt.user_headers = NULL; + return 1; + } + if (!check_user_specified_header (val)) { fprintf (stderr, _("%s: %s: Invalid header `%s'.\n"), exec_name, com, val); return 0; } - return cmd_vector (com, val, place); + opt.user_headers = vec_append (opt.user_headers, val); + return 1; } static int @@ -1250,14 +1244,14 @@ cmd_spec_timeout (const char *com, const char *val, void *place_ignored) static int cmd_spec_useragent (const char *com, const char *val, void *place_ignored) { - /* Just check for empty string and newline, so we don't throw total - junk to the server. */ - if (!*val || strchr (val, '\n')) + /* Disallow embedded newlines. */ + if (strchr (val, '\n')) { fprintf (stderr, _("%s: %s: Invalid value `%s'.\n"), exec_name, com, val); return 0; } + xfree_null (opt.useragent); opt.useragent = xstrdup (val); return 1; } @@ -1403,8 +1397,8 @@ decode_string (const char *val, const struct decode_item *items, int itemcount, } -void cleanup_html_url PARAMS ((void)); -void http_cleanup PARAMS ((void)); +void cleanup_html_url (void); +void http_cleanup (void); /* Free the memory allocated by global variables. */ @@ -1453,7 +1447,6 @@ cleanup (void) free_vec (opt.follow_tags); free_vec (opt.ignore_tags); xfree_null (opt.progress_type); - xfree (opt.ftp_acc); xfree_null (opt.ftp_user); xfree_null (opt.ftp_passwd); xfree_null (opt.ftp_proxy); @@ -1468,6 +1461,10 @@ cleanup (void) # ifdef HAVE_SSL xfree_null (opt.cert_file); xfree_null (opt.private_key); + xfree_null (opt.ca_directory); + xfree_null (opt.ca_cert); + xfree_null (opt.random_file); + xfree_null (opt.egd_file); # endif xfree_null (opt.bind_address); xfree_null (opt.cookies_input);