]> sjero.net Git - wget/blobdiff - src/main.c
Now --version works again.
[wget] / src / main.c
index 98c17451ec55c1c9edf654ac45e3c55a0063ad18..9b704d1fddcf6b7afbffc49e6b129ae0b0e628f3 100644 (file)
@@ -1,6 +1,7 @@
 /* Command line parsing.
    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+   2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
+   Inc.
 
 This file is part of GNU Wget.
 
@@ -32,9 +33,7 @@ as that of the covered work.  */
 
 #include <stdio.h>
 #include <stdlib.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif /* HAVE_UNISTD_H */
+#include <unistd.h>
 #include <string.h>
 #include <signal.h>
 #ifdef ENABLE_NLS
@@ -55,19 +54,29 @@ as that of the covered work.  */
 #include "convert.h"
 #include "spider.h"
 #include "http.h"               /* for save_cookies */
+#include "ptimer.h"
 
 #include <getopt.h>
 #include <getpass.h>
 #include <quote.h>
 
+#ifdef WINDOWS
+# include <io.h>
+# include <fcntl.h>
+#endif
+
 #ifdef __VMS
-#include "vms.h"
+# include "vms.h"
 #endif /* __VMS */
 
 #ifndef PATH_SEPARATOR
 # define PATH_SEPARATOR '/'
 #endif
 
+#ifndef ENABLE_IRI
+struct iri dummy_iri;
+#endif
+
 struct options opt;
 
 /* defined in version.c */
@@ -164,6 +173,7 @@ static struct cmdline_option option_data[] =
     { IF_SSL ("certificate-type"), 0, OPT_VALUE, "certificatetype", -1 },
     { IF_SSL ("check-certificate"), 0, OPT_BOOLEAN, "checkcertificate", -1 },
     { "clobber", 0, OPT__CLOBBER, NULL, optional_argument },
+    { "config", 0, OPT_VALUE, "chooseconfig", -1 },
     { "connect-timeout", 0, OPT_VALUE, "connecttimeout", -1 },
     { "continue", 'c', OPT_BOOLEAN, "continue", -1 },
     { "convert-links", 'k', OPT_BOOLEAN, "convertlinks", -1 },
@@ -383,11 +393,11 @@ init_switches (void)
 }
 
 /* Print the usage message.  */
-static void
+static int
 print_usage (int error)
 {
-  fprintf (error ? stderr : stdout, _("Usage: %s [OPTION]... [URL]...\n"),
-           exec_name);
+  return fprintf (error ? stderr : stdout,
+                  _("Usage: %s [OPTION]... [URL]...\n"), exec_name);
 }
 
 /* Print the help message, describing all the available options.  If
@@ -440,6 +450,8 @@ Logging and input file:\n"),
     N_("\
   -B,  --base=URL            resolves HTML input-file links (-i -F)\n\
                              relative to URL.\n"),
+    N_("\
+       --config=FILE         Specify config file to use.\n"), 
     "\n",
 
     N_("\
@@ -452,7 +464,7 @@ Download:\n"),
   -O,  --output-document=FILE    write documents to FILE.\n"),
     N_("\
   -nc, --no-clobber              skip downloads that would download to\n\
-                                 existing files.\n"),
+                                 existing files (overwriting them).\n"),
     N_("\
   -c,  --continue                resume getting a partially-downloaded file.\n"),
     N_("\
@@ -697,12 +709,15 @@ Recursive accept/reject:\n"),
 
   size_t i;
 
-  printf (_("GNU Wget %s, a non-interactive network retriever.\n"),
-          version_string);
-  print_usage (0);
+  if (printf (_("GNU Wget %s, a non-interactive network retriever.\n"),
+              version_string))
+    exit (3);
+  if (print_usage (0) < 0)
+    exit (3);
 
   for (i = 0; i < countof (help); i++)
-    fputs (_(help[i]), stdout);
+    if (fputs (_(help[i]), stdout) < 0)
+      exit (3);
 
   exit (0);
 }
@@ -737,9 +752,9 @@ static char *
 prompt_for_password (void)
 {
   if (opt.user)
-    printf (_("Password for user %s: "), quote (opt.user));
+    fprintf (stderr, _("Password for user %s: "), quote (opt.user));
   else
-    printf (_("Password: "));
+    fprintf (stderr, _("Password: "));
   return getpass("");
 }
 
@@ -747,7 +762,7 @@ prompt_for_password (void)
    to at most line_length. prefix is printed on the first line
    and an appropriate number of spaces are added on subsequent
    lines.*/
