]> sjero.net Git - wget/blobdiff - src/init.c
[svn] Merge of fix for bugs 20341 and 20410.
[wget] / src / init.c
index 686cac9692f7b7ad97a31bc793a4acdb6275f15a..6ad97f3645100b745090c6e21ac5789cd4b519e9 100644 (file)
@@ -1,11 +1,11 @@
 /* Reading/parsing the initialization file.
-   Copyright (C) 2005 Free Software Foundation, Inc.
+   Copyright (C) 1996-2006 Free Software Foundation, Inc.
 
 This file is part of GNU Wget.
 
 GNU Wget is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
+the Free Software Foundation; either version 3 of the License, or
 (at your option) any later version.
 
 GNU Wget is distributed in the hope that it will be useful,
@@ -14,8 +14,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with Wget; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+along with Wget.  If not, see <http://www.gnu.org/licenses/>.
 
 In addition, as a special exception, the Free Software Foundation
 gives permission to link the code of its release of Wget with the
@@ -51,6 +50,12 @@ so, delete this exception statement from your version.  */
 #include "recur.h"             /* for INFINITE_RECURSION */
 #include "convert.h"           /* for convert_cleanup */
 #include "res.h"               /* for res_cleanup */
+#include "http.h"              /* for http_cleanup */
+#include "retr.h"              /* for output_stream */
+
+#ifdef TESTING
+#include "test.h"
+#endif
 
 /* We want tilde expansion enabled only when reading `.wgetrc' lines;
    otherwise, it will be performed by the shell.  This variable will
@@ -63,7 +68,7 @@ static bool enable_tilde_expansion;
 
 CMD_DECLARE (cmd_boolean);
 CMD_DECLARE (cmd_bytes);
-CMD_DECLARE (cmd_bytes_large);
+CMD_DECLARE (cmd_bytes_sum);
 #ifdef HAVE_SSL
 CMD_DECLARE (cmd_cert_type);
 #endif
@@ -94,15 +99,16 @@ CMD_DECLARE (cmd_spec_verbose);
 /* List of recognized commands, each consisting of name, place and
    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) to the
-   cleanup() function below. */
+   command_by_name's binary search depends on it.  Also, be sure to
+   add any entries that allocate memory (e.g. cmd_string and
+   cmd_vector) to the cleanup() function below. */
 
 static struct {
   const char *name;
   void *place;
   bool (*action) (const char *, const char *, void *);
 } commands[] = {
+  /* KEEP THIS LIST ALPHABETICALLY SORTED */
   { "accept",          &opt.accepts,           cmd_vector },
   { "addhostdir",      &opt.add_hostdir,       cmd_boolean },
   { "alwaysrest",      &opt.always_rest,       cmd_boolean }, /* deprecated */
@@ -122,6 +128,7 @@ static struct {
   { "checkcertificate", &opt.check_cert,       cmd_boolean },
 #endif
   { "connecttimeout",  &opt.connect_timeout,   cmd_time },
+  { "contentdisposition", &opt.content_disposition, cmd_boolean },
   { "continue",                &opt.always_rest,       cmd_boolean },
   { "convertlinks",    &opt.convert_links,     cmd_boolean },
   { "cookies",         &opt.cookies,           cmd_boolean },
@@ -161,6 +168,7 @@ static struct {
   { "httpproxy",       &opt.http_proxy,        cmd_string },
   { "httpsproxy",      &opt.https_proxy,       cmd_string },
   { "httpuser",                &opt.http_user,         cmd_string },
+  { "ignorecase",      &opt.ignore_case,       cmd_boolean },
   { "ignorelength",    &opt.ignore_length,     cmd_boolean },
   { "ignoretags",      &opt.ignore_tags,       cmd_vector },
   { "includedirectories", &opt.includes,       cmd_directory_vector },
@@ -170,7 +178,6 @@ static struct {
 #endif
   { "input",           &opt.input_filename,    cmd_file },
   { "keepsessioncookies", &opt.keep_session_cookies, cmd_boolean },
-  { "killlonger",      &opt.kill_longer,       cmd_boolean },
   { "limitrate",       &opt.limit_rate,        cmd_bytes },
   { "loadcookies",     &opt.cookies_input,     cmd_file },
   { "logfile",         &opt.lfilename,         cmd_file },
@@ -200,7 +207,7 @@ static struct {
   { "proxypassword",   &opt.proxy_passwd,      cmd_string },
   { "proxyuser",       &opt.proxy_user,        cmd_string },
   { "quiet",           &opt.quiet,             cmd_boolean },
-  { "quota",           &opt.quota,             cmd_bytes_large },
+  { "quota",           &opt.quota,             cmd_bytes_sum },
 #ifdef HAVE_SSL
   { "randomfile",      &opt.random_file,       cmd_file },
 #endif
@@ -311,6 +318,9 @@ defaults (void)
   opt.restrict_files_os = restrict_windows;
 #endif
   opt.restrict_files_ctrl = true;
+  opt.restrict_files_case = restrict_no_case_restriction;
+
+  opt.content_disposition = true;
 }
 \f
 /* Return the user's home directory (strdup-ed), or NULL if none is
@@ -560,7 +570,7 @@ parse_line (const char *line, char **com, char **val, int *comind)
   p = line;
 
   cmdstart = p;
-  while (p < end && (ISALPHA (*p) || *p == '_' || *p == '-'))
+  while (p < end && (ISALNUM (*p) || *p == '_' || *p == '-'))
     ++p;
   cmdend = p;
 
@@ -862,7 +872,7 @@ cmd_directory_vector (const char *com, const char *val, void *place)
   return true;
 }
 
-/* Engine for cmd_bytes and cmd_bytes_large: converts a string such as
+/* Engine for cmd_bytes and cmd_bytes_sum: converts a string such as
    "100k" or "2.5G" to a floating point number.  */
 
 static bool
@@ -948,12 +958,12 @@ cmd_bytes (const char *com, const char *val, void *place)
 }
 
 /* Like cmd_bytes, but PLACE is interpreted as a pointer to
-   LARGE_INT.  It works by converting the string to double, therefore
+   SIZE_SUM.  It works by converting the string to double, therefore
    working with values up to 2^53-1 without loss of precision.  This
    value (8192 TB) is large enough to serve for a while.  */
 
 static bool
-cmd_bytes_large (const char *com, const char *val, void *place)
+cmd_bytes_sum (const char *com, const char *val, void *place)
 {
   double byte_value;
   if (!parse_bytes_helper (val, &byte_value))
@@ -962,7 +972,7 @@ cmd_bytes_large (const char *com, const char *val, void *place)
               exec_name, com, val);
       return false;
     }
-  *(LARGE_INT *)place = (LARGE_INT)byte_value;
+  *(SUM_SIZE_INT *) place = (SUM_SIZE_INT) byte_value;
   return true;
 }
 
@@ -1124,10 +1134,11 @@ cmd_spec_prefer_family (const char *com, const char *val, void *place_ignored)
     { "IPv6", prefer_ipv6 },
     { "none", prefer_none },
   };
