1
0
mirror of https://github.com/moparisthebest/wget synced 2024-07-03 16:38:41 -04:00

[svn] Support human-readable file size printing.

Don't use persistent connection over proxies.
This commit is contained in:
hniksic 2005-03-22 05:20:02 -08:00
parent 7c044778bc
commit b9a31d78dd
9 changed files with 155 additions and 40 deletions

View File

@ -1,3 +1,21 @@
2005-03-21 Hrvoje Niksic <hniksic@xemacs.org>
* http.c (gethttp): Print the human-readable size.
* ftp.c (getftp): Print the human-readable size of the file to be
downloaded.
* utils.c (human_readable): New function.
* utils.c: Renamed "legible" to "with_thousand_seps",
"legible_large_int" to "with_thousand_seps_large", and "legible_1"
to "add_thousand_seps".
2005-03-21 Hrvoje Niksic <hniksic@xemacs.org>
* http.c (gethttp): Inhibit persistent connections when talking to
proxies, as mandated by RFC 2068.
2005-03-20 Hrvoje Niksic <hniksic@xemacs.org> 2005-03-20 Hrvoje Niksic <hniksic@xemacs.org>
* url.c (unescape_single_char): New function. * url.c (unescape_single_char): New function.

View File

@ -939,7 +939,7 @@ ftp_index (const char *file, struct url *u, struct fileinfo *f)
putc ('/', fp); putc ('/', fp);
fprintf (fp, "</a> "); fprintf (fp, "</a> ");
if (f->type == FT_PLAINFILE) if (f->type == FT_PLAINFILE)
fprintf (fp, _(" (%s bytes)"), legible (f->size)); fprintf (fp, _(" (%s bytes)"), with_thousand_seps (f->size));
else if (f->type == FT_SYMLINK) else if (f->type == FT_SYMLINK)
fprintf (fp, "-> %s", f->linkto ? f->linkto : "(nil)"); fprintf (fp, "-> %s", f->linkto ? f->linkto : "(nil)");
putc ('\n', fp); putc ('\n', fp);

View File

@ -220,6 +220,26 @@ ftp_do_port (int csock, int *local_sock)
} }
#endif #endif
static void
print_length (wgint size, wgint start, int authoritative)
{
logprintf (LOG_VERBOSE, _("Length: %s"), with_thousand_seps (size));
if (size >= 1024)
logprintf (LOG_VERBOSE, " (%s)", human_readable (size));
if (start > 0)
{
if (start >= 1024)
logprintf (LOG_VERBOSE, _(", %s (%s) remaining"),
with_thousand_seps (size - start),
human_readable (size - start));
else
logprintf (LOG_VERBOSE, _(", %s remaining"),
with_thousand_seps (size - start));
}
if (!authoritative)
logputs (LOG_VERBOSE, _(" (unauthoritative)\n"));
}
/* Retrieves a file with denoted parameters through opening an FTP /* Retrieves a file with denoted parameters through opening an FTP
connection to the server. It always closes the data connection, connection to the server. It always closes the data connection,
and closes the control connection in case of error. */ and closes the control connection in case of error. */
@ -993,20 +1013,11 @@ Error in server response, closing control connection.\n"));
if (*len) if (*len)
{ {
logprintf (LOG_VERBOSE, _("Length: %s"), legible (*len)); print_length (*len, restval, 1);
if (restval)
logprintf (LOG_VERBOSE, _(" [%s to go]"), legible (*len - restval));
logputs (LOG_VERBOSE, "\n");
expected_bytes = *len; /* for get_contents/show_progress */ expected_bytes = *len; /* for get_contents/show_progress */
} }
else if (expected_bytes) else if (expected_bytes)
{ print_length (expected_bytes, restval, 0);
logprintf (LOG_VERBOSE, _("Length: %s"), legible (expected_bytes));
if (restval)
logprintf (LOG_VERBOSE, _(" [%s to go]"),
legible (expected_bytes - restval));
logputs (LOG_VERBOSE, _(" (unauthoritative)\n"));
}
/* Get the contents of the document. */ /* Get the contents of the document. */
flags = 0; flags = 0;

View File