-static void
+static int
 format_and_print_line (const char *prefix, const char *line,
                        int line_length)
 {
@@ -762,7 +777,8 @@ format_and_print_line (const char *prefix, const char *line,
   if (line_length <= 0)
     line_length = MAX_CHARS_PER_LINE - TABULATION;
 
-  printf ("%s", prefix);
+  if (printf ("%s", prefix) < 0)
+    return -1;
   remaining_chars = line_length;
   /* We break on spaces. */
   token = strtok (line_dup, " ");
@@ -773,17 +789,21 @@ format_and_print_line (const char *prefix, const char *line,
          token on the next line. */
       if (remaining_chars <= strlen (token))
         {
-          printf ("\n%*c", TABULATION, ' ');
+          if (printf ("\n%*c", TABULATION, ' ') < 0)
+            return -1;
           remaining_chars = line_length - TABULATION;
         }
-      printf ("%s ", token);
+      if (printf ("%s ", token) < 0)
+        return -1;
       remaining_chars -= strlen (token) + 1;  /* account for " " */
       token = strtok (NULL, " ");
     }
 
-  printf ("\n");
+  if (printf ("\n") < 0)
+    return -1;
 
   xfree (line_dup);
+  return 0;
 }
 
 static void
@@ -796,72 +816,91 @@ print_version (void)
   char *env_wgetrc, *user_wgetrc;
   int i;
 
-  printf (_("GNU Wget %s built on %s.\n\n"), version_string, OS_TYPE);
+  if (printf (_("GNU Wget %s built on %s.\n\n"), version_string, OS_TYPE) < 0)
+    exit (3);
 
   for (i = 0; compiled_features[i] != NULL; )
     {
       int line_length = MAX_CHARS_PER_LINE;
       while ((line_length > 0) && (compiled_features[i] != NULL))
         {
-          printf ("%s ", compiled_features[i]);
+          if (printf ("%s ", compiled_features[i]) < 0)
+            exit (3);
           line_length -= strlen (compiled_features[i]) + 2;
           i++;
         }
-      printf ("\n");
+      if (printf ("\n") < 0)
+        exit (3);
     }
-  printf ("\n");
+  if (printf ("\n") < 0)
+    exit (3);
 
   /* Handle the case when $WGETRC is unset and $HOME/.wgetrc is
      absent. */
-  printf ("%s\n", wgetrc_title);
+  if (printf ("%s\n", wgetrc_title) < 0)
+    exit (3);
+
   env_wgetrc = wgetrc_env_file_name ();
   if (env_wgetrc && *env_wgetrc)
     {
-      printf (_("    %s (env)\n"), env_wgetrc);
+      if (printf (_("    %s (env)\n"), env_wgetrc) < 0)
+        exit (3);
       xfree (env_wgetrc);
     }
   user_wgetrc = wgetrc_user_file_name ();
   if (user_wgetrc)
     {
-      printf (_("    %s (user)\n"), user_wgetrc);
+      if (printf (_("    %s (user)\n"), user_wgetrc) < 0)
+        exit (3);
       xfree (user_wgetrc);
     }
 #ifdef SYSTEM_WGETRC
-  printf (_("    %s (system)\n"), SYSTEM_WGETRC);
+  if (printf (_("    %s (system)\n"), SYSTEM_WGETRC) < 0)
+    exit (3);
 #endif
 
 #ifdef ENABLE_NLS
-  format_and_print_line (locale_title,
+  if (format_and_print_line (locale_title,
                         LOCALEDIR,
-                        MAX_CHARS_PER_LINE);
+                             MAX_CHARS_PER_LINE) < 0)
+    exit (3);
 #endif /* def ENABLE_NLS */
 
   if (compilation_string != NULL)
-    format_and_print_line (compile_title,
-                           compilation_string,
-                           MAX_CHARS_PER_LINE);
+    if (format_and_print_line (compile_title,
+                               compilation_string,
+                               MAX_CHARS_PER_LINE) < 0)
+      exit (3);
 
   if (link_string != NULL)
-    format_and_print_line (link_title,
-                           link_string,
-                           MAX_CHARS_PER_LINE);
+    if (format_and_print_line (link_title,
+                               link_string,
+                               MAX_CHARS_PER_LINE) < 0)
+      exit (3);
+
+  if (printf ("\n") < 0)
+    exit (3);
 
-  printf ("\n");
   /* TRANSLATORS: When available, an actual copyright character
      (cirle-c) should be used in preference to "(C)". */
-  fputs (_("\
-Copyright (C) 2009 Free Software Foundation, Inc.\n"), stdout);
-  fputs (_("\
+  if (fputs (_("\
+Copyright (C) 2009 Free Software Foundation, Inc.\n"), stdout) < 0)
+    exit (3);
+  if (fputs (_("\
 License GPLv3+: GNU GPL version 3 or later\n\
 <http://www.gnu.org/licenses/gpl.html>.\n\
 This is free software: you are free to change and redistribute it.\n\
-There is NO WARRANTY, to the extent permitted by law.\n"), stdout);
+There is NO WARRANTY, to the extent permitted by law.\n"), stdout) < 0)
+    exit (3);
   /* TRANSLATORS: When available, please use the proper diacritics for
      names such as this one. See en_US.po for reference. */
-  fputs (_("\nOriginally written by Hrvoje Niksic <hniksic@xemacs.org>.\n"),
-         stdout);
-  fputs (_("Please send bug reports and questions to <bug-wget@gnu.org>.\n"),
-         stdout);
+  if (fputs (_("\nOriginally written by Hrvoje Niksic <hniksic@xemacs.org>.\n"),
+             stdout) < 0)
+    exit (3);
+  if (fputs (_("Please send bug reports and questions to <bug-wget@gnu.org>.\n"),
+             stdout) < 0)
+    exit (3);
+
   exit (0);
 }
 
@@ -875,8 +914,13 @@ main (int argc, char **argv)
   int nurl;
   bool append_to_log = false;
 
+  total_downloaded_bytes = 0;
+
   program_name = argv[0];
 
+  struct ptimer *timer = ptimer_new ();
+  double start_time = ptimer_measure (timer);
+
   i18n_initialize ();
 
   /* Construct the name of the executable, without the directory part.  */
@@ -896,10 +940,46 @@ main (int argc, char **argv)
   windows_main ((char **) &exec_name);
 #endif
 
-  /* Set option defaults; read the system wgetrc and ~/.wgetrc.  */
-  initialize ();
+  /* Load the hard-coded defaults.  */
+  defaults ();
 
   init_switches ();
+
+  /* This seperate getopt_long is needed to find the user config
+     and parse it before the other user options. */
+  longindex = -1;
+  int retconf;
+  bool use_userconfig = false;
+
+  while ((retconf = getopt_long (argc, argv,
+                                short_options, long_options, &longindex)) != -1)
+    {
+      int confval;
+      bool userrc_ret = true;
+      struct cmdline_option *config_opt;
+      confval = long_options[longindex].val;
+      config_opt = &option_data[confval & ~BOOLEAN_NEG_MARKER];
+      if (strcmp (config_opt->long_name, "config") == 0)
+        {
+          userrc_ret &= run_wgetrc (optarg);
+          use_userconfig = true;
+        }
+      if (!userrc_ret)
+        {
+          printf ("Exiting due to error in %s\n", optarg);
+          exit (2);
+        }
+      else
+        break;
+    }
+
+  /* If the user did not specify a config, read the system wgetrc and ~/.wgetrc. */
+  if (use_userconfig == false)
+    initialize ();
+
+  opterr = 0;
+  optind = 0;
+
   longindex = -1;
   while ((ret = getopt_long (argc, argv,
                              short_options, long_options, &longindex)) != -1)
@@ -1019,6 +1099,14 @@ main (int argc, char **argv)
   /* All user options have now been processed, so it's now safe to do
      interoption dependency checks. */
 
+  if (opt.noclobber && opt.convert_links)
+    {
+      fprintf (stderr,
+               _("Both --no-clobber and --convert-links were specified,"
+                 "only --convert-links will be used.\n"));
+      opt.noclobber = false;
+    }
+
   if (opt.reclevel == 0)
       opt.reclevel = INFINITE_RECURSION; /* see recur.h for commentary */
 
@@ -1129,6 +1217,7 @@ for details.\n\n"));
         opt.encoding_remote = NULL;
     }
 #else
+  memset (&dummy_iri, 0, sizeof (dummy_iri));
   if (opt.enable_iri || opt.locale || opt.encoding_remote)
     {
       /* sXXXav : be more specific... */
@@ -1192,14 +1281,7 @@ for details.\n\n"));
       if (HYPHENP (opt.output_document))
         {
 #ifdef WINDOWS
-          FILE *result;
-          result = freopen ("CONOUT$", "wb", stdout);
-          if (result == NULL)
-            {
-              logputs (LOG_NOTQUIET, _("\
-WARNING: Can't reopen standard output in binary mode;\n\
-         downloaded file may contain inappropriate line endings.\n"));
-            }
+          _setmode (_fileno (stdout), _O_BINARY);
 #endif
           output_stream = stdout;
         }
@@ -1290,6 +1372,7 @@ outputting to a regular file.\n"));
           char *error = url_error (*t, url_err);
           logprintf (LOG_NOTQUIET, "%s: %s.\n",*t, error);
           xfree (error);
+          inform_exit_status (URLERROR);
         }
       else
         {
@@ -1330,7 +1413,9 @@ outputting to a regular file.\n"));
   if (opt.input_filename)
     {
       int count;
-      retrieve_from_file (opt.input_filename, opt.force_html, &count);
+      int status;
+      status = retrieve_from_file (opt.input_filename, opt.force_html, &count);
+      inform_exit_status (status);
       if (!count)
         logprintf (LOG_NOTQUIET, _("No URLs found in %s.\n"),
                    opt.input_filename);
@@ -1347,13 +1432,23 @@ outputting to a regular file.\n"));
       &&
       total_downloaded_bytes != 0)
     {
+      double end_time = ptimer_measure (timer);
+      ptimer_destroy (timer);
+
+      char *wall_time = xstrdup (secs_to_human_time (end_time - start_time));
+      char *download_time = xstrdup (secs_to_human_time (total_download_time));
       logprintf (LOG_NOTQUIET,
-                 _("FINISHED --%s--\nDownloaded: %d files, %s in %s (%s)\n"),
-                 datetime_str (time (NULL)),
-                 numurls,
-                 human_readable (total_downloaded_bytes),
-                 secs_to_human_time (total_download_time),
-                 retr_rate (total_downloaded_bytes, total_download_time));
+                _("FINISHED --%s--\nTotal wall clock time: %s\n"
+                  "Downloaded: %d files, %s in %s (%s)\n"),
+                datetime_str (time (NULL)),
+                wall_time,
+                numurls,
+                human_readable (total_downloaded_bytes),
+                download_time,
+                retr_rate (total_downloaded_bytes, total_download_time));
+      xfree (wall_time);
+      xfree (download_time);
+
       /* Print quota warning, if exceeded.  */
       if (opt.quota && total_downloaded_bytes > opt.quota)
         logprintf (LOG_NOTQUIET,