-  int ok = decode_string (val, choices, countof (choices),
-                         (int *) &opt.prefer_family);
+  int prefer_family = prefer_ipv4;
+  int ok = decode_string (val, choices, countof (choices), &prefer_family);
   if (!ok)
     fprintf (stderr, _("%s: %s: Invalid value `%s'.\n"), exec_name, com, val);
+  opt.prefer_family = prefer_family;
   return ok;
 }
 
@@ -1173,40 +1184,47 @@ cmd_spec_restrict_file_names (const char *com, const char *val, void *place_igno
 {
   int restrict_os = opt.restrict_files_os;
   int restrict_ctrl = opt.restrict_files_ctrl;
+  int restrict_case = opt.restrict_files_case;
 
-  const char *end = strchr (val, ',');
-  if (!end)
-    end = val + strlen (val);
+  const char *end;
 
 #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
+  do
     {
-    err:
-      fprintf (stderr,
-              _("%s: %s: Invalid restriction `%s', use `unix' or `windows'.\n"),
-              exec_name, com, val);
-      return false;
+      end = strchr (val, ',');
+      if (!end)
+        end = val + strlen (val);
+      
+      if (VAL_IS ("unix"))
+        restrict_os = restrict_unix;
+      else if (VAL_IS ("windows"))
+        restrict_os = restrict_windows;
+      else if (VAL_IS ("lowercase"))
+        restrict_case = restrict_lowercase;
+      else if (VAL_IS ("uppercase"))
+        restrict_case = restrict_uppercase;
+      else if (VAL_IS ("nocontrol"))
+        restrict_ctrl = false;
+      else
+        {
+          fprintf (stderr,
+                   _("%s: %s: Invalid restriction `%s', use [unix|windows],[lowercase|uppercase],[nocontrol].\n"),
+                   exec_name, com, val);
+          return false;
+       }
+
+      if (*end) 
+       val = end + 1;
     }
+  while (*val && *end);
 
 #undef VAL_IS
 
-  if (*end)
-    {
-      if (!strcmp (end + 1, "nocontrol"))
-       restrict_ctrl = false;
-      else
-       goto err;
-    }
-
   opt.restrict_files_os = restrict_os;
   opt.restrict_files_ctrl = restrict_ctrl;
+  opt.restrict_files_case = restrict_case;
+  
   return true;
 }
 
@@ -1386,7 +1404,8 @@ check_user_specified_header (const char *s)
 {
   const char *p;
 
-  for (p = s; *p && *p != ':' && !ISSPACE (*p); p++);
+  for (p = s; *p && *p != ':' && !ISSPACE (*p); p++)
+    ;
   /* The header MUST contain `:' preceded by at least one
      non-whitespace character.  */
   if (*p != ':' || p == s)
@@ -1415,7 +1434,6 @@ decode_string (const char *val, const struct decode_item *items, int itemcount,
 
 \f
 void cleanup_html_url (void);
-void http_cleanup (void);
 
 
 /* Free the memory allocated by global variables.  */
@@ -1424,13 +1442,10 @@ cleanup (void)
 {
   /* Free external resources, close files, etc. */
 
-  {
-    extern FILE *output_stream;
-    if (output_stream)
-      fclose (output_stream);
-    /* No need to check for error because Wget flushes its output (and
-       checks for errors) after any data arrives.  */
-  }
+  if (output_stream)
+    fclose (output_stream);
+  /* No need to check for error because Wget flushes its output (and
+     checks for errors) after any data arrives.  */
 
   /* We're exiting anyway so there's no real need to call free()
      hundreds of times.  Skipping the frees will make Wget exit
@@ -1490,3 +1505,50 @@ cleanup (void)
   xfree_null (opt.passwd);
 #endif /* DEBUG_MALLOC */
 }
+\f
+/* Unit testing routines.  */
+
+#ifdef TESTING
+
+const char *
+test_cmd_spec_restrict_file_names()
+{
+  int i;
+  struct {
+    char *val;
+    int expected_restrict_files_os;
+    int expected_restrict_files_ctrl;
+    int expected_restrict_files_case;
+    bool result;
+  } test_array[] = {
+    { "windows", restrict_windows, true, restrict_no_case_restriction, true },
+    { "windows,", restrict_windows, true, restrict_no_case_restriction, true },
+    { "windows,lowercase", restrict_windows, true, restrict_lowercase, true },
+    { "unix,nocontrol,lowercase,", restrict_unix, false, restrict_lowercase, true },
+  };
+  
+  for (i = 0; i < sizeof(test_array)/sizeof(test_array[0]); ++i) 
+    {
+      bool res;
+      
+      defaults();
+      res = cmd_spec_restrict_file_names ("dummy", test_array[i].val, NULL);
+
+      /*
+      fprintf (stderr, "test_cmd_spec_restrict_file_names: TEST %d\n", i); fflush (stderr);
+      fprintf (stderr, "opt.restrict_files_os: %d\n",   opt.restrict_files_os); fflush (stderr);
+      fprintf (stderr, "opt.restrict_files_ctrl: %d\n", opt.restrict_files_ctrl); fflush (stderr);
+      fprintf (stderr, "opt.restrict_files_case: %d\n", opt.restrict_files_case); fflush (stderr);
+      */
+      mu_assert ("test_cmd_spec_restrict_file_names: wrong result", 
+                 res == test_array[i].result
+                 && opt.restrict_files_os   == test_array[i].expected_restrict_files_os 
+                 && opt.restrict_files_ctrl == test_array[i].expected_restrict_files_ctrl 
+                 && opt.restrict_files_case == test_array[i].expected_restrict_files_case);
+    }
+
+  return NULL;
+}
+
+#endif /* TESTING */
+