]> sjero.net Git - wget/blobdiff - src/init.c
[svn] Better version of read_whole_line().
[wget] / src / init.c
index 83c954b1e0a14596aa9fe677f20354bf961018dd..b511c724859ddf3260482eb26deaaf5b45bc7c09 100644 (file)
@@ -1,5 +1,5 @@
 /* Reading/parsing the initialization file.
-   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
 
 This file is part of Wget.
 
@@ -33,6 +33,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #endif
 #include <errno.h>
 
+#ifdef WINDOWS
+# include <winsock.h>
+#else
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+#endif
+
 #ifdef HAVE_PWD_H
 #include <pwd.h>
 #endif
@@ -52,29 +60,30 @@ extern int errno;
 #define CMD_DECLARE(func) static int func \
   PARAMS ((const char *, const char *, void *))
 
+CMD_DECLARE (cmd_address);
 CMD_DECLARE (cmd_boolean);
-CMD_DECLARE (cmd_boolean);
+CMD_DECLARE (cmd_bytes);
+CMD_DECLARE (cmd_directory_vector);
+CMD_DECLARE (cmd_lockable_boolean);
 CMD_DECLARE (cmd_number);
 CMD_DECLARE (cmd_number_inf);
 CMD_DECLARE (cmd_string);
-CMD_DECLARE (cmd_vector);
-CMD_DECLARE (cmd_directory_vector);
-CMD_DECLARE (cmd_bytes);
 CMD_DECLARE (cmd_time);
+CMD_DECLARE (cmd_vector);
 
 CMD_DECLARE (cmd_spec_dirstruct);
 CMD_DECLARE (cmd_spec_dotstyle);
 CMD_DECLARE (cmd_spec_header);
 CMD_DECLARE (cmd_spec_htmlify);
 CMD_DECLARE (cmd_spec_mirror);
-CMD_DECLARE (cmd_spec_outputdocument);
 CMD_DECLARE (cmd_spec_recursive);
 CMD_DECLARE (cmd_spec_useragent);
 
-/* List of recognized commands, each consisting of name, closure and
-   function.  When adding a new command, simply add it to the list,
-   but be sure to keep the list sorted alphabetically, as comind()
-   depends on it.  */
+/* List of recognized commands, each consisting of name, closure and function.
+   When adding a new command, simply add it to the list, but be sure to keep the
+   list sorted alphabetically, as comind() depends on it.  Also, be sure to add
+   any entries that allocate memory (e.g. cmd_string and cmd_vector guys) to the
+   cleanup() function below. */
 static struct {
   char *name;
   void *closure;
@@ -87,6 +96,7 @@ static struct {
   { "backupconverted", &opt.backup_converted,  cmd_boolean },
   { "backups",         &opt.backups,           cmd_number },
   { "base",            &opt.base_href,         cmd_string },
+  { "bindaddress",     &opt.bind_address,      cmd_address },
   { "cache",           &opt.proxy_cache,       cmd_boolean },
   { "continue",                &opt.always_rest,       cmd_boolean },
   { "convertlinks",    &opt.convert_links,     cmd_boolean },
@@ -105,15 +115,18 @@ static struct {
   { "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 },
   { "ftpproxy",                &opt.ftp_proxy,         cmd_string },
   { "glob",            &opt.ftp_glob,          cmd_boolean },
   { "header",          NULL,                   cmd_spec_header },
+  { "htmlextension",   &opt.html_extension,    cmd_boolean },
   { "htmlify",         NULL,                   cmd_spec_htmlify },
   { "httppasswd",      &opt.http_passwd,       cmd_string },
   { "httpproxy",       &opt.http_proxy,        cmd_string },
   { "httpuser",                &opt.http_user,         cmd_string },
   { "ignorelength",    &opt.ignore_length,     cmd_boolean },
+  { "ignoretags",      &opt.ignore_tags,       cmd_vector },
   { "includedirectories", &opt.includes,       cmd_directory_vector },
   { "input",           &opt.input_filename,    cmd_string },
   { "killlonger",      &opt.kill_longer,       cmd_boolean },
@@ -124,9 +137,10 @@ static struct {
   { "noclobber",       &opt.noclobber,         cmd_boolean },
   { "noparent",                &opt.no_parent,         cmd_boolean },
   { "noproxy",         &opt.no_proxy,          cmd_vector },
-  { "numtries",                &opt.ntry,              cmd_number_inf }, /* deprecated */
-  { "outputdocument",  NULL,                   cmd_spec_outputdocument },
-  { "passiveftp",      &opt.ftp_pasv,          cmd_boolean },
+  { "numtries",                &opt.ntry,              cmd_number_inf },/* deprecated*/
+  { "outputdocument",  &opt.output_document,   cmd_string },
+  { "pagerequisites",  &opt.page_requisites,   cmd_boolean },
+  { "passiveftp",      &opt.ftp_pasv,          cmd_lockable_boolean },
   { "passwd",          &opt.ftp_pass,          cmd_string },
   { "proxypasswd",     &opt.proxy_passwd,      cmd_string },
   { "proxyuser",       &opt.proxy_user,        cmd_string },
@@ -151,7 +165,8 @@ static struct {
   { "useproxy",                &opt.use_proxy,         cmd_boolean },
   { "useragent",       NULL,                   cmd_spec_useragent },
   { "verbose",         &opt.verbose,           cmd_boolean },
-  { "wait",            &opt.wait,              cmd_time }
+  { "wait",            &opt.wait,              cmd_time },
+  { "waitretry",       &opt.waitretry,         cmd_time }
 };
 
 /* Return index of COM if it is a valid command, or -1 otherwise.  COM
@@ -159,7 +174,7 @@ static struct {
 static int
 comind (const char *com)
 {
-  int min = 0, max = ARRAY_SIZE (commands);
+  int min = 0, max = ARRAY_SIZE (commands) - 1;
 
   do
     {
@@ -274,6 +289,7 @@ wgetrc_file_name (void)
       file = (char *)xmalloc (strlen (home) + 1 + strlen (".wgetrc") + 1);
       sprintf (file, "%s/.wgetrc", home);
     }
+  FREE_MAYBE (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
@@ -289,7 +305,6 @@ wgetrc_file_name (void)
     }
 #endif /* WINDOWS */
 
-  FREE_MAYBE (home);
   if (!file)
     return NULL;
   if (!file_exists_p (file))
@@ -321,10 +336,7 @@ run_wgetrc (const char *file)
     {
       char *com, *val;
       int status;
-      int length = strlen (line);
 
-      if (length && line[length - 1] == '\r')
-       line[length - 1] = '\0';
       /* Parse the line.  */
       status = parse_line (line, &com, &val);
       free (line);
@@ -396,12 +408,12 @@ parse_line (const char *line, char **com, char **val)
   const char *orig_comptr, *end;
   char *new_comptr;
 
-  /* Skip spaces.  */
-  while (*p == ' ' || *p == '\t')
+  /* Skip whitespace.  */
+  while (*p && ISSPACE (*p))
     ++p;
 
   /* Don't process empty lines.  */
-  if (!*p || *p == '\n' || *p == '#')
+  if (!*p || *p == '#')
     return -1;
 
   for (orig_comptr = p; ISALPHA (*p) || *p == '_' || *p == '-'; p++)
@@ -409,6 +421,8 @@ parse_line (const char *line, char **com, char **val)
   /* The next char should be space or '='.  */
   if (!ISSPACE (*p) && (*p != '='))
     return 0;
+  /* Here we cannot use strdupdelim() as we normally would because we
+     want to skip the `-' and `_' characters in the input string.  */
   *com = (char *)xmalloc (p - orig_comptr + 1);
   for (new_comptr = *com; orig_comptr < p; orig_comptr++)
     {
@@ -434,10 +448,12 @@ parse_line (const char *line, char **com, char **val)
     }
   /* Skip spaces after '='.  */
   for (++p; ISSPACE (*p); p++);
-  /* Get the ending position.  */
-  for (end = p; *end && *end != '\n'; end++);
-  /* Allocate *val, and copy from line.  */
-  *val = strdupdelim (p, end);
+  /* Get the ending position for VAL by starting with the end of the
+     line and skipping whitespace.  */
+  end = line + strlen (line) - 1;
+  while (end > p && ISSPACE (*end))
+    --end;
+  *val = strdupdelim (p, end + 1);
   return 1;
 }
 
@@ -469,6 +485,35 @@ setval (const char *com, const char *val)
 
 static int myatoi PARAMS ((const char *s));
 
+/* Store the address (specified as hostname or dotted-quad IP address) from VAL
+   to CLOSURE.  COM is ignored, except for error messages.  */
+static int
+cmd_address (const char *com, const char *val, void *closure)
+{
+    struct sockaddr_in *sin;
+    
+    sin = (struct sockaddr_in *) malloc(sizeof *sin);
+    if (sin == NULL)
+    {
+       fprintf (stderr, _("%s: Out of memory.\n"), exec_name);
+       return 0;
+    }
+    
+    if (!store_hostaddress ((unsigned char *)&sin->sin_addr, val))
+    {
+       fprintf (stderr, _("%s: %s: Cannot convert `%s' to an IP address.\n"),
+                exec_name, com, val);
+       return 0;
+    }
+    
+    sin->sin_family = AF_INET;
+    sin->sin_port = 0;
+    
+    * (struct sockaddr_in **) closure = sin;
+    
+    return 1;
+}
+
 /* Store the boolean value from VAL to CLOSURE.  COM is ignored,
    except for error messages.  */
 static int
@@ -493,6 +538,51 @@ cmd_boolean (const char *com, const char *val, void *closure)
   return 1;
 }
 
+/* Store the lockable_boolean {2, 1, 0, -1} value from VAL to CLOSURE.  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 *closure)
+{
+  int lockable_boolean_value;
+
+  /*
+   * If a config file said "always" or "never", don't allow command line
+   * arguments to override the config file.
+   */
+  if (*(int *)closure == -1 || *(int *)closure == 2)
+    return 1;
+
+  if (!strcasecmp (val, "always")
+      || (*val == '2' && !*(val + 1)))
+    lockable_boolean_value = 2;
+  else if (!strcasecmp (val, "on")
+      || (*val == '1' && !*(val + 1)))
+    lockable_boolean_value = 1;
+  else if (!strcasecmp (val, "off")
+          || (*val == '0' && !*(val + 1)))
+    lockable_boolean_value = 0;
+  else if (!strcasecmp (val, "never")
+      || (*val == '-' && *(val + 1) == '1' && !*(val + 2)))
+    lockable_boolean_value = -1;
+  else
+    {
+      fprintf (stderr, _("%s: %s: Please specify always, on, off, "
+                        "or never.\n"),
+              exec_name, com);
+      return 0;
+    }
+
+  *(int *)closure = lockable_boolean_value;
+  return 1;
+}
+
 /* Set the non-negative integer value from VAL to CLOSURE.  With
    incorrect specification, the number remains unchanged.  */
 static int
@@ -619,7 +709,7 @@ cmd_bytes (const char *com, const char *val, void *closure)
       return 0;
     }
   /* Search for a designator.  */
-  switch (tolower (*p))
+  switch (TOLOWER (*p))
     {
     case '\0':
       /* None */
@@ -663,7 +753,7 @@ cmd_time (const char *com, const char *val, void *closure)
       return 0;
     }
   /* Search for a suffix.  */
-  switch (tolower (*p))
+  switch (TOLOWER (*p))
     {
     case '\0':
       /* None */
@@ -819,21 +909,12 @@ cmd_spec_mirror (const char *com, const char *val, void *closure)
       if (!opt.no_dirstruct)
        opt.dirstruct = 1;
       opt.timestamping = 1;
-      opt.reclevel = 0;
+      opt.reclevel = INFINITE_RECURSION;
       opt.remove_listing = 0;
     }
   return 1;
 }
 
-static int
-cmd_spec_outputdocument (const char *com, const char *val, void *closure)
-{
-  FREE_MAYBE (opt.output_document);
-  opt.output_document = xstrdup (val);
-  opt.ntry = 1;
-  return 1;
-}
-
 static int
 cmd_spec_recursive (const char *com, const char *val, void *closure)
 {
@@ -918,6 +999,8 @@ cleanup (void)
   free_vec (opt.excludes);
   free_vec (opt.includes);
   free_vec (opt.domains);
+  free_vec (opt.follow_tags);
+  free_vec (opt.ignore_tags);
   free (opt.ftp_acc);
   free (opt.ftp_pass);
   FREE_MAYBE (opt.ftp_proxy);