X-Git-Url: http://sjero.net/git/?p=wget;a=blobdiff_plain;f=src%2Finit.c;h=d3d0f9b3efba8c33a7e74fdcbeb00961fab58829;hp=e836e2a315a5f52dc61a47cffafd0eb9d69987b8;hb=e911bc29434b7da90446d2ca5304106724d05680;hpb=bdad650583fa4648a3675a7a9aee056240a593e0 diff --git a/src/init.c b/src/init.c index e836e2a3..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,14 +59,15 @@ 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); CMD_DECLARE (cmd_bytes_large); +#ifdef HAVE_SSL +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); @@ -84,9 +76,6 @@ CMD_DECLARE (cmd_directory); CMD_DECLARE (cmd_time); CMD_DECLARE (cmd_vector); -#ifdef HAVE_SSL -CMD_DECLARE (cmd_spec_cert_type); -#endif CMD_DECLARE (cmd_spec_dirstruct); CMD_DECLARE (cmd_spec_header); CMD_DECLARE (cmd_spec_htmlify); @@ -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 }, @@ -128,8 +117,7 @@ static struct { #ifdef HAVE_SSL { "cadirectory", &opt.ca_directory, cmd_directory }, { "certificate", &opt.cert_file, cmd_file }, - { "certificatekey", &opt.cert_key, cmd_file }, - { "certificatetype", &opt.cert_type, cmd_spec_cert_type }, + { "certificatetype", &opt.cert_type, cmd_cert_type }, { "checkcertificate", &opt.check_cert, cmd_boolean }, #endif { "connecttimeout", &opt.connect_timeout, cmd_time }, @@ -158,14 +146,17 @@ static struct { { "followftp", &opt.follow_ftp, cmd_boolean }, { "followtags", &opt.follow_tags, cmd_vector }, { "forcehtml", &opt.force_html, cmd_boolean }, - { "ftppasswd", &opt.ftp_pass, cmd_string }, + { "ftppasswd", &opt.ftp_passwd, cmd_string }, /* deprecated */ + { "ftppassword", &opt.ftp_passwd, 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 }, - { "httppasswd", &opt.http_passwd, cmd_string }, + { "httppasswd", &opt.http_passwd, cmd_string }, /* deprecated */ + { "httppassword", &opt.http_passwd, cmd_string }, { "httpproxy", &opt.http_proxy, cmd_string }, { "httpsproxy", &opt.https_proxy, cmd_string }, { "httpuser", &opt.http_user, cmd_string }, @@ -182,7 +173,7 @@ static struct { { "limitrate", &opt.limit_rate, cmd_bytes }, { "loadcookies", &opt.cookies_input, cmd_file }, { "logfile", &opt.lfilename, cmd_file }, - { "login", &opt.ftp_acc, cmd_string }, + { "login", &opt.ftp_user, cmd_string },/* deprecated*/ { "mirror", NULL, cmd_spec_mirror }, { "netrc", &opt.netrc, cmd_boolean }, { "noclobber", &opt.noclobber, cmd_boolean }, @@ -191,17 +182,27 @@ 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 }, { "postfile", &opt.post_file_name, cmd_file }, { "preferfamily", NULL, cmd_spec_prefer_family }, { "preservepermissions", &opt.preserve_perm, cmd_boolean }, +#ifdef HAVE_SSL + { "privatekey", &opt.private_key, cmd_file }, + { "privatekeytype", &opt.private_key_type, cmd_cert_type }, +#endif { "progress", &opt.progress_type, cmd_spec_progress }, { "protocoldirectories", &opt.protocol_directories, cmd_boolean }, - { "proxypasswd", &opt.proxy_passwd, cmd_string }, + { "proxypasswd", &opt.proxy_passwd, cmd_string }, /* deprecated */ + { "proxypassword", &opt.proxy_passwd, cmd_string }, { "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 }, @@ -227,6 +228,7 @@ static struct { { "timestamping", &opt.timestamping, cmd_boolean }, { "tries", &opt.ntry, cmd_number_inf }, { "useproxy", &opt.use_proxy, cmd_boolean }, + { "user", &opt.user, cmd_string }, { "useragent", NULL, cmd_spec_useragent }, { "verbose", &opt.verbose, cmd_boolean }, { "wait", &opt.wait, cmd_time }, @@ -275,8 +277,6 @@ defaults (void) opt.ntry = 20; opt.reclevel = 5; opt.add_hostdir = 1; - opt.ftp_acc = xstrdup ("anonymous"); - opt.ftp_pass = xstrdup ("-wget@"); opt.netrc = 1; opt.ftp_glob = 1; opt.htmlify = 1; @@ -393,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 @@ -446,6 +473,7 @@ void initialize (void) { char *file; + int ok = 1; /* Load the hard-coded defaults. */ defaults (); @@ -453,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 (); @@ -470,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; } @@ -496,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; @@ -524,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; @@ -537,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; @@ -545,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. */ @@ -567,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 @@ -582,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); } @@ -598,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); @@ -616,6 +654,15 @@ run_command (const char *opt) /* Generic helper functions, for use with `commands'. */ +/* Forward declarations: */ +struct decode_item { + const char *name; + int code; +}; +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') #define CMP2(p, c0, c1) (TOLOWER((p)[0]) == (c0) \ @@ -644,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; } @@ -653,51 +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; -} - -static int simple_atoi PARAMS ((const char *, const char *, int *)); - /* Set the non-negative integer value from VAL to PLACE. With incorrect specification, the number remains unchanged. */ static int @@ -860,8 +862,6 @@ cmd_directory_vector (const char *com, const char *val, void *place) return 1; } -static int simple_atof PARAMS ((const char *, const char *, double *)); - /* Engine for cmd_bytes and cmd_bytes_large: converts a string such as "100k" or "2.5G" to a floating point number. */ @@ -1007,7 +1007,7 @@ cmd_time (const char *com, const char *val, void *place) break; default: /* Not a recognized suffix: assume it belongs to the number. - (If not, atof simple_atof will raise an error.) */ + (If not, simple_atof will raise an error.) */ mult = 1; } @@ -1025,26 +1025,15 @@ cmd_time (const char *com, const char *val, void *place) *(double *)place = number * mult; return 1; } - -/* Specialized helper functions, used by `commands' to handle some - options specially. */ - -static int check_user_specified_header PARAMS ((const char *)); -/* Forward decl */ -struct decode_item { - const char *name; - int code; -}; -static int decode_string PARAMS ((const char *, const struct decode_item *, - int, int *)); #ifdef HAVE_SSL static int -cmd_spec_cert_type (const char *com, const char *val, void *place) +cmd_cert_type (const char *com, const char *val, void *place) { static const struct decode_item choices[] = { - { "pem", cert_type_pem }, - { "asn1", cert_type_asn1 }, + { "pem", keyfile_pem }, + { "der", keyfile_asn1 }, + { "asn1", keyfile_asn1 }, }; int ok = decode_string (val, choices, countof (choices), place); if (!ok) @@ -1052,6 +1041,11 @@ cmd_spec_cert_type (const char *com, const char *val, void *place) return ok; } #endif + +/* Specialized helper functions, used by `commands' to handle some + options specially. */ + +static int check_user_specified_header (const char *); static int cmd_spec_dirstruct (const char *com, const char *val, void *place_ignored) @@ -1068,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 @@ -1241,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; } @@ -1394,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. */ @@ -1444,8 +1447,8 @@ 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_pass); + xfree_null (opt.ftp_user); + xfree_null (opt.ftp_passwd); xfree_null (opt.ftp_proxy); xfree_null (opt.https_proxy); xfree_null (opt.http_proxy); @@ -1455,12 +1458,18 @@ cleanup (void) xfree_null (opt.http_user); xfree_null (opt.http_passwd); free_vec (opt.user_headers); -#ifdef HAVE_SSL - xfree_null (opt.sslcertkey); - xfree_null (opt.sslcertfile); -#endif /* HAVE_SSL */ +# 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); xfree_null (opt.cookies_output); -#endif + xfree_null (opt.user); + xfree_null (opt.passwd); +#endif /* DEBUG_MALLOC */ }