@ -1089,8 +1089,15 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
is done. */ is done. */
int keep_alive; int keep_alive;
/* Whether keep-alive should be inhibited. */ /* Whether keep-alive should be inhibited.
int inhibit_keep_alive = !opt.http_keep_alive || opt.ignore_length;
RFC 2068 requests that 1.0 clients not send keep-alive requests
to proxies. This is because many 1.0 proxies do not interpret
the Connection header and transfer it to the remote server,
causing it to not close the connection and leave both the proxy
and the client hanging. */
int inhibit_keep_alive =
!opt.http_keep_alive || opt.ignore_length /*|| proxy != NULL*/;
/* Headers sent when using POST. */ /* Headers sent when using POST. */
wgint post_data_size = 0; wgint post_data_size = 0;
@ -1733,9 +1740,20 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
logputs (LOG_VERBOSE, _("Length: ")); logputs (LOG_VERBOSE, _("Length: "));
if (contlen != -1) if (contlen != -1)
{ {
logputs (LOG_VERBOSE, legible (contlen + contrange)); logputs (LOG_VERBOSE, with_thousand_seps (contlen + contrange));
if (contlen + contrange >= 1024)
logprintf (LOG_VERBOSE, " (%s)",
human_readable (contlen + contrange));
if (contrange) if (contrange)
logprintf (LOG_VERBOSE, _(" (%s to go)"), legible (contlen)); {
if (contlen >= 1024)
logprintf (LOG_VERBOSE, _(", %s (%s) remaining"),
with_thousand_seps (contlen),
human_readable (contlen));
else
logprintf (LOG_VERBOSE, _(", %s remaining"),
with_thousand_seps (contlen));
}
} }
else else
logputs (LOG_VERBOSE, logputs (LOG_VERBOSE,

View File

@ -943,13 +943,13 @@ Can't timestamp and not clobber old files at the same time.\n"));
{ {
logprintf (LOG_NOTQUIET, logprintf (LOG_NOTQUIET,
_("\nFINISHED --%s--\nDownloaded: %s bytes in %d files\n"), _("\nFINISHED --%s--\nDownloaded: %s bytes in %d files\n"),
time_str (NULL), legible_large_int (total_downloaded_bytes), time_str (NULL), with_thousand_seps_large (total_downloaded_bytes),
opt.numurls); opt.numurls);
/* Print quota warning, if exceeded. */ /* Print quota warning, if exceeded. */
if (opt.quota && total_downloaded_bytes > opt.quota) if (opt.quota && total_downloaded_bytes > opt.quota)
logprintf (LOG_NOTQUIET, logprintf (LOG_NOTQUIET,
_("Download quota (%s bytes) EXCEEDED!\n"), _("Download quota (%s bytes) EXCEEDED!\n"),
legible (opt.quota)); with_thousand_seps_large (opt.quota));
} }
if (opt.cookies_output) if (opt.cookies_output)

View File

@ -721,7 +721,7 @@ create_image (struct bar_progress *bp, double dl_total_time)
char *p = bp->buffer; char *p = bp->buffer;
wgint size = bp->initial_length + bp->count; wgint size = bp->initial_length + bp->count;
char *size_legible = legible (size); char *size_legible = with_thousand_seps (size);
int size_legible_len = strlen (size_legible); int size_legible_len = strlen (size_legible);
struct bar_progress_hist *hist = &bp->hist; struct bar_progress_hist *hist = &bp->hist;
@ -828,7 +828,7 @@ create_image (struct bar_progress *bp, double dl_total_time)
} }
/* " 234,567,890" */ /* " 234,567,890" */
sprintf (p, " %-11s", legible (size)); sprintf (p, " %-11s", with_thousand_seps (size));
p += strlen (p); p += strlen (p);
/* " 1012.45K/s" */ /* " 1012.45K/s" */

View File

