#include <config.h>
#include <stdio.h>
-#include <sys/types.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
-#ifdef HAVE_STRING_H
-# include <string.h>
-#else
-# include <strings.h>
-#endif
+#include <string.h>
#include <errno.h>
#ifdef HAVE_PWD_H
#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. */
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_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);
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 },
#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 },
{ "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 },
{ "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 },
{ "outputdocument", &opt.output_document, cmd_file },
{ "pagerequisites", &opt.page_requisites, cmd_boolean },
{ "passiveftp", &opt.ftp_pasv, cmd_lockable_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 },
{ "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 },
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;
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
initialize (void)
{
char *file;
+ int ok = 1;
/* Load the hard-coded defaults. */
defaults ();
/* 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 ();
}
else
#endif
- run_wgetrc (file);
+ ok &= run_wgetrc (file);
+
+ /* If there were errors processing either `.wgetrc', abort. */
+ if (!ok)
+ exit (2);
+
xfree (file);
return;
}
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;
/* Skip empty lines and comments. */
if (!*line || *line == '#')
- return -1;
+ return line_empty;
p = line;
while (p < end && ISSPACE (*p))
++p;
if (p == end || *p != '=')
- return 0;
+ return line_syntax_error;
++p;
while (p < end && ISSPACE (*p))
++p;
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. */
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
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);
}
{
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);
\f
/* 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) \
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;
}
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") */
+ -1 - Disable an option for good ("never")
+
+ #### This hack is currently only used for passive FTP because a
+ contributor had broken scripts specify --passive-ftp where he
+ didn't want it. It should be removed because the same can now be
+ achieved by replacing the wget executable with a script containing:
+
+ exec wget "$@" --no-passive-ftp
+*/
+
static int
cmd_lockable_boolean (const char *com, const char *val, void *place)
{
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'))
+ 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'))
+ else if (0 == strcasecmp (val, "always"))
+ lockable_boolean_value = 2;
+ else if (0 == strcasecmp (val, "never"))
lockable_boolean_value = -1;
else
{
fprintf (stderr,
- _("%s: %s: Invalid boolean `%s', use always, on, off, or never.\n"),
+ _("%s: %s: Invalid extended boolean `%s';\n\
+use one of `on', `off', `always', or `never'.\n"),
exec_name, com, val);
return 0;
}
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
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. */
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;
}
*(double *)place = number * mult;
return 1;
}
-\f
-/* 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)
return ok;
}
#endif
+\f
+/* 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)
}
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
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;
}
}
\f
-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. */
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);
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 */
}