mirror of
https://github.com/moparisthebest/wget
synced 2024-07-03 16:38:41 -04:00
[svn] Big progress bar update.
Published in <sxsn11ehyn1.fsf@florida.arsdigita.de>.
This commit is contained in:
parent
4d352013ac
commit
cdcf67a5bd
@ -1,3 +1,7 @@
|
|||||||
|
2001-11-23 Hrvoje Niksic <hniksic@arsdigita.com>
|
||||||
|
|
||||||
|
* configure.in: Check for sys/ioctl.h.
|
||||||
|
|
||||||
2001-11-22 Herold Heiko <Heiko.Herold@previnet.it>
|
2001-11-22 Herold Heiko <Heiko.Herold@previnet.it>
|
||||||
|
|
||||||
* windows/Readme
|
* windows/Readme
|
||||||
|
@ -155,7 +155,7 @@ dnl
|
|||||||
dnl Checks for headers
|
dnl Checks for headers
|
||||||
dnl
|
dnl
|
||||||
AC_CHECK_HEADERS(string.h stdarg.h unistd.h sys/time.h utime.h sys/utime.h)
|
AC_CHECK_HEADERS(string.h stdarg.h unistd.h sys/time.h utime.h sys/utime.h)
|
||||||
AC_CHECK_HEADERS(sys/select.h sys/utsname.h pwd.h signal.h)
|
AC_CHECK_HEADERS(sys/ioctl.h sys/select.h sys/utsname.h pwd.h signal.h)
|
||||||
AC_HEADER_TIME
|
AC_HEADER_TIME
|
||||||
|
|
||||||
dnl
|
dnl
|
||||||
|
@ -1,3 +1,31 @@
|
|||||||
|
2001-11-23 Hrvoje Niksic <hniksic@arsdigita.com>
|
||||||
|
|
||||||
|
* utils.c (determine_screen_width): New function.
|
||||||
|
|
||||||
|
* main.c (main): New option `--progress=TYPE'.
|
||||||
|
(main): Implement compatibility with the old option `--dot-style'.
|
||||||
|
|
||||||
|
* init.c: Removed cmd_spec_dotstyle -- that logic is now in
|
||||||
|
dp_set_params.
|
||||||
|
(cmd_spec_progress): New function.
|
||||||
|
|
||||||
|
* retr.c (get_contents): Use the progress_* functions instead of
|
||||||
|
the old show_progress().
|
||||||
|
(show_progress): Removed.
|
||||||
|
(rate): Print "xxxx.xx K/s" instead of "KB/s". Ditto for MB/s,
|
||||||
|
etc.
|
||||||
|
|
||||||
|
* progress.c (set_progress_implementation): New function.
|
||||||
|
(valid_progress_implementation_p): Ditto.
|
||||||
|
(progress_create): Ditto.
|
||||||
|
(progress_update): Ditto.
|
||||||
|
(progress_finish): Ditto.
|
||||||
|
(dp_create): Ditto.
|
||||||
|
(dp_update): Ditto.
|
||||||
|
(dp_finish): Ditto.
|
||||||
|
(dp_set_params): Ditto.
|
||||||
|
(print_elapsed): Ditto.
|
||||||
|
|
||||||
2001-11-22 Hrvoje Niksic <hniksic@arsdigita.com>
|
2001-11-22 Hrvoje Niksic <hniksic@arsdigita.com>
|
||||||
|
|
||||||
* retr.c (show_progress): Use it.
|
* retr.c (show_progress): Use it.
|
||||||
|
@ -65,8 +65,8 @@ GETOPT_OBJ = @GETOPT_OBJ@
|
|||||||
OBJ = $(ALLOCA) cmpt$o connect$o cookies$o fnmatch$o ftp$o \
|
OBJ = $(ALLOCA) cmpt$o connect$o cookies$o fnmatch$o ftp$o \
|
||||||
ftp-basic$o ftp-ls$o $(OPIE_OBJ) $(GETOPT_OBJ) hash$o \
|
ftp-basic$o ftp-ls$o $(OPIE_OBJ) $(GETOPT_OBJ) hash$o \
|
||||||
headers$o host$o html-parse$o html-url$o http$o init$o \
|
headers$o host$o html-parse$o html-url$o http$o init$o \
|
||||||
log$o main$o $(MD5_OBJ) netrc$o rbuf$o recur$o res$o \
|
log$o main$o $(MD5_OBJ) netrc$o progress$o rbuf$o recur$o \
|
||||||
retr$o safe-ctype$o snprintf$o $(SSL_OBJ) url$o \
|
res$o retr$o safe-ctype$o snprintf$o $(SSL_OBJ) url$o \
|
||||||
utils$o version$o
|
utils$o version$o
|
||||||
|
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
|
@ -180,6 +180,9 @@ char *alloca ();
|
|||||||
/* Define if you have the <sys/utime.h> header file. */
|
/* Define if you have the <sys/utime.h> header file. */
|
||||||
#undef HAVE_SYS_UTIME_H
|
#undef HAVE_SYS_UTIME_H
|
||||||
|
|
||||||
|
/* Define if you have the <sys/ioctl.h> header file. */
|
||||||
|
#undef HAVE_SYS_IOCTL_H
|
||||||
|
|
||||||
/* Define if you have the <sys/select.h> header file. */
|
/* Define if you have the <sys/select.h> header file. */
|
||||||
#undef HAVE_SYS_SELECT_H
|
#undef HAVE_SYS_SELECT_H
|
||||||
|
|
||||||
|
73
src/init.c
73
src/init.c
@ -82,10 +82,10 @@ CMD_DECLARE (cmd_time);
|
|||||||
CMD_DECLARE (cmd_vector);
|
CMD_DECLARE (cmd_vector);
|
||||||
|
|
||||||
CMD_DECLARE (cmd_spec_dirstruct);
|
CMD_DECLARE (cmd_spec_dirstruct);
|
||||||
CMD_DECLARE (cmd_spec_dotstyle);
|
|
||||||
CMD_DECLARE (cmd_spec_header);
|
CMD_DECLARE (cmd_spec_header);
|
||||||
CMD_DECLARE (cmd_spec_htmlify);
|
CMD_DECLARE (cmd_spec_htmlify);
|
||||||
CMD_DECLARE (cmd_spec_mirror);
|
CMD_DECLARE (cmd_spec_mirror);
|
||||||
|
CMD_DECLARE (cmd_spec_progress);
|
||||||
CMD_DECLARE (cmd_spec_recursive);
|
CMD_DECLARE (cmd_spec_recursive);
|
||||||
CMD_DECLARE (cmd_spec_useragent);
|
CMD_DECLARE (cmd_spec_useragent);
|
||||||
|
|
||||||
@ -122,7 +122,6 @@ static struct {
|
|||||||
{ "dotbytes", &opt.dot_bytes, cmd_bytes },
|
{ "dotbytes", &opt.dot_bytes, cmd_bytes },
|
||||||
{ "dotsinline", &opt.dots_in_line, cmd_number },
|
{ "dotsinline", &opt.dots_in_line, cmd_number },
|
||||||
{ "dotspacing", &opt.dot_spacing, cmd_number },
|
{ "dotspacing", &opt.dot_spacing, cmd_number },
|
||||||
{ "dotstyle", NULL, cmd_spec_dotstyle },
|
|
||||||
{ "excludedirectories", &opt.excludes, cmd_directory_vector },
|
{ "excludedirectories", &opt.excludes, cmd_directory_vector },
|
||||||
{ "excludedomains", &opt.exclude_domains, cmd_vector },
|
{ "excludedomains", &opt.exclude_domains, cmd_vector },
|
||||||
{ "followftp", &opt.follow_ftp, cmd_boolean },
|
{ "followftp", &opt.follow_ftp, cmd_boolean },
|
||||||
@ -156,6 +155,7 @@ static struct {
|
|||||||
{ "pagerequisites", &opt.page_requisites, cmd_boolean },
|
{ "pagerequisites", &opt.page_requisites, cmd_boolean },
|
||||||
{ "passiveftp", &opt.ftp_pasv, cmd_lockable_boolean },
|
{ "passiveftp", &opt.ftp_pasv, cmd_lockable_boolean },
|
||||||
{ "passwd", &opt.ftp_pass, cmd_string },
|
{ "passwd", &opt.ftp_pass, cmd_string },
|
||||||
|
{ "progress", NULL, cmd_spec_progress },
|
||||||
{ "proxypasswd", &opt.proxy_passwd, cmd_string },
|
{ "proxypasswd", &opt.proxy_passwd, cmd_string },
|
||||||
{ "proxyuser", &opt.proxy_user, cmd_string },
|
{ "proxyuser", &opt.proxy_user, cmd_string },
|
||||||
{ "quiet", &opt.quiet, cmd_boolean },
|
{ "quiet", &opt.quiet, cmd_boolean },
|
||||||
@ -249,6 +249,7 @@ defaults (void)
|
|||||||
|
|
||||||
opt.remove_listing = 1;
|
opt.remove_listing = 1;
|
||||||
|
|
||||||
|
set_progress_implementation ("dot");
|
||||||
opt.dot_bytes = 1024;
|
opt.dot_bytes = 1024;
|
||||||
opt.dot_spacing = 10;
|
opt.dot_spacing = 10;
|
||||||
opt.dots_in_line = 50;
|
opt.dots_in_line = 50;
|
||||||
@ -870,61 +871,6 @@ cmd_spec_dirstruct (const char *com, const char *val, void *closure)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
cmd_spec_dotstyle (const char *com, const char *val, void *closure)
|
|
||||||
{
|
|
||||||
/* Retrieval styles. */
|
|
||||||
if (!strcasecmp (val, "default"))
|
|
||||||
{
|
|
||||||
/* Default style: 1K dots, 10 dots in a cluster, 50 dots in a
|
|
||||||
line. */
|
|
||||||
opt.dot_bytes = 1024;
|
|
||||||
opt.dot_spacing = 10;
|
|
||||||
opt.dots_in_line = 50;
|
|
||||||
}
|
|
||||||
else if (!strcasecmp (val, "binary"))
|
|
||||||
{
|
|
||||||
/* "Binary" retrieval: 8K dots, 16 dots in a cluster, 48 dots
|
|
||||||
(384K) in a line. */
|
|
||||||
opt.dot_bytes = 8192;
|
|
||||||
opt.dot_spacing = 16;
|
|
||||||
opt.dots_in_line = 48;
|
|
||||||
}
|
|
||||||
else if (!strcasecmp (val, "mega"))
|
|
||||||
{
|
|
||||||
/* "Mega" retrieval, for retrieving very long files; each dot is
|
|
||||||
64K, 8 dots in a cluster, 6 clusters (3M) in a line. */
|
|
||||||
opt.dot_bytes = 65536L;
|
|
||||||
opt.dot_spacing = 8;
|
|
||||||
opt.dots_in_line = 48;
|
|
||||||
}
|
|
||||||
else if (!strcasecmp (val, "giga"))
|
|
||||||
{
|
|
||||||
/* "Giga" retrieval, for retrieving very very *very* long files;
|
|
||||||
each dot is 1M, 8 dots in a cluster, 4 clusters (32M) in a
|
|
||||||
line. */
|
|
||||||
opt.dot_bytes = (1L << 20);
|
|
||||||
opt.dot_spacing = 8;
|
|
||||||
opt.dots_in_line = 32;
|
|
||||||
}
|
|
||||||
else if (!strcasecmp (val, "micro"))
|
|
||||||
{
|
|
||||||
/* "Micro" retrieval, for retrieving very small files (and/or
|
|
||||||
slow connections); each dot is 128 bytes, 8 dots in a
|
|
||||||
cluster, 6 clusters (6K) in a line. */
|
|
||||||
opt.dot_bytes = 128;
|
|
||||||
opt.dot_spacing = 8;
|
|
||||||
opt.dots_in_line = 48;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf (stderr, _("%s: %s: Invalid specification `%s'.\n"),
|
|
||||||
exec_name, com, val);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cmd_spec_header (const char *com, const char *val, void *closure)
|
cmd_spec_header (const char *com, const char *val, void *closure)
|
||||||
{
|
{
|
||||||
@ -984,6 +930,19 @@ cmd_spec_mirror (const char *com, const char *val, void *closure)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmd_spec_progress (const char *com, const char *val, void *closure)
|
||||||
|
{
|
||||||
|
if (!valid_progress_implementation_p (val))
|
||||||
|
{
|
||||||
|
fprintf (stderr, _("%s: %s: Invalid progress type `%s'.\n"),
|
||||||
|
exec_name, com, val);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
set_progress_implementation (val);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cmd_spec_recursive (const char *com, const char *val, void *closure)
|
cmd_spec_recursive (const char *com, const char *val, void *closure)
|
||||||
{
|
{
|
||||||
|
20
src/main.c
20
src/main.c
@ -51,6 +51,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
#include "host.h"
|
#include "host.h"
|
||||||
#include "cookies.h"
|
#include "cookies.h"
|
||||||
#include "url.h"
|
#include "url.h"
|
||||||
|
#include "progress.h" /* for progress_handle_sigwinch */
|
||||||
|
|
||||||
/* On GNU system this will include system-wide getopt.h. */
|
/* On GNU system this will include system-wide getopt.h. */
|
||||||
#include "getopt.h"
|
#include "getopt.h"
|
||||||
@ -165,7 +166,7 @@ Download:\n\
|
|||||||
-O --output-document=FILE write documents to FILE.\n\
|
-O --output-document=FILE write documents to FILE.\n\
|
||||||
-nc, --no-clobber don\'t clobber existing files or use .# suffixes.\n\
|
-nc, --no-clobber don\'t clobber existing files or use .# suffixes.\n\
|
||||||
-c, --continue resume getting a partially-downloaded file.\n\
|
-c, --continue resume getting a partially-downloaded file.\n\
|
||||||
--dot-style=STYLE set retrieval display style.\n\
|
--progress=TYPE select progress gauge type.\n\
|
||||||
-N, --timestamping don\'t re-retrieve files unless newer than local.\n\
|
-N, --timestamping don\'t re-retrieve files unless newer than local.\n\
|
||||||
-S, --server-response print server response.\n\
|
-S, --server-response print server response.\n\
|
||||||
--spider don\'t download anything.\n\
|
--spider don\'t download anything.\n\
|
||||||
@ -312,6 +313,7 @@ main (int argc, char *const *argv)
|
|||||||
{ "no", required_argument, NULL, 'n' },
|
{ "no", required_argument, NULL, 'n' },
|
||||||
{ "output-document", required_argument, NULL, 'O' },
|
{ "output-document", required_argument, NULL, 'O' },
|
||||||
{ "output-file", required_argument, NULL, 'o' },
|
{ "output-file", required_argument, NULL, 'o' },
|
||||||
|
{ "progress", required_argument, NULL, 163 },
|
||||||
{ "proxy", required_argument, NULL, 'Y' },
|
{ "proxy", required_argument, NULL, 'Y' },
|
||||||
{ "proxy-passwd", required_argument, NULL, 144 },
|
{ "proxy-passwd", required_argument, NULL, 144 },
|
||||||
{ "proxy-user", required_argument, NULL, 143 },
|
{ "proxy-user", required_argument, NULL, 143 },
|
||||||
@ -499,7 +501,13 @@ GNU General Public License for more details.\n"));
|
|||||||
setval ("header", optarg);
|
setval ("header", optarg);
|
||||||
break;
|
break;
|
||||||
case 134:
|
case 134:
|
||||||
setval ("dotstyle", optarg);
|
/* Supported for compatibility; --dot-style=foo equivalent
|
||||||
|
to --progress=dot:foo. */
|
||||||
|
{
|
||||||
|
char *tmp = alloca (3 + 1 + strlen (optarg));
|
||||||
|
sprintf (tmp, "dot:%s", optarg);
|
||||||
|
setval ("progress", tmp);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 135:
|
case 135:
|
||||||
setval ("htmlify", optarg);
|
setval ("htmlify", optarg);
|
||||||
@ -531,6 +539,9 @@ GNU General Public License for more details.\n"));
|
|||||||
case 162:
|
case 162:
|
||||||
setval ("savecookies", optarg);
|
setval ("savecookies", optarg);
|
||||||
break;
|
break;
|
||||||
|
case 163:
|
||||||
|
setval ("progress", optarg);
|
||||||
|
break;
|
||||||
case 157:
|
case 157:
|
||||||
setval ("referer", optarg);
|
setval ("referer", optarg);
|
||||||
break;
|
break;
|
||||||
@ -784,6 +795,9 @@ Can't timestamp and not clobber old files at the same time.\n"));
|
|||||||
process exits. What we want is to ignore SIGPIPE and just check
|
process exits. What we want is to ignore SIGPIPE and just check
|
||||||
for the return value of write(). */
|
for the return value of write(). */
|
||||||
signal (SIGPIPE, SIG_IGN);
|
signal (SIGPIPE, SIG_IGN);
|
||||||
|
#ifdef SIGWINCH
|
||||||
|
signal (SIGWINCH, progress_handle_sigwinch);
|
||||||
|
#endif
|
||||||
#endif /* HAVE_SIGNAL */
|
#endif /* HAVE_SIGNAL */
|
||||||
|
|
||||||
status = RETROK; /* initialize it, just-in-case */
|
status = RETROK; /* initialize it, just-in-case */
|
||||||
@ -860,11 +874,11 @@ Can't timestamp and not clobber old files at the same time.\n"));
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_SIGNAL
|
||||||
/* Hangup signal handler. When wget receives SIGHUP or SIGUSR1, it
|
/* Hangup signal handler. When wget receives SIGHUP or SIGUSR1, it
|
||||||
will proceed operation as usual, trying to write into a log file.
|
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. */
|
||||||
|
|
||||||
#ifdef HAVE_SIGNAL
|
|
||||||
static RETSIGTYPE
|
static RETSIGTYPE
|
||||||
redirect_output_signal (int sig)
|
redirect_output_signal (int sig)
|
||||||
{
|
{
|
||||||
|
584
src/progress.c
Normal file
584
src/progress.c
Normal file
@ -0,0 +1,584 @@
|
|||||||
|
/* Download progress.
|
||||||
|
Copyright (C) 2001 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
|
||||||
|
\(at your option) any later version.
|
||||||
|
|
||||||
|
GNU Wget is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
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. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
#endif /* HAVE_STRING_H */
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "wget.h"
|
||||||
|
#include "progress.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "retr.h"
|
||||||
|
|
||||||
|
struct progress_implementation {
|
||||||
|
char *name;
|
||||||
|
void *(*create) (long, long);
|
||||||
|
void (*update) (void *, long);
|
||||||
|
void (*finish) (void *);
|
||||||
|
void (*set_params) (const char *);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Necessary forward declarations. */
|
||||||
|
|
||||||
|
static void *dp_create PARAMS ((long, long));
|
||||||
|
static void dp_update PARAMS ((void *, long));
|
||||||
|
static void dp_finish PARAMS ((void *));
|
||||||
|
static void dp_set_params PARAMS ((const char *));
|
||||||
|
|
||||||
|
static void *bar_create PARAMS ((long, long));
|
||||||
|
static void bar_update PARAMS ((void *, long));
|
||||||
|
static void bar_finish PARAMS ((void *));
|
||||||
|
static void bar_set_params PARAMS ((const char *));
|
||||||
|
|
||||||
|
static struct progress_implementation implementations[] = {
|
||||||
|
{ "dot", dp_create, dp_update, dp_finish, dp_set_params },
|
||||||
|
{ "bar", bar_create, bar_update, bar_finish, bar_set_params }
|
||||||
|
};
|
||||||
|
static struct progress_implementation *current_impl;
|
||||||
|
|
||||||
|
/* Return non-zero if NAME names a valid progress bar implementation.
|
||||||
|
The characters after the first : will be ignored. */
|
||||||
|
|
||||||
|
int
|
||||||
|
valid_progress_implementation_p (const char *name)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
struct progress_implementation *pi = implementations;
|
||||||
|
char *colon = strchr (name, ':');
|
||||||
|
int namelen = colon ? colon - name : strlen (name);
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE (implementations); i++, pi++)
|
||||||
|
if (!strncmp (pi->name, name, namelen))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the progress implementation to NAME. */
|
||||||
|
|
||||||
|
void
|
||||||
|
set_progress_implementation (const char *name)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
struct progress_implementation *pi = implementations;
|
||||||
|
char *colon = strchr (name, ':');
|
||||||
|
int namelen = colon ? colon - name : strlen (name);
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE (implementations); i++, pi++)
|
||||||
|
if (!strncmp (pi->name, name, namelen))
|
||||||
|
{
|
||||||
|
current_impl = pi;
|
||||||
|
|
||||||
|
if (colon)
|
||||||
|
/* We call pi->set_params even if colon is NULL because we
|
||||||
|
want to give the implementation a chance to set up some
|
||||||
|
things it needs to run. */
|
||||||
|
++colon;
|
||||||
|
|
||||||
|
if (pi->set_params)
|
||||||
|
pi->set_params (colon);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a progress gauge. INITIAL is the number of bytes the
|
||||||
|
download starts from (zero if the download starts from scratch).
|
||||||
|
TOTAL is the expected total number of bytes in this download. If
|
||||||
|
TOTAL is zero, it means that the download size is not known in
|
||||||
|
advance. */
|
||||||
|
|
||||||
|
void *
|
||||||
|
progress_create (long initial, long total)
|
||||||
|
{
|
||||||
|
return current_impl->create (initial, total);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inform the progress gauge of newly received bytes. */
|
||||||
|
|
||||||
|
void
|
||||||
|
progress_update (void *progress, long howmuch)
|
||||||
|
{
|
||||||
|
current_impl->update (progress, howmuch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tell the progress gauge to clean up. Calling this will free the
|
||||||
|
PROGRESS object, the further use of which is not allowed. */
|
||||||
|
|
||||||
|
void
|
||||||
|
progress_finish (void *progress)
|
||||||
|
{
|
||||||
|
current_impl->finish (progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dot-printing. */
|
||||||
|
|
||||||
|
struct dot_progress {
|
||||||
|
long initial_length; /* how many bytes have been downloaded
|
||||||
|
previously. */
|
||||||
|
long total_length; /* expected total byte count when the
|
||||||
|
download finishes */
|
||||||
|
|
||||||
|
int accumulated;
|
||||||
|
|
||||||
|
int rows; /* number of rows printed so far */
|
||||||
|
int dots; /* number of dots printed in this row */
|
||||||
|
|
||||||
|
struct wget_timer *timer; /* timer used to measure per-row
|
||||||
|
download rates. */
|
||||||
|
long last_timer_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Dot-progress backend for progress_create. */
|
||||||
|
|
||||||
|
static void *
|
||||||
|
dp_create (long initial, long total)
|
||||||
|
{
|
||||||
|
struct dot_progress *dp = xmalloc (sizeof (struct dot_progress));
|
||||||
|
|
||||||
|
memset (dp, 0, sizeof (*dp));
|
||||||
|
|
||||||
|
dp->initial_length = initial;
|
||||||
|
dp->total_length = total;
|
||||||
|
dp->timer = wtimer_new ();
|
||||||
|
|
||||||
|
if (dp->initial_length)
|
||||||
|
{
|
||||||
|
int dot_bytes = opt.dot_bytes;
|
||||||
|
long row_bytes = opt.dot_bytes * opt.dots_in_line;
|
||||||
|
|
||||||
|
int remainder = (int) (dp->initial_length % row_bytes);
|
||||||
|
long skipped = dp->initial_length - remainder;
|
||||||
|
|
||||||
|
if (skipped)
|
||||||
|
{
|
||||||
|
logputs (LOG_VERBOSE, "\n "); /* leave spacing untranslated */
|
||||||
|
logprintf (LOG_VERBOSE, _("[ skipping %dK ]"),
|
||||||
|
(int) (skipped / 1024));
|
||||||
|
}
|
||||||
|
|
||||||
|
logprintf (LOG_VERBOSE, "\n%5ldK", skipped / 1024);
|
||||||
|
for (; remainder >= dot_bytes; remainder -= dot_bytes)
|
||||||
|
{
|
||||||
|
if (dp->dots % opt.dot_spacing == 0)
|
||||||
|
logputs (LOG_VERBOSE, " ");
|
||||||
|
logputs (LOG_VERBOSE, ",");
|
||||||
|
++dp->dots;
|
||||||
|
}
|
||||||
|
assert (dp->dots < opt.dots_in_line);
|
||||||
|
|
||||||
|
dp->accumulated = remainder;
|
||||||
|
dp->rows = skipped / row_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_percentage (long bytes, long expected)
|
||||||
|
{
|
||||||
|
int percentage = (int)(100.0 * bytes / expected);
|
||||||
|
logprintf (LOG_VERBOSE, "%3d%%", percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_elapsed (struct dot_progress *dp, long bytes)
|
||||||
|
{
|
||||||
|
long timer_value = wtimer_elapsed (dp->timer);
|
||||||
|
logprintf (LOG_VERBOSE, " @ %s",
|
||||||
|
rate (bytes, timer_value - dp->last_timer_value, 1));
|
||||||
|
dp->last_timer_value = timer_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dot-progress backend for progress_update. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
dp_update (void *progress, long howmuch)
|
||||||
|
{
|
||||||
|
struct dot_progress *dp = progress;
|
||||||
|
int dot_bytes = opt.dot_bytes;
|
||||||
|
long row_bytes = opt.dot_bytes * opt.dots_in_line;
|
||||||
|
|
||||||
|
log_set_flush (0);
|
||||||
|
|
||||||
|
dp->accumulated += howmuch;
|
||||||
|
for (; dp->accumulated >= dot_bytes; dp->accumulated -= dot_bytes)
|
||||||
|
{
|
||||||
|
if (dp->dots == 0)
|
||||||
|
logprintf (LOG_VERBOSE, "\n%5ldK", dp->rows * row_bytes / 1024);
|
||||||
|
|
||||||
|
if (dp->dots % opt.dot_spacing == 0)
|
||||||
|
logputs (LOG_VERBOSE, " ");
|
||||||
|
logputs (LOG_VERBOSE, ".");
|
||||||
|
|
||||||
|
++dp->dots;
|
||||||
|
if (dp->dots >= opt.dots_in_line)
|
||||||
|
{
|
||||||
|
++dp->rows;
|
||||||
|
dp->dots = 0;
|
||||||
|
|
||||||
|
if (dp->total_length)
|
||||||
|
print_percentage (dp->rows * row_bytes, dp->total_length);
|
||||||
|
|
||||||
|
print_elapsed (dp, row_bytes - (dp->initial_length % row_bytes));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log_set_flush (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dot-progress backend for progress_finish. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
dp_finish (void *progress)
|
||||||
|
{
|
||||||
|
struct dot_progress *dp = progress;
|
||||||
|
int dot_bytes = opt.dot_bytes;
|
||||||
|
long row_bytes = opt.dot_bytes * opt.dots_in_line;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
log_set_flush (0);
|
||||||
|
|
||||||
|
for (i = dp->dots; i < opt.dots_in_line; i++)
|
||||||
|
{
|
||||||
|
if (i % opt.dot_spacing == 0)
|
||||||
|
logputs (LOG_VERBOSE, " ");
|
||||||
|
logputs (LOG_VERBOSE, " ");
|
||||||
|
}
|
||||||
|
if (dp->total_length)
|
||||||
|
{
|
||||||
|
print_percentage (dp->rows * row_bytes
|
||||||
|
+ dp->dots * dot_bytes
|
||||||
|
+ dp->accumulated,
|
||||||
|
dp->total_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
print_elapsed (dp, dp->dots * dot_bytes
|
||||||
|
+ dp->accumulated
|
||||||
|
- dp->initial_length % row_bytes);
|
||||||
|
logputs (LOG_VERBOSE, "\n\n");
|
||||||
|
|
||||||
|
log_set_flush (0);
|
||||||
|
|
||||||
|
wtimer_delete (dp->timer);
|
||||||
|
xfree (dp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function interprets the progress "parameters". For example,
|
||||||
|
if Wget is invoked with --progress=bar:mega, it will set the
|
||||||
|
"dot-style" to "mega". Valid styles are default, binary, mega, and
|
||||||
|
giga. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
dp_set_params (const char *params)
|
||||||
|
{
|
||||||
|
if (!params)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* We use this to set the retrieval style. */
|
||||||
|
if (!strcasecmp (params, "default"))
|
||||||
|
{
|
||||||
|
/* Default style: 1K dots, 10 dots in a cluster, 50 dots in a
|
||||||
|
line. */
|
||||||
|
opt.dot_bytes = 1024;
|
||||||
|
opt.dot_spacing = 10;
|
||||||
|
opt.dots_in_line = 50;
|
||||||
|
}
|
||||||
|
else if (!strcasecmp (params, "binary"))
|
||||||
|
{
|
||||||
|
/* "Binary" retrieval: 8K dots, 16 dots in a cluster, 48 dots
|
||||||
|
(384K) in a line. */
|
||||||
|
opt.dot_bytes = 8192;
|
||||||
|
opt.dot_spacing = 16;
|
||||||
|
opt.dots_in_line = 48;
|
||||||
|
}
|
||||||
|
else if (!strcasecmp (params, "mega"))
|
||||||
|
{
|
||||||
|
/* "Mega" retrieval, for retrieving very long files; each dot is
|
||||||
|
64K, 8 dots in a cluster, 6 clusters (3M) in a line. */
|
||||||
|
opt.dot_bytes = 65536L;
|
||||||
|
opt.dot_spacing = 8;
|
||||||
|
opt.dots_in_line = 48;
|
||||||
|
}
|
||||||
|
else if (!strcasecmp (params, "giga"))
|
||||||
|
{
|
||||||
|
/* "Giga" retrieval, for retrieving very very *very* long files;
|
||||||
|
each dot is 1M, 8 dots in a cluster, 4 clusters (32M) in a
|
||||||
|
line. */
|
||||||
|
opt.dot_bytes = (1L << 20);
|
||||||
|
opt.dot_spacing = 8;
|
||||||
|
opt.dots_in_line = 32;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fprintf (stderr,
|
||||||
|
_("Invalid dot style specification `%s'; leaving unchanged.\n"),
|
||||||
|
params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* "Thermometer" (bar) progress. */
|
||||||
|
|
||||||
|
/* Assumed screen width if we can't find the real value. */
|
||||||
|
#define DEFAULT_SCREEN_WIDTH 80
|
||||||
|
|
||||||
|
/* Minimum screen width we'll try to work with. If this is too small,
|
||||||
|
create_image will overflow the buffer. */
|
||||||
|
#define MINIMUM_SCREEN_WIDTH 45
|
||||||
|
|
||||||
|
static int screen_width = DEFAULT_SCREEN_WIDTH;
|
||||||
|
|
||||||
|
struct bar_progress {
|
||||||
|
long initial_length; /* how many bytes have been downloaded
|
||||||
|
previously. */
|
||||||
|
long total_length; /* expected total byte count when the
|
||||||
|
download finishes */
|
||||||
|
long count; /* bytes downloaded so far */
|
||||||
|
|
||||||
|
struct wget_timer *timer; /* timer used to measure the download
|
||||||
|
rates. */
|
||||||
|
long last_update; /* time of the last screen update. */
|
||||||
|
|
||||||
|
int width; /* screen width at the time the
|
||||||
|
progress gauge was created. */
|
||||||
|
char *buffer; /* buffer where the bar "image" is
|
||||||
|
stored. */
|
||||||
|
};
|
||||||
|
|
||||||
|
static void create_image PARAMS ((struct bar_progress *, long));
|
||||||
|
static void display_image PARAMS ((char *));
|
||||||
|
|
||||||
|
static void *
|
||||||
|
bar_create (long initial, long total)
|
||||||
|
{
|
||||||
|
struct bar_progress *bp = xmalloc (sizeof (struct bar_progress));
|
||||||
|
|
||||||
|
memset (bp, 0, sizeof (*bp));
|
||||||
|
|
||||||
|
bp->initial_length = initial;
|
||||||
|
bp->total_length = total;
|
||||||
|
bp->timer = wtimer_new ();
|
||||||
|
bp->width = screen_width;
|
||||||
|
bp->buffer = xmalloc (bp->width + 1);
|
||||||
|
|
||||||
|
logputs (LOG_VERBOSE, "\n");
|
||||||
|
|
||||||
|
create_image (bp, 0);
|
||||||
|
display_image (bp->buffer);
|
||||||
|
|
||||||
|
return bp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bar_update (void *progress, long howmuch)
|
||||||
|
{
|
||||||
|
struct bar_progress *bp = progress;
|
||||||
|
int force_update = 0;
|
||||||
|
long dltime = wtimer_elapsed (bp->timer);
|
||||||
|
|
||||||
|
bp->count += howmuch;
|
||||||
|
|
||||||
|
if (screen_width != bp->width)
|
||||||
|
{
|
||||||
|
bp->width = screen_width;
|
||||||
|
bp->buffer = xrealloc (bp->buffer, bp->width + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dltime - bp->last_update < 200 && !force_update)
|
||||||
|
/* Don't update more often than every half a second. */
|
||||||
|
return;
|
||||||
|
|
||||||
|
bp->last_update = dltime;
|
||||||
|
|
||||||
|
create_image (bp, dltime);
|
||||||
|
display_image (bp->buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bar_finish (void *progress)
|
||||||
|
{
|
||||||
|
struct bar_progress *bp = progress;
|
||||||
|
|
||||||
|
create_image (bp, wtimer_elapsed (bp->timer));
|
||||||
|
display_image (bp->buffer);
|
||||||
|
|
||||||
|
logputs (LOG_VERBOSE, "\n\n");
|
||||||
|
|
||||||
|
xfree (bp->buffer);
|
||||||
|
wtimer_delete (bp->timer);
|
||||||
|
xfree (bp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_image (struct bar_progress *bp, long dltime)
|
||||||
|
{
|
||||||
|
char *p = bp->buffer;
|
||||||
|
long size = bp->initial_length + bp->count;
|
||||||
|
|
||||||
|
/* The progress bar should look like this:
|
||||||
|
xxx% |=======> | xx KB/s nnnnn ETA: 00:00
|
||||||
|
|
||||||
|
Calculate its geometry:
|
||||||
|
|
||||||
|
"xxx% " - percentage - 5 chars
|
||||||
|
"| ... | " - progress bar decorations - 3 chars
|
||||||
|
"1234.56 K/s " - dl rate - 12 chars
|
||||||
|
"nnnn " - downloaded bytes - 11 chars
|
||||||
|
"ETA: xx:xx:xx" - ETA - 13 chars
|
||||||
|
|
||||||
|
"=====>..." - progress bar content - the rest
|
||||||
|
*/
|
||||||
|
int progress_len = screen_width - (5 + 3 + 12 + 11 + 13);
|
||||||
|
|
||||||
|
if (progress_len < 7)
|
||||||
|
progress_len = 0;
|
||||||
|
|
||||||
|
/* "xxx% " */
|
||||||
|
if (bp->total_length > 0)
|
||||||
|
{
|
||||||
|
int percentage = (int)(100.0 * size / bp->total_length);
|
||||||
|
|
||||||
|
assert (percentage <= 100);
|
||||||
|
|
||||||
|
sprintf (p, "%3d%% ", percentage);
|
||||||
|
p += 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The progress bar: "|====> | " */
|
||||||
|
if (progress_len && bp->total_length > 0)
|
||||||
|
{
|
||||||
|
double fraction = (double)size / bp->total_length;
|
||||||
|
int dlsz = (int)(fraction * progress_len);
|
||||||
|
char *begin;
|
||||||
|
|
||||||
|
assert (dlsz <= progress_len);
|
||||||
|
|
||||||
|
*p++ = '|';
|
||||||
|
begin = p;
|
||||||
|
|
||||||
|
if (dlsz > 0)
|
||||||
|
{
|
||||||
|
/* Draw dlsz-1 '=' chars and one arrow char. */
|
||||||
|
while (dlsz-- > 1)
|
||||||
|
*p++ = '=';
|
||||||
|
*p++ = '>';
|
||||||
|
}
|
||||||
|
|
||||||
|
while (p - begin < progress_len)
|
||||||
|
*p++ = ' ';
|
||||||
|
|
||||||
|
*p++ = '|';
|
||||||
|
*p++ = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* "2.3 KB/s " */
|
||||||
|
if (dltime && bp->count)
|
||||||
|
{
|
||||||
|
char *rt = rate (bp->count, dltime, 1);
|
||||||
|
strcpy (p, rt);
|
||||||
|
p += strlen (p);
|
||||||
|
*p++ = ' ';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy (p, "----.-- KB/s ");
|
||||||
|
p += 13;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* "12376 " */
|
||||||
|
sprintf (p, _("%ld "), size);
|
||||||
|
p += strlen (p);
|
||||||
|
|
||||||
|
/* "ETA: xx:xx:xx" */
|
||||||
|
if (bp->total_length > 0 && bp->count > 0)
|
||||||
|
{
|
||||||
|
int eta, eta_hrs, eta_min, eta_sec;
|
||||||
|
double tm_sofar = (double)dltime / 1000;
|
||||||
|
long bytes_remaining = bp->total_length - size;
|
||||||
|
|
||||||
|
eta = (int) (tm_sofar * bytes_remaining / bp->count);
|
||||||
|
|
||||||
|
eta_hrs = eta / 3600, eta %= 3600;
|
||||||
|
eta_min = eta / 60, eta %= 60;
|
||||||
|
eta_sec = eta;
|
||||||
|
|
||||||
|
/*printf ("\neta: %d, %d %d %d\n", eta, eta_hrs, eta_min, eta_sec);*/
|
||||||
|
/*printf ("\n%ld %f %ld %ld\n", dltime, tm_sofar, bytes_remaining, bp->count);*/
|
||||||
|
|
||||||
|
*p++ = 'E';
|
||||||
|
*p++ = 'T';
|
||||||
|
*p++ = 'A';
|
||||||
|
*p++ = ':';
|
||||||
|
*p++ = ' ';
|
||||||
|
|
||||||
|
if (eta_hrs > 99)
|
||||||
|
/* Bogus value, for whatever reason. We must avoid overflow. */
|
||||||
|
sprintf (p, "--:--");
|
||||||
|
else if (eta_hrs > 0)
|
||||||
|
sprintf (p, "%d:%02d:%02d", eta_hrs, eta_min, eta_sec);
|
||||||
|
else
|
||||||
|
sprintf (p, "%02d:%02d", eta_min, eta_sec);
|
||||||
|
p += strlen (p);
|
||||||
|
}
|
||||||
|
else if (bp->total_length > 0)
|
||||||
|
{
|
||||||
|
strcpy (p, "ETA: --:--");
|
||||||
|
p += 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert (p - bp->buffer <= screen_width);
|
||||||
|
|
||||||
|
while (p < bp->buffer + screen_width)
|
||||||
|
*p++ = ' ';
|
||||||
|
*p = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
display_image (char *buf)
|
||||||
|
{
|
||||||
|
int len = strlen (buf);
|
||||||
|
char *del_buf = alloca (len + 1);
|
||||||
|
|
||||||
|
logputs (LOG_VERBOSE, buf);
|
||||||
|
|
||||||
|
memset (del_buf, '\b', len);
|
||||||
|
del_buf[len] = '\0';
|
||||||
|
|
||||||
|
logputs (LOG_VERBOSE, del_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bar_set_params (const char *ignored)
|
||||||
|
{
|
||||||
|
int sw = determine_screen_width ();
|
||||||
|
if (sw && sw >= MINIMUM_SCREEN_WIDTH)
|
||||||
|
screen_width = sw;
|
||||||
|
}
|
||||||
|
|
||||||
|
RETSIGTYPE
|
||||||
|
progress_handle_sigwinch (int sig)
|
||||||
|
{
|
||||||
|
int sw = determine_screen_width ();
|
||||||
|
if (sw && sw >= MINIMUM_SCREEN_WIDTH)
|
||||||
|
screen_width = sw;
|
||||||
|
}
|
27
src/progress.h
Normal file
27
src/progress.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/* Download progress.
|
||||||
|
Copyright (C) 2001 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
|
||||||
|
\(at your option) any later version.
|
||||||
|
|
||||||
|
GNU Wget is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
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. */
|
||||||
|
|
||||||
|
int valid_progress_implementation_p PARAMS ((const char *));
|
||||||
|
void set_progress_implementation PARAMS ((const char *));
|
||||||
|
|
||||||
|
void *progress_create PARAMS ((long, long));
|
||||||
|
void progress_update PARAMS ((void *, long));
|
||||||
|
void progress_finish PARAMS ((void *));
|
||||||
|
|
||||||
|
RETSIGTYPE progress_handle_sigwinch PARAMS ((int));
|
168
src/retr.c
168
src/retr.c
@ -36,6 +36,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
#include "wget.h"
|
#include "wget.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "retr.h"
|
#include "retr.h"
|
||||||
|
#include "progress.h"
|
||||||
#include "url.h"
|
#include "url.h"
|
||||||
#include "recur.h"
|
#include "recur.h"
|
||||||
#include "ftp.h"
|
#include "ftp.h"
|
||||||
@ -51,11 +52,6 @@ extern int errno;
|
|||||||
int global_download_count;
|
int global_download_count;
|
||||||
|
|
||||||
|
|
||||||
/* Flags for show_progress(). */
|
|
||||||
enum spflags { SP_NONE, SP_INIT, SP_FINISH };
|
|
||||||
|
|
||||||
static int show_progress PARAMS ((long, long, enum spflags));
|
|
||||||
|
|
||||||
#define MIN(i, j) ((i) <= (j) ? (i) : (j))
|
#define MIN(i, j) ((i) <= (j) ? (i) : (j))
|
||||||
|
|
||||||
/* Reads the contents of file descriptor FD, until it is closed, or a
|
/* Reads the contents of file descriptor FD, until it is closed, or a
|
||||||
@ -85,23 +81,28 @@ get_contents (int fd, FILE *fp, long *len, long restval, long expected,
|
|||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
static char c[8192];
|
static char c[8192];
|
||||||
|
void *progress = NULL;
|
||||||
|
|
||||||
*len = restval;
|
*len = restval;
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
show_progress (restval, expected, SP_INIT);
|
progress = progress_create (restval, expected);
|
||||||
|
|
||||||
if (rbuf && RBUF_FD (rbuf) == fd)
|
if (rbuf && RBUF_FD (rbuf) == fd)
|
||||||
{
|
{
|
||||||
|
int need_flush = 0;
|
||||||
while ((res = rbuf_flush (rbuf, c, sizeof (c))) != 0)
|
while ((res = rbuf_flush (rbuf, c, sizeof (c))) != 0)
|
||||||
{
|
{
|
||||||
if (fwrite (c, sizeof (char), res, fp) < res)
|
if (fwrite (c, sizeof (char), res, fp) < res)
|
||||||
return -2;
|
return -2;
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
{
|
progress_update (progress, res);
|
||||||
if (show_progress (res, expected, SP_NONE))
|
|
||||||
fflush (fp);
|
|
||||||
}
|
|
||||||
*len += res;
|
*len += res;
|
||||||
|
need_flush = 1;
|
||||||
}
|
}
|
||||||
|
if (need_flush)
|
||||||
|
fflush (fp);
|
||||||
|
if (ferror (fp))
|
||||||
|
return -2;
|
||||||
}
|
}
|
||||||
/* Read from fd while there is available data.
|
/* Read from fd while there is available data.
|
||||||
|
|
||||||
@ -124,13 +125,15 @@ get_contents (int fd, FILE *fp, long *len, long restval, long expected,
|
|||||||
#endif /* HAVE_SSL */
|
#endif /* HAVE_SSL */
|
||||||
if (res > 0)
|
if (res > 0)
|
||||||
{
|
{
|
||||||
if (fwrite (c, sizeof (char), res, fp) < res)
|
fwrite (c, sizeof (char), res, fp);
|
||||||
|
/* Always flush the contents of the network packet. This
|
||||||
|
should not be adverse to performance, as the network
|
||||||
|
packets typically won't be too tiny anyway. */
|
||||||
|
fflush (fp);
|
||||||
|
if (ferror (fp))
|
||||||
return -2;
|
return -2;
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
{
|
progress_update (progress, res);
|
||||||
if (show_progress (res, expected, SP_NONE))
|
|
||||||
fflush (fp);
|
|
||||||
}
|
|
||||||
*len += res;
|
*len += res;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -139,132 +142,14 @@ get_contents (int fd, FILE *fp, long *len, long restval, long expected,
|
|||||||
if (res < -1)
|
if (res < -1)
|
||||||
res = -1;
|
res = -1;
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
show_progress (0, expected, SP_FINISH);
|
progress_finish (progress);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
print_percentage (long bytes, long expected)
|
|
||||||
{
|
|
||||||
int percentage = (int)(100.0 * bytes / expected);
|
|
||||||
logprintf (LOG_VERBOSE, "%3d%%", percentage);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Show the dotted progress report of file loading. Called with
|
|
||||||
length and a flag to tell it whether to reset or not. It keeps the
|
|
||||||
offset information in static local variables.
|
|
||||||
|
|
||||||
Return value: 1 or 0, designating whether any dots have been drawn.
|
|
||||||
|
|
||||||
If the init argument is set, the routine will initialize.
|
|
||||||
|
|
||||||
If the res is non-zero, res/line_bytes lines are skipped
|
|
||||||
(meaning the appropriate number ok kilobytes), and the number of
|
|
||||||
"dots" fitting on the first line are drawn as ','. */
|
|
||||||
static int
|
|
||||||
show_progress (long res, long expected, enum spflags flags)
|
|
||||||
{
|
|
||||||
static struct wget_timer *timer;
|
|
||||||
static long line_bytes;
|
|
||||||
static long offs, initial_skip;
|
|
||||||
static int ndot, nrow;
|
|
||||||
static long last_timer_value, time_offset;
|
|
||||||
int any_output = 0;
|
|
||||||
|
|
||||||
if (flags == SP_FINISH)
|
|
||||||
{
|
|
||||||
int dot = ndot;
|
|
||||||
char *tmpstr = (char *)alloca (2 * opt.dots_in_line + 1);
|
|
||||||
char *tmpp = tmpstr;
|
|
||||||
time_offset = wtimer_elapsed (timer) - last_timer_value;
|
|
||||||
for (; dot < opt.dots_in_line; dot++)
|
|
||||||
{
|
|
||||||
if (!(dot % opt.dot_spacing))
|
|
||||||
*tmpp++ = ' ';
|
|
||||||
*tmpp++ = ' ';
|
|
||||||
}
|
|
||||||
*tmpp = '\0';
|
|
||||||
logputs (LOG_VERBOSE, tmpstr);
|
|
||||||
if (expected)
|
|
||||||
print_percentage (nrow * line_bytes + ndot * opt.dot_bytes + offs,
|
|
||||||
expected);
|
|
||||||
logprintf (LOG_VERBOSE, " @%s",
|
|
||||||
rate (ndot * opt.dot_bytes
|
|
||||||
+ offs - (initial_skip % line_bytes),
|
|
||||||
time_offset, 1));
|
|
||||||
logputs (LOG_VERBOSE, "\n\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Temporarily disable flushing. */
|
|
||||||
log_set_flush (0);
|
|
||||||
|
|
||||||
/* init set means initialization. If res is set, it also means that
|
|
||||||
the retrieval is *not* done from the beginning. The part that
|
|
||||||
was already retrieved is not shown again. */
|
|
||||||
if (flags == SP_INIT)
|
|
||||||
{
|
|
||||||
/* Generic initialization of static variables. */
|
|
||||||
offs = 0L;
|
|
||||||
ndot = nrow = 0;
|
|
||||||
line_bytes = (long)opt.dots_in_line * opt.dot_bytes;
|
|
||||||
if (!timer)
|
|
||||||
timer = wtimer_allocate ();
|
|
||||||
wtimer_reset (timer);
|
|
||||||
last_timer_value = 0;
|
|
||||||
time_offset = 0;
|
|
||||||
initial_skip = res;
|
|
||||||
if (res)
|
|
||||||
{
|
|
||||||
if (res >= line_bytes)
|
|
||||||
{
|
|
||||||
nrow = res / line_bytes;
|
|
||||||
res %= line_bytes;
|
|
||||||
logprintf (LOG_VERBOSE,
|
|
||||||
_("\n [ skipping %dK ]"),
|
|
||||||
(int) ((nrow * line_bytes) / 1024));
|
|
||||||
ndot = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
logprintf (LOG_VERBOSE, "\n%5ldK", nrow * line_bytes / 1024);
|
|
||||||
}
|
|
||||||
/* Offset gets incremented by current value. */
|
|
||||||
offs += res;
|
|
||||||
/* While offset is >= opt.dot_bytes, print dots, taking care to
|
|
||||||
precede every 50th dot with a status message. */
|
|
||||||
for (; offs >= opt.dot_bytes; offs -= opt.dot_bytes)
|
|
||||||
{
|
|
||||||
if (!(ndot % opt.dot_spacing))
|
|
||||||
logputs (LOG_VERBOSE, " ");
|
|
||||||
any_output = 1;
|
|
||||||
logputs (LOG_VERBOSE, flags == SP_INIT ? "," : ".");
|
|
||||||
++ndot;
|
|
||||||
if (ndot == opt.dots_in_line)
|
|
||||||
{
|
|
||||||
time_offset = wtimer_elapsed (timer) - last_timer_value;
|
|
||||||
last_timer_value += time_offset;
|
|
||||||
|
|
||||||
ndot = 0;
|
|
||||||
++nrow;
|
|
||||||
if (expected)
|
|
||||||
print_percentage (nrow * line_bytes, expected);
|
|
||||||
logprintf (LOG_VERBOSE, " @%s",
|
|
||||||
rate (line_bytes - (initial_skip % line_bytes),
|
|
||||||
time_offset, 1));
|
|
||||||
initial_skip = 0;
|
|
||||||
logprintf (LOG_VERBOSE, "\n%5ldK", nrow * line_bytes / 1024);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reenable flushing. */
|
|
||||||
log_set_flush (1);
|
|
||||||
|
|
||||||
return any_output;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print out the appropriate download rate. Appropriate means that if
|
/* Return a printed representation of the download rate, as
|
||||||
rate is > 1024 bytes per second, kilobytes are used, and if rate >
|
appropriate for the speed. Appropriate means that if rate is
|
||||||
1024 * 1024 bps, megabytes are used.
|
greater than 1K/s, kilobytes are used, and if rate is greater than
|
||||||
|
1MB/s, megabytes are used.
|
||||||
|
|
||||||
If PAD is non-zero, strings will be padded to the width of 7
|
If PAD is non-zero, strings will be padded to the width of 7
|
||||||
characters (xxxx.xx). */
|
characters (xxxx.xx). */
|
||||||
@ -274,6 +159,9 @@ rate (long bytes, long msecs, int pad)
|
|||||||
static char res[15];
|
static char res[15];
|
||||||
double dlrate;
|
double dlrate;
|
||||||
|
|
||||||
|
assert (msecs >= 0);
|
||||||
|
assert (bytes >= 0);
|
||||||
|
|
||||||
if (msecs == 0)
|
if (msecs == 0)
|
||||||
/* If elapsed time is 0, it means we're under the granularity of
|
/* If elapsed time is 0, it means we're under the granularity of
|
||||||
the timer. This often happens on systems that use time() for
|
the timer. This often happens on systems that use time() for
|
||||||
@ -284,9 +172,9 @@ rate (long bytes, long msecs, int pad)
|
|||||||
if (dlrate < 1024.0)
|
if (dlrate < 1024.0)
|
||||||
sprintf (res, pad ? "%7.2f B/s" : "%.2f B/s", dlrate);
|
sprintf (res, pad ? "%7.2f B/s" : "%.2f B/s", dlrate);
|
||||||
else if (dlrate < 1024.0 * 1024.0)
|
else if (dlrate < 1024.0 * 1024.0)
|
||||||
sprintf (res, pad ? "%7.2f KB/s" : "%.2f KB/s", dlrate / 1024.0);
|
sprintf (res, pad ? "%7.2f K/s" : "%.2f K/s", dlrate / 1024.0);
|
||||||
else if (dlrate < 1024.0 * 1024.0 * 1024.0)
|
else if (dlrate < 1024.0 * 1024.0 * 1024.0)
|
||||||
sprintf (res, pad ? "%7.2f MB/s" : "%.2f MB/s", dlrate / (1024.0 * 1024.0));
|
sprintf (res, pad ? "%7.2f M/s" : "%.2f M/s", dlrate / (1024.0 * 1024.0));
|
||||||
else
|
else
|
||||||
/* Maybe someone will need this one day. More realistically, it
|
/* Maybe someone will need this one day. More realistically, it
|
||||||
will get tickled by buggy timers. */
|
will get tickled by buggy timers. */
|
||||||
|
28
src/utils.c
28
src/utils.c
@ -50,6 +50,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
#endif
|
#endif
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#ifdef HAVE_SYS_IOCTL_H
|
||||||
|
# include <sys/ioctl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "wget.h"
|
#include "wget.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
@ -1704,3 +1707,28 @@ html_quote_string (const char *s)
|
|||||||
*p = '\0';
|
*p = '\0';
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Determine the width of the terminal we're running on. If that's
|
||||||
|
not possible, return 0. */
|
||||||
|
|
||||||
|
int
|
||||||
|
determine_screen_width (void)
|
||||||
|
{
|
||||||
|
/* If there's a way to get the terminal size using POSIX
|
||||||
|
tcgetattr(), somebody please tell me. */
|
||||||
|
#ifndef TIOCGWINSZ
|
||||||
|
return 0;
|
||||||
|
#else /* TIOCGWINSZ */
|
||||||
|
int fd;
|
||||||
|
struct winsize wsz;
|
||||||
|
|
||||||
|
if (opt.lfilename != NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fd = fileno (stderr);
|
||||||
|
if (ioctl (fd, TIOCGWINSZ, &wsz) < 0)
|
||||||
|
return 0; /* most likely ENOTTY */
|
||||||
|
|
||||||
|
return wsz.ws_col;
|
||||||
|
#endif /* TIOCGWINSZ */
|
||||||
|
}
|
||||||
|
@ -28,6 +28,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
# define NDEBUG /* To kill off assertions */
|
# define NDEBUG /* To kill off assertions */
|
||||||
#endif /* not DEBUG */
|
#endif /* not DEBUG */
|
||||||
|
|
||||||
|
#define DEBUG_MALLOC
|
||||||
|
|
||||||
#ifndef PARAMS
|
#ifndef PARAMS
|
||||||
# if PROTOTYPES
|
# if PROTOTYPES
|
||||||
# define PARAMS(args) args
|
# define PARAMS(args) args
|
||||||
|
Loading…
Reference in New Issue
Block a user