]> sjero.net Git - wget/blobdiff - src/init.c
[svn] Renamed the SSL switches and commands.
[wget] / src / init.c
index baafc09c7c68ab3b9ca0b37af746f78edcf54e38..c3562cc302a787c2470263827d49d38607167649 100644 (file)
@@ -1,6 +1,5 @@
 /* Reading/parsing the initialization file.
-   Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2003
-   Free Software Foundation, Inc.
+   Copyright (C) 2005 Free Software Foundation, Inc.
 
 This file is part of GNU Wget.
 
@@ -53,16 +52,15 @@ so, delete this exception statement from your version.  */
 #include "init.h"
 #include "host.h"
 #include "netrc.h"
-#include "cookies.h"           /* for cookie_jar_delete */
 #include "progress.h"
 #include "recur.h"             /* for INFINITE_RECURSION */
+#include "convert.h"           /* for convert_cleanup */
+#include "res.h"               /* for res_cleanup */
 
 #ifndef errno
 extern int errno;
 #endif
 
-extern struct cookie_jar *wget_cookie_jar;
-
 /* 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.  */
@@ -86,13 +84,20 @@ 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);
 CMD_DECLARE (cmd_spec_mirror);
+CMD_DECLARE (cmd_spec_prefer_family);
 CMD_DECLARE (cmd_spec_progress);
 CMD_DECLARE (cmd_spec_recursive);
 CMD_DECLARE (cmd_spec_restrict_file_names);
+#ifdef HAVE_SSL
+CMD_DECLARE (cmd_spec_secure_protocol);
+#endif
 CMD_DECLARE (cmd_spec_timeout);
 CMD_DECLARE (cmd_spec_useragent);
 
