CMD_DECLARE (cmd_spec_mirror);
CMD_DECLARE (cmd_spec_progress);
CMD_DECLARE (cmd_spec_recursive);
+CMD_DECLARE (cmd_spec_restrict_file_names);
CMD_DECLARE (cmd_spec_useragent);
/* List of recognized commands, each consisting of name, closure and function.
{ "deleteafter", &opt.delete_after, cmd_boolean },
{ "dirprefix", &opt.dir_prefix, cmd_directory },
{ "dirstruct", NULL, cmd_spec_dirstruct },
+ { "dnscache", &opt.dns_cache, cmd_boolean },
{ "domains", &opt.domains, cmd_vector },
{ "dotbytes", &opt.dot_bytes, cmd_bytes },
{ "dotsinline", &opt.dots_in_line, cmd_number },
{ "reject", &opt.rejects, cmd_vector },
{ "relativeonly", &opt.relative_only, cmd_boolean },
{ "removelisting", &opt.remove_listing, cmd_boolean },
+ { "restrictfilenames", NULL, cmd_spec_restrict_file_names },
{ "retrsymlinks", &opt.retr_symlinks, cmd_boolean },
{ "retryconnrefused", &opt.retry_connrefused, cmd_boolean },
{ "robots", &opt.use_robots, cmd_boolean },
{ "sslcheckcert", &opt.sslcheckcert, cmd_number },
{ "sslprotocol", &opt.sslprotocol, cmd_number },
#endif /* HAVE_SSL */
+ { "strictcomments", &opt.strict_comments, cmd_boolean },
{ "timeout", &opt.timeout, cmd_time },
{ "timestamping", &opt.timestamping, cmd_boolean },
{ "tries", &opt.ntry, cmd_number_inf },
static int
comind (const char *com)
{
- int lo = 0, hi = ARRAY_SIZE (commands) - 1;
+ int lo = 0, hi = countof (commands) - 1;
while (lo <= hi)
{
opt.cookies = 1;
opt.verbose = -1;
- opt.dir_prefix = xstrdup (".");
opt.ntry = 20;
opt.reclevel = 5;
opt.add_hostdir = 1;
opt.dot_bytes = 1024;
opt.dot_spacing = 10;
opt.dots_in_line = 50;
+
+ opt.dns_cache = 1;
+
+ /* The default for file name restriction defaults to the OS type. */
+#if !defined(WINDOWS) && !defined(__CYGWIN__)
+ opt.restrict_files_os = restrict_unix;
+#else
+ opt.restrict_files_os = restrict_windows;
+#endif
+ opt.restrict_files_ctrl = 1;
}
\f
/* Return the user's home directory (strdup-ed), or NULL if none is
cmd_boolean (const char *com, const char *val, void *closure)
{
int bool_value;
-
- if (!strcasecmp (val, "on")
- || (*val == '1' && !*(val + 1)))
+ const char *v = val;
+#define LC(x) TOLOWER(x)
+
+ if ((LC(v[0]) == 'o' && LC(v[1]) == 'n' && !v[2])
+ ||
+ (LC(v[0]) == 'y' && LC(v[1]) == 'e' && LC(v[2]) == 's' && !v[3])
+ ||
+ (v[0] == '1' && !v[1]))
+ /* "on", "yes" and "1" mean true. */
bool_value = 1;
- else if (!strcasecmp (val, "off")
- || (*val == '0' && !*(val + 1)))
+ else if ((LC(v[0]) == 'o' && LC(v[1]) == 'f' && LC(v[2]) == 'f' && !v[3])
+ ||
+ (LC(v[0]) == 'n' && LC(v[1]) == 'o' && !v[2])
+ ||
+ (v[0] == '0' && !v[1]))
+ /* "off", "no" and "0" mean false. */
bool_value = 0;
else
{
if (*(int *)closure == -1 || *(int *)closure == 2)
return 1;
- if (!strcasecmp (val, "always")
- || (*val == '2' && !*(val + 1)))
+ if (!strcasecmp (val, "always") || !strcmp (val, "2"))
lockable_boolean_value = 2;
else if (!strcasecmp (val, "on")
- || (*val == '1' && !*(val + 1)))
+ || !strcasecmp (val, "yes")
+ || !strcmp (val, "1"))
lockable_boolean_value = 1;
else if (!strcasecmp (val, "off")
- || (*val == '0' && !*(val + 1)))
+ || !strcasecmp (val, "no")
+ || !strcmp (val, "0"))
lockable_boolean_value = 0;
- else if (!strcasecmp (val, "never")
- || (*val == '-' && *(val + 1) == '1' && !*(val + 2)))
+ else if (!strcasecmp (val, "never") || !strcmp (val, "-1"))
lockable_boolean_value = -1;
else
{
return 1;
}
+#ifndef WINDOWS
+# define ISSEP(c) ((c) == '/')
+#else
+# define ISSEP(c) ((c) == '/' || (c) == '\\')
+#endif
+
/* Like the above, but handles tilde-expansion when reading a user's
`.wgetrc'. In that case, and if VAL begins with `~', the tilde
gets expanded to the user's home directory. */
/* #### If VAL is empty, perhaps should set *CLOSURE to NULL. */
- if (!enable_tilde_expansion || !(*val == '~' && (*(val + 1) == '/'
-#ifdef WINDOWS
- || *(val + 1) == '\\'
-#endif
- )))
+ if (!enable_tilde_expansion || !(*val == '~' && ISSEP (val[1])))
{
noexpand:
*pstring = xstrdup (val);
goto noexpand;
homelen = strlen (home);
- while (homelen && (home[homelen - 1] == '/'
-#ifdef WINDOWS
- || home[homelen - 1] == '\\'
-#endif
- ))
+ while (homelen && ISSEP (home[homelen - 1]))
home[--homelen] = '\0';
/* Skip the leading "~/". */
-#ifdef WINDOWS
- for (++val; *val == '/' || *val == '\\'; val++)
- ;
-#else
- for (++val; *val == '/'; val++)
+ for (++val; ISSEP (*val); val++)
;
-#endif
result = xmalloc (homelen + 1 + strlen (val) + 1);
memcpy (result, home, homelen);
*pstring = result;
}
+
#ifdef WINDOWS
/* Convert "\" to "/". */
{
return 1;
}
-/* Store the value of VAL to *OUT, allowing suffixes for minutes and
- hours. */
+/* Store the value of VAL to *OUT. The value is a time period, by
+ default expressed in seconds. */
+
static int
cmd_time (const char *com, const char *val, void *closure)
{
- long result = 0;
- const char *p = val;
+ double result, mult, divider;
+ int seen_dot, seen_digit;
- /* Search for digits and construct result. */
- for (; *p && ISDIGIT (*p); p++)
- result = (10 * result) + (*p - '0');
- /* If no digits were found, or more than one character is following
- them, bail out. */
- if (p == val || (*p != '\0' && *(p + 1) != '\0'))
+ const char *p;
+ const char *end = val + strlen (val);
+
+ /* Skip trailing whitespace. */
+ while (end > val && ISSPACE (end[-1]))
+ --end;
+
+ if (val == end)
{
- printf (_("%s: Invalid specification `%s'\n"), com, val);
+ err:
+ fprintf (stderr, _("%s: Invalid time specification `%s'\n"), com, val);
return 0;
}
- /* Search for a suffix. */
- switch (TOLOWER (*p))
+
+ switch (TOLOWER (end[-1]))
{
- case '\0':
- /* None */
+ case 's':
+ --end, mult = 1; /* seconds */
break;
case 'm':
- /* Minutes */
- result *= 60;
+ --end, mult = 60; /* minutes */
break;
case 'h':
- /* Seconds */
- result *= 3600;
+ --end, mult = 3600; /* hours */
break;
case 'd':
- /* Days (overflow on 16bit machines) */
- result *= 86400L;
+ --end, mult = 86400; /* days */
break;
case 'w':
- /* Weeks :-) */
- result *= 604800L;
+ --end, mult = 604800; /* weeks */
break;
default:
- printf (_("%s: Invalid specification `%s'\n"), com, val);
- return 0;
+ /* Not a recognized suffix: treat it as part of number, and
+ assume seconds. */
+ mult = 1;
+ }
+
+ /* Skip leading and trailing whitespace. */
+ while (val < end && ISSPACE (*val))
+ ++val;
+ while (val > end && ISSPACE (end[-1]))
+ --end;
+ if (val == end)
+ goto err;
+
+ /* Poor man's strtod: */
+ result = 0;
+ seen_dot = seen_digit = 0;
+ divider = 1;
+
+ p = val;
+ while (p < end)
+ {
+ char ch = *p++;
+ if (ISDIGIT (ch))
+ {
+ if (!seen_dot)
+ result = (10 * result) + (ch - '0');
+ else
+ result += (ch - '0') / (divider *= 10);
+ seen_digit = 1;
+ }
+ else if (ch == '.')
+ {
+ if (!seen_dot)
+ seen_dot = 1;
+ else
+ goto err;
+ }
}
- *(long *)closure = result;
+ if (!seen_digit)
+ goto err;
+ result *= mult;
+ *(double *)closure = result;
return 1;
}
\f
return 1;
}
+static int
+cmd_spec_restrict_file_names (const char *com, const char *val, void *closure)
+{
+ int restrict_os = opt.restrict_files_os;
+ int restrict_ctrl = opt.restrict_files_ctrl;
+
+ const char *end = strchr (val, ',');
+ if (!end)
+ end = val + strlen (val);
+
+#define VAL_IS(string_literal) BOUNDED_EQUAL (val, end, string_literal)
+
+ if (VAL_IS ("unix"))
+ restrict_os = restrict_unix;
+ else if (VAL_IS ("windows"))
+ restrict_os = restrict_windows;
+ else if (VAL_IS ("nocontrol"))
+ restrict_ctrl = 0;
+ else
+ {
+ err:
+ fprintf (stderr, _("%s: %s: Invalid specification `%s'.\n"),
+ exec_name, com, val);
+ return 0;
+ }
+
+#undef VAL_IS
+
+ if (*end)
+ {
+ if (!strcmp (end + 1, "nocontrol"))
+ restrict_ctrl = 0;
+ else
+ goto err;
+ }
+
+ opt.restrict_files_os = restrict_os;
+ opt.restrict_files_ctrl = restrict_ctrl;
+ return 1;
+}
+
static int
cmd_spec_useragent (const char *com, const char *val, void *closure)
{
return res;
}
-#define ISODIGIT(x) ((x) >= '0' && (x) <= '7')
-
static int
check_user_specified_header (const char *s)
{
free_netrc (netrc_list);
}
FREE_MAYBE (opt.lfilename);
- xfree (opt.dir_prefix);
+ FREE_MAYBE (opt.dir_prefix);
FREE_MAYBE (opt.input_filename);
FREE_MAYBE (opt.output_document);
free_vec (opt.accepts);