]> sjero.net Git - wget/blobdiff - src/main.c
[svn] Include ETA information in dot progress.
[wget] / src / main.c
index 73aba87c598dd009a31a4abaa05369fefffd2192..ecbd88083836ddec0639422850256f69c11d82cc 100644 (file)
@@ -34,26 +34,13 @@ so, delete this exception statement from your version.  */
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif /* HAVE_UNISTD_H */
-#include <sys/types.h>
-#ifdef HAVE_STRING_H
-# include <string.h>
-#else
-# include <strings.h>
-#endif /* HAVE_STRING_H */
-#ifdef HAVE_SIGNAL_H
-# include <signal.h>
-#endif
-#ifdef HAVE_NLS
-#ifdef HAVE_LOCALE_H
+#include <string.h>
+#include <signal.h>
+#if defined(HAVE_NLS) && defined(HAVE_LOCALE_H)
 # include <locale.h>
-#endif /* HAVE_LOCALE_H */
-#endif /* HAVE_NLS */
+#endif
 #include <assert.h>
-
 #include <errno.h>
-#ifndef errno
-extern int errno;
-#endif
 
 #include "wget.h"
 #include "utils.h"
@@ -64,6 +51,7 @@ extern int errno;
 #include "url.h"
 #include "progress.h"          /* for progress_handle_sigwinch */
 #include "convert.h"
+#include "http.h"              /* for save_cookies */
 
 /* On GNU system this will include system-wide getopt.h. */
 #include "getopt.h"
@@ -74,12 +62,9 @@ extern int errno;
 
 struct options opt;
 
-extern LARGE_INT total_downloaded_bytes;
 extern char *version_string;
 
-extern struct cookie_jar *wget_cookie_jar;
-
-static RETSIGTYPE redirect_output_signal PARAMS ((int));
+static void redirect_output_signal (int);
 
 const char *exec_name;
 \f
@@ -93,20 +78,7 @@ i18n_initialize (void)
   /* HAVE_NLS implies existence of functions invoked here.  */
 #ifdef HAVE_NLS
   /* Set the current locale.  */
-  /* Where possible, sets only LC_MESSAGES and LC_CTYPE.  Other
-     categories, such as numeric, time, or collation, break code that
-     parses data received from the network and relies on C-locale
-     behavior of libc functions.  For example, Solaris strptime fails
-     to recognize English month names in non-English locales, which
-     breaks http_atotm.  Some implementations of fnmatch perform
-     unwanted case folding in non-C locales.  ctype macros, while they
-     were used, provided another example against LC_ALL.  */
-#if defined(LC_MESSAGES) && defined(LC_CTYPE)
-  setlocale (LC_MESSAGES, "");
-  setlocale (LC_CTYPE, "");    /* safe because we use safe-ctype */
-#else
   setlocale (LC_ALL, "");
-#endif
   /* Set the text message domain.  */
   bindtextdomain ("wget", LOCALEDIR);
   textdomain ("wget");
@@ -115,8 +87,8 @@ i18n_initialize (void)
 \f
 /* Definition of command-line options. */
 
-static void print_help PARAMS ((void));
-static void print_version PARAMS ((void));
+static void print_help (void);
+static void print_version (void);
 
 #ifdef HAVE_SSL
 # define IF_SSL(x) x
@@ -125,9 +97,9 @@ static void print_version PARAMS ((void));
 #endif
 
 #ifdef ENABLE_DEBUG
-# define IF_DEBUG(x) x
+# define WHEN_DEBUG(x) x
 #else