@@ -116,7 +121,17 @@ static struct {
   { "backups",         &opt.backups,           cmd_number },
   { "base",            &opt.base_href,         cmd_string },
   { "bindaddress",     &opt.bind_address,      cmd_string },
+#ifdef HAVE_SSL
+  { "cacertificate",   &opt.ca_cert,           cmd_file },
+#endif
   { "cache",           &opt.allow_cache,       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 },
+  { "checkcertificate", &opt.check_cert,       cmd_boolean },
+#endif
   { "connecttimeout",  &opt.connect_timeout,   cmd_time },
   { "continue",                &opt.always_rest,       cmd_boolean },
   { "convertlinks",    &opt.convert_links,     cmd_boolean },
@@ -136,13 +151,14 @@ static struct {
   { "dotspacing",      &opt.dot_spacing,       cmd_number },
   { "dotstyle",                &opt.dot_style,         cmd_string },
 #ifdef HAVE_SSL
-  { "egdfile",         &opt.sslegdsock,        cmd_file },
+  { "egdfile",         &opt.egd_file,  cmd_file },
 #endif
   { "excludedirectories", &opt.excludes,       cmd_directory_vector },
   { "excludedomains",  &opt.exclude_domains,   cmd_vector },
   { "followftp",       &opt.follow_ftp,        cmd_boolean },
   { "followtags",      &opt.follow_tags,       cmd_vector },
   { "forcehtml",       &opt.force_html,        cmd_boolean },
+  { "ftppasswd",       &opt.ftp_pass,          cmd_string },
   { "ftpproxy",                &opt.ftp_proxy,         cmd_string },
   { "glob",            &opt.ftp_glob,          cmd_boolean },
   { "header",          &opt.user_headers,      cmd_spec_header },
@@ -176,9 +192,9 @@ static struct {
   { "outputdocument",  &opt.output_document,   cmd_file },
   { "pagerequisites",  &opt.page_requisites,   cmd_boolean },
   { "passiveftp",      &opt.ftp_pasv,          cmd_lockable_boolean },
-  { "passwd",          &opt.ftp_pass,          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 },
   { "progress",                &opt.progress_type,     cmd_spec_progress },
   { "protocoldirectories", &opt.protocol_directories, cmd_boolean },
@@ -200,18 +216,12 @@ static struct {
   { "robots",          &opt.use_robots,        cmd_boolean },
   { "savecookies",     &opt.cookies_output,    cmd_file },
   { "saveheaders",     &opt.save_headers,      cmd_boolean },
+#ifdef HAVE_SSL
+  { "secureprotocol",  &opt.secure_protocol,   cmd_spec_secure_protocol },
+#endif
   { "serverresponse",  &opt.server_response,   cmd_boolean },
   { "spanhosts",       &opt.spanhost,          cmd_boolean },
   { "spider",          &opt.spider,            cmd_boolean },
-#ifdef HAVE_SSL
-  { "sslcadir",                &opt.sslcadir,          cmd_directory },
-  { "sslcafile",       &opt.sslcafile,         cmd_file },
-  { "sslcertfile",     &opt.sslcertfile,       cmd_file },
-  { "sslcertkey",      &opt.sslcertkey,        cmd_file },
-  { "sslcerttype",     &opt.sslcerttype,       cmd_number },
-  { "sslcheckcert",    &opt.sslcheckcert,      cmd_number },
-  { "sslprotocol",     &opt.sslprotocol,       cmd_number },
-#endif /* HAVE_SSL */
   { "strictcomments",  &opt.strict_comments,   cmd_boolean },
   { "timeout",         NULL,                   cmd_spec_timeout },
   { "timestamping",    &opt.timestamping,      cmd_boolean },
@@ -287,6 +297,11 @@ defaults (void)
   opt.dots_in_line = 50;
 
   opt.dns_cache = 1;
+  opt.ftp_pasv = 1;
+
+#ifdef HAVE_SSL
+  opt.check_cert = 1;
+#endif
 
   /* The default for file name restriction defaults to the OS type. */
 #if !defined(WINDOWS) && !defined(__CYGWIN__)
@@ -314,9 +329,9 @@ home_dir (void)
        return NULL;
       home = pwd->pw_dir;
 #else  /* WINDOWS */
-      home = "C:\\";
-      /* #### Maybe I should grab home_dir from registry, but the best
-        that I could get from there is user's Start menu.  It sucks!  */
+      /* Under Windows, if $HOME isn't defined, use the directory where
+         `wget.exe' resides.  */
+      home = ws_mypath ();
 #endif /* WINDOWS */
     }
 
@@ -347,27 +362,24 @@ wgetrc_file_name (void)
       return xstrdup (env);
     }
 
-#ifndef WINDOWS
   /* If that failed, try $HOME/.wgetrc.  */
   home = home_dir ();
   if (home)
-    {
-      file = (char *)xmalloc (strlen (home) + 1 + strlen (".wgetrc") + 1);
-      sprintf (file, "%s/.wgetrc", home);
-    }
+    file = aprintf ("%s/.wgetrc", home);
   xfree_null (home);
-#else  /* WINDOWS */
-  /* Under Windows, "home" is (for the purposes of this function) the
-     directory where `wget.exe' resides, and `wget.ini' will be used
-     as file name.  SYSTEM_WGETRC should not be defined under WINDOWS.
 
-     It is not as trivial as I assumed, because on 95 argv[0] is full
-     path, but on NT you get what you typed in command line.  --dbudor */
-  home = ws_mypath ();
-  if (home)
+#ifdef WINDOWS
+  /* Under Windows, if we still haven't found .wgetrc, look for the file
+     `wget.ini' in the directory where `wget.exe' resides; we do this for
+     backward compatibility with previous versions of Wget.
+     SYSTEM_WGETRC should not be defined under WINDOWS.  */
+  if (!file || !file_exists_p (file))
     {
-      file = (char *)xmalloc (strlen (home) + strlen ("wget.ini") + 1);
-      sprintf (file, "%swget.ini", home);
+      xfree_null (file);
+      file = NULL;
+      home = ws_mypath ();
+      if (home)
+       file = aprintf ("%s/wget.ini", home);
     }
 #endif /* WINDOWS */
 
@@ -402,7 +414,7 @@ run_wgetrc (const char *file)
     }
   enable_tilde_expansion = 1;
   ln = 1;
-  while ((line = read_whole_line (fp)))
+  while ((line = read_whole_line (fp)) != NULL)
     {
       char *com, *val;
       int comind, status;
@@ -691,7 +703,8 @@ static int simple_atoi PARAMS ((const char *, const char *, int *));
 static int
 cmd_number (const char *com, const char *val, void *closure)
 {
-  if (!simple_atoi (val, val + strlen (val), closure))
+  if (!simple_atoi (val, val + strlen (val), closure)
+      || *(int *) closure < 0)
     {
       fprintf (stderr, _("%s: %s: Invalid number `%s'.\n"),
               exec_name, com, val);
@@ -749,7 +762,6 @@ cmd_file (const char *com, const char *val, void *closure)
     }
   else
     {
-      char *result;
       int homelen;
       char *home = home_dir ();
       if (!home)
@@ -763,12 +775,7 @@ cmd_file (const char *com, const char *val, void *closure)
       for (++val; ISSEP (*val); val++)
        ;
 
-      result = xmalloc (homelen + 1 + strlen (val) + 1);
-      memcpy (result, home, homelen);
-      result[homelen] = '/';
-      strcpy (result + homelen + 1, val);
-
-      *pstring = result;
+      *pstring = concat_strings (home, "/", val, (char *) 0);
     }
 
 #ifdef WINDOWS
@@ -855,8 +862,8 @@ cmd_directory_vector (const char *com, const char *val, void *closure)
 
 static int simple_atof PARAMS ((const char *, const char *, double *));
 
-/* Enginge for cmd_bytes and cmd_bytes_large: converts a string such
-   as "100k" or "2.5G" to a floating point number.  */
+/* Engine for cmd_bytes and cmd_bytes_large: converts a string such as
+   "100k" or "2.5G" to a floating point number.  */
 
 static int
 parse_bytes_helper (const char *val, double *result)
@@ -905,7 +912,7 @@ parse_bytes_helper (const char *val, double *result)
   if (val == end)
     return 0;
 
-  if (!simple_atof (val, end, &number))
+  if (!simple_atof (val, end, &number) || number < 0)
     return 0;
 
   *result = number * mult;
@@ -913,7 +920,7 @@ parse_bytes_helper (const char *val, double *result)
 }
 
 /* Parse VAL as a number and set its value to CLOSURE (which should
-   point to a long int).
+   point to a wgint).
 
    By default, the value is assumed to be in bytes.  If "K", "M", or
    "G" are appended, the value is multiplied with 1<<10, 1<<20, or
@@ -936,7 +943,7 @@ cmd_bytes (const char *com, const char *val, void *closure)
               exec_name, com, val);
       return 0;
     }
-  *(long *)closure = (long)byte_value;
+  *(wgint *)closure = (wgint)byte_value;
   return 1;
 }
 
@@ -1023,6 +1030,28 @@ cmd_time (const char *com, const char *val, void *closure)
    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 *closure)
+{
+  static const struct decode_item choices[] = {
+    { "pem", cert_type_pem },
+    { "asn1", cert_type_asn1 },
+  };
+  int ok = decode_string (val, choices, countof (choices), closure);
+  if (!ok)
+    fprintf (stderr, _("%s: %s: Invalid value `%s'.\n"), exec_name, com, val);
+  return ok;
+}
+#endif
 
 static int
 cmd_spec_dirstruct (const char *com, const char *val, void *closure)
@@ -1081,6 +1110,24 @@ cmd_spec_mirror (const char *com, const char *val, void *closure)
   return 1;
 }
 
+/* Validate --prefer-family and set the choice.  Allowed values are
+   "IPv4", "IPv6", and "none".  */
+
+static int
+cmd_spec_prefer_family (const char *com, const char *val, void *closure)
+{
+  static const struct decode_item choices[] = {
+    { "IPv4", prefer_ipv4 },
+    { "IPv6", prefer_ipv6 },
+    { "none", prefer_none },
+  };
+  int ok = decode_string (val, choices, countof (choices),
+                         (int *) &opt.prefer_family);
+  if (!ok)
+    fprintf (stderr, _("%s: %s: Invalid value `%s'.\n"), exec_name, com, val);
+  return ok;
+}
+
 /* Set progress.type to VAL, but verify that it's a valid progress
    implementation before that.  */
 
@@ -1160,6 +1207,23 @@ cmd_spec_restrict_file_names (const char *com, const char *val, void *closure)
   return 1;
 }
 
+#ifdef HAVE_SSL
+static int
+cmd_spec_secure_protocol (const char *com, const char *val, void *closure)
+{
+  static const struct decode_item choices[] = {
+    { "auto", secure_protocol_auto },
+    { "sslv2", secure_protocol_sslv2 },
+    { "sslv3", secure_protocol_sslv3 },
+    { "tlsv1", secure_protocol_tlsv1 },
+  };
+  int ok = decode_string (val, choices, countof (choices), closure);
+  if (!ok)
+    fprintf (stderr, _("%s: %s: Invalid value `%s'.\n"), exec_name, com, val);
+  return ok;
+}
+#endif
+
 /* Set all three timeout values. */
 
 static int
@@ -1191,21 +1255,46 @@ cmd_spec_useragent (const char *com, const char *val, void *closure)
 \f
 /* Miscellaneous useful routines.  */
 
-/* A very simple atoi clone, more portable than strtol and friends,
-   but reports errors, unlike atoi.  Returns 1 on success, 0 on
-   failure.  In case of success, stores result to *DEST.  */
+/* A very simple atoi clone, more useful than atoi because it works on
+   delimited strings, and has error reportage.  Returns 1 on success,
+   0 on failure.  If successful, stores result to *DEST.  */
 
 static int
 simple_atoi (const char *beg, const char *end, int *dest)
 {
   int result = 0;
-  const char *p;
+  int negative = 0;
+  const char *p = beg;
 
-  if (beg == end)
+  while (p < end && ISSPACE (*p))
+    ++p;
+  if (p < end && (*p == '-' || *p == '+'))
+    {
+      negative = (*p == '-');
+      ++p;
+    }
+  if (p == end)
     return 0;
 
-  for (p = beg; p < end && ISDIGIT (*p); p++)
-    result = (10 * result) + (*p - '0');
+  /* Read negative numbers in a separate loop because the most
+     negative integer cannot be represented as a positive number.  */
+
+  if (!negative)
+    for (; p < end && ISDIGIT (*p); p++)
+      {
+       int next = (10 * result) + (*p - '0');
+       if (next < result)
+         return 0;             /* overflow */
+       result = next;
+      }
+  else
+    for (; p < end && ISDIGIT (*p); p++)
+      {
+       int next = (10 * result) - (*p - '0');
+       if (next > result)
+         return 0;             /* underflow */
+       result = next;
+      }
 
   if (p != end)
     return 0;
@@ -1223,13 +1312,22 @@ simple_atof (const char *beg, const char *end, double *dest)
 {
   double result = 0;
 
+  int negative = 0;
   int seen_dot = 0;
   int seen_digit = 0;
   double divider = 1;
 
-  const char *p;
+  const char *p = beg;
+
+  while (p < end && ISSPACE (*p))
+    ++p;
+  if (p < end && (*p == '-' || *p == '+'))
+    {
+      negative = (*p == '-');
+      ++p;
+    }
 
-  for (p = beg; p < end; p++)
+  for (; p < end; p++)
     {
       char ch = *p;
       if (ISDIGIT (ch))
@@ -1252,11 +1350,17 @@ simple_atof (const char *beg, const char *end, double *dest)
     }
   if (!seen_digit)
     return 0;
+  if (negative)
+    result = -result;
 
   *dest = result;
   return 1;
 }
 
+/* Verify that the user-specified header in S is valid.  It must
+   contain a colon preceded by non-white-space characters and must not
+   contain newlines.  */
+
 static int
 check_user_specified_header (const char *s)
 {
@@ -1272,10 +1376,25 @@ check_user_specified_header (const char *s)
     return 0;
   return 1;
 }
+
+/* Decode VAL into a number, according to ITEMS. */
+
+static int
+decode_string (const char *val, const struct decode_item *items, int itemcount,
+              int *place)
+{
+  int i;
+  for (i = 0; i < itemcount; i++)
+    if (0 == strcasecmp (val, items[i].name))
+      {
+       *place = items[i].code;
+       return 1;
+      }
+  return 0;
+}
+
 \f
 void cleanup_html_url PARAMS ((void));
-void res_cleanup PARAMS ((void));
-void downloaded_files_free PARAMS ((void));
 void http_cleanup PARAMS ((void));
 
 
@@ -1306,10 +1425,8 @@ cleanup (void)
   res_cleanup ();
   http_cleanup ();
   cleanup_html_url ();
-  downloaded_files_free ();
   host_cleanup ();
-  if (wget_cookie_jar)
-    cookie_jar_delete (wget_cookie_jar);
+  log_cleanup ();
 
   {
     extern acc_t *netrc_list;
@@ -1337,7 +1454,7 @@ cleanup (void)
   xfree_null (opt.referer);
   xfree_null (opt.http_user);
   xfree_null (opt.http_passwd);
-  xfree_null (opt.user_header);
+  free_vec (opt.user_headers);
 #ifdef HAVE_SSL
   xfree_null (opt.sslcertkey);
   xfree_null (opt.sslcertfile);