@ -111,7 +111,9 @@ so, delete this exception statement from your version. */
/* Define a large integral type useful for storing large sizes that /* Define a large integral type useful for storing large sizes that
exceed sizes of one download, such as when printing the sum of all exceed sizes of one download, such as when printing the sum of all
downloads. Note that this has nothing to do with large file downloads. Note that this has nothing to do with large file
support, which determines the wgint type. support, which determines the wgint type. This should be as large
as possible even on systems where when wgint is 32-bit; also,
unlike wgint, this can be a floating point type.
We use a 64-bit integral type where available, `double' otherwise. We use a 64-bit integral type where available, `double' otherwise.
It's hard to print LARGE_INT's portably, but fortunately it's It's hard to print LARGE_INT's portably, but fortunately it's

View File

@ -1226,11 +1226,11 @@ free_keys_and_values (struct hash_table *ht)
} }
/* Engine for legible and legible_large_int; add thousand separators /* Add thousand separators to a number already in string form. Used
to numbers printed in strings. */ by with_thousand_seps and with_thousand_seps_large. */
static char * static char *
legible_1 (const char *repr) add_thousand_seps (const char *repr)
{ {
static char outbuf[48]; static char outbuf[48];
int i, i1, mod; int i, i1, mod;
@ -1266,41 +1266,106 @@ legible_1 (const char *repr)
return outbuf; return outbuf;
} }
/* Legible -- return a static pointer to the legibly printed wgint. */ /* Return a static pointer to the number printed with thousand
separators inserted at the right places. */
char * char *
legible (wgint l) with_thousand_seps (wgint l)
{ {
char inbuf[24]; char inbuf[24];
/* Print the number into the buffer. */ /* Print the number into the buffer. */
number_to_string (inbuf, l); number_to_string (inbuf, l);
return legible_1 (inbuf); return add_thousand_seps (inbuf);
} }
/* Write a string representation of LARGE_INT NUMBER into the provided /* Write a string representation of LARGE_INT NUMBER into the provided
buffer. The buffer should be able to accept 24 characters, buffer.
including the terminating zero.
It would be dangerous to use sprintf, because the code wouldn't It would be dangerous to use sprintf, because the code wouldn't
work on a machine with gcc-provided long long support, but without work on a machine with gcc-provided long long support, but without
libc support for "%lld". However, such platforms will typically libc support for "%lld". However, such old systems platforms
not have snprintf and will use our version, which does support typically lack snprintf and will end up using our version, which
"%lld" where long longs are available. */ does support "%lld" whereever long longs are available. */
static void static void
large_int_to_string (char *buffer, LARGE_INT number) large_int_to_string (char *buffer, int bufsize, LARGE_INT number)
{ {
snprintf (buffer, 24, LARGE_INT_FMT, number); snprintf (buffer, bufsize, LARGE_INT_FMT, number);
} }
/* The same as legible(), but works on LARGE_INT. */ /* The same as with_thousand_seps, but works on LARGE_INT. */
char * char *
legible_large_int (LARGE_INT l) with_thousand_seps_large (LARGE_INT l)
{ {
char inbuf[48]; char inbuf[48];
large_int_to_string (inbuf, l); large_int_to_string (inbuf, sizeof (inbuf), l);
return legible_1 (inbuf); return add_thousand_seps (inbuf);
}
/* N, a byte quantity, is converted to a human-readable abberviated
form a la sizes printed by `ls -lh'. The result is written to a
static buffer, a pointer to which is returned.
Unlike `with_thousand_seps', this approximates to the nearest unit.
Quoting GNU libit: "Most people visually process strings of 3-4
digits effectively, but longer strings of digits are more prone to
misinterpretation. Hence, converting to an abbreviated form
usually improves readability."
This intentionally uses kilobyte (KB), megabyte (MB), etc. in their
original computer science meaning of "multiples of 1024".
Multiples of 1000 would be useless since Wget already adds thousand
separators for legibility. We don't use the "*bibyte" names
invented in 1998, and seldom used in practice. Wikipedia's entry
on kilobyte discusses this in some detail. */
char *
human_readable (wgint n)
{
/* These suffixes are compatible with those of GNU `ls -lh'. */
static char powers[] =
{
'K', /* kilobyte, 2^10 bytes */
'M', /* megabyte, 2^20 bytes */
'G', /* gigabyte, 2^30 bytes */
'T', /* terabyte, 2^40 bytes */
'P', /* petabyte, 2^50 bytes */
'E', /* exabyte, 2^60 bytes */
};
static char buf[8];
int i;
/* If the quantity is smaller than 1K, just print it. */
if (n < 1024)
{
snprintf (buf, sizeof (buf), "%d", (int) n);
return buf;
}
/* Loop over powers, dividing N with 1024 in each iteration. This
works unchanged for all sizes of wgint, while still avoiding
non-portable `long double' arithmetic. */
for (i = 0; i < countof (powers); i++)
{
/* At each iteration N is greater than the *subsequent* power.
That way N/1024.0 produces a decimal number in the units of
*this* power. */
if ((n >> 10) < 1024 || i == countof (powers) - 1)
{
/* Must cast to long first because MS VC can't directly cast
__int64 to double. (This is safe because N is known to
be <2**20.) */
double val = (double) (long) n / 1024.0;
/* Print values smaller than 10 with one decimal digits, and
others without any decimals. */
snprintf (buf, sizeof (buf), "%.*f%c",
val < 10 ? 1 : 0, val, powers[i]);
return buf;
}
n >>= 10;
}
return NULL; /* unreached */
} }
/* Count the digits in an integer number. */ /* Count the digits in an integer number. */

View File

@ -112,8 +112,9 @@ int string_set_contains PARAMS ((struct hash_table *, const char *));
void string_set_free PARAMS ((struct hash_table *)); void string_set_free PARAMS ((struct hash_table *));
void free_keys_and_values PARAMS ((struct hash_table *)); void free_keys_and_values PARAMS ((struct hash_table *));
char *legible PARAMS ((wgint)); char *with_thousand_seps PARAMS ((wgint));
char *legible_large_int PARAMS ((LARGE_INT)); char *with_thousand_seps_large PARAMS ((LARGE_INT));
char *human_readable PARAMS ((wgint));
int numdigit PARAMS ((wgint)); int numdigit PARAMS ((wgint));
char *number_to_string PARAMS ((char *, wgint)); char *number_to_string PARAMS ((char *, wgint));
char *number_to_static_string PARAMS ((wgint)); char *number_to_static_string PARAMS ((wgint));