-# define IF_DEBUG(x) NULL
+# define WHEN_DEBUG(x) NULL
 #endif
 
 struct cmdline_option {
@@ -150,7 +122,7 @@ struct cmdline_option {
   int argtype;                 /* for non-standard options */
 };
 
-struct cmdline_option option_data[] =
+static struct cmdline_option option_data[] =
   {
     { "accept", 'A', OPT_VALUE, "accept", -1 },
     { "append-output", 'a', OPT__APPEND_OUTPUT, NULL, required_argument },
@@ -171,7 +143,7 @@ struct cmdline_option option_data[] =
     { "convert-links", 'k', OPT_BOOLEAN, "convertlinks", -1 },
     { "cookies", 0, OPT_BOOLEAN, "cookies", -1 },
     { "cut-dirs", 0, OPT_VALUE, "cutdirs", -1 },
-    { IF_DEBUG ("debug"), 'd', OPT_BOOLEAN, "debug", -1 },
+    { WHEN_DEBUG ("debug"), 'd', OPT_BOOLEAN, "debug", -1 },
     { "delete-after", 0, OPT_BOOLEAN, "deleteafter", -1 },
     { "directories", 0, OPT_BOOLEAN, "dirstruct", -1 },
     { "directory-prefix", 'P', OPT_VALUE, "dirprefix", -1 },
@@ -267,7 +239,7 @@ struct cmdline_option option_data[] =
     { "waitretry", 0, OPT_VALUE, "waitretry", -1 },
   };
 
-#undef IF_DEBUG
+#undef WHEN_DEBUG
 #undef IF_SSL
 
 /* Return a string that contains S with "no-" prepended.  The string
@@ -651,6 +623,32 @@ Recursive accept/reject:\n"),
   exit (0);
 }
 
+/* Return a human-readable printed representation of INTERVAL,
+   measured in seconds.  */
+
+static char *
+secs_to_human_time (double interval)
+{
+  static char buf[32];
+  int secs = (int) (interval + 0.5);
+  int hours, mins, days;
+
+  days = secs / 86400, secs %= 86400;
+  hours = secs / 3600, secs %= 3600;
+  mins = secs / 60, secs %= 60;
+
+  if (days)
+    sprintf (buf, "%dd %dh %dm %ds", days, hours, mins, secs);
+  else if (hours)
+    sprintf (buf, "%dh %dm %ds", hours, mins, secs);
+  else if (mins)
+    sprintf (buf, "%dm %ds", mins, secs);
+  else
+    sprintf (buf, "%ss", print_decimal (interval));
+
+  return buf;
+}
+
 static void
 print_version (void)
 {
@@ -673,7 +671,7 @@ main (int argc, char *const *argv)
   char **url, **t;
   int i, ret, longindex;
   int nurl, status;
-  int append_to_log = 0;
+  bool append_to_log = false;
 
   i18n_initialize ();
 
@@ -732,19 +730,19 @@ main (int argc, char *const *argv)
          else
            {
              /* NEG is true for `--no-FOO' style boolean options. */
-             int neg = val & BOOLEAN_NEG_MARKER;
+             bool neg = !!(val & BOOLEAN_NEG_MARKER);
              setoptval (opt->data, neg ? "0" : "1", opt->long_name);
            }
          break;
        case OPT_FUNCALL:
          {
-           void (*func) PARAMS ((void)) = (void (*) PARAMS ((void))) opt->data;
+           void (*func) (void) = (void (*) (void)) opt->data;
            func ();
          }
          break;
        case OPT__APPEND_OUTPUT:
          setoptval ("logfile", optarg, opt->long_name);
-         append_to_log = 1;
+         append_to_log = true;
          break;
        case OPT__EXECUTE:
          run_command (optarg);
@@ -788,7 +786,7 @@ main (int argc, char *const *argv)
            /* The wgetrc commands are named noparent and noclobber,
               so we must revert the meaning of the cmdline options
               before passing the value to setoptval.  */
-           int flag = 1;
+           bool flag = true;
            if (optarg)
              flag = (*optarg == '1' || TOLOWER (*optarg) == 'y'
                      || (TOLOWER (optarg[0]) == 'o'
@@ -889,14 +887,11 @@ Can't timestamp and not clobber old files at the same time.\n"));
   /* Open the output filename if necessary.  */
   if (opt.output_document)
     {
-      extern FILE *output_stream;
-      extern int output_stream_regular;
-
       if (HYPHENP (opt.output_document))
        output_stream = stdout;
       else
        {
-         struct_stat st;
+         struct_fstat st;
          output_stream = fopen (opt.output_document,
                                 opt.always_rest ? "ab" : "wb");
          if (output_stream == NULL)
@@ -905,7 +900,7 @@ Can't timestamp and not clobber old files at the same time.\n"));
              exit (1);
            }
          if (fstat (fileno (output_stream), &st) == 0 && S_ISREG (st.st_mode))
-           output_stream_regular = 1;
+           output_stream_regular = true;
        }
     }
 
@@ -913,21 +908,25 @@ Can't timestamp and not clobber old files at the same time.\n"));
   ws_startup ();
 #endif
 
+#ifdef SIGHUP
   /* Setup the signal handler to redirect output when hangup is
      received.  */
-#ifdef HAVE_SIGNAL
   if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
     signal(SIGHUP, redirect_output_signal);
+#endif
   /* ...and do the same for SIGUSR1.  */
+#ifdef SIGUSR1
   signal (SIGUSR1, redirect_output_signal);
+#endif
+#ifdef SIGPIPE
   /* Writing to a closed socket normally signals SIGPIPE, and the
      process exits.  What we want is to ignore SIGPIPE and just check
      for the return value of write().  */
   signal (SIGPIPE, SIG_IGN);
+#endif
 #ifdef SIGWINCH
   signal (SIGWINCH, progress_handle_sigwinch);
 #endif
-#endif /* HAVE_SIGNAL */
 
   status = RETROK;             /* initialize it, just-in-case */
   /* Retrieve the URLs from argument list.  */
@@ -969,14 +968,17 @@ Can't timestamp and not clobber old files at the same time.\n"));
       || (opt.input_filename && total_downloaded_bytes != 0))
     {
       logprintf (LOG_NOTQUIET,
-                _("\nFINISHED --%s--\nDownloaded: %s bytes in %d files\n"),
-                time_str (NULL), with_thousand_seps_large (total_downloaded_bytes),
-                opt.numurls);
+                _("FINISHED --%s--\nDownloaded: %d files, %s in %s (%s)\n"),
+                time_str (NULL),
+                opt.numurls,
+                human_readable (total_downloaded_bytes),
+                secs_to_human_time (total_download_time / 1000),
+                retr_rate (total_downloaded_bytes, total_download_time));
       /* Print quota warning, if exceeded.  */
       if (opt.quota && total_downloaded_bytes > opt.quota)
        logprintf (LOG_NOTQUIET,
-                  _("Download quota (%s bytes) EXCEEDED!\n"),
-                  with_thousand_seps_large (opt.quota));
+                  _("Download quota of %s EXCEEDED!\n"),
+                  human_readable (opt.quota));
     }
 
   if (opt.cookies_output)
@@ -999,16 +1001,12 @@ Can't timestamp and not clobber old files at the same time.\n"));
     return 1;
 }
 \f
-#ifdef HAVE_SIGNAL
+#if defined(SIGHUP) || defined(SIGUSR1)
 /* Hangup signal handler.  When wget receives SIGHUP or SIGUSR1, it
    will proceed operation as usual, trying to write into a log file.
-   If that is impossible, the output will be turned off.
+   If that is impossible, the output will be turned off.  */
 
-   #### It is unsafe to do call libc functions from a signal handler.
-   What we should do is, set a global variable, and have the code in
-   log.c pick it up.  */
-
-static RETSIGTYPE
+static void
 redirect_output_signal (int sig)
 {
   const char *signal_name = (sig == SIGHUP ? "SIGHUP" :
@@ -1018,4 +1016,4 @@ redirect_output_signal (int sig)
   progress_schedule_redirect ();
   signal (sig, redirect_output_signal);
 }
-#endif /* HAVE_SIGNAL */
+#endif