[svn] Make indentation consistent (all-spaces, no tabs).

This commit is contained in:
micah 2007-08-02 20:38:21 -07:00
parent 2fe72be505
commit 7d2066b221
29 changed files with 5744 additions and 5744 deletions

View File

@ -74,7 +74,7 @@ typedef char *pointer;
#endif #endif
#ifndef NULL #ifndef NULL
#define NULL 0 #define NULL 0
#endif #endif
/* Different portions of Emacs need to call different versions of /* Different portions of Emacs need to call different versions of
@ -103,37 +103,37 @@ extern pointer malloc ();
STACK_DIRECTION = 0 => direction of growth unknown */ STACK_DIRECTION = 0 => direction of growth unknown */
#ifndef STACK_DIRECTION #ifndef STACK_DIRECTION
#define STACK_DIRECTION 0 /* Direction unknown. */ #define STACK_DIRECTION 0 /* Direction unknown. */
#endif #endif
#if STACK_DIRECTION != 0 #if STACK_DIRECTION != 0
#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */ #define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
#else /* STACK_DIRECTION == 0; need run-time code. */ #else /* STACK_DIRECTION == 0; need run-time code. */
static int stack_dir; /* 1 or -1 once known. */ static int stack_dir; /* 1 or -1 once known. */
#define STACK_DIR stack_dir #define STACK_DIR stack_dir
static void static void
find_stack_direction () find_stack_direction ()
{ {
static char *addr = NULL; /* Address of first `dummy', once known. */ static char *addr = NULL; /* Address of first `dummy', once known. */
auto char dummy; /* To get stack address. */ auto char dummy; /* To get stack address. */
if (addr == NULL) if (addr == NULL)
{ /* Initial entry. */ { /* Initial entry. */
addr = ADDRESS_FUNCTION (dummy); addr = ADDRESS_FUNCTION (dummy);
find_stack_direction (); /* Recurse once. */ find_stack_direction (); /* Recurse once. */
} }
else else
{ {
/* Second entry. */ /* Second entry. */
if (ADDRESS_FUNCTION (dummy) > addr) if (ADDRESS_FUNCTION (dummy) > addr)
stack_dir = 1; /* Stack grew upward. */ stack_dir = 1; /* Stack grew upward. */
else else
stack_dir = -1; /* Stack grew downward. */ stack_dir = -1; /* Stack grew downward. */
} }
} }
@ -146,21 +146,21 @@ find_stack_direction ()
It is very important that sizeof(header) agree with malloc It is very important that sizeof(header) agree with malloc
alignment chunk size. The following default should work okay. */ alignment chunk size. The following default should work okay. */
#ifndef ALIGN_SIZE #ifndef ALIGN_SIZE
#define ALIGN_SIZE sizeof(double) #define ALIGN_SIZE sizeof(double)
#endif #endif
typedef union hdr typedef union hdr
{ {
char align[ALIGN_SIZE]; /* To force sizeof(header). */ char align[ALIGN_SIZE]; /* To force sizeof(header). */
struct struct
{ {
union hdr *next; /* For chaining headers. */ union hdr *next; /* For chaining headers. */
char *deep; /* For stack depth measure. */ char *deep; /* For stack depth measure. */
} h; } h;
} header; } header;
static header *last_alloca_header = NULL; /* -> last alloca header. */ static header *last_alloca_header = NULL; /* -> last alloca header. */
/* Return a pointer to at least SIZE bytes of storage, /* Return a pointer to at least SIZE bytes of storage,
which will be automatically reclaimed upon exit from which will be automatically reclaimed upon exit from
@ -173,11 +173,11 @@ pointer
alloca (size) alloca (size)
unsigned size; unsigned size;
{ {
auto char probe; /* Probes stack depth: */ auto char probe; /* Probes stack depth: */
register char *depth = ADDRESS_FUNCTION (probe); register char *depth = ADDRESS_FUNCTION (probe);
#if STACK_DIRECTION == 0 #if STACK_DIRECTION == 0
if (STACK_DIR == 0) /* Unknown growth direction. */ if (STACK_DIR == 0) /* Unknown growth direction. */
find_stack_direction (); find_stack_direction ();
#endif #endif
@ -185,7 +185,7 @@ alloca (size)
was allocated from deeper in the stack than currently. */ was allocated from deeper in the stack than currently. */
{ {
register header *hp; /* Traverses linked list. */ register header *hp; /* Traverses linked list. */
#ifdef emacs #ifdef emacs
BLOCK_INPUT; BLOCK_INPUT;
@ -193,18 +193,18 @@ alloca (size)
for (hp = last_alloca_header; hp != NULL;) for (hp = last_alloca_header; hp != NULL;)
if ((STACK_DIR > 0 && hp->h.deep > depth) if ((STACK_DIR > 0 && hp->h.deep > depth)
|| (STACK_DIR < 0 && hp->h.deep < depth)) || (STACK_DIR < 0 && hp->h.deep < depth))
{ {
register header *np = hp->h.next; register header *np = hp->h.next;
free ((pointer) hp); /* Collect garbage. */ free ((pointer) hp); /* Collect garbage. */
hp = np; /* -> next header. */ hp = np; /* -> next header. */
} }
else else
break; /* Rest are not deeper. */ break; /* Rest are not deeper. */
last_alloca_header = hp; /* -> last valid storage. */ last_alloca_header = hp; /* -> last valid storage. */
#ifdef emacs #ifdef emacs
UNBLOCK_INPUT; UNBLOCK_INPUT;
@ -212,7 +212,7 @@ alloca (size)
} }
if (size == 0) if (size == 0)
return NULL; /* No allocation required. */ return NULL; /* No allocation required. */
/* Allocate combined header + user data storage. */ /* Allocate combined header + user data storage. */
@ -246,10 +246,10 @@ alloca (size)
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */ /* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
struct stack_control_header struct stack_control_header
{ {
long shgrow:32; /* Number of times stack has grown. */ long shgrow:32; /* Number of times stack has grown. */
long shaseg:32; /* Size of increments to stack. */ long shaseg:32; /* Size of increments to stack. */
long shhwm:32; /* High water mark of stack. */ long shhwm:32; /* High water mark of stack. */
long shsize:32; /* Current size of stack (all segments). */ long shsize:32; /* Current size of stack (all segments). */
}; };
/* The stack segment linkage control information occurs at /* The stack segment linkage control information occurs at
@ -261,21 +261,21 @@ struct stack_control_header
struct stack_segment_linkage struct stack_segment_linkage
{ {
long ss[0200]; /* 0200 overflow words. */ long ss[0200]; /* 0200 overflow words. */
long sssize:32; /* Number of words in this segment. */ long sssize:32; /* Number of words in this segment. */
long ssbase:32; /* Offset to stack base. */ long ssbase:32; /* Offset to stack base. */
long:32; long:32;
long sspseg:32; /* Offset to linkage control of previous long sspseg:32; /* Offset to linkage control of previous
segment of stack. */ segment of stack. */
long:32; long:32;
long sstcpt:32; /* Pointer to task common address block. */ long sstcpt:32; /* Pointer to task common address block. */
long sscsnm; /* Private control structure number for long sscsnm; /* Private control structure number for
microtasking. */ microtasking. */
long ssusr1; /* Reserved for user. */ long ssusr1; /* Reserved for user. */
long ssusr2; /* Reserved for user. */ long ssusr2; /* Reserved for user. */
long sstpid; /* Process ID for pid based multi-tasking. */ long sstpid; /* Process ID for pid based multi-tasking. */
long ssgvup; /* Pointer to multitasking thread giveup. */ long ssgvup; /* Pointer to multitasking thread giveup. */
long sscray[7]; /* Reserved for Cray Research. */ long sscray[7]; /* Reserved for Cray Research. */
long ssa0; long ssa0;
long ssa1; long ssa1;
long ssa2; long ssa2;
@ -299,27 +299,27 @@ struct stack_segment_linkage
returned by the STKSTAT library routine. */ returned by the STKSTAT library routine. */
struct stk_stat struct stk_stat
{ {
long now; /* Current total stack size. */ long now; /* Current total stack size. */
long maxc; /* Amount of contiguous space which would long maxc; /* Amount of contiguous space which would
be required to satisfy the maximum be required to satisfy the maximum
stack demand to date. */ stack demand to date. */
long high_water; /* Stack high-water mark. */ long high_water; /* Stack high-water mark. */
long overflows; /* Number of stack overflow ($STKOFEN) calls. */ long overflows; /* Number of stack overflow ($STKOFEN) calls. */
long hits; /* Number of internal buffer hits. */ long hits; /* Number of internal buffer hits. */
long extends; /* Number of block extensions. */ long extends; /* Number of block extensions. */
long stko_mallocs; /* Block allocations by $STKOFEN. */ long stko_mallocs; /* Block allocations by $STKOFEN. */
long underflows; /* Number of stack underflow calls ($STKRETN). */ long underflows; /* Number of stack underflow calls ($STKRETN). */
long stko_free; /* Number of deallocations by $STKRETN. */ long stko_free; /* Number of deallocations by $STKRETN. */
long stkm_free; /* Number of deallocations by $STKMRET. */ long stkm_free; /* Number of deallocations by $STKMRET. */
long segments; /* Current number of stack segments. */ long segments; /* Current number of stack segments. */
long maxs; /* Maximum number of stack segments so far. */ long maxs; /* Maximum number of stack segments so far. */
long pad_size; /* Stack pad size. */ long pad_size; /* Stack pad size. */
long current_address; /* Current stack segment address. */ long current_address; /* Current stack segment address. */
long current_size; /* Current stack segment size. This long current_size; /* Current stack segment size. This
number is actually corrupted by STKSTAT to number is actually corrupted by STKSTAT to
include the fifteen word trailer area. */ include the fifteen word trailer area. */
long initial_address; /* Address of initial segment. */ long initial_address; /* Address of initial segment. */
long initial_size; /* Size of initial segment. */ long initial_size; /* Size of initial segment. */
}; };
/* The following structure describes the data structure which trails /* The following structure describes the data structure which trails
@ -328,13 +328,13 @@ struct stk_stat
struct stk_trailer struct stk_trailer
{ {
long this_address; /* Address of this block. */ long this_address; /* Address of this block. */
long this_size; /* Size of this block (does not include long this_size; /* Size of this block (does not include
this trailer). */ this trailer). */
long unknown2; long unknown2;
long unknown3; long unknown3;
long link; /* Address of trailer block of previous long link; /* Address of trailer block of previous
segment. */ segment. */
long unknown5; long unknown5;
long unknown6; long unknown6;
long unknown7; long unknown7;
@ -372,8 +372,8 @@ i00afunc (long *address)
/* Set up the iteration. */ /* Set up the iteration. */
trailer = (struct stk_trailer *) (status.current_address trailer = (struct stk_trailer *) (status.current_address
+ status.current_size + status.current_size
- 15); - 15);
/* There must be at least one stack segment. Therefore it is /* There must be at least one stack segment. Therefore it is
a fatal error if "trailer" is null. */ a fatal error if "trailer" is null. */
@ -388,10 +388,10 @@ i00afunc (long *address)
block = (long *) trailer->this_address; block = (long *) trailer->this_address;
size = trailer->this_size; size = trailer->this_size;
if (block == 0 || size == 0) if (block == 0 || size == 0)
abort (); abort ();
trailer = (struct stk_trailer *) trailer->link; trailer = (struct stk_trailer *) trailer->link;
if ((block <= address) && (address < (block + size))) if ((block <= address) && (address < (block + size)))
break; break;
} }
/* Set the result to the offset in this segment and add the sizes /* Set the result to the offset in this segment and add the sizes
@ -407,7 +407,7 @@ i00afunc (long *address)
do do
{ {
if (trailer->this_size <= 0) if (trailer->this_size <= 0)
abort (); abort ();
result += trailer->this_size; result += trailer->this_size;
trailer = (struct stk_trailer *) trailer->link; trailer = (struct stk_trailer *) trailer->link;
} }
@ -470,7 +470,7 @@ i00afunc (long address)
fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl); fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
#endif #endif
if (pseg == 0) if (pseg == 0)
break; break;
stkl = stkl - pseg; stkl = stkl - pseg;
ssptr = (struct stack_segment_linkage *) stkl; ssptr = (struct stack_segment_linkage *) stkl;
size = ssptr->sssize; size = ssptr->sssize;

1590
src/cmpt.c

File diff suppressed because it is too large Load Diff

View File

@ -76,25 +76,25 @@ sockaddr_set_data (struct sockaddr *sa, const ip_address *ip, int port)
{ {
case AF_INET: case AF_INET:
{ {
struct sockaddr_in *sin = (struct sockaddr_in *)sa; struct sockaddr_in *sin = (struct sockaddr_in *)sa;
xzero (*sin); xzero (*sin);
sin->sin_family = AF_INET; sin->sin_family = AF_INET;
sin->sin_port = htons (port); sin->sin_port = htons (port);
sin->sin_addr = ip->data.d4; sin->sin_addr = ip->data.d4;
break; break;
} }
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
case AF_INET6: case AF_INET6:
{ {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
xzero (*sin6); xzero (*sin6);
sin6->sin6_family = AF_INET6; sin6->sin6_family = AF_INET6;
sin6->sin6_port = htons (port); sin6->sin6_port = htons (port);
sin6->sin6_addr = ip->data.d6; sin6->sin6_addr = ip->data.d6;
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
sin6->sin6_scope_id = ip->ipv6_scope; sin6->sin6_scope_id = ip->ipv6_scope;
#endif #endif
break; break;
} }
#endif /* ENABLE_IPV6 */ #endif /* ENABLE_IPV6 */
default: default:
@ -113,31 +113,31 @@ sockaddr_get_data (const struct sockaddr *sa, ip_address *ip, int *port)
{ {
case AF_INET: case AF_INET:
{ {
struct sockaddr_in *sin = (struct sockaddr_in *)sa; struct sockaddr_in *sin = (struct sockaddr_in *)sa;
if (ip) if (ip)
{ {
ip->family = AF_INET; ip->family = AF_INET;
ip->data.d4 = sin->sin_addr; ip->data.d4 = sin->sin_addr;
} }
if (port) if (port)
*port = ntohs (sin->sin_port); *port = ntohs (sin->sin_port);
break; break;
} }
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
case AF_INET6: case AF_INET6:
{ {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
if (ip) if (ip)
{ {
ip->family = AF_INET6; ip->family = AF_INET6;
ip->data.d6 = sin6->sin6_addr; ip->data.d6 = sin6->sin6_addr;
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
ip->ipv6_scope = sin6->sin6_scope_id; ip->ipv6_scope = sin6->sin6_scope_id;
#endif #endif
} }
if (port) if (port)
*port = ntohs (sin6->sin6_port); *port = ntohs (sin6->sin6_port);
break; break;
} }
#endif #endif
default: default:
@ -182,7 +182,7 @@ resolve_bind_address (struct sockaddr *sa)
if (called) if (called)
{ {
if (should_bind) if (should_bind)
sockaddr_set_data (sa, &ip, 0); sockaddr_set_data (sa, &ip, 0);
return should_bind; return should_bind;
} }
called = true; called = true;
@ -192,8 +192,8 @@ resolve_bind_address (struct sockaddr *sa)
{ {
/* #### We should be able to print the error message here. */ /* #### We should be able to print the error message here. */
logprintf (LOG_NOTQUIET, logprintf (LOG_NOTQUIET,
_("%s: unable to resolve bind address `%s'; disabling bind.\n"), _("%s: unable to resolve bind address `%s'; disabling bind.\n"),
exec_name, opt.bind_address); exec_name, opt.bind_address);
should_bind = false; should_bind = false;
return false; return false;
} }
@ -229,7 +229,7 @@ connect_with_timeout_callback (void *arg)
static int static int
connect_with_timeout (int fd, const struct sockaddr *addr, socklen_t addrlen, connect_with_timeout (int fd, const struct sockaddr *addr, socklen_t addrlen,
double timeout) double timeout)
{ {
struct cwt_context ctx; struct cwt_context ctx;
ctx.fd = fd; ctx.fd = fd;
@ -264,10 +264,10 @@ connect_to_ip (const ip_address *ip, int port, const char *print)
{ {
const char *txt_addr = print_address (ip); const char *txt_addr = print_address (ip);
if (print && 0 != strcmp (print, txt_addr)) if (print && 0 != strcmp (print, txt_addr))
logprintf (LOG_VERBOSE, _("Connecting to %s|%s|:%d... "), logprintf (LOG_VERBOSE, _("Connecting to %s|%s|:%d... "),
escnonprint (print), txt_addr, port); escnonprint (print), txt_addr, port);
else else
logprintf (LOG_VERBOSE, _("Connecting to %s:%d... "), txt_addr, port); logprintf (LOG_VERBOSE, _("Connecting to %s:%d... "), txt_addr, port);
} }
/* Store the sockaddr info to SA. */ /* Store the sockaddr info to SA. */
@ -285,7 +285,7 @@ connect_to_ip (const ip_address *ip, int port, const char *print)
int err = setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)); int err = setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on));
IF_DEBUG IF_DEBUG
if (err < 0) if (err < 0)
DEBUGP (("Failed setting IPV6_V6ONLY: %s", strerror (errno))); DEBUGP (("Failed setting IPV6_V6ONLY: %s", strerror (errno)));
} }
#endif #endif
@ -297,31 +297,31 @@ connect_to_ip (const ip_address *ip, int port, const char *print)
{ {
int bufsize = opt.limit_rate; int bufsize = opt.limit_rate;
if (bufsize < 512) if (bufsize < 512)
bufsize = 512; /* avoid pathologically small values */ bufsize = 512; /* avoid pathologically small values */
#ifdef SO_RCVBUF #ifdef SO_RCVBUF
setsockopt (sock, SOL_SOCKET, SO_RCVBUF, setsockopt (sock, SOL_SOCKET, SO_RCVBUF,
(void *)&bufsize, (socklen_t)sizeof (bufsize)); (void *)&bufsize, (socklen_t)sizeof (bufsize));
#endif #endif
/* When we add limit_rate support for writing, which is useful /* When we add limit_rate support for writing, which is useful
for POST, we should also set SO_SNDBUF here. */ for POST, we should also set SO_SNDBUF here. */
} }
if (opt.bind_address) if (opt.bind_address)
{ {
/* Bind the client side of the socket to the requested /* Bind the client side of the socket to the requested
address. */ address. */
struct sockaddr_storage bind_ss; struct sockaddr_storage bind_ss;
struct sockaddr *bind_sa = (struct sockaddr *)&bind_ss; struct sockaddr *bind_sa = (struct sockaddr *)&bind_ss;
if (resolve_bind_address (bind_sa)) if (resolve_bind_address (bind_sa))
{ {
if (bind (sock, bind_sa, sockaddr_size (bind_sa)) < 0) if (bind (sock, bind_sa, sockaddr_size (bind_sa)) < 0)
goto err; goto err;
} }
} }
/* Connect the socket to the remote endpoint. */ /* Connect the socket to the remote endpoint. */
if (connect_with_timeout (sock, sa, sockaddr_size (sa), if (connect_with_timeout (sock, sa, sockaddr_size (sa),
opt.connect_timeout) < 0) opt.connect_timeout) < 0)
goto err; goto err;
/* Success. */ /* Success. */
@ -369,15 +369,15 @@ connect_to_host (const char *host, int port)
const ip_address *ip = address_list_address_at (al, i); const ip_address *ip = address_list_address_at (al, i);
sock = connect_to_ip (ip, port, host); sock = connect_to_ip (ip, port, host);
if (sock >= 0) if (sock >= 0)
{ {
/* Success. */ /* Success. */
address_list_set_connected (al); address_list_set_connected (al);
address_list_release (al); address_list_release (al);
return sock; return sock;
} }
/* The attempt to connect has failed. Continue with the loop /* The attempt to connect has failed. Continue with the loop
and try next address. */ and try next address. */
address_list_set_faulty (al, i); address_list_set_faulty (al, i);
} }
@ -387,7 +387,7 @@ connect_to_host (const char *host, int port)
if (address_list_connected_p (al)) if (address_list_connected_p (al))
{ {
/* We connected to AL before, but cannot do so now. That might /* We connected to AL before, but cannot do so now. That might
indicate that our DNS cache entry for HOST has expired. */ indicate that our DNS cache entry for HOST has expired. */
address_list_release (al); address_list_release (al);
al = lookup_host (host, LH_REFRESH); al = lookup_host (host, LH_REFRESH);
goto retry; goto retry;
@ -444,17 +444,17 @@ bind_local (const ip_address *bind_address, int *port)
{ {
socklen_t addrlen = sockaddr_size (sa); socklen_t addrlen = sockaddr_size (sa);
if (getsockname (sock, sa, &addrlen) < 0) if (getsockname (sock, sa, &addrlen) < 0)
{ {
/* If we can't find out the socket's local address ("name"), /* If we can't find out the socket's local address ("name"),
something is seriously wrong with the socket, and it's something is seriously wrong with the socket, and it's
unusable for us anyway because we must know the chosen unusable for us anyway because we must know the chosen
port. */ port. */
fd_close (sock); fd_close (sock);
return -1; return -1;
} }
sockaddr_get_data (sa, NULL, port); sockaddr_get_data (sa, NULL, port);
DEBUGP (("binding to address %s using port %i.\n", DEBUGP (("binding to address %s using port %i.\n",
print_address (bind_address), *port)); print_address (bind_address), *port));
} }
if (listen (sock, 1) < 0) if (listen (sock, 1) < 0)
{ {
@ -489,9 +489,9 @@ accept_connection (int local_sock)
{ {
int test = select_fd (local_sock, opt.connect_timeout, WAIT_FOR_READ); int test = select_fd (local_sock, opt.connect_timeout, WAIT_FOR_READ);
if (test == 0) if (test == 0)
errno = ETIMEDOUT; errno = ETIMEDOUT;
if (test <= 0) if (test <= 0)
return -1; return -1;
} }
sock = accept (local_sock, sa, &addrlen); sock = accept (local_sock, sa, &addrlen);
DEBUGP (("Accepted client at socket %d.\n", sock)); DEBUGP (("Accepted client at socket %d.\n", sock));
@ -528,21 +528,21 @@ socket_ip_address (int sock, ip_address *ip, int endpoint)
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
case AF_INET6: case AF_INET6:
{ {
struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&storage; struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&storage;
ip->data.d6 = sa6->sin6_addr; ip->data.d6 = sa6->sin6_addr;
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
ip->ipv6_scope = sa6->sin6_scope_id; ip->ipv6_scope = sa6->sin6_scope_id;
#endif #endif
DEBUGP (("conaddr is: %s\n", print_address (ip))); DEBUGP (("conaddr is: %s\n", print_address (ip)));
return true; return true;
} }
#endif #endif
case AF_INET: case AF_INET:
{ {
struct sockaddr_in *sa = (struct sockaddr_in *)&storage; struct sockaddr_in *sa = (struct sockaddr_in *)&storage;
ip->data.d4 = sa->sin_addr; ip->data.d4 = sa->sin_addr;
DEBUGP (("conaddr is: %s\n", print_address (ip))); DEBUGP (("conaddr is: %s\n", print_address (ip)));
return true; return true;
} }
default: default:
abort (); abort ();
@ -567,7 +567,7 @@ retryable_socket_connect_error (int err)
#ifdef EPFNOSUPPORT #ifdef EPFNOSUPPORT
|| err == EPFNOSUPPORT || err == EPFNOSUPPORT
#endif #endif
#ifdef ESOCKTNOSUPPORT /* no, "sockt" is not a typo! */ #ifdef ESOCKTNOSUPPORT /* no, "sockt" is not a typo! */
|| err == ESOCKTNOSUPPORT || err == ESOCKTNOSUPPORT
#endif #endif
#ifdef EPROTONOSUPPORT #ifdef EPROTONOSUPPORT
@ -577,7 +577,7 @@ retryable_socket_connect_error (int err)
|| err == ENOPROTOOPT || err == ENOPROTOOPT
#endif #endif
/* Apparently, older versions of Linux and BSD used EINVAL /* Apparently, older versions of Linux and BSD used EINVAL
instead of EAFNOSUPPORT and such. */ instead of EAFNOSUPPORT and such. */
|| err == EINVAL || err == EINVAL
) )
return false; return false;
@ -585,12 +585,12 @@ retryable_socket_connect_error (int err)
if (!opt.retry_connrefused) if (!opt.retry_connrefused)
if (err == ECONNREFUSED if (err == ECONNREFUSED
#ifdef ENETUNREACH #ifdef ENETUNREACH
|| err == ENETUNREACH /* network is unreachable */ || err == ENETUNREACH /* network is unreachable */
#endif #endif
#ifdef EHOSTUNREACH #ifdef EHOSTUNREACH
|| err == EHOSTUNREACH /* host is unreachable */ || err == EHOSTUNREACH /* host is unreachable */
#endif #endif
) )
return false; return false;
return true; return true;
@ -787,21 +787,21 @@ fd_transport_context (int fd)
This is a macro because we want the static storage variables to be This is a macro because we want the static storage variables to be
per-function. */ per-function. */
#define LAZY_RETRIEVE_INFO(info) do { \ #define LAZY_RETRIEVE_INFO(info) do { \
static struct transport_info *last_info; \ static struct transport_info *last_info; \
static int last_fd = -1; \ static int last_fd = -1; \
static unsigned int last_tick; \ static unsigned int last_tick; \
if (!transport_map) \ if (!transport_map) \
info = NULL; \ info = NULL; \
else if (last_fd == fd && last_tick == transport_map_modified_tick) \ else if (last_fd == fd && last_tick == transport_map_modified_tick) \
info = last_info; \ info = last_info; \
else \ else \
{ \ { \
info = hash_table_get (transport_map, (void *)(intptr_t) fd); \ info = hash_table_get (transport_map, (void *)(intptr_t) fd); \
last_fd = fd; \ last_fd = fd; \
last_info = info; \ last_info = info; \
last_tick = transport_map_modified_tick; \ last_tick = transport_map_modified_tick; \
} \ } \
} while (0) } while (0)
static bool static bool
@ -813,13 +813,13 @@ poll_internal (int fd, struct transport_info *info, int wf, double timeout)
{ {
int test; int test;
if (info && info->imp->poller) if (info && info->imp->poller)
test = info->imp->poller (fd, timeout, wf, info->ctx); test = info->imp->poller (fd, timeout, wf, info->ctx);
else else
test = sock_poll (fd, timeout, wf); test = sock_poll (fd, timeout, wf);
if (test == 0) if (test == 0)
errno = ETIMEDOUT; errno = ETIMEDOUT;
if (test <= 0) if (test <= 0)
return false; return false;
} }
return true; return true;
} }
@ -885,13 +885,13 @@ fd_write (int fd, char *buf, int bufsize, double timeout)
while (bufsize > 0) while (bufsize > 0)
{ {
if (!poll_internal (fd, info, WAIT_FOR_WRITE, timeout)) if (!poll_internal (fd, info, WAIT_FOR_WRITE, timeout))
return -1; return -1;
if (info && info->imp->writer) if (info && info->imp->writer)
res = info->imp->writer (fd, buf, bufsize, info->ctx); res = info->imp->writer (fd, buf, bufsize, info->ctx);
else else
res = sock_write (fd, buf, bufsize); res = sock_write (fd, buf, bufsize);
if (res <= 0) if (res <= 0)
break; break;
buf += res; buf += res;
bufsize -= res; bufsize -= res;
} }
@ -921,7 +921,7 @@ fd_errstr (int fd)
{ {
const char *err = info->imp->errstr (fd, info->ctx); const char *err = info->imp->errstr (fd, info->ctx);
if (err) if (err)
return err; return err;
/* else, fall through and print the system error. */ /* else, fall through and print the system error. */
} }
return strerror (errno); return strerror (errno);

File diff suppressed because it is too large Load Diff

View File

@ -65,30 +65,30 @@ ftp_response (int fd, char **ret_line)
char *p; char *p;
char *line = fd_read_line (fd); char *line = fd_read_line (fd);
if (!line) if (!line)
return FTPRERR; return FTPRERR;
/* Strip trailing CRLF before printing the line, so that /* Strip trailing CRLF before printing the line, so that
escnonprint doesn't include bogus \012 and \015. */ escnonprint doesn't include bogus \012 and \015. */
p = strchr (line, '\0'); p = strchr (line, '\0');
if (p > line && p[-1] == '\n') if (p > line && p[-1] == '\n')
*--p = '\0'; *--p = '\0';
if (p > line && p[-1] == '\r') if (p > line && p[-1] == '\r')
*--p = '\0'; *--p = '\0';
if (opt.server_response) if (opt.server_response)
logprintf (LOG_NOTQUIET, "%s\n", escnonprint (line)); logprintf (LOG_NOTQUIET, "%s\n", escnonprint (line));
else else
DEBUGP (("%s\n", escnonprint (line))); DEBUGP (("%s\n", escnonprint (line)));
/* The last line of output is the one that begins with "ddd ". */ /* The last line of output is the one that begins with "ddd ". */
if (ISDIGIT (line[0]) && ISDIGIT (line[1]) && ISDIGIT (line[2]) if (ISDIGIT (line[0]) && ISDIGIT (line[1]) && ISDIGIT (line[2])
&& line[3] == ' ') && line[3] == ' ')
{ {
strncpy (ftp_last_respline, line, sizeof (ftp_last_respline)); strncpy (ftp_last_respline, line, sizeof (ftp_last_respline));
ftp_last_respline[sizeof (ftp_last_respline) - 1] = '\0'; ftp_last_respline[sizeof (ftp_last_respline) - 1] = '\0';
*ret_line = line; *ret_line = line;
return FTPOK; return FTPOK;
} }
xfree (line); xfree (line);
} }
} }
@ -103,23 +103,23 @@ ftp_request (const char *command, const char *value)
if (value) if (value)
{ {
/* Check for newlines in VALUE (possibly injected by the %0A URL /* Check for newlines in VALUE (possibly injected by the %0A URL
escape) making the callers inadvertently send multiple FTP escape) making the callers inadvertently send multiple FTP
commands at once. Without this check an attacker could commands at once. Without this check an attacker could
intentionally redirect to ftp://server/fakedir%0Acommand.../ intentionally redirect to ftp://server/fakedir%0Acommand.../
and execute arbitrary FTP command on a remote FTP server. */ and execute arbitrary FTP command on a remote FTP server. */
if (strpbrk (value, "\r\n")) if (strpbrk (value, "\r\n"))
{ {
/* Copy VALUE to the stack and modify CR/LF to space. */ /* Copy VALUE to the stack and modify CR/LF to space. */
char *defanged, *p; char *defanged, *p;
STRDUP_ALLOCA (defanged, value); STRDUP_ALLOCA (defanged, value);
for (p = defanged; *p; p++) for (p = defanged; *p; p++)
if (*p == '\r' || *p == '\n') if (*p == '\r' || *p == '\n')
*p = ' '; *p = ' ';
DEBUGP (("\nDetected newlines in %s \"%s\"; changing to %s \"%s\"\n", DEBUGP (("\nDetected newlines in %s \"%s\"; changing to %s \"%s\"\n",
command, escnonprint (value), command, escnonprint (defanged))); command, escnonprint (value), command, escnonprint (defanged)));
/* Make VALUE point to the defanged copy of the string. */ /* Make VALUE point to the defanged copy of the string. */
value = defanged; value = defanged;
} }
res = concat_strings (command, " ", value, "\r\n", (char *) 0); res = concat_strings (command, " ", value, "\r\n", (char *) 0);
} }
else else
@ -192,29 +192,29 @@ ftp_login (int csock, const char *acc, const char *pass)
for (i = 0; i < countof (skey_head); i++) for (i = 0; i < countof (skey_head); i++)
{ {
int l = strlen (skey_head[i]); int l = strlen (skey_head[i]);
if (0 == strncasecmp (skey_head[i], respline, l)) if (0 == strncasecmp (skey_head[i], respline, l))
{ {
seed = respline + l; seed = respline + l;
break; break;
} }
} }
if (seed) if (seed)
{ {
int skey_sequence = 0; int skey_sequence = 0;
/* Extract the sequence from SEED. */ /* Extract the sequence from SEED. */
for (; ISDIGIT (*seed); seed++) for (; ISDIGIT (*seed); seed++)
skey_sequence = 10 * skey_sequence + *seed - '0'; skey_sequence = 10 * skey_sequence + *seed - '0';
if (*seed == ' ') if (*seed == ' ')
++seed; ++seed;
else else
{ {
xfree (respline); xfree (respline);
return FTPLOGREFUSED; return FTPLOGREFUSED;
} }
/* Replace the password with the SKEY response to the /* Replace the password with the SKEY response to the
challenge. */ challenge. */
pass = skey_response (skey_sequence, seed, pass); pass = skey_response (skey_sequence, seed, pass);
} }
} }
@ -333,16 +333,16 @@ ip_address_to_lprt_repr (const ip_address *addr, int port, char *buf,
{ {
case AF_INET: case AF_INET:
snprintf (buf, buflen, "%d,%d,%d,%d,%d,%d,%d,%d,%d", 4, 4, snprintf (buf, buflen, "%d,%d,%d,%d,%d,%d,%d,%d,%d", 4, 4,
ptr[0], ptr[1], ptr[2], ptr[3], 2, ptr[0], ptr[1], ptr[2], ptr[3], 2,
(port & 0xff00) >> 8, port & 0xff); (port & 0xff00) >> 8, port & 0xff);
break; break;
case AF_INET6: case AF_INET6:
snprintf (buf, buflen, snprintf (buf, buflen,
"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
6, 16, 6, 16,
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7], ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7],
ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15],
2, (port & 0xff00) >> 8, port & 0xff); 2, (port & 0xff00) >> 8, port & 0xff);
break; break;
default: default:
abort (); abort ();
@ -985,14 +985,14 @@ ftp_list (int csock, const char *file)
{ {
err = FTPNSFOD; err = FTPNSFOD;
} }
else if (*respline == '1') else if (*respline == '1')
{ {
err = FTPOK; err = FTPOK;
ok = true; ok = true;
} }
else else
{ {
err = FTPRERR; err = FTPRERR;
} }
xfree (respline); xfree (respline);
} }
@ -1044,7 +1044,7 @@ ftp_syst (int csock, enum stype *server_type)
else if (!strcasecmp (request, "UNIX")) else if (!strcasecmp (request, "UNIX"))
*server_type = ST_UNIX; *server_type = ST_UNIX;
else if (!strcasecmp (request, "WINDOWS_NT") else if (!strcasecmp (request, "WINDOWS_NT")
|| !strcasecmp (request, "WINDOWS2000")) || !strcasecmp (request, "WINDOWS2000"))
*server_type = ST_WINNT; *server_type = ST_WINNT;
else if (!strcasecmp (request, "MACOS")) else if (!strcasecmp (request, "MACOS"))
*server_type = ST_MACOS; *server_type = ST_MACOS;

View File

@ -41,8 +41,8 @@ so, delete this exception statement from your version. */
#include "utils.h" #include "utils.h"
#include "ftp.h" #include "ftp.h"
#include "url.h" #include "url.h"
#include "convert.h" /* for html_quote_string prototype */ #include "convert.h" /* for html_quote_string prototype */
#include "retr.h" /* for output_stream */ #include "retr.h" /* for output_stream */
/* Converts symbolic permissions to number-style ones, e.g. string /* Converts symbolic permissions to number-style ones, e.g. string
rwxr-xr-x to 755. For now, it knows nothing of rwxr-xr-x to 755. For now, it knows nothing of
@ -58,7 +58,7 @@ symperms (const char *s)
{ {
perms <<= 3; perms <<= 3;
perms += (((s[0] == 'r') << 2) + ((s[1] == 'w') << 1) + perms += (((s[0] == 'r') << 2) + ((s[1] == 'w') << 1) +
(s[2] == 'x' || s[2] == 's')); (s[2] == 'x' || s[2] == 's'));
} }
return perms; return perms;
} }
@ -98,12 +98,12 @@ ftp_parse_unix_ls (const char *file, int ignore_perms)
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
}; };
int next, len, i, error, ignore; int next, len, i, error, ignore;
int year, month, day; /* for time analysis */ int year, month, day; /* for time analysis */
int hour, min, sec; int hour, min, sec;
struct tm timestruct, *tnow; struct tm timestruct, *tnow;
time_t timenow; time_t timenow;
char *line, *tok, *ptok; /* tokenizer */ char *line, *tok, *ptok; /* tokenizer */
struct fileinfo *dir, *l, cur; /* list creation */ struct fileinfo *dir, *l, cur; /* list creation */
fp = fopen (file, "rb"); fp = fopen (file, "rb");
@ -120,270 +120,270 @@ ftp_parse_unix_ls (const char *file, int ignore_perms)
len = clean_line (line); len = clean_line (line);
/* Skip if total... */ /* Skip if total... */
if (!strncasecmp (line, "total", 5)) if (!strncasecmp (line, "total", 5))
{ {
xfree (line); xfree (line);
continue; continue;
} }
/* Get the first token (permissions). */ /* Get the first token (permissions). */
tok = strtok (line, " "); tok = strtok (line, " ");
if (!tok) if (!tok)
{ {
xfree (line); xfree (line);
continue; continue;
} }
cur.name = NULL; cur.name = NULL;
cur.linkto = NULL; cur.linkto = NULL;
/* Decide whether we deal with a file or a directory. */ /* Decide whether we deal with a file or a directory. */
switch (*tok) switch (*tok)
{ {
case '-': case '-':
cur.type = FT_PLAINFILE; cur.type = FT_PLAINFILE;
DEBUGP (("PLAINFILE; ")); DEBUGP (("PLAINFILE; "));
break; break;
case 'd': case 'd':
cur.type = FT_DIRECTORY; cur.type = FT_DIRECTORY;
DEBUGP (("DIRECTORY; ")); DEBUGP (("DIRECTORY; "));
break; break;
case 'l': case 'l':
cur.type = FT_SYMLINK; cur.type = FT_SYMLINK;
DEBUGP (("SYMLINK; ")); DEBUGP (("SYMLINK; "));
break; break;
default: default:
cur.type = FT_UNKNOWN; cur.type = FT_UNKNOWN;
DEBUGP (("UNKNOWN; ")); DEBUGP (("UNKNOWN; "));
break; break;
} }
if (ignore_perms) if (ignore_perms)
{ {
switch (cur.type) switch (cur.type)
{ {
case FT_PLAINFILE: case FT_PLAINFILE:
cur.perms = 0644; cur.perms = 0644;
break; break;
case FT_DIRECTORY: case FT_DIRECTORY:
cur.perms = 0755; cur.perms = 0755;
break; break;
default: default:
/*cur.perms = 1023;*/ /* #### What is this? --hniksic */ /*cur.perms = 1023;*/ /* #### What is this? --hniksic */
cur.perms = 0644; cur.perms = 0644;
} }
DEBUGP (("implicit perms %0o; ", cur.perms)); DEBUGP (("implicit perms %0o; ", cur.perms));
} }
else else
{ {
cur.perms = symperms (tok + 1); cur.perms = symperms (tok + 1);
DEBUGP (("perms %0o; ", cur.perms)); DEBUGP (("perms %0o; ", cur.perms));
} }
error = ignore = 0; /* Erroneous and ignoring entries are error = ignore = 0; /* Erroneous and ignoring entries are
treated equally for now. */ treated equally for now. */
year = hour = min = sec = 0; /* Silence the compiler. */ year = hour = min = sec = 0; /* Silence the compiler. */
month = day = 0; month = day = 0;
next = -1; next = -1;
/* While there are tokens on the line, parse them. Next is the /* While there are tokens on the line, parse them. Next is the
number of tokens left until the filename. number of tokens left until the filename.
Use the month-name token as the "anchor" (the place where the Use the month-name token as the "anchor" (the place where the
position wrt the file name is "known"). When a month name is position wrt the file name is "known"). When a month name is
encountered, `next' is set to 5. Also, the preceding encountered, `next' is set to 5. Also, the preceding
characters are parsed to get the file size. characters are parsed to get the file size.
This tactic is quite dubious when it comes to This tactic is quite dubious when it comes to
internationalization issues (non-English month names), but it internationalization issues (non-English month names), but it
works for now. */ works for now. */
tok = line; tok = line;
while (ptok = tok, while (ptok = tok,
(tok = strtok (NULL, " ")) != NULL) (tok = strtok (NULL, " ")) != NULL)
{ {
--next; --next;
if (next < 0) /* a month name was not encountered */ if (next < 0) /* a month name was not encountered */
{ {
for (i = 0; i < 12; i++) for (i = 0; i < 12; i++)
if (!strcmp (tok, months[i])) if (!strcmp (tok, months[i]))
break; break;
/* If we got a month, it means the token before it is the /* If we got a month, it means the token before it is the
size, and the filename is three tokens away. */ size, and the filename is three tokens away. */
if (i != 12) if (i != 12)
{ {
wgint size; wgint size;
/* Parse the previous token with str_to_wgint. */ /* Parse the previous token with str_to_wgint. */
if (ptok == line) if (ptok == line)
{ {
/* Something has gone wrong during parsing. */ /* Something has gone wrong during parsing. */
error = 1; error = 1;
break; break;
} }
errno = 0; errno = 0;
size = str_to_wgint (ptok, NULL, 10); size = str_to_wgint (ptok, NULL, 10);
if (size == WGINT_MAX && errno == ERANGE) if (size == WGINT_MAX && errno == ERANGE)
/* Out of range -- ignore the size. #### Should /* Out of range -- ignore the size. #### Should
we refuse to start the download. */ we refuse to start the download. */
cur.size = 0; cur.size = 0;
else else
cur.size = size; cur.size = size;
DEBUGP (("size: %s; ", number_to_static_string(cur.size))); DEBUGP (("size: %s; ", number_to_static_string(cur.size)));
month = i; month = i;
next = 5; next = 5;
DEBUGP (("month: %s; ", months[month])); DEBUGP (("month: %s; ", months[month]));
} }
} }
else if (next == 4) /* days */ else if (next == 4) /* days */
{ {
if (tok[1]) /* two-digit... */ if (tok[1]) /* two-digit... */
day = 10 * (*tok - '0') + tok[1] - '0'; day = 10 * (*tok - '0') + tok[1] - '0';
else /* ...or one-digit */ else /* ...or one-digit */
day = *tok - '0'; day = *tok - '0';
DEBUGP (("day: %d; ", day)); DEBUGP (("day: %d; ", day));
} }
else if (next == 3) else if (next == 3)
{ {
/* This ought to be either the time, or the year. Let's /* This ought to be either the time, or the year. Let's
be flexible! be flexible!
If we have a number x, it's a year. If we have x:y, If we have a number x, it's a year. If we have x:y,
it's hours and minutes. If we have x:y:z, z are it's hours and minutes. If we have x:y:z, z are
seconds. */ seconds. */
year = 0; year = 0;
min = hour = sec = 0; min = hour = sec = 0;
/* We must deal with digits. */ /* We must deal with digits. */
if (ISDIGIT (*tok)) if (ISDIGIT (*tok))
{ {
/* Suppose it's year. */ /* Suppose it's year. */
for (; ISDIGIT (*tok); tok++) for (; ISDIGIT (*tok); tok++)
year = (*tok - '0') + 10 * year; year = (*tok - '0') + 10 * year;
if (*tok == ':') if (*tok == ':')
{ {
/* This means these were hours! */ /* This means these were hours! */
hour = year; hour = year;
year = 0; year = 0;
++tok; ++tok;
/* Get the minutes... */ /* Get the minutes... */
for (; ISDIGIT (*tok); tok++) for (; ISDIGIT (*tok); tok++)
min = (*tok - '0') + 10 * min; min = (*tok - '0') + 10 * min;
if (*tok == ':') if (*tok == ':')
{ {
/* ...and the seconds. */ /* ...and the seconds. */
++tok; ++tok;
for (; ISDIGIT (*tok); tok++) for (; ISDIGIT (*tok); tok++)
sec = (*tok - '0') + 10 * sec; sec = (*tok - '0') + 10 * sec;
} }
} }
} }
if (year) if (year)
DEBUGP (("year: %d (no tm); ", year)); DEBUGP (("year: %d (no tm); ", year));
else else
DEBUGP (("time: %02d:%02d:%02d (no yr); ", hour, min, sec)); DEBUGP (("time: %02d:%02d:%02d (no yr); ", hour, min, sec));
} }
else if (next == 2) /* The file name */ else if (next == 2) /* The file name */
{ {
int fnlen; int fnlen;
char *p; char *p;
/* Since the file name may contain a SPC, it is possible /* Since the file name may contain a SPC, it is possible
for strtok to handle it wrong. */ for strtok to handle it wrong. */
fnlen = strlen (tok); fnlen = strlen (tok);
if (fnlen < len - (tok - line)) if (fnlen < len - (tok - line))
{ {
/* So we have a SPC in the file name. Restore the /* So we have a SPC in the file name. Restore the
original. */ original. */
tok[fnlen] = ' '; tok[fnlen] = ' ';
/* If the file is a symbolic link, it should have a /* If the file is a symbolic link, it should have a
` -> ' somewhere. */ ` -> ' somewhere. */
if (cur.type == FT_SYMLINK) if (cur.type == FT_SYMLINK)
{ {
p = strstr (tok, " -> "); p = strstr (tok, " -> ");
if (!p) if (!p)
{ {
error = 1; error = 1;
break; break;
} }
cur.linkto = xstrdup (p + 4); cur.linkto = xstrdup (p + 4);
DEBUGP (("link to: %s\n", cur.linkto)); DEBUGP (("link to: %s\n", cur.linkto));
/* And separate it from the file name. */ /* And separate it from the file name. */
*p = '\0'; *p = '\0';
} }
} }
/* If we have the filename, add it to the list of files or /* If we have the filename, add it to the list of files or
directories. */ directories. */
/* "." and ".." are an exception! */ /* "." and ".." are an exception! */
if (!strcmp (tok, ".") || !strcmp (tok, "..")) if (!strcmp (tok, ".") || !strcmp (tok, ".."))
{ {
DEBUGP (("\nIgnoring `.' and `..'; ")); DEBUGP (("\nIgnoring `.' and `..'; "));
ignore = 1; ignore = 1;
break; break;
} }
/* Some FTP sites choose to have ls -F as their default /* Some FTP sites choose to have ls -F as their default
LIST output, which marks the symlinks with a trailing LIST output, which marks the symlinks with a trailing
`@', directory names with a trailing `/' and `@', directory names with a trailing `/' and
executables with a trailing `*'. This is no problem executables with a trailing `*'. This is no problem
unless encountering a symbolic link ending with `@', unless encountering a symbolic link ending with `@',
or an executable ending with `*' on a server without or an executable ending with `*' on a server without
default -F output. I believe these cases are very default -F output. I believe these cases are very
rare. */ rare. */
fnlen = strlen (tok); /* re-calculate `fnlen' */ fnlen = strlen (tok); /* re-calculate `fnlen' */
cur.name = xmalloc (fnlen + 1); cur.name = xmalloc (fnlen + 1);
memcpy (cur.name, tok, fnlen + 1); memcpy (cur.name, tok, fnlen + 1);
if (fnlen) if (fnlen)
{ {
if (cur.type == FT_DIRECTORY && cur.name[fnlen - 1] == '/') if (cur.type == FT_DIRECTORY && cur.name[fnlen - 1] == '/')
{ {
cur.name[fnlen - 1] = '\0'; cur.name[fnlen - 1] = '\0';
DEBUGP (("trailing `/' on dir.\n")); DEBUGP (("trailing `/' on dir.\n"));
} }
else if (cur.type == FT_SYMLINK && cur.name[fnlen - 1] == '@') else if (cur.type == FT_SYMLINK && cur.name[fnlen - 1] == '@')
{ {
cur.name[fnlen - 1] = '\0'; cur.name[fnlen - 1] = '\0';
DEBUGP (("trailing `@' on link.\n")); DEBUGP (("trailing `@' on link.\n"));
} }
else if (cur.type == FT_PLAINFILE else if (cur.type == FT_PLAINFILE
&& (cur.perms & 0111) && (cur.perms & 0111)
&& cur.name[fnlen - 1] == '*') && cur.name[fnlen - 1] == '*')
{ {
cur.name[fnlen - 1] = '\0'; cur.name[fnlen - 1] = '\0';
DEBUGP (("trailing `*' on exec.\n")); DEBUGP (("trailing `*' on exec.\n"));
} }
} /* if (fnlen) */ } /* if (fnlen) */
else else
error = 1; error = 1;
break; break;
} }
else else
abort (); abort ();
} /* while */ } /* while */
if (!cur.name || (cur.type == FT_SYMLINK && !cur.linkto)) if (!cur.name || (cur.type == FT_SYMLINK && !cur.linkto))
error = 1; error = 1;
DEBUGP (("%s\n", cur.name ? cur.name : "")); DEBUGP (("%s\n", cur.name ? cur.name : ""));
if (error || ignore) if (error || ignore)
{ {
DEBUGP (("Skipping.\n")); DEBUGP (("Skipping.\n"));
xfree_null (cur.name); xfree_null (cur.name);
xfree_null (cur.linkto); xfree_null (cur.linkto);
xfree (line); xfree (line);
continue; continue;
} }
if (!dir) if (!dir)
{ {
l = dir = xnew (struct fileinfo); l = dir = xnew (struct fileinfo);
memcpy (l, &cur, sizeof (cur)); memcpy (l, &cur, sizeof (cur));
l->prev = l->next = NULL; l->prev = l->next = NULL;
} }
else else
{ {
cur.prev = l; cur.prev = l;
l->next = xnew (struct fileinfo); l->next = xnew (struct fileinfo);
l = l->next; l = l->next;
memcpy (l, &cur, sizeof (cur)); memcpy (l, &cur, sizeof (cur));
l->next = NULL; l->next = NULL;
} }
/* Get the current time. */ /* Get the current time. */
timenow = time (NULL); timenow = time (NULL);
tnow = localtime (&timenow); tnow = localtime (&timenow);
@ -394,21 +394,21 @@ ftp_parse_unix_ls (const char *file, int ignore_perms)
timestruct.tm_mday = day; timestruct.tm_mday = day;
timestruct.tm_mon = month; timestruct.tm_mon = month;
if (year == 0) if (year == 0)
{ {
/* Some listings will not specify the year if it is "obvious" /* Some listings will not specify the year if it is "obvious"
that the file was from the previous year. E.g. if today that the file was from the previous year. E.g. if today
is 97-01-12, and you see a file of Dec 15th, its year is is 97-01-12, and you see a file of Dec 15th, its year is
1996, not 1997. Thanks to Vladimir Volovich for 1996, not 1997. Thanks to Vladimir Volovich for
mentioning this! */ mentioning this! */
if (month > tnow->tm_mon) if (month > tnow->tm_mon)
timestruct.tm_year = tnow->tm_year - 1; timestruct.tm_year = tnow->tm_year - 1;
else else
timestruct.tm_year = tnow->tm_year; timestruct.tm_year = tnow->tm_year;
} }
else else
timestruct.tm_year = year; timestruct.tm_year = year;
if (timestruct.tm_year >= 1900) if (timestruct.tm_year >= 1900)
timestruct.tm_year -= 1900; timestruct.tm_year -= 1900;
timestruct.tm_wday = 0; timestruct.tm_wday = 0;
timestruct.tm_yday = 0; timestruct.tm_yday = 0;
timestruct.tm_isdst = -1; timestruct.tm_isdst = -1;
@ -458,7 +458,7 @@ ftp_parse_winnt_ls (const char *file)
DEBUGP(("Name: '%s'\n", cur.name)); DEBUGP(("Name: '%s'\n", cur.name));
/* First column: mm-dd-yy. Should atoi() on the month fail, january /* First column: mm-dd-yy. Should atoi() on the month fail, january
will be assumed. */ will be assumed. */
tok = strtok(line, "-"); tok = strtok(line, "-");
if (tok == NULL) continue; if (tok == NULL) continue;
month = atoi(tok) - 1; month = atoi(tok) - 1;
@ -512,43 +512,43 @@ ftp_parse_winnt_ls (const char *file)
while ((tok != NULL) && (*tok == '\0')) tok = strtok(NULL, " "); while ((tok != NULL) && (*tok == '\0')) tok = strtok(NULL, " ");
if (tok == NULL) continue; if (tok == NULL) continue;
if (*tok == '<') if (*tok == '<')
{ {
cur.type = FT_DIRECTORY; cur.type = FT_DIRECTORY;
cur.size = 0; cur.size = 0;
cur.perms = 0755; cur.perms = 0755;
DEBUGP(("Directory\n")); DEBUGP(("Directory\n"));
} }
else else
{ {
wgint size; wgint size;
cur.type = FT_PLAINFILE; cur.type = FT_PLAINFILE;
errno = 0; errno = 0;
size = str_to_wgint (tok, NULL, 10); size = str_to_wgint (tok, NULL, 10);
if (size == WGINT_MAX && errno == ERANGE) if (size == WGINT_MAX && errno == ERANGE)
cur.size = 0; /* overflow */ cur.size = 0; /* overflow */
else else
cur.size = size; cur.size = size;
cur.perms = 0644; cur.perms = 0644;
DEBUGP(("File, size %s bytes\n", number_to_static_string (cur.size))); DEBUGP(("File, size %s bytes\n", number_to_static_string (cur.size)));
} }
cur.linkto = NULL; cur.linkto = NULL;
/* And put everything into the linked list */ /* And put everything into the linked list */
if (!dir) if (!dir)
{ {
l = dir = xnew (struct fileinfo); l = dir = xnew (struct fileinfo);
memcpy (l, &cur, sizeof (cur)); memcpy (l, &cur, sizeof (cur));
l->prev = l->next = NULL; l->prev = l->next = NULL;
} }
else else
{ {
cur.prev = l; cur.prev = l;
l->next = xnew (struct fileinfo); l->next = xnew (struct fileinfo);
l = l->next; l = l->next;
memcpy (l, &cur, sizeof (cur)); memcpy (l, &cur, sizeof (cur));
l->next = NULL; l->next = NULL;
} }
xfree (line); xfree (line);
} }
@ -595,7 +595,7 @@ ftp_parse_vms_ls (const char *file)
int hour, min, sec; int hour, min, sec;
struct tm timestruct; struct tm timestruct;
char *line, *tok; /* tokenizer */ char *line, *tok; /* tokenizer */
struct fileinfo *dir, *l, cur; /* list creation */ struct fileinfo *dir, *l, cur; /* list creation */
fp = fopen (file, "rb"); fp = fopen (file, "rb");
@ -624,10 +624,10 @@ ftp_parse_vms_ls (const char *file)
char *p; char *p;
i = clean_line (line); i = clean_line (line);
if (!i) if (!i)
{ {
xfree (line); xfree (line);
break; break;
} }
/* First column: Name. A bit of black magic again. The name my be /* First column: Name. A bit of black magic again. The name my be
either ABCD.EXT or ABCD.EXT;NUM and it might be on a separate either ABCD.EXT or ABCD.EXT;NUM and it might be on a separate
@ -641,7 +641,7 @@ ftp_parse_vms_ls (const char *file)
if (tok == NULL) tok = line; if (tok == NULL) tok = line;
DEBUGP(("file name: '%s'\n", tok)); DEBUGP(("file name: '%s'\n", tok));
for (p = tok ; *p && *p != ';' ; p++) for (p = tok ; *p && *p != ';' ; p++)
; ;
if (*p == ';') *p = '\0'; if (*p == ';') *p = '\0';
p = tok + strlen(tok) - 4; p = tok + strlen(tok) - 4;
if (!strcmp(p, ".DIR")) *p = '\0'; if (!strcmp(p, ".DIR")) *p = '\0';
@ -685,7 +685,7 @@ ftp_parse_vms_ls (const char *file)
if (!i) if (!i)
{ {
DEBUGP(("confusing VMS listing item, leaving listing parser\n")); DEBUGP(("confusing VMS listing item, leaving listing parser\n"));
xfree (line); xfree (line);
break; break;
} }
tok = strtok(line, " "); tok = strtok(line, " ");
@ -706,7 +706,7 @@ ftp_parse_vms_ls (const char *file)
the first strtok(NULL, "-") will return everything until the end the first strtok(NULL, "-") will return everything until the end
of the line and only the next strtok() call will return NULL. */ of the line and only the next strtok() call will return NULL. */
DEBUGP(("nonsense in VMS listing, skipping this line\n")); DEBUGP(("nonsense in VMS listing, skipping this line\n"));
xfree (line); xfree (line);
break; break;
} }
for (i=0; i<12; i++) if (!strcmp(tok,months[i])) break; for (i=0; i<12; i++) if (!strcmp(tok,months[i])) break;
@ -724,13 +724,13 @@ ftp_parse_vms_ls (const char *file)
p = tok; p = tok;
hour = atoi (p); hour = atoi (p);
for (; *p && *p != ':'; ++p) for (; *p && *p != ':'; ++p)
; ;
if (*p) if (*p)
min = atoi (++p); min = atoi (++p);
for (; *p && *p != ':'; ++p) for (; *p && *p != ':'; ++p)
; ;
if (*p) if (*p)
sec = atoi (++p); sec = atoi (++p);
DEBUGP(("YYYY/MM/DD HH:MM:SS - %d/%02d/%02d %02d:%02d:%02d\n", DEBUGP(("YYYY/MM/DD HH:MM:SS - %d/%02d/%02d %02d:%02d:%02d\n",
year+1900, month, day, hour, min, sec)); year+1900, month, day, hour, min, sec));
@ -762,7 +762,7 @@ ftp_parse_vms_ls (const char *file)
if (tok == NULL) if (tok == NULL)
{ {
DEBUGP(("confusing VMS permissions, skipping line\n")); DEBUGP(("confusing VMS permissions, skipping line\n"));
xfree (line); xfree (line);
continue; continue;
} }
/* Permissons have the format "RWED,RWED,RE" */ /* Permissons have the format "RWED,RWED,RE" */
@ -810,21 +810,21 @@ ftp_parse_ls (const char *file, const enum stype system_type)
return ftp_parse_unix_ls (file, 0); return ftp_parse_unix_ls (file, 0);
case ST_WINNT: case ST_WINNT:
{ {
/* Detect whether the listing is simulating the UNIX format */ /* Detect whether the listing is simulating the UNIX format */
FILE *fp; FILE *fp;
int c; int c;
fp = fopen (file, "rb"); fp = fopen (file, "rb");
if (!fp) if (!fp)
{ {
logprintf (LOG_NOTQUIET, "%s: %s\n", file, strerror (errno)); logprintf (LOG_NOTQUIET, "%s: %s\n", file, strerror (errno));
return NULL; return NULL;
} }
c = fgetc(fp); c = fgetc(fp);
fclose(fp); fclose(fp);
/* If the first character of the file is '0'-'9', it's WINNT /* If the first character of the file is '0'-'9', it's WINNT
format. */ format. */
if (c >= '0' && c <='9') if (c >= '0' && c <='9')
return ftp_parse_winnt_ls (file); return ftp_parse_winnt_ls (file);
else else
return ftp_parse_unix_ls (file, 1); return ftp_parse_unix_ls (file, 1);
} }
@ -849,16 +849,16 @@ ftp_index (const char *file, struct url *u, struct fileinfo *f)
{ {
FILE *fp; FILE *fp;
char *upwd; char *upwd;
char *htclfile; /* HTML-clean file name */ char *htclfile; /* HTML-clean file name */
if (!output_stream) if (!output_stream)
{ {
fp = fopen (file, "wb"); fp = fopen (file, "wb");
if (!fp) if (!fp)
{ {
logprintf (LOG_NOTQUIET, "%s: %s\n", file, strerror (errno)); logprintf (LOG_NOTQUIET, "%s: %s\n", file, strerror (errno));
return FOPENERR; return FOPENERR;
} }
} }
else else
fp = output_stream; fp = output_stream;
@ -869,9 +869,9 @@ ftp_index (const char *file, struct url *u, struct fileinfo *f)
tmpu = url_escape (u->user); tmpu = url_escape (u->user);
tmpp = u->passwd ? url_escape (u->passwd) : NULL; tmpp = u->passwd ? url_escape (u->passwd) : NULL;
if (tmpp) if (tmpp)
upwd = concat_strings (tmpu, ":", tmpp, "@", (char *) 0); upwd = concat_strings (tmpu, ":", tmpp, "@", (char *) 0);
else else
upwd = concat_strings (tmpu, "@", (char *) 0); upwd = concat_strings (tmpu, "@", (char *) 0);
xfree (tmpu); xfree (tmpu);
xfree_null (tmpp); xfree_null (tmpp);
} }
@ -887,57 +887,57 @@ ftp_index (const char *file, struct url *u, struct fileinfo *f)
{ {
fprintf (fp, " "); fprintf (fp, " ");
if (f->tstamp != -1) if (f->tstamp != -1)
{ {
/* #### Should we translate the months? Or, even better, use /* #### Should we translate the months? Or, even better, use
ISO 8601 dates? */ ISO 8601 dates? */
static const char *months[] = { static const char *months[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
}; };
struct tm *ptm = localtime ((time_t *)&f->tstamp); struct tm *ptm = localtime ((time_t *)&f->tstamp);
fprintf (fp, "%d %s %02d ", ptm->tm_year + 1900, months[ptm->tm_mon], fprintf (fp, "%d %s %02d ", ptm->tm_year + 1900, months[ptm->tm_mon],
ptm->tm_mday); ptm->tm_mday);
if (ptm->tm_hour) if (ptm->tm_hour)
fprintf (fp, "%02d:%02d ", ptm->tm_hour, ptm->tm_min); fprintf (fp, "%02d:%02d ", ptm->tm_hour, ptm->tm_min);
else else
fprintf (fp, " "); fprintf (fp, " ");
} }
else else
fprintf (fp, _("time unknown ")); fprintf (fp, _("time unknown "));
switch (f->type) switch (f->type)
{ {
case FT_PLAINFILE: case FT_PLAINFILE:
fprintf (fp, _("File ")); fprintf (fp, _("File "));
break; break;
case FT_DIRECTORY: case FT_DIRECTORY:
fprintf (fp, _("Directory ")); fprintf (fp, _("Directory "));
break; break;
case FT_SYMLINK: case FT_SYMLINK:
fprintf (fp, _("Link ")); fprintf (fp, _("Link "));
break; break;
default: default:
fprintf (fp, _("Not sure ")); fprintf (fp, _("Not sure "));
break; break;
} }
htclfile = html_quote_string (f->name); htclfile = html_quote_string (f->name);
fprintf (fp, "<a href=\"ftp://%s%s:%d", upwd, u->host, u->port); fprintf (fp, "<a href=\"ftp://%s%s:%d", upwd, u->host, u->port);
if (*u->dir != '/') if (*u->dir != '/')
putc ('/', fp); putc ('/', fp);
fprintf (fp, "%s", u->dir); fprintf (fp, "%s", u->dir);
if (*u->dir) if (*u->dir)
putc ('/', fp); putc ('/', fp);
fprintf (fp, "%s", htclfile); fprintf (fp, "%s", htclfile);
if (f->type == FT_DIRECTORY) if (f->type == FT_DIRECTORY)
putc ('/', fp); putc ('/', fp);
fprintf (fp, "\">%s", htclfile); fprintf (fp, "\">%s", htclfile);
if (f->type == FT_DIRECTORY) if (f->type == FT_DIRECTORY)
putc ('/', fp); putc ('/', fp);
fprintf (fp, "</a> "); fprintf (fp, "</a> ");
if (f->type == FT_PLAINFILE) if (f->type == FT_PLAINFILE)
fprintf (fp, _(" (%s bytes)"), number_to_static_string (f->size)); fprintf (fp, _(" (%s bytes)"), number_to_static_string (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);
xfree (htclfile); xfree (htclfile);
f = f->next; f = f->next;

View File

@ -2117,8 +2117,8 @@ extract (const unsigned char *s, int start, int length)
static char * static char *
btoe (char *store, const unsigned char *c) btoe (char *store, const unsigned char *c)
{ {
unsigned char cp[10]; /* add in room for the parity 2 bits + unsigned char cp[10]; /* add in room for the parity 2 bits +
extract() slop. */ extract() slop. */
int p, i; int p, i;
char *store_beg = store; char *store_beg = store;
@ -2154,7 +2154,7 @@ btoe (char *store, const unsigned char *c)
store += STRLEN_1_4 (store); store += STRLEN_1_4 (store);
*store++ = ' '; *store++ = ' ';
memcpy (store, &Wp[extract (cp, 55, 11)][0], 4); memcpy (store, &Wp[extract (cp, 55, 11)][0], 4);
store[4] = '\0'; /* make sure the string is terminated */ store[4] = '\0'; /* make sure the string is terminated */
DEBUGP (("wrote `%s' to STORE\n", store_beg)); DEBUGP (("wrote `%s' to STORE\n", store_beg));
return store_beg; return store_beg;

1812
src/ftp.c

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -38,7 +38,7 @@
#endif #endif
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
# define SWAP(n) \ # define SWAP(n) \
(((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
#else #else
# define SWAP(n) (n) # define SWAP(n) (n)
@ -103,7 +103,7 @@ md5_finish_ctx (struct md5_ctx *ctx, void *resbuf)
/* Put the 64-bit file length in *bits* at the end of the buffer. */ /* Put the 64-bit file length in *bits* at the end of the buffer. */
*(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3); *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
*(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) | *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |
(ctx->total[0] >> 29)); (ctx->total[0] >> 29));
/* Process last bytes. */ /* Process last bytes. */
md5_process_block (ctx->buffer, bytes + pad + 8, ctx); md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
@ -132,28 +132,28 @@ md5_stream (FILE *stream, void *resblock)
while (1) while (1)
{ {
/* We read the file in blocks of BLOCKSIZE bytes. One call of the /* We read the file in blocks of BLOCKSIZE bytes. One call of the
computation function processes the whole buffer so that with the computation function processes the whole buffer so that with the
next round of the loop another block can be read. */ next round of the loop another block can be read. */
size_t n; size_t n;
sum = 0; sum = 0;
/* Read block. Take care for partial reads. */ /* Read block. Take care for partial reads. */
do do
{ {
n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
sum += n; sum += n;
} }
while (sum < BLOCKSIZE && n != 0); while (sum < BLOCKSIZE && n != 0);
if (n == 0 && ferror (stream)) if (n == 0 && ferror (stream))
return 1; return 1;
/* If end of file is reached, end the loop. */ /* If end of file is reached, end the loop. */
if (n == 0) if (n == 0)
break; break;
/* Process buffer with BLOCKSIZE bytes. Note that /* Process buffer with BLOCKSIZE bytes. Note that
BLOCKSIZE % 64 == 0 BLOCKSIZE % 64 == 0
*/ */
md5_process_block (buffer, BLOCKSIZE, &ctx); md5_process_block (buffer, BLOCKSIZE, &ctx);
} }
@ -202,13 +202,13 @@ md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx)
ctx->buflen += add; ctx->buflen += add;
if (left_over + add > 64) if (left_over + add > 64)
{ {
md5_process_block (ctx->buffer, (left_over + add) & ~63, ctx); md5_process_block (ctx->buffer, (left_over + add) & ~63, ctx);
/* The regions in the following copy operation cannot overlap. */ /* The regions in the following copy operation cannot overlap. */
memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63], memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
(left_over + add) & 63); (left_over + add) & 63);
ctx->buflen = (left_over + add) & 63; ctx->buflen = (left_over + add) & 63;
} }
buffer = (const char *) buffer + add; buffer = (const char *) buffer + add;
len -= add; len -= add;
@ -273,30 +273,30 @@ md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx)
md5_uint32 D_save = D; md5_uint32 D_save = D;
/* First round: using the given function, the context and a constant /* First round: using the given function, the context and a constant
the next context is computed. Because the algorithms processing the next context is computed. Because the algorithms processing
unit is a 32-bit word and it is determined to work on words in unit is a 32-bit word and it is determined to work on words in
little endian byte order we perhaps have to change the byte order little endian byte order we perhaps have to change the byte order
before the computation. To reduce the work for the next steps before the computation. To reduce the work for the next steps
we store the swapped words in the array CORRECT_WORDS. */ we store the swapped words in the array CORRECT_WORDS. */
#define OP(a, b, c, d, s, T) \ #define OP(a, b, c, d, s, T) \
do \ do \
{ \ { \
a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \ a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \
++words; \ ++words; \
CYCLIC (a, s); \ CYCLIC (a, s); \
a += b; \ a += b; \
} \ } \
while (0) while (0)
/* It is unfortunate that C does not provide an operator for /* It is unfortunate that C does not provide an operator for
cyclic rotation. Hope the C compiler is smart enough. */ cyclic rotation. Hope the C compiler is smart enough. */
#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) #define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
/* Before we start, one word to the strange constants. /* Before we start, one word to the strange constants.
They are defined in RFC 1321 as They are defined in RFC 1321 as
T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
*/ */
/* Round 1. */ /* Round 1. */
@ -318,16 +318,16 @@ md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx)
OP (B, C, D, A, 22, 0x49b40821); OP (B, C, D, A, 22, 0x49b40821);
/* For the second to fourth round we have the possibly swapped words /* For the second to fourth round we have the possibly swapped words
in CORRECT_WORDS. Redefine the macro to take an additional first in CORRECT_WORDS. Redefine the macro to take an additional first
argument specifying the function to use. */ argument specifying the function to use. */
#undef OP #undef OP
#define OP(f, a, b, c, d, k, s, T) \ #define OP(f, a, b, c, d, k, s, T) \
do \ do \
{ \ { \
a += f (b, c, d) + correct_words[k] + T; \ a += f (b, c, d) + correct_words[k] + T; \
CYCLIC (a, s); \ CYCLIC (a, s); \
a += b; \ a += b; \
} \ } \
while (0) while (0)
/* Round 2. */ /* Round 2. */

View File

@ -59,13 +59,13 @@ ssl_init ()
gnutls_certificate_allocate_credentials (&credentials); gnutls_certificate_allocate_credentials (&credentials);
if (opt.ca_cert) if (opt.ca_cert)
gnutls_certificate_set_x509_trust_file (credentials, opt.ca_cert, gnutls_certificate_set_x509_trust_file (credentials, opt.ca_cert,
GNUTLS_X509_FMT_PEM); GNUTLS_X509_FMT_PEM);
return true; return true;
} }
struct wgnutls_transport_context { struct wgnutls_transport_context {
gnutls_session session; /* GnuTLS session handle */ gnutls_session session; /* GnuTLS session handle */
int last_error; /* last error returned by read/write/... */ int last_error; /* last error returned by read/write/... */
/* Since GnuTLS doesn't support the equivalent to recv(..., /* Since GnuTLS doesn't support the equivalent to recv(...,
MSG_PEEK) or SSL_peek(), we have to do it ourselves. Peeked data MSG_PEEK) or SSL_peek(), we have to do it ourselves. Peeked data
@ -92,9 +92,9 @@ wgnutls_read (int fd, char *buf, int bufsize, void *arg)
memcpy (buf, ctx->peekbuf + ctx->peekstart, copysize); memcpy (buf, ctx->peekbuf + ctx->peekstart, copysize);
ctx->peeklen -= copysize; ctx->peeklen -= copysize;
if (ctx->peeklen != 0) if (ctx->peeklen != 0)
ctx->peekstart += copysize; ctx->peekstart += copysize;
else else
ctx->peekstart = 0; ctx->peekstart = 0;
return copysize; return copysize;
} }
@ -223,7 +223,7 @@ ssl_check_certificate (int fd, const char *host)
if (err < 0) if (err < 0)
{ {
logprintf (LOG_NOTQUIET, _("%s: No certificate presented by %s.\n"), logprintf (LOG_NOTQUIET, _("%s: No certificate presented by %s.\n"),
severity, escnonprint (host)); severity, escnonprint (host));
success = false; success = false;
goto out; goto out;
} }
@ -231,19 +231,19 @@ ssl_check_certificate (int fd, const char *host)
if (status & GNUTLS_CERT_INVALID) if (status & GNUTLS_CERT_INVALID)
{ {
logprintf (LOG_NOTQUIET, _("%s: The certificate of `%s' is not trusted.\n"), logprintf (LOG_NOTQUIET, _("%s: The certificate of `%s' is not trusted.\n"),
severity, escnonprint (host)); severity, escnonprint (host));
success = false; success = false;
} }
if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
{ {
logprintf (LOG_NOTQUIET, _("%s: The certificate of `%s' hasn't got a known issuer.\n"), logprintf (LOG_NOTQUIET, _("%s: The certificate of `%s' hasn't got a known issuer.\n"),
severity, escnonprint (host)); severity, escnonprint (host));
success = false; success = false;
} }
if (status & GNUTLS_CERT_REVOKED) if (status & GNUTLS_CERT_REVOKED)
{ {
logprintf (LOG_NOTQUIET, _("%s: The certificate of `%s' has been revoked.\n"), logprintf (LOG_NOTQUIET, _("%s: The certificate of `%s' has been revoked.\n"),
severity, escnonprint (host)); severity, escnonprint (host));
success = false; success = false;
} }
@ -255,45 +255,45 @@ ssl_check_certificate (int fd, const char *host)
unsigned int cert_list_size; unsigned int cert_list_size;
if ((err = gnutls_x509_crt_init (&cert)) < 0) if ((err = gnutls_x509_crt_init (&cert)) < 0)
{ {
logprintf (LOG_NOTQUIET, _("Error initializing X509 certificate: %s\n"), logprintf (LOG_NOTQUIET, _("Error initializing X509 certificate: %s\n"),
gnutls_strerror (err)); gnutls_strerror (err));
success = false; success = false;
goto out; goto out;
} }
cert_list = gnutls_certificate_get_peers (ctx->session, &cert_list_size); cert_list = gnutls_certificate_get_peers (ctx->session, &cert_list_size);
if (!cert_list) if (!cert_list)
{ {
logprintf (LOG_NOTQUIET, _("No certificate found\n")); logprintf (LOG_NOTQUIET, _("No certificate found\n"));
success = false; success = false;
goto out; goto out;
} }
err = gnutls_x509_crt_import (cert, cert_list, GNUTLS_X509_FMT_DER); err = gnutls_x509_crt_import (cert, cert_list, GNUTLS_X509_FMT_DER);
if (err < 0) if (err < 0)
{ {
logprintf (LOG_NOTQUIET, _("Error parsing certificate: %s\n"), logprintf (LOG_NOTQUIET, _("Error parsing certificate: %s\n"),
gnutls_strerror (err)); gnutls_strerror (err));
success = false; success = false;
goto out; goto out;
} }
if (now < gnutls_x509_crt_get_activation_time (cert)) if (now < gnutls_x509_crt_get_activation_time (cert))
{ {
logprintf (LOG_NOTQUIET, _("The certificate has not yet been activated\n")); logprintf (LOG_NOTQUIET, _("The certificate has not yet been activated\n"));
success = false; success = false;
} }
if (now >= gnutls_x509_crt_get_expiration_time (cert)) if (now >= gnutls_x509_crt_get_expiration_time (cert))
{ {
logprintf (LOG_NOTQUIET, _("The certificate has expired\n")); logprintf (LOG_NOTQUIET, _("The certificate has expired\n"));
success = false; success = false;
} }
if (!gnutls_x509_crt_check_hostname (cert, host)) if (!gnutls_x509_crt_check_hostname (cert, host))
{ {
logprintf (LOG_NOTQUIET, logprintf (LOG_NOTQUIET,
_("The certificate's owner does not match hostname '%s'\n"), _("The certificate's owner does not match hostname '%s'\n"),
host); host);
success = false; success = false;
} }
gnutls_x509_crt_deinit (cert); gnutls_x509_crt_deinit (cert);
} }

View File

@ -156,14 +156,14 @@ struct hash_table {
hashfun_t hash_function; hashfun_t hash_function;
testfun_t test_function; testfun_t test_function;
struct cell *cells; /* contiguous array of cells. */ struct cell *cells; /* contiguous array of cells. */
int size; /* size of the array. */ int size; /* size of the array. */
int count; /* number of occupied entries. */ int count; /* number of occupied entries. */
int resize_threshold; /* after size exceeds this number of int resize_threshold; /* after size exceeds this number of
entries, resize the table. */ entries, resize the table. */
int prime_offset; /* the offset of the current prime in int prime_offset; /* the offset of the current prime in
the prime table. */ the prime table. */
}; };
/* We use the all-bits-set constant (INVALID_PTR) marker to mean that /* We use the all-bits-set constant (INVALID_PTR) marker to mean that
@ -195,7 +195,7 @@ struct hash_table {
/* Loop over occupied cells starting at C, terminating the loop when /* Loop over occupied cells starting at C, terminating the loop when
an empty cell is encountered. */ an empty cell is encountered. */
#define FOREACH_OCCUPIED_ADJACENT(c, cells, size) \ #define FOREACH_OCCUPIED_ADJACENT(c, cells, size) \
for (; CELL_OCCUPIED (c); c = NEXT_CELL (c, cells, size)) for (; CELL_OCCUPIED (c); c = NEXT_CELL (c, cells, size))
/* Return the position of KEY in hash table SIZE large, hash function /* Return the position of KEY in hash table SIZE large, hash function
@ -230,13 +230,13 @@ prime_size (int size, int *prime_offset)
for (i = *prime_offset; i < countof (primes); i++) for (i = *prime_offset; i < countof (primes); i++)
if (primes[i] >= size) if (primes[i] >= size)
{ {
/* Set the offset to the next prime. That is safe because, /* Set the offset to the next prime. That is safe because,
next time we are called, it will be with a larger SIZE, next time we are called, it will be with a larger SIZE,
which means we could never return the same prime anyway. which means we could never return the same prime anyway.
(If that is not the case, the caller can simply reset (If that is not the case, the caller can simply reset
*prime_offset.) */ *prime_offset.) */
*prime_offset = i + 1; *prime_offset = i + 1;
return primes[i]; return primes[i];
} }
abort (); abort ();
@ -270,8 +270,8 @@ static int cmp_pointer (const void *, const void *);
struct hash_table * struct hash_table *
hash_table_new (int items, hash_table_new (int items,
unsigned long (*hash_function) (const void *), unsigned long (*hash_function) (const void *),
int (*test_function) (const void *, const void *)) int (*test_function) (const void *, const void *))
{ {
int size; int size;
struct hash_table *ht = xnew (struct hash_table); struct hash_table *ht = xnew (struct hash_table);
@ -351,15 +351,15 @@ hash_table_get (const struct hash_table *ht, const void *key)
int int
hash_table_get_pair (const struct hash_table *ht, const void *lookup_key, hash_table_get_pair (const struct hash_table *ht, const void *lookup_key,
void *orig_key, void *value) void *orig_key, void *value)
{ {
struct cell *c = find_cell (ht, lookup_key); struct cell *c = find_cell (ht, lookup_key);
if (CELL_OCCUPIED (c)) if (CELL_OCCUPIED (c))
{ {
if (orig_key) if (orig_key)
*(void **)orig_key = c->key; *(void **)orig_key = c->key;
if (value) if (value)
*(void **)value = c->value; *(void **)value = c->value;
return 1; return 1;
} }
else else
@ -390,9 +390,9 @@ grow_hash_table (struct hash_table *ht)
newsize = prime_size (ht->size * HASH_RESIZE_FACTOR, &ht->prime_offset); newsize = prime_size (ht->size * HASH_RESIZE_FACTOR, &ht->prime_offset);
#if 0 #if 0
printf ("growing from %d to %d; fullness %.2f%% to %.2f%%\n", printf ("growing from %d to %d; fullness %.2f%% to %.2f%%\n",
ht->size, newsize, ht->size, newsize,
100.0 * ht->count / ht->size, 100.0 * ht->count / ht->size,
100.0 * ht->count / newsize); 100.0 * ht->count / newsize);
#endif #endif
ht->size = newsize; ht->size = newsize;
@ -405,14 +405,14 @@ grow_hash_table (struct hash_table *ht)
for (c = old_cells; c < old_end; c++) for (c = old_cells; c < old_end; c++)
if (CELL_OCCUPIED (c)) if (CELL_OCCUPIED (c))
{ {
struct cell *new_c; struct cell *new_c;
/* We don't need to test for uniqueness of keys because they /* We don't need to test for uniqueness of keys because they
come from the hash table and are therefore known to be come from the hash table and are therefore known to be
unique. */ unique. */
new_c = cells + HASH_POSITION (c->key, hasher, newsize); new_c = cells + HASH_POSITION (c->key, hasher, newsize);
FOREACH_OCCUPIED_ADJACENT (new_c, cells, newsize) FOREACH_OCCUPIED_ADJACENT (new_c, cells, newsize)
; ;
*new_c = *c; *new_c = *c;
} }
xfree (old_cells); xfree (old_cells);
@ -443,7 +443,7 @@ hash_table_put (struct hash_table *ht, const void *key, void *value)
/* add new item */ /* add new item */
++ht->count; ++ht->count;
c->key = (void *)key; /* const? */ c->key = (void *)key; /* const? */
c->value = value; c->value = value;
} }
@ -466,30 +466,30 @@ hash_table_remove (struct hash_table *ht, const void *key)
--ht->count; --ht->count;
/* Rehash all the entries following C. The alternative /* Rehash all the entries following C. The alternative
approach is to mark the entry as deleted, i.e. create a approach is to mark the entry as deleted, i.e. create a
"tombstone". That speeds up removal, but leaves a lot of "tombstone". That speeds up removal, but leaves a lot of
garbage and slows down hash_table_get and hash_table_put. */ garbage and slows down hash_table_get and hash_table_put. */
c = NEXT_CELL (c, cells, size); c = NEXT_CELL (c, cells, size);
FOREACH_OCCUPIED_ADJACENT (c, cells, size) FOREACH_OCCUPIED_ADJACENT (c, cells, size)
{ {
const void *key2 = c->key; const void *key2 = c->key;
struct cell *c_new; struct cell *c_new;
/* Find the new location for the key. */ /* Find the new location for the key. */
c_new = cells + HASH_POSITION (key2, hasher, size); c_new = cells + HASH_POSITION (key2, hasher, size);
FOREACH_OCCUPIED_ADJACENT (c_new, cells, size) FOREACH_OCCUPIED_ADJACENT (c_new, cells, size)
if (key2 == c_new->key) if (key2 == c_new->key)
/* The cell C (key2) is already where we want it (in /* The cell C (key2) is already where we want it (in
C_NEW's "chain" of keys.) */ C_NEW's "chain" of keys.) */
goto next_rehash; goto next_rehash;
*c_new = *c; *c_new = *c;
CLEAR_CELL (c); CLEAR_CELL (c);
next_rehash: next_rehash:
; ;
} }
return 1; return 1;
} }
} }
@ -518,7 +518,7 @@ hash_table_clear (struct hash_table *ht)
void void
hash_table_for_each (struct hash_table *ht, hash_table_for_each (struct hash_table *ht,
int (*fn) (void *, void *, void *), void *arg) int (*fn) (void *, void *, void *), void *arg)
{ {
struct cell *c = ht->cells; struct cell *c = ht->cells;
struct cell *end = ht->cells + ht->size; struct cell *end = ht->cells + ht->size;
@ -526,14 +526,14 @@ hash_table_for_each (struct hash_table *ht,
for (; c < end; c++) for (; c < end; c++)
if (CELL_OCCUPIED (c)) if (CELL_OCCUPIED (c))
{ {
void *key; void *key;
repeat: repeat:
key = c->key; key = c->key;
if (fn (key, c->value, arg)) if (fn (key, c->value, arg))
return; return;
/* hash_table_remove might have moved the adjacent cells. */ /* hash_table_remove might have moved the adjacent cells. */
if (c->key != key && CELL_OCCUPIED (c)) if (c->key != key && CELL_OCCUPIED (c))
goto repeat; goto repeat;
} }
} }
@ -571,10 +571,10 @@ hash_table_iter_next (hash_table_iterator *iter)
for (; c < end; c++) for (; c < end; c++)
if (CELL_OCCUPIED (c)) if (CELL_OCCUPIED (c))
{ {
iter->key = c->key; iter->key = c->key;
iter->value = c->value; iter->value = c->value;
iter->pos = c + 1; iter->pos = c + 1;
return 1; return 1;
} }
return 0; return 0;
} }
@ -770,20 +770,20 @@ main (void)
{ {
int len = strlen (line); int len = strlen (line);
if (len <= 1) if (len <= 1)
continue; continue;
line[--len] = '\0'; line[--len] = '\0';
if (!hash_table_contains (ht, line)) if (!hash_table_contains (ht, line))
hash_table_put (ht, strdup (line), "here I am!"); hash_table_put (ht, strdup (line), "here I am!");
#if 1 #if 1
if (len % 5 == 0) if (len % 5 == 0)
{ {
char *line_copy; char *line_copy;
if (hash_table_get_pair (ht, line, &line_copy, NULL)) if (hash_table_get_pair (ht, line, &line_copy, NULL))
{ {
hash_table_remove (ht, line); hash_table_remove (ht, line);
xfree (line_copy); xfree (line_copy);
} }
} }
#endif #endif
} }
#if 0 #if 0

View File

@ -61,16 +61,16 @@ so, delete this exception statement from your version. */
lookup_host for details. */ lookup_host for details. */
struct address_list { struct address_list {
int count; /* number of adrresses */ int count; /* number of adrresses */
ip_address *addresses; /* pointer to the string of addresses */ ip_address *addresses; /* pointer to the string of addresses */
int faulty; /* number of addresses known not to work. */ int faulty; /* number of addresses known not to work. */
bool connected; /* whether we were able to connect to bool connected; /* whether we were able to connect to
one of the addresses in the list, one of the addresses in the list,
at least once. */ at least once. */
int refcount; /* reference count; when it drops to int refcount; /* reference count; when it drops to
0, the entry is freed. */ 0, the entry is freed. */
}; };
/* Get the bounds of the address list. */ /* Get the bounds of the address list. */
@ -101,25 +101,25 @@ address_list_contains (const struct address_list *al, const ip_address *ip)
{ {
case AF_INET: case AF_INET:
for (i = 0; i < al->count; i++) for (i = 0; i < al->count; i++)
{ {
ip_address *cur = al->addresses + i; ip_address *cur = al->addresses + i;
if (cur->family == AF_INET if (cur->family == AF_INET
&& (cur->data.d4.s_addr == ip->data.d4.s_addr)) && (cur->data.d4.s_addr == ip->data.d4.s_addr))
return true; return true;
} }
return false; return false;
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
case AF_INET6: case AF_INET6:
for (i = 0; i < al->count; i++) for (i = 0; i < al->count; i++)
{ {
ip_address *cur = al->addresses + i; ip_address *cur = al->addresses + i;
if (cur->family == AF_INET6 if (cur->family == AF_INET6
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
&& cur->ipv6_scope == ip->ipv6_scope && cur->ipv6_scope == ip->ipv6_scope
#endif #endif
&& IN6_ARE_ADDR_EQUAL (&cur->data.d6, &ip->data.d6)) && IN6_ARE_ADDR_EQUAL (&cur->data.d6, &ip->data.d6))
return true; return true;
} }
return false; return false;
#endif /* ENABLE_IPV6 */ #endif /* ENABLE_IPV6 */
default: default:
@ -193,22 +193,22 @@ address_list_from_addrinfo (const struct addrinfo *ai)
for (ptr = ai; ptr != NULL; ptr = ptr->ai_next) for (ptr = ai; ptr != NULL; ptr = ptr->ai_next)
if (ptr->ai_family == AF_INET6) if (ptr->ai_family == AF_INET6)
{ {
const struct sockaddr_in6 *sin6 = const struct sockaddr_in6 *sin6 =
(const struct sockaddr_in6 *)ptr->ai_addr; (const struct sockaddr_in6 *)ptr->ai_addr;
ip->family = AF_INET6; ip->family = AF_INET6;
ip->data.d6 = sin6->sin6_addr; ip->data.d6 = sin6->sin6_addr;
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
ip->ipv6_scope = sin6->sin6_scope_id; ip->ipv6_scope = sin6->sin6_scope_id;
#endif #endif
++ip; ++ip;
} }
else if (ptr->ai_family == AF_INET) else if (ptr->ai_family == AF_INET)
{ {
const struct sockaddr_in *sin = const struct sockaddr_in *sin =
(const struct sockaddr_in *)ptr->ai_addr; (const struct sockaddr_in *)ptr->ai_addr;
ip->family = AF_INET; ip->family = AF_INET;
ip->data.d4 = sin->sin_addr; ip->data.d4 = sin->sin_addr;
++ip; ++ip;
} }
assert (ip - al->addresses == cnt); assert (ip - al->addresses == cnt);
return al; return al;
@ -288,7 +288,7 @@ address_list_release (struct address_list *al)
{ {
--al->refcount; --al->refcount;
DEBUGP (("Releasing 0x%0*lx (new refcount %d).\n", PTR_FORMAT (al), DEBUGP (("Releasing 0x%0*lx (new refcount %d).\n", PTR_FORMAT (al),
al->refcount)); al->refcount));
if (al->refcount <= 0) if (al->refcount <= 0)
{ {
DEBUGP (("Deleting unused 0x%0*lx.\n", PTR_FORMAT (al))); DEBUGP (("Deleting unused 0x%0*lx.\n", PTR_FORMAT (al)));
@ -376,8 +376,8 @@ getaddrinfo_with_timeout_callback (void *arg)
static int static int
getaddrinfo_with_timeout (const char *node, const char *service, getaddrinfo_with_timeout (const char *node, const char *service,
const struct addrinfo *hints, struct addrinfo **res, const struct addrinfo *hints, struct addrinfo **res,
double timeout) double timeout)
{ {
struct gaiwt_context ctx; struct gaiwt_context ctx;
ctx.node = node; ctx.node = node;
@ -427,27 +427,27 @@ is_valid_ipv4_address (const char *str, const char *end)
int ch = *str++; int ch = *str++;
if (ch >= '0' && ch <= '9') if (ch >= '0' && ch <= '9')
{ {
val = val * 10 + (ch - '0'); val = val * 10 + (ch - '0');
if (val > 255) if (val > 255)
return false; return false;
if (!saw_digit) if (!saw_digit)
{ {
if (++octets > 4) if (++octets > 4)
return false; return false;
saw_digit = true; saw_digit = true;
} }
} }
else if (ch == '.' && saw_digit) else if (ch == '.' && saw_digit)
{ {
if (octets == 4) if (octets == 4)
return false; return false;
val = 0; val = 0;
saw_digit = false; saw_digit = false;
} }
else else
return false; return false;
} }
if (octets < 4) if (octets < 4)
return false; return false;
@ -482,7 +482,7 @@ is_valid_ipv6_address (const char *str, const char *end)
{ {
++str; ++str;
if (str == end || *str != ':') if (str == end || *str != ':')
return false; return false;
} }
curtok = str; curtok = str;
@ -495,44 +495,44 @@ is_valid_ipv6_address (const char *str, const char *end)
/* if ch is a number, add it to val. */ /* if ch is a number, add it to val. */
if (ISXDIGIT (ch)) if (ISXDIGIT (ch))
{ {
val <<= 4; val <<= 4;
val |= XDIGIT_TO_NUM (ch); val |= XDIGIT_TO_NUM (ch);
if (val > 0xffff) if (val > 0xffff)
return false; return false;
saw_xdigit = true; saw_xdigit = true;
continue; continue;
} }
/* if ch is a colon ... */ /* if ch is a colon ... */
if (ch == ':') if (ch == ':')
{ {
curtok = str; curtok = str;
if (!saw_xdigit) if (!saw_xdigit)
{ {
if (colonp != NULL) if (colonp != NULL)
return false; return false;
colonp = str + tp; colonp = str + tp;
continue; continue;
} }
else if (str == end) else if (str == end)
return false; return false;
if (tp > ns_in6addrsz - ns_int16sz) if (tp > ns_in6addrsz - ns_int16sz)
return false; return false;
tp += ns_int16sz; tp += ns_int16sz;
saw_xdigit = false; saw_xdigit = false;
val = 0; val = 0;
continue; continue;
} }
/* if ch is a dot ... */ /* if ch is a dot ... */
if (ch == '.' && (tp <= ns_in6addrsz - ns_inaddrsz) if (ch == '.' && (tp <= ns_in6addrsz - ns_inaddrsz)
&& is_valid_ipv4_address (curtok, end) == 1) && is_valid_ipv4_address (curtok, end) == 1)
{ {
tp += ns_inaddrsz; tp += ns_inaddrsz;
saw_xdigit = false; saw_xdigit = false;
break; break;
} }
return false; return false;
} }
@ -540,14 +540,14 @@ is_valid_ipv6_address (const char *str, const char *end)
if (saw_xdigit) if (saw_xdigit)
{ {
if (tp > ns_in6addrsz - ns_int16sz) if (tp > ns_in6addrsz - ns_int16sz)
return false; return false;
tp += ns_int16sz; tp += ns_int16sz;
} }
if (colonp != NULL) if (colonp != NULL)
{ {
if (tp == ns_in6addrsz) if (tp == ns_in6addrsz)
return false; return false;
tp = ns_in6addrsz; tp = ns_in6addrsz;
} }
@ -602,7 +602,7 @@ cache_store (const char *host, struct address_list *al)
int i; int i;
debug_logprintf ("Caching %s =>", host); debug_logprintf ("Caching %s =>", host);
for (i = 0; i < al->count; i++) for (i = 0; i < al->count; i++)
debug_logprintf (" %s", print_address (al->addresses + i)); debug_logprintf (" %s", print_address (al->addresses + i));
debug_logprintf ("\n"); debug_logprintf ("\n");
} }
} }
@ -642,7 +642,7 @@ cache_remove (const char *host)
LH_SILENT - don't print the "resolving ... done" messages. LH_SILENT - don't print the "resolving ... done" messages.
LH_BIND - resolve addresses for use with bind, which under LH_BIND - resolve addresses for use with bind, which under
IPv6 means to use AI_PASSIVE flag to getaddrinfo. IPv6 means to use AI_PASSIVE flag to getaddrinfo.
Passive lookups are not cached under IPv6. Passive lookups are not cached under IPv6.
LH_REFRESH - if HOST is cached, remove the entry from the cache LH_REFRESH - if HOST is cached, remove the entry from the cache
and resolve it anew. */ and resolve it anew. */
@ -664,12 +664,12 @@ lookup_host (const char *host, int flags)
uint32_t addr_ipv4 = (uint32_t)inet_addr (host); uint32_t addr_ipv4 = (uint32_t)inet_addr (host);
if (addr_ipv4 != (uint32_t) -1) if (addr_ipv4 != (uint32_t) -1)
{ {
/* No need to cache host->addr relation, just return the /* No need to cache host->addr relation, just return the
address. */ address. */
char *vec[2]; char *vec[2];
vec[0] = (char *)&addr_ipv4; vec[0] = (char *)&addr_ipv4;
vec[1] = NULL; vec[1] = NULL;
return address_list_from_ipv4_addresses (vec); return address_list_from_ipv4_addresses (vec);
} }
} }
#else /* ENABLE_IPV6 */ #else /* ENABLE_IPV6 */
@ -699,13 +699,13 @@ lookup_host (const char *host, int flags)
if (use_cache) if (use_cache)
{ {
if (!(flags & LH_REFRESH)) if (!(flags & LH_REFRESH))
{ {
al = cache_query (host); al = cache_query (host);
if (al) if (al)
return al; return al;
} }
else else
cache_remove (host); cache_remove (host);
} }
/* No luck with the cache; resolve HOST. */ /* No luck with the cache; resolve HOST. */
@ -726,9 +726,9 @@ lookup_host (const char *host, int flags)
hints.ai_family = AF_INET6; hints.ai_family = AF_INET6;
else else
/* We tried using AI_ADDRCONFIG, but removed it because: it /* We tried using AI_ADDRCONFIG, but removed it because: it
misinterprets IPv6 loopbacks, it is broken on AIX 5.1, and misinterprets IPv6 loopbacks, it is broken on AIX 5.1, and
it's unneeded since we sort the addresses anyway. */ it's unneeded since we sort the addresses anyway. */
hints.ai_family = AF_UNSPEC; hints.ai_family = AF_UNSPEC;
if (flags & LH_BIND) if (flags & LH_BIND)
hints.ai_flags |= AI_PASSIVE; hints.ai_flags |= AI_PASSIVE;
@ -736,30 +736,30 @@ lookup_host (const char *host, int flags)
#ifdef AI_NUMERICHOST #ifdef AI_NUMERICHOST
if (numeric_address) if (numeric_address)
{ {
/* Where available, the AI_NUMERICHOST hint can prevent costly /* Where available, the AI_NUMERICHOST hint can prevent costly
access to DNS servers. */ access to DNS servers. */
hints.ai_flags |= AI_NUMERICHOST; hints.ai_flags |= AI_NUMERICHOST;
timeout = 0; /* no timeout needed when "resolving" timeout = 0; /* no timeout needed when "resolving"
numeric hosts -- avoid setting up numeric hosts -- avoid setting up
signal handlers and such. */ signal handlers and such. */
} }
#endif #endif
err = getaddrinfo_with_timeout (host, NULL, &hints, &res, timeout); err = getaddrinfo_with_timeout (host, NULL, &hints, &res, timeout);
if (err != 0 || res == NULL) if (err != 0 || res == NULL)
{ {
if (!silent) if (!silent)
logprintf (LOG_VERBOSE, _("failed: %s.\n"), logprintf (LOG_VERBOSE, _("failed: %s.\n"),
err != EAI_SYSTEM ? gai_strerror (err) : strerror (errno)); err != EAI_SYSTEM ? gai_strerror (err) : strerror (errno));
return NULL; return NULL;
} }
al = address_list_from_addrinfo (res); al = address_list_from_addrinfo (res);
freeaddrinfo (res); freeaddrinfo (res);
if (!al) if (!al)
{ {
logprintf (LOG_VERBOSE, logprintf (LOG_VERBOSE,
_("failed: No IPv4/IPv6 addresses for host.\n")); _("failed: No IPv4/IPv6 addresses for host.\n"));
return NULL; return NULL;
} }
/* Reorder addresses so that IPv4 ones (or IPv6 ones, as per /* Reorder addresses so that IPv4 ones (or IPv6 ones, as per
@ -767,23 +767,23 @@ lookup_host (const char *host, int flags)
the addresses with the same family is undisturbed. */ the addresses with the same family is undisturbed. */
if (al->count > 1 && opt.prefer_family != prefer_none) if (al->count > 1 && opt.prefer_family != prefer_none)
stable_sort (al->addresses, al->count, sizeof (ip_address), stable_sort (al->addresses, al->count, sizeof (ip_address),
opt.prefer_family == prefer_ipv4 opt.prefer_family == prefer_ipv4
? cmp_prefer_ipv4 : cmp_prefer_ipv6); ? cmp_prefer_ipv4 : cmp_prefer_ipv6);
} }
#else /* not ENABLE_IPV6 */ #else /* not ENABLE_IPV6 */
{ {
struct hostent *hptr = gethostbyname_with_timeout (host, timeout); struct hostent *hptr = gethostbyname_with_timeout (host, timeout);
if (!hptr) if (!hptr)
{ {
if (!silent) if (!silent)
{ {
if (errno != ETIMEDOUT) if (errno != ETIMEDOUT)
logprintf (LOG_VERBOSE, _("failed: %s.\n"), logprintf (LOG_VERBOSE, _("failed: %s.\n"),
host_errstr (h_errno)); host_errstr (h_errno));
else else
logputs (LOG_VERBOSE, _("failed: timed out.\n")); logputs (LOG_VERBOSE, _("failed: timed out.\n"));
} }
return NULL; return NULL;
} }
/* Do older systems have h_addr_list? */ /* Do older systems have h_addr_list? */
al = address_list_from_ipv4_addresses (hptr->h_addr_list); al = address_list_from_ipv4_addresses (hptr->h_addr_list);
@ -797,13 +797,13 @@ lookup_host (const char *host, int flags)
int i; int i;
int printmax = al->count <= 3 ? al->count : 3; int printmax = al->count <= 3 ? al->count : 3;
for (i = 0; i < printmax; i++) for (i = 0; i < printmax; i++)
{ {
logputs (LOG_VERBOSE, print_address (al->addresses + i)); logputs (LOG_VERBOSE, print_address (al->addresses + i));
if (i < printmax - 1) if (i < printmax - 1)
logputs (LOG_VERBOSE, ", "); logputs (LOG_VERBOSE, ", ");
} }
if (printmax != al->count) if (printmax != al->count)
logputs (LOG_VERBOSE, ", ..."); logputs (LOG_VERBOSE, ", ...");
logputs (LOG_VERBOSE, "\n"); logputs (LOG_VERBOSE, "\n");
} }
@ -823,12 +823,12 @@ accept_domain (struct url *u)
if (opt.domains) if (opt.domains)
{ {
if (!sufmatch ((const char **)opt.domains, u->host)) if (!sufmatch ((const char **)opt.domains, u->host))
return false; return false;
} }
if (opt.exclude_domains) if (opt.exclude_domains)
{ {
if (sufmatch ((const char **)opt.exclude_domains, u->host)) if (sufmatch ((const char **)opt.exclude_domains, u->host))
return false; return false;
} }
return true; return true;
} }
@ -847,11 +847,11 @@ sufmatch (const char **list, const char *what)
for (i = 0; list[i]; i++) for (i = 0; list[i]; i++)
{ {
for (j = strlen (list[i]), k = lw; j >= 0 && k >= 0; j--, k--) for (j = strlen (list[i]), k = lw; j >= 0 && k >= 0; j--, k--)
if (TOLOWER (list[i][j]) != TOLOWER (what[k])) if (TOLOWER (list[i][j]) != TOLOWER (what[k]))
break; break;
/* The domain must be first to reach to beginning. */ /* The domain must be first to reach to beginning. */
if (j == -1) if (j == -1)
return true; return true;
} }
return false; return false;
} }
@ -863,15 +863,15 @@ host_cleanup (void)
{ {
hash_table_iterator iter; hash_table_iterator iter;
for (hash_table_iterate (host_name_addresses_map, &iter); for (hash_table_iterate (host_name_addresses_map, &iter);
hash_table_iter_next (&iter); hash_table_iter_next (&iter);
) )
{ {
char *host = iter.key; char *host = iter.key;
struct address_list *al = iter.value; struct address_list *al = iter.value;
xfree (host); xfree (host);
assert (al->refcount == 1); assert (al->refcount == 1);
address_list_delete (al); address_list_delete (al);
} }
hash_table_destroy (host_name_addresses_map); hash_table_destroy (host_name_addresses_map);
host_name_addresses_map = NULL; host_name_addresses_map = NULL;
} }

File diff suppressed because it is too large Load Diff

View File

@ -40,13 +40,13 @@ so, delete this exception statement from your version. */
#include "utils.h" #include "utils.h"
#include "hash.h" #include "hash.h"
#include "convert.h" #include "convert.h"
#include "recur.h" /* declaration of get_urls_html */ #include "recur.h" /* declaration of get_urls_html */
struct map_context; struct map_context;
typedef void (*tag_handler_t) (int, struct taginfo *, struct map_context *); typedef void (*tag_handler_t) (int, struct taginfo *, struct map_context *);
#define DECLARE_TAG_HANDLER(fun) \ #define DECLARE_TAG_HANDLER(fun) \
static void fun (int, struct taginfo *, struct map_context *) static void fun (int, struct taginfo *, struct map_context *)
DECLARE_TAG_HANDLER (tag_find_urls); DECLARE_TAG_HANDLER (tag_find_urls);
@ -87,28 +87,28 @@ static struct known_tag {
const char *name; const char *name;
tag_handler_t handler; tag_handler_t handler;
} known_tags[] = { } known_tags[] = {
{ TAG_A, "a", tag_find_urls }, { TAG_A, "a", tag_find_urls },
{ TAG_APPLET, "applet", tag_find_urls }, { TAG_APPLET, "applet", tag_find_urls },
{ TAG_AREA, "area", tag_find_urls }, { TAG_AREA, "area", tag_find_urls },
{ TAG_BASE, "base", tag_handle_base }, { TAG_BASE, "base", tag_handle_base },
{ TAG_BGSOUND, "bgsound", tag_find_urls }, { TAG_BGSOUND, "bgsound", tag_find_urls },
{ TAG_BODY, "body", tag_find_urls }, { TAG_BODY, "body", tag_find_urls },
{ TAG_EMBED, "embed", tag_find_urls }, { TAG_EMBED, "embed", tag_find_urls },
{ TAG_FIG, "fig", tag_find_urls }, { TAG_FIG, "fig", tag_find_urls },
{ TAG_FORM, "form", tag_handle_form }, { TAG_FORM, "form", tag_handle_form },
{ TAG_FRAME, "frame", tag_find_urls }, { TAG_FRAME, "frame", tag_find_urls },
{ TAG_IFRAME, "iframe", tag_find_urls }, { TAG_IFRAME, "iframe", tag_find_urls },
{ TAG_IMG, "img", tag_find_urls }, { TAG_IMG, "img", tag_find_urls },
{ TAG_INPUT, "input", tag_find_urls }, { TAG_INPUT, "input", tag_find_urls },
{ TAG_LAYER, "layer", tag_find_urls }, { TAG_LAYER, "layer", tag_find_urls },
{ TAG_LINK, "link", tag_handle_link }, { TAG_LINK, "link", tag_handle_link },
{ TAG_META, "meta", tag_handle_meta }, { TAG_META, "meta", tag_handle_meta },
{ TAG_OBJECT, "object", tag_find_urls }, { TAG_OBJECT, "object", tag_find_urls },
{ TAG_OVERLAY, "overlay", tag_find_urls }, { TAG_OVERLAY, "overlay", tag_find_urls },
{ TAG_SCRIPT, "script", tag_find_urls }, { TAG_SCRIPT, "script", tag_find_urls },
{ TAG_TABLE, "table", tag_find_urls }, { TAG_TABLE, "table", tag_find_urls },
{ TAG_TD, "td", tag_find_urls }, { TAG_TD, "td", tag_find_urls },
{ TAG_TH, "th", tag_find_urls } { TAG_TH, "th", tag_find_urls }
}; };
/* tag_url_attributes documents which attributes of which tags contain /* tag_url_attributes documents which attributes of which tags contain
@ -119,14 +119,14 @@ static struct known_tag {
/* The link is "inline", i.e. needs to be retrieved for this document /* The link is "inline", i.e. needs to be retrieved for this document
to be correctly rendered. Inline links include inlined images, to be correctly rendered. Inline links include inlined images,
stylesheets, children frames, etc. */ stylesheets, children frames, etc. */
#define ATTR_INLINE 1 #define ATTR_INLINE 1
/* The link is expected to yield HTML contents. It's important not to /* The link is expected to yield HTML contents. It's important not to
try to follow HTML obtained by following e.g. <img src="..."> try to follow HTML obtained by following e.g. <img src="...">
regardless of content-type. Doing this causes infinite loops for regardless of content-type. Doing this causes infinite loops for
"images" that return non-404 error pages with links to the same "images" that return non-404 error pages with links to the same
image. */ image. */
#define ATTR_HTML 2 #define ATTR_HTML 2
/* For tags handled by tag_find_urls: attributes that contain URLs to /* For tags handled by tag_find_urls: attributes that contain URLs to
download. */ download. */
@ -135,38 +135,38 @@ static struct {
const char *attr_name; const char *attr_name;
int flags; int flags;
} tag_url_attributes[] = { } tag_url_attributes[] = {
{ TAG_A, "href", ATTR_HTML }, { TAG_A, "href", ATTR_HTML },
{ TAG_APPLET, "code", ATTR_INLINE }, { TAG_APPLET, "code", ATTR_INLINE },
{ TAG_AREA, "href", ATTR_HTML }, { TAG_AREA, "href", ATTR_HTML },
{ TAG_BGSOUND, "src", ATTR_INLINE }, { TAG_BGSOUND, "src", ATTR_INLINE },
{ TAG_BODY, "background", ATTR_INLINE }, { TAG_BODY, "background", ATTR_INLINE },
{ TAG_EMBED, "href", ATTR_HTML }, { TAG_EMBED, "href", ATTR_HTML },
{ TAG_EMBED, "src", ATTR_INLINE | ATTR_HTML }, { TAG_EMBED, "src", ATTR_INLINE | ATTR_HTML },
{ TAG_FIG, "src", ATTR_INLINE }, { TAG_FIG, "src", ATTR_INLINE },
{ TAG_FRAME, "src", ATTR_INLINE | ATTR_HTML }, { TAG_FRAME, "src", ATTR_INLINE | ATTR_HTML },
{ TAG_IFRAME, "src", ATTR_INLINE | ATTR_HTML }, { TAG_IFRAME, "src", ATTR_INLINE | ATTR_HTML },
{ TAG_IMG, "href", ATTR_INLINE }, { TAG_IMG, "href", ATTR_INLINE },
{ TAG_IMG, "lowsrc", ATTR_INLINE }, { TAG_IMG, "lowsrc", ATTR_INLINE },
{ TAG_IMG, "src", ATTR_INLINE }, { TAG_IMG, "src", ATTR_INLINE },
{ TAG_INPUT, "src", ATTR_INLINE }, { TAG_INPUT, "src", ATTR_INLINE },
{ TAG_LAYER, "src", ATTR_INLINE | ATTR_HTML }, { TAG_LAYER, "src", ATTR_INLINE | ATTR_HTML },
{ TAG_OBJECT, "data", ATTR_INLINE }, { TAG_OBJECT, "data", ATTR_INLINE },
{ TAG_OVERLAY, "src", ATTR_INLINE | ATTR_HTML }, { TAG_OVERLAY, "src", ATTR_INLINE | ATTR_HTML },
{ TAG_SCRIPT, "src", ATTR_INLINE }, { TAG_SCRIPT, "src", ATTR_INLINE },
{ TAG_TABLE, "background", ATTR_INLINE }, { TAG_TABLE, "background", ATTR_INLINE },
{ TAG_TD, "background", ATTR_INLINE }, { TAG_TD, "background", ATTR_INLINE },
{ TAG_TH, "background", ATTR_INLINE } { TAG_TH, "background", ATTR_INLINE }
}; };
/* The lists of interesting tags and attributes are built dynamically, /* The lists of interesting tags and attributes are built dynamically,
from the information above. However, some places in the code refer from the information above. However, some places in the code refer
to the attributes not mentioned here. We add them manually. */ to the attributes not mentioned here. We add them manually. */
static const char *additional_attributes[] = { static const char *additional_attributes[] = {
"rel", /* used by tag_handle_link */ "rel", /* used by tag_handle_link */
"http-equiv", /* used by tag_handle_meta */ "http-equiv", /* used by tag_handle_meta */
"name", /* used by tag_handle_meta */ "name", /* used by tag_handle_meta */
"content", /* used by tag_handle_meta */ "content", /* used by tag_handle_meta */
"action" /* used by tag_handle_form */ "action" /* used by tag_handle_form */
}; };
static struct hash_table *interesting_tags; static struct hash_table *interesting_tags;
@ -197,23 +197,23 @@ init_interesting (void)
{ {
char **ignored; char **ignored;
for (ignored = opt.ignore_tags; *ignored; ignored++) for (ignored = opt.ignore_tags; *ignored; ignored++)
hash_table_remove (interesting_tags, *ignored); hash_table_remove (interesting_tags, *ignored);
} }
/* If --follow-tags is specified, use only those tags. */ /* If --follow-tags is specified, use only those tags. */
if (opt.follow_tags) if (opt.follow_tags)
{ {
/* Create a new table intersecting --follow-tags and known_tags, /* Create a new table intersecting --follow-tags and known_tags,
and use it as interesting_tags. */ and use it as interesting_tags. */
struct hash_table *intersect = make_nocase_string_hash_table (0); struct hash_table *intersect = make_nocase_string_hash_table (0);
char **followed; char **followed;
for (followed = opt.follow_tags; *followed; followed++) for (followed = opt.follow_tags; *followed; followed++)
{ {
struct known_tag *t = hash_table_get (interesting_tags, *followed); struct known_tag *t = hash_table_get (interesting_tags, *followed);
if (!t) if (!t)
continue; /* ignore unknown --follow-tags entries. */ continue; /* ignore unknown --follow-tags entries. */
hash_table_put (intersect, *followed, t); hash_table_put (intersect, *followed, t);
} }
hash_table_destroy (interesting_tags); hash_table_destroy (interesting_tags);
interesting_tags = intersect; interesting_tags = intersect;
} }
@ -224,7 +224,7 @@ init_interesting (void)
hash_table_put (interesting_attributes, additional_attributes[i], "1"); hash_table_put (interesting_attributes, additional_attributes[i], "1");
for (i = 0; i < countof (tag_url_attributes); i++) for (i = 0; i < countof (tag_url_attributes); i++)
hash_table_put (interesting_attributes, hash_table_put (interesting_attributes,
tag_url_attributes[i].attr_name, "1"); tag_url_attributes[i].attr_name, "1");
} }
/* Find the value of attribute named NAME in the taginfo TAG. If the /* Find the value of attribute named NAME in the taginfo TAG. If the
@ -238,24 +238,24 @@ find_attr (struct taginfo *tag, const char *name, int *attrind)
for (i = 0; i < tag->nattrs; i++) for (i = 0; i < tag->nattrs; i++)
if (!strcasecmp (tag->attrs[i].name, name)) if (!strcasecmp (tag->attrs[i].name, name))
{ {
if (attrind) if (attrind)
*attrind = i; *attrind = i;
return tag->attrs[i].value; return tag->attrs[i].value;
} }
return NULL; return NULL;
} }
struct map_context { struct map_context {
char *text; /* HTML text. */ char *text; /* HTML text. */
char *base; /* Base URI of the document, possibly char *base; /* Base URI of the document, possibly
changed through <base href=...>. */ changed through <base href=...>. */
const char *parent_base; /* Base of the current document. */ const char *parent_base; /* Base of the current document. */
const char *document_file; /* File name of this document. */ const char *document_file; /* File name of this document. */
bool nofollow; /* whether NOFOLLOW was specified in a bool nofollow; /* whether NOFOLLOW was specified in a
<meta name=robots> tag. */ <meta name=robots> tag. */
struct urlpos *head, *tail; /* List of URLs that is being struct urlpos *head, *tail; /* List of URLs that is being
built. */ built. */
}; };
/* Append LINK_URI to the urlpos structure that is being built. /* Append LINK_URI to the urlpos structure that is being built.
@ -266,7 +266,7 @@ struct map_context {
static struct urlpos * static struct urlpos *
append_url (const char *link_uri, append_url (const char *link_uri,
struct taginfo *tag, int attrind, struct map_context *ctx) struct taginfo *tag, int attrind, struct map_context *ctx)
{ {
int link_has_scheme = url_has_scheme (link_uri); int link_has_scheme = url_has_scheme (link_uri);
struct urlpos *newel; struct urlpos *newel;
@ -276,47 +276,47 @@ append_url (const char *link_uri,
if (!base) if (!base)
{ {
DEBUGP (("%s: no base, merge will use \"%s\".\n", DEBUGP (("%s: no base, merge will use \"%s\".\n",
ctx->document_file, link_uri)); ctx->document_file, link_uri));
if (!link_has_scheme) if (!link_has_scheme)
{ {
/* Base URL is unavailable, and the link does not have a /* Base URL is unavailable, and the link does not have a
location attached to it -- we have to give up. Since location attached to it -- we have to give up. Since
this can only happen when using `--force-html -i', print this can only happen when using `--force-html -i', print
a warning. */ a warning. */
logprintf (LOG_NOTQUIET, logprintf (LOG_NOTQUIET,
_("%s: Cannot resolve incomplete link %s.\n"), _("%s: Cannot resolve incomplete link %s.\n"),
ctx->document_file, link_uri); ctx->document_file, link_uri);
return NULL; return NULL;
} }
url = url_parse (link_uri, NULL); url = url_parse (link_uri, NULL);
if (!url) if (!url)
{ {
DEBUGP (("%s: link \"%s\" doesn't parse.\n", DEBUGP (("%s: link \"%s\" doesn't parse.\n",
ctx->document_file, link_uri)); ctx->document_file, link_uri));
return NULL; return NULL;
} }
} }
else else
{ {
/* Merge BASE with LINK_URI, but also make sure the result is /* Merge BASE with LINK_URI, but also make sure the result is
canonicalized, i.e. that "../" have been resolved. canonicalized, i.e. that "../" have been resolved.
(parse_url will do that for us.) */ (parse_url will do that for us.) */
char *complete_uri = uri_merge (base, link_uri); char *complete_uri = uri_merge (base, link_uri);
DEBUGP (("%s: merge(\"%s\", \"%s\") -> %s\n", DEBUGP (("%s: merge(\"%s\", \"%s\") -> %s\n",
ctx->document_file, base, link_uri, complete_uri)); ctx->document_file, base, link_uri, complete_uri));
url = url_parse (complete_uri, NULL); url = url_parse (complete_uri, NULL);
if (!url) if (!url)
{ {
DEBUGP (("%s: merged link \"%s\" doesn't parse.\n", DEBUGP (("%s: merged link \"%s\" doesn't parse.\n",
ctx->document_file, complete_uri)); ctx->document_file, complete_uri));
xfree (complete_uri); xfree (complete_uri);
return NULL; return NULL;
} }
xfree (complete_uri); xfree (complete_uri);
} }
@ -360,10 +360,10 @@ tag_find_urls (int tagid, struct taginfo *tag, struct map_context *ctx)
for (i = 0; i < countof (tag_url_attributes); i++) for (i = 0; i < countof (tag_url_attributes); i++)
if (tag_url_attributes[i].tagid == tagid) if (tag_url_attributes[i].tagid == tagid)
{ {
/* We've found the index of tag_url_attributes where the /* We've found the index of tag_url_attributes where the
attributes of our tag begin. */ attributes of our tag begin. */
first = i; first = i;
break; break;
} }
assert (first != -1); assert (first != -1);
@ -379,30 +379,30 @@ tag_find_urls (int tagid, struct taginfo *tag, struct map_context *ctx)
for (attrind = 0; attrind < tag->nattrs; attrind++) for (attrind = 0; attrind < tag->nattrs; attrind++)
{ {
/* Find whether TAG/ATTRIND is a combination that contains a /* Find whether TAG/ATTRIND is a combination that contains a
URL. */ URL. */
char *link = tag->attrs[attrind].value; char *link = tag->attrs[attrind].value;
const int size = countof (tag_url_attributes); const int size = countof (tag_url_attributes);
/* If you're cringing at the inefficiency of the nested loops, /* If you're cringing at the inefficiency of the nested loops,
remember that they both iterate over a very small number of remember that they both iterate over a very small number of
items. The worst-case inner loop is for the IMG tag, which items. The worst-case inner loop is for the IMG tag, which
has three attributes. */ has three attributes. */
for (i = first; i < size && tag_url_attributes[i].tagid == tagid; i++) for (i = first; i < size && tag_url_attributes[i].tagid == tagid; i++)
{ {
if (0 == strcasecmp (tag->attrs[attrind].name, if (0 == strcasecmp (tag->attrs[attrind].name,
tag_url_attributes[i].attr_name)) tag_url_attributes[i].attr_name))
{ {
struct urlpos *up = append_url (link, tag, attrind, ctx); struct urlpos *up = append_url (link, tag, attrind, ctx);
if (up) if (up)
{ {
int flags = tag_url_attributes[i].flags; int flags = tag_url_attributes[i].flags;
if (flags & ATTR_INLINE) if (flags & ATTR_INLINE)
up->link_inline_p = 1; up->link_inline_p = 1;
if (flags & ATTR_HTML) if (flags & ATTR_HTML)
up->link_expect_html = 1; up->link_expect_html = 1;
} }
} }
} }
} }
} }
@ -442,7 +442,7 @@ tag_handle_form (int tagid, struct taginfo *tag, struct map_context *ctx)
{ {
struct urlpos *up = append_url (action, tag, attrind, ctx); struct urlpos *up = append_url (action, tag, attrind, ctx);
if (up) if (up)
up->ignore_when_downloading = 1; up->ignore_when_downloading = 1;
} }
} }
@ -465,17 +465,17 @@ tag_handle_link (int tagid, struct taginfo *tag, struct map_context *ctx)
{ {
struct urlpos *up = append_url (href, tag, attrind, ctx); struct urlpos *up = append_url (href, tag, attrind, ctx);
if (up) if (up)
{ {
char *rel = find_attr (tag, "rel", NULL); char *rel = find_attr (tag, "rel", NULL);
if (rel if (rel
&& (0 == strcasecmp (rel, "stylesheet") && (0 == strcasecmp (rel, "stylesheet")
|| 0 == strcasecmp (rel, "shortcut icon"))) || 0 == strcasecmp (rel, "shortcut icon")))
up->link_inline_p = 1; up->link_inline_p = 1;
else else
/* The external ones usually point to HTML pages, such as /* The external ones usually point to HTML pages, such as
<link rel="next" href="..."> */ <link rel="next" href="..."> */
up->link_expect_html = 1; up->link_expect_html = 1;
} }
} }
} }
@ -491,13 +491,13 @@ tag_handle_meta (int tagid, struct taginfo *tag, struct map_context *ctx)
if (http_equiv && 0 == strcasecmp (http_equiv, "refresh")) if (http_equiv && 0 == strcasecmp (http_equiv, "refresh"))
{ {
/* Some pages use a META tag to specify that the page be /* Some pages use a META tag to specify that the page be
refreshed by a new page after a given number of seconds. The refreshed by a new page after a given number of seconds. The
general format for this is: general format for this is:
<meta http-equiv=Refresh content="NUMBER; URL=index2.html"> <meta http-equiv=Refresh content="NUMBER; URL=index2.html">
So we just need to skip past the "NUMBER; URL=" garbage to So we just need to skip past the "NUMBER; URL=" garbage to
get to the URL. */ get to the URL. */
struct urlpos *entry; struct urlpos *entry;
int attrind; int attrind;
@ -506,57 +506,57 @@ tag_handle_meta (int tagid, struct taginfo *tag, struct map_context *ctx)
char *refresh = find_attr (tag, "content", &attrind); char *refresh = find_attr (tag, "content", &attrind);
if (!refresh) if (!refresh)
return; return;
for (p = refresh; ISDIGIT (*p); p++) for (p = refresh; ISDIGIT (*p); p++)
timeout = 10 * timeout + *p - '0'; timeout = 10 * timeout + *p - '0';
if (*p++ != ';') if (*p++ != ';')
return; return;
while (ISSPACE (*p)) while (ISSPACE (*p))
++p; ++p;
if (!( TOUPPER (*p) == 'U' if (!( TOUPPER (*p) == 'U'
&& TOUPPER (*(p + 1)) == 'R' && TOUPPER (*(p + 1)) == 'R'
&& TOUPPER (*(p + 2)) == 'L' && TOUPPER (*(p + 2)) == 'L'
&& *(p + 3) == '=')) && *(p + 3) == '='))
return; return;
p += 4; p += 4;
while (ISSPACE (*p)) while (ISSPACE (*p))
++p; ++p;
entry = append_url (p, tag, attrind, ctx); entry = append_url (p, tag, attrind, ctx);
if (entry) if (entry)
{ {
entry->link_refresh_p = 1; entry->link_refresh_p = 1;
entry->refresh_timeout = timeout; entry->refresh_timeout = timeout;
entry->link_expect_html = 1; entry->link_expect_html = 1;
} }
} }
else if (name && 0 == strcasecmp (name, "robots")) else if (name && 0 == strcasecmp (name, "robots"))
{ {
/* Handle stuff like: /* Handle stuff like:
<meta name="robots" content="index,nofollow"> */ <meta name="robots" content="index,nofollow"> */
char *content = find_attr (tag, "content", NULL); char *content = find_attr (tag, "content", NULL);
if (!content) if (!content)
return; return;
if (!strcasecmp (content, "none")) if (!strcasecmp (content, "none"))
ctx->nofollow = true; ctx->nofollow = true;
else else
{ {
while (*content) while (*content)
{ {
/* Find the next occurrence of ',' or the end of /* Find the next occurrence of ',' or the end of
the string. */ the string. */
char *end = strchr (content, ','); char *end = strchr (content, ',');
if (end) if (end)
++end; ++end;
else else
end = content + strlen (content); end = content + strlen (content);
if (!strncasecmp (content, "nofollow", end - content)) if (!strncasecmp (content, "nofollow", end - content))
ctx->nofollow = true; ctx->nofollow = true;
content = end; content = end;
} }
} }
} }
} }
@ -618,7 +618,7 @@ get_urls_html (const char *file, const char *url, bool *meta_disallow_follow)
flags |= MHT_STRICT_COMMENTS; flags |= MHT_STRICT_COMMENTS;
map_html_tags (fm->content, fm->length, collect_tags_mapper, &ctx, flags, map_html_tags (fm->content, fm->length, collect_tags_mapper, &ctx, flags,
interesting_tags, interesting_attributes); interesting_tags, interesting_attributes);
DEBUGP (("no-follow in %s: %d\n", file, ctx.nofollow)); DEBUGP (("no-follow in %s: %d\n", file, ctx.nofollow));
if (meta_disallow_follow) if (meta_disallow_follow)
@ -661,51 +661,51 @@ get_urls_file (const char *file)
const char *line_beg = text; const char *line_beg = text;
const char *line_end = memchr (text, '\n', text_end - text); const char *line_end = memchr (text, '\n', text_end - text);
if (!line_end) if (!line_end)
line_end = text_end; line_end = text_end;
else else
++line_end; ++line_end;
text = line_end; text = line_end;
/* Strip whitespace from the beginning and end of line. */ /* Strip whitespace from the beginning and end of line. */
while (line_beg < line_end && ISSPACE (*line_beg)) while (line_beg < line_end && ISSPACE (*line_beg))
++line_beg; ++line_beg;
while (line_end > line_beg && ISSPACE (*(line_end - 1))) while (line_end > line_beg && ISSPACE (*(line_end - 1)))
--line_end; --line_end;
if (line_beg == line_end) if (line_beg == line_end)
continue; continue;
/* The URL is in the [line_beg, line_end) region. */ /* The URL is in the [line_beg, line_end) region. */
/* We must copy the URL to a zero-terminated string, and we /* We must copy the URL to a zero-terminated string, and we
can't use alloca because we're in a loop. *sigh*. */ can't use alloca because we're in a loop. *sigh*. */
url_text = strdupdelim (line_beg, line_end); url_text = strdupdelim (line_beg, line_end);
if (opt.base_href) if (opt.base_href)
{ {
/* Merge opt.base_href with URL. */ /* Merge opt.base_href with URL. */
char *merged = uri_merge (opt.base_href, url_text); char *merged = uri_merge (opt.base_href, url_text);
xfree (url_text); xfree (url_text);
url_text = merged; url_text = merged;
} }
url = url_parse (url_text, &up_error_code); url = url_parse (url_text, &up_error_code);
if (!url) if (!url)
{ {
logprintf (LOG_NOTQUIET, _("%s: Invalid URL %s: %s\n"), logprintf (LOG_NOTQUIET, _("%s: Invalid URL %s: %s\n"),
file, url_text, url_error (up_error_code)); file, url_text, url_error (up_error_code));
xfree (url_text); xfree (url_text);
continue; continue;
} }
xfree (url_text); xfree (url_text);
entry = xnew0 (struct urlpos); entry = xnew0 (struct urlpos);
entry->url = url; entry->url = url;
if (!head) if (!head)
head = entry; head = entry;
else else
tail->next = entry; tail->next = entry;
tail = entry; tail = entry;
} }
read_file_free (fm); read_file_free (fm);

View File

@ -145,7 +145,7 @@ ntlm_input (struct ntlmdata *ntlm, const char *header)
size = base64_decode (header, buffer); size = base64_decode (header, buffer);
if (size < 0) if (size < 0)
return false; /* malformed base64 from server */ return false; /* malformed base64 from server */
ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */ ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */
@ -158,10 +158,10 @@ ntlm_input (struct ntlmdata *ntlm, const char *header)
else else
{ {
if (ntlm->state >= NTLMSTATE_TYPE1) if (ntlm->state >= NTLMSTATE_TYPE1)
{ {
DEBUGP (("Unexpected empty NTLM message.\n")); DEBUGP (("Unexpected empty NTLM message.\n"));
return false; /* this is an error */ return false; /* this is an error */
} }
DEBUGP (("Empty NTLM message, starting transaction.\n")); DEBUGP (("Empty NTLM message, starting transaction.\n"));
ntlm->state = NTLMSTATE_TYPE1; /* we should sent away a type-1 */ ntlm->state = NTLMSTATE_TYPE1; /* we should sent away a type-1 */
@ -176,7 +176,7 @@ ntlm_input (struct ntlmdata *ntlm, const char *header)
*/ */
static void static void
setup_des_key(unsigned char *key_56, setup_des_key(unsigned char *key_56,
DES_key_schedule DESKEYARG(ks)) DES_key_schedule DESKEYARG(ks))
{ {
DES_cblock key; DES_cblock key;
@ -221,8 +221,8 @@ calc_resp(unsigned char *keys, unsigned char *plaintext, unsigned char *results)
*/ */
static void static void
mkhash(const char *password, mkhash(const char *password,
unsigned char *nonce, /* 8 bytes */ unsigned char *nonce, /* 8 bytes */
unsigned char *lmresp /* must fit 0x18 bytes */ unsigned char *lmresp /* must fit 0x18 bytes */
#ifdef USE_NTRESPONSES #ifdef USE_NTRESPONSES
, unsigned char *ntresp /* must fit 0x18 bytes */ , unsigned char *ntresp /* must fit 0x18 bytes */
#endif #endif
@ -298,7 +298,7 @@ mkhash(const char *password,
/* this is for creating ntlm header output */ /* this is for creating ntlm header output */
char * char *
ntlm_output (struct ntlmdata *ntlm, const char *user, const char *passwd, ntlm_output (struct ntlmdata *ntlm, const char *user, const char *passwd,
bool *ready) bool *ready)
{ {
const char *domain=""; /* empty */ const char *domain=""; /* empty */
const char *host=""; /* empty */ const char *host=""; /* empty */
@ -345,35 +345,35 @@ ntlm_output (struct ntlmdata *ntlm, const char *user, const char *passwd,
*/ */
snprintf (ntlmbuf, sizeof(ntlmbuf), "NTLMSSP%c" snprintf (ntlmbuf, sizeof(ntlmbuf), "NTLMSSP%c"
"\x01%c%c%c" /* 32-bit type = 1 */ "\x01%c%c%c" /* 32-bit type = 1 */
"%c%c%c%c" /* 32-bit NTLM flag field */ "%c%c%c%c" /* 32-bit NTLM flag field */
"%c%c" /* domain length */ "%c%c" /* domain length */
"%c%c" /* domain allocated space */ "%c%c" /* domain allocated space */
"%c%c" /* domain name offset */ "%c%c" /* domain name offset */
"%c%c" /* 2 zeroes */ "%c%c" /* 2 zeroes */
"%c%c" /* host length */ "%c%c" /* host length */
"%c%c" /* host allocated space */ "%c%c" /* host allocated space */
"%c%c" /* host name offset */ "%c%c" /* host name offset */
"%c%c" /* 2 zeroes */ "%c%c" /* 2 zeroes */
"%s" /* host name */ "%s" /* host name */
"%s", /* domain string */ "%s", /* domain string */
0, /* trailing zero */ 0, /* trailing zero */
0,0,0, /* part of type-1 long */ 0,0,0, /* part of type-1 long */
LONGQUARTET( LONGQUARTET(
NTLMFLAG_NEGOTIATE_OEM| /* 2 */ NTLMFLAG_NEGOTIATE_OEM| /* 2 */
NTLMFLAG_NEGOTIATE_NTLM_KEY /* 200 */ NTLMFLAG_NEGOTIATE_NTLM_KEY /* 200 */
/* equals 0x0202 */ /* equals 0x0202 */
), ),
SHORTPAIR(domlen), SHORTPAIR(domlen),
SHORTPAIR(domlen), SHORTPAIR(domlen),
SHORTPAIR(domoff), SHORTPAIR(domoff),
0,0, 0,0,
SHORTPAIR(hostlen), SHORTPAIR(hostlen),
SHORTPAIR(hostlen), SHORTPAIR(hostlen),
SHORTPAIR(hostoff), SHORTPAIR(hostoff),
0,0, 0,0,
host, domain); host, domain);
/* initial packet length */ /* initial packet length */
size = 32 + hostlen + domlen; size = 32 + hostlen + domlen;
@ -443,81 +443,81 @@ ntlm_output (struct ntlmdata *ntlm, const char *user, const char *passwd,
/* Create the big type-3 message binary blob */ /* Create the big type-3 message binary blob */
size = snprintf (ntlmbuf, sizeof(ntlmbuf), size = snprintf (ntlmbuf, sizeof(ntlmbuf),
"NTLMSSP%c" "NTLMSSP%c"
"\x03%c%c%c" /* type-3, 32 bits */ "\x03%c%c%c" /* type-3, 32 bits */
"%c%c%c%c" /* LanManager length + allocated space */ "%c%c%c%c" /* LanManager length + allocated space */
"%c%c" /* LanManager offset */ "%c%c" /* LanManager offset */
"%c%c" /* 2 zeroes */ "%c%c" /* 2 zeroes */
"%c%c" /* NT-response length */ "%c%c" /* NT-response length */
"%c%c" /* NT-response allocated space */ "%c%c" /* NT-response allocated space */
"%c%c" /* NT-response offset */ "%c%c" /* NT-response offset */
"%c%c" /* 2 zeroes */ "%c%c" /* 2 zeroes */
"%c%c" /* domain length */ "%c%c" /* domain length */
"%c%c" /* domain allocated space */ "%c%c" /* domain allocated space */
"%c%c" /* domain name offset */ "%c%c" /* domain name offset */
"%c%c" /* 2 zeroes */ "%c%c" /* 2 zeroes */
"%c%c" /* user length */ "%c%c" /* user length */
"%c%c" /* user allocated space */ "%c%c" /* user allocated space */
"%c%c" /* user offset */ "%c%c" /* user offset */
"%c%c" /* 2 zeroes */ "%c%c" /* 2 zeroes */
"%c%c" /* host length */ "%c%c" /* host length */
"%c%c" /* host allocated space */ "%c%c" /* host allocated space */
"%c%c" /* host offset */ "%c%c" /* host offset */
"%c%c%c%c%c%c" /* 6 zeroes */ "%c%c%c%c%c%c" /* 6 zeroes */
"\xff\xff" /* message length */ "\xff\xff" /* message length */
"%c%c" /* 2 zeroes */ "%c%c" /* 2 zeroes */
"\x01\x82" /* flags */ "\x01\x82" /* flags */
"%c%c" /* 2 zeroes */ "%c%c" /* 2 zeroes */
/* domain string */ /* domain string */
/* user string */ /* user string */
/* host string */ /* host string */
/* LanManager response */ /* LanManager response */
/* NT response */ /* NT response */
, ,
0, /* zero termination */ 0, /* zero termination */
0,0,0, /* type-3 long, the 24 upper bits */ 0,0,0, /* type-3 long, the 24 upper bits */
SHORTPAIR(0x18), /* LanManager response length, twice */ SHORTPAIR(0x18), /* LanManager response length, twice */
SHORTPAIR(0x18), SHORTPAIR(0x18),
SHORTPAIR(lmrespoff), SHORTPAIR(lmrespoff),
0x0, 0x0, 0x0, 0x0,
#ifdef USE_NTRESPONSES #ifdef USE_NTRESPONSES
SHORTPAIR(0x18), /* NT-response length, twice */ SHORTPAIR(0x18), /* NT-response length, twice */
SHORTPAIR(0x18), SHORTPAIR(0x18),
#else #else
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
#endif #endif
SHORTPAIR(ntrespoff), SHORTPAIR(ntrespoff),
0x0, 0x0, 0x0, 0x0,
SHORTPAIR(domlen), SHORTPAIR(domlen),
SHORTPAIR(domlen), SHORTPAIR(domlen),
SHORTPAIR(domoff), SHORTPAIR(domoff),
0x0, 0x0, 0x0, 0x0,
SHORTPAIR(userlen), SHORTPAIR(userlen),
SHORTPAIR(userlen), SHORTPAIR(userlen),
SHORTPAIR(useroff), SHORTPAIR(useroff),
0x0, 0x0, 0x0, 0x0,
SHORTPAIR(hostlen), SHORTPAIR(hostlen),
SHORTPAIR(hostlen), SHORTPAIR(hostlen),
SHORTPAIR(hostoff), SHORTPAIR(hostoff),
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0); 0x0, 0x0);
/* size is now 64 */ /* size is now 64 */
size=64; size=64;

View File

@ -47,11 +47,11 @@ so, delete this exception statement from your version. */
#include "host.h" #include "host.h"
#include "netrc.h" #include "netrc.h"
#include "progress.h" #include "progress.h"
#include "recur.h" /* for INFINITE_RECURSION */ #include "recur.h" /* for INFINITE_RECURSION */
#include "convert.h" /* for convert_cleanup */ #include "convert.h" /* for convert_cleanup */
#include "res.h" /* for res_cleanup */ #include "res.h" /* for res_cleanup */
#include "http.h" /* for http_cleanup */ #include "http.h" /* for http_cleanup */
#include "retr.h" /* for output_stream */ #include "retr.h" /* for output_stream */
#ifdef TESTING #ifdef TESTING
#include "test.h" #include "test.h"
@ -109,139 +109,139 @@ static struct {
bool (*action) (const char *, const char *, void *); bool (*action) (const char *, const char *, void *);
} commands[] = { } commands[] = {
/* KEEP THIS LIST ALPHABETICALLY SORTED */ /* KEEP THIS LIST ALPHABETICALLY SORTED */
{ "accept", &opt.accepts, cmd_vector }, { "accept", &opt.accepts, cmd_vector },
{ "addhostdir", &opt.add_hostdir, cmd_boolean }, { "addhostdir", &opt.add_hostdir, cmd_boolean },
{ "alwaysrest", &opt.always_rest, cmd_boolean }, /* deprecated */ { "alwaysrest", &opt.always_rest, cmd_boolean }, /* deprecated */
{ "background", &opt.background, cmd_boolean }, { "background", &opt.background, cmd_boolean },
{ "backupconverted", &opt.backup_converted, cmd_boolean }, { "backupconverted", &opt.backup_converted, cmd_boolean },
{ "backups", &opt.backups, cmd_number }, { "backups", &opt.backups, cmd_number },
{ "base", &opt.base_href, cmd_string }, { "base", &opt.base_href, cmd_string },
{ "bindaddress", &opt.bind_address, cmd_string }, { "bindaddress", &opt.bind_address, cmd_string },
#ifdef HAVE_SSL #ifdef HAVE_SSL
{ "cacertificate", &opt.ca_cert, cmd_file }, { "cacertificate", &opt.ca_cert, cmd_file },
#endif #endif
{ "cache", &opt.allow_cache, cmd_boolean }, { "cache", &opt.allow_cache, cmd_boolean },
#ifdef HAVE_SSL #ifdef HAVE_SSL
{ "cadirectory", &opt.ca_directory, cmd_directory }, { "cadirectory", &opt.ca_directory, cmd_directory },
{ "certificate", &opt.cert_file, cmd_file }, { "certificate", &opt.cert_file, cmd_file },
{ "certificatetype", &opt.cert_type, cmd_cert_type }, { "certificatetype", &opt.cert_type, cmd_cert_type },
{ "checkcertificate", &opt.check_cert, cmd_boolean }, { "checkcertificate", &opt.check_cert, cmd_boolean },
#endif #endif
{ "connecttimeout", &opt.connect_timeout, cmd_time }, { "connecttimeout", &opt.connect_timeout, cmd_time },
{ "contentdisposition", &opt.content_disposition, cmd_boolean }, { "contentdisposition", &opt.content_disposition, cmd_boolean },
{ "continue", &opt.always_rest, cmd_boolean }, { "continue", &opt.always_rest, cmd_boolean },
{ "convertlinks", &opt.convert_links, cmd_boolean }, { "convertlinks", &opt.convert_links, cmd_boolean },
{ "cookies", &opt.cookies, cmd_boolean }, { "cookies", &opt.cookies, cmd_boolean },
{ "cutdirs", &opt.cut_dirs, cmd_number }, { "cutdirs", &opt.cut_dirs, cmd_number },
#ifdef ENABLE_DEBUG #ifdef ENABLE_DEBUG
{ "debug", &opt.debug, cmd_boolean }, { "debug", &opt.debug, cmd_boolean },
#endif #endif
{ "deleteafter", &opt.delete_after, cmd_boolean }, { "deleteafter", &opt.delete_after, cmd_boolean },
{ "dirprefix", &opt.dir_prefix, cmd_directory }, { "dirprefix", &opt.dir_prefix, cmd_directory },
{ "dirstruct", NULL, cmd_spec_dirstruct }, { "dirstruct", NULL, cmd_spec_dirstruct },
{ "dnscache", &opt.dns_cache, cmd_boolean }, { "dnscache", &opt.dns_cache, cmd_boolean },
{ "dnstimeout", &opt.dns_timeout, cmd_time }, { "dnstimeout", &opt.dns_timeout, cmd_time },
{ "domains", &opt.domains, cmd_vector }, { "domains", &opt.domains, cmd_vector },
{ "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", &opt.dot_style, cmd_string }, { "dotstyle", &opt.dot_style, cmd_string },
#ifdef HAVE_SSL #ifdef HAVE_SSL
{ "egdfile", &opt.egd_file, cmd_file }, { "egdfile", &opt.egd_file, cmd_file },
#endif #endif
{ "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 },
{ "followtags", &opt.follow_tags, cmd_vector }, { "followtags", &opt.follow_tags, cmd_vector },
{ "forcehtml", &opt.force_html, cmd_boolean }, { "forcehtml", &opt.force_html, cmd_boolean },
{ "ftppasswd", &opt.ftp_passwd, cmd_string }, /* deprecated */ { "ftppasswd", &opt.ftp_passwd, cmd_string }, /* deprecated */
{ "ftppassword", &opt.ftp_passwd, cmd_string }, { "ftppassword", &opt.ftp_passwd, cmd_string },
{ "ftpproxy", &opt.ftp_proxy, cmd_string }, { "ftpproxy", &opt.ftp_proxy, cmd_string },
{ "ftpuser", &opt.ftp_user, cmd_string }, { "ftpuser", &opt.ftp_user, cmd_string },
{ "glob", &opt.ftp_glob, cmd_boolean }, { "glob", &opt.ftp_glob, cmd_boolean },
{ "header", NULL, cmd_spec_header }, { "header", NULL, cmd_spec_header },
{ "htmlextension", &opt.html_extension, cmd_boolean }, { "htmlextension", &opt.html_extension, cmd_boolean },
{ "htmlify", NULL, cmd_spec_htmlify }, { "htmlify", NULL, cmd_spec_htmlify },
{ "httpkeepalive", &opt.http_keep_alive, cmd_boolean }, { "httpkeepalive", &opt.http_keep_alive, cmd_boolean },
{ "httppasswd", &opt.http_passwd, cmd_string }, /* deprecated */ { "httppasswd", &opt.http_passwd, cmd_string }, /* deprecated */
{ "httppassword", &opt.http_passwd, cmd_string }, { "httppassword", &opt.http_passwd, cmd_string },
{ "httpproxy", &opt.http_proxy, cmd_string }, { "httpproxy", &opt.http_proxy, cmd_string },
{ "httpsproxy", &opt.https_proxy, cmd_string }, { "httpsproxy", &opt.https_proxy, cmd_string },
{ "httpuser", &opt.http_user, cmd_string }, { "httpuser", &opt.http_user, cmd_string },
{ "ignorecase", &opt.ignore_case, cmd_boolean }, { "ignorecase", &opt.ignore_case, cmd_boolean },
{ "ignorelength", &opt.ignore_length, cmd_boolean }, { "ignorelength", &opt.ignore_length, cmd_boolean },
{ "ignoretags", &opt.ignore_tags, cmd_vector }, { "ignoretags", &opt.ignore_tags, cmd_vector },
{ "includedirectories", &opt.includes, cmd_directory_vector }, { "includedirectories", &opt.includes, cmd_directory_vector },
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
{ "inet4only", &opt.ipv4_only, cmd_boolean }, { "inet4only", &opt.ipv4_only, cmd_boolean },
{ "inet6only", &opt.ipv6_only, cmd_boolean }, { "inet6only", &opt.ipv6_only, cmd_boolean },
#endif #endif
{ "input", &opt.input_filename, cmd_file }, { "input", &opt.input_filename, cmd_file },
{ "keepsessioncookies", &opt.keep_session_cookies, cmd_boolean }, { "keepsessioncookies", &opt.keep_session_cookies, cmd_boolean },
{ "limitrate", &opt.limit_rate, cmd_bytes }, { "limitrate", &opt.limit_rate, cmd_bytes },
{ "loadcookies", &opt.cookies_input, cmd_file }, { "loadcookies", &opt.cookies_input, cmd_file },
{ "logfile", &opt.lfilename, cmd_file }, { "logfile", &opt.lfilename, cmd_file },
{ "login", &opt.ftp_user, cmd_string },/* deprecated*/ { "login", &opt.ftp_user, cmd_string },/* deprecated*/
{ "maxredirect", &opt.max_redirect, cmd_number }, { "maxredirect", &opt.max_redirect, cmd_number },
{ "mirror", NULL, cmd_spec_mirror }, { "mirror", NULL, cmd_spec_mirror },
{ "netrc", &opt.netrc, cmd_boolean }, { "netrc", &opt.netrc, cmd_boolean },
{ "noclobber", &opt.noclobber, cmd_boolean }, { "noclobber", &opt.noclobber, cmd_boolean },
{ "noparent", &opt.no_parent, cmd_boolean }, { "noparent", &opt.no_parent, cmd_boolean },
{ "noproxy", &opt.no_proxy, cmd_vector }, { "noproxy", &opt.no_proxy, cmd_vector },
{ "numtries", &opt.ntry, cmd_number_inf },/* deprecated*/ { "numtries", &opt.ntry, cmd_number_inf },/* deprecated*/
{ "outputdocument", &opt.output_document, cmd_file }, { "outputdocument", &opt.output_document, cmd_file },
{ "pagerequisites", &opt.page_requisites, cmd_boolean }, { "pagerequisites", &opt.page_requisites, cmd_boolean },
{ "passiveftp", &opt.ftp_pasv, cmd_boolean }, { "passiveftp", &opt.ftp_pasv, cmd_boolean },
{ "passwd", &opt.ftp_passwd, cmd_string },/* deprecated*/ { "passwd", &opt.ftp_passwd, cmd_string },/* deprecated*/
{ "password", &opt.passwd, cmd_string }, { "password", &opt.passwd, cmd_string },
{ "postdata", &opt.post_data, cmd_string }, { "postdata", &opt.post_data, cmd_string },
{ "postfile", &opt.post_file_name, cmd_file }, { "postfile", &opt.post_file_name, cmd_file },
{ "preferfamily", NULL, cmd_spec_prefer_family }, { "preferfamily", NULL, cmd_spec_prefer_family },
{ "preservepermissions", &opt.preserve_perm, cmd_boolean }, { "preservepermissions", &opt.preserve_perm, cmd_boolean },
#ifdef HAVE_SSL #ifdef HAVE_SSL
{ "privatekey", &opt.private_key, cmd_file }, { "privatekey", &opt.private_key, cmd_file },
{ "privatekeytype", &opt.private_key_type, cmd_cert_type }, { "privatekeytype", &opt.private_key_type, cmd_cert_type },
#endif #endif
{ "progress", &opt.progress_type, cmd_spec_progress }, { "progress", &opt.progress_type, cmd_spec_progress },
{ "protocoldirectories", &opt.protocol_directories, cmd_boolean }, { "protocoldirectories", &opt.protocol_directories, cmd_boolean },
{ "proxypasswd", &opt.proxy_passwd, cmd_string }, /* deprecated */ { "proxypasswd", &opt.proxy_passwd, cmd_string }, /* deprecated */
{ "proxypassword", &opt.proxy_passwd, cmd_string }, { "proxypassword", &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 },
{ "quota", &opt.quota, cmd_bytes_sum }, { "quota", &opt.quota, cmd_bytes_sum },
#ifdef HAVE_SSL #ifdef HAVE_SSL
{ "randomfile", &opt.random_file, cmd_file }, { "randomfile", &opt.random_file, cmd_file },
#endif #endif
{ "randomwait", &opt.random_wait, cmd_boolean }, { "randomwait", &opt.random_wait, cmd_boolean },
{ "readtimeout", &opt.read_timeout, cmd_time }, { "readtimeout", &opt.read_timeout, cmd_time },
{ "reclevel", &opt.reclevel, cmd_number_inf }, { "reclevel", &opt.reclevel, cmd_number_inf },
{ "recursive", NULL, cmd_spec_recursive }, { "recursive", NULL, cmd_spec_recursive },
{ "referer", &opt.referer, cmd_string }, { "referer", &opt.referer, cmd_string },
{ "reject", &opt.rejects, cmd_vector }, { "reject", &opt.rejects, cmd_vector },
{ "relativeonly", &opt.relative_only, cmd_boolean }, { "relativeonly", &opt.relative_only, cmd_boolean },
{ "removelisting", &opt.remove_listing, cmd_boolean }, { "removelisting", &opt.remove_listing, cmd_boolean },
{ "restrictfilenames", NULL, cmd_spec_restrict_file_names }, { "restrictfilenames", NULL, cmd_spec_restrict_file_names },
{ "retrsymlinks", &opt.retr_symlinks, cmd_boolean }, { "retrsymlinks", &opt.retr_symlinks, cmd_boolean },
{ "retryconnrefused", &opt.retry_connrefused, cmd_boolean }, { "retryconnrefused", &opt.retry_connrefused, cmd_boolean },
{ "robots", &opt.use_robots, cmd_boolean }, { "robots", &opt.use_robots, cmd_boolean },
{ "savecookies", &opt.cookies_output, cmd_file }, { "savecookies", &opt.cookies_output, cmd_file },
{ "saveheaders", &opt.save_headers, cmd_boolean }, { "saveheaders", &opt.save_headers, cmd_boolean },
#ifdef HAVE_SSL #ifdef HAVE_SSL
{ "secureprotocol", &opt.secure_protocol, cmd_spec_secure_protocol }, { "secureprotocol", &opt.secure_protocol, cmd_spec_secure_protocol },
#endif #endif
{ "serverresponse", &opt.server_response, cmd_boolean }, { "serverresponse", &opt.server_response, cmd_boolean },
{ "spanhosts", &opt.spanhost, cmd_boolean }, { "spanhosts", &opt.spanhost, cmd_boolean },
{ "spider", &opt.spider, cmd_boolean }, { "spider", &opt.spider, cmd_boolean },
{ "strictcomments", &opt.strict_comments, cmd_boolean }, { "strictcomments", &opt.strict_comments, cmd_boolean },
{ "timeout", NULL, cmd_spec_timeout }, { "timeout", NULL, cmd_spec_timeout },
{ "timestamping", &opt.timestamping, cmd_boolean }, { "timestamping", &opt.timestamping, cmd_boolean },
{ "tries", &opt.ntry, cmd_number_inf }, { "tries", &opt.ntry, cmd_number_inf },
{ "useproxy", &opt.use_proxy, cmd_boolean }, { "useproxy", &opt.use_proxy, cmd_boolean },
{ "user", &opt.user, cmd_string }, { "user", &opt.user, cmd_string },
{ "useragent", NULL, cmd_spec_useragent }, { "useragent", NULL, cmd_spec_useragent },
{ "verbose", NULL, cmd_spec_verbose }, { "verbose", NULL, cmd_spec_verbose },
{ "wait", &opt.wait, cmd_time }, { "wait", &opt.wait, cmd_time },
{ "waitretry", &opt.waitretry, cmd_time } { "waitretry", &opt.waitretry, cmd_time }
}; };
/* Look up CMDNAME in the commands[] and return its position in the /* Look up CMDNAME in the commands[] and return its position in the
@ -259,11 +259,11 @@ command_by_name (const char *cmdname)
int mid = (lo + hi) >> 1; int mid = (lo + hi) >> 1;
int cmp = strcasecmp (cmdname, commands[mid].name); int cmp = strcasecmp (cmdname, commands[mid].name);
if (cmp < 0) if (cmp < 0)
hi = mid - 1; hi = mid - 1;
else if (cmp > 0) else if (cmp > 0)
lo = mid + 1; lo = mid + 1;
else else
return mid; return mid;
} }
return -1; return -1;
} }
@ -339,7 +339,7 @@ home_dir (void)
file. */ file. */
struct passwd *pwd = getpwuid (getuid ()); struct passwd *pwd = getpwuid (getuid ());
if (!pwd || !pwd->pw_dir) if (!pwd || !pwd->pw_dir)
return NULL; return NULL;
home = pwd->pw_dir; home = pwd->pw_dir;
#else /* WINDOWS */ #else /* WINDOWS */
/* Under Windows, if $HOME isn't defined, use the directory where /* Under Windows, if $HOME isn't defined, use the directory where
@ -367,11 +367,11 @@ wgetrc_file_name (void)
if (env && *env) if (env && *env)
{ {
if (!file_exists_p (env)) if (!file_exists_p (env))
{ {
fprintf (stderr, _("%s: WGETRC points to %s, which doesn't exist.\n"), fprintf (stderr, _("%s: WGETRC points to %s, which doesn't exist.\n"),
exec_name, env); exec_name, env);
exit (1); exit (1);
} }
return xstrdup (env); return xstrdup (env);
} }
@ -392,7 +392,7 @@ wgetrc_file_name (void)
file = NULL; file = NULL;
home = ws_mypath (); home = ws_mypath ();
if (home) if (home)
file = aprintf ("%s/wget.ini", home); file = aprintf ("%s/wget.ini", home);
} }
#endif /* WINDOWS */ #endif /* WINDOWS */
@ -432,8 +432,8 @@ run_wgetrc (const char *file)
if (!fp) if (!fp)
{ {
fprintf (stderr, _("%s: Cannot read %s (%s).\n"), exec_name, fprintf (stderr, _("%s: Cannot read %s (%s).\n"), exec_name,
file, strerror (errno)); file, strerror (errno));
return true; /* not a fatal error */ return true; /* not a fatal error */
} }
enable_tilde_expansion = true; enable_tilde_expansion = true;
ln = 1; ln = 1;
@ -444,31 +444,31 @@ run_wgetrc (const char *file)
/* Parse the line. */ /* Parse the line. */
switch (parse_line (line, &com, &val, &comind)) switch (parse_line (line, &com, &val, &comind))
{ {
case line_ok: case line_ok:
/* If everything is OK, set the value. */ /* If everything is OK, set the value. */
if (!setval_internal (comind, com, val)) if (!setval_internal (comind, com, val))
{ {
fprintf (stderr, _("%s: Error in %s at line %d.\n"), fprintf (stderr, _("%s: Error in %s at line %d.\n"),
exec_name, file, ln); exec_name, file, ln);
++errcnt; ++errcnt;
} }
break; break;
case line_syntax_error: case line_syntax_error:
fprintf (stderr, _("%s: Syntax error in %s at line %d.\n"), fprintf (stderr, _("%s: Syntax error in %s at line %d.\n"),
exec_name, file, ln); exec_name, file, ln);
++errcnt; ++errcnt;
break; break;
case line_unknown_command: case line_unknown_command:
fprintf (stderr, _("%s: Unknown command `%s' in %s at line %d.\n"), fprintf (stderr, _("%s: Unknown command `%s' in %s at line %d.\n"),
exec_name, com, file, ln); exec_name, com, file, ln);
++errcnt; ++errcnt;
break; break;
case line_empty: case line_empty:
break; break;
default: default:
abort (); abort ();
} }
xfree_null (com); xfree_null (com);
xfree_null (val); xfree_null (val);
xfree (line); xfree (line);
@ -507,7 +507,7 @@ initialize (void)
{ {
fprintf (stderr, _("\ fprintf (stderr, _("\
%s: Warning: Both system and user wgetrc point to `%s'.\n"), %s: Warning: Both system and user wgetrc point to `%s'.\n"),
exec_name, file); exec_name, file);
} }
else else
#endif #endif
@ -527,8 +527,8 @@ initialize (void)
static void static void
dehyphen (char *s) dehyphen (char *s)
{ {
char *t = s; /* t - tortoise */ char *t = s; /* t - tortoise */
char *h = s; /* h - hare */ char *h = s; /* h - hare */
while (*h) while (*h)
if (*h == '_' || *h == '-') if (*h == '_' || *h == '-')
++h; ++h;
@ -653,13 +653,13 @@ run_command (const char *opt)
{ {
case line_ok: case line_ok:
if (!setval_internal (comind, com, val)) if (!setval_internal (comind, com, val))
exit (2); exit (2);
xfree (com); xfree (com);
xfree (val); xfree (val);
break; break;
default: default:
fprintf (stderr, _("%s: Invalid --execute command `%s'\n"), fprintf (stderr, _("%s: Invalid --execute command `%s'\n"),
exec_name, opt); exec_name, opt);
exit (2); exit (2);
} }
} }
@ -677,14 +677,14 @@ static bool simple_atof (const char *, const char *, double *);
#define CMP1(p, c0) (TOLOWER((p)[0]) == (c0) && (p)[1] == '\0') #define CMP1(p, c0) (TOLOWER((p)[0]) == (c0) && (p)[1] == '\0')
#define CMP2(p, c0, c1) (TOLOWER((p)[0]) == (c0) \ #define CMP2(p, c0, c1) (TOLOWER((p)[0]) == (c0) \
&& TOLOWER((p)[1]) == (c1) \ && TOLOWER((p)[1]) == (c1) \
&& (p)[2] == '\0') && (p)[2] == '\0')
#define CMP3(p, c0, c1, c2) (TOLOWER((p)[0]) == (c0) \ #define CMP3(p, c0, c1, c2) (TOLOWER((p)[0]) == (c0) \
&& TOLOWER((p)[1]) == (c1) \ && TOLOWER((p)[1]) == (c1) \
&& TOLOWER((p)[2]) == (c2) \ && TOLOWER((p)[2]) == (c2) \
&& (p)[3] == '\0') && (p)[3] == '\0')
/* Store the boolean value from VAL to PLACE. COM is ignored, /* Store the boolean value from VAL to PLACE. COM is ignored,
@ -703,8 +703,8 @@ cmd_boolean (const char *com, const char *val, void *place)
else else
{ {
fprintf (stderr, fprintf (stderr,
_("%s: %s: Invalid boolean `%s'; use `on' or `off'.\n"), _("%s: %s: Invalid boolean `%s'; use `on' or `off'.\n"),
exec_name, com, val); exec_name, com, val);
return false; return false;
} }
@ -721,7 +721,7 @@ cmd_number (const char *com, const char *val, void *place)
|| *(int *) place < 0) || *(int *) place < 0)
{ {
fprintf (stderr, _("%s: %s: Invalid number `%s'.\n"), fprintf (stderr, _("%s: %s: Invalid number `%s'.\n"),
exec_name, com, val); exec_name, com, val);
return false; return false;
} }
return true; return true;
@ -779,15 +779,15 @@ cmd_file (const char *com, const char *val, void *place)
int homelen; int homelen;
char *home = home_dir (); char *home = home_dir ();
if (!home) if (!home)
goto noexpand; goto noexpand;
homelen = strlen (home); homelen = strlen (home);
while (homelen && ISSEP (home[homelen - 1])) while (homelen && ISSEP (home[homelen - 1]))
home[--homelen] = '\0'; home[--homelen] = '\0';
/* Skip the leading "~/". */ /* Skip the leading "~/". */
for (++val; ISSEP (*val); val++) for (++val; ISSEP (*val); val++)
; ;
*pstring = concat_strings (home, "/", val, (char *) 0); *pstring = concat_strings (home, "/", val, (char *) 0);
} }
@ -798,7 +798,7 @@ cmd_file (const char *com, const char *val, void *place)
char *s; char *s;
for (s = *pstring; *s; s++) for (s = *pstring; *s; s++)
if (*s == '\\') if (*s == '\\')
*s = '/'; *s = '/';
} }
#endif #endif
return true; return true;
@ -855,15 +855,15 @@ cmd_directory_vector (const char *com, const char *val, void *place)
seps = sepstring (val); seps = sepstring (val);
for (t = seps; t && *t; t++) for (t = seps; t && *t; t++)
{ {
int len = strlen (*t); int len = strlen (*t);
/* Skip degenerate case of root directory. */ /* Skip degenerate case of root directory. */
if (len > 1) if (len > 1)
{ {
if ((*t)[len - 1] == '/') if ((*t)[len - 1] == '/')
(*t)[len - 1] = '\0'; (*t)[len - 1] = '\0';
} }
} }
*pvec = merge_vecs (*pvec, seps); *pvec = merge_vecs (*pvec, seps);
} }
else else
@ -912,7 +912,7 @@ parse_bytes_helper (const char *val, double *result)
break; break;
default: default:
/* Not a recognized suffix: assume it's a digit. (If not, /* Not a recognized suffix: assume it's a digit. (If not,
simple_atof will raise an error.) */ simple_atof will raise an error.) */
mult = 1; mult = 1;
} }
@ -952,7 +952,7 @@ cmd_bytes (const char *com, const char *val, void *place)
if (!parse_bytes_helper (val, &byte_value)) if (!parse_bytes_helper (val, &byte_value))
{ {
fprintf (stderr, _("%s: %s: Invalid byte value `%s'\n"), fprintf (stderr, _("%s: %s: Invalid byte value `%s'\n"),
exec_name, com, val); exec_name, com, val);
return false; return false;
} }
*(wgint *)place = (wgint)byte_value; *(wgint *)place = (wgint)byte_value;
@ -971,7 +971,7 @@ cmd_bytes_sum (const char *com, const char *val, void *place)
if (!parse_bytes_helper (val, &byte_value)) if (!parse_bytes_helper (val, &byte_value))
{ {
fprintf (stderr, _("%s: %s: Invalid byte value `%s'\n"), fprintf (stderr, _("%s: %s: Invalid byte value `%s'\n"),
exec_name, com, val); exec_name, com, val);
return false; return false;
} }
*(SUM_SIZE_INT *) place = (SUM_SIZE_INT) byte_value; *(SUM_SIZE_INT *) place = (SUM_SIZE_INT) byte_value;
@ -996,30 +996,30 @@ cmd_time (const char *com, const char *val, void *place)
{ {
err: err:
fprintf (stderr, _("%s: %s: Invalid time period `%s'\n"), fprintf (stderr, _("%s: %s: Invalid time period `%s'\n"),
exec_name, com, val); exec_name, com, val);
return false; return false;
} }
switch (TOLOWER (end[-1])) switch (TOLOWER (end[-1]))
{ {
case 's': case 's':
--end, mult = 1; /* seconds */ --end, mult = 1; /* seconds */
break; break;
case 'm': case 'm':
--end, mult = 60; /* minutes */ --end, mult = 60; /* minutes */
break; break;
case 'h': case 'h':
--end, mult = 3600; /* hours */ --end, mult = 3600; /* hours */
break; break;
case 'd': case 'd':
--end, mult = 86400.0; /* days */ --end, mult = 86400.0; /* days */
break; break;
case 'w': case 'w':
--end, mult = 604800.0; /* weeks */ --end, mult = 604800.0; /* weeks */
break; break;
default: default:
/* Not a recognized suffix: assume it belongs to the number. /* Not a recognized suffix: assume it belongs to the number.
(If not, simple_atof will raise an error.) */ (If not, simple_atof will raise an error.) */
mult = 1; mult = 1;
} }
@ -1087,7 +1087,7 @@ cmd_spec_header (const char *com, const char *val, void *place_ignored)
if (!check_user_specified_header (val)) if (!check_user_specified_header (val))
{ {
fprintf (stderr, _("%s: %s: Invalid header `%s'.\n"), fprintf (stderr, _("%s: %s: Invalid header `%s'.\n"),
exec_name, com, val); exec_name, com, val);
return false; return false;
} }
opt.user_headers = vec_append (opt.user_headers, val); opt.user_headers = vec_append (opt.user_headers, val);
@ -1117,7 +1117,7 @@ cmd_spec_mirror (const char *com, const char *val, void *place_ignored)
{ {
opt.recursive = true; opt.recursive = true;
if (!opt.no_dirstruct) if (!opt.no_dirstruct)
opt.dirstruct = true; opt.dirstruct = true;
opt.timestamping = true; opt.timestamping = true;
opt.reclevel = INFINITE_RECURSION; opt.reclevel = INFINITE_RECURSION;
opt.remove_listing = false; opt.remove_listing = false;
@ -1153,7 +1153,7 @@ cmd_spec_progress (const char *com, const char *val, void *place_ignored)
if (!valid_progress_implementation_p (val)) if (!valid_progress_implementation_p (val))
{ {
fprintf (stderr, _("%s: %s: Invalid progress type `%s'.\n"), fprintf (stderr, _("%s: %s: Invalid progress type `%s'.\n"),
exec_name, com, val); exec_name, com, val);
return false; return false;
} }
xfree_null (opt.progress_type); xfree_null (opt.progress_type);
@ -1176,7 +1176,7 @@ cmd_spec_recursive (const char *com, const char *val, void *place_ignored)
else else
{ {
if (opt.recursive && !opt.no_dirstruct) if (opt.recursive && !opt.no_dirstruct)
opt.dirstruct = true; opt.dirstruct = true;
} }
return true; return true;
} }
@ -1214,10 +1214,10 @@ cmd_spec_restrict_file_names (const char *com, const char *val, void *place_igno
_("%s: %s: Invalid restriction `%s', use [unix|windows],[lowercase|uppercase],[nocontrol].\n"), _("%s: %s: Invalid restriction `%s', use [unix|windows],[lowercase|uppercase],[nocontrol].\n"),
exec_name, com, val); exec_name, com, val);
return false; return false;
} }
if (*end) if (*end)
val = end + 1; val = end + 1;
} }
while (*val && *end); while (*val && *end);
@ -1268,7 +1268,7 @@ cmd_spec_useragent (const char *com, const char *val, void *place_ignored)
if (strchr (val, '\n')) if (strchr (val, '\n'))
{ {
fprintf (stderr, _("%s: %s: Invalid value `%s'.\n"), fprintf (stderr, _("%s: %s: Invalid value `%s'.\n"),
exec_name, com, val); exec_name, com, val);
return false; return false;
} }
xfree_null (opt.useragent); xfree_null (opt.useragent);
@ -1321,18 +1321,18 @@ simple_atoi (const char *beg, const char *end, int *dest)
if (!negative) if (!negative)
for (; p < end && ISDIGIT (*p); p++) for (; p < end && ISDIGIT (*p); p++)
{ {
int next = (10 * result) + (*p - '0'); int next = (10 * result) + (*p - '0');
if (next < result) if (next < result)
return false; /* overflow */ return false; /* overflow */
result = next; result = next;
} }
else else
for (; p < end && ISDIGIT (*p); p++) for (; p < end && ISDIGIT (*p); p++)
{ {
int next = (10 * result) - (*p - '0'); int next = (10 * result) - (*p - '0');
if (next > result) if (next > result)
return false; /* underflow */ return false; /* underflow */
result = next; result = next;
} }
if (p != end) if (p != end)
@ -1371,22 +1371,22 @@ simple_atof (const char *beg, const char *end, double *dest)
{ {
char ch = *p; char ch = *p;
if (ISDIGIT (ch)) if (ISDIGIT (ch))
{ {
if (!seen_dot) if (!seen_dot)
result = (10 * result) + (ch - '0'); result = (10 * result) + (ch - '0');
else else
result += (ch - '0') / (divider *= 10); result += (ch - '0') / (divider *= 10);
seen_digit = true; seen_digit = true;
} }
else if (ch == '.') else if (ch == '.')
{ {
if (!seen_dot) if (!seen_dot)
seen_dot = true; seen_dot = true;
else else
return false; return false;
} }
else else
return false; return false;
} }
if (!seen_digit) if (!seen_digit)
return false; return false;
@ -1422,14 +1422,14 @@ check_user_specified_header (const char *s)
static bool static bool
decode_string (const char *val, const struct decode_item *items, int itemcount, decode_string (const char *val, const struct decode_item *items, int itemcount,
int *place) int *place)
{ {
int i; int i;
for (i = 0; i < itemcount; i++) for (i = 0; i < itemcount; i++)
if (0 == strcasecmp (val, items[i].name)) if (0 == strcasecmp (val, items[i].name))
{ {
*place = items[i].code; *place = items[i].code;
return true; return true;
} }
return false; return false;
} }

222
src/log.c
View File

@ -107,9 +107,9 @@ static bool needs_flushing;
static struct log_ln { static struct log_ln {
char static_line[STATIC_LENGTH + 1]; /* statically allocated char static_line[STATIC_LENGTH + 1]; /* statically allocated
line. */ line. */
char *malloced_line; /* malloc'ed line, for lines of output char *malloced_line; /* malloc'ed line, for lines of output
larger than 80 characters. */ larger than 80 characters. */
char *content; /* this points either to malloced_line char *content; /* this points either to malloced_line
or to the appropriate static_line. or to the appropriate static_line.
If this is NULL, it means the line If this is NULL, it means the line
has not yet been used. */ has not yet been used. */
@ -126,9 +126,9 @@ static bool trailing_line;
static void check_redirect_output (void); static void check_redirect_output (void);
#define ROT_ADVANCE(num) do { \ #define ROT_ADVANCE(num) do { \
if (++num >= SAVED_LOG_LINES) \ if (++num >= SAVED_LOG_LINES) \
num = 0; \ num = 0; \
} while (0) } while (0)
/* Free the log line index with NUM. This calls free on /* Free the log line index with NUM. This calls free on
@ -166,21 +166,21 @@ saved_append_1 (const char *start, const char *end)
struct log_ln *ln; struct log_ln *ln;
if (log_line_current == -1) if (log_line_current == -1)
log_line_current = 0; log_line_current = 0;
else else
free_log_line (log_line_current); free_log_line (log_line_current);
ln = log_lines + log_line_current; ln = log_lines + log_line_current;
if (len > STATIC_LENGTH) if (len > STATIC_LENGTH)
{ {
ln->malloced_line = strdupdelim (start, end); ln->malloced_line = strdupdelim (start, end);
ln->content = ln->malloced_line; ln->content = ln->malloced_line;
} }
else else
{ {
memcpy (ln->static_line, start, len); memcpy (ln->static_line, start, len);
ln->static_line[len] = '\0'; ln->static_line[len] = '\0';
ln->content = ln->static_line; ln->content = ln->static_line;
} }
} }
else else
{ {
@ -191,38 +191,38 @@ saved_append_1 (const char *start, const char *end)
convert it to malloc(). */ convert it to malloc(). */
struct log_ln *ln = log_lines + log_line_current; struct log_ln *ln = log_lines + log_line_current;
if (ln->malloced_line) if (ln->malloced_line)
{ {
/* Resize malloc'ed line and append. */ /* Resize malloc'ed line and append. */
int old_len = strlen (ln->malloced_line); int old_len = strlen (ln->malloced_line);
ln->malloced_line = xrealloc (ln->malloced_line, old_len + len + 1); ln->malloced_line = xrealloc (ln->malloced_line, old_len + len + 1);
memcpy (ln->malloced_line + old_len, start, len); memcpy (ln->malloced_line + old_len, start, len);
ln->malloced_line[old_len + len] = '\0'; ln->malloced_line[old_len + len] = '\0';
/* might have changed due to realloc */ /* might have changed due to realloc */
ln->content = ln->malloced_line; ln->content = ln->malloced_line;
} }
else else
{ {
int old_len = strlen (ln->static_line); int old_len = strlen (ln->static_line);
if (old_len + len > STATIC_LENGTH) if (old_len + len > STATIC_LENGTH)
{ {
/* Allocate memory and concatenate the old and the new /* Allocate memory and concatenate the old and the new
contents. */ contents. */
ln->malloced_line = xmalloc (old_len + len + 1); ln->malloced_line = xmalloc (old_len + len + 1);
memcpy (ln->malloced_line, ln->static_line, memcpy (ln->malloced_line, ln->static_line,
old_len); old_len);
memcpy (ln->malloced_line + old_len, start, len); memcpy (ln->malloced_line + old_len, start, len);
ln->malloced_line[old_len + len] = '\0'; ln->malloced_line[old_len + len] = '\0';
ln->content = ln->malloced_line; ln->content = ln->malloced_line;
} }
else else
{ {
/* Just append to the old, statically allocated /* Just append to the old, statically allocated
contents. */ contents. */
memcpy (ln->static_line + old_len, start, len); memcpy (ln->static_line + old_len, start, len);
ln->static_line[old_len + len] = '\0'; ln->static_line[old_len + len] = '\0';
ln->content = ln->static_line; ln->content = ln->static_line;
} }
} }
} }
trailing_line = !(end[-1] == '\n'); trailing_line = !(end[-1] == '\n');
if (!trailing_line) if (!trailing_line)
@ -241,9 +241,9 @@ saved_append (const char *s)
{ {
const char *end = strchr (s, '\n'); const char *end = strchr (s, '\n');
if (!end) if (!end)
end = s + strlen (s); end = s + strlen (s);
else else
++end; ++end;
saved_append_1 (s, end); saved_append_1 (s, end);
s = end; s = end;
} }
@ -259,22 +259,22 @@ saved_append (const char *s)
* LOG_NONVERBOSE - print the message if opt.verbose is zero; * LOG_NONVERBOSE - print the message if opt.verbose is zero;
* LOG_VERBOSE - print the message if opt.verbose is non-zero. */ * LOG_VERBOSE - print the message if opt.verbose is non-zero. */
#define CHECK_VERBOSE(x) \ #define CHECK_VERBOSE(x) \
switch (x) \ switch (x) \
{ \ { \
case LOG_ALWAYS: \ case LOG_ALWAYS: \
break; \ break; \
case LOG_NOTQUIET: \ case LOG_NOTQUIET: \
if (opt.quiet) \ if (opt.quiet) \
return; \ return; \
break; \ break; \
case LOG_NONVERBOSE: \ case LOG_NONVERBOSE: \
if (opt.verbose || opt.quiet) \ if (opt.verbose || opt.quiet) \
return; \ return; \
break; \ break; \
case LOG_VERBOSE: \ case LOG_VERBOSE: \
if (!opt.verbose) \ if (!opt.verbose) \
return; \ return; \
} }
/* Returns the file descriptor for logging. This is LOGFP, except if /* Returns the file descriptor for logging. This is LOGFP, except if
@ -337,7 +337,7 @@ struct logvprintf_state {
static bool static bool
log_vprintf_internal (struct logvprintf_state *state, const char *fmt, log_vprintf_internal (struct logvprintf_state *state, const char *fmt,
va_list args) va_list args)
{ {
char smallmsg[128]; char smallmsg[128];
char *write_ptr = smallmsg; char *write_ptr = smallmsg;
@ -378,7 +378,7 @@ log_vprintf_internal (struct logvprintf_state *state, const char *fmt,
if (numwritten == -1) if (numwritten == -1)
{ {
/* Writing failed, and we don't know the needed size. Try /* Writing failed, and we don't know the needed size. Try
again with doubled size. */ again with doubled size. */
int newsize = available_size << 1; int newsize = available_size << 1;
state->bigmsg = xrealloc (state->bigmsg, newsize); state->bigmsg = xrealloc (state->bigmsg, newsize);
state->allocated = newsize; state->allocated = newsize;
@ -387,7 +387,7 @@ log_vprintf_internal (struct logvprintf_state *state, const char *fmt,
else if (numwritten >= available_size) else if (numwritten >= available_size)
{ {
/* Writing failed, but we know exactly how much space we /* Writing failed, but we know exactly how much space we
need. */ need. */
int newsize = numwritten + 1; int newsize = numwritten + 1;
state->bigmsg = xrealloc (state->bigmsg, newsize); state->bigmsg = xrealloc (state->bigmsg, newsize);
state->allocated = newsize; state->allocated = newsize;
@ -434,9 +434,9 @@ log_set_flush (bool flush)
else else
{ {
/* Reenable flushing. If anything was printed in no-flush mode, /* Reenable flushing. If anything was printed in no-flush mode,
flush the log now. */ flush the log now. */
if (needs_flushing) if (needs_flushing)
logflush (); logflush ();
flush_log_p = true; flush_log_p = true;
} }
} }
@ -493,15 +493,15 @@ debug_logprintf (const char *fmt, ...)
check_redirect_output (); check_redirect_output ();
if (inhibit_logging) if (inhibit_logging)
return; return;
xzero (lpstate); xzero (lpstate);
do do
{ {
va_start (args, fmt); va_start (args, fmt);
done = log_vprintf_internal (&lpstate, fmt, args); done = log_vprintf_internal (&lpstate, fmt, args);
va_end (args); va_end (args);
} }
while (!done); while (!done);
} }
} }
@ -516,10 +516,10 @@ log_init (const char *file, bool appendp)
{ {
logfp = fopen (file, appendp ? "a" : "w"); logfp = fopen (file, appendp ? "a" : "w");
if (!logfp) if (!logfp)
{ {
fprintf (stderr, "%s: %s: %s\n", exec_name, file, strerror (errno)); fprintf (stderr, "%s: %s: %s\n", exec_name, file, strerror (errno));
exit (1); exit (1);
} }
} }
else else
{ {
@ -533,16 +533,16 @@ log_init (const char *file, bool appendp)
if (1 if (1
#ifdef HAVE_ISATTY #ifdef HAVE_ISATTY
&& isatty (fileno (logfp)) && isatty (fileno (logfp))
#endif #endif
) )
{ {
/* If the output is a TTY, enable save context, i.e. store /* If the output is a TTY, enable save context, i.e. store
the most recent several messages ("context") and dump the most recent several messages ("context") and dump
them to a log file in case SIGHUP or SIGUSR1 is received them to a log file in case SIGHUP or SIGUSR1 is received
(or Ctrl+Break is pressed under Windows). */ (or Ctrl+Break is pressed under Windows). */
save_context_p = true; save_context_p = true;
} }
} }
} }
@ -582,7 +582,7 @@ log_dump_context (void)
{ {
struct log_ln *ln = log_lines + num; struct log_ln *ln = log_lines + num;
if (ln->content) if (ln->content)
fputs (ln->content, fp); fputs (ln->content, fp);
ROT_ADVANCE (num); ROT_ADVANCE (num);
} }
while (num != log_line_current); while (num != log_line_current);
@ -643,26 +643,26 @@ copy_and_escape (const char *source, char *dest, char escape, int base)
{ {
case 8: case 8:
while ((c = *from++) != '\0') while ((c = *from++) != '\0')
if (ISPRINT (c)) if (ISPRINT (c))
*to++ = c; *to++ = c;
else else
{ {
*to++ = escape; *to++ = escape;
*to++ = '0' + (c >> 6); *to++ = '0' + (c >> 6);
*to++ = '0' + ((c >> 3) & 7); *to++ = '0' + ((c >> 3) & 7);
*to++ = '0' + (c & 7); *to++ = '0' + (c & 7);
} }
break; break;
case 16: case 16:
while ((c = *from++) != '\0') while ((c = *from++) != '\0')
if (ISPRINT (c)) if (ISPRINT (c))
*to++ = c; *to++ = c;
else else
{ {
*to++ = escape; *to++ = escape;
*to++ = XNUM_TO_DIGIT (c >> 4); *to++ = XNUM_TO_DIGIT (c >> 4);
*to++ = XNUM_TO_DIGIT (c & 0xf); *to++ = XNUM_TO_DIGIT (c & 0xf);
} }
break; break;
default: default:
abort (); abort ();
@ -675,12 +675,12 @@ struct ringel {
char *buffer; char *buffer;
int size; int size;
}; };
static struct ringel ring[RING_SIZE]; /* ring data */ static struct ringel ring[RING_SIZE]; /* ring data */
static const char * static const char *
escnonprint_internal (const char *str, char escape, int base) escnonprint_internal (const char *str, char escape, int base)
{ {
static int ringpos; /* current ring position */ static int ringpos; /* current ring position */
int nprcnt; int nprcnt;
assert (base == 8 || base == 16); assert (base == 8 || base == 16);
@ -706,8 +706,8 @@ escnonprint_internal (const char *str, char escape, int base)
(re)allocate it. */ (re)allocate it. */
if (r->buffer == NULL || r->size < needed_size) if (r->buffer == NULL || r->size < needed_size)
{ {
r->buffer = xrealloc (r->buffer, needed_size); r->buffer = xrealloc (r->buffer, needed_size);
r->size = needed_size; r->size = needed_size;
} }
copy_and_escape (str, r->buffer, escape, base); copy_and_escape (str, r->buffer, escape, base);
@ -781,7 +781,7 @@ redirect_output (void)
if (logfp) if (logfp)
{ {
fprintf (stderr, _("\n%s received, redirecting output to `%s'.\n"), fprintf (stderr, _("\n%s received, redirecting output to `%s'.\n"),
redirect_request_signal_name, logfile); redirect_request_signal_name, logfile);
xfree (logfile); xfree (logfile);
/* Dump the context output to the newly opened log. */ /* Dump the context output to the newly opened log. */
log_dump_context (); log_dump_context ();
@ -792,7 +792,7 @@ redirect_output (void)
can do but disable printing completely. */ can do but disable printing completely. */
fprintf (stderr, _("\n%s received.\n"), redirect_request_signal_name); fprintf (stderr, _("\n%s received.\n"), redirect_request_signal_name);
fprintf (stderr, _("%s: %s; disabling logging.\n"), fprintf (stderr, _("%s: %s; disabling logging.\n"),
logfile, strerror (errno)); logfile, strerror (errno));
inhibit_logging = true; inhibit_logging = true;
} }
save_context_p = false; save_context_p = false;

View File

@ -159,12 +159,12 @@ fake_fork_child (void)
/* See utils:fork_to_background for explanation. */ /* See utils:fork_to_background for explanation. */
FILE *new_log_fp = unique_create (DEFAULT_LOGFILE, false, &opt.lfilename); FILE *new_log_fp = unique_create (DEFAULT_LOGFILE, false, &opt.lfilename);
if (new_log_fp) if (new_log_fp)
{ {
info->logfile_changed = true; info->logfile_changed = true;
strncpy (info->lfilename, opt.lfilename, sizeof (info->lfilename)); strncpy (info->lfilename, opt.lfilename, sizeof (info->lfilename));
info->lfilename[sizeof (info->lfilename) - 1] = '\0'; info->lfilename[sizeof (info->lfilename) - 1] = '\0';
fclose (new_log_fp); fclose (new_log_fp);
} }
} }
UnmapViewOfFile (info); UnmapViewOfFile (info);
@ -457,14 +457,14 @@ ws_startup (void)
if (err != 0) if (err != 0)
{ {
fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"), fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
exec_name); exec_name);
exit (1); exit (1);
} }
if (data.wVersion < requested) if (data.wVersion < requested)
{ {
fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"), fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
exec_name); exec_name);
WSACleanup (); WSACleanup ();
exit (1); exit (1);
} }
@ -542,7 +542,7 @@ run_with_timeout (double seconds, void (*fun) (void *), void *arg)
thread_arg.arg = arg; thread_arg.arg = arg;
thread_arg.ws_error = WSAGetLastError (); thread_arg.ws_error = WSAGetLastError ();
thread_hnd = CreateThread (NULL, THREAD_STACK_SIZE, thread_helper, thread_hnd = CreateThread (NULL, THREAD_STACK_SIZE, thread_helper,
&thread_arg, 0, &thread_id); &thread_arg, 0, &thread_id);
if (!thread_hnd) if (!thread_hnd)
{ {
DEBUGP (("CreateThread() failed; [0x%x]\n", GetLastError ())); DEBUGP (("CreateThread() failed; [0x%x]\n", GetLastError ()));
@ -553,7 +553,7 @@ run_with_timeout (double seconds, void (*fun) (void *), void *arg)
== WAIT_OBJECT_0) == WAIT_OBJECT_0)
{ {
/* Propagate error state (which is per-thread) to this thread, /* Propagate error state (which is per-thread) to this thread,
so the caller can inspect it. */ so the caller can inspect it. */
WSASetLastError (thread_arg.ws_error); WSASetLastError (thread_arg.ws_error);
DEBUGP (("Winsock error: %d\n", WSAGetLastError ())); DEBUGP (("Winsock error: %d\n", WSAGetLastError ()));
rc = false; rc = false;
@ -564,7 +564,7 @@ run_with_timeout (double seconds, void (*fun) (void *), void *arg)
rc = true; rc = true;
} }
CloseHandle (thread_hnd); /* Clear-up after TerminateThread(). */ CloseHandle (thread_hnd); /* Clear-up after TerminateThread(). */
thread_hnd = NULL; thread_hnd = NULL;
return rc; return rc;
} }
@ -578,11 +578,11 @@ run_with_timeout (double seconds, void (*fun) (void *), void *arg)
/* Define a macro that creates a function definition that wraps FUN into /* Define a macro that creates a function definition that wraps FUN into
a function that sets errno the way the rest of the code expects. */ a function that sets errno the way the rest of the code expects. */
#define WRAP(fun, decl, call) int wrapped_##fun decl { \ #define WRAP(fun, decl, call) int wrapped_##fun decl { \
int retval = fun call; \ int retval = fun call; \
if (retval < 0) \ if (retval < 0) \
errno = WSAGetLastError (); \ errno = WSAGetLastError (); \
return retval; \ return retval; \
} }
WRAP (socket, (int domain, int type, int protocol), (domain, type, protocol)) WRAP (socket, (int domain, int type, int protocol), (domain, type, protocol))

View File

@ -57,7 +57,7 @@ static acc_t *parse_netrc (const char *);
You will typically turn it off for HTTP. */ You will typically turn it off for HTTP. */
void void
search_netrc (const char *host, const char **acc, const char **passwd, search_netrc (const char *host, const char **acc, const char **passwd,
int slack_default) int slack_default)
{ {
acc_t *l; acc_t *l;
static int processed_netrc; static int processed_netrc;
@ -72,17 +72,17 @@ search_netrc (const char *host, const char **acc, const char **passwd,
netrc_list = NULL; netrc_list = NULL;
processed_netrc = 1; processed_netrc = 1;
if (home) if (home)
{ {
int err; int err;
struct_stat buf; struct_stat buf;
char *path = (char *)alloca (strlen (home) + 1 char *path = (char *)alloca (strlen (home) + 1
+ strlen (NETRC_FILE_NAME) + 1); + strlen (NETRC_FILE_NAME) + 1);
sprintf (path, "%s/%s", home, NETRC_FILE_NAME); sprintf (path, "%s/%s", home, NETRC_FILE_NAME);
xfree (home); xfree (home);
err = stat (path, &buf); err = stat (path, &buf);
if (err == 0) if (err == 0)
netrc_list = parse_netrc (path); netrc_list = parse_netrc (path);
} }
} }
/* If nothing to do... */ /* If nothing to do... */
if (!netrc_list) if (!netrc_list)
@ -94,44 +94,44 @@ search_netrc (const char *host, const char **acc, const char **passwd,
for (l = netrc_list; l; l = l->next) for (l = netrc_list; l; l = l->next)
{ {
if (!l->host) if (!l->host)
continue; continue;
else if (!strcasecmp (l->host, host)) else if (!strcasecmp (l->host, host))
break; break;
} }
if (l) if (l)
{ {
if (*acc) if (*acc)
{ {
/* Looking for password in .netrc. */ /* Looking for password in .netrc. */
if (!strcmp (l->acc, *acc)) if (!strcmp (l->acc, *acc))
*passwd = l->passwd; /* usernames match; password OK */ *passwd = l->passwd; /* usernames match; password OK */
else else
*passwd = NULL; /* usernames don't match */ *passwd = NULL; /* usernames don't match */
} }
else /* NOT *acc */ else /* NOT *acc */
{ {
/* If password was given, use it. The account is l->acc. */ /* If password was given, use it. The account is l->acc. */
*acc = l->acc; *acc = l->acc;
if (l->passwd) if (l->passwd)
*passwd = l->passwd; *passwd = l->passwd;
} }
return; return;
} }
else else
{ {
if (!slack_default) if (!slack_default)
return; return;
if (*acc) if (*acc)
return; return;
/* Try looking for the default account. */ /* Try looking for the default account. */
for (l = netrc_list; l; l = l->next) for (l = netrc_list; l; l = l->next)
if (!l->host) if (!l->host)
break; break;
if (!l) if (!l)
return; return;
*acc = l->acc; *acc = l->acc;
if (!*passwd) if (!*passwd)
*passwd = l->passwd; *passwd = l->passwd;
return; return;
} }
} }
@ -170,7 +170,7 @@ read_whole_line (FILE *fp)
length += strlen (line + length); length += strlen (line + length);
assert (length > 0); assert (length > 0);
if (line[length - 1] == '\n') if (line[length - 1] == '\n')
break; break;
/* fgets() guarantees to read the whole line, or to use up the /* fgets() guarantees to read the whole line, or to use up the
space we've given it. We can double the buffer space we've given it. We can double the buffer
unconditionally. */ unconditionally. */
@ -212,11 +212,11 @@ maybe_add_to_list (acc_t **newentry, acc_t **list)
else else
{ {
if (a) if (a)
{ {
/* Add the current machine into our list. */ /* Add the current machine into our list. */
a->next = l; a->next = l;
l = a; l = a;
} }
/* Allocate a new acc_t structure. */ /* Allocate a new acc_t structure. */
a = xmalloc (sizeof (acc_t)); a = xmalloc (sizeof (acc_t));
@ -265,7 +265,7 @@ parse_netrc (const char *path)
if (!fp) if (!fp)
{ {
fprintf (stderr, _("%s: Cannot read %s (%s).\n"), exec_name, fprintf (stderr, _("%s: Cannot read %s (%s).\n"), exec_name,
path, strerror (errno)); path, strerror (errno));
return retval; return retval;
} }
@ -284,129 +284,129 @@ parse_netrc (const char *path)
/* Skip leading whitespace. */ /* Skip leading whitespace. */
while (*p && ISSPACE (*p)) while (*p && ISSPACE (*p))
p ++; p ++;
/* If the line is empty, then end any macro definition. */ /* If the line is empty, then end any macro definition. */
if (last_token == tok_macdef && !*p) if (last_token == tok_macdef && !*p)
/* End of macro if the line is empty. */ /* End of macro if the line is empty. */
last_token = tok_nothing; last_token = tok_nothing;
/* If we are defining macros, then skip parsing the line. */ /* If we are defining macros, then skip parsing the line. */
while (*p && last_token != tok_macdef) while (*p && last_token != tok_macdef)
{ {
/* Skip any whitespace. */ /* Skip any whitespace. */
while (*p && ISSPACE (*p)) while (*p && ISSPACE (*p))
p ++; p ++;
/* Discard end-of-line comments; also, stop processing if /* Discard end-of-line comments; also, stop processing if
the above `while' merely skipped trailing whitespace. */ the above `while' merely skipped trailing whitespace. */
if (*p == '#' || !*p) if (*p == '#' || !*p)
break; break;
/* If the token starts with quotation mark, note this fact, /* If the token starts with quotation mark, note this fact,
and squash the quotation character */ and squash the quotation character */
if (*p == '"'){ if (*p == '"'){
quote = 1; quote = 1;
shift_left (p); shift_left (p);
} }
tok = p; tok = p;
/* Find the end of the token, handling quotes and escapes. */ /* Find the end of the token, handling quotes and escapes. */
while (*p && (quote ? *p != '"' : !ISSPACE (*p))){ while (*p && (quote ? *p != '"' : !ISSPACE (*p))){
if (*p == '\\') if (*p == '\\')
shift_left (p); shift_left (p);
p ++; p ++;
} }
/* If field was quoted, squash the trailing quotation mark /* If field was quoted, squash the trailing quotation mark
and reset quote flag. */ and reset quote flag. */
if (quote) if (quote)
{ {
shift_left (p); shift_left (p);
quote = 0; quote = 0;
} }
/* Null-terminate the token, if it isn't already. */ /* Null-terminate the token, if it isn't already. */
if (*p) if (*p)
*p ++ = '\0'; *p ++ = '\0';
switch (last_token) switch (last_token)
{ {
case tok_login: case tok_login:
if (current) if (current)
current->acc = xstrdup (tok); current->acc = xstrdup (tok);
else else
premature_token = "login"; premature_token = "login";
break; break;
case tok_machine: case tok_machine:
/* Start a new machine entry. */ /* Start a new machine entry. */
maybe_add_to_list (&current, &retval); maybe_add_to_list (&current, &retval);
current->host = xstrdup (tok); current->host = xstrdup (tok);
break; break;
case tok_password: case tok_password:
if (current) if (current)
current->passwd = xstrdup (tok); current->passwd = xstrdup (tok);
else else
premature_token = "password"; premature_token = "password";
break; break;
/* We handle most of tok_macdef above. */ /* We handle most of tok_macdef above. */
case tok_macdef: case tok_macdef:
if (!current) if (!current)
premature_token = "macdef"; premature_token = "macdef";
break; break;
/* We don't handle the account keyword at all. */ /* We don't handle the account keyword at all. */
case tok_account: case tok_account:
if (!current) if (!current)
premature_token = "account"; premature_token = "account";
break; break;
/* We handle tok_nothing below this switch. */ /* We handle tok_nothing below this switch. */
case tok_nothing: case tok_nothing:
break; break;
} }
if (premature_token) if (premature_token)
{ {
fprintf (stderr, _("\ fprintf (stderr, _("\
%s: %s:%d: warning: \"%s\" token appears before any machine name\n"), %s: %s:%d: warning: \"%s\" token appears before any machine name\n"),
exec_name, path, ln, premature_token); exec_name, path, ln, premature_token);
premature_token = NULL; premature_token = NULL;
} }
if (last_token != tok_nothing) if (last_token != tok_nothing)
/* We got a value, so reset the token state. */ /* We got a value, so reset the token state. */
last_token = tok_nothing; last_token = tok_nothing;
else else
{ {
/* Fetch the next token. */ /* Fetch the next token. */
if (!strcmp (tok, "account")) if (!strcmp (tok, "account"))
last_token = tok_account; last_token = tok_account;
else if (!strcmp (tok, "default")) else if (!strcmp (tok, "default"))
{ {
maybe_add_to_list (&current, &retval); maybe_add_to_list (&current, &retval);
} }
else if (!strcmp (tok, "login")) else if (!strcmp (tok, "login"))
last_token = tok_login; last_token = tok_login;
else if (!strcmp (tok, "macdef")) else if (!strcmp (tok, "macdef"))
last_token = tok_macdef; last_token = tok_macdef;
else if (!strcmp (tok, "machine")) else if (!strcmp (tok, "machine"))
last_token = tok_machine; last_token = tok_machine;
else if (!strcmp (tok, "password")) else if (!strcmp (tok, "password"))
last_token = tok_password; last_token = tok_password;
else else
fprintf (stderr, _("%s: %s:%d: unknown token \"%s\"\n"), fprintf (stderr, _("%s: %s:%d: unknown token \"%s\"\n"),
exec_name, path, ln, tok); exec_name, path, ln, tok);
} }
} }
xfree (line); xfree (line);
} }
@ -478,7 +478,7 @@ main (int argc, char **argv)
if (stat (file, &sb)) if (stat (file, &sb))
{ {
fprintf (stderr, _("%s: cannot stat %s: %s\n"), argv[0], file, fprintf (stderr, _("%s: cannot stat %s: %s\n"), argv[0], file,
strerror (errno)); strerror (errno));
exit (1); exit (1);
} }
@ -488,37 +488,37 @@ main (int argc, char **argv)
{ {
/* Skip if we have a target and this isn't it. */ /* Skip if we have a target and this isn't it. */
if (target && a->host && strcmp (target, a->host)) if (target && a->host && strcmp (target, a->host))
{ {
a = a->next; a = a->next;
continue; continue;
} }
if (!target) if (!target)
{ {
/* Print the host name if we have no target. */ /* Print the host name if we have no target. */
if (a->host) if (a->host)
fputs (a->host, stdout); fputs (a->host, stdout);
else else
fputs ("DEFAULT", stdout); fputs ("DEFAULT", stdout);
fputc (' ', stdout); fputc (' ', stdout);
} }
/* Print the account name. */ /* Print the account name. */
fputs (a->acc, stdout); fputs (a->acc, stdout);
if (a->passwd) if (a->passwd)
{ {
/* Print the password, if there is any. */ /* Print the password, if there is any. */
fputc (' ', stdout); fputc (' ', stdout);
fputs (a->passwd, stdout); fputs (a->passwd, stdout);
} }
fputc ('\n', stdout); fputc ('\n', stdout);
/* Exit if we found the target. */ /* Exit if we found the target. */
if (target) if (target)
exit (0); exit (0);
a = a->next; a = a->next;
} }

View File

@ -113,8 +113,8 @@ init_prng (void)
while (RAND_status () == 0 && maxrand-- > 0) while (RAND_status () == 0 && maxrand-- > 0)
{ {
unsigned char rnd = random_number (256); unsigned char rnd = random_number (256);
RAND_seed (&rnd, sizeof (rnd)); RAND_seed (&rnd, sizeof (rnd));
} }
} }
#endif #endif
@ -169,7 +169,7 @@ ssl_init ()
if (RAND_status () != 1) if (RAND_status () != 1)
{ {
logprintf (LOG_NOTQUIET, logprintf (LOG_NOTQUIET,
_("Could not seed PRNG; consider using --random-file.\n")); _("Could not seed PRNG; consider using --random-file.\n"));
goto error; goto error;
} }
@ -211,13 +211,13 @@ ssl_init ()
if (opt.cert_file) if (opt.cert_file)
if (SSL_CTX_use_certificate_file (ssl_ctx, opt.cert_file, if (SSL_CTX_use_certificate_file (ssl_ctx, opt.cert_file,
key_type_to_ssl_type (opt.cert_type)) key_type_to_ssl_type (opt.cert_type))
!= 1) != 1)
goto error; goto error;
if (opt.private_key) if (opt.private_key)
if (SSL_CTX_use_PrivateKey_file (ssl_ctx, opt.private_key, if (SSL_CTX_use_PrivateKey_file (ssl_ctx, opt.private_key,
key_type_to_ssl_type (opt.private_key_type)) key_type_to_ssl_type (opt.private_key_type))
!= 1) != 1)
goto error; goto error;
/* Since fd_write unconditionally assumes partial writes (and /* Since fd_write unconditionally assumes partial writes (and
@ -238,8 +238,8 @@ ssl_init ()
} }
struct openssl_transport_context { struct openssl_transport_context {
SSL *conn; /* SSL connection handle */ SSL *conn; /* SSL connection handle */
char *last_error; /* last error printed with openssl_errstr */ char *last_error; /* last error printed with openssl_errstr */
}; };
static int static int
@ -251,8 +251,8 @@ openssl_read (int fd, char *buf, int bufsize, void *arg)
do do
ret = SSL_read (conn, buf, bufsize); ret = SSL_read (conn, buf, bufsize);
while (ret == -1 while (ret == -1
&& SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
&& errno == EINTR); && errno == EINTR);
return ret; return ret;
} }
@ -265,8 +265,8 @@ openssl_write (int fd, char *buf, int bufsize, void *arg)
do do
ret = SSL_write (conn, buf, bufsize); ret = SSL_write (conn, buf, bufsize);
while (ret == -1 while (ret == -1
&& SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
&& errno == EINTR); && errno == EINTR);
return ret; return ret;
} }
@ -291,8 +291,8 @@ openssl_peek (int fd, char *buf, int bufsize, void *arg)
do do
ret = SSL_peek (conn, buf, bufsize); ret = SSL_peek (conn, buf, bufsize);
while (ret == -1 while (ret == -1
&& SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
&& errno == EINTR); && errno == EINTR);
return ret; return ret;
} }
@ -323,7 +323,7 @@ openssl_errstr (int fd, void *arg)
int len = strlen (str); int len = strlen (str);
/* Allocate space for the existing message, plus two more chars /* Allocate space for the existing message, plus two more chars
for the "; " separator and one for the terminating \0. */ for the "; " separator and one for the terminating \0. */
errmsg = xrealloc (errmsg, msglen + len + 2 + 1); errmsg = xrealloc (errmsg, msglen + len + 2 + 1);
memcpy (errmsg + msglen, str, len); memcpy (errmsg + msglen, str, len);
msglen += len; msglen += len;
@ -331,7 +331,7 @@ openssl_errstr (int fd, void *arg)
/* Get next error and bail out if there are no more. */ /* Get next error and bail out if there are no more. */
errcode = ERR_get_error (); errcode = ERR_get_error ();
if (errcode == 0) if (errcode == 0)
break; break;
errmsg[msglen++] = ';'; errmsg[msglen++] = ';';
errmsg[msglen++] = ' '; errmsg[msglen++] = ' ';
@ -406,7 +406,7 @@ ssl_connect (int fd)
functions are used for reading, writing, and polling. */ functions are used for reading, writing, and polling. */
fd_register_transport (fd, &openssl_transport, ctx); fd_register_transport (fd, &openssl_transport, ctx);
DEBUGP (("Handshake successful; connected socket %d to SSL handle 0x%0*lx\n", DEBUGP (("Handshake successful; connected socket %d to SSL handle 0x%0*lx\n",
fd, PTR_FORMAT (conn))); fd, PTR_FORMAT (conn)));
return true; return true;
error: error:
@ -417,7 +417,7 @@ ssl_connect (int fd)
return false; return false;
} }
#define ASTERISK_EXCLUDES_DOT /* mandated by rfc2818 */ #define ASTERISK_EXCLUDES_DOT /* mandated by rfc2818 */
/* Return true is STRING (case-insensitively) matches PATTERN, false /* Return true is STRING (case-insensitively) matches PATTERN, false
otherwise. The recognized wildcard character is "*", which matches otherwise. The recognized wildcard character is "*", which matches
@ -441,21 +441,21 @@ pattern_match (const char *pattern, const char *string)
for (; (c = TOLOWER (*p++)) != '\0'; n++) for (; (c = TOLOWER (*p++)) != '\0'; n++)
if (c == '*') if (c == '*')
{ {
for (c = TOLOWER (*p); c == '*'; c = TOLOWER (*++p)) for (c = TOLOWER (*p); c == '*'; c = TOLOWER (*++p))
; ;
for (; *n != '\0'; n++) for (; *n != '\0'; n++)
if (TOLOWER (*n) == c && pattern_match (p, n)) if (TOLOWER (*n) == c && pattern_match (p, n))
return true; return true;
#ifdef ASTERISK_EXCLUDES_DOT #ifdef ASTERISK_EXCLUDES_DOT
else if (*n == '.') else if (*n == '.')
return false; return false;
#endif #endif
return c == '\0'; return c == '\0';
} }
else else
{ {
if (c != TOLOWER (*n)) if (c != TOLOWER (*n))
return false; return false;
} }
return *n == '\0'; return *n == '\0';
} }
@ -494,9 +494,9 @@ ssl_check_certificate (int fd, const char *host)
if (!cert) if (!cert)
{ {
logprintf (LOG_NOTQUIET, _("%s: No certificate presented by %s.\n"), logprintf (LOG_NOTQUIET, _("%s: No certificate presented by %s.\n"),
severity, escnonprint (host)); severity, escnonprint (host));
success = false; success = false;
goto no_cert; /* must bail out since CERT is NULL */ goto no_cert; /* must bail out since CERT is NULL */
} }
IF_DEBUG IF_DEBUG
@ -504,7 +504,7 @@ ssl_check_certificate (int fd, const char *host)
char *subject = X509_NAME_oneline (X509_get_subject_name (cert), 0, 0); char *subject = X509_NAME_oneline (X509_get_subject_name (cert), 0, 0);
char *issuer = X509_NAME_oneline (X509_get_issuer_name (cert), 0, 0); char *issuer = X509_NAME_oneline (X509_get_issuer_name (cert), 0, 0);
DEBUGP (("certificate:\n subject: %s\n issuer: %s\n", DEBUGP (("certificate:\n subject: %s\n issuer: %s\n",
escnonprint (subject), escnonprint (issuer))); escnonprint (subject), escnonprint (issuer)));
OPENSSL_free (subject); OPENSSL_free (subject);
OPENSSL_free (issuer); OPENSSL_free (issuer);
} }
@ -514,35 +514,35 @@ ssl_check_certificate (int fd, const char *host)
{ {
char *issuer = X509_NAME_oneline (X509_get_issuer_name (cert), 0, 0); char *issuer = X509_NAME_oneline (X509_get_issuer_name (cert), 0, 0);
logprintf (LOG_NOTQUIET, logprintf (LOG_NOTQUIET,
_("%s: cannot verify %s's certificate, issued by `%s':\n"), _("%s: cannot verify %s's certificate, issued by `%s':\n"),
severity, escnonprint (host), escnonprint (issuer)); severity, escnonprint (host), escnonprint (issuer));
/* Try to print more user-friendly (and translated) messages for /* Try to print more user-friendly (and translated) messages for
the frequent verification errors. */ the frequent verification errors. */
switch (vresult) switch (vresult)
{ {
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
logprintf (LOG_NOTQUIET, logprintf (LOG_NOTQUIET,
_(" Unable to locally verify the issuer's authority.\n")); _(" Unable to locally verify the issuer's authority.\n"));
break; break;
case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
logprintf (LOG_NOTQUIET, _(" Self-signed certificate encountered.\n")); logprintf (LOG_NOTQUIET, _(" Self-signed certificate encountered.\n"));
break; break;
case X509_V_ERR_CERT_NOT_YET_VALID: case X509_V_ERR_CERT_NOT_YET_VALID:
logprintf (LOG_NOTQUIET, _(" Issued certificate not yet valid.\n")); logprintf (LOG_NOTQUIET, _(" Issued certificate not yet valid.\n"));
break; break;
case X509_V_ERR_CERT_HAS_EXPIRED: case X509_V_ERR_CERT_HAS_EXPIRED:
logprintf (LOG_NOTQUIET, _(" Issued certificate has expired.\n")); logprintf (LOG_NOTQUIET, _(" Issued certificate has expired.\n"));
break; break;
default: default:
/* For the less frequent error strings, simply provide the /* For the less frequent error strings, simply provide the
OpenSSL error message. */ OpenSSL error message. */
logprintf (LOG_NOTQUIET, " %s\n", logprintf (LOG_NOTQUIET, " %s\n",
X509_verify_cert_error_string (vresult)); X509_verify_cert_error_string (vresult));
} }
success = false; success = false;
/* Fall through, so that the user is warned about *all* issues /* Fall through, so that the user is warned about *all* issues
with the cert (important with --no-check-certificate.) */ with the cert (important with --no-check-certificate.) */
} }
/* Check that HOST matches the common name in the certificate. /* Check that HOST matches the common name in the certificate.
@ -561,25 +561,25 @@ ssl_check_certificate (int fd, const char *host)
common_name[0] = '\0'; common_name[0] = '\0';
X509_NAME_get_text_by_NID (X509_get_subject_name (cert), X509_NAME_get_text_by_NID (X509_get_subject_name (cert),
NID_commonName, common_name, sizeof (common_name)); NID_commonName, common_name, sizeof (common_name));
if (!pattern_match (common_name, host)) if (!pattern_match (common_name, host))
{ {
logprintf (LOG_NOTQUIET, _("\ logprintf (LOG_NOTQUIET, _("\
%s: certificate common name `%s' doesn't match requested host name `%s'.\n"), %s: certificate common name `%s' doesn't match requested host name `%s'.\n"),
severity, escnonprint (common_name), escnonprint (host)); severity, escnonprint (common_name), escnonprint (host));
success = false; success = false;
} }
if (success) if (success)
DEBUGP (("X509 certificate successfully verified and matches host %s\n", DEBUGP (("X509 certificate successfully verified and matches host %s\n",
escnonprint (host))); escnonprint (host)));
X509_free (cert); X509_free (cert);
no_cert: no_cert:
if (opt.check_cert && !success) if (opt.check_cert && !success)
logprintf (LOG_NOTQUIET, _("\ logprintf (LOG_NOTQUIET, _("\
To connect to %s insecurely, use `--no-check-certificate'.\n"), To connect to %s insecurely, use `--no-check-certificate'.\n"),
escnonprint (host)); escnonprint (host));
/* Allow --no-check-cert to disable certificate checking. */ /* Allow --no-check-cert to disable certificate checking. */
return opt.check_cert ? success : true; return opt.check_cert ? success : true;

View File

@ -118,18 +118,18 @@ set_progress_implementation (const char *name)
for (i = 0; i < countof (implementations); i++, pi++) for (i = 0; i < countof (implementations); i++, pi++)
if (!strncmp (pi->name, name, namelen)) if (!strncmp (pi->name, name, namelen))
{ {
current_impl = pi; current_impl = pi;
current_impl_locked = 0; current_impl_locked = 0;
if (colon) if (colon)
/* We call pi->set_params even if colon is NULL because we /* We call pi->set_params even if colon is NULL because we
want to give the implementation a chance to set up some want to give the implementation a chance to set up some
things it needs to run. */ things it needs to run. */
++colon; ++colon;
if (pi->set_params) if (pi->set_params)
pi->set_params (colon); pi->set_params (colon);
return; return;
} }
abort (); abort ();
} }
@ -155,7 +155,7 @@ progress_create (wgint initial, wgint total)
if (output_redirected) if (output_redirected)
{ {
if (!current_impl_locked) if (!current_impl_locked)
set_progress_implementation (FALLBACK_PROGRESS_IMPLEMENTATION); set_progress_implementation (FALLBACK_PROGRESS_IMPLEMENTATION);
output_redirected = 0; output_redirected = 0;
} }
@ -194,16 +194,16 @@ progress_finish (void *progress, double dltime)
/* Dot-printing. */ /* Dot-printing. */
struct dot_progress { struct dot_progress {
wgint initial_length; /* how many bytes have been downloaded wgint initial_length; /* how many bytes have been downloaded
previously. */ previously. */
wgint total_length; /* expected total byte count when the wgint total_length; /* expected total byte count when the
download finishes */ download finishes */
int accumulated; /* number of bytes accumulated after int accumulated; /* number of bytes accumulated after
the last printed dot */ the last printed dot */
int rows; /* number of rows printed so far */ int rows; /* number of rows printed so far */
int dots; /* number of dots printed in this row */ int dots; /* number of dots printed in this row */
double last_timer_value; double last_timer_value;
}; };
@ -226,29 +226,29 @@ dot_create (wgint initial, wgint total)
wgint skipped = dp->initial_length - remainder; wgint skipped = dp->initial_length - remainder;
if (skipped) if (skipped)
{ {
wgint skipped_k = skipped / 1024; /* skipped amount in K */ wgint skipped_k = skipped / 1024; /* skipped amount in K */
int skipped_k_len = numdigit (skipped_k); int skipped_k_len = numdigit (skipped_k);
if (skipped_k_len < 6) if (skipped_k_len < 6)
skipped_k_len = 6; skipped_k_len = 6;
/* Align the [ skipping ... ] line with the dots. To do /* Align the [ skipping ... ] line with the dots. To do
that, insert the number of spaces equal to the number of that, insert the number of spaces equal to the number of
digits in the skipped amount in K. */ digits in the skipped amount in K. */
logprintf (LOG_VERBOSE, _("\n%*s[ skipping %sK ]"), logprintf (LOG_VERBOSE, _("\n%*s[ skipping %sK ]"),
2 + skipped_k_len, "", 2 + skipped_k_len, "",
number_to_static_string (skipped_k)); number_to_static_string (skipped_k));
} }
logprintf (LOG_VERBOSE, "\n%6sK", logprintf (LOG_VERBOSE, "\n%6sK",
number_to_static_string (skipped / 1024)); number_to_static_string (skipped / 1024));
for (; remainder >= dot_bytes; remainder -= dot_bytes) for (; remainder >= dot_bytes; remainder -= dot_bytes)
{ {
if (dp->dots % opt.dot_spacing == 0) if (dp->dots % opt.dot_spacing == 0)
logputs (LOG_VERBOSE, " "); logputs (LOG_VERBOSE, " ");
logputs (LOG_VERBOSE, ","); logputs (LOG_VERBOSE, ",");
++dp->dots; ++dp->dots;
} }
assert (dp->dots < opt.dots_in_line); assert (dp->dots < opt.dots_in_line);
dp->accumulated = remainder; dp->accumulated = remainder;
@ -284,8 +284,8 @@ print_row_stats (struct dot_progress *dp, double dltime, bool last)
if (dp->total_length) if (dp->total_length)
{ {
/* Round to floor value to provide gauge how much data *has* /* Round to floor value to provide gauge how much data *has*
been retrieved. 12.8% will round to 12% because the 13% mark been retrieved. 12.8% will round to 12% because the 13% mark
has not yet been reached. 100% is only shown when done. */ has not yet been reached. 100% is only shown when done. */
int percentage = 100.0 * bytes_displayed / dp->total_length; int percentage = 100.0 * bytes_displayed / dp->total_length;
logprintf (LOG_VERBOSE, "%3d%%", percentage); logprintf (LOG_VERBOSE, "%3d%%", percentage);
} }
@ -305,34 +305,34 @@ print_row_stats (struct dot_progress *dp, double dltime, bool last)
bytes_this_row -= dp->initial_length % ROW_BYTES; bytes_this_row -= dp->initial_length % ROW_BYTES;
rate = calc_rate (bytes_this_row, dltime - dp->last_timer_value, &units); rate = calc_rate (bytes_this_row, dltime - dp->last_timer_value, &units);
logprintf (LOG_VERBOSE, " %4.*f%c", logprintf (LOG_VERBOSE, " %4.*f%c",
rate >= 99.95 ? 0 : rate >= 9.995 ? 1 : 2, rate >= 99.95 ? 0 : rate >= 9.995 ? 1 : 2,
rate, names[units]); rate, names[units]);
dp->last_timer_value = dltime; dp->last_timer_value = dltime;
} }
if (!last) if (!last)
{ {
/* Display ETA based on average speed. Inspired by Vladi /* Display ETA based on average speed. Inspired by Vladi
Belperchinov-Shabanski's "wget-new-percentage" patch. */ Belperchinov-Shabanski's "wget-new-percentage" patch. */
if (dp->total_length) if (dp->total_length)
{ {
wgint bytes_remaining = dp->total_length - bytes_displayed; wgint bytes_remaining = dp->total_length - bytes_displayed;
/* The quantity downloaded in this download run. */ /* The quantity downloaded in this download run. */
wgint bytes_sofar = bytes_displayed - dp->initial_length; wgint bytes_sofar = bytes_displayed - dp->initial_length;
double eta = dltime * bytes_remaining / bytes_sofar; double eta = dltime * bytes_remaining / bytes_sofar;
if (eta < INT_MAX - 1) if (eta < INT_MAX - 1)
logprintf (LOG_VERBOSE, " %s", logprintf (LOG_VERBOSE, " %s",
eta_to_human_short ((int) (eta + 0.5), true)); eta_to_human_short ((int) (eta + 0.5), true));
} }
} }
else else
{ {
/* When done, print the total download time */ /* When done, print the total download time */
if (dltime >= 10) if (dltime >= 10)
logprintf (LOG_VERBOSE, "=%s", logprintf (LOG_VERBOSE, "=%s",
eta_to_human_short ((int) (dltime + 0.5), true)); eta_to_human_short ((int) (dltime + 0.5), true));
else else
logprintf (LOG_VERBOSE, "=%ss", print_decimal (dltime)); logprintf (LOG_VERBOSE, "=%ss", print_decimal (dltime));
} }
} }
@ -351,21 +351,21 @@ dot_update (void *progress, wgint howmuch, double dltime)
for (; dp->accumulated >= dot_bytes; dp->accumulated -= dot_bytes) for (; dp->accumulated >= dot_bytes; dp->accumulated -= dot_bytes)
{ {
if (dp->dots == 0) if (dp->dots == 0)
logprintf (LOG_VERBOSE, "\n%6sK", logprintf (LOG_VERBOSE, "\n%6sK",
number_to_static_string (dp->rows * ROW_BYTES / 1024)); number_to_static_string (dp->rows * ROW_BYTES / 1024));
if (dp->dots % opt.dot_spacing == 0) if (dp->dots % opt.dot_spacing == 0)
logputs (LOG_VERBOSE, " "); logputs (LOG_VERBOSE, " ");
logputs (LOG_VERBOSE, "."); logputs (LOG_VERBOSE, ".");
++dp->dots; ++dp->dots;
if (dp->dots >= opt.dots_in_line) if (dp->dots >= opt.dots_in_line)
{ {
++dp->rows; ++dp->rows;
dp->dots = 0; dp->dots = 0;
print_row_stats (dp, dltime, false); print_row_stats (dp, dltime, false);
} }
} }
log_set_flush (true); log_set_flush (true);
@ -384,11 +384,11 @@ dot_finish (void *progress, double dltime)
if (dp->dots == 0) if (dp->dots == 0)
logprintf (LOG_VERBOSE, "\n%6sK", logprintf (LOG_VERBOSE, "\n%6sK",
number_to_static_string (dp->rows * ROW_BYTES / 1024)); number_to_static_string (dp->rows * ROW_BYTES / 1024));
for (i = dp->dots; i < opt.dots_in_line; i++) for (i = dp->dots; i < opt.dots_in_line; i++)
{ {
if (i % opt.dot_spacing == 0) if (i % opt.dot_spacing == 0)
logputs (LOG_VERBOSE, " "); logputs (LOG_VERBOSE, " ");
logputs (LOG_VERBOSE, " "); logputs (LOG_VERBOSE, " ");
} }
@ -417,7 +417,7 @@ dot_set_params (const char *params)
if (!strcasecmp (params, "default")) if (!strcasecmp (params, "default"))
{ {
/* Default style: 1K dots, 10 dots in a cluster, 50 dots in a /* Default style: 1K dots, 10 dots in a cluster, 50 dots in a
line. */ line. */
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;
@ -425,7 +425,7 @@ dot_set_params (const char *params)
else if (!strcasecmp (params, "binary")) else if (!strcasecmp (params, "binary"))
{ {
/* "Binary" retrieval: 8K dots, 16 dots in a cluster, 48 dots /* "Binary" retrieval: 8K dots, 16 dots in a cluster, 48 dots
(384K) in a line. */ (384K) in a line. */
opt.dot_bytes = 8192; opt.dot_bytes = 8192;
opt.dot_spacing = 16; opt.dot_spacing = 16;
opt.dots_in_line = 48; opt.dots_in_line = 48;
@ -433,7 +433,7 @@ dot_set_params (const char *params)
else if (!strcasecmp (params, "mega")) else if (!strcasecmp (params, "mega"))
{ {
/* "Mega" retrieval, for retrieving very long files; each dot is /* "Mega" retrieval, for retrieving very long files; each dot is
64K, 8 dots in a cluster, 6 clusters (3M) in a line. */ 64K, 8 dots in a cluster, 6 clusters (3M) in a line. */
opt.dot_bytes = 65536L; opt.dot_bytes = 65536L;
opt.dot_spacing = 8; opt.dot_spacing = 8;
opt.dots_in_line = 48; opt.dots_in_line = 48;
@ -441,16 +441,16 @@ dot_set_params (const char *params)
else if (!strcasecmp (params, "giga")) else if (!strcasecmp (params, "giga"))
{ {
/* "Giga" retrieval, for retrieving very very *very* long files; /* "Giga" retrieval, for retrieving very very *very* long files;
each dot is 1M, 8 dots in a cluster, 4 clusters (32M) in a each dot is 1M, 8 dots in a cluster, 4 clusters (32M) in a
line. */ line. */
opt.dot_bytes = (1L << 20); opt.dot_bytes = (1L << 20);
opt.dot_spacing = 8; opt.dot_spacing = 8;
opt.dots_in_line = 32; opt.dots_in_line = 32;
} }
else else
fprintf (stderr, fprintf (stderr,
_("Invalid dot style specification `%s'; leaving unchanged.\n"), _("Invalid dot style specification `%s'; leaving unchanged.\n"),
params); params);
} }
/* "Thermometer" (bar) progress. */ /* "Thermometer" (bar) progress. */
@ -493,27 +493,27 @@ static volatile sig_atomic_t received_sigwinch;
#define ETA_REFRESH_INTERVAL 0.99 #define ETA_REFRESH_INTERVAL 0.99
struct bar_progress { struct bar_progress {
wgint initial_length; /* how many bytes have been downloaded wgint initial_length; /* how many bytes have been downloaded
previously. */ previously. */
wgint total_length; /* expected total byte count when the wgint total_length; /* expected total byte count when the
download finishes */ download finishes */
wgint count; /* bytes downloaded so far */ wgint count; /* bytes downloaded so far */
double last_screen_update; /* time of the last screen update, double last_screen_update; /* time of the last screen update,
measured since the beginning of measured since the beginning of
download. */ download. */
int width; /* screen width we're using at the int width; /* screen width we're using at the
time the progress gauge was time the progress gauge was
created. this is different from created. this is different from
the screen_width global variable in the screen_width global variable in
that the latter can be changed by a that the latter can be changed by a
signal. */ signal. */
char *buffer; /* buffer where the bar "image" is char *buffer; /* buffer where the bar "image" is
stored. */ stored. */
int tick; /* counter used for drawing the int tick; /* counter used for drawing the
progress bar where the total size progress bar where the total size
is not known. */ is not known. */
/* The following variables (kept in a struct for namespace reasons) /* The following variables (kept in a struct for namespace reasons)
keep track of recent download speeds. See bar_update() for keep track of recent download speeds. See bar_update() for
@ -529,19 +529,19 @@ struct bar_progress {
wgint total_bytes; wgint total_bytes;
} hist; } hist;
double recent_start; /* timestamp of beginning of current double recent_start; /* timestamp of beginning of current
position. */ position. */
wgint recent_bytes; /* bytes downloaded so far. */ wgint recent_bytes; /* bytes downloaded so far. */
bool stalled; /* set when no data arrives for longer bool stalled; /* set when no data arrives for longer
than STALL_START_TIME, then reset than STALL_START_TIME, then reset
when new data arrives. */ when new data arrives. */
/* create_image() uses these to make sure that ETA information /* create_image() uses these to make sure that ETA information
doesn't flicker. */ doesn't flicker. */
double last_eta_time; /* time of the last update to download double last_eta_time; /* time of the last update to download
speed and ETA, measured since the speed and ETA, measured since the
beginning of download. */ beginning of download. */
int last_eta_value; int last_eta_value;
}; };
@ -567,9 +567,9 @@ bar_create (wgint initial, wgint total)
{ {
screen_width = determine_screen_width (); screen_width = determine_screen_width ();
if (!screen_width) if (!screen_width)
screen_width = DEFAULT_SCREEN_WIDTH; screen_width = DEFAULT_SCREEN_WIDTH;
else if (screen_width < MINIMUM_SCREEN_WIDTH) else if (screen_width < MINIMUM_SCREEN_WIDTH)
screen_width = MINIMUM_SCREEN_WIDTH; screen_width = MINIMUM_SCREEN_WIDTH;
received_sigwinch = 0; received_sigwinch = 0;
} }
@ -613,15 +613,15 @@ bar_update (void *progress, wgint howmuch, double dltime)
int old_width = screen_width; int old_width = screen_width;
screen_width = determine_screen_width (); screen_width = determine_screen_width ();
if (!screen_width) if (!screen_width)
screen_width = DEFAULT_SCREEN_WIDTH; screen_width = DEFAULT_SCREEN_WIDTH;
else if (screen_width < MINIMUM_SCREEN_WIDTH) else if (screen_width < MINIMUM_SCREEN_WIDTH)
screen_width = MINIMUM_SCREEN_WIDTH; screen_width = MINIMUM_SCREEN_WIDTH;
if (screen_width != old_width) if (screen_width != old_width)
{ {
bp->width = screen_width - 1; bp->width = screen_width - 1;
bp->buffer = xrealloc (bp->buffer, bp->width + 1); bp->buffer = xrealloc (bp->buffer, bp->width + 1);
force_screen_update = true; force_screen_update = true;
} }
received_sigwinch = 0; received_sigwinch = 0;
} }
@ -689,18 +689,18 @@ update_speed_ring (struct bar_progress *bp, wgint howmuch, double dltime)
if (howmuch == 0) if (howmuch == 0)
{ {
/* If we're not downloading anything, we might be stalling, /* If we're not downloading anything, we might be stalling,
i.e. not downloading anything for an extended period of time. i.e. not downloading anything for an extended period of time.
Since 0-reads do not enter the history ring, recent_age Since 0-reads do not enter the history ring, recent_age
effectively measures the time since last read. */ effectively measures the time since last read. */
if (recent_age >= STALL_START_TIME) if (recent_age >= STALL_START_TIME)
{ {
/* If we're stalling, reset the ring contents because it's /* If we're stalling, reset the ring contents because it's
stale and because it will make bar_update stop printing stale and because it will make bar_update stop printing
the (bogus) current bandwidth. */ the (bogus) current bandwidth. */
bp->stalled = true; bp->stalled = true;
xzero (*hist); xzero (*hist);
bp->recent_bytes = 0; bp->recent_bytes = 0;
} }
return; return;
} }
@ -711,10 +711,10 @@ update_speed_ring (struct bar_progress *bp, wgint howmuch, double dltime)
{ {
bp->stalled = false; bp->stalled = false;
/* "recent_age" includes the the entired stalled period, which /* "recent_age" includes the the entired stalled period, which
could be very long. Don't update the speed ring with that could be very long. Don't update the speed ring with that
value because the current bandwidth would start too small. value because the current bandwidth would start too small.
Start with an arbitrary (but more reasonable) time value and Start with an arbitrary (but more reasonable) time value and
let it level out. */ let it level out. */
recent_age = 1; recent_age = 1;
} }
@ -747,8 +747,8 @@ update_speed_ring (struct bar_progress *bp, wgint howmuch, double dltime)
double sumt = 0, sumb = 0; double sumt = 0, sumb = 0;
for (i = 0; i < DLSPEED_HISTORY_SIZE; i++) for (i = 0; i < DLSPEED_HISTORY_SIZE; i++)
{ {
sumt += hist->times[i]; sumt += hist->times[i];
sumb += hist->bytes[i]; sumb += hist->bytes[i];
} }
assert (sumb == hist->total_bytes); assert (sumb == hist->total_bytes);
/* We can't use assert(sumt==hist->total_time) because some /* We can't use assert(sumt==hist->total_time) because some
@ -762,9 +762,9 @@ update_speed_ring (struct bar_progress *bp, wgint howmuch, double dltime)
#endif #endif
} }
#define APPEND_LITERAL(s) do { \ #define APPEND_LITERAL(s) do { \
memcpy (p, s, sizeof (s) - 1); \ memcpy (p, s, sizeof (s) - 1); \
p += sizeof (s) - 1; \ p += sizeof (s) - 1; \
} while (0) } while (0)
/* Use move_to_end (s) to get S to point the end of the string (the /* Use move_to_end (s) to get S to point the end of the string (the
@ -818,9 +818,9 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
assert (percentage <= 100); assert (percentage <= 100);
if (percentage < 100) if (percentage < 100)
sprintf (p, "%2d%% ", percentage); sprintf (p, "%2d%% ", percentage);
else else
strcpy (p, "100%"); strcpy (p, "100%");
p += 4; p += 4;
} }
else else
@ -845,43 +845,43 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
begin = p; begin = p;
/* Print the initial portion of the download with '+' chars, the /* Print the initial portion of the download with '+' chars, the
rest with '=' and one '>'. */ rest with '=' and one '>'. */
for (i = 0; i < insz; i++) for (i = 0; i < insz; i++)
*p++ = '+'; *p++ = '+';
dlsz -= insz; dlsz -= insz;
if (dlsz > 0) if (dlsz > 0)
{ {
for (i = 0; i < dlsz - 1; i++) for (i = 0; i < dlsz - 1; i++)
*p++ = '='; *p++ = '=';
*p++ = '>'; *p++ = '>';
} }
while (p - begin < progress_size) while (p - begin < progress_size)
*p++ = ' '; *p++ = ' ';
*p++ = ']'; *p++ = ']';
} }
else if (progress_size) else if (progress_size)
{ {
/* If we can't draw a real progress bar, then at least show /* If we can't draw a real progress bar, then at least show
*something* to the user. */ *something* to the user. */
int ind = bp->tick % (progress_size * 2 - 6); int ind = bp->tick % (progress_size * 2 - 6);
int i, pos; int i, pos;
/* Make the star move in two directions. */ /* Make the star move in two directions. */
if (ind < progress_size - 2) if (ind < progress_size - 2)
pos = ind + 1; pos = ind + 1;
else else
pos = progress_size - (ind - progress_size + 5); pos = progress_size - (ind - progress_size + 5);
*p++ = '['; *p++ = '[';
for (i = 0; i < progress_size; i++) for (i = 0; i < progress_size; i++)
{ {
if (i == pos - 1) *p++ = '<'; if (i == pos - 1) *p++ = '<';
else if (i == pos ) *p++ = '='; else if (i == pos ) *p++ = '=';
else if (i == pos + 1) *p++ = '>'; else if (i == pos + 1) *p++ = '>';
else else
*p++ = ' '; *p++ = ' ';
} }
*p++ = ']'; *p++ = ']';
++bp->tick; ++bp->tick;
@ -897,12 +897,12 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
static const char *short_units[] = { "B/s", "K/s", "M/s", "G/s" }; static const char *short_units[] = { "B/s", "K/s", "M/s", "G/s" };
int units = 0; int units = 0;
/* Calculate the download speed using the history ring and /* Calculate the download speed using the history ring and
recent data that hasn't made it to the ring yet. */ recent data that hasn't made it to the ring yet. */
wgint dlquant = hist->total_bytes + bp->recent_bytes; wgint dlquant = hist->total_bytes + bp->recent_bytes;
double dltime = hist->total_time + (dl_total_time - bp->recent_start); double dltime = hist->total_time + (dl_total_time - bp->recent_start);
double dlspeed = calc_rate (dlquant, dltime, &units); double dlspeed = calc_rate (dlquant, dltime, &units);
sprintf (p, " %4.*f%s", dlspeed >= 99.95 ? 0 : dlspeed >= 9.995 ? 1 : 2, sprintf (p, " %4.*f%s", dlspeed >= 99.95 ? 0 : dlspeed >= 9.995 ? 1 : 2,
dlspeed, short_units[units]); dlspeed, short_units[units]);
move_to_end (p); move_to_end (p);
} }
else else
@ -911,59 +911,59 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
if (!done) if (!done)
{ {
/* " eta ..m ..s"; wait for three seconds before displaying the ETA. /* " eta ..m ..s"; wait for three seconds before displaying the ETA.
That's because the ETA value needs a while to become That's because the ETA value needs a while to become
reliable. */ reliable. */
if (bp->total_length > 0 && bp->count > 0 && dl_total_time > 3) if (bp->total_length > 0 && bp->count > 0 && dl_total_time > 3)
{ {
int eta; int eta;
/* Don't change the value of ETA more than approximately once /* Don't change the value of ETA more than approximately once
per second; doing so would cause flashing without providing per second; doing so would cause flashing without providing
any value to the user. */ any value to the user. */
if (bp->total_length != size if (bp->total_length != size
&& bp->last_eta_value != 0 && bp->last_eta_value != 0
&& dl_total_time - bp->last_eta_time < ETA_REFRESH_INTERVAL) && dl_total_time - bp->last_eta_time < ETA_REFRESH_INTERVAL)
eta = bp->last_eta_value; eta = bp->last_eta_value;
else else
{ {
/* Calculate ETA using the average download speed to predict /* Calculate ETA using the average download speed to predict
the future speed. If you want to use a speed averaged the future speed. If you want to use a speed averaged
over a more recent period, replace dl_total_time with over a more recent period, replace dl_total_time with
hist->total_time and bp->count with hist->total_bytes. hist->total_time and bp->count with hist->total_bytes.
I found that doing that results in a very jerky and I found that doing that results in a very jerky and
ultimately unreliable ETA. */ ultimately unreliable ETA. */
wgint bytes_remaining = bp->total_length - size; wgint bytes_remaining = bp->total_length - size;
double eta_ = dl_total_time * bytes_remaining / bp->count; double eta_ = dl_total_time * bytes_remaining / bp->count;
if (eta_ >= INT_MAX - 1) if (eta_ >= INT_MAX - 1)
goto skip_eta; goto skip_eta;
eta = (int) (eta_ + 0.5); eta = (int) (eta_ + 0.5);
bp->last_eta_value = eta; bp->last_eta_value = eta;
bp->last_eta_time = dl_total_time; bp->last_eta_time = dl_total_time;
} }
/* Translation note: "ETA" is English-centric, but this must /* Translation note: "ETA" is English-centric, but this must
be short, ideally 3 chars. Abbreviate if necessary. */ be short, ideally 3 chars. Abbreviate if necessary. */
sprintf (p, _(" eta %s"), eta_to_human_short (eta, false)); sprintf (p, _(" eta %s"), eta_to_human_short (eta, false));
move_to_end (p); move_to_end (p);
} }
else if (bp->total_length > 0) else if (bp->total_length > 0)
{ {
skip_eta: skip_eta:
APPEND_LITERAL (" "); APPEND_LITERAL (" ");
} }
} }
else else
{ {
/* When the download is done, print the elapsed time. */ /* When the download is done, print the elapsed time. */
/* Note to translators: this should not take up more room than /* Note to translators: this should not take up more room than
available here. Abbreviate if necessary. */ available here. Abbreviate if necessary. */
strcpy (p, _(" in ")); strcpy (p, _(" in "));
move_to_end (p); /* not p+=6, think translations! */ move_to_end (p); /* not p+=6, think translations! */
if (dl_total_time >= 10) if (dl_total_time >= 10)
strcpy (p, eta_to_human_short ((int) (dl_total_time + 0.5), false)); strcpy (p, eta_to_human_short ((int) (dl_total_time + 0.5), false));
else else
sprintf (p, "%ss", print_decimal (dl_total_time)); sprintf (p, "%ss", print_decimal (dl_total_time));
move_to_end (p); move_to_end (p);
} }
@ -998,24 +998,24 @@ bar_set_params (const char *params)
if ((opt.lfilename if ((opt.lfilename
#ifdef HAVE_ISATTY #ifdef HAVE_ISATTY
/* The progress bar doesn't make sense if the output is not a /* The progress bar doesn't make sense if the output is not a
TTY -- when logging to file, it is better to review the TTY -- when logging to file, it is better to review the
dots. */ dots. */
|| !isatty (fileno (stderr)) || !isatty (fileno (stderr))
#endif #endif
/* Normally we don't depend on terminal type because the /* Normally we don't depend on terminal type because the
progress bar only uses ^M to move the cursor to the progress bar only uses ^M to move the cursor to the
beginning of line, which works even on dumb terminals. But beginning of line, which works even on dumb terminals. But
Jamie Zawinski reports that ^M and ^H tricks don't work in Jamie Zawinski reports that ^M and ^H tricks don't work in
Emacs shell buffers, and only make a mess. */ Emacs shell buffers, and only make a mess. */
|| (term && 0 == strcmp (term, "emacs")) || (term && 0 == strcmp (term, "emacs"))
) )
&& !current_impl_locked) && !current_impl_locked)
{ {
/* We're not printing to a TTY, so revert to the fallback /* We're not printing to a TTY, so revert to the fallback
display. #### We're recursively calling display. #### We're recursively calling
set_progress_implementation here, which is slightly kludgy. set_progress_implementation here, which is slightly kludgy.
It would be nicer if we provided that function a return value It would be nicer if we provided that function a return value
indicating a failure of some sort. */ indicating a failure of some sort. */
set_progress_implementation (FALLBACK_PROGRESS_IMPLEMENTATION); set_progress_implementation (FALLBACK_PROGRESS_IMPLEMENTATION);
return; return;
} }
@ -1049,7 +1049,7 @@ progress_handle_sigwinch (int sig)
static const char * static const char *
eta_to_human_short (int secs, bool condensed) eta_to_human_short (int secs, bool condensed)
{ {
static char buf[10]; /* 8 should be enough, but just in case */ static char buf[10]; /* 8 should be enough, but just in case */
static int last = -1; static int last = -1;
const char *space = condensed ? "" : " "; const char *space = condensed ? "" : " ";

View File

@ -33,7 +33,7 @@ so, delete this exception statement from your version. */
ptimer_new -- creates a timer. ptimer_new -- creates a timer.
ptimer_reset -- resets the timer's elapsed time to zero. ptimer_reset -- resets the timer's elapsed time to zero.
ptimer_measure -- measure and return the time elapsed since ptimer_measure -- measure and return the time elapsed since
creation or last reset. creation or last reset.
ptimer_read -- reads the last measured elapsed value. ptimer_read -- reads the last measured elapsed value.
ptimer_destroy -- destroy the timer. ptimer_destroy -- destroy the timer.
ptimer_granularity -- returns the approximate granularity of the timers. ptimer_granularity -- returns the approximate granularity of the timers.
@ -81,11 +81,11 @@ so, delete this exception statement from your version. */
#undef PTIMER_WINDOWS #undef PTIMER_WINDOWS
#if defined(WINDOWS) || defined(__CYGWIN__) #if defined(WINDOWS) || defined(__CYGWIN__)
# define PTIMER_WINDOWS /* use Windows timers */ # define PTIMER_WINDOWS /* use Windows timers */
#elif _POSIX_TIMERS - 0 > 0 #elif _POSIX_TIMERS - 0 > 0
# define PTIMER_POSIX /* use POSIX timers (clock_gettime) */ # define PTIMER_POSIX /* use POSIX timers (clock_gettime) */
#else #else
# define PTIMER_GETTIMEOFDAY /* use gettimeofday */ # define PTIMER_GETTIMEOFDAY /* use gettimeofday */
#endif #endif
#ifdef PTIMER_POSIX #ifdef PTIMER_POSIX
@ -142,23 +142,23 @@ posix_init (void)
{ {
struct timespec r; struct timespec r;
if (clocks[i].sysconf_name != NO_SYSCONF_CHECK) if (clocks[i].sysconf_name != NO_SYSCONF_CHECK)
if (sysconf (clocks[i].sysconf_name) < 0) if (sysconf (clocks[i].sysconf_name) < 0)
continue; /* sysconf claims this clock is unavailable */ continue; /* sysconf claims this clock is unavailable */
if (clock_getres (clocks[i].id, &r) < 0) if (clock_getres (clocks[i].id, &r) < 0)
continue; /* clock_getres doesn't work for this clock */ continue; /* clock_getres doesn't work for this clock */
posix_clock_id = clocks[i].id; posix_clock_id = clocks[i].id;
posix_clock_resolution = (double) r.tv_sec + r.tv_nsec / 1e9; posix_clock_resolution = (double) r.tv_sec + r.tv_nsec / 1e9;
/* Guard against nonsense returned by a broken clock_getres. */ /* Guard against nonsense returned by a broken clock_getres. */
if (posix_clock_resolution == 0) if (posix_clock_resolution == 0)
posix_clock_resolution = 1e-3; posix_clock_resolution = 1e-3;
break; break;
} }
if (i == countof (clocks)) if (i == countof (clocks))
{ {
/* If no clock was found, it means that clock_getres failed for /* If no clock was found, it means that clock_getres failed for
the realtime clock. */ the realtime clock. */
logprintf (LOG_NOTQUIET, _("Cannot get REALTIME clock frequency: %s\n"), logprintf (LOG_NOTQUIET, _("Cannot get REALTIME clock frequency: %s\n"),
strerror (errno)); strerror (errno));
/* Use CLOCK_REALTIME, but invent a plausible resolution. */ /* Use CLOCK_REALTIME, but invent a plausible resolution. */
posix_clock_id = CLOCK_REALTIME; posix_clock_id = CLOCK_REALTIME;
posix_clock_resolution = 1e-3; posix_clock_resolution = 1e-3;
@ -175,7 +175,7 @@ static inline double
posix_diff (ptimer_system_time *pst1, ptimer_system_time *pst2) posix_diff (ptimer_system_time *pst1, ptimer_system_time *pst2)
{ {
return ((pst1->tv_sec - pst2->tv_sec) return ((pst1->tv_sec - pst2->tv_sec)
+ (pst1->tv_nsec - pst2->tv_nsec) / 1e9); + (pst1->tv_nsec - pst2->tv_nsec) / 1e9);
} }
static inline double static inline double
@ -183,7 +183,7 @@ posix_resolution (void)
{ {
return posix_clock_resolution; return posix_clock_resolution;
} }
#endif /* PTIMER_POSIX */ #endif /* PTIMER_POSIX */
#ifdef PTIMER_GETTIMEOFDAY #ifdef PTIMER_GETTIMEOFDAY
/* Elapsed time measurement using gettimeofday: system time is held in /* Elapsed time measurement using gettimeofday: system time is held in
@ -208,7 +208,7 @@ static inline double
gettimeofday_diff (ptimer_system_time *pst1, ptimer_system_time *pst2) gettimeofday_diff (ptimer_system_time *pst1, ptimer_system_time *pst2)
{ {
return ((pst1->tv_sec - pst2->tv_sec) return ((pst1->tv_sec - pst2->tv_sec)
+ (pst1->tv_usec - pst2->tv_usec) / 1e6); + (pst1->tv_usec - pst2->tv_usec) / 1e6);
} }
static inline double static inline double
@ -219,7 +219,7 @@ gettimeofday_resolution (void)
than 1ms. Assume 100 usecs. */ than 1ms. Assume 100 usecs. */
return 0.1; return 0.1;
} }
#endif /* PTIMER_GETTIMEOFDAY */ #endif /* PTIMER_GETTIMEOFDAY */
#ifdef PTIMER_WINDOWS #ifdef PTIMER_WINDOWS
/* Elapsed time measurement on Windows: where high-resolution timers /* Elapsed time measurement on Windows: where high-resolution timers
@ -290,9 +290,9 @@ windows_resolution (void)
if (windows_hires_timers) if (windows_hires_timers)
return 1.0 / windows_hires_freq; return 1.0 / windows_hires_freq;
else else
return 10; /* according to MSDN */ return 10; /* according to MSDN */
} }
#endif /* PTIMER_WINDOWS */ #endif /* PTIMER_WINDOWS */
/* The code below this point is independent of timer implementation. */ /* The code below this point is independent of timer implementation. */

View File

@ -52,13 +52,13 @@ so, delete this exception statement from your version. */
/* Functions for maintaining the URL queue. */ /* Functions for maintaining the URL queue. */
struct queue_element { struct queue_element {
const char *url; /* the URL to download */ const char *url; /* the URL to download */
const char *referer; /* the referring document */ const char *referer; /* the referring document */
int depth; /* the depth */ int depth; /* the depth */
bool html_allowed; /* whether the document is allowed to bool html_allowed; /* whether the document is allowed to
be treated as HTML. */ be treated as HTML. */
struct queue_element *next; /* next element in queue */ struct queue_element *next; /* next element in queue */
}; };
struct url_queue { struct url_queue {
@ -90,7 +90,7 @@ url_queue_delete (struct url_queue *queue)
static void static void
url_enqueue (struct url_queue *queue, url_enqueue (struct url_queue *queue,
const char *url, const char *referer, int depth, bool html_allowed) const char *url, const char *referer, int depth, bool html_allowed)
{ {
struct queue_element *qel = xnew (struct queue_element); struct queue_element *qel = xnew (struct queue_element);
qel->url = url; qel->url = url;
@ -119,8 +119,8 @@ url_enqueue (struct url_queue *queue,
static bool static bool
url_dequeue (struct url_queue *queue, url_dequeue (struct url_queue *queue,
const char **url, const char **referer, int *depth, const char **url, const char **referer, int *depth,
bool *html_allowed) bool *html_allowed)
{ {
struct queue_element *qel = queue->head; struct queue_element *qel = queue->head;
@ -146,9 +146,9 @@ url_dequeue (struct url_queue *queue,
} }
static bool download_child_p (const struct urlpos *, struct url *, int, static bool download_child_p (const struct urlpos *, struct url *, int,
struct url *, struct hash_table *); struct url *, struct hash_table *);
static bool descend_redirect_p (const char *, const char *, int, static bool descend_redirect_p (const char *, const char *, int,
struct url *, struct hash_table *); struct url *, struct hash_table *);
/* Retrieve a part of the web beginning with START_URL. This used to /* Retrieve a part of the web beginning with START_URL. This used to
@ -170,7 +170,7 @@ static bool descend_redirect_p (const char *, const char *, int,
7. if the URL is not one of those downloaded before, and if it 7. if the URL is not one of those downloaded before, and if it
satisfies the criteria specified by the various command-line satisfies the criteria specified by the various command-line
options, add it to the queue. */ options, add it to the queue. */
uerr_t uerr_t
retrieve_tree (const char *start_url) retrieve_tree (const char *start_url)
@ -190,7 +190,7 @@ retrieve_tree (const char *start_url)
if (!start_url_parsed) if (!start_url_parsed)
{ {
logprintf (LOG_NOTQUIET, "%s: %s.\n", start_url, logprintf (LOG_NOTQUIET, "%s: %s.\n", start_url,
url_error (up_error_code)); url_error (up_error_code));
return URLERROR; return URLERROR;
} }
@ -211,176 +211,176 @@ retrieve_tree (const char *start_url)
bool dash_p_leaf_HTML = false; bool dash_p_leaf_HTML = false;
if (opt.quota && total_downloaded_bytes > opt.quota) if (opt.quota && total_downloaded_bytes > opt.quota)
break; break;
if (status == FWRITEERR) if (status == FWRITEERR)
break; break;
/* Get the next URL from the queue... */ /* Get the next URL from the queue... */
if (!url_dequeue (queue, if (!url_dequeue (queue,
(const char **)&url, (const char **)&referer, (const char **)&url, (const char **)&referer,
&depth, &html_allowed)) &depth, &html_allowed))
break; break;
/* ...and download it. Note that this download is in most cases /* ...and download it. Note that this download is in most cases
unconditional, as download_child_p already makes sure a file unconditional, as download_child_p already makes sure a file
doesn't get enqueued twice -- and yet this check is here, and doesn't get enqueued twice -- and yet this check is here, and
not in download_child_p. This is so that if you run `wget -r not in download_child_p. This is so that if you run `wget -r
URL1 URL2', and a random URL is encountered once under URL1 URL1 URL2', and a random URL is encountered once under URL1
and again under URL2, but at a different (possibly smaller) and again under URL2, but at a different (possibly smaller)
depth, we want the URL's children to be taken into account depth, we want the URL's children to be taken into account
the second time. */ the second time. */
if (dl_url_file_map && hash_table_contains (dl_url_file_map, url)) if (dl_url_file_map && hash_table_contains (dl_url_file_map, url))
{ {
file = xstrdup (hash_table_get (dl_url_file_map, url)); file = xstrdup (hash_table_get (dl_url_file_map, url));
DEBUGP (("Already downloaded \"%s\", reusing it from \"%s\".\n", DEBUGP (("Already downloaded \"%s\", reusing it from \"%s\".\n",
url, file)); url, file));
if (html_allowed if (html_allowed
&& downloaded_html_set && downloaded_html_set
&& string_set_contains (downloaded_html_set, file)) && string_set_contains (downloaded_html_set, file))
descend = true; descend = true;
} }
else else
{ {
int dt = 0; int dt = 0;
char *redirected = NULL; char *redirected = NULL;
status = retrieve_url (url, &file, &redirected, referer, &dt, false); status = retrieve_url (url, &file, &redirected, referer, &dt, false);
if (html_allowed && file && status == RETROK if (html_allowed && file && status == RETROK
&& (dt & RETROKF) && (dt & TEXTHTML)) && (dt & RETROKF) && (dt & TEXTHTML))
descend = true; descend = true;
if (redirected) if (redirected)
{ {
/* We have been redirected, possibly to another host, or /* We have been redirected, possibly to another host, or
different path, or wherever. Check whether we really different path, or wherever. Check whether we really
want to follow it. */ want to follow it. */
if (descend) if (descend)
{ {
if (!descend_redirect_p (redirected, url, depth, if (!descend_redirect_p (redirected, url, depth,
start_url_parsed, blacklist)) start_url_parsed, blacklist))
descend = false; descend = false;
else else
/* Make sure that the old pre-redirect form gets /* Make sure that the old pre-redirect form gets
blacklisted. */ blacklisted. */
string_set_add (blacklist, url); string_set_add (blacklist, url);
} }
xfree (url); xfree (url);
url = redirected; url = redirected;
} }
} }
if (opt.spider) if (opt.spider)
{ {
visited_url (url, referer); visited_url (url, referer);
} }
if (descend if (descend
&& depth >= opt.reclevel && opt.reclevel != INFINITE_RECURSION) && depth >= opt.reclevel && opt.reclevel != INFINITE_RECURSION)
{ {
if (opt.page_requisites if (opt.page_requisites
&& (depth == opt.reclevel || depth == opt.reclevel + 1)) && (depth == opt.reclevel || depth == opt.reclevel + 1))
{ {
/* When -p is specified, we are allowed to exceed the /* When -p is specified, we are allowed to exceed the
maximum depth, but only for the "inline" links, maximum depth, but only for the "inline" links,
i.e. those that are needed to display the page. i.e. those that are needed to display the page.
Originally this could exceed the depth at most by Originally this could exceed the depth at most by
one, but we allow one more level so that the leaf one, but we allow one more level so that the leaf
pages that contain frames can be loaded pages that contain frames can be loaded
correctly. */ correctly. */
dash_p_leaf_HTML = true; dash_p_leaf_HTML = true;
} }
else else
{ {
/* Either -p wasn't specified or it was and we've /* Either -p wasn't specified or it was and we've
already spent the two extra (pseudo-)levels that it already spent the two extra (pseudo-)levels that it
affords us, so we need to bail out. */ affords us, so we need to bail out. */
DEBUGP (("Not descending further; at depth %d, max. %d.\n", DEBUGP (("Not descending further; at depth %d, max. %d.\n",
depth, opt.reclevel)); depth, opt.reclevel));
descend = false; descend = false;
} }
} }
/* If the downloaded document was HTML, parse it and enqueue the /* If the downloaded document was HTML, parse it and enqueue the
links it contains. */ links it contains. */
if (descend) if (descend)
{ {
bool meta_disallow_follow = false; bool meta_disallow_follow = false;
struct urlpos *children struct urlpos *children
= get_urls_html (file, url, &meta_disallow_follow); = get_urls_html (file, url, &meta_disallow_follow);
if (opt.use_robots && meta_disallow_follow) if (opt.use_robots && meta_disallow_follow)
{ {
free_urlpos (children); free_urlpos (children);
children = NULL; children = NULL;
} }
if (children) if (children)
{ {
struct urlpos *child = children; struct urlpos *child = children;
struct url *url_parsed = url_parsed = url_parse (url, NULL); struct url *url_parsed = url_parsed = url_parse (url, NULL);
char *referer_url = url; char *referer_url = url;
bool strip_auth = url_parsed->user; bool strip_auth = url_parsed->user;
assert (url_parsed != NULL); assert (url_parsed != NULL);
/* Strip auth info if present */ /* Strip auth info if present */
if (strip_auth) if (strip_auth)
referer_url = url_string (url_parsed, URL_AUTH_HIDE); referer_url = url_string (url_parsed, URL_AUTH_HIDE);
for (; child; child = child->next) for (; child; child = child->next)
{ {
if (child->ignore_when_downloading) if (child->ignore_when_downloading)
continue; continue;
if (dash_p_leaf_HTML && !child->link_inline_p) if (dash_p_leaf_HTML && !child->link_inline_p)
continue; continue;
if (download_child_p (child, url_parsed, depth, start_url_parsed, if (download_child_p (child, url_parsed, depth, start_url_parsed,
blacklist)) blacklist))
{ {
url_enqueue (queue, xstrdup (child->url->url), url_enqueue (queue, xstrdup (child->url->url),
xstrdup (referer_url), depth + 1, xstrdup (referer_url), depth + 1,
child->link_expect_html); child->link_expect_html);
/* We blacklist the URL we have enqueued, because we /* We blacklist the URL we have enqueued, because we
don't want to enqueue (and hence download) the don't want to enqueue (and hence download) the
same URL twice. */ same URL twice. */
string_set_add (blacklist, child->url->url); string_set_add (blacklist, child->url->url);
} }
} }
if (strip_auth) if (strip_auth)
xfree (referer_url); xfree (referer_url);
url_free (url_parsed); url_free (url_parsed);
free_urlpos (children); free_urlpos (children);
} }
} }
if (file if (file
&& (opt.delete_after && (opt.delete_after
|| opt.spider /* opt.recursive is implicitely true */ || opt.spider /* opt.recursive is implicitely true */
|| !acceptable (file))) || !acceptable (file)))
{ {
/* Either --delete-after was specified, or we loaded this /* Either --delete-after was specified, or we loaded this
(otherwise unneeded because of --spider or rejected by -R) (otherwise unneeded because of --spider or rejected by -R)
HTML file just to harvest its hyperlinks -- in either case, HTML file just to harvest its hyperlinks -- in either case,
delete the local file. */ delete the local file. */
DEBUGP (("Removing file due to %s in recursive_retrieve():\n", DEBUGP (("Removing file due to %s in recursive_retrieve():\n",
opt.delete_after ? "--delete-after" : opt.delete_after ? "--delete-after" :
(opt.spider ? "--spider" : (opt.spider ? "--spider" :
"recursive rejection criteria"))); "recursive rejection criteria")));
logprintf (LOG_VERBOSE, logprintf (LOG_VERBOSE,
(opt.delete_after || opt.spider (opt.delete_after || opt.spider
? _("Removing %s.\n") ? _("Removing %s.\n")
: _("Removing %s since it should be rejected.\n")), : _("Removing %s since it should be rejected.\n")),
file); file);
if (unlink (file)) if (unlink (file))
logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno)); logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
logputs (LOG_VERBOSE, "\n"); logputs (LOG_VERBOSE, "\n");
register_delete_file (file); register_delete_file (file);
} }
xfree (url); xfree (url);
xfree_null (referer); xfree_null (referer);
@ -394,10 +394,10 @@ retrieve_tree (const char *start_url)
int d3; int d3;
bool d4; bool d4;
while (url_dequeue (queue, while (url_dequeue (queue,
(const char **)&d1, (const char **)&d2, &d3, &d4)) (const char **)&d1, (const char **)&d2, &d3, &d4))
{ {
xfree (d1); xfree (d1);
xfree_null (d2); xfree_null (d2);
} }
} }
url_queue_delete (queue); url_queue_delete (queue);
@ -424,7 +424,7 @@ retrieve_tree (const char *start_url)
static bool static bool
download_child_p (const struct urlpos *upos, struct url *parent, int depth, download_child_p (const struct urlpos *upos, struct url *parent, int depth,
struct url *start_url_parsed, struct hash_table *blacklist) struct url *start_url_parsed, struct hash_table *blacklist)
{ {
struct url *u = upos->url; struct url *u = upos->url;
const char *url = u->url; const char *url = u->url;
@ -435,12 +435,12 @@ download_child_p (const struct urlpos *upos, struct url *parent, int depth,
if (string_set_contains (blacklist, url)) if (string_set_contains (blacklist, url))
{ {
if (opt.spider) if (opt.spider)
{ {
char *referrer = url_string (parent, URL_AUTH_HIDE_PASSWD); char *referrer = url_string (parent, URL_AUTH_HIDE_PASSWD);
DEBUGP (("download_child_p: parent->url is: `%s'\n", parent->url)); DEBUGP (("download_child_p: parent->url is: `%s'\n", parent->url));
visited_url (url, referrer); visited_url (url, referrer);
xfree (referrer); xfree (referrer);
} }
DEBUGP (("Already on the black list.\n")); DEBUGP (("Already on the black list.\n"));
goto out; goto out;
} }
@ -481,8 +481,8 @@ download_child_p (const struct urlpos *upos, struct url *parent, int depth,
if (u_scheme_like_http) if (u_scheme_like_http)
if (opt.relative_only && !upos->link_relative_p) if (opt.relative_only && !upos->link_relative_p)
{ {
DEBUGP (("It doesn't really look like a relative link.\n")); DEBUGP (("It doesn't really look like a relative link.\n"));
goto out; goto out;
} }
/* 3. If its domain is not to be accepted/looked-up, chuck it /* 3. If its domain is not to be accepted/looked-up, chuck it
@ -505,11 +505,11 @@ download_child_p (const struct urlpos *upos, struct url *parent, int depth,
&& !(opt.page_requisites && upos->link_inline_p)) && !(opt.page_requisites && upos->link_inline_p))
{ {
if (!subdir_p (start_url_parsed->dir, u->dir)) if (!subdir_p (start_url_parsed->dir, u->dir))
{ {
DEBUGP (("Going to \"%s\" would escape \"%s\" with no_parent on.\n", DEBUGP (("Going to \"%s\" would escape \"%s\" with no_parent on.\n",
u->dir, start_url_parsed->dir)); u->dir, start_url_parsed->dir));
goto out; goto out;
} }
} }
/* 5. If the file does not match the acceptance list, or is on the /* 5. If the file does not match the acceptance list, or is on the
@ -518,10 +518,10 @@ download_child_p (const struct urlpos *upos, struct url *parent, int depth,
if (opt.includes || opt.excludes) if (opt.includes || opt.excludes)
{ {
if (!accdir (u->dir)) if (!accdir (u->dir))
{ {
DEBUGP (("%s (%s) is excluded/not-included.\n", url, u->dir)); DEBUGP (("%s (%s) is excluded/not-included.\n", url, u->dir));
goto out; goto out;
} }
} }
/* 6. Check for acceptance/rejection rules. We ignore these rules /* 6. Check for acceptance/rejection rules. We ignore these rules
@ -531,31 +531,31 @@ download_child_p (const struct urlpos *upos, struct url *parent, int depth,
necesary, overstep the maximum depth to get the page requisites.) */ necesary, overstep the maximum depth to get the page requisites.) */
if (u->file[0] != '\0' if (u->file[0] != '\0'
&& !(has_html_suffix_p (u->file) && !(has_html_suffix_p (u->file)
/* The exception only applies to non-leaf HTMLs (but -p /* The exception only applies to non-leaf HTMLs (but -p
always implies non-leaf because we can overstep the always implies non-leaf because we can overstep the
maximum depth to get the requisites): */ maximum depth to get the requisites): */
&& (/* non-leaf */ && (/* non-leaf */
opt.reclevel == INFINITE_RECURSION opt.reclevel == INFINITE_RECURSION
/* also non-leaf */ /* also non-leaf */
|| depth < opt.reclevel - 1 || depth < opt.reclevel - 1
/* -p, which implies non-leaf (see above) */ /* -p, which implies non-leaf (see above) */
|| opt.page_requisites))) || opt.page_requisites)))
{ {
if (!acceptable (u->file)) if (!acceptable (u->file))
{ {
DEBUGP (("%s (%s) does not match acc/rej rules.\n", DEBUGP (("%s (%s) does not match acc/rej rules.\n",
url, u->file)); url, u->file));
goto out; goto out;
} }
} }
/* 7. */ /* 7. */
if (schemes_are_similar_p (u->scheme, parent->scheme)) if (schemes_are_similar_p (u->scheme, parent->scheme))
if (!opt.spanhost && 0 != strcasecmp (parent->host, u->host)) if (!opt.spanhost && 0 != strcasecmp (parent->host, u->host))
{ {
DEBUGP (("This is not the same hostname as the parent's (%s and %s).\n", DEBUGP (("This is not the same hostname as the parent's (%s and %s).\n",
u->host, parent->host)); u->host, parent->host));
goto out; goto out;
} }
/* 8. */ /* 8. */
@ -563,31 +563,31 @@ download_child_p (const struct urlpos *upos, struct url *parent, int depth,
{ {
struct robot_specs *specs = res_get_specs (u->host, u->port); struct robot_specs *specs = res_get_specs (u->host, u->port);
if (!specs) if (!specs)
{ {
char *rfile; char *rfile;
if (res_retrieve_file (url, &rfile)) if (res_retrieve_file (url, &rfile))
{ {
specs = res_parse_from_file (rfile); specs = res_parse_from_file (rfile);
xfree (rfile); xfree (rfile);
} }
else else
{ {
/* If we cannot get real specs, at least produce /* If we cannot get real specs, at least produce
dummy ones so that we can register them and stop dummy ones so that we can register them and stop
trying to retrieve them. */ trying to retrieve them. */
specs = res_parse ("", 0); specs = res_parse ("", 0);
} }
res_register_specs (u->host, u->port, specs); res_register_specs (u->host, u->port, specs);
} }
/* Now that we have (or don't have) robots.txt specs, we can /* Now that we have (or don't have) robots.txt specs, we can
check what they say. */ check what they say. */
if (!res_match_path (specs, u->path)) if (!res_match_path (specs, u->path))
{ {
DEBUGP (("Not following %s because robots.txt forbids it.\n", url)); DEBUGP (("Not following %s because robots.txt forbids it.\n", url));
string_set_add (blacklist, url); string_set_add (blacklist, url);
goto out; goto out;
} }
} }
/* The URL has passed all the tests. It can be placed in the /* The URL has passed all the tests. It can be placed in the
@ -609,7 +609,7 @@ download_child_p (const struct urlpos *upos, struct url *parent, int depth,
static bool static bool
descend_redirect_p (const char *redirected, const char *original, int depth, descend_redirect_p (const char *redirected, const char *original, int depth,
struct url *start_url_parsed, struct hash_table *blacklist) struct url *start_url_parsed, struct hash_table *blacklist)
{ {
struct url *orig_parsed, *new_parsed; struct url *orig_parsed, *new_parsed;
struct urlpos *upos; struct urlpos *upos;
@ -625,7 +625,7 @@ descend_redirect_p (const char *redirected, const char *original, int depth,
upos->url = new_parsed; upos->url = new_parsed;
success = download_child_p (upos, orig_parsed, depth, success = download_child_p (upos, orig_parsed, depth,
start_url_parsed, blacklist); start_url_parsed, blacklist);
url_free (orig_parsed); url_free (orig_parsed);
url_free (new_parsed); url_free (new_parsed);

View File

@ -99,31 +99,31 @@ limit_bandwidth (wgint bytes, struct ptimer *timer)
double slp = expected - delta_t + limit_data.sleep_adjust; double slp = expected - delta_t + limit_data.sleep_adjust;
double t0, t1; double t0, t1;
if (slp < 0.2) if (slp < 0.2)
{ {
DEBUGP (("deferring a %.2f ms sleep (%s/%.2f).\n", DEBUGP (("deferring a %.2f ms sleep (%s/%.2f).\n",
slp * 1000, number_to_static_string (limit_data.chunk_bytes), slp * 1000, number_to_static_string (limit_data.chunk_bytes),
delta_t)); delta_t));
return; return;
} }
DEBUGP (("\nsleeping %.2f ms for %s bytes, adjust %.2f ms\n", DEBUGP (("\nsleeping %.2f ms for %s bytes, adjust %.2f ms\n",
slp * 1000, number_to_static_string (limit_data.chunk_bytes), slp * 1000, number_to_static_string (limit_data.chunk_bytes),
limit_data.sleep_adjust)); limit_data.sleep_adjust));
t0 = ptimer_read (timer); t0 = ptimer_read (timer);
xsleep (slp); xsleep (slp);
t1 = ptimer_measure (timer); t1 = ptimer_measure (timer);
/* Due to scheduling, we probably slept slightly longer (or /* Due to scheduling, we probably slept slightly longer (or
shorter) than desired. Calculate the difference between the shorter) than desired. Calculate the difference between the
desired and the actual sleep, and adjust the next sleep by desired and the actual sleep, and adjust the next sleep by
that amount. */ that amount. */
limit_data.sleep_adjust = slp - (t1 - t0); limit_data.sleep_adjust = slp - (t1 - t0);
/* If sleep_adjust is very large, it's likely due to suspension /* If sleep_adjust is very large, it's likely due to suspension
and not clock inaccuracy. Don't enforce those. */ and not clock inaccuracy. Don't enforce those. */
if (limit_data.sleep_adjust > 0.5) if (limit_data.sleep_adjust > 0.5)
limit_data.sleep_adjust = 0.5; limit_data.sleep_adjust = 0.5;
else if (limit_data.sleep_adjust < -0.5) else if (limit_data.sleep_adjust < -0.5)
limit_data.sleep_adjust = -0.5; limit_data.sleep_adjust = -0.5;
} }
limit_data.chunk_bytes = 0; limit_data.chunk_bytes = 0;
@ -140,7 +140,7 @@ limit_bandwidth (wgint bytes, struct ptimer *timer)
static int static int
write_data (FILE *out, const char *buf, int bufsize, wgint *skip, write_data (FILE *out, const char *buf, int bufsize, wgint *skip,
wgint *written) wgint *written)
{ {
if (!out) if (!out)
return 1; return 1;
@ -155,7 +155,7 @@ write_data (FILE *out, const char *buf, int bufsize, wgint *skip,
bufsize -= *skip; bufsize -= *skip;
*skip = 0; *skip = 0;
if (bufsize == 0) if (bufsize == 0)
return 1; return 1;
} }
fwrite (buf, 1, bufsize, out); fwrite (buf, 1, bufsize, out);
@ -190,7 +190,7 @@ write_data (FILE *out, const char *buf, int bufsize, wgint *skip,
int int
fd_read_body (int fd, FILE *out, wgint toread, wgint startpos, fd_read_body (int fd, FILE *out, wgint toread, wgint startpos,
wgint *qtyread, wgint *qtywritten, double *elapsed, int flags) wgint *qtyread, wgint *qtywritten, double *elapsed, int flags)
{ {
int ret = 0; int ret = 0;
@ -222,8 +222,8 @@ fd_read_body (int fd, FILE *out, wgint toread, wgint startpos,
if (opt.verbose) if (opt.verbose)
{ {
/* If we're skipping STARTPOS bytes, pass 0 as the INITIAL /* If we're skipping STARTPOS bytes, pass 0 as the INITIAL
argument to progress_create because the indicator doesn't argument to progress_create because the indicator doesn't
(yet) know about "skipping" data. */ (yet) know about "skipping" data. */
progress = progress_create (skip ? 0 : startpos, startpos + toread); progress = progress_create (skip ? 0 : startpos, startpos + toread);
progress_interactive = progress_interactive_p (progress); progress_interactive = progress_interactive_p (progress);
} }
@ -256,61 +256,61 @@ fd_read_body (int fd, FILE *out, wgint toread, wgint startpos,
int rdsize = exact ? MIN (toread - sum_read, dlbufsize) : dlbufsize; int rdsize = exact ? MIN (toread - sum_read, dlbufsize) : dlbufsize;
double tmout = opt.read_timeout; double tmout = opt.read_timeout;
if (progress_interactive) if (progress_interactive)
{ {
/* For interactive progress gauges, always specify a ~1s /* For interactive progress gauges, always specify a ~1s
timeout, so that the gauge can be updated regularly even timeout, so that the gauge can be updated regularly even
when the data arrives very slowly or stalls. */ when the data arrives very slowly or stalls. */
tmout = 0.95; tmout = 0.95;
if (opt.read_timeout) if (opt.read_timeout)
{ {
double waittm; double waittm;
waittm = ptimer_read (timer) - last_successful_read_tm; waittm = ptimer_read (timer) - last_successful_read_tm;
if (waittm + tmout > opt.read_timeout) if (waittm + tmout > opt.read_timeout)
{ {
/* Don't let total idle time exceed read timeout. */ /* Don't let total idle time exceed read timeout. */
tmout = opt.read_timeout - waittm; tmout = opt.read_timeout - waittm;
if (tmout < 0) if (tmout < 0)
{ {
/* We've already exceeded the timeout. */ /* We've already exceeded the timeout. */
ret = -1, errno = ETIMEDOUT; ret = -1, errno = ETIMEDOUT;
break; break;
} }
} }
} }
} }
ret = fd_read (fd, dlbuf, rdsize, tmout); ret = fd_read (fd, dlbuf, rdsize, tmout);
if (progress_interactive && ret < 0 && errno == ETIMEDOUT) if (progress_interactive && ret < 0 && errno == ETIMEDOUT)
ret = 0; /* interactive timeout, handled above */ ret = 0; /* interactive timeout, handled above */
else if (ret <= 0) else if (ret <= 0)
break; /* EOF or read error */ break; /* EOF or read error */
if (progress || opt.limit_rate) if (progress || opt.limit_rate)
{ {
ptimer_measure (timer); ptimer_measure (timer);
if (ret > 0) if (ret > 0)
last_successful_read_tm = ptimer_read (timer); last_successful_read_tm = ptimer_read (timer);
} }
if (ret > 0) if (ret > 0)
{ {
sum_read += ret; sum_read += ret;
if (!write_data (out, dlbuf, ret, &skip, &sum_written)) if (!write_data (out, dlbuf, ret, &skip, &sum_written))
{ {
ret = -2; ret = -2;
goto out; goto out;
} }
} }
if (opt.limit_rate) if (opt.limit_rate)
limit_bandwidth (ret, timer); limit_bandwidth (ret, timer);
if (progress) if (progress)
progress_update (progress, ret, ptimer_read (timer)); progress_update (progress, ret, ptimer_read (timer));
#ifdef WINDOWS #ifdef WINDOWS
if (toread > 0 && !opt.quiet) if (toread > 0 && !opt.quiet)
ws_percenttitle (100.0 * ws_percenttitle (100.0 *
(startpos + sum_read) / (startpos + toread)); (startpos + sum_read) / (startpos + toread));
#endif #endif
} }
if (ret < -1) if (ret < -1)
@ -389,7 +389,7 @@ fd_read_hunk (int fd, hunk_terminator_t terminator, long sizehint, long maxsize)
{ {
long bufsize = sizehint; long bufsize = sizehint;
char *hunk = xmalloc (bufsize); char *hunk = xmalloc (bufsize);
int tail = 0; /* tail position in HUNK */ int tail = 0; /* tail position in HUNK */
assert (maxsize >= bufsize); assert (maxsize >= bufsize);
@ -402,82 +402,82 @@ fd_read_hunk (int fd, hunk_terminator_t terminator, long sizehint, long maxsize)
pklen = fd_peek (fd, hunk + tail, bufsize - 1 - tail, -1); pklen = fd_peek (fd, hunk + tail, bufsize - 1 - tail, -1);
if (pklen < 0) if (pklen < 0)
{ {
xfree (hunk); xfree (hunk);
return NULL; return NULL;
} }
end = terminator (hunk, hunk + tail, pklen); end = terminator (hunk, hunk + tail, pklen);
if (end) if (end)
{ {
/* The data contains the terminator: we'll drain the data up /* The data contains the terminator: we'll drain the data up
to the end of the terminator. */ to the end of the terminator. */
remain = end - (hunk + tail); remain = end - (hunk + tail);
assert (remain >= 0); assert (remain >= 0);
if (remain == 0) if (remain == 0)
{ {
/* No more data needs to be read. */ /* No more data needs to be read. */
hunk[tail] = '\0'; hunk[tail] = '\0';
return hunk; return hunk;
} }
if (bufsize - 1 < tail + remain) if (bufsize - 1 < tail + remain)
{ {
bufsize = tail + remain + 1; bufsize = tail + remain + 1;
hunk = xrealloc (hunk, bufsize); hunk = xrealloc (hunk, bufsize);
} }
} }
else else
/* No terminator: simply read the data we know is (or should /* No terminator: simply read the data we know is (or should
be) available. */ be) available. */
remain = pklen; remain = pklen;
/* Now, read the data. Note that we make no assumptions about /* Now, read the data. Note that we make no assumptions about
how much data we'll get. (Some TCP stacks are notorious for how much data we'll get. (Some TCP stacks are notorious for
read returning less data than the previous MSG_PEEK.) */ read returning less data than the previous MSG_PEEK.) */
rdlen = fd_read (fd, hunk + tail, remain, 0); rdlen = fd_read (fd, hunk + tail, remain, 0);
if (rdlen < 0) if (rdlen < 0)
{ {
xfree_null (hunk); xfree_null (hunk);
return NULL; return NULL;
} }
tail += rdlen; tail += rdlen;
hunk[tail] = '\0'; hunk[tail] = '\0';
if (rdlen == 0) if (rdlen == 0)
{ {
if (tail == 0) if (tail == 0)
{ {
/* EOF without anything having been read */ /* EOF without anything having been read */
xfree (hunk); xfree (hunk);
errno = 0; errno = 0;
return NULL; return NULL;
} }
else else
/* EOF seen: return the data we've read. */ /* EOF seen: return the data we've read. */
return hunk; return hunk;
} }
if (end && rdlen == remain) if (end && rdlen == remain)
/* The terminator was seen and the remaining data drained -- /* The terminator was seen and the remaining data drained --
we got what we came for. */ we got what we came for. */
return hunk; return hunk;
/* Keep looping until all the data arrives. */ /* Keep looping until all the data arrives. */
if (tail == bufsize - 1) if (tail == bufsize - 1)
{ {
/* Double the buffer size, but refuse to allocate more than /* Double the buffer size, but refuse to allocate more than
MAXSIZE bytes. */ MAXSIZE bytes. */
if (maxsize && bufsize >= maxsize) if (maxsize && bufsize >= maxsize)
{ {
xfree (hunk); xfree (hunk);
errno = ENOMEM; errno = ENOMEM;
return NULL; return NULL;
} }
bufsize <<= 1; bufsize <<= 1;
if (maxsize && bufsize > maxsize) if (maxsize && bufsize > maxsize)
bufsize = maxsize; bufsize = maxsize;
hunk = xrealloc (hunk, bufsize); hunk = xrealloc (hunk, bufsize);
} }
} }
} }
@ -524,8 +524,8 @@ retr_rate (wgint bytes, double secs)
/* Use more digits for smaller numbers (regardless of unit used), /* Use more digits for smaller numbers (regardless of unit used),
e.g. "1022", "247", "12.5", "2.38". */ e.g. "1022", "247", "12.5", "2.38". */
sprintf (res, "%.*f %s", sprintf (res, "%.*f %s",
dlrate >= 99.95 ? 0 : dlrate >= 9.995 ? 1 : 2, dlrate >= 99.95 ? 0 : dlrate >= 9.995 ? 1 : 2,
dlrate, rate_names[units]); dlrate, rate_names[units]);
return res; return res;
} }
@ -568,21 +568,21 @@ calc_rate (wgint bytes, double secs, int *units)
} }
#define SUSPEND_POST_DATA do { \ #define SUSPEND_POST_DATA do { \
post_data_suspended = true; \ post_data_suspended = true; \
saved_post_data = opt.post_data; \ saved_post_data = opt.post_data; \
saved_post_file_name = opt.post_file_name; \ saved_post_file_name = opt.post_file_name; \
opt.post_data = NULL; \ opt.post_data = NULL; \
opt.post_file_name = NULL; \ opt.post_file_name = NULL; \
} while (0) } while (0)
#define RESTORE_POST_DATA do { \ #define RESTORE_POST_DATA do { \
if (post_data_suspended) \ if (post_data_suspended) \
{ \ { \
opt.post_data = saved_post_data; \ opt.post_data = saved_post_data; \
opt.post_file_name = saved_post_file_name; \ opt.post_file_name = saved_post_file_name; \
post_data_suspended = false; \ post_data_suspended = false; \
} \ } \
} while (0) } while (0)
static char *getproxy (struct url *); static char *getproxy (struct url *);
@ -595,7 +595,7 @@ static char *getproxy (struct url *);
uerr_t uerr_t
retrieve_url (const char *origurl, char **file, char **newloc, retrieve_url (const char *origurl, char **file, char **newloc,
const char *refurl, int *dt, bool recursive) const char *refurl, int *dt, bool recursive)
{ {
uerr_t result; uerr_t result;
char *url; char *url;
@ -603,7 +603,7 @@ retrieve_url (const char *origurl, char **file, char **newloc,
int dummy; int dummy;
char *mynewloc, *proxy; char *mynewloc, *proxy;
struct url *u, *proxy_url; struct url *u, *proxy_url;
int up_error_code; /* url parse error code */ int up_error_code; /* url parse error code */
char *local_file; char *local_file;
int redirection_count = 0; int redirection_count = 0;
@ -647,21 +647,21 @@ retrieve_url (const char *origurl, char **file, char **newloc,
/* Parse the proxy URL. */ /* Parse the proxy URL. */
proxy_url = url_parse (proxy, &up_error_code); proxy_url = url_parse (proxy, &up_error_code);
if (!proxy_url) if (!proxy_url)
{ {
logprintf (LOG_NOTQUIET, _("Error parsing proxy URL %s: %s.\n"), logprintf (LOG_NOTQUIET, _("Error parsing proxy URL %s: %s.\n"),
proxy, url_error (up_error_code)); proxy, url_error (up_error_code));
xfree (url); xfree (url);
RESTORE_POST_DATA; RESTORE_POST_DATA;
return PROXERR; return PROXERR;
} }
if (proxy_url->scheme != SCHEME_HTTP && proxy_url->scheme != u->scheme) if (proxy_url->scheme != SCHEME_HTTP && proxy_url->scheme != u->scheme)
{ {
logprintf (LOG_NOTQUIET, _("Error in proxy URL %s: Must be HTTP.\n"), proxy); logprintf (LOG_NOTQUIET, _("Error in proxy URL %s: Must be HTTP.\n"), proxy);
url_free (proxy_url); url_free (proxy_url);
xfree (url); xfree (url);
RESTORE_POST_DATA; RESTORE_POST_DATA;
return PROXERR; return PROXERR;
} }
} }
if (u->scheme == SCHEME_HTTP if (u->scheme == SCHEME_HTTP
@ -675,24 +675,24 @@ retrieve_url (const char *origurl, char **file, char **newloc,
else if (u->scheme == SCHEME_FTP) else if (u->scheme == SCHEME_FTP)
{ {
/* If this is a redirection, temporarily turn off opt.ftp_glob /* If this is a redirection, temporarily turn off opt.ftp_glob
and opt.recursive, both being undesirable when following and opt.recursive, both being undesirable when following
redirects. */ redirects. */
bool oldrec = recursive, glob = opt.ftp_glob; bool oldrec = recursive, glob = opt.ftp_glob;
if (redirection_count) if (redirection_count)
oldrec = glob = false; oldrec = glob = false;
result = ftp_loop (u, dt, proxy_url, recursive, glob); result = ftp_loop (u, dt, proxy_url, recursive, glob);
recursive = oldrec; recursive = oldrec;
/* There is a possibility of having HTTP being redirected to /* There is a possibility of having HTTP being redirected to
FTP. In these cases we must decide whether the text is HTML FTP. In these cases we must decide whether the text is HTML
according to the suffix. The HTML suffixes are `.html', according to the suffix. The HTML suffixes are `.html',
`.htm' and a few others, case-insensitive. */ `.htm' and a few others, case-insensitive. */
if (redirection_count && local_file && u->scheme == SCHEME_FTP) if (redirection_count && local_file && u->scheme == SCHEME_FTP)
{ {
if (has_html_suffix_p (local_file)) if (has_html_suffix_p (local_file))
*dt |= TEXTHTML; *dt |= TEXTHTML;
} }
} }
if (proxy_url) if (proxy_url)
@ -710,12 +710,12 @@ retrieve_url (const char *origurl, char **file, char **newloc,
assert (mynewloc != NULL); assert (mynewloc != NULL);
if (local_file) if (local_file)
xfree (local_file); xfree (local_file);
/* The HTTP specs only allow absolute URLs to appear in /* The HTTP specs only allow absolute URLs to appear in
redirects, but a ton of boneheaded webservers and CGIs out redirects, but a ton of boneheaded webservers and CGIs out
there break the rules and use relative URLs, and popular there break the rules and use relative URLs, and popular
browsers are lenient about this, so wget should be too. */ browsers are lenient about this, so wget should be too. */
construced_newloc = uri_merge (url, mynewloc); construced_newloc = uri_merge (url, mynewloc);
xfree (mynewloc); xfree (mynewloc);
mynewloc = construced_newloc; mynewloc = construced_newloc;
@ -723,15 +723,15 @@ retrieve_url (const char *origurl, char **file, char **newloc,
/* Now, see if this new location makes sense. */ /* Now, see if this new location makes sense. */
newloc_parsed = url_parse (mynewloc, &up_error_code); newloc_parsed = url_parse (mynewloc, &up_error_code);
if (!newloc_parsed) if (!newloc_parsed)
{ {
logprintf (LOG_NOTQUIET, "%s: %s.\n", escnonprint_uri (mynewloc), logprintf (LOG_NOTQUIET, "%s: %s.\n", escnonprint_uri (mynewloc),
url_error (up_error_code)); url_error (up_error_code));
url_free (u); url_free (u);
xfree (url); xfree (url);
xfree (mynewloc); xfree (mynewloc);
RESTORE_POST_DATA; RESTORE_POST_DATA;
return result; return result;
} }
/* Now mynewloc will become newloc_parsed->url, because if the /* Now mynewloc will become newloc_parsed->url, because if the
Location contained relative paths like .././something, we Location contained relative paths like .././something, we
@ -741,16 +741,16 @@ retrieve_url (const char *origurl, char **file, char **newloc,
/* Check for max. number of redirections. */ /* Check for max. number of redirections. */
if (++redirection_count > opt.max_redirect) if (++redirection_count > opt.max_redirect)
{ {
logprintf (LOG_NOTQUIET, _("%d redirections exceeded.\n"), logprintf (LOG_NOTQUIET, _("%d redirections exceeded.\n"),
opt.max_redirect); opt.max_redirect);
url_free (newloc_parsed); url_free (newloc_parsed);
url_free (u); url_free (u);
xfree (url); xfree (url);
xfree (mynewloc); xfree (mynewloc);
RESTORE_POST_DATA; RESTORE_POST_DATA;
return WRONGCODE; return WRONGCODE;
} }
xfree (url); xfree (url);
url = mynewloc; url = mynewloc;
@ -758,12 +758,12 @@ retrieve_url (const char *origurl, char **file, char **newloc,
u = newloc_parsed; u = newloc_parsed;
/* If we're being redirected from POST, we don't want to POST /* If we're being redirected from POST, we don't want to POST
again. Many requests answer POST with a redirection to an again. Many requests answer POST with a redirection to an
index page; that redirection is clearly a GET. We "suspend" index page; that redirection is clearly a GET. We "suspend"
POST data for the duration of the redirections, and restore POST data for the duration of the redirections, and restore
it when we're done. */ it when we're done. */
if (!post_data_suspended) if (!post_data_suspended)
SUSPEND_POST_DATA; SUSPEND_POST_DATA;
goto redirected; goto redirected;
} }
@ -771,13 +771,13 @@ retrieve_url (const char *origurl, char **file, char **newloc,
if (local_file) if (local_file)
{ {
if (*dt & RETROKF) if (*dt & RETROKF)
{ {
register_download (u->url, local_file); register_download (u->url, local_file);
if (redirection_count && 0 != strcmp (origurl, u->url)) if (redirection_count && 0 != strcmp (origurl, u->url))
register_redirection (origurl, u->url); register_redirection (origurl, u->url);
if (*dt & TEXTHTML) if (*dt & TEXTHTML)
register_html (u->url, local_file); register_html (u->url, local_file);
} }
} }
if (file) if (file)
@ -790,14 +790,14 @@ retrieve_url (const char *origurl, char **file, char **newloc,
if (redirection_count) if (redirection_count)
{ {
if (newloc) if (newloc)
*newloc = url; *newloc = url;
else else
xfree (url); xfree (url);
} }
else else
{ {
if (newloc) if (newloc)
*newloc = NULL; *newloc = NULL;
xfree (url); xfree (url);
} }
@ -819,7 +819,7 @@ retrieve_from_file (const char *file, bool html, int *count)
struct urlpos *url_list, *cur_url; struct urlpos *url_list, *cur_url;
url_list = (html ? get_urls_html (file, NULL, NULL) url_list = (html ? get_urls_html (file, NULL, NULL)
: get_urls_file (file)); : get_urls_file (file));
status = RETROK; /* Suppose everything is OK. */ status = RETROK; /* Suppose everything is OK. */
*count = 0; /* Reset the URL count. */ *count = 0; /* Reset the URL count. */
@ -829,38 +829,38 @@ retrieve_from_file (const char *file, bool html, int *count)
int dt; int dt;
if (cur_url->ignore_when_downloading) if (cur_url->ignore_when_downloading)
continue; continue;
if (opt.quota && total_downloaded_bytes > opt.quota) if (opt.quota && total_downloaded_bytes > opt.quota)
{ {
status = QUOTEXC; status = QUOTEXC;
break; break;
} }
if ((opt.recursive || opt.page_requisites) if ((opt.recursive || opt.page_requisites)
&& (cur_url->url->scheme != SCHEME_FTP || getproxy (cur_url->url))) && (cur_url->url->scheme != SCHEME_FTP || getproxy (cur_url->url)))
{ {
int old_follow_ftp = opt.follow_ftp; int old_follow_ftp = opt.follow_ftp;
/* Turn opt.follow_ftp on in case of recursive FTP retrieval */ /* Turn opt.follow_ftp on in case of recursive FTP retrieval */
if (cur_url->url->scheme == SCHEME_FTP) if (cur_url->url->scheme == SCHEME_FTP)
opt.follow_ftp = 1; opt.follow_ftp = 1;
status = retrieve_tree (cur_url->url->url); status = retrieve_tree (cur_url->url->url);
opt.follow_ftp = old_follow_ftp; opt.follow_ftp = old_follow_ftp;
} }
else else
status = retrieve_url (cur_url->url->url, &filename, &new_file, NULL, &dt, opt.recursive); status = retrieve_url (cur_url->url->url, &filename, &new_file, NULL, &dt, opt.recursive);
if (filename && opt.delete_after && file_exists_p (filename)) if (filename && opt.delete_after && file_exists_p (filename))
{ {
DEBUGP (("\ DEBUGP (("\
Removing file due to --delete-after in retrieve_from_file():\n")); Removing file due to --delete-after in retrieve_from_file():\n"));
logprintf (LOG_VERBOSE, _("Removing %s.\n"), filename); logprintf (LOG_VERBOSE, _("Removing %s.\n"), filename);
if (unlink (filename)) if (unlink (filename))
logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno)); logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
dt &= ~RETROKF; dt &= ~RETROKF;
} }
xfree_null (new_file); xfree_null (new_file);
xfree_null (filename); xfree_null (filename);
@ -901,29 +901,29 @@ sleep_between_retrievals (int count)
if (opt.waitretry && count > 1) if (opt.waitretry && count > 1)
{ {
/* If opt.waitretry is specified and this is a retry, wait for /* If opt.waitretry is specified and this is a retry, wait for
COUNT-1 number of seconds, or for opt.waitretry seconds. */ COUNT-1 number of seconds, or for opt.waitretry seconds. */
if (count <= opt.waitretry) if (count <= opt.waitretry)
xsleep (count - 1); xsleep (count - 1);
else else
xsleep (opt.waitretry); xsleep (opt.waitretry);
} }
else if (opt.wait) else if (opt.wait)
{ {
if (!opt.random_wait || count > 1) if (!opt.random_wait || count > 1)
/* If random-wait is not specified, or if we are sleeping /* If random-wait is not specified, or if we are sleeping
between retries of the same download, sleep the fixed between retries of the same download, sleep the fixed
interval. */ interval. */
xsleep (opt.wait); xsleep (opt.wait);
else else
{ {
/* Sleep a random amount of time averaging in opt.wait /* Sleep a random amount of time averaging in opt.wait
seconds. The sleeping amount ranges from 0.5*opt.wait to seconds. The sleeping amount ranges from 0.5*opt.wait to
1.5*opt.wait. */ 1.5*opt.wait. */
double waitsecs = (0.5 + random_float ()) * opt.wait; double waitsecs = (0.5 + random_float ()) * opt.wait;
DEBUGP (("sleep_between_retrievals: avg=%f,sleep=%f\n", DEBUGP (("sleep_between_retrievals: avg=%f,sleep=%f\n",
opt.wait, waitsecs)); opt.wait, waitsecs));
xsleep (waitsecs); xsleep (waitsecs);
} }
} }
} }
@ -935,7 +935,7 @@ free_urlpos (struct urlpos *l)
{ {
struct urlpos *next = l->next; struct urlpos *next = l->next;
if (l->url) if (l->url)
url_free (l->url); url_free (l->url);
xfree_null (l->local_name); xfree_null (l->local_name);
xfree (l); xfree (l);
l = next; l = next;

View File

@ -56,20 +56,20 @@ so, delete this exception statement from your version. */
#define xd _sch_isxdigit #define xd _sch_isxdigit
/* Masks. */ /* Masks. */
#define L lo|is |pr /* lower case letter */ #define L lo|is |pr /* lower case letter */
#define XL lo|is|xd|pr /* lowercase hex digit */ #define XL lo|is|xd|pr /* lowercase hex digit */
#define U up|is |pr /* upper case letter */ #define U up|is |pr /* upper case letter */
#define XU up|is|xd|pr /* uppercase hex digit */ #define XU up|is|xd|pr /* uppercase hex digit */
#define D di |xd|pr /* decimal digit */ #define D di |xd|pr /* decimal digit */
#define P pn |pr /* punctuation */ #define P pn |pr /* punctuation */
#define _ pn|is |pr /* underscore */ #define _ pn|is |pr /* underscore */
#define C cn /* control character */ #define C cn /* control character */
#define Z nv |cn /* NUL */ #define Z nv |cn /* NUL */
#define M nv|sp |cn /* cursor movement: \f \v */ #define M nv|sp |cn /* cursor movement: \f \v */
#define V vs|sp |cn /* vertical space: \r \n */ #define V vs|sp |cn /* vertical space: \r \n */
#define T nv|sp|bl|cn /* tab */ #define T nv|sp|bl|cn /* tab */
#define S nv|sp|bl|pr /* space */ #define S nv|sp|bl|pr /* space */
/* Are we ASCII? */ /* Are we ASCII? */
#if '\n' == 0x0A && ' ' == 0x20 && '0' == 0x30 \ #if '\n' == 0x0A && ' ' == 0x20 && '0' == 0x30 \

View File

@ -106,7 +106,7 @@
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include <stdio.h> /* for NULL */ #include <stdio.h> /* for NULL */
#include <stdarg.h> #include <stdarg.h>
@ -133,13 +133,13 @@ int snprintf (char *str, size_t count, const char *fmt, ...);
int vsnprintf (char *str, size_t count, const char *fmt, va_list arg); int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
static int dopr (char *buffer, size_t maxlen, const char *format, static int dopr (char *buffer, size_t maxlen, const char *format,
va_list args); va_list args);
static int fmtstr (char *buffer, size_t *currlen, size_t maxlen, static int fmtstr (char *buffer, size_t *currlen, size_t maxlen,
const char *value, int flags, int min, int max); const char *value, int flags, int min, int max);
static int fmtint (char *buffer, size_t *currlen, size_t maxlen, static int fmtint (char *buffer, size_t *currlen, size_t maxlen,
LLONG value, int base, int min, int max, int flags); LLONG value, int base, int min, int max, int flags);
static int fmtfp (char *buffer, size_t *currlen, size_t maxlen, static int fmtfp (char *buffer, size_t *currlen, size_t maxlen,
LDOUBLE fvalue, int min, int max, int flags); LDOUBLE fvalue, int min, int max, int flags);
static int dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c); static int dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c);
/* /*
@ -158,14 +158,14 @@ static int dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c);
#define DP_S_DONE 8 #define DP_S_DONE 8
/* format flags - Bits */ /* format flags - Bits */
#define DP_F_MINUS (1 << 0) #define DP_F_MINUS (1 << 0)
#define DP_F_PLUS (1 << 1) #define DP_F_PLUS (1 << 1)
#define DP_F_SPACE (1 << 2) #define DP_F_SPACE (1 << 2)
#define DP_F_NUM (1 << 3) #define DP_F_NUM (1 << 3)
#define DP_F_ZERO (1 << 4) #define DP_F_ZERO (1 << 4)
#define DP_F_UP (1 << 5) #define DP_F_UP (1 << 5)
#define DP_F_UNSIGNED (1 << 6) #define DP_F_UNSIGNED (1 << 6)
#define DP_F_FP_G (1 << 7) #define DP_F_FP_G (1 << 7)
/* Conversion Flags */ /* Conversion Flags */
#define DP_C_SHORT 1 #define DP_C_SHORT 1
@ -206,113 +206,113 @@ static int dopr (char *buffer, size_t maxlen, const char *format, va_list args)
{ {
case DP_S_DEFAULT: case DP_S_DEFAULT:
if (ch == '%') if (ch == '%')
state = DP_S_FLAGS; state = DP_S_FLAGS;
else else
total += dopr_outch (buffer, &currlen, maxlen, ch); total += dopr_outch (buffer, &currlen, maxlen, ch);
ch = *format++; ch = *format++;
break; break;
case DP_S_FLAGS: case DP_S_FLAGS:
switch (ch) switch (ch)
{ {
case '-': case '-':
flags |= DP_F_MINUS; flags |= DP_F_MINUS;
ch = *format++; ch = *format++;
break; break;
case '+': case '+':
flags |= DP_F_PLUS; flags |= DP_F_PLUS;
ch = *format++; ch = *format++;
break; break;
case ' ': case ' ':
flags |= DP_F_SPACE; flags |= DP_F_SPACE;
ch = *format++; ch = *format++;
break; break;
case '#': case '#':
flags |= DP_F_NUM; flags |= DP_F_NUM;
ch = *format++; ch = *format++;
break; break;
case '0': case '0':
flags |= DP_F_ZERO; flags |= DP_F_ZERO;
ch = *format++; ch = *format++;
break; break;
default: default:
state = DP_S_MIN; state = DP_S_MIN;
break; break;
} }
break; break;
case DP_S_MIN: case DP_S_MIN:
if ('0' <= ch && ch <= '9') if ('0' <= ch && ch <= '9')
{ {
min = 10*min + char_to_int (ch); min = 10*min + char_to_int (ch);
ch = *format++; ch = *format++;
} }
else if (ch == '*') else if (ch == '*')
{ {
min = va_arg (args, int); min = va_arg (args, int);
ch = *format++; ch = *format++;
state = DP_S_DOT; state = DP_S_DOT;
} }
else else
state = DP_S_DOT; state = DP_S_DOT;
break; break;
case DP_S_DOT: case DP_S_DOT:
if (ch == '.') if (ch == '.')
{ {
state = DP_S_MAX; state = DP_S_MAX;
ch = *format++; ch = *format++;
} }
else else
state = DP_S_MOD; state = DP_S_MOD;
break; break;
case DP_S_MAX: case DP_S_MAX:
if ('0' <= ch && ch <= '9') if ('0' <= ch && ch <= '9')
{ {
if (max < 0) if (max < 0)
max = 0; max = 0;
max = 10*max + char_to_int (ch); max = 10*max + char_to_int (ch);
ch = *format++; ch = *format++;
} }
else if (ch == '*') else if (ch == '*')
{ {
max = va_arg (args, int); max = va_arg (args, int);
ch = *format++; ch = *format++;
state = DP_S_MOD; state = DP_S_MOD;
} }
else else
state = DP_S_MOD; state = DP_S_MOD;
break; break;
case DP_S_MOD: case DP_S_MOD:
switch (ch) switch (ch)
{ {
case 'h': case 'h':
cflags = DP_C_SHORT; cflags = DP_C_SHORT;
ch = *format++; ch = *format++;
break; break;
case 'l': case 'l':
cflags = DP_C_LONG; cflags = DP_C_LONG;
ch = *format++; ch = *format++;
break; break;
case 'L': case 'L':
cflags = DP_C_LDOUBLE; cflags = DP_C_LDOUBLE;
ch = *format++; ch = *format++;
break; break;
default: default:
break; break;
} }
if (cflags != DP_C_LONG) if (cflags != DP_C_LONG)
state = DP_S_CONV; state = DP_S_CONV;
else else
state = DP_S_MOD_L; state = DP_S_MOD_L;
break; break;
case DP_S_MOD_L: case DP_S_MOD_L:
switch (ch) switch (ch)
{ {
case 'l': case 'l':
cflags = DP_C_LLONG; cflags = DP_C_LLONG;
ch = *format++; ch = *format++;
break; break;
default: default:
break; break;
} }
state = DP_S_CONV; state = DP_S_CONV;
break; break;
case DP_S_CONV: case DP_S_CONV:
@ -320,131 +320,131 @@ static int dopr (char *buffer, size_t maxlen, const char *format, va_list args)
{ {
case 'd': case 'd':
case 'i': case 'i':
if (cflags == DP_C_SHORT) if (cflags == DP_C_SHORT)
value = (short int) va_arg (args, int); value = (short int) va_arg (args, int);
else if (cflags == DP_C_LONG) else if (cflags == DP_C_LONG)
value = va_arg (args, long int); value = va_arg (args, long int);
else if (cflags == DP_C_LLONG) else if (cflags == DP_C_LLONG)
value = va_arg (args, LLONG); value = va_arg (args, LLONG);
else else
value = va_arg (args, int); value = va_arg (args, int);
total += fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); total += fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
break; break;
case 'o': case 'o':
flags |= DP_F_UNSIGNED; flags |= DP_F_UNSIGNED;
if (cflags == DP_C_SHORT) if (cflags == DP_C_SHORT)
value = (unsigned short int) va_arg (args, unsigned int); value = (unsigned short int) va_arg (args, unsigned int);
else if (cflags == DP_C_LONG) else if (cflags == DP_C_LONG)
value = va_arg (args, unsigned long int); value = va_arg (args, unsigned long int);
else if (cflags == DP_C_LLONG) else if (cflags == DP_C_LLONG)
value = va_arg (args, unsigned LLONG); value = va_arg (args, unsigned LLONG);
else else
value = va_arg (args, unsigned int); value = va_arg (args, unsigned int);
total += fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags); total += fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
break; break;
case 'u': case 'u':
flags |= DP_F_UNSIGNED; flags |= DP_F_UNSIGNED;
if (cflags == DP_C_SHORT) if (cflags == DP_C_SHORT)
value = (unsigned short int) va_arg (args, unsigned int); value = (unsigned short int) va_arg (args, unsigned int);
else if (cflags == DP_C_LONG) else if (cflags == DP_C_LONG)
value = va_arg (args, unsigned long int); value = va_arg (args, unsigned long int);
else if (cflags == DP_C_LLONG) else if (cflags == DP_C_LLONG)
value = va_arg (args, unsigned LLONG); value = va_arg (args, unsigned LLONG);
else else
value = va_arg (args, unsigned int); value = va_arg (args, unsigned int);
total += fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); total += fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
break; break;
case 'X': case 'X':
flags |= DP_F_UP; flags |= DP_F_UP;
case 'x': case 'x':
flags |= DP_F_UNSIGNED; flags |= DP_F_UNSIGNED;
if (cflags == DP_C_SHORT) if (cflags == DP_C_SHORT)
value = (unsigned short int) va_arg (args, unsigned int); value = (unsigned short int) va_arg (args, unsigned int);
else if (cflags == DP_C_LONG) else if (cflags == DP_C_LONG)
value = va_arg (args, unsigned long int); value = va_arg (args, unsigned long int);
else if (cflags == DP_C_LLONG) else if (cflags == DP_C_LLONG)
value = va_arg (args, unsigned LLONG); value = va_arg (args, unsigned LLONG);
else else
value = va_arg (args, unsigned int); value = va_arg (args, unsigned int);
total += fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags); total += fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
break; break;
case 'f': case 'f':
if (cflags == DP_C_LDOUBLE) if (cflags == DP_C_LDOUBLE)
fvalue = va_arg (args, LDOUBLE); fvalue = va_arg (args, LDOUBLE);
else else
fvalue = va_arg (args, double); fvalue = va_arg (args, double);
total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
break; break;
case 'E': case 'E':
flags |= DP_F_UP; flags |= DP_F_UP;
case 'e': case 'e':
if (cflags == DP_C_LDOUBLE) if (cflags == DP_C_LDOUBLE)
fvalue = va_arg (args, LDOUBLE); fvalue = va_arg (args, LDOUBLE);
else else
fvalue = va_arg (args, double); fvalue = va_arg (args, double);
total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
break; break;
case 'G': case 'G':
flags |= DP_F_UP; flags |= DP_F_UP;
case 'g': case 'g':
flags |= DP_F_FP_G; flags |= DP_F_FP_G;
if (cflags == DP_C_LDOUBLE) if (cflags == DP_C_LDOUBLE)
fvalue = va_arg (args, LDOUBLE); fvalue = va_arg (args, LDOUBLE);
else else
fvalue = va_arg (args, double); fvalue = va_arg (args, double);
if (max == 0) if (max == 0)
/* C99 says: if precision [for %g] is zero, it is taken as one */ /* C99 says: if precision [for %g] is zero, it is taken as one */
max = 1; max = 1;
total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
break; break;
case 'c': case 'c':
total += dopr_outch (buffer, &currlen, maxlen, va_arg (args, int)); total += dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
break; break;
case 's': case 's':
strvalue = va_arg (args, char *); strvalue = va_arg (args, char *);
total += fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max); total += fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
break; break;
case 'p': case 'p':
strvalue = va_arg (args, void *); strvalue = va_arg (args, void *);
total += fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, total += fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min,
max, flags); max, flags);
break; break;
case 'n': case 'n':
if (cflags == DP_C_SHORT) if (cflags == DP_C_SHORT)
{ {
short int *num; short int *num;
num = va_arg (args, short int *); num = va_arg (args, short int *);
*num = currlen; *num = currlen;
} }
else if (cflags == DP_C_LONG) else if (cflags == DP_C_LONG)
{ {
long int *num; long int *num;
num = va_arg (args, long int *); num = va_arg (args, long int *);
*num = currlen; *num = currlen;
} }
else if (cflags == DP_C_LLONG) else if (cflags == DP_C_LLONG)
{ {
LLONG *num; LLONG *num;
num = va_arg (args, LLONG *); num = va_arg (args, LLONG *);
*num = currlen; *num = currlen;
} }
else else
{ {
int *num; int *num;
num = va_arg (args, int *); num = va_arg (args, int *);
*num = currlen; *num = currlen;
} }
break; break;
case '%': case '%':
total += dopr_outch (buffer, &currlen, maxlen, ch); total += dopr_outch (buffer, &currlen, maxlen, ch);
break; break;
case 'w': case 'w':
/* not supported yet, treat as next char */ /* not supported yet, treat as next char */
ch = *format++; ch = *format++;
break; break;
default: default:
/* Unknown, skip */ /* Unknown, skip */
break; break;
} }
ch = *format++; ch = *format++;
state = DP_S_DEFAULT; state = DP_S_DEFAULT;
@ -469,7 +469,7 @@ static int dopr (char *buffer, size_t maxlen, const char *format, va_list args)
} }
static int fmtstr (char *buffer, size_t *currlen, size_t maxlen, static int fmtstr (char *buffer, size_t *currlen, size_t maxlen,
const char *value, int flags, int min, int max) const char *value, int flags, int min, int max)
{ {
int padlen, strln; /* amount to pad */ int padlen, strln; /* amount to pad */
int cnt = 0; int cnt = 0;
@ -514,7 +514,7 @@ static int fmtstr (char *buffer, size_t *currlen, size_t maxlen,
/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
static int fmtint (char *buffer, size_t *currlen, size_t maxlen, static int fmtint (char *buffer, size_t *currlen, size_t maxlen,
LLONG value, int base, int min, int max, int flags) LLONG value, int base, int min, int max, int flags)
{ {
int signvalue = 0; int signvalue = 0;
unsigned LLONG uvalue; unsigned LLONG uvalue;
@ -538,10 +538,10 @@ static int fmtint (char *buffer, size_t *currlen, size_t maxlen,
} }
else else
if (flags & DP_F_PLUS) /* Do a sign (+/i) */ if (flags & DP_F_PLUS) /* Do a sign (+/i) */
signvalue = '+'; signvalue = '+';
else else
if (flags & DP_F_SPACE) if (flags & DP_F_SPACE)
signvalue = ' '; signvalue = ' ';
} }
if (flags & DP_F_UP) if (flags & DP_F_UP)
@ -644,7 +644,7 @@ static LLONG round_int (LDOUBLE value)
} }
static int fmtfp (char *buffer, size_t *currlen, size_t maxlen, static int fmtfp (char *buffer, size_t *currlen, size_t maxlen,
LDOUBLE fvalue, int min, int max, int flags) LDOUBLE fvalue, int min, int max, int flags)
{ {
int signvalue = 0; int signvalue = 0;
LDOUBLE ufvalue; LDOUBLE ufvalue;
@ -678,7 +678,7 @@ static int fmtfp (char *buffer, size_t *currlen, size_t maxlen,
signvalue = '+'; signvalue = '+';
else else
if (flags & DP_F_SPACE) if (flags & DP_F_SPACE)
signvalue = ' '; signvalue = ' ';
#if 0 #if 0
if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
@ -691,23 +691,23 @@ static int fmtfp (char *buffer, size_t *currlen, size_t maxlen,
if (flags & DP_F_FP_G) if (flags & DP_F_FP_G)
{ {
if (intpart != 0) if (intpart != 0)
{ {
/* For each digit of INTPART, print one less fractional digit. */ /* For each digit of INTPART, print one less fractional digit. */
LLONG temp = intpart; LLONG temp = intpart;
for (temp = intpart; temp != 0; temp /= 10) for (temp = intpart; temp != 0; temp /= 10)
--max; --max;
if (max < 0) if (max < 0)
max = 0; max = 0;
} }
else else
{ {
/* For each leading 0 in fractional part, print one more /* For each leading 0 in fractional part, print one more
fractional digit. */ fractional digit. */
LDOUBLE temp; LDOUBLE temp;
if (ufvalue != 0) if (ufvalue != 0)
for (temp = ufvalue; temp < 0.1; temp *= 10) for (temp = ufvalue; temp < 0.1; temp *= 10)
++max; ++max;
} }
} }
/* C99: trailing zeros are removed from the fractional portion of the /* C99: trailing zeros are removed from the fractional portion of the
@ -716,9 +716,9 @@ static int fmtfp (char *buffer, size_t *currlen, size_t maxlen,
omitzeros = 1; omitzeros = 1;
#if SIZEOF_LONG_LONG > 0 #if SIZEOF_LONG_LONG > 0
# define MAX_DIGITS 18 /* grok more digits with long long */ # define MAX_DIGITS 18 /* grok more digits with long long */
#else #else
# define MAX_DIGITS 9 /* just long */ # define MAX_DIGITS 9 /* just long */
#endif #endif
/* /*
@ -747,8 +747,8 @@ static int fmtfp (char *buffer, size_t *currlen, size_t maxlen,
requires one leading zero to distinguish it from 2.1. */ requires one leading zero to distinguish it from 2.1. */
while (fracpart < mask10 / 10) while (fracpart < mask10 / 10)
{ {
++leadingfrac0s; ++leadingfrac0s;
mask10 /= 10; mask10 /= 10;
} }
#ifdef DEBUG_SNPRINTF #ifdef DEBUG_SNPRINTF
@ -915,8 +915,8 @@ int main (void)
NULL NULL
}; };
double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
0.9996, 1.996, 4.136, 0.00205, 0.0001, 321.000009, 0.9996, 1.996, 4.136, 0.00205, 0.0001, 321.000009,
0}; 0};
char *int_fmt[] = { char *int_fmt[] = {
"%-1.5d", "%-1.5d",
"%1.5d", "%1.5d",
@ -932,20 +932,20 @@ int main (void)
long int_nums[] = { -1, 134, 91340, 341, 0203, 0}; long int_nums[] = { -1, 134, 91340, 341, 0203, 0};
#if SIZEOF_LONG_LONG != 0 #if SIZEOF_LONG_LONG != 0
char *llong_fmt[] = { char *llong_fmt[] = {
"%lld", "%llu", "%lld", "%llu",
"%-1.5lld", "%-1.5llu", "%-1.5lld", "%-1.5llu",
"%1.5lld", "%1.5llu", "%1.5lld", "%1.5llu",
"%123.9lld", "%123.9llu", "%123.9lld", "%123.9llu",
"%5.5lld", "%5.5llu", "%5.5lld", "%5.5llu",
"%10.5lld", "%10.5llu", "%10.5lld", "%10.5llu",
"% 10.5lld", "% 10.5llu", "% 10.5lld", "% 10.5llu",
"%+22.33lld", "%+22.33llu", "%+22.33lld", "%+22.33llu",
"%01.3lld", "%01.3llu", "%01.3lld", "%01.3llu",
"%4lld", "%4llu", "%4lld", "%4llu",
NULL NULL
}; };
long long llong_nums[] = { long long llong_nums[] = {
~(long long)0, /* all-1 bit pattern */ ~(long long)0, /* all-1 bit pattern */
(~(unsigned long long)0) >> 1, /* largest signed long long */ (~(unsigned long long)0) >> 1, /* largest signed long long */
/* random... */ /* random... */
-150, 134, 91340, 341, -150, 134, 91340, 341,
@ -965,9 +965,9 @@ int main (void)
sprintf (buf2, fp_fmt[x], fp_nums[y]); sprintf (buf2, fp_fmt[x], fp_nums[y]);
if (strcmp (buf1, buf2)) if (strcmp (buf1, buf2))
{ {
printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
fp_fmt[x], buf1, buf2); fp_fmt[x], buf1, buf2);
fail++; fail++;
} }
num++; num++;
} }
@ -979,9 +979,9 @@ int main (void)
sprintf (buf2, int_fmt[x], int_nums[y]); sprintf (buf2, int_fmt[x], int_nums[y]);
if (strcmp (buf1, buf2)) if (strcmp (buf1, buf2))
{ {
printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
int_fmt[x], buf1, buf2); int_fmt[x], buf1, buf2);
fail++; fail++;
} }
num++; num++;
} }
@ -994,9 +994,9 @@ int main (void)
sprintf (buf2, llong_fmt[x], llong_nums[y]); sprintf (buf2, llong_fmt[x], llong_nums[y]);
if (strcmp (buf1, buf2)) if (strcmp (buf1, buf2))
{ {
printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
llong_fmt[x], buf1, buf2); llong_fmt[x], buf1, buf2);
fail++; fail++;
} }
num++; num++;
} }

View File

@ -125,18 +125,18 @@ sepstring (const char *s)
while (*s) while (*s)
{ {
if (*s == ',') if (*s == ',')
{ {
res = xrealloc (res, (i + 2) * sizeof (char *)); res = xrealloc (res, (i + 2) * sizeof (char *));
res[i] = strdupdelim (p, s); res[i] = strdupdelim (p, s);
res[++i] = NULL; res[++i] = NULL;
++s; ++s;
/* Skip the blanks following the ','. */ /* Skip the blanks following the ','. */
while (ISSPACE (*s)) while (ISSPACE (*s))
++s; ++s;
p = s; p = s;
} }
else else
++s; ++s;
} }
res = xrealloc (res, (i + 2) * sizeof (char *)); res = xrealloc (res, (i + 2) * sizeof (char *));
res[i] = strdupdelim (p, s); res[i] = strdupdelim (p, s);
@ -167,7 +167,7 @@ aprintf (const char *fmt, ...)
ret = vasprintf (&str, fmt, args); ret = vasprintf (&str, fmt, args);
va_end (args); va_end (args);
if (ret < 0 && errno == ENOMEM) if (ret < 0 && errno == ENOMEM)
abort (); /* for consistency with xmalloc/xrealloc */ abort (); /* for consistency with xmalloc/xrealloc */
else if (ret < 0) else if (ret < 0)
return NULL; return NULL;
return str; return str;
@ -192,13 +192,13 @@ aprintf (const char *fmt, ...)
/* If the printing worked, return the string. */ /* If the printing worked, return the string. */
if (n > -1 && n < size) if (n > -1 && n < size)
return str; return str;
/* Else try again with a larger buffer. */ /* Else try again with a larger buffer. */
if (n > -1) /* C99 */ if (n > -1) /* C99 */
size = n + 1; /* precisely what is needed */ size = n + 1; /* precisely what is needed */
else else
size <<= 1; /* twice the old size */ size <<= 1; /* twice the old size */
str = xrealloc (str, size); str = xrealloc (str, size);
} }
#endif /* not HAVE_VASPRINTF */ #endif /* not HAVE_VASPRINTF */
@ -211,7 +211,7 @@ char *
concat_strings (const char *str0, ...) concat_strings (const char *str0, ...)
{ {
va_list args; va_list args;
int saved_lengths[5]; /* inspired by Apache's apr_pstrcat */ int saved_lengths[5]; /* inspired by Apache's apr_pstrcat */
char *ret, *p; char *ret, *p;
const char *next_str; const char *next_str;
@ -226,7 +226,7 @@ concat_strings (const char *str0, ...)
{ {
int len = strlen (next_str); int len = strlen (next_str);
if (argcount < countof (saved_lengths)) if (argcount < countof (saved_lengths))
saved_lengths[argcount++] = len; saved_lengths[argcount++] = len;
total_length += len; total_length += len;
} }
va_end (args); va_end (args);
@ -240,9 +240,9 @@ concat_strings (const char *str0, ...)
{ {
int len; int len;
if (argcount < countof (saved_lengths)) if (argcount < countof (saved_lengths))
len = saved_lengths[argcount++]; len = saved_lengths[argcount++];
else else
len = strlen (next_str); len = strlen (next_str);
memcpy (p, next_str, len); memcpy (p, next_str, len);
p += len; p += len;
} }
@ -300,16 +300,16 @@ fork_to_background (void)
if (!opt.lfilename) if (!opt.lfilename)
{ {
/* We must create the file immediately to avoid either a race /* We must create the file immediately to avoid either a race
condition (which arises from using unique_name and failing to condition (which arises from using unique_name and failing to
use fopen_excl) or lying to the user about the log file name use fopen_excl) or lying to the user about the log file name
(which arises from using unique_name, printing the name, and (which arises from using unique_name, printing the name, and
using fopen_excl later on.) */ using fopen_excl later on.) */
FILE *new_log_fp = unique_create (DEFAULT_LOGFILE, false, &opt.lfilename); FILE *new_log_fp = unique_create (DEFAULT_LOGFILE, false, &opt.lfilename);
if (new_log_fp) if (new_log_fp)
{ {
logfile_changed = true; logfile_changed = true;
fclose (new_log_fp); fclose (new_log_fp);
} }
} }
pid = fork (); pid = fork ();
if (pid < 0) if (pid < 0)
@ -323,8 +323,8 @@ fork_to_background (void)
/* parent, no error */ /* parent, no error */
printf (_("Continuing in background, pid %d.\n"), (int) pid); printf (_("Continuing in background, pid %d.\n"), (int) pid);
if (logfile_changed) if (logfile_changed)
printf (_("Output will be written to `%s'.\n"), opt.lfilename); printf (_("Output will be written to `%s'.\n"), opt.lfilename);
exit (0); /* #### should we use _exit()? */ exit (0); /* #### should we use _exit()? */
} }
/* child: give up the privileges and keep running. */ /* child: give up the privileges and keep running. */
@ -369,8 +369,8 @@ remove_link (const char *file)
DEBUGP (("Unlinking %s (symlink).\n", file)); DEBUGP (("Unlinking %s (symlink).\n", file));
err = unlink (file); err = unlink (file);
if (err != 0) if (err != 0)
logprintf (LOG_VERBOSE, _("Failed to unlink symlink `%s': %s\n"), logprintf (LOG_VERBOSE, _("Failed to unlink symlink `%s': %s\n"),
file, strerror (errno)); file, strerror (errno));
} }
return err; return err;
} }
@ -502,12 +502,12 @@ unique_create (const char *name, bool binary, char **opened_name)
if (opened_name && fp != NULL) if (opened_name && fp != NULL)
{ {
if (fp) if (fp)
*opened_name = uname; *opened_name = uname;
else else
{ {
*opened_name = NULL; *opened_name = NULL;
xfree (uname); xfree (uname);
} }
} }
else else
xfree (uname); xfree (uname);
@ -572,21 +572,21 @@ make_directory (const char *directory)
for (i = (*dir == '/'); 1; ++i) for (i = (*dir == '/'); 1; ++i)
{ {
for (; dir[i] && dir[i] != '/'; i++) for (; dir[i] && dir[i] != '/'; i++)
; ;
if (!dir[i]) if (!dir[i])
quit = 1; quit = 1;
dir[i] = '\0'; dir[i] = '\0';
/* Check whether the directory already exists. Allow creation of /* Check whether the directory already exists. Allow creation of
of intermediate directories to fail, as the initial path components of intermediate directories to fail, as the initial path components
are not necessarily directories! */ are not necessarily directories! */
if (!file_exists_p (dir)) if (!file_exists_p (dir))
ret = mkdir (dir, 0777); ret = mkdir (dir, 0777);
else else
ret = 0; ret = 0;
if (quit) if (quit)
break; break;
else else
dir[i] = '/'; dir[i] = '/';
} }
return ret; return ret;
} }
@ -657,10 +657,10 @@ acceptable (const char *s)
if (opt.accepts) if (opt.accepts)
{ {
if (opt.rejects) if (opt.rejects)
return (in_acclist ((const char *const *)opt.accepts, s, true) return (in_acclist ((const char *const *)opt.accepts, s, true)
&& !in_acclist ((const char *const *)opt.rejects, s, true)); && !in_acclist ((const char *const *)opt.rejects, s, true));
else else
return in_acclist ((const char *const *)opt.accepts, s, true); return in_acclist ((const char *const *)opt.accepts, s, true);
} }
else if (opt.rejects) else if (opt.rejects)
return !in_acclist ((const char *const *)opt.rejects, s, true); return !in_acclist ((const char *const *)opt.rejects, s, true);
@ -698,15 +698,15 @@ dir_matches_p (char **dirlist, const char *dir)
/* Remove leading '/' */ /* Remove leading '/' */
char *p = *x + (**x == '/'); char *p = *x + (**x == '/');
if (has_wildcards_p (p)) if (has_wildcards_p (p))
{ {
if (matcher (p, dir, FNM_PATHNAME) == 0) if (matcher (p, dir, FNM_PATHNAME) == 0)
break; break;
} }
else else
{ {
if (subdir_p (p, dir)) if (subdir_p (p, dir))
break; break;
} }
} }
return *x ? true : false; return *x ? true : false;
@ -727,12 +727,12 @@ accdir (const char *directory)
if (opt.includes) if (opt.includes)
{ {
if (!dir_matches_p (opt.includes, directory)) if (!dir_matches_p (opt.includes, directory))
return false; return false;
} }
if (opt.excludes) if (opt.excludes)
{ {
if (dir_matches_p (opt.excludes, directory)) if (dir_matches_p (opt.excludes, directory))
return false; return false;
} }
return true; return true;
} }
@ -756,14 +756,14 @@ match_tail (const char *string, const char *tail, bool fold_case)
if (!fold_case) if (!fold_case)
{ {
for (i = strlen (string), j = strlen (tail); i >= 0 && j >= 0; i--, j--) for (i = strlen (string), j = strlen (tail); i >= 0 && j >= 0; i--, j--)
if (string[i] != tail[j]) if (string[i] != tail[j])
break; break;
} }
else else
{ {
for (i = strlen (string), j = strlen (tail); i >= 0 && j >= 0; i--, j--) for (i = strlen (string), j = strlen (tail); i >= 0 && j >= 0; i--, j--)
if (TOLOWER (string[i]) != TOLOWER (tail[j])) if (TOLOWER (string[i]) != TOLOWER (tail[j]))
break; break;
} }
/* If the tail was exhausted, the match was succesful. */ /* If the tail was exhausted, the match was succesful. */
@ -785,28 +785,28 @@ in_acclist (const char *const *accepts, const char *s, bool backward)
for (; *accepts; accepts++) for (; *accepts; accepts++)
{ {
if (has_wildcards_p (*accepts)) if (has_wildcards_p (*accepts))
{ {
int res = opt.ignore_case int res = opt.ignore_case
? fnmatch_nocase (*accepts, s, 0) : fnmatch (*accepts, s, 0); ? fnmatch_nocase (*accepts, s, 0) : fnmatch (*accepts, s, 0);
/* fnmatch returns 0 if the pattern *does* match the string. */ /* fnmatch returns 0 if the pattern *does* match the string. */
if (res == 0) if (res == 0)
return true; return true;
} }
else else
{ {
if (backward) if (backward)
{ {
if (match_tail (s, *accepts, opt.ignore_case)) if (match_tail (s, *accepts, opt.ignore_case))
return true; return true;
} }
else else
{ {
int cmp = opt.ignore_case int cmp = opt.ignore_case
? strcasecmp (s, *accepts) : strcmp (s, *accepts); ? strcasecmp (s, *accepts) : strcmp (s, *accepts);
if (cmp == 0) if (cmp == 0)
return true; return true;
} }
} }
} }
return false; return false;
} }
@ -891,12 +891,12 @@ read_whole_line (FILE *fp)
{ {
length += strlen (line + length); length += strlen (line + length);
if (length == 0) if (length == 0)
/* Possible for example when reading from a binary file where /* Possible for example when reading from a binary file where
a line begins with \0. */ a line begins with \0. */
continue; continue;
if (line[length - 1] == '\n') if (line[length - 1] == '\n')
break; break;
/* fgets() guarantees to read the whole line, or to use up the /* fgets() guarantees to read the whole line, or to use up the
space we've given it. We can double the buffer space we've given it. We can double the buffer
@ -968,7 +968,7 @@ read_file (const char *file)
specify PROT_READ and MAP_SHARED for a marginal gain in specify PROT_READ and MAP_SHARED for a marginal gain in
efficiency, but at some cost to generality. */ efficiency, but at some cost to generality. */
fm->content = mmap (NULL, fm->length, PROT_READ | PROT_WRITE, fm->content = mmap (NULL, fm->length, PROT_READ | PROT_WRITE,
MAP_PRIVATE, fd, 0); MAP_PRIVATE, fd, 0);
if (fm->content == (char *)MAP_FAILED) if (fm->content == (char *)MAP_FAILED)
goto mmap_lose; goto mmap_lose;
if (!inhibit_close) if (!inhibit_close)
@ -986,41 +986,41 @@ read_file (const char *file)
#endif /* HAVE_MMAP */ #endif /* HAVE_MMAP */
fm->length = 0; fm->length = 0;
size = 512; /* number of bytes fm->contents can size = 512; /* number of bytes fm->contents can
hold at any given time. */ hold at any given time. */
fm->content = xmalloc (size); fm->content = xmalloc (size);
while (1) while (1)
{ {
wgint nread; wgint nread;
if (fm->length > size / 2) if (fm->length > size / 2)
{ {
/* #### I'm not sure whether the whole exponential-growth /* #### I'm not sure whether the whole exponential-growth
thing makes sense with kernel read. On Linux at least, thing makes sense with kernel read. On Linux at least,
read() refuses to read more than 4K from a file at a read() refuses to read more than 4K from a file at a
single chunk anyway. But other Unixes might optimize it single chunk anyway. But other Unixes might optimize it
better, and it doesn't *hurt* anything, so I'm leaving better, and it doesn't *hurt* anything, so I'm leaving
it. */ it. */
/* Normally, we grow SIZE exponentially to make the number /* Normally, we grow SIZE exponentially to make the number
of calls to read() and realloc() logarithmic in relation of calls to read() and realloc() logarithmic in relation
to file size. However, read() can read an amount of data to file size. However, read() can read an amount of data
smaller than requested, and it would be unreasonable to smaller than requested, and it would be unreasonable to
double SIZE every time *something* was read. Therefore, double SIZE every time *something* was read. Therefore,
we double SIZE only when the length exceeds half of the we double SIZE only when the length exceeds half of the
entire allocated size. */ entire allocated size. */
size <<= 1; size <<= 1;
fm->content = xrealloc (fm->content, size); fm->content = xrealloc (fm->content, size);
} }
nread = read (fd, fm->content + fm->length, size - fm->length); nread = read (fd, fm->content + fm->length, size - fm->length);
if (nread > 0) if (nread > 0)
/* Successful read. */ /* Successful read. */
fm->length += nread; fm->length += nread;
else if (nread < 0) else if (nread < 0)
/* Error. */ /* Error. */
goto lose; goto lose;
else else
/* EOF */ /* EOF */
break; break;
} }
if (!inhibit_close) if (!inhibit_close)
close (fd); close (fd);
@ -1069,7 +1069,7 @@ free_vec (char **vec)
{ {
char **p = vec; char **p = vec;
while (*p) while (*p)
xfree (*p++); xfree (*p++);
xfree (vec); xfree (vec);
} }
} }
@ -1111,12 +1111,12 @@ merge_vecs (char **v1, char **v2)
char ** char **
vec_append (char **vec, const char *str) vec_append (char **vec, const char *str)
{ {
int cnt; /* count of vector elements, including int cnt; /* count of vector elements, including
the one we're about to append */ the one we're about to append */
if (vec != NULL) if (vec != NULL)
{ {
for (cnt = 0; vec[cnt]; cnt++) for (cnt = 0; vec[cnt]; cnt++)
; ;
++cnt; ++cnt;
} }
else else
@ -1216,18 +1216,18 @@ get_grouping_data (const char **sep, const char **grouping)
cached_sep = lconv->thousands_sep; cached_sep = lconv->thousands_sep;
cached_grouping = lconv->grouping; cached_grouping = lconv->grouping;
if (!*cached_sep) if (!*cached_sep)
{ {
/* Many locales (such as "C" or "hr_HR") don't specify /* Many locales (such as "C" or "hr_HR") don't specify
grouping, which we still want to use it for legibility. grouping, which we still want to use it for legibility.
In those locales set the sep char to ',', unless that In those locales set the sep char to ',', unless that
character is used for decimal point, in which case set it character is used for decimal point, in which case set it
to ".". */ to ".". */
if (*lconv->decimal_point != ',') if (*lconv->decimal_point != ',')
cached_sep = ","; cached_sep = ",";
else else
cached_sep = "."; cached_sep = ".";
cached_grouping = "\x03"; cached_grouping = "\x03";
} }
initialized = true; initialized = true;
} }
*sep = cached_sep; *sep = cached_sep;
@ -1278,18 +1278,18 @@ with_thousand_seps (wgint n)
*--p = n % 10 + '0'; *--p = n % 10 + '0';
n /= 10; n /= 10;
if (n == 0) if (n == 0)
break; break;
/* Prepend SEP to every groupsize'd digit and get new groupsize. */ /* Prepend SEP to every groupsize'd digit and get new groupsize. */
if (++i == groupsize) if (++i == groupsize)
{ {
if (seplen == 1) if (seplen == 1)
*--p = *sep; *--p = *sep;
else else
memcpy (p -= seplen, sep, seplen); memcpy (p -= seplen, sep, seplen);
i = 0; i = 0;
if (*atgroup) if (*atgroup)
groupsize = *atgroup++; groupsize = *atgroup++;
} }
} }
if (negative) if (negative)
*--p = '-'; *--p = '-';
@ -1319,12 +1319,12 @@ human_readable (HR_NUMTYPE n)
/* These suffixes are compatible with those of GNU `ls -lh'. */ /* These suffixes are compatible with those of GNU `ls -lh'. */
static char powers[] = static char powers[] =
{ {
'K', /* kilobyte, 2^10 bytes */ 'K', /* kilobyte, 2^10 bytes */
'M', /* megabyte, 2^20 bytes */ 'M', /* megabyte, 2^20 bytes */
'G', /* gigabyte, 2^30 bytes */ 'G', /* gigabyte, 2^30 bytes */
'T', /* terabyte, 2^40 bytes */ 'T', /* terabyte, 2^40 bytes */
'P', /* petabyte, 2^50 bytes */ 'P', /* petabyte, 2^50 bytes */
'E', /* exabyte, 2^60 bytes */ 'E', /* exabyte, 2^60 bytes */
}; };
static char buf[8]; static char buf[8];
int i; int i;
@ -1342,20 +1342,20 @@ human_readable (HR_NUMTYPE n)
for (i = 0; i < countof (powers); i++) for (i = 0; i < countof (powers); i++)
{ {
/* At each iteration N is greater than the *subsequent* power. /* At each iteration N is greater than the *subsequent* power.
That way N/1024.0 produces a decimal number in the units of That way N/1024.0 produces a decimal number in the units of
*this* power. */ *this* power. */
if ((n / 1024) < 1024 || i == countof (powers) - 1) if ((n / 1024) < 1024 || i == countof (powers) - 1)
{ {
double val = n / 1024.0; double val = n / 1024.0;
/* Print values smaller than 10 with one decimal digits, and /* Print values smaller than 10 with one decimal digits, and
others without any decimals. */ others without any decimals. */
snprintf (buf, sizeof (buf), "%.*f%c", snprintf (buf, sizeof (buf), "%.*f%c",
val < 10 ? 1 : 0, val, powers[i]); val < 10 ? 1 : 0, val, powers[i]);
return buf; return buf;
} }
n /= 1024; n /= 1024;
} }
return NULL; /* unreached */ return NULL; /* unreached */
} }
/* Count the digits in the provided number. Used to allocate space /* Count the digits in the provided number. Used to allocate space
@ -1366,7 +1366,7 @@ numdigit (wgint number)
{ {
int cnt = 1; int cnt = 1;
if (number < 0) if (number < 0)
++cnt; /* accomodate '-' */ ++cnt; /* accomodate '-' */
while ((number /= 10) != 0) while ((number /= 10) != 0)
++cnt; ++cnt;
return cnt; return cnt;
@ -1441,8 +1441,8 @@ number_to_string (char *buffer, wgint number)
if (n < 0) if (n < 0)
{ {
if (n < -WGINT_MAX) if (n < -WGINT_MAX)
{ {
/* n = -n would overflow because -n would evaluate to a /* n = -n would overflow because -n would evaluate to a
wgint value larger than WGINT_MAX. Need to make n wgint value larger than WGINT_MAX. Need to make n
smaller and handle the last digit separately. */ smaller and handle the last digit separately. */
int last_digit = n % 10; int last_digit = n % 10;
@ -1453,7 +1453,7 @@ number_to_string (char *buffer, wgint number)
last_digit_char = '0' + last_digit; last_digit_char = '0' + last_digit;
/* After n is made smaller, -n will not overflow. */ /* After n is made smaller, -n will not overflow. */
n /= 10; n /= 10;
} }
*p++ = '-'; *p++ = '-';
n = -n; n = -n;
@ -1585,7 +1585,7 @@ determine_screen_width (void)
fd = fileno (stderr); fd = fileno (stderr);
if (ioctl (fd, TIOCGWINSZ, &wsz) < 0) if (ioctl (fd, TIOCGWINSZ, &wsz) < 0)
return 0; /* most likely ENOTTY */ return 0; /* most likely ENOTTY */
return wsz.ws_col; return wsz.ws_col;
#elif defined(WINDOWS) #elif defined(WINDOWS)
@ -1661,9 +1661,9 @@ random_float (void)
return drand48 (); return drand48 ();
#else /* not HAVE_DRAND48 */ #else /* not HAVE_DRAND48 */
return ( random_number (10000) / 10000.0 return ( random_number (10000) / 10000.0
+ random_number (10000) / (10000.0 * 10000.0) + random_number (10000) / (10000.0 * 10000.0)
+ random_number (10000) / (10000.0 * 10000.0 * 10000.0) + random_number (10000) / (10000.0 * 10000.0 * 10000.0)
+ random_number (10000) / (10000.0 * 10000.0 * 10000.0 * 10000.0)); + random_number (10000) / (10000.0 * 10000.0 * 10000.0 * 10000.0));
#endif /* not HAVE_DRAND48 */ #endif /* not HAVE_DRAND48 */
} }
@ -1851,8 +1851,8 @@ xsleep (double seconds)
if (seconds >= 1) if (seconds >= 1)
{ {
/* On some systems, usleep cannot handle values larger than /* On some systems, usleep cannot handle values larger than
1,000,000. If the period is larger than that, use sleep 1,000,000. If the period is larger than that, use sleep
first, then add usleep for subsecond accuracy. */ first, then add usleep for subsecond accuracy. */
sleep (seconds); sleep (seconds);
seconds -= (long) seconds; seconds -= (long) seconds;
} }
@ -1934,8 +1934,8 @@ base64_encode (const void *data, int length, char *dest)
/* Store in C the next non-whitespace character from the string, or \0 /* Store in C the next non-whitespace character from the string, or \0
when end of string is reached. */ when end of string is reached. */
#define NEXT_CHAR(c, p) do { \ #define NEXT_CHAR(c, p) do { \
c = (unsigned char) *p++; \ c = (unsigned char) *p++; \
} while (ISSPACE (c)) } while (ISSPACE (c))
#define IS_ASCII(c) (((c) & 0x80) == 0) #define IS_ASCII(c) (((c) & 0x80) == 0)
@ -1959,19 +1959,19 @@ base64_decode (const char *base64, void *dest)
assumes ASCII (but so does Wget in other places). */ assumes ASCII (but so does Wget in other places). */
static const signed char base64_char_to_value[128] = static const signed char base64_char_to_value[128] =
{ {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0- 9 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0- 9 */
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 10- 19 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 10- 19 */
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 20- 29 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 20- 29 */
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 30- 39 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 30- 39 */
-1, -1, -1, 62, -1, -1, -1, 63, 52, 53, /* 40- 49 */ -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, /* 40- 49 */
54, 55, 56, 57, 58, 59, 60, 61, -1, -1, /* 50- 59 */ 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, /* 50- 59 */
-1, -1, -1, -1, -1, 0, 1, 2, 3, 4, /* 60- 69 */ -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, /* 60- 69 */
5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 70- 79 */ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 70- 79 */
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, /* 80- 89 */ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, /* 80- 89 */
25, -1, -1, -1, -1, -1, -1, 26, 27, 28, /* 90- 99 */ 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, /* 90- 99 */
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, /* 100-109 */ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, /* 100-109 */
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, /* 110-119 */ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, /* 110-119 */
49, 50, 51, -1, -1, -1, -1, -1 /* 120-127 */ 49, 50, 51, -1, -1, -1, -1, -1 /* 120-127 */
}; };
#define BASE64_CHAR_TO_VALUE(c) ((int) base64_char_to_value[c]) #define BASE64_CHAR_TO_VALUE(c) ((int) base64_char_to_value[c])
#define IS_BASE64(c) ((IS_ASCII (c) && BASE64_CHAR_TO_VALUE (c) >= 0) || c == '=') #define IS_BASE64(c) ((IS_ASCII (c) && BASE64_CHAR_TO_VALUE (c) >= 0) || c == '=')
@ -1987,36 +1987,36 @@ base64_decode (const char *base64, void *dest)
/* Process first byte of a quadruplet. */ /* Process first byte of a quadruplet. */
NEXT_CHAR (c, p); NEXT_CHAR (c, p);
if (!c) if (!c)
break; break;
if (c == '=' || !IS_BASE64 (c)) if (c == '=' || !IS_BASE64 (c))
return -1; /* illegal char while decoding base64 */ return -1; /* illegal char while decoding base64 */
value = BASE64_CHAR_TO_VALUE (c) << 18; value = BASE64_CHAR_TO_VALUE (c) << 18;
/* Process second byte of a quadruplet. */ /* Process second byte of a quadruplet. */
NEXT_CHAR (c, p); NEXT_CHAR (c, p);
if (!c) if (!c)
return -1; /* premature EOF while decoding base64 */ return -1; /* premature EOF while decoding base64 */
if (c == '=' || !IS_BASE64 (c)) if (c == '=' || !IS_BASE64 (c))
return -1; /* illegal char while decoding base64 */ return -1; /* illegal char while decoding base64 */
value |= BASE64_CHAR_TO_VALUE (c) << 12; value |= BASE64_CHAR_TO_VALUE (c) << 12;
*q++ = value >> 16; *q++ = value >> 16;
/* Process third byte of a quadruplet. */ /* Process third byte of a quadruplet. */
NEXT_CHAR (c, p); NEXT_CHAR (c, p);
if (!c) if (!c)
return -1; /* premature EOF while decoding base64 */ return -1; /* premature EOF while decoding base64 */
if (!IS_BASE64 (c)) if (!IS_BASE64 (c))
return -1; /* illegal char while decoding base64 */ return -1; /* illegal char while decoding base64 */
if (c == '=') if (c == '=')
{ {
NEXT_CHAR (c, p); NEXT_CHAR (c, p);
if (!c) if (!c)
return -1; /* premature EOF while decoding base64 */ return -1; /* premature EOF while decoding base64 */
if (c != '=') if (c != '=')
return -1; /* padding `=' expected but not found */ return -1; /* padding `=' expected but not found */
continue; continue;
} }
value |= BASE64_CHAR_TO_VALUE (c) << 6; value |= BASE64_CHAR_TO_VALUE (c) << 6;
*q++ = 0xff & value >> 8; *q++ = 0xff & value >> 8;
@ -2024,11 +2024,11 @@ base64_decode (const char *base64, void *dest)
/* Process fourth byte of a quadruplet. */ /* Process fourth byte of a quadruplet. */
NEXT_CHAR (c, p); NEXT_CHAR (c, p);
if (!c) if (!c)
return -1; /* premature EOF while decoding base64 */ return -1; /* premature EOF while decoding base64 */
if (c == '=') if (c == '=')
continue; continue;
if (!IS_BASE64 (c)) if (!IS_BASE64 (c))
return -1; /* illegal char while decoding base64 */ return -1; /* illegal char while decoding base64 */
value |= BASE64_CHAR_TO_VALUE (c); value |= BASE64_CHAR_TO_VALUE (c);
*q++ = 0xff & value; *q++ = 0xff & value;
@ -2047,7 +2047,7 @@ base64_decode (const char *base64, void *dest)
static void static void
mergesort_internal (void *base, void *temp, size_t size, size_t from, size_t to, mergesort_internal (void *base, void *temp, size_t size, size_t from, size_t to,
int (*cmpfun) (const void *, const void *)) int (*cmpfun) (const void *, const void *))
{ {
#define ELT(array, pos) ((char *)(array) + (pos) * size) #define ELT(array, pos) ((char *)(array) + (pos) * size)
if (from < to) if (from < to)
@ -2059,16 +2059,16 @@ mergesort_internal (void *base, void *temp, size_t size, size_t from, size_t to,
i = from; i = from;
j = mid + 1; j = mid + 1;
for (k = from; (i <= mid) && (j <= to); k++) for (k = from; (i <= mid) && (j <= to); k++)
if (cmpfun (ELT (base, i), ELT (base, j)) <= 0) if (cmpfun (ELT (base, i), ELT (base, j)) <= 0)
memcpy (ELT (temp, k), ELT (base, i++), size); memcpy (ELT (temp, k), ELT (base, i++), size);
else else
memcpy (ELT (temp, k), ELT (base, j++), size); memcpy (ELT (temp, k), ELT (base, j++), size);
while (i <= mid) while (i <= mid)
memcpy (ELT (temp, k++), ELT (base, i++), size); memcpy (ELT (temp, k++), ELT (base, i++), size);
while (j <= to) while (j <= to)
memcpy (ELT (temp, k++), ELT (base, j++), size); memcpy (ELT (temp, k++), ELT (base, j++), size);
for (k = from; k <= to; k++) for (k = from; k <= to; k++)
memcpy (ELT (base, k), ELT (temp, k), size); memcpy (ELT (base, k), ELT (temp, k), size);
} }
#undef ELT #undef ELT
} }
@ -2079,7 +2079,7 @@ mergesort_internal (void *base, void *temp, size_t size, size_t from, size_t to,
void void
stable_sort (void *base, size_t nmemb, size_t size, stable_sort (void *base, size_t nmemb, size_t size,
int (*cmpfun) (const void *, const void *)) int (*cmpfun) (const void *, const void *))
{ {
if (size > 1) if (size > 1)
{ {

View File

@ -36,7 +36,7 @@ so, delete this exception statement from your version. */
#include "wget.h" #include "wget.h"
#include "xmalloc.h" #include "xmalloc.h"
#include "hash.h" /* for hash_pointer */ #include "hash.h" /* for hash_pointer */
/* This file implements several wrappers around the basic allocation /* This file implements several wrappers around the basic allocation
routines. This is done for two reasons: first, so that the callers routines. This is done for two reasons: first, so that the callers
@ -59,8 +59,8 @@ memfatal (const char *context, long attempted_size)
call malloc. */ call malloc. */
log_set_save_context (false); log_set_save_context (false);
logprintf (LOG_ALWAYS, logprintf (LOG_ALWAYS,
_("%s: %s: Failed to allocate %ld bytes; memory exhausted.\n"), _("%s: %s: Failed to allocate %ld bytes; memory exhausted.\n"),
exec_name, context, attempted_size); exec_name, context, attempted_size);
exit (1); exit (1);
} }
@ -208,8 +208,8 @@ static int malloc_count, free_count;
/* Home-grown hash table of mallocs: */ /* Home-grown hash table of mallocs: */
#define SZ 100003 /* Prime just over 100,000. Increase #define SZ 100003 /* Prime just over 100,000. Increase
it to debug larger Wget runs. */ it to debug larger Wget runs. */
static struct { static struct {
const void *ptr; const void *ptr;
@ -269,10 +269,10 @@ unregister_ptr (void *ptr)
/* Find the new location for the key. */ /* Find the new location for the key. */
int j = hash_pointer (ptr2) % SZ; int j = hash_pointer (ptr2) % SZ;
for (; malloc_table[j].ptr != NULL; j = (j + 1) % SZ) for (; malloc_table[j].ptr != NULL; j = (j + 1) % SZ)
if (ptr2 == malloc_table[j].ptr) if (ptr2 == malloc_table[j].ptr)
/* No need to relocate entry at [i]; it's already at or near /* No need to relocate entry at [i]; it's already at or near
its hash position. */ its hash position. */
goto cont_outer; goto cont_outer;
malloc_table[j] = malloc_table[i]; malloc_table[j] = malloc_table[i];
malloc_table[i].ptr = NULL; malloc_table[i].ptr = NULL;
cont_outer: cont_outer:
@ -291,11 +291,11 @@ print_malloc_debug_stats (void)
{ {
int i; int i;
printf ("\nMalloc: %d\nFree: %d\nBalance: %d\n\n", printf ("\nMalloc: %d\nFree: %d\nBalance: %d\n\n",
malloc_count, free_count, malloc_count - free_count); malloc_count, free_count, malloc_count - free_count);
for (i = 0; i < SZ; i++) for (i = 0; i < SZ; i++)
if (malloc_table[i].ptr != NULL) if (malloc_table[i].ptr != NULL)
printf ("0x%0*lx: %s:%d\n", PTR_FORMAT (malloc_table[i].ptr), printf ("0x%0*lx: %s:%d\n", PTR_FORMAT (malloc_table[i].ptr),
malloc_table[i].file, malloc_table[i].line); malloc_table[i].file, malloc_table[i].line);
} }
void * void *
@ -351,13 +351,13 @@ debugging_free (void *ptr, const char *source_file, int source_line)
if (ptr == NULL) if (ptr == NULL)
{ {
fprintf (stderr, "%s: xfree(NULL) at %s:%d\n", fprintf (stderr, "%s: xfree(NULL) at %s:%d\n",
exec_name, source_file, source_line); exec_name, source_file, source_line);
abort (); abort ();
} }
if (!unregister_ptr (ptr)) if (!unregister_ptr (ptr))
{ {
fprintf (stderr, "%s: bad xfree(0x%0*lx) at %s:%d\n", fprintf (stderr, "%s: bad xfree(0x%0*lx) at %s:%d\n",
exec_name, PTR_FORMAT (ptr), source_file, source_line); exec_name, PTR_FORMAT (ptr), source_file, source_line);
abort (); abort ();
} }
++free_count; ++free_count;