mirror of
https://github.com/mirror/wget.git
synced 2025-02-06 09:40:24 +08:00
[svn] Make indentation consistent (all-spaces, no tabs).
This commit is contained in:
parent
2fe72be505
commit
7d2066b221
156
src/alloca.c
156
src/alloca.c
@ -74,7 +74,7 @@ typedef char *pointer;
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
/* Different portions of Emacs need to call different versions of
|
||||
@ -103,37 +103,37 @@ extern pointer malloc ();
|
||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||
|
||||
#ifndef STACK_DIRECTION
|
||||
#define STACK_DIRECTION 0 /* Direction unknown. */
|
||||
#define STACK_DIRECTION 0 /* Direction unknown. */
|
||||
#endif
|
||||
|
||||
#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. */
|
||||
|
||||
static int stack_dir; /* 1 or -1 once known. */
|
||||
#define STACK_DIR stack_dir
|
||||
static int stack_dir; /* 1 or -1 once known. */
|
||||
#define STACK_DIR stack_dir
|
||||
|
||||
static void
|
||||
find_stack_direction ()
|
||||
{
|
||||
static char *addr = NULL; /* Address of first `dummy', once known. */
|
||||
auto char dummy; /* To get stack address. */
|
||||
static char *addr = NULL; /* Address of first `dummy', once known. */
|
||||
auto char dummy; /* To get stack address. */
|
||||
|
||||
if (addr == NULL)
|
||||
{ /* Initial entry. */
|
||||
{ /* Initial entry. */
|
||||
addr = ADDRESS_FUNCTION (dummy);
|
||||
|
||||
find_stack_direction (); /* Recurse once. */
|
||||
find_stack_direction (); /* Recurse once. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Second entry. */
|
||||
if (ADDRESS_FUNCTION (dummy) > addr)
|
||||
stack_dir = 1; /* Stack grew upward. */
|
||||
stack_dir = 1; /* Stack grew upward. */
|
||||
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
|
||||
alignment chunk size. The following default should work okay. */
|
||||
|
||||
#ifndef ALIGN_SIZE
|
||||
#define ALIGN_SIZE sizeof(double)
|
||||
#ifndef ALIGN_SIZE
|
||||
#define ALIGN_SIZE sizeof(double)
|
||||
#endif
|
||||
|
||||
typedef union hdr
|
||||
{
|
||||
char align[ALIGN_SIZE]; /* To force sizeof(header). */
|
||||
char align[ALIGN_SIZE]; /* To force sizeof(header). */
|
||||
struct
|
||||
{
|
||||
union hdr *next; /* For chaining headers. */
|
||||
char *deep; /* For stack depth measure. */
|
||||
union hdr *next; /* For chaining headers. */
|
||||
char *deep; /* For stack depth measure. */
|
||||
} h;
|
||||
} 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,
|
||||
which will be automatically reclaimed upon exit from
|
||||
@ -173,11 +173,11 @@ pointer
|
||||
alloca (size)
|
||||
unsigned size;
|
||||
{
|
||||
auto char probe; /* Probes stack depth: */
|
||||
auto char probe; /* Probes stack depth: */
|
||||
register char *depth = ADDRESS_FUNCTION (probe);
|
||||
|
||||
#if STACK_DIRECTION == 0
|
||||
if (STACK_DIR == 0) /* Unknown growth direction. */
|
||||
if (STACK_DIR == 0) /* Unknown growth direction. */
|
||||
find_stack_direction ();
|
||||
#endif
|
||||
|
||||
@ -185,7 +185,7 @@ alloca (size)
|
||||
was allocated from deeper in the stack than currently. */
|
||||
|
||||
{
|
||||
register header *hp; /* Traverses linked list. */
|
||||
register header *hp; /* Traverses linked list. */
|
||||
|
||||
#ifdef emacs
|
||||
BLOCK_INPUT;
|
||||
@ -193,18 +193,18 @@ alloca (size)
|
||||
|
||||
for (hp = last_alloca_header; hp != NULL;)
|
||||
if ((STACK_DIR > 0 && hp->h.deep > depth)
|
||||
|| (STACK_DIR < 0 && hp->h.deep < depth))
|
||||
{
|
||||
register header *np = hp->h.next;
|
||||
|| (STACK_DIR < 0 && hp->h.deep < depth))
|
||||
{
|
||||
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
|
||||
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
|
||||
UNBLOCK_INPUT;
|
||||
@ -212,7 +212,7 @@ alloca (size)
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
return NULL; /* No allocation required. */
|
||||
return NULL; /* No allocation required. */
|
||||
|
||||
/* Allocate combined header + user data storage. */
|
||||
|
||||
@ -246,10 +246,10 @@ alloca (size)
|
||||
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
|
||||
struct stack_control_header
|
||||
{
|
||||
long shgrow:32; /* Number of times stack has grown. */
|
||||
long shaseg:32; /* Size of increments to stack. */
|
||||
long shhwm:32; /* High water mark of stack. */
|
||||
long shsize:32; /* Current size of stack (all segments). */
|
||||
long shgrow:32; /* Number of times stack has grown. */
|
||||
long shaseg:32; /* Size of increments to stack. */
|
||||
long shhwm:32; /* High water mark of stack. */
|
||||
long shsize:32; /* Current size of stack (all segments). */
|
||||
};
|
||||
|
||||
/* The stack segment linkage control information occurs at
|
||||
@ -261,21 +261,21 @@ struct stack_control_header
|
||||
|
||||
struct stack_segment_linkage
|
||||
{
|
||||
long ss[0200]; /* 0200 overflow words. */
|
||||
long sssize:32; /* Number of words in this segment. */
|
||||
long ssbase:32; /* Offset to stack base. */
|
||||
long ss[0200]; /* 0200 overflow words. */
|
||||
long sssize:32; /* Number of words in this segment. */
|
||||
long ssbase:32; /* Offset to stack base. */
|
||||
long:32;
|
||||
long sspseg:32; /* Offset to linkage control of previous
|
||||
segment of stack. */
|
||||
long sspseg:32; /* Offset to linkage control of previous
|
||||
segment of stack. */
|
||||
long:32;
|
||||
long sstcpt:32; /* Pointer to task common address block. */
|
||||
long sscsnm; /* Private control structure number for
|
||||
microtasking. */
|
||||
long ssusr1; /* Reserved for user. */
|
||||
long ssusr2; /* Reserved for user. */
|
||||
long sstpid; /* Process ID for pid based multi-tasking. */
|
||||
long ssgvup; /* Pointer to multitasking thread giveup. */
|
||||
long sscray[7]; /* Reserved for Cray Research. */
|
||||
long sstcpt:32; /* Pointer to task common address block. */
|
||||
long sscsnm; /* Private control structure number for
|
||||
microtasking. */
|
||||
long ssusr1; /* Reserved for user. */
|
||||
long ssusr2; /* Reserved for user. */
|
||||
long sstpid; /* Process ID for pid based multi-tasking. */
|
||||
long ssgvup; /* Pointer to multitasking thread giveup. */
|
||||
long sscray[7]; /* Reserved for Cray Research. */
|
||||
long ssa0;
|
||||
long ssa1;
|
||||
long ssa2;
|
||||
@ -299,27 +299,27 @@ struct stack_segment_linkage
|
||||
returned by the STKSTAT library routine. */
|
||||
struct stk_stat
|
||||
{
|
||||
long now; /* Current total stack size. */
|
||||
long maxc; /* Amount of contiguous space which would
|
||||
be required to satisfy the maximum
|
||||
stack demand to date. */
|
||||
long high_water; /* Stack high-water mark. */
|
||||
long overflows; /* Number of stack overflow ($STKOFEN) calls. */
|
||||
long hits; /* Number of internal buffer hits. */
|
||||
long extends; /* Number of block extensions. */
|
||||
long stko_mallocs; /* Block allocations by $STKOFEN. */
|
||||
long underflows; /* Number of stack underflow calls ($STKRETN). */
|
||||
long stko_free; /* Number of deallocations by $STKRETN. */
|
||||
long stkm_free; /* Number of deallocations by $STKMRET. */
|
||||
long segments; /* Current number of stack segments. */
|
||||
long maxs; /* Maximum number of stack segments so far. */
|
||||
long pad_size; /* Stack pad size. */
|
||||
long current_address; /* Current stack segment address. */
|
||||
long current_size; /* Current stack segment size. This
|
||||
number is actually corrupted by STKSTAT to
|
||||
include the fifteen word trailer area. */
|
||||
long initial_address; /* Address of initial segment. */
|
||||
long initial_size; /* Size of initial segment. */
|
||||
long now; /* Current total stack size. */
|
||||
long maxc; /* Amount of contiguous space which would
|
||||
be required to satisfy the maximum
|
||||
stack demand to date. */
|
||||
long high_water; /* Stack high-water mark. */
|
||||
long overflows; /* Number of stack overflow ($STKOFEN) calls. */
|
||||
long hits; /* Number of internal buffer hits. */
|
||||
long extends; /* Number of block extensions. */
|
||||
long stko_mallocs; /* Block allocations by $STKOFEN. */
|
||||
long underflows; /* Number of stack underflow calls ($STKRETN). */
|
||||
long stko_free; /* Number of deallocations by $STKRETN. */
|
||||
long stkm_free; /* Number of deallocations by $STKMRET. */
|
||||
long segments; /* Current number of stack segments. */
|
||||
long maxs; /* Maximum number of stack segments so far. */
|
||||
long pad_size; /* Stack pad size. */
|
||||
long current_address; /* Current stack segment address. */
|
||||
long current_size; /* Current stack segment size. This
|
||||
number is actually corrupted by STKSTAT to
|
||||
include the fifteen word trailer area. */
|
||||
long initial_address; /* Address of initial segment. */
|
||||
long initial_size; /* Size of initial segment. */
|
||||
};
|
||||
|
||||
/* The following structure describes the data structure which trails
|
||||
@ -328,13 +328,13 @@ struct stk_stat
|
||||
|
||||
struct stk_trailer
|
||||
{
|
||||
long this_address; /* Address of this block. */
|
||||
long this_size; /* Size of this block (does not include
|
||||
this trailer). */
|
||||
long this_address; /* Address of this block. */
|
||||
long this_size; /* Size of this block (does not include
|
||||
this trailer). */
|
||||
long unknown2;
|
||||
long unknown3;
|
||||
long link; /* Address of trailer block of previous
|
||||
segment. */
|
||||
long link; /* Address of trailer block of previous
|
||||
segment. */
|
||||
long unknown5;
|
||||
long unknown6;
|
||||
long unknown7;
|
||||
@ -372,8 +372,8 @@ i00afunc (long *address)
|
||||
/* Set up the iteration. */
|
||||
|
||||
trailer = (struct stk_trailer *) (status.current_address
|
||||
+ status.current_size
|
||||
- 15);
|
||||
+ status.current_size
|
||||
- 15);
|
||||
|
||||
/* There must be at least one stack segment. Therefore it is
|
||||
a fatal error if "trailer" is null. */
|
||||
@ -388,10 +388,10 @@ i00afunc (long *address)
|
||||
block = (long *) trailer->this_address;
|
||||
size = trailer->this_size;
|
||||
if (block == 0 || size == 0)
|
||||
abort ();
|
||||
abort ();
|
||||
trailer = (struct stk_trailer *) trailer->link;
|
||||
if ((block <= address) && (address < (block + size)))
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the result to the offset in this segment and add the sizes
|
||||
@ -407,7 +407,7 @@ i00afunc (long *address)
|
||||
do
|
||||
{
|
||||
if (trailer->this_size <= 0)
|
||||
abort ();
|
||||
abort ();
|
||||
result += trailer->this_size;
|
||||
trailer = (struct stk_trailer *) trailer->link;
|
||||
}
|
||||
@ -470,7 +470,7 @@ i00afunc (long address)
|
||||
fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
|
||||
#endif
|
||||
if (pseg == 0)
|
||||
break;
|
||||
break;
|
||||
stkl = stkl - pseg;
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
size = ssptr->sssize;
|
||||
|
1590
src/cmpt.c
1590
src/cmpt.c
File diff suppressed because it is too large
Load Diff
210
src/connect.c
210
src/connect.c
@ -76,25 +76,25 @@ sockaddr_set_data (struct sockaddr *sa, const ip_address *ip, int port)
|
||||
{
|
||||
case AF_INET:
|
||||
{
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
||||
xzero (*sin);
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_port = htons (port);
|
||||
sin->sin_addr = ip->data.d4;
|
||||
break;
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
||||
xzero (*sin);
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_port = htons (port);
|
||||
sin->sin_addr = ip->data.d4;
|
||||
break;
|
||||
}
|
||||
#ifdef ENABLE_IPV6
|
||||
case AF_INET6:
|
||||
{
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
|
||||
xzero (*sin6);
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_port = htons (port);
|
||||
sin6->sin6_addr = ip->data.d6;
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
|
||||
xzero (*sin6);
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_port = htons (port);
|
||||
sin6->sin6_addr = ip->data.d6;
|
||||
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
|
||||
sin6->sin6_scope_id = ip->ipv6_scope;
|
||||
sin6->sin6_scope_id = ip->ipv6_scope;
|
||||
#endif
|
||||
break;
|
||||
break;
|
||||
}
|
||||
#endif /* ENABLE_IPV6 */
|
||||
default:
|
||||
@ -113,31 +113,31 @@ sockaddr_get_data (const struct sockaddr *sa, ip_address *ip, int *port)
|
||||
{
|
||||
case AF_INET:
|
||||
{
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
||||
if (ip)
|
||||
{
|
||||
ip->family = AF_INET;
|
||||
ip->data.d4 = sin->sin_addr;
|
||||
}
|
||||
if (port)
|
||||
*port = ntohs (sin->sin_port);
|
||||
break;
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
||||
if (ip)
|
||||
{
|
||||
ip->family = AF_INET;
|
||||
ip->data.d4 = sin->sin_addr;
|
||||
}
|
||||
if (port)
|
||||
*port = ntohs (sin->sin_port);
|
||||
break;
|
||||
}
|
||||
#ifdef ENABLE_IPV6
|
||||
case AF_INET6:
|
||||
{
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
|
||||
if (ip)
|
||||
{
|
||||
ip->family = AF_INET6;
|
||||
ip->data.d6 = sin6->sin6_addr;
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
|
||||
if (ip)
|
||||
{
|
||||
ip->family = AF_INET6;
|
||||
ip->data.d6 = sin6->sin6_addr;
|
||||
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
|
||||
ip->ipv6_scope = sin6->sin6_scope_id;
|
||||
ip->ipv6_scope = sin6->sin6_scope_id;
|
||||
#endif
|
||||
}
|
||||
if (port)
|
||||
*port = ntohs (sin6->sin6_port);
|
||||
break;
|
||||
}
|
||||
if (port)
|
||||
*port = ntohs (sin6->sin6_port);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
@ -182,7 +182,7 @@ resolve_bind_address (struct sockaddr *sa)
|
||||
if (called)
|
||||
{
|
||||
if (should_bind)
|
||||
sockaddr_set_data (sa, &ip, 0);
|
||||
sockaddr_set_data (sa, &ip, 0);
|
||||
return should_bind;
|
||||
}
|
||||
called = true;
|
||||
@ -192,8 +192,8 @@ resolve_bind_address (struct sockaddr *sa)
|
||||
{
|
||||
/* #### We should be able to print the error message here. */
|
||||
logprintf (LOG_NOTQUIET,
|
||||
_("%s: unable to resolve bind address `%s'; disabling bind.\n"),
|
||||
exec_name, opt.bind_address);
|
||||
_("%s: unable to resolve bind address `%s'; disabling bind.\n"),
|
||||
exec_name, opt.bind_address);
|
||||
should_bind = false;
|
||||
return false;
|
||||
}
|
||||
@ -229,7 +229,7 @@ connect_with_timeout_callback (void *arg)
|
||||
|
||||
static int
|
||||
connect_with_timeout (int fd, const struct sockaddr *addr, socklen_t addrlen,
|
||||
double timeout)
|
||||
double timeout)
|
||||
{
|
||||
struct cwt_context ctx;
|
||||
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);
|
||||
if (print && 0 != strcmp (print, txt_addr))
|
||||
logprintf (LOG_VERBOSE, _("Connecting to %s|%s|:%d... "),
|
||||
escnonprint (print), txt_addr, port);
|
||||
logprintf (LOG_VERBOSE, _("Connecting to %s|%s|:%d... "),
|
||||
escnonprint (print), txt_addr, port);
|
||||
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. */
|
||||
@ -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));
|
||||
IF_DEBUG
|
||||
if (err < 0)
|
||||
DEBUGP (("Failed setting IPV6_V6ONLY: %s", strerror (errno)));
|
||||
DEBUGP (("Failed setting IPV6_V6ONLY: %s", strerror (errno)));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -297,31 +297,31 @@ connect_to_ip (const ip_address *ip, int port, const char *print)
|
||||
{
|
||||
int bufsize = opt.limit_rate;
|
||||
if (bufsize < 512)
|
||||
bufsize = 512; /* avoid pathologically small values */
|
||||
bufsize = 512; /* avoid pathologically small values */
|
||||
#ifdef SO_RCVBUF
|
||||
setsockopt (sock, SOL_SOCKET, SO_RCVBUF,
|
||||
(void *)&bufsize, (socklen_t)sizeof (bufsize));
|
||||
(void *)&bufsize, (socklen_t)sizeof (bufsize));
|
||||
#endif
|
||||
/* 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)
|
||||
{
|
||||
/* Bind the client side of the socket to the requested
|
||||
address. */
|
||||
address. */
|
||||
struct sockaddr_storage bind_ss;
|
||||
struct sockaddr *bind_sa = (struct sockaddr *)&bind_ss;
|
||||
if (resolve_bind_address (bind_sa))
|
||||
{
|
||||
{
|
||||
if (bind (sock, bind_sa, sockaddr_size (bind_sa)) < 0)
|
||||
goto err;
|
||||
}
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Connect the socket to the remote endpoint. */
|
||||
if (connect_with_timeout (sock, sa, sockaddr_size (sa),
|
||||
opt.connect_timeout) < 0)
|
||||
opt.connect_timeout) < 0)
|
||||
goto err;
|
||||
|
||||
/* Success. */
|
||||
@ -369,15 +369,15 @@ connect_to_host (const char *host, int port)
|
||||
const ip_address *ip = address_list_address_at (al, i);
|
||||
sock = connect_to_ip (ip, port, host);
|
||||
if (sock >= 0)
|
||||
{
|
||||
/* Success. */
|
||||
address_list_set_connected (al);
|
||||
address_list_release (al);
|
||||
return sock;
|
||||
}
|
||||
{
|
||||
/* Success. */
|
||||
address_list_set_connected (al);
|
||||
address_list_release (al);
|
||||
return sock;
|
||||
}
|
||||
|
||||
/* The attempt to connect has failed. Continue with the loop
|
||||
and try next address. */
|
||||
and try next address. */
|
||||
|
||||
address_list_set_faulty (al, i);
|
||||
}
|
||||
@ -387,7 +387,7 @@ connect_to_host (const char *host, int port)
|
||||
if (address_list_connected_p (al))
|
||||
{
|
||||
/* 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);
|
||||
al = lookup_host (host, LH_REFRESH);
|
||||
goto retry;
|
||||
@ -444,17 +444,17 @@ bind_local (const ip_address *bind_address, int *port)
|
||||
{
|
||||
socklen_t addrlen = sockaddr_size (sa);
|
||||
if (getsockname (sock, sa, &addrlen) < 0)
|
||||
{
|
||||
/* If we can't find out the socket's local address ("name"),
|
||||
something is seriously wrong with the socket, and it's
|
||||
unusable for us anyway because we must know the chosen
|
||||
port. */
|
||||
fd_close (sock);
|
||||
return -1;
|
||||
}
|
||||
{
|
||||
/* If we can't find out the socket's local address ("name"),
|
||||
something is seriously wrong with the socket, and it's
|
||||
unusable for us anyway because we must know the chosen
|
||||
port. */
|
||||
fd_close (sock);
|
||||
return -1;
|
||||
}
|
||||
sockaddr_get_data (sa, NULL, port);
|
||||
DEBUGP (("binding to address %s using port %i.\n",
|
||||
print_address (bind_address), *port));
|
||||
print_address (bind_address), *port));
|
||||
}
|
||||
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);
|
||||
if (test == 0)
|
||||
errno = ETIMEDOUT;
|
||||
errno = ETIMEDOUT;
|
||||
if (test <= 0)
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
sock = accept (local_sock, sa, &addrlen);
|
||||
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
|
||||
case AF_INET6:
|
||||
{
|
||||
struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&storage;
|
||||
ip->data.d6 = sa6->sin6_addr;
|
||||
struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&storage;
|
||||
ip->data.d6 = sa6->sin6_addr;
|
||||
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
|
||||
ip->ipv6_scope = sa6->sin6_scope_id;
|
||||
ip->ipv6_scope = sa6->sin6_scope_id;
|
||||
#endif
|
||||
DEBUGP (("conaddr is: %s\n", print_address (ip)));
|
||||
return true;
|
||||
DEBUGP (("conaddr is: %s\n", print_address (ip)));
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
case AF_INET:
|
||||
{
|
||||
struct sockaddr_in *sa = (struct sockaddr_in *)&storage;
|
||||
ip->data.d4 = sa->sin_addr;
|
||||
DEBUGP (("conaddr is: %s\n", print_address (ip)));
|
||||
return true;
|
||||
struct sockaddr_in *sa = (struct sockaddr_in *)&storage;
|
||||
ip->data.d4 = sa->sin_addr;
|
||||
DEBUGP (("conaddr is: %s\n", print_address (ip)));
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
abort ();
|
||||
@ -567,7 +567,7 @@ retryable_socket_connect_error (int err)
|
||||
#ifdef EPFNOSUPPORT
|
||||
|| err == EPFNOSUPPORT
|
||||
#endif
|
||||
#ifdef ESOCKTNOSUPPORT /* no, "sockt" is not a typo! */
|
||||
#ifdef ESOCKTNOSUPPORT /* no, "sockt" is not a typo! */
|
||||
|| err == ESOCKTNOSUPPORT
|
||||
#endif
|
||||
#ifdef EPROTONOSUPPORT
|
||||
@ -577,7 +577,7 @@ retryable_socket_connect_error (int err)
|
||||
|| err == ENOPROTOOPT
|
||||
#endif
|
||||
/* Apparently, older versions of Linux and BSD used EINVAL
|
||||
instead of EAFNOSUPPORT and such. */
|
||||
instead of EAFNOSUPPORT and such. */
|
||||
|| err == EINVAL
|
||||
)
|
||||
return false;
|
||||
@ -585,12 +585,12 @@ retryable_socket_connect_error (int err)
|
||||
if (!opt.retry_connrefused)
|
||||
if (err == ECONNREFUSED
|
||||
#ifdef ENETUNREACH
|
||||
|| err == ENETUNREACH /* network is unreachable */
|
||||
|| err == ENETUNREACH /* network is unreachable */
|
||||
#endif
|
||||
#ifdef EHOSTUNREACH
|
||||
|| err == EHOSTUNREACH /* host is unreachable */
|
||||
|| err == EHOSTUNREACH /* host is unreachable */
|
||||
#endif
|
||||
)
|
||||
)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -787,21 +787,21 @@ fd_transport_context (int fd)
|
||||
This is a macro because we want the static storage variables to be
|
||||
per-function. */
|
||||
|
||||
#define LAZY_RETRIEVE_INFO(info) do { \
|
||||
static struct transport_info *last_info; \
|
||||
static int last_fd = -1; \
|
||||
static unsigned int last_tick; \
|
||||
if (!transport_map) \
|
||||
info = NULL; \
|
||||
else if (last_fd == fd && last_tick == transport_map_modified_tick) \
|
||||
info = last_info; \
|
||||
else \
|
||||
{ \
|
||||
info = hash_table_get (transport_map, (void *)(intptr_t) fd); \
|
||||
last_fd = fd; \
|
||||
last_info = info; \
|
||||
last_tick = transport_map_modified_tick; \
|
||||
} \
|
||||
#define LAZY_RETRIEVE_INFO(info) do { \
|
||||
static struct transport_info *last_info; \
|
||||
static int last_fd = -1; \
|
||||
static unsigned int last_tick; \
|
||||
if (!transport_map) \
|
||||
info = NULL; \
|
||||
else if (last_fd == fd && last_tick == transport_map_modified_tick) \
|
||||
info = last_info; \
|
||||
else \
|
||||
{ \
|
||||
info = hash_table_get (transport_map, (void *)(intptr_t) fd); \
|
||||
last_fd = fd; \
|
||||
last_info = info; \
|
||||
last_tick = transport_map_modified_tick; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static bool
|
||||
@ -813,13 +813,13 @@ poll_internal (int fd, struct transport_info *info, int wf, double timeout)
|
||||
{
|
||||
int test;
|
||||
if (info && info->imp->poller)
|
||||
test = info->imp->poller (fd, timeout, wf, info->ctx);
|
||||
test = info->imp->poller (fd, timeout, wf, info->ctx);
|
||||
else
|
||||
test = sock_poll (fd, timeout, wf);
|
||||
test = sock_poll (fd, timeout, wf);
|
||||
if (test == 0)
|
||||
errno = ETIMEDOUT;
|
||||
errno = ETIMEDOUT;
|
||||
if (test <= 0)
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -885,13 +885,13 @@ fd_write (int fd, char *buf, int bufsize, double timeout)
|
||||
while (bufsize > 0)
|
||||
{
|
||||
if (!poll_internal (fd, info, WAIT_FOR_WRITE, timeout))
|
||||
return -1;
|
||||
return -1;
|
||||
if (info && info->imp->writer)
|
||||
res = info->imp->writer (fd, buf, bufsize, info->ctx);
|
||||
res = info->imp->writer (fd, buf, bufsize, info->ctx);
|
||||
else
|
||||
res = sock_write (fd, buf, bufsize);
|
||||
res = sock_write (fd, buf, bufsize);
|
||||
if (res <= 0)
|
||||
break;
|
||||
break;
|
||||
buf += res;
|
||||
bufsize -= res;
|
||||
}
|
||||
@ -921,7 +921,7 @@ fd_errstr (int fd)
|
||||
{
|
||||
const char *err = info->imp->errstr (fd, info->ctx);
|
||||
if (err)
|
||||
return err;
|
||||
return err;
|
||||
/* else, fall through and print the system error. */
|
||||
}
|
||||
return strerror (errno);
|
||||
|
690
src/cookies.c
690
src/cookies.c
File diff suppressed because it is too large
Load Diff
100
src/ftp-basic.c
100
src/ftp-basic.c
@ -65,30 +65,30 @@ ftp_response (int fd, char **ret_line)
|
||||
char *p;
|
||||
char *line = fd_read_line (fd);
|
||||
if (!line)
|
||||
return FTPRERR;
|
||||
return FTPRERR;
|
||||
|
||||
/* 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');
|
||||
if (p > line && p[-1] == '\n')
|
||||
*--p = '\0';
|
||||
*--p = '\0';
|
||||
if (p > line && p[-1] == '\r')
|
||||
*--p = '\0';
|
||||
*--p = '\0';
|
||||
|
||||
if (opt.server_response)
|
||||
logprintf (LOG_NOTQUIET, "%s\n", escnonprint (line));
|
||||
logprintf (LOG_NOTQUIET, "%s\n", escnonprint (line));
|
||||
else
|
||||
DEBUGP (("%s\n", escnonprint (line)));
|
||||
|
||||
/* The last line of output is the one that begins with "ddd ". */
|
||||
if (ISDIGIT (line[0]) && ISDIGIT (line[1]) && ISDIGIT (line[2])
|
||||
&& line[3] == ' ')
|
||||
{
|
||||
strncpy (ftp_last_respline, line, sizeof (ftp_last_respline));
|
||||
ftp_last_respline[sizeof (ftp_last_respline) - 1] = '\0';
|
||||
*ret_line = line;
|
||||
return FTPOK;
|
||||
}
|
||||
&& line[3] == ' ')
|
||||
{
|
||||
strncpy (ftp_last_respline, line, sizeof (ftp_last_respline));
|
||||
ftp_last_respline[sizeof (ftp_last_respline) - 1] = '\0';
|
||||
*ret_line = line;
|
||||
return FTPOK;
|
||||
}
|
||||
xfree (line);
|
||||
}
|
||||
}
|
||||
@ -103,23 +103,23 @@ ftp_request (const char *command, const char *value)
|
||||
if (value)
|
||||
{
|
||||
/* Check for newlines in VALUE (possibly injected by the %0A URL
|
||||
escape) making the callers inadvertently send multiple FTP
|
||||
commands at once. Without this check an attacker could
|
||||
intentionally redirect to ftp://server/fakedir%0Acommand.../
|
||||
and execute arbitrary FTP command on a remote FTP server. */
|
||||
escape) making the callers inadvertently send multiple FTP
|
||||
commands at once. Without this check an attacker could
|
||||
intentionally redirect to ftp://server/fakedir%0Acommand.../
|
||||
and execute arbitrary FTP command on a remote FTP server. */
|
||||
if (strpbrk (value, "\r\n"))
|
||||
{
|
||||
/* Copy VALUE to the stack and modify CR/LF to space. */
|
||||
char *defanged, *p;
|
||||
STRDUP_ALLOCA (defanged, value);
|
||||
for (p = defanged; *p; p++)
|
||||
if (*p == '\r' || *p == '\n')
|
||||
*p = ' ';
|
||||
DEBUGP (("\nDetected newlines in %s \"%s\"; changing to %s \"%s\"\n",
|
||||
command, escnonprint (value), command, escnonprint (defanged)));
|
||||
/* Make VALUE point to the defanged copy of the string. */
|
||||
value = defanged;
|
||||
}
|
||||
{
|
||||
/* Copy VALUE to the stack and modify CR/LF to space. */
|
||||
char *defanged, *p;
|
||||
STRDUP_ALLOCA (defanged, value);
|
||||
for (p = defanged; *p; p++)
|
||||
if (*p == '\r' || *p == '\n')
|
||||
*p = ' ';
|
||||
DEBUGP (("\nDetected newlines in %s \"%s\"; changing to %s \"%s\"\n",
|
||||
command, escnonprint (value), command, escnonprint (defanged)));
|
||||
/* Make VALUE point to the defanged copy of the string. */
|
||||
value = defanged;
|
||||
}
|
||||
res = concat_strings (command, " ", value, "\r\n", (char *) 0);
|
||||
}
|
||||
else
|
||||
@ -192,29 +192,29 @@ ftp_login (int csock, const char *acc, const char *pass)
|
||||
|
||||
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))
|
||||
{
|
||||
seed = respline + l;
|
||||
break;
|
||||
}
|
||||
{
|
||||
seed = respline + l;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (seed)
|
||||
{
|
||||
int skey_sequence = 0;
|
||||
|
||||
/* Extract the sequence from SEED. */
|
||||
for (; ISDIGIT (*seed); seed++)
|
||||
skey_sequence = 10 * skey_sequence + *seed - '0';
|
||||
if (*seed == ' ')
|
||||
++seed;
|
||||
/* Extract the sequence from SEED. */
|
||||
for (; ISDIGIT (*seed); seed++)
|
||||
skey_sequence = 10 * skey_sequence + *seed - '0';
|
||||
if (*seed == ' ')
|
||||
++seed;
|
||||
else
|
||||
{
|
||||
xfree (respline);
|
||||
return FTPLOGREFUSED;
|
||||
}
|
||||
/* Replace the password with the SKEY response to the
|
||||
challenge. */
|
||||
/* Replace the password with the SKEY response to the
|
||||
challenge. */
|
||||
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:
|
||||
snprintf (buf, buflen, "%d,%d,%d,%d,%d,%d,%d,%d,%d", 4, 4,
|
||||
ptr[0], ptr[1], ptr[2], ptr[3], 2,
|
||||
(port & 0xff00) >> 8, port & 0xff);
|
||||
ptr[0], ptr[1], ptr[2], ptr[3], 2,
|
||||
(port & 0xff00) >> 8, port & 0xff);
|
||||
break;
|
||||
case AF_INET6:
|
||||
snprintf (buf, buflen,
|
||||
"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
|
||||
6, 16,
|
||||
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],
|
||||
2, (port & 0xff00) >> 8, port & 0xff);
|
||||
"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
|
||||
6, 16,
|
||||
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],
|
||||
2, (port & 0xff00) >> 8, port & 0xff);
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
@ -985,14 +985,14 @@ ftp_list (int csock, const char *file)
|
||||
{
|
||||
err = FTPNSFOD;
|
||||
}
|
||||
else if (*respline == '1')
|
||||
else if (*respline == '1')
|
||||
{
|
||||
err = FTPOK;
|
||||
ok = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
err = FTPRERR;
|
||||
err = FTPRERR;
|
||||
}
|
||||
xfree (respline);
|
||||
}
|
||||
@ -1044,7 +1044,7 @@ ftp_syst (int csock, enum stype *server_type)
|
||||
else if (!strcasecmp (request, "UNIX"))
|
||||
*server_type = ST_UNIX;
|
||||
else if (!strcasecmp (request, "WINDOWS_NT")
|
||||
|| !strcasecmp (request, "WINDOWS2000"))
|
||||
|| !strcasecmp (request, "WINDOWS2000"))
|
||||
*server_type = ST_WINNT;
|
||||
else if (!strcasecmp (request, "MACOS"))
|
||||
*server_type = ST_MACOS;
|
||||
|
694
src/ftp-ls.c
694
src/ftp-ls.c
@ -41,8 +41,8 @@ so, delete this exception statement from your version. */
|
||||
#include "utils.h"
|
||||
#include "ftp.h"
|
||||
#include "url.h"
|
||||
#include "convert.h" /* for html_quote_string prototype */
|
||||
#include "retr.h" /* for output_stream */
|
||||
#include "convert.h" /* for html_quote_string prototype */
|
||||
#include "retr.h" /* for output_stream */
|
||||
|
||||
/* Converts symbolic permissions to number-style ones, e.g. string
|
||||
rwxr-xr-x to 755. For now, it knows nothing of
|
||||
@ -58,7 +58,7 @@ symperms (const char *s)
|
||||
{
|
||||
perms <<= 3;
|
||||
perms += (((s[0] == 'r') << 2) + ((s[1] == 'w') << 1) +
|
||||
(s[2] == 'x' || s[2] == 's'));
|
||||
(s[2] == 'x' || s[2] == 's'));
|
||||
}
|
||||
return perms;
|
||||
}
|
||||
@ -98,12 +98,12 @@ ftp_parse_unix_ls (const char *file, int ignore_perms)
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
int next, len, i, error, ignore;
|
||||
int year, month, day; /* for time analysis */
|
||||
int year, month, day; /* for time analysis */
|
||||
int hour, min, sec;
|
||||
struct tm timestruct, *tnow;
|
||||
time_t timenow;
|
||||
|
||||
char *line, *tok, *ptok; /* tokenizer */
|
||||
char *line, *tok, *ptok; /* tokenizer */
|
||||
struct fileinfo *dir, *l, cur; /* list creation */
|
||||
|
||||
fp = fopen (file, "rb");
|
||||
@ -120,270 +120,270 @@ ftp_parse_unix_ls (const char *file, int ignore_perms)
|
||||
len = clean_line (line);
|
||||
/* Skip if total... */
|
||||
if (!strncasecmp (line, "total", 5))
|
||||
{
|
||||
xfree (line);
|
||||
continue;
|
||||
}
|
||||
{
|
||||
xfree (line);
|
||||
continue;
|
||||
}
|
||||
/* Get the first token (permissions). */
|
||||
tok = strtok (line, " ");
|
||||
if (!tok)
|
||||
{
|
||||
xfree (line);
|
||||
continue;
|
||||
}
|
||||
{
|
||||
xfree (line);
|
||||
continue;
|
||||
}
|
||||
|
||||
cur.name = NULL;
|
||||
cur.linkto = NULL;
|
||||
|
||||
/* Decide whether we deal with a file or a directory. */
|
||||
switch (*tok)
|
||||
{
|
||||
case '-':
|
||||
cur.type = FT_PLAINFILE;
|
||||
DEBUGP (("PLAINFILE; "));
|
||||
break;
|
||||
case 'd':
|
||||
cur.type = FT_DIRECTORY;
|
||||
DEBUGP (("DIRECTORY; "));
|
||||
break;
|
||||
case 'l':
|
||||
cur.type = FT_SYMLINK;
|
||||
DEBUGP (("SYMLINK; "));
|
||||
break;
|
||||
default:
|
||||
cur.type = FT_UNKNOWN;
|
||||
DEBUGP (("UNKNOWN; "));
|
||||
break;
|
||||
}
|
||||
{
|
||||
case '-':
|
||||
cur.type = FT_PLAINFILE;
|
||||
DEBUGP (("PLAINFILE; "));
|
||||
break;
|
||||
case 'd':
|
||||
cur.type = FT_DIRECTORY;
|
||||
DEBUGP (("DIRECTORY; "));
|
||||
break;
|
||||
case 'l':
|
||||
cur.type = FT_SYMLINK;
|
||||
DEBUGP (("SYMLINK; "));
|
||||
break;
|
||||
default:
|
||||
cur.type = FT_UNKNOWN;
|
||||
DEBUGP (("UNKNOWN; "));
|
||||
break;
|
||||
}
|
||||
|
||||
if (ignore_perms)
|
||||
{
|
||||
switch (cur.type)
|
||||
{
|
||||
case FT_PLAINFILE:
|
||||
cur.perms = 0644;
|
||||
break;
|
||||
case FT_DIRECTORY:
|
||||
cur.perms = 0755;
|
||||
break;
|
||||
default:
|
||||
/*cur.perms = 1023;*/ /* #### What is this? --hniksic */
|
||||
cur.perms = 0644;
|
||||
}
|
||||
DEBUGP (("implicit perms %0o; ", cur.perms));
|
||||
}
|
||||
{
|
||||
switch (cur.type)
|
||||
{
|
||||
case FT_PLAINFILE:
|
||||
cur.perms = 0644;
|
||||
break;
|
||||
case FT_DIRECTORY:
|
||||
cur.perms = 0755;
|
||||
break;
|
||||
default:
|
||||
/*cur.perms = 1023;*/ /* #### What is this? --hniksic */
|
||||
cur.perms = 0644;
|
||||
}
|
||||
DEBUGP (("implicit perms %0o; ", cur.perms));
|
||||
}
|
||||
else
|
||||
{
|
||||
cur.perms = symperms (tok + 1);
|
||||
DEBUGP (("perms %0o; ", cur.perms));
|
||||
}
|
||||
cur.perms = symperms (tok + 1);
|
||||
DEBUGP (("perms %0o; ", cur.perms));
|
||||
}
|
||||
|
||||
error = ignore = 0; /* Erroneous and ignoring entries are
|
||||
treated equally for now. */
|
||||
treated equally for now. */
|
||||
year = hour = min = sec = 0; /* Silence the compiler. */
|
||||
month = day = 0;
|
||||
next = -1;
|
||||
/* 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
|
||||
position wrt the file name is "known"). When a month name is
|
||||
encountered, `next' is set to 5. Also, the preceding
|
||||
characters are parsed to get the file size.
|
||||
Use the month-name token as the "anchor" (the place where the
|
||||
position wrt the file name is "known"). When a month name is
|
||||
encountered, `next' is set to 5. Also, the preceding
|
||||
characters are parsed to get the file size.
|
||||
|
||||
This tactic is quite dubious when it comes to
|
||||
internationalization issues (non-English month names), but it
|
||||
works for now. */
|
||||
This tactic is quite dubious when it comes to
|
||||
internationalization issues (non-English month names), but it
|
||||
works for now. */
|
||||
tok = line;
|
||||
while (ptok = tok,
|
||||
(tok = strtok (NULL, " ")) != NULL)
|
||||
{
|
||||
--next;
|
||||
if (next < 0) /* a month name was not encountered */
|
||||
{
|
||||
for (i = 0; i < 12; i++)
|
||||
if (!strcmp (tok, months[i]))
|
||||
break;
|
||||
/* If we got a month, it means the token before it is the
|
||||
size, and the filename is three tokens away. */
|
||||
if (i != 12)
|
||||
{
|
||||
wgint size;
|
||||
(tok = strtok (NULL, " ")) != NULL)
|
||||
{
|
||||
--next;
|
||||
if (next < 0) /* a month name was not encountered */
|
||||
{
|
||||
for (i = 0; i < 12; i++)
|
||||
if (!strcmp (tok, months[i]))
|
||||
break;
|
||||
/* If we got a month, it means the token before it is the
|
||||
size, and the filename is three tokens away. */
|
||||
if (i != 12)
|
||||
{
|
||||
wgint size;
|
||||
|
||||
/* Parse the previous token with str_to_wgint. */
|
||||
if (ptok == line)
|
||||
{
|
||||
/* Something has gone wrong during parsing. */
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
errno = 0;
|
||||
size = str_to_wgint (ptok, NULL, 10);
|
||||
if (size == WGINT_MAX && errno == ERANGE)
|
||||
/* Out of range -- ignore the size. #### Should
|
||||
we refuse to start the download. */
|
||||
cur.size = 0;
|
||||
else
|
||||
cur.size = size;
|
||||
DEBUGP (("size: %s; ", number_to_static_string(cur.size)));
|
||||
/* Parse the previous token with str_to_wgint. */
|
||||
if (ptok == line)
|
||||
{
|
||||
/* Something has gone wrong during parsing. */
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
errno = 0;
|
||||
size = str_to_wgint (ptok, NULL, 10);
|
||||
if (size == WGINT_MAX && errno == ERANGE)
|
||||
/* Out of range -- ignore the size. #### Should
|
||||
we refuse to start the download. */
|
||||
cur.size = 0;
|
||||
else
|
||||
cur.size = size;
|
||||
DEBUGP (("size: %s; ", number_to_static_string(cur.size)));
|
||||
|
||||
month = i;
|
||||
next = 5;
|
||||
DEBUGP (("month: %s; ", months[month]));
|
||||
}
|
||||
}
|
||||
else if (next == 4) /* days */
|
||||
{
|
||||
if (tok[1]) /* two-digit... */
|
||||
day = 10 * (*tok - '0') + tok[1] - '0';
|
||||
else /* ...or one-digit */
|
||||
day = *tok - '0';
|
||||
DEBUGP (("day: %d; ", day));
|
||||
}
|
||||
else if (next == 3)
|
||||
{
|
||||
/* This ought to be either the time, or the year. Let's
|
||||
be flexible!
|
||||
month = i;
|
||||
next = 5;
|
||||
DEBUGP (("month: %s; ", months[month]));
|
||||
}
|
||||
}
|
||||
else if (next == 4) /* days */
|
||||
{
|
||||
if (tok[1]) /* two-digit... */
|
||||
day = 10 * (*tok - '0') + tok[1] - '0';
|
||||
else /* ...or one-digit */
|
||||
day = *tok - '0';
|
||||
DEBUGP (("day: %d; ", day));
|
||||
}
|
||||
else if (next == 3)
|
||||
{
|
||||
/* This ought to be either the time, or the year. Let's
|
||||
be flexible!
|
||||
|
||||
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
|
||||
seconds. */
|
||||
year = 0;
|
||||
min = hour = sec = 0;
|
||||
/* We must deal with digits. */
|
||||
if (ISDIGIT (*tok))
|
||||
{
|
||||
/* Suppose it's year. */
|
||||
for (; ISDIGIT (*tok); tok++)
|
||||
year = (*tok - '0') + 10 * year;
|
||||
if (*tok == ':')
|
||||
{
|
||||
/* This means these were hours! */
|
||||
hour = year;
|
||||
year = 0;
|
||||
++tok;
|
||||
/* Get the minutes... */
|
||||
for (; ISDIGIT (*tok); tok++)
|
||||
min = (*tok - '0') + 10 * min;
|
||||
if (*tok == ':')
|
||||
{
|
||||
/* ...and the seconds. */
|
||||
++tok;
|
||||
for (; ISDIGIT (*tok); tok++)
|
||||
sec = (*tok - '0') + 10 * sec;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (year)
|
||||
DEBUGP (("year: %d (no tm); ", year));
|
||||
else
|
||||
DEBUGP (("time: %02d:%02d:%02d (no yr); ", hour, min, sec));
|
||||
}
|
||||
else if (next == 2) /* The file name */
|
||||
{
|
||||
int fnlen;
|
||||
char *p;
|
||||
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
|
||||
seconds. */
|
||||
year = 0;
|
||||
min = hour = sec = 0;
|
||||
/* We must deal with digits. */
|
||||
if (ISDIGIT (*tok))
|
||||
{
|
||||
/* Suppose it's year. */
|
||||
for (; ISDIGIT (*tok); tok++)
|
||||
year = (*tok - '0') + 10 * year;
|
||||
if (*tok == ':')
|
||||
{
|
||||
/* This means these were hours! */
|
||||
hour = year;
|
||||
year = 0;
|
||||
++tok;
|
||||
/* Get the minutes... */
|
||||
for (; ISDIGIT (*tok); tok++)
|
||||
min = (*tok - '0') + 10 * min;
|
||||
if (*tok == ':')
|
||||
{
|
||||
/* ...and the seconds. */
|
||||
++tok;
|
||||
for (; ISDIGIT (*tok); tok++)
|
||||
sec = (*tok - '0') + 10 * sec;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (year)
|
||||
DEBUGP (("year: %d (no tm); ", year));
|
||||
else
|
||||
DEBUGP (("time: %02d:%02d:%02d (no yr); ", hour, min, sec));
|
||||
}
|
||||
else if (next == 2) /* The file name */
|
||||
{
|
||||
int fnlen;
|
||||
char *p;
|
||||
|
||||
/* Since the file name may contain a SPC, it is possible
|
||||
for strtok to handle it wrong. */
|
||||
fnlen = strlen (tok);
|
||||
if (fnlen < len - (tok - line))
|
||||
{
|
||||
/* So we have a SPC in the file name. Restore the
|
||||
original. */
|
||||
tok[fnlen] = ' ';
|
||||
/* If the file is a symbolic link, it should have a
|
||||
` -> ' somewhere. */
|
||||
if (cur.type == FT_SYMLINK)
|
||||
{
|
||||
p = strstr (tok, " -> ");
|
||||
if (!p)
|
||||
{
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
cur.linkto = xstrdup (p + 4);
|
||||
DEBUGP (("link to: %s\n", cur.linkto));
|
||||
/* And separate it from the file name. */
|
||||
*p = '\0';
|
||||
}
|
||||
}
|
||||
/* If we have the filename, add it to the list of files or
|
||||
directories. */
|
||||
/* "." and ".." are an exception! */
|
||||
if (!strcmp (tok, ".") || !strcmp (tok, ".."))
|
||||
{
|
||||
DEBUGP (("\nIgnoring `.' and `..'; "));
|
||||
ignore = 1;
|
||||
break;
|
||||
}
|
||||
/* Some FTP sites choose to have ls -F as their default
|
||||
LIST output, which marks the symlinks with a trailing
|
||||
`@', directory names with a trailing `/' and
|
||||
executables with a trailing `*'. This is no problem
|
||||
unless encountering a symbolic link ending with `@',
|
||||
or an executable ending with `*' on a server without
|
||||
default -F output. I believe these cases are very
|
||||
rare. */
|
||||
fnlen = strlen (tok); /* re-calculate `fnlen' */
|
||||
cur.name = xmalloc (fnlen + 1);
|
||||
memcpy (cur.name, tok, fnlen + 1);
|
||||
if (fnlen)
|
||||
{
|
||||
if (cur.type == FT_DIRECTORY && cur.name[fnlen - 1] == '/')
|
||||
{
|
||||
cur.name[fnlen - 1] = '\0';
|
||||
DEBUGP (("trailing `/' on dir.\n"));
|
||||
}
|
||||
else if (cur.type == FT_SYMLINK && cur.name[fnlen - 1] == '@')
|
||||
{
|
||||
cur.name[fnlen - 1] = '\0';
|
||||
DEBUGP (("trailing `@' on link.\n"));
|
||||
}
|
||||
else if (cur.type == FT_PLAINFILE
|
||||
&& (cur.perms & 0111)
|
||||
&& cur.name[fnlen - 1] == '*')
|
||||
{
|
||||
cur.name[fnlen - 1] = '\0';
|
||||
DEBUGP (("trailing `*' on exec.\n"));
|
||||
}
|
||||
} /* if (fnlen) */
|
||||
else
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
abort ();
|
||||
} /* while */
|
||||
/* Since the file name may contain a SPC, it is possible
|
||||
for strtok to handle it wrong. */
|
||||
fnlen = strlen (tok);
|
||||
if (fnlen < len - (tok - line))
|
||||
{
|
||||
/* So we have a SPC in the file name. Restore the
|
||||
original. */
|
||||
tok[fnlen] = ' ';
|
||||
/* If the file is a symbolic link, it should have a
|
||||
` -> ' somewhere. */
|
||||
if (cur.type == FT_SYMLINK)
|
||||
{
|
||||
p = strstr (tok, " -> ");
|
||||
if (!p)
|
||||
{
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
cur.linkto = xstrdup (p + 4);
|
||||
DEBUGP (("link to: %s\n", cur.linkto));
|
||||
/* And separate it from the file name. */
|
||||
*p = '\0';
|
||||
}
|
||||
}
|
||||
/* If we have the filename, add it to the list of files or
|
||||
directories. */
|
||||
/* "." and ".." are an exception! */
|
||||
if (!strcmp (tok, ".") || !strcmp (tok, ".."))
|
||||
{
|
||||
DEBUGP (("\nIgnoring `.' and `..'; "));
|
||||
ignore = 1;
|
||||
break;
|
||||
}
|
||||
/* Some FTP sites choose to have ls -F as their default
|
||||
LIST output, which marks the symlinks with a trailing
|
||||
`@', directory names with a trailing `/' and
|
||||
executables with a trailing `*'. This is no problem
|
||||
unless encountering a symbolic link ending with `@',
|
||||
or an executable ending with `*' on a server without
|
||||
default -F output. I believe these cases are very
|
||||
rare. */
|
||||
fnlen = strlen (tok); /* re-calculate `fnlen' */
|
||||
cur.name = xmalloc (fnlen + 1);
|
||||
memcpy (cur.name, tok, fnlen + 1);
|
||||
if (fnlen)
|
||||
{
|
||||
if (cur.type == FT_DIRECTORY && cur.name[fnlen - 1] == '/')
|
||||
{
|
||||
cur.name[fnlen - 1] = '\0';
|
||||
DEBUGP (("trailing `/' on dir.\n"));
|
||||
}
|
||||
else if (cur.type == FT_SYMLINK && cur.name[fnlen - 1] == '@')
|
||||
{
|
||||
cur.name[fnlen - 1] = '\0';
|
||||
DEBUGP (("trailing `@' on link.\n"));
|
||||
}
|
||||
else if (cur.type == FT_PLAINFILE
|
||||
&& (cur.perms & 0111)
|
||||
&& cur.name[fnlen - 1] == '*')
|
||||
{
|
||||
cur.name[fnlen - 1] = '\0';
|
||||
DEBUGP (("trailing `*' on exec.\n"));
|
||||
}
|
||||
} /* if (fnlen) */
|
||||
else
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
abort ();
|
||||
} /* while */
|
||||
|
||||
if (!cur.name || (cur.type == FT_SYMLINK && !cur.linkto))
|
||||
error = 1;
|
||||
error = 1;
|
||||
|
||||
DEBUGP (("%s\n", cur.name ? cur.name : ""));
|
||||
|
||||
if (error || ignore)
|
||||
{
|
||||
DEBUGP (("Skipping.\n"));
|
||||
xfree_null (cur.name);
|
||||
xfree_null (cur.linkto);
|
||||
xfree (line);
|
||||
continue;
|
||||
}
|
||||
{
|
||||
DEBUGP (("Skipping.\n"));
|
||||
xfree_null (cur.name);
|
||||
xfree_null (cur.linkto);
|
||||
xfree (line);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!dir)
|
||||
{
|
||||
l = dir = xnew (struct fileinfo);
|
||||
memcpy (l, &cur, sizeof (cur));
|
||||
l->prev = l->next = NULL;
|
||||
}
|
||||
{
|
||||
l = dir = xnew (struct fileinfo);
|
||||
memcpy (l, &cur, sizeof (cur));
|
||||
l->prev = l->next = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur.prev = l;
|
||||
l->next = xnew (struct fileinfo);
|
||||
l = l->next;
|
||||
memcpy (l, &cur, sizeof (cur));
|
||||
l->next = NULL;
|
||||
}
|
||||
{
|
||||
cur.prev = l;
|
||||
l->next = xnew (struct fileinfo);
|
||||
l = l->next;
|
||||
memcpy (l, &cur, sizeof (cur));
|
||||
l->next = NULL;
|
||||
}
|
||||
/* Get the current time. */
|
||||
timenow = time (NULL);
|
||||
tnow = localtime (&timenow);
|
||||
@ -394,21 +394,21 @@ ftp_parse_unix_ls (const char *file, int ignore_perms)
|
||||
timestruct.tm_mday = day;
|
||||
timestruct.tm_mon = month;
|
||||
if (year == 0)
|
||||
{
|
||||
/* Some listings will not specify the year if it is "obvious"
|
||||
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
|
||||
1996, not 1997. Thanks to Vladimir Volovich for
|
||||
mentioning this! */
|
||||
if (month > tnow->tm_mon)
|
||||
timestruct.tm_year = tnow->tm_year - 1;
|
||||
else
|
||||
timestruct.tm_year = tnow->tm_year;
|
||||
}
|
||||
{
|
||||
/* Some listings will not specify the year if it is "obvious"
|
||||
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
|
||||
1996, not 1997. Thanks to Vladimir Volovich for
|
||||
mentioning this! */
|
||||
if (month > tnow->tm_mon)
|
||||
timestruct.tm_year = tnow->tm_year - 1;
|
||||
else
|
||||
timestruct.tm_year = tnow->tm_year;
|
||||
}
|
||||
else
|
||||
timestruct.tm_year = year;
|
||||
timestruct.tm_year = year;
|
||||
if (timestruct.tm_year >= 1900)
|
||||
timestruct.tm_year -= 1900;
|
||||
timestruct.tm_year -= 1900;
|
||||
timestruct.tm_wday = 0;
|
||||
timestruct.tm_yday = 0;
|
||||
timestruct.tm_isdst = -1;
|
||||
@ -458,7 +458,7 @@ ftp_parse_winnt_ls (const char *file)
|
||||
DEBUGP(("Name: '%s'\n", cur.name));
|
||||
|
||||
/* First column: mm-dd-yy. Should atoi() on the month fail, january
|
||||
will be assumed. */
|
||||
will be assumed. */
|
||||
tok = strtok(line, "-");
|
||||
if (tok == NULL) continue;
|
||||
month = atoi(tok) - 1;
|
||||
@ -512,43 +512,43 @@ ftp_parse_winnt_ls (const char *file)
|
||||
while ((tok != NULL) && (*tok == '\0')) tok = strtok(NULL, " ");
|
||||
if (tok == NULL) continue;
|
||||
if (*tok == '<')
|
||||
{
|
||||
cur.type = FT_DIRECTORY;
|
||||
cur.size = 0;
|
||||
cur.perms = 0755;
|
||||
DEBUGP(("Directory\n"));
|
||||
}
|
||||
{
|
||||
cur.type = FT_DIRECTORY;
|
||||
cur.size = 0;
|
||||
cur.perms = 0755;
|
||||
DEBUGP(("Directory\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
wgint size;
|
||||
cur.type = FT_PLAINFILE;
|
||||
errno = 0;
|
||||
size = str_to_wgint (tok, NULL, 10);
|
||||
if (size == WGINT_MAX && errno == ERANGE)
|
||||
cur.size = 0; /* overflow */
|
||||
else
|
||||
cur.size = size;
|
||||
cur.perms = 0644;
|
||||
DEBUGP(("File, size %s bytes\n", number_to_static_string (cur.size)));
|
||||
}
|
||||
{
|
||||
wgint size;
|
||||
cur.type = FT_PLAINFILE;
|
||||
errno = 0;
|
||||
size = str_to_wgint (tok, NULL, 10);
|
||||
if (size == WGINT_MAX && errno == ERANGE)
|
||||
cur.size = 0; /* overflow */
|
||||
else
|
||||
cur.size = size;
|
||||
cur.perms = 0644;
|
||||
DEBUGP(("File, size %s bytes\n", number_to_static_string (cur.size)));
|
||||
}
|
||||
|
||||
cur.linkto = NULL;
|
||||
|
||||
/* And put everything into the linked list */
|
||||
if (!dir)
|
||||
{
|
||||
l = dir = xnew (struct fileinfo);
|
||||
memcpy (l, &cur, sizeof (cur));
|
||||
l->prev = l->next = NULL;
|
||||
}
|
||||
{
|
||||
l = dir = xnew (struct fileinfo);
|
||||
memcpy (l, &cur, sizeof (cur));
|
||||
l->prev = l->next = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur.prev = l;
|
||||
l->next = xnew (struct fileinfo);
|
||||
l = l->next;
|
||||
memcpy (l, &cur, sizeof (cur));
|
||||
l->next = NULL;
|
||||
}
|
||||
{
|
||||
cur.prev = l;
|
||||
l->next = xnew (struct fileinfo);
|
||||
l = l->next;
|
||||
memcpy (l, &cur, sizeof (cur));
|
||||
l->next = NULL;
|
||||
}
|
||||
|
||||
xfree (line);
|
||||
}
|
||||
@ -595,7 +595,7 @@ ftp_parse_vms_ls (const char *file)
|
||||
int hour, min, sec;
|
||||
struct tm timestruct;
|
||||
|
||||
char *line, *tok; /* tokenizer */
|
||||
char *line, *tok; /* tokenizer */
|
||||
struct fileinfo *dir, *l, cur; /* list creation */
|
||||
|
||||
fp = fopen (file, "rb");
|
||||
@ -624,10 +624,10 @@ ftp_parse_vms_ls (const char *file)
|
||||
char *p;
|
||||
i = clean_line (line);
|
||||
if (!i)
|
||||
{
|
||||
xfree (line);
|
||||
break;
|
||||
}
|
||||
{
|
||||
xfree (line);
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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
|
||||
@ -641,7 +641,7 @@ ftp_parse_vms_ls (const char *file)
|
||||
if (tok == NULL) tok = line;
|
||||
DEBUGP(("file name: '%s'\n", tok));
|
||||
for (p = tok ; *p && *p != ';' ; p++)
|
||||
;
|
||||
;
|
||||
if (*p == ';') *p = '\0';
|
||||
p = tok + strlen(tok) - 4;
|
||||
if (!strcmp(p, ".DIR")) *p = '\0';
|
||||
@ -685,7 +685,7 @@ ftp_parse_vms_ls (const char *file)
|
||||
if (!i)
|
||||
{
|
||||
DEBUGP(("confusing VMS listing item, leaving listing parser\n"));
|
||||
xfree (line);
|
||||
xfree (line);
|
||||
break;
|
||||
}
|
||||
tok = strtok(line, " ");
|
||||
@ -706,7 +706,7 @@ ftp_parse_vms_ls (const char *file)
|
||||
the first strtok(NULL, "-") will return everything until the end
|
||||
of the line and only the next strtok() call will return NULL. */
|
||||
DEBUGP(("nonsense in VMS listing, skipping this line\n"));
|
||||
xfree (line);
|
||||
xfree (line);
|
||||
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;
|
||||
hour = atoi (p);
|
||||
for (; *p && *p != ':'; ++p)
|
||||
;
|
||||
;
|
||||
if (*p)
|
||||
min = atoi (++p);
|
||||
min = atoi (++p);
|
||||
for (; *p && *p != ':'; ++p)
|
||||
;
|
||||
;
|
||||
if (*p)
|
||||
sec = atoi (++p);
|
||||
sec = atoi (++p);
|
||||
|
||||
DEBUGP(("YYYY/MM/DD HH:MM:SS - %d/%02d/%02d %02d:%02d:%02d\n",
|
||||
year+1900, month, day, hour, min, sec));
|
||||
@ -762,7 +762,7 @@ ftp_parse_vms_ls (const char *file)
|
||||
if (tok == NULL)
|
||||
{
|
||||
DEBUGP(("confusing VMS permissions, skipping line\n"));
|
||||
xfree (line);
|
||||
xfree (line);
|
||||
continue;
|
||||
}
|
||||
/* 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);
|
||||
case ST_WINNT:
|
||||
{
|
||||
/* Detect whether the listing is simulating the UNIX format */
|
||||
FILE *fp;
|
||||
int c;
|
||||
fp = fopen (file, "rb");
|
||||
if (!fp)
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, "%s: %s\n", file, strerror (errno));
|
||||
return NULL;
|
||||
/* Detect whether the listing is simulating the UNIX format */
|
||||
FILE *fp;
|
||||
int c;
|
||||
fp = fopen (file, "rb");
|
||||
if (!fp)
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, "%s: %s\n", file, strerror (errno));
|
||||
return NULL;
|
||||
}
|
||||
c = fgetc(fp);
|
||||
fclose(fp);
|
||||
/* If the first character of the file is '0'-'9', it's WINNT
|
||||
format. */
|
||||
if (c >= '0' && c <='9')
|
||||
return ftp_parse_winnt_ls (file);
|
||||
c = fgetc(fp);
|
||||
fclose(fp);
|
||||
/* If the first character of the file is '0'-'9', it's WINNT
|
||||
format. */
|
||||
if (c >= '0' && c <='9')
|
||||
return ftp_parse_winnt_ls (file);
|
||||
else
|
||||
return ftp_parse_unix_ls (file, 1);
|
||||
}
|
||||
@ -849,16 +849,16 @@ ftp_index (const char *file, struct url *u, struct fileinfo *f)
|
||||
{
|
||||
FILE *fp;
|
||||
char *upwd;
|
||||
char *htclfile; /* HTML-clean file name */
|
||||
char *htclfile; /* HTML-clean file name */
|
||||
|
||||
if (!output_stream)
|
||||
{
|
||||
fp = fopen (file, "wb");
|
||||
if (!fp)
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, "%s: %s\n", file, strerror (errno));
|
||||
return FOPENERR;
|
||||
}
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, "%s: %s\n", file, strerror (errno));
|
||||
return FOPENERR;
|
||||
}
|
||||
}
|
||||
else
|
||||
fp = output_stream;
|
||||
@ -869,9 +869,9 @@ ftp_index (const char *file, struct url *u, struct fileinfo *f)
|
||||
tmpu = url_escape (u->user);
|
||||
tmpp = u->passwd ? url_escape (u->passwd) : NULL;
|
||||
if (tmpp)
|
||||
upwd = concat_strings (tmpu, ":", tmpp, "@", (char *) 0);
|
||||
upwd = concat_strings (tmpu, ":", tmpp, "@", (char *) 0);
|
||||
else
|
||||
upwd = concat_strings (tmpu, "@", (char *) 0);
|
||||
upwd = concat_strings (tmpu, "@", (char *) 0);
|
||||
xfree (tmpu);
|
||||
xfree_null (tmpp);
|
||||
}
|
||||
@ -887,57 +887,57 @@ ftp_index (const char *file, struct url *u, struct fileinfo *f)
|
||||
{
|
||||
fprintf (fp, " ");
|
||||
if (f->tstamp != -1)
|
||||
{
|
||||
/* #### Should we translate the months? Or, even better, use
|
||||
ISO 8601 dates? */
|
||||
static const char *months[] = {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
struct tm *ptm = localtime ((time_t *)&f->tstamp);
|
||||
{
|
||||
/* #### Should we translate the months? Or, even better, use
|
||||
ISO 8601 dates? */
|
||||
static const char *months[] = {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
struct tm *ptm = localtime ((time_t *)&f->tstamp);
|
||||
|
||||
fprintf (fp, "%d %s %02d ", ptm->tm_year + 1900, months[ptm->tm_mon],
|
||||
ptm->tm_mday);
|
||||
if (ptm->tm_hour)
|
||||
fprintf (fp, "%02d:%02d ", ptm->tm_hour, ptm->tm_min);
|
||||
else
|
||||
fprintf (fp, " ");
|
||||
}
|
||||
fprintf (fp, "%d %s %02d ", ptm->tm_year + 1900, months[ptm->tm_mon],
|
||||
ptm->tm_mday);
|
||||
if (ptm->tm_hour)
|
||||
fprintf (fp, "%02d:%02d ", ptm->tm_hour, ptm->tm_min);
|
||||
else
|
||||
fprintf (fp, " ");
|
||||
}
|
||||
else
|
||||
fprintf (fp, _("time unknown "));
|
||||
fprintf (fp, _("time unknown "));
|
||||
switch (f->type)
|
||||
{
|
||||
case FT_PLAINFILE:
|
||||
fprintf (fp, _("File "));
|
||||
break;
|
||||
case FT_DIRECTORY:
|
||||
fprintf (fp, _("Directory "));
|
||||
break;
|
||||
case FT_SYMLINK:
|
||||
fprintf (fp, _("Link "));
|
||||
break;
|
||||
default:
|
||||
fprintf (fp, _("Not sure "));
|
||||
break;
|
||||
}
|
||||
{
|
||||
case FT_PLAINFILE:
|
||||
fprintf (fp, _("File "));
|
||||
break;
|
||||
case FT_DIRECTORY:
|
||||
fprintf (fp, _("Directory "));
|
||||
break;
|
||||
case FT_SYMLINK:
|
||||
fprintf (fp, _("Link "));
|
||||
break;
|
||||
default:
|
||||
fprintf (fp, _("Not sure "));
|
||||
break;
|
||||
}
|
||||
htclfile = html_quote_string (f->name);
|
||||
fprintf (fp, "<a href=\"ftp://%s%s:%d", upwd, u->host, u->port);
|
||||
if (*u->dir != '/')
|
||||
putc ('/', fp);
|
||||
putc ('/', fp);
|
||||
fprintf (fp, "%s", u->dir);
|
||||
if (*u->dir)
|
||||
putc ('/', fp);
|
||||
putc ('/', fp);
|
||||
fprintf (fp, "%s", htclfile);
|
||||
if (f->type == FT_DIRECTORY)
|
||||
putc ('/', fp);
|
||||
putc ('/', fp);
|
||||
fprintf (fp, "\">%s", htclfile);
|
||||
if (f->type == FT_DIRECTORY)
|
||||
putc ('/', fp);
|
||||
putc ('/', fp);
|
||||
fprintf (fp, "</a> ");
|
||||
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)
|
||||
fprintf (fp, "-> %s", f->linkto ? f->linkto : "(nil)");
|
||||
fprintf (fp, "-> %s", f->linkto ? f->linkto : "(nil)");
|
||||
putc ('\n', fp);
|
||||
xfree (htclfile);
|
||||
f = f->next;
|
||||
|
@ -2117,8 +2117,8 @@ extract (const unsigned char *s, int start, int length)
|
||||
static char *
|
||||
btoe (char *store, const unsigned char *c)
|
||||
{
|
||||
unsigned char cp[10]; /* add in room for the parity 2 bits +
|
||||
extract() slop. */
|
||||
unsigned char cp[10]; /* add in room for the parity 2 bits +
|
||||
extract() slop. */
|
||||
int p, i;
|
||||
char *store_beg = store;
|
||||
|
||||
@ -2154,7 +2154,7 @@ btoe (char *store, const unsigned char *c)
|
||||
store += STRLEN_1_4 (store);
|
||||
*store++ = ' ';
|
||||
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));
|
||||
return store_beg;
|
||||
|
870
src/getopt.c
870
src/getopt.c
File diff suppressed because it is too large
Load Diff
@ -38,7 +38,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
# define SWAP(n) \
|
||||
# define SWAP(n) \
|
||||
(((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
|
||||
#else
|
||||
# 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. */
|
||||
*(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
|
||||
*(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |
|
||||
(ctx->total[0] >> 29));
|
||||
(ctx->total[0] >> 29));
|
||||
|
||||
/* Process last bytes. */
|
||||
md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
|
||||
@ -132,28 +132,28 @@ md5_stream (FILE *stream, void *resblock)
|
||||
while (1)
|
||||
{
|
||||
/* We read the file in blocks of BLOCKSIZE bytes. One call of the
|
||||
computation function processes the whole buffer so that with the
|
||||
next round of the loop another block can be read. */
|
||||
computation function processes the whole buffer so that with the
|
||||
next round of the loop another block can be read. */
|
||||
size_t n;
|
||||
sum = 0;
|
||||
|
||||
/* Read block. Take care for partial reads. */
|
||||
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);
|
||||
if (n == 0 && ferror (stream))
|
||||
return 1;
|
||||
|
||||
/* If end of file is reached, end the loop. */
|
||||
if (n == 0)
|
||||
break;
|
||||
break;
|
||||
|
||||
/* Process buffer with BLOCKSIZE bytes. Note that
|
||||
BLOCKSIZE % 64 == 0
|
||||
BLOCKSIZE % 64 == 0
|
||||
*/
|
||||
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;
|
||||
|
||||
if (left_over + add > 64)
|
||||
{
|
||||
md5_process_block (ctx->buffer, (left_over + add) & ~63, ctx);
|
||||
/* The regions in the following copy operation cannot overlap. */
|
||||
memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
|
||||
(left_over + add) & 63);
|
||||
ctx->buflen = (left_over + add) & 63;
|
||||
}
|
||||
{
|
||||
md5_process_block (ctx->buffer, (left_over + add) & ~63, ctx);
|
||||
/* The regions in the following copy operation cannot overlap. */
|
||||
memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
|
||||
(left_over + add) & 63);
|
||||
ctx->buflen = (left_over + add) & 63;
|
||||
}
|
||||
|
||||
buffer = (const char *) buffer + 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;
|
||||
|
||||
/* First round: using the given function, the context and a constant
|
||||
the next context is computed. Because the algorithms processing
|
||||
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
|
||||
before the computation. To reduce the work for the next steps
|
||||
we store the swapped words in the array CORRECT_WORDS. */
|
||||
the next context is computed. Because the algorithms processing
|
||||
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
|
||||
before the computation. To reduce the work for the next steps
|
||||
we store the swapped words in the array CORRECT_WORDS. */
|
||||
|
||||
#define OP(a, b, c, d, s, T) \
|
||||
do \
|
||||
{ \
|
||||
a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \
|
||||
++words; \
|
||||
CYCLIC (a, s); \
|
||||
a += b; \
|
||||
} \
|
||||
#define OP(a, b, c, d, s, T) \
|
||||
do \
|
||||
{ \
|
||||
a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \
|
||||
++words; \
|
||||
CYCLIC (a, s); \
|
||||
a += b; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* 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)))
|
||||
|
||||
/* 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. */
|
||||
@ -318,16 +318,16 @@ md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx)
|
||||
OP (B, C, D, A, 22, 0x49b40821);
|
||||
|
||||
/* For the second to fourth round we have the possibly swapped words
|
||||
in CORRECT_WORDS. Redefine the macro to take an additional first
|
||||
argument specifying the function to use. */
|
||||
in CORRECT_WORDS. Redefine the macro to take an additional first
|
||||
argument specifying the function to use. */
|
||||
#undef OP
|
||||
#define OP(f, a, b, c, d, k, s, T) \
|
||||
do \
|
||||
{ \
|
||||
a += f (b, c, d) + correct_words[k] + T; \
|
||||
CYCLIC (a, s); \
|
||||
a += b; \
|
||||
} \
|
||||
#define OP(f, a, b, c, d, k, s, T) \
|
||||
do \
|
||||
{ \
|
||||
a += f (b, c, d) + correct_words[k] + T; \
|
||||
CYCLIC (a, s); \
|
||||
a += b; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Round 2. */
|
||||
|
80
src/gnutls.c
80
src/gnutls.c
@ -59,13 +59,13 @@ ssl_init ()
|
||||
gnutls_certificate_allocate_credentials (&credentials);
|
||||
if (opt.ca_cert)
|
||||
gnutls_certificate_set_x509_trust_file (credentials, opt.ca_cert,
|
||||
GNUTLS_X509_FMT_PEM);
|
||||
GNUTLS_X509_FMT_PEM);
|
||||
return true;
|
||||
}
|
||||
|
||||
struct wgnutls_transport_context {
|
||||
gnutls_session session; /* GnuTLS session handle */
|
||||
int last_error; /* last error returned by read/write/... */
|
||||
gnutls_session session; /* GnuTLS session handle */
|
||||
int last_error; /* last error returned by read/write/... */
|
||||
|
||||
/* Since GnuTLS doesn't support the equivalent to recv(...,
|
||||
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);
|
||||
ctx->peeklen -= copysize;
|
||||
if (ctx->peeklen != 0)
|
||||
ctx->peekstart += copysize;
|
||||
ctx->peekstart += copysize;
|
||||
else
|
||||
ctx->peekstart = 0;
|
||||
ctx->peekstart = 0;
|
||||
return copysize;
|
||||
}
|
||||
|
||||
@ -223,7 +223,7 @@ ssl_check_certificate (int fd, const char *host)
|
||||
if (err < 0)
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("%s: No certificate presented by %s.\n"),
|
||||
severity, escnonprint (host));
|
||||
severity, escnonprint (host));
|
||||
success = false;
|
||||
goto out;
|
||||
}
|
||||
@ -231,19 +231,19 @@ ssl_check_certificate (int fd, const char *host)
|
||||
if (status & GNUTLS_CERT_INVALID)
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("%s: The certificate of `%s' is not trusted.\n"),
|
||||
severity, escnonprint (host));
|
||||
severity, escnonprint (host));
|
||||
success = false;
|
||||
}
|
||||
if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("%s: The certificate of `%s' hasn't got a known issuer.\n"),
|
||||
severity, escnonprint (host));
|
||||
severity, escnonprint (host));
|
||||
success = false;
|
||||
}
|
||||
if (status & GNUTLS_CERT_REVOKED)
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("%s: The certificate of `%s' has been revoked.\n"),
|
||||
severity, escnonprint (host));
|
||||
severity, escnonprint (host));
|
||||
success = false;
|
||||
}
|
||||
|
||||
@ -255,45 +255,45 @@ ssl_check_certificate (int fd, const char *host)
|
||||
unsigned int cert_list_size;
|
||||
|
||||
if ((err = gnutls_x509_crt_init (&cert)) < 0)
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("Error initializing X509 certificate: %s\n"),
|
||||
gnutls_strerror (err));
|
||||
success = false;
|
||||
goto out;
|
||||
}
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("Error initializing X509 certificate: %s\n"),
|
||||
gnutls_strerror (err));
|
||||
success = false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
cert_list = gnutls_certificate_get_peers (ctx->session, &cert_list_size);
|
||||
if (!cert_list)
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("No certificate found\n"));
|
||||
success = false;
|
||||
goto out;
|
||||
}
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("No certificate found\n"));
|
||||
success = false;
|
||||
goto out;
|
||||
}
|
||||
err = gnutls_x509_crt_import (cert, cert_list, GNUTLS_X509_FMT_DER);
|
||||
if (err < 0)
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("Error parsing certificate: %s\n"),
|
||||
gnutls_strerror (err));
|
||||
success = false;
|
||||
goto out;
|
||||
}
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("Error parsing certificate: %s\n"),
|
||||
gnutls_strerror (err));
|
||||
success = false;
|
||||
goto out;
|
||||
}
|
||||
if (now < gnutls_x509_crt_get_activation_time (cert))
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("The certificate has not yet been activated\n"));
|
||||
success = false;
|
||||
}
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("The certificate has not yet been activated\n"));
|
||||
success = false;
|
||||
}
|
||||
if (now >= gnutls_x509_crt_get_expiration_time (cert))
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("The certificate has expired\n"));
|
||||
success = false;
|
||||
}
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("The certificate has expired\n"));
|
||||
success = false;
|
||||
}
|
||||
if (!gnutls_x509_crt_check_hostname (cert, host))
|
||||
{
|
||||
logprintf (LOG_NOTQUIET,
|
||||
_("The certificate's owner does not match hostname '%s'\n"),
|
||||
host);
|
||||
success = false;
|
||||
}
|
||||
{
|
||||
logprintf (LOG_NOTQUIET,
|
||||
_("The certificate's owner does not match hostname '%s'\n"),
|
||||
host);
|
||||
success = false;
|
||||
}
|
||||
gnutls_x509_crt_deinit (cert);
|
||||
}
|
||||
|
||||
|
144
src/hash.c
144
src/hash.c
@ -156,14 +156,14 @@ struct hash_table {
|
||||
hashfun_t hash_function;
|
||||
testfun_t test_function;
|
||||
|
||||
struct cell *cells; /* contiguous array of cells. */
|
||||
int size; /* size of the array. */
|
||||
struct cell *cells; /* contiguous array of cells. */
|
||||
int size; /* size of the array. */
|
||||
|
||||
int count; /* number of occupied entries. */
|
||||
int resize_threshold; /* after size exceeds this number of
|
||||
entries, resize the table. */
|
||||
int prime_offset; /* the offset of the current prime in
|
||||
the prime table. */
|
||||
int count; /* number of occupied entries. */
|
||||
int resize_threshold; /* after size exceeds this number of
|
||||
entries, resize the table. */
|
||||
int prime_offset; /* the offset of the current prime in
|
||||
the prime table. */
|
||||
};
|
||||
|
||||
/* 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
|
||||
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))
|
||||
|
||||
/* 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++)
|
||||
if (primes[i] >= size)
|
||||
{
|
||||
/* Set the offset to the next prime. That is safe because,
|
||||
next time we are called, it will be with a larger SIZE,
|
||||
which means we could never return the same prime anyway.
|
||||
(If that is not the case, the caller can simply reset
|
||||
*prime_offset.) */
|
||||
*prime_offset = i + 1;
|
||||
return primes[i];
|
||||
/* Set the offset to the next prime. That is safe because,
|
||||
next time we are called, it will be with a larger SIZE,
|
||||
which means we could never return the same prime anyway.
|
||||
(If that is not the case, the caller can simply reset
|
||||
*prime_offset.) */
|
||||
*prime_offset = i + 1;
|
||||
return primes[i];
|
||||
}
|
||||
|
||||
abort ();
|
||||
@ -270,8 +270,8 @@ static int cmp_pointer (const void *, const void *);
|
||||
|
||||
struct hash_table *
|
||||
hash_table_new (int items,
|
||||
unsigned long (*hash_function) (const void *),
|
||||
int (*test_function) (const void *, const void *))
|
||||
unsigned long (*hash_function) (const void *),
|
||||
int (*test_function) (const void *, const void *))
|
||||
{
|
||||
int size;
|
||||
struct hash_table *ht = xnew (struct hash_table);
|
||||
@ -351,15 +351,15 @@ hash_table_get (const struct hash_table *ht, const void *key)
|
||||
|
||||
int
|
||||
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);
|
||||
if (CELL_OCCUPIED (c))
|
||||
{
|
||||
if (orig_key)
|
||||
*(void **)orig_key = c->key;
|
||||
*(void **)orig_key = c->key;
|
||||
if (value)
|
||||
*(void **)value = c->value;
|
||||
*(void **)value = c->value;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
@ -390,9 +390,9 @@ grow_hash_table (struct hash_table *ht)
|
||||
newsize = prime_size (ht->size * HASH_RESIZE_FACTOR, &ht->prime_offset);
|
||||
#if 0
|
||||
printf ("growing from %d to %d; fullness %.2f%% to %.2f%%\n",
|
||||
ht->size, newsize,
|
||||
100.0 * ht->count / ht->size,
|
||||
100.0 * ht->count / newsize);
|
||||
ht->size, newsize,
|
||||
100.0 * ht->count / ht->size,
|
||||
100.0 * ht->count / newsize);
|
||||
#endif
|
||||
|
||||
ht->size = newsize;
|
||||
@ -405,14 +405,14 @@ grow_hash_table (struct hash_table *ht)
|
||||
for (c = old_cells; c < old_end; c++)
|
||||
if (CELL_OCCUPIED (c))
|
||||
{
|
||||
struct cell *new_c;
|
||||
/* We don't need to test for uniqueness of keys because they
|
||||
come from the hash table and are therefore known to be
|
||||
unique. */
|
||||
new_c = cells + HASH_POSITION (c->key, hasher, newsize);
|
||||
FOREACH_OCCUPIED_ADJACENT (new_c, cells, newsize)
|
||||
;
|
||||
*new_c = *c;
|
||||
struct cell *new_c;
|
||||
/* We don't need to test for uniqueness of keys because they
|
||||
come from the hash table and are therefore known to be
|
||||
unique. */
|
||||
new_c = cells + HASH_POSITION (c->key, hasher, newsize);
|
||||
FOREACH_OCCUPIED_ADJACENT (new_c, cells, newsize)
|
||||
;
|
||||
*new_c = *c;
|
||||
}
|
||||
|
||||
xfree (old_cells);
|
||||
@ -443,7 +443,7 @@ hash_table_put (struct hash_table *ht, const void *key, void *value)
|
||||
|
||||
/* add new item */
|
||||
++ht->count;
|
||||
c->key = (void *)key; /* const? */
|
||||
c->key = (void *)key; /* const? */
|
||||
c->value = value;
|
||||
}
|
||||
|
||||
@ -466,30 +466,30 @@ hash_table_remove (struct hash_table *ht, const void *key)
|
||||
--ht->count;
|
||||
|
||||
/* Rehash all the entries following C. The alternative
|
||||
approach is to mark the entry as deleted, i.e. create a
|
||||
"tombstone". That speeds up removal, but leaves a lot of
|
||||
garbage and slows down hash_table_get and hash_table_put. */
|
||||
approach is to mark the entry as deleted, i.e. create a
|
||||
"tombstone". That speeds up removal, but leaves a lot of
|
||||
garbage and slows down hash_table_get and hash_table_put. */
|
||||
|
||||
c = NEXT_CELL (c, cells, size);
|
||||
FOREACH_OCCUPIED_ADJACENT (c, cells, size)
|
||||
{
|
||||
const void *key2 = c->key;
|
||||
struct cell *c_new;
|
||||
{
|
||||
const void *key2 = c->key;
|
||||
struct cell *c_new;
|
||||
|
||||
/* Find the new location for the key. */
|
||||
c_new = cells + HASH_POSITION (key2, hasher, size);
|
||||
FOREACH_OCCUPIED_ADJACENT (c_new, cells, size)
|
||||
if (key2 == c_new->key)
|
||||
/* The cell C (key2) is already where we want it (in
|
||||
C_NEW's "chain" of keys.) */
|
||||
goto next_rehash;
|
||||
/* Find the new location for the key. */
|
||||
c_new = cells + HASH_POSITION (key2, hasher, size);
|
||||
FOREACH_OCCUPIED_ADJACENT (c_new, cells, size)
|
||||
if (key2 == c_new->key)
|
||||
/* The cell C (key2) is already where we want it (in
|
||||
C_NEW's "chain" of keys.) */
|
||||
goto next_rehash;
|
||||
|
||||
*c_new = *c;
|
||||
CLEAR_CELL (c);
|
||||
*c_new = *c;
|
||||
CLEAR_CELL (c);
|
||||
|
||||
next_rehash:
|
||||
;
|
||||
}
|
||||
next_rehash:
|
||||
;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -518,7 +518,7 @@ hash_table_clear (struct hash_table *ht)
|
||||
|
||||
void
|
||||
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 *end = ht->cells + ht->size;
|
||||
@ -526,14 +526,14 @@ hash_table_for_each (struct hash_table *ht,
|
||||
for (; c < end; c++)
|
||||
if (CELL_OCCUPIED (c))
|
||||
{
|
||||
void *key;
|
||||
void *key;
|
||||
repeat:
|
||||
key = c->key;
|
||||
if (fn (key, c->value, arg))
|
||||
return;
|
||||
/* hash_table_remove might have moved the adjacent cells. */
|
||||
if (c->key != key && CELL_OCCUPIED (c))
|
||||
goto repeat;
|
||||
key = c->key;
|
||||
if (fn (key, c->value, arg))
|
||||
return;
|
||||
/* hash_table_remove might have moved the adjacent cells. */
|
||||
if (c->key != key && CELL_OCCUPIED (c))
|
||||
goto repeat;
|
||||
}
|
||||
}
|
||||
|
||||
@ -571,10 +571,10 @@ hash_table_iter_next (hash_table_iterator *iter)
|
||||
for (; c < end; c++)
|
||||
if (CELL_OCCUPIED (c))
|
||||
{
|
||||
iter->key = c->key;
|
||||
iter->value = c->value;
|
||||
iter->pos = c + 1;
|
||||
return 1;
|
||||
iter->key = c->key;
|
||||
iter->value = c->value;
|
||||
iter->pos = c + 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -770,20 +770,20 @@ main (void)
|
||||
{
|
||||
int len = strlen (line);
|
||||
if (len <= 1)
|
||||
continue;
|
||||
continue;
|
||||
line[--len] = '\0';
|
||||
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 (len % 5 == 0)
|
||||
{
|
||||
char *line_copy;
|
||||
if (hash_table_get_pair (ht, line, &line_copy, NULL))
|
||||
{
|
||||
hash_table_remove (ht, line);
|
||||
xfree (line_copy);
|
||||
}
|
||||
}
|
||||
{
|
||||
char *line_copy;
|
||||
if (hash_table_get_pair (ht, line, &line_copy, NULL))
|
||||
{
|
||||
hash_table_remove (ht, line);
|
||||
xfree (line_copy);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if 0
|
||||
|
298
src/host.c
298
src/host.c
@ -61,16 +61,16 @@ so, delete this exception statement from your version. */
|
||||
lookup_host for details. */
|
||||
|
||||
struct address_list {
|
||||
int count; /* number of adrresses */
|
||||
ip_address *addresses; /* pointer to the string of addresses */
|
||||
int count; /* number of adrresses */
|
||||
ip_address *addresses; /* pointer to the string of addresses */
|
||||
|
||||
int faulty; /* number of addresses known not to work. */
|
||||
bool connected; /* whether we were able to connect to
|
||||
one of the addresses in the list,
|
||||
at least once. */
|
||||
int faulty; /* number of addresses known not to work. */
|
||||
bool connected; /* whether we were able to connect to
|
||||
one of the addresses in the list,
|
||||
at least once. */
|
||||
|
||||
int refcount; /* reference count; when it drops to
|
||||
0, the entry is freed. */
|
||||
int refcount; /* reference count; when it drops to
|
||||
0, the entry is freed. */
|
||||
};
|
||||
|
||||
/* 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:
|
||||
for (i = 0; i < al->count; i++)
|
||||
{
|
||||
ip_address *cur = al->addresses + i;
|
||||
if (cur->family == AF_INET
|
||||
&& (cur->data.d4.s_addr == ip->data.d4.s_addr))
|
||||
return true;
|
||||
}
|
||||
{
|
||||
ip_address *cur = al->addresses + i;
|
||||
if (cur->family == AF_INET
|
||||
&& (cur->data.d4.s_addr == ip->data.d4.s_addr))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
#ifdef ENABLE_IPV6
|
||||
case AF_INET6:
|
||||
for (i = 0; i < al->count; i++)
|
||||
{
|
||||
ip_address *cur = al->addresses + i;
|
||||
if (cur->family == AF_INET6
|
||||
{
|
||||
ip_address *cur = al->addresses + i;
|
||||
if (cur->family == AF_INET6
|
||||
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
|
||||
&& cur->ipv6_scope == ip->ipv6_scope
|
||||
&& cur->ipv6_scope == ip->ipv6_scope
|
||||
#endif
|
||||
&& IN6_ARE_ADDR_EQUAL (&cur->data.d6, &ip->data.d6))
|
||||
return true;
|
||||
}
|
||||
&& IN6_ARE_ADDR_EQUAL (&cur->data.d6, &ip->data.d6))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
#endif /* ENABLE_IPV6 */
|
||||
default:
|
||||
@ -193,22 +193,22 @@ address_list_from_addrinfo (const struct addrinfo *ai)
|
||||
for (ptr = ai; ptr != NULL; ptr = ptr->ai_next)
|
||||
if (ptr->ai_family == AF_INET6)
|
||||
{
|
||||
const struct sockaddr_in6 *sin6 =
|
||||
(const struct sockaddr_in6 *)ptr->ai_addr;
|
||||
ip->family = AF_INET6;
|
||||
ip->data.d6 = sin6->sin6_addr;
|
||||
const struct sockaddr_in6 *sin6 =
|
||||
(const struct sockaddr_in6 *)ptr->ai_addr;
|
||||
ip->family = AF_INET6;
|
||||
ip->data.d6 = sin6->sin6_addr;
|
||||
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
|
||||
ip->ipv6_scope = sin6->sin6_scope_id;
|
||||
ip->ipv6_scope = sin6->sin6_scope_id;
|
||||
#endif
|
||||
++ip;
|
||||
++ip;
|
||||
}
|
||||
else if (ptr->ai_family == AF_INET)
|
||||
{
|
||||
const struct sockaddr_in *sin =
|
||||
(const struct sockaddr_in *)ptr->ai_addr;
|
||||
ip->family = AF_INET;
|
||||
ip->data.d4 = sin->sin_addr;
|
||||
++ip;
|
||||
const struct sockaddr_in *sin =
|
||||
(const struct sockaddr_in *)ptr->ai_addr;
|
||||
ip->family = AF_INET;
|
||||
ip->data.d4 = sin->sin_addr;
|
||||
++ip;
|
||||
}
|
||||
assert (ip - al->addresses == cnt);
|
||||
return al;
|
||||
@ -288,7 +288,7 @@ address_list_release (struct address_list *al)
|
||||
{
|
||||
--al->refcount;
|
||||
DEBUGP (("Releasing 0x%0*lx (new refcount %d).\n", PTR_FORMAT (al),
|
||||
al->refcount));
|
||||
al->refcount));
|
||||
if (al->refcount <= 0)
|
||||
{
|
||||
DEBUGP (("Deleting unused 0x%0*lx.\n", PTR_FORMAT (al)));
|
||||
@ -376,8 +376,8 @@ getaddrinfo_with_timeout_callback (void *arg)
|
||||
|
||||
static int
|
||||
getaddrinfo_with_timeout (const char *node, const char *service,
|
||||
const struct addrinfo *hints, struct addrinfo **res,
|
||||
double timeout)
|
||||
const struct addrinfo *hints, struct addrinfo **res,
|
||||
double timeout)
|
||||
{
|
||||
struct gaiwt_context ctx;
|
||||
ctx.node = node;
|
||||
@ -427,27 +427,27 @@ is_valid_ipv4_address (const char *str, const char *end)
|
||||
int ch = *str++;
|
||||
|
||||
if (ch >= '0' && ch <= '9')
|
||||
{
|
||||
val = val * 10 + (ch - '0');
|
||||
{
|
||||
val = val * 10 + (ch - '0');
|
||||
|
||||
if (val > 255)
|
||||
return false;
|
||||
if (!saw_digit)
|
||||
{
|
||||
if (++octets > 4)
|
||||
return false;
|
||||
saw_digit = true;
|
||||
}
|
||||
}
|
||||
if (val > 255)
|
||||
return false;
|
||||
if (!saw_digit)
|
||||
{
|
||||
if (++octets > 4)
|
||||
return false;
|
||||
saw_digit = true;
|
||||
}
|
||||
}
|
||||
else if (ch == '.' && saw_digit)
|
||||
{
|
||||
if (octets == 4)
|
||||
return false;
|
||||
val = 0;
|
||||
saw_digit = false;
|
||||
}
|
||||
{
|
||||
if (octets == 4)
|
||||
return false;
|
||||
val = 0;
|
||||
saw_digit = false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
if (octets < 4)
|
||||
return false;
|
||||
@ -482,7 +482,7 @@ is_valid_ipv6_address (const char *str, const char *end)
|
||||
{
|
||||
++str;
|
||||
if (str == end || *str != ':')
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
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 (ISXDIGIT (ch))
|
||||
{
|
||||
val <<= 4;
|
||||
val |= XDIGIT_TO_NUM (ch);
|
||||
if (val > 0xffff)
|
||||
return false;
|
||||
saw_xdigit = true;
|
||||
continue;
|
||||
}
|
||||
{
|
||||
val <<= 4;
|
||||
val |= XDIGIT_TO_NUM (ch);
|
||||
if (val > 0xffff)
|
||||
return false;
|
||||
saw_xdigit = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if ch is a colon ... */
|
||||
if (ch == ':')
|
||||
{
|
||||
curtok = str;
|
||||
if (!saw_xdigit)
|
||||
{
|
||||
if (colonp != NULL)
|
||||
return false;
|
||||
colonp = str + tp;
|
||||
continue;
|
||||
}
|
||||
else if (str == end)
|
||||
return false;
|
||||
if (tp > ns_in6addrsz - ns_int16sz)
|
||||
return false;
|
||||
tp += ns_int16sz;
|
||||
saw_xdigit = false;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
{
|
||||
curtok = str;
|
||||
if (!saw_xdigit)
|
||||
{
|
||||
if (colonp != NULL)
|
||||
return false;
|
||||
colonp = str + tp;
|
||||
continue;
|
||||
}
|
||||
else if (str == end)
|
||||
return false;
|
||||
if (tp > ns_in6addrsz - ns_int16sz)
|
||||
return false;
|
||||
tp += ns_int16sz;
|
||||
saw_xdigit = false;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if ch is a dot ... */
|
||||
if (ch == '.' && (tp <= ns_in6addrsz - ns_inaddrsz)
|
||||
&& is_valid_ipv4_address (curtok, end) == 1)
|
||||
{
|
||||
tp += ns_inaddrsz;
|
||||
saw_xdigit = false;
|
||||
break;
|
||||
}
|
||||
&& is_valid_ipv4_address (curtok, end) == 1)
|
||||
{
|
||||
tp += ns_inaddrsz;
|
||||
saw_xdigit = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -540,14 +540,14 @@ is_valid_ipv6_address (const char *str, const char *end)
|
||||
if (saw_xdigit)
|
||||
{
|
||||
if (tp > ns_in6addrsz - ns_int16sz)
|
||||
return false;
|
||||
return false;
|
||||
tp += ns_int16sz;
|
||||
}
|
||||
|
||||
if (colonp != NULL)
|
||||
{
|
||||
if (tp == ns_in6addrsz)
|
||||
return false;
|
||||
return false;
|
||||
tp = ns_in6addrsz;
|
||||
}
|
||||
|
||||
@ -602,7 +602,7 @@ cache_store (const char *host, struct address_list *al)
|
||||
int i;
|
||||
debug_logprintf ("Caching %s =>", host);
|
||||
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");
|
||||
}
|
||||
}
|
||||
@ -642,7 +642,7 @@ cache_remove (const char *host)
|
||||
LH_SILENT - don't print the "resolving ... done" messages.
|
||||
LH_BIND - resolve addresses for use with bind, which under
|
||||
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
|
||||
and resolve it anew. */
|
||||
|
||||
@ -664,12 +664,12 @@ lookup_host (const char *host, int flags)
|
||||
uint32_t addr_ipv4 = (uint32_t)inet_addr (host);
|
||||
if (addr_ipv4 != (uint32_t) -1)
|
||||
{
|
||||
/* No need to cache host->addr relation, just return the
|
||||
address. */
|
||||
char *vec[2];
|
||||
vec[0] = (char *)&addr_ipv4;
|
||||
vec[1] = NULL;
|
||||
return address_list_from_ipv4_addresses (vec);
|
||||
/* No need to cache host->addr relation, just return the
|
||||
address. */
|
||||
char *vec[2];
|
||||
vec[0] = (char *)&addr_ipv4;
|
||||
vec[1] = NULL;
|
||||
return address_list_from_ipv4_addresses (vec);
|
||||
}
|
||||
}
|
||||
#else /* ENABLE_IPV6 */
|
||||
@ -699,13 +699,13 @@ lookup_host (const char *host, int flags)
|
||||
if (use_cache)
|
||||
{
|
||||
if (!(flags & LH_REFRESH))
|
||||
{
|
||||
al = cache_query (host);
|
||||
if (al)
|
||||
return al;
|
||||
}
|
||||
{
|
||||
al = cache_query (host);
|
||||
if (al)
|
||||
return al;
|
||||
}
|
||||
else
|
||||
cache_remove (host);
|
||||
cache_remove (host);
|
||||
}
|
||||
|
||||
/* No luck with the cache; resolve HOST. */
|
||||
@ -726,9 +726,9 @@ lookup_host (const char *host, int flags)
|
||||
hints.ai_family = AF_INET6;
|
||||
else
|
||||
/* We tried using AI_ADDRCONFIG, but removed it because: it
|
||||
misinterprets IPv6 loopbacks, it is broken on AIX 5.1, and
|
||||
it's unneeded since we sort the addresses anyway. */
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
misinterprets IPv6 loopbacks, it is broken on AIX 5.1, and
|
||||
it's unneeded since we sort the addresses anyway. */
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
|
||||
if (flags & LH_BIND)
|
||||
hints.ai_flags |= AI_PASSIVE;
|
||||
@ -736,30 +736,30 @@ lookup_host (const char *host, int flags)
|
||||
#ifdef AI_NUMERICHOST
|
||||
if (numeric_address)
|
||||
{
|
||||
/* Where available, the AI_NUMERICHOST hint can prevent costly
|
||||
access to DNS servers. */
|
||||
hints.ai_flags |= AI_NUMERICHOST;
|
||||
timeout = 0; /* no timeout needed when "resolving"
|
||||
numeric hosts -- avoid setting up
|
||||
signal handlers and such. */
|
||||
/* Where available, the AI_NUMERICHOST hint can prevent costly
|
||||
access to DNS servers. */
|
||||
hints.ai_flags |= AI_NUMERICHOST;
|
||||
timeout = 0; /* no timeout needed when "resolving"
|
||||
numeric hosts -- avoid setting up
|
||||
signal handlers and such. */
|
||||
}
|
||||
#endif
|
||||
|
||||
err = getaddrinfo_with_timeout (host, NULL, &hints, &res, timeout);
|
||||
if (err != 0 || res == NULL)
|
||||
{
|
||||
if (!silent)
|
||||
logprintf (LOG_VERBOSE, _("failed: %s.\n"),
|
||||
err != EAI_SYSTEM ? gai_strerror (err) : strerror (errno));
|
||||
return NULL;
|
||||
if (!silent)
|
||||
logprintf (LOG_VERBOSE, _("failed: %s.\n"),
|
||||
err != EAI_SYSTEM ? gai_strerror (err) : strerror (errno));
|
||||
return NULL;
|
||||
}
|
||||
al = address_list_from_addrinfo (res);
|
||||
freeaddrinfo (res);
|
||||
if (!al)
|
||||
{
|
||||
logprintf (LOG_VERBOSE,
|
||||
_("failed: No IPv4/IPv6 addresses for host.\n"));
|
||||
return NULL;
|
||||
logprintf (LOG_VERBOSE,
|
||||
_("failed: No IPv4/IPv6 addresses for host.\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
if (al->count > 1 && opt.prefer_family != prefer_none)
|
||||
stable_sort (al->addresses, al->count, sizeof (ip_address),
|
||||
opt.prefer_family == prefer_ipv4
|
||||
? cmp_prefer_ipv4 : cmp_prefer_ipv6);
|
||||
opt.prefer_family == prefer_ipv4
|
||||
? cmp_prefer_ipv4 : cmp_prefer_ipv6);
|
||||
}
|
||||
#else /* not ENABLE_IPV6 */
|
||||
{
|
||||
struct hostent *hptr = gethostbyname_with_timeout (host, timeout);
|
||||
if (!hptr)
|
||||
{
|
||||
if (!silent)
|
||||
{
|
||||
if (errno != ETIMEDOUT)
|
||||
logprintf (LOG_VERBOSE, _("failed: %s.\n"),
|
||||
host_errstr (h_errno));
|
||||
else
|
||||
logputs (LOG_VERBOSE, _("failed: timed out.\n"));
|
||||
}
|
||||
return NULL;
|
||||
if (!silent)
|
||||
{
|
||||
if (errno != ETIMEDOUT)
|
||||
logprintf (LOG_VERBOSE, _("failed: %s.\n"),
|
||||
host_errstr (h_errno));
|
||||
else
|
||||
logputs (LOG_VERBOSE, _("failed: timed out.\n"));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/* Do older systems have 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 printmax = al->count <= 3 ? al->count : 3;
|
||||
for (i = 0; i < printmax; i++)
|
||||
{
|
||||
logputs (LOG_VERBOSE, print_address (al->addresses + i));
|
||||
if (i < printmax - 1)
|
||||
logputs (LOG_VERBOSE, ", ");
|
||||
}
|
||||
{
|
||||
logputs (LOG_VERBOSE, print_address (al->addresses + i));
|
||||
if (i < printmax - 1)
|
||||
logputs (LOG_VERBOSE, ", ");
|
||||
}
|
||||
if (printmax != al->count)
|
||||
logputs (LOG_VERBOSE, ", ...");
|
||||
logputs (LOG_VERBOSE, ", ...");
|
||||
logputs (LOG_VERBOSE, "\n");
|
||||
}
|
||||
|
||||
@ -823,12 +823,12 @@ accept_domain (struct url *u)
|
||||
if (opt.domains)
|
||||
{
|
||||
if (!sufmatch ((const char **)opt.domains, u->host))
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
if (opt.exclude_domains)
|
||||
{
|
||||
if (sufmatch ((const char **)opt.exclude_domains, u->host))
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -847,11 +847,11 @@ sufmatch (const char **list, const char *what)
|
||||
for (i = 0; list[i]; i++)
|
||||
{
|
||||
for (j = strlen (list[i]), k = lw; j >= 0 && k >= 0; j--, k--)
|
||||
if (TOLOWER (list[i][j]) != TOLOWER (what[k]))
|
||||
break;
|
||||
if (TOLOWER (list[i][j]) != TOLOWER (what[k]))
|
||||
break;
|
||||
/* The domain must be first to reach to beginning. */
|
||||
if (j == -1)
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -863,15 +863,15 @@ host_cleanup (void)
|
||||
{
|
||||
hash_table_iterator iter;
|
||||
for (hash_table_iterate (host_name_addresses_map, &iter);
|
||||
hash_table_iter_next (&iter);
|
||||
)
|
||||
{
|
||||
char *host = iter.key;
|
||||
struct address_list *al = iter.value;
|
||||
xfree (host);
|
||||
assert (al->refcount == 1);
|
||||
address_list_delete (al);
|
||||
}
|
||||
hash_table_iter_next (&iter);
|
||||
)
|
||||
{
|
||||
char *host = iter.key;
|
||||
struct address_list *al = iter.value;
|
||||
xfree (host);
|
||||
assert (al->refcount == 1);
|
||||
address_list_delete (al);
|
||||
}
|
||||
hash_table_destroy (host_name_addresses_map);
|
||||
host_name_addresses_map = NULL;
|
||||
}
|
||||
|
848
src/html-parse.c
848
src/html-parse.c
File diff suppressed because it is too large
Load Diff
382
src/html-url.c
382
src/html-url.c
@ -40,13 +40,13 @@ so, delete this exception statement from your version. */
|
||||
#include "utils.h"
|
||||
#include "hash.h"
|
||||
#include "convert.h"
|
||||
#include "recur.h" /* declaration of get_urls_html */
|
||||
#include "recur.h" /* declaration of get_urls_html */
|
||||
|
||||
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 *)
|
||||
|
||||
DECLARE_TAG_HANDLER (tag_find_urls);
|
||||
@ -87,28 +87,28 @@ static struct known_tag {
|
||||
const char *name;
|
||||
tag_handler_t handler;
|
||||
} known_tags[] = {
|
||||
{ TAG_A, "a", tag_find_urls },
|
||||
{ TAG_APPLET, "applet", tag_find_urls },
|
||||
{ TAG_AREA, "area", tag_find_urls },
|
||||
{ TAG_BASE, "base", tag_handle_base },
|
||||
{ TAG_BGSOUND, "bgsound", tag_find_urls },
|
||||
{ TAG_BODY, "body", tag_find_urls },
|
||||
{ TAG_EMBED, "embed", tag_find_urls },
|
||||
{ TAG_FIG, "fig", tag_find_urls },
|
||||
{ TAG_FORM, "form", tag_handle_form },
|
||||
{ TAG_FRAME, "frame", tag_find_urls },
|
||||
{ TAG_IFRAME, "iframe", tag_find_urls },
|
||||
{ TAG_IMG, "img", tag_find_urls },
|
||||
{ TAG_INPUT, "input", tag_find_urls },
|
||||
{ TAG_LAYER, "layer", tag_find_urls },
|
||||
{ TAG_LINK, "link", tag_handle_link },
|
||||
{ TAG_META, "meta", tag_handle_meta },
|
||||
{ TAG_OBJECT, "object", tag_find_urls },
|
||||
{ TAG_OVERLAY, "overlay", tag_find_urls },
|
||||
{ TAG_SCRIPT, "script", tag_find_urls },
|
||||
{ TAG_TABLE, "table", tag_find_urls },
|
||||
{ TAG_TD, "td", tag_find_urls },
|
||||
{ TAG_TH, "th", tag_find_urls }
|
||||
{ TAG_A, "a", tag_find_urls },
|
||||
{ TAG_APPLET, "applet", tag_find_urls },
|
||||
{ TAG_AREA, "area", tag_find_urls },
|
||||
{ TAG_BASE, "base", tag_handle_base },
|
||||
{ TAG_BGSOUND, "bgsound", tag_find_urls },
|
||||
{ TAG_BODY, "body", tag_find_urls },
|
||||
{ TAG_EMBED, "embed", tag_find_urls },
|
||||
{ TAG_FIG, "fig", tag_find_urls },
|
||||
{ TAG_FORM, "form", tag_handle_form },
|
||||
{ TAG_FRAME, "frame", tag_find_urls },
|
||||
{ TAG_IFRAME, "iframe", tag_find_urls },
|
||||
{ TAG_IMG, "img", tag_find_urls },
|
||||
{ TAG_INPUT, "input", tag_find_urls },
|
||||
{ TAG_LAYER, "layer", tag_find_urls },
|
||||
{ TAG_LINK, "link", tag_handle_link },
|
||||
{ TAG_META, "meta", tag_handle_meta },
|
||||
{ TAG_OBJECT, "object", tag_find_urls },
|
||||
{ TAG_OVERLAY, "overlay", tag_find_urls },
|
||||
{ TAG_SCRIPT, "script", tag_find_urls },
|
||||
{ TAG_TABLE, "table", tag_find_urls },
|
||||
{ TAG_TD, "td", tag_find_urls },
|
||||
{ TAG_TH, "th", tag_find_urls }
|
||||
};
|
||||
|
||||
/* 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
|
||||
to be correctly rendered. Inline links include inlined images,
|
||||
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
|
||||
try to follow HTML obtained by following e.g. <img src="...">
|
||||
regardless of content-type. Doing this causes infinite loops for
|
||||
"images" that return non-404 error pages with links to the same
|
||||
image. */
|
||||
#define ATTR_HTML 2
|
||||
#define ATTR_HTML 2
|
||||
|
||||
/* For tags handled by tag_find_urls: attributes that contain URLs to
|
||||
download. */
|
||||
@ -135,38 +135,38 @@ static struct {
|
||||
const char *attr_name;
|
||||
int flags;
|
||||
} tag_url_attributes[] = {
|
||||
{ TAG_A, "href", ATTR_HTML },
|
||||
{ TAG_APPLET, "code", ATTR_INLINE },
|
||||
{ TAG_AREA, "href", ATTR_HTML },
|
||||
{ TAG_BGSOUND, "src", ATTR_INLINE },
|
||||
{ TAG_BODY, "background", ATTR_INLINE },
|
||||
{ TAG_EMBED, "href", ATTR_HTML },
|
||||
{ TAG_EMBED, "src", ATTR_INLINE | ATTR_HTML },
|
||||
{ TAG_FIG, "src", ATTR_INLINE },
|
||||
{ TAG_FRAME, "src", ATTR_INLINE | ATTR_HTML },
|
||||
{ TAG_IFRAME, "src", ATTR_INLINE | ATTR_HTML },
|
||||
{ TAG_IMG, "href", ATTR_INLINE },
|
||||
{ TAG_IMG, "lowsrc", ATTR_INLINE },
|
||||
{ TAG_IMG, "src", ATTR_INLINE },
|
||||
{ TAG_INPUT, "src", ATTR_INLINE },
|
||||
{ TAG_LAYER, "src", ATTR_INLINE | ATTR_HTML },
|
||||
{ TAG_OBJECT, "data", ATTR_INLINE },
|
||||
{ TAG_OVERLAY, "src", ATTR_INLINE | ATTR_HTML },
|
||||
{ TAG_SCRIPT, "src", ATTR_INLINE },
|
||||
{ TAG_TABLE, "background", ATTR_INLINE },
|
||||
{ TAG_TD, "background", ATTR_INLINE },
|
||||
{ TAG_TH, "background", ATTR_INLINE }
|
||||
{ TAG_A, "href", ATTR_HTML },
|
||||
{ TAG_APPLET, "code", ATTR_INLINE },
|
||||
{ TAG_AREA, "href", ATTR_HTML },
|
||||
{ TAG_BGSOUND, "src", ATTR_INLINE },
|
||||
{ TAG_BODY, "background", ATTR_INLINE },
|
||||
{ TAG_EMBED, "href", ATTR_HTML },
|
||||
{ TAG_EMBED, "src", ATTR_INLINE | ATTR_HTML },
|
||||
{ TAG_FIG, "src", ATTR_INLINE },
|
||||
{ TAG_FRAME, "src", ATTR_INLINE | ATTR_HTML },
|
||||
{ TAG_IFRAME, "src", ATTR_INLINE | ATTR_HTML },
|
||||
{ TAG_IMG, "href", ATTR_INLINE },
|
||||
{ TAG_IMG, "lowsrc", ATTR_INLINE },
|
||||
{ TAG_IMG, "src", ATTR_INLINE },
|
||||
{ TAG_INPUT, "src", ATTR_INLINE },
|
||||
{ TAG_LAYER, "src", ATTR_INLINE | ATTR_HTML },
|
||||
{ TAG_OBJECT, "data", ATTR_INLINE },
|
||||
{ TAG_OVERLAY, "src", ATTR_INLINE | ATTR_HTML },
|
||||
{ TAG_SCRIPT, "src", ATTR_INLINE },
|
||||
{ TAG_TABLE, "background", ATTR_INLINE },
|
||||
{ TAG_TD, "background", ATTR_INLINE },
|
||||
{ TAG_TH, "background", ATTR_INLINE }
|
||||
};
|
||||
|
||||
/* The lists of interesting tags and attributes are built dynamically,
|
||||
from the information above. However, some places in the code refer
|
||||
to the attributes not mentioned here. We add them manually. */
|
||||
static const char *additional_attributes[] = {
|
||||
"rel", /* used by tag_handle_link */
|
||||
"http-equiv", /* used by tag_handle_meta */
|
||||
"name", /* used by tag_handle_meta */
|
||||
"content", /* used by tag_handle_meta */
|
||||
"action" /* used by tag_handle_form */
|
||||
"rel", /* used by tag_handle_link */
|
||||
"http-equiv", /* used by tag_handle_meta */
|
||||
"name", /* used by tag_handle_meta */
|
||||
"content", /* used by tag_handle_meta */
|
||||
"action" /* used by tag_handle_form */
|
||||
};
|
||||
|
||||
static struct hash_table *interesting_tags;
|
||||
@ -197,23 +197,23 @@ init_interesting (void)
|
||||
{
|
||||
char **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 (opt.follow_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);
|
||||
char **followed;
|
||||
for (followed = opt.follow_tags; *followed; followed++)
|
||||
{
|
||||
struct known_tag *t = hash_table_get (interesting_tags, *followed);
|
||||
if (!t)
|
||||
continue; /* ignore unknown --follow-tags entries. */
|
||||
hash_table_put (intersect, *followed, t);
|
||||
}
|
||||
{
|
||||
struct known_tag *t = hash_table_get (interesting_tags, *followed);
|
||||
if (!t)
|
||||
continue; /* ignore unknown --follow-tags entries. */
|
||||
hash_table_put (intersect, *followed, t);
|
||||
}
|
||||
hash_table_destroy (interesting_tags);
|
||||
interesting_tags = intersect;
|
||||
}
|
||||
@ -224,7 +224,7 @@ init_interesting (void)
|
||||
hash_table_put (interesting_attributes, additional_attributes[i], "1");
|
||||
for (i = 0; i < countof (tag_url_attributes); i++)
|
||||
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
|
||||
@ -238,24 +238,24 @@ find_attr (struct taginfo *tag, const char *name, int *attrind)
|
||||
for (i = 0; i < tag->nattrs; i++)
|
||||
if (!strcasecmp (tag->attrs[i].name, name))
|
||||
{
|
||||
if (attrind)
|
||||
*attrind = i;
|
||||
return tag->attrs[i].value;
|
||||
if (attrind)
|
||||
*attrind = i;
|
||||
return tag->attrs[i].value;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct map_context {
|
||||
char *text; /* HTML text. */
|
||||
char *base; /* Base URI of the document, possibly
|
||||
changed through <base href=...>. */
|
||||
const char *parent_base; /* Base of the current document. */
|
||||
const char *document_file; /* File name of this document. */
|
||||
bool nofollow; /* whether NOFOLLOW was specified in a
|
||||
char *text; /* HTML text. */
|
||||
char *base; /* Base URI of the document, possibly
|
||||
changed through <base href=...>. */
|
||||
const char *parent_base; /* Base of the current document. */
|
||||
const char *document_file; /* File name of this document. */
|
||||
bool nofollow; /* whether NOFOLLOW was specified in a
|
||||
<meta name=robots> tag. */
|
||||
|
||||
struct urlpos *head, *tail; /* List of URLs that is being
|
||||
built. */
|
||||
struct urlpos *head, *tail; /* List of URLs 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 *
|
||||
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);
|
||||
struct urlpos *newel;
|
||||
@ -276,47 +276,47 @@ append_url (const char *link_uri,
|
||||
if (!base)
|
||||
{
|
||||
DEBUGP (("%s: no base, merge will use \"%s\".\n",
|
||||
ctx->document_file, link_uri));
|
||||
ctx->document_file, link_uri));
|
||||
|
||||
if (!link_has_scheme)
|
||||
{
|
||||
/* Base URL is unavailable, and the link does not have a
|
||||
location attached to it -- we have to give up. Since
|
||||
this can only happen when using `--force-html -i', print
|
||||
a warning. */
|
||||
logprintf (LOG_NOTQUIET,
|
||||
_("%s: Cannot resolve incomplete link %s.\n"),
|
||||
ctx->document_file, link_uri);
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
/* Base URL is unavailable, and the link does not have a
|
||||
location attached to it -- we have to give up. Since
|
||||
this can only happen when using `--force-html -i', print
|
||||
a warning. */
|
||||
logprintf (LOG_NOTQUIET,
|
||||
_("%s: Cannot resolve incomplete link %s.\n"),
|
||||
ctx->document_file, link_uri);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
url = url_parse (link_uri, NULL);
|
||||
if (!url)
|
||||
{
|
||||
DEBUGP (("%s: link \"%s\" doesn't parse.\n",
|
||||
ctx->document_file, link_uri));
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
DEBUGP (("%s: link \"%s\" doesn't parse.\n",
|
||||
ctx->document_file, link_uri));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Merge BASE with LINK_URI, but also make sure the result is
|
||||
canonicalized, i.e. that "../" have been resolved.
|
||||
(parse_url will do that for us.) */
|
||||
canonicalized, i.e. that "../" have been resolved.
|
||||
(parse_url will do that for us.) */
|
||||
|
||||
char *complete_uri = uri_merge (base, link_uri);
|
||||
|
||||
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);
|
||||
if (!url)
|
||||
{
|
||||
DEBUGP (("%s: merged link \"%s\" doesn't parse.\n",
|
||||
ctx->document_file, complete_uri));
|
||||
xfree (complete_uri);
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
DEBUGP (("%s: merged link \"%s\" doesn't parse.\n",
|
||||
ctx->document_file, complete_uri));
|
||||
xfree (complete_uri);
|
||||
return NULL;
|
||||
}
|
||||
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++)
|
||||
if (tag_url_attributes[i].tagid == tagid)
|
||||
{
|
||||
/* We've found the index of tag_url_attributes where the
|
||||
attributes of our tag begin. */
|
||||
first = i;
|
||||
break;
|
||||
/* We've found the index of tag_url_attributes where the
|
||||
attributes of our tag begin. */
|
||||
first = i;
|
||||
break;
|
||||
}
|
||||
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++)
|
||||
{
|
||||
/* Find whether TAG/ATTRIND is a combination that contains a
|
||||
URL. */
|
||||
URL. */
|
||||
char *link = tag->attrs[attrind].value;
|
||||
const int size = countof (tag_url_attributes);
|
||||
|
||||
/* If you're cringing at the inefficiency of the nested loops,
|
||||
remember that they both iterate over a very small number of
|
||||
items. The worst-case inner loop is for the IMG tag, which
|
||||
has three attributes. */
|
||||
remember that they both iterate over a very small number of
|
||||
items. The worst-case inner loop is for the IMG tag, which
|
||||
has three attributes. */
|
||||
for (i = first; i < size && tag_url_attributes[i].tagid == tagid; i++)
|
||||
{
|
||||
if (0 == strcasecmp (tag->attrs[attrind].name,
|
||||
tag_url_attributes[i].attr_name))
|
||||
{
|
||||
struct urlpos *up = append_url (link, tag, attrind, ctx);
|
||||
if (up)
|
||||
{
|
||||
int flags = tag_url_attributes[i].flags;
|
||||
if (flags & ATTR_INLINE)
|
||||
up->link_inline_p = 1;
|
||||
if (flags & ATTR_HTML)
|
||||
up->link_expect_html = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
if (0 == strcasecmp (tag->attrs[attrind].name,
|
||||
tag_url_attributes[i].attr_name))
|
||||
{
|
||||
struct urlpos *up = append_url (link, tag, attrind, ctx);
|
||||
if (up)
|
||||
{
|
||||
int flags = tag_url_attributes[i].flags;
|
||||
if (flags & ATTR_INLINE)
|
||||
up->link_inline_p = 1;
|
||||
if (flags & ATTR_HTML)
|
||||
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);
|
||||
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);
|
||||
if (up)
|
||||
{
|
||||
char *rel = find_attr (tag, "rel", NULL);
|
||||
if (rel
|
||||
&& (0 == strcasecmp (rel, "stylesheet")
|
||||
|| 0 == strcasecmp (rel, "shortcut icon")))
|
||||
up->link_inline_p = 1;
|
||||
else
|
||||
/* The external ones usually point to HTML pages, such as
|
||||
<link rel="next" href="..."> */
|
||||
up->link_expect_html = 1;
|
||||
}
|
||||
{
|
||||
char *rel = find_attr (tag, "rel", NULL);
|
||||
if (rel
|
||||
&& (0 == strcasecmp (rel, "stylesheet")
|
||||
|| 0 == strcasecmp (rel, "shortcut icon")))
|
||||
up->link_inline_p = 1;
|
||||
else
|
||||
/* The external ones usually point to HTML pages, such as
|
||||
<link rel="next" href="..."> */
|
||||
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"))
|
||||
{
|
||||
/* Some pages use a META tag to specify that the page be
|
||||
refreshed by a new page after a given number of seconds. The
|
||||
general format for this is:
|
||||
refreshed by a new page after a given number of seconds. The
|
||||
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
|
||||
get to the URL. */
|
||||
So we just need to skip past the "NUMBER; URL=" garbage to
|
||||
get to the URL. */
|
||||
|
||||
struct urlpos *entry;
|
||||
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);
|
||||
if (!refresh)
|
||||
return;
|
||||
return;
|
||||
|
||||
for (p = refresh; ISDIGIT (*p); p++)
|
||||
timeout = 10 * timeout + *p - '0';
|
||||
timeout = 10 * timeout + *p - '0';
|
||||
if (*p++ != ';')
|
||||
return;
|
||||
return;
|
||||
|
||||
while (ISSPACE (*p))
|
||||
++p;
|
||||
++p;
|
||||
if (!( TOUPPER (*p) == 'U'
|
||||
&& TOUPPER (*(p + 1)) == 'R'
|
||||
&& TOUPPER (*(p + 2)) == 'L'
|
||||
&& *(p + 3) == '='))
|
||||
return;
|
||||
&& TOUPPER (*(p + 1)) == 'R'
|
||||
&& TOUPPER (*(p + 2)) == 'L'
|
||||
&& *(p + 3) == '='))
|
||||
return;
|
||||
p += 4;
|
||||
while (ISSPACE (*p))
|
||||
++p;
|
||||
++p;
|
||||
|
||||
entry = append_url (p, tag, attrind, ctx);
|
||||
if (entry)
|
||||
{
|
||||
entry->link_refresh_p = 1;
|
||||
entry->refresh_timeout = timeout;
|
||||
entry->link_expect_html = 1;
|
||||
}
|
||||
{
|
||||
entry->link_refresh_p = 1;
|
||||
entry->refresh_timeout = timeout;
|
||||
entry->link_expect_html = 1;
|
||||
}
|
||||
}
|
||||
else if (name && 0 == strcasecmp (name, "robots"))
|
||||
{
|
||||
/* Handle stuff like:
|
||||
<meta name="robots" content="index,nofollow"> */
|
||||
<meta name="robots" content="index,nofollow"> */
|
||||
char *content = find_attr (tag, "content", NULL);
|
||||
if (!content)
|
||||
return;
|
||||
return;
|
||||
if (!strcasecmp (content, "none"))
|
||||
ctx->nofollow = true;
|
||||
ctx->nofollow = true;
|
||||
else
|
||||
{
|
||||
while (*content)
|
||||
{
|
||||
/* Find the next occurrence of ',' or the end of
|
||||
the string. */
|
||||
char *end = strchr (content, ',');
|
||||
if (end)
|
||||
++end;
|
||||
else
|
||||
end = content + strlen (content);
|
||||
if (!strncasecmp (content, "nofollow", end - content))
|
||||
ctx->nofollow = true;
|
||||
content = end;
|
||||
}
|
||||
}
|
||||
{
|
||||
while (*content)
|
||||
{
|
||||
/* Find the next occurrence of ',' or the end of
|
||||
the string. */
|
||||
char *end = strchr (content, ',');
|
||||
if (end)
|
||||
++end;
|
||||
else
|
||||
end = content + strlen (content);
|
||||
if (!strncasecmp (content, "nofollow", end - content))
|
||||
ctx->nofollow = true;
|
||||
content = end;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -618,7 +618,7 @@ get_urls_html (const char *file, const char *url, bool *meta_disallow_follow)
|
||||
flags |= MHT_STRICT_COMMENTS;
|
||||
|
||||
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));
|
||||
if (meta_disallow_follow)
|
||||
@ -661,51 +661,51 @@ get_urls_file (const char *file)
|
||||
const char *line_beg = text;
|
||||
const char *line_end = memchr (text, '\n', text_end - text);
|
||||
if (!line_end)
|
||||
line_end = text_end;
|
||||
line_end = text_end;
|
||||
else
|
||||
++line_end;
|
||||
++line_end;
|
||||
text = line_end;
|
||||
|
||||
/* Strip whitespace from the beginning and end of line. */
|
||||
while (line_beg < line_end && ISSPACE (*line_beg))
|
||||
++line_beg;
|
||||
++line_beg;
|
||||
while (line_end > line_beg && ISSPACE (*(line_end - 1)))
|
||||
--line_end;
|
||||
--line_end;
|
||||
|
||||
if (line_beg == line_end)
|
||||
continue;
|
||||
continue;
|
||||
|
||||
/* The URL is in the [line_beg, line_end) region. */
|
||||
|
||||
/* 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);
|
||||
|
||||
if (opt.base_href)
|
||||
{
|
||||
/* Merge opt.base_href with URL. */
|
||||
char *merged = uri_merge (opt.base_href, url_text);
|
||||
xfree (url_text);
|
||||
url_text = merged;
|
||||
}
|
||||
{
|
||||
/* Merge opt.base_href with URL. */
|
||||
char *merged = uri_merge (opt.base_href, url_text);
|
||||
xfree (url_text);
|
||||
url_text = merged;
|
||||
}
|
||||
|
||||
url = url_parse (url_text, &up_error_code);
|
||||
if (!url)
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("%s: Invalid URL %s: %s\n"),
|
||||
file, url_text, url_error (up_error_code));
|
||||
xfree (url_text);
|
||||
continue;
|
||||
}
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("%s: Invalid URL %s: %s\n"),
|
||||
file, url_text, url_error (up_error_code));
|
||||
xfree (url_text);
|
||||
continue;
|
||||
}
|
||||
xfree (url_text);
|
||||
|
||||
entry = xnew0 (struct urlpos);
|
||||
entry->url = url;
|
||||
|
||||
if (!head)
|
||||
head = entry;
|
||||
head = entry;
|
||||
else
|
||||
tail->next = entry;
|
||||
tail->next = entry;
|
||||
tail = entry;
|
||||
}
|
||||
read_file_free (fm);
|
||||
|
188
src/http-ntlm.c
188
src/http-ntlm.c
@ -145,7 +145,7 @@ ntlm_input (struct ntlmdata *ntlm, const char *header)
|
||||
|
||||
size = base64_decode (header, buffer);
|
||||
if (size < 0)
|
||||
return false; /* malformed base64 from server */
|
||||
return false; /* malformed base64 from server */
|
||||
|
||||
ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */
|
||||
|
||||
@ -158,10 +158,10 @@ ntlm_input (struct ntlmdata *ntlm, const char *header)
|
||||
else
|
||||
{
|
||||
if (ntlm->state >= NTLMSTATE_TYPE1)
|
||||
{
|
||||
DEBUGP (("Unexpected empty NTLM message.\n"));
|
||||
return false; /* this is an error */
|
||||
}
|
||||
{
|
||||
DEBUGP (("Unexpected empty NTLM message.\n"));
|
||||
return false; /* this is an error */
|
||||
}
|
||||
|
||||
DEBUGP (("Empty NTLM message, starting transaction.\n"));
|
||||
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
|
||||
setup_des_key(unsigned char *key_56,
|
||||
DES_key_schedule DESKEYARG(ks))
|
||||
DES_key_schedule DESKEYARG(ks))
|
||||
{
|
||||
DES_cblock key;
|
||||
|
||||
@ -221,8 +221,8 @@ calc_resp(unsigned char *keys, unsigned char *plaintext, unsigned char *results)
|
||||
*/
|
||||
static void
|
||||
mkhash(const char *password,
|
||||
unsigned char *nonce, /* 8 bytes */
|
||||
unsigned char *lmresp /* must fit 0x18 bytes */
|
||||
unsigned char *nonce, /* 8 bytes */
|
||||
unsigned char *lmresp /* must fit 0x18 bytes */
|
||||
#ifdef USE_NTRESPONSES
|
||||
, unsigned char *ntresp /* must fit 0x18 bytes */
|
||||
#endif
|
||||
@ -298,7 +298,7 @@ mkhash(const char *password,
|
||||
/* this is for creating ntlm header output */
|
||||
char *
|
||||
ntlm_output (struct ntlmdata *ntlm, const char *user, const char *passwd,
|
||||
bool *ready)
|
||||
bool *ready)
|
||||
{
|
||||
const char *domain=""; /* 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"
|
||||
"\x01%c%c%c" /* 32-bit type = 1 */
|
||||
"%c%c%c%c" /* 32-bit NTLM flag field */
|
||||
"%c%c" /* domain length */
|
||||
"%c%c" /* domain allocated space */
|
||||
"%c%c" /* domain name offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
"%c%c" /* host length */
|
||||
"%c%c" /* host allocated space */
|
||||
"%c%c" /* host name offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
"%s" /* host name */
|
||||
"%s", /* domain string */
|
||||
0, /* trailing zero */
|
||||
0,0,0, /* part of type-1 long */
|
||||
"\x01%c%c%c" /* 32-bit type = 1 */
|
||||
"%c%c%c%c" /* 32-bit NTLM flag field */
|
||||
"%c%c" /* domain length */
|
||||
"%c%c" /* domain allocated space */
|
||||
"%c%c" /* domain name offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
"%c%c" /* host length */
|
||||
"%c%c" /* host allocated space */
|
||||
"%c%c" /* host name offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
"%s" /* host name */
|
||||
"%s", /* domain string */
|
||||
0, /* trailing zero */
|
||||
0,0,0, /* part of type-1 long */
|
||||
|
||||
LONGQUARTET(
|
||||
NTLMFLAG_NEGOTIATE_OEM| /* 2 */
|
||||
NTLMFLAG_NEGOTIATE_NTLM_KEY /* 200 */
|
||||
/* equals 0x0202 */
|
||||
),
|
||||
SHORTPAIR(domlen),
|
||||
SHORTPAIR(domlen),
|
||||
SHORTPAIR(domoff),
|
||||
0,0,
|
||||
SHORTPAIR(hostlen),
|
||||
SHORTPAIR(hostlen),
|
||||
SHORTPAIR(hostoff),
|
||||
0,0,
|
||||
host, domain);
|
||||
LONGQUARTET(
|
||||
NTLMFLAG_NEGOTIATE_OEM| /* 2 */
|
||||
NTLMFLAG_NEGOTIATE_NTLM_KEY /* 200 */
|
||||
/* equals 0x0202 */
|
||||
),
|
||||
SHORTPAIR(domlen),
|
||||
SHORTPAIR(domlen),
|
||||
SHORTPAIR(domoff),
|
||||
0,0,
|
||||
SHORTPAIR(hostlen),
|
||||
SHORTPAIR(hostlen),
|
||||
SHORTPAIR(hostoff),
|
||||
0,0,
|
||||
host, domain);
|
||||
|
||||
/* initial packet length */
|
||||
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 */
|
||||
|
||||
size = snprintf (ntlmbuf, sizeof(ntlmbuf),
|
||||
"NTLMSSP%c"
|
||||
"\x03%c%c%c" /* type-3, 32 bits */
|
||||
"NTLMSSP%c"
|
||||
"\x03%c%c%c" /* type-3, 32 bits */
|
||||
|
||||
"%c%c%c%c" /* LanManager length + allocated space */
|
||||
"%c%c" /* LanManager offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
"%c%c%c%c" /* LanManager length + allocated space */
|
||||
"%c%c" /* LanManager offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
"%c%c" /* NT-response length */
|
||||
"%c%c" /* NT-response allocated space */
|
||||
"%c%c" /* NT-response offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
"%c%c" /* NT-response length */
|
||||
"%c%c" /* NT-response allocated space */
|
||||
"%c%c" /* NT-response offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
"%c%c" /* domain length */
|
||||
"%c%c" /* domain allocated space */
|
||||
"%c%c" /* domain name offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
"%c%c" /* domain length */
|
||||
"%c%c" /* domain allocated space */
|
||||
"%c%c" /* domain name offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
"%c%c" /* user length */
|
||||
"%c%c" /* user allocated space */
|
||||
"%c%c" /* user offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
"%c%c" /* user length */
|
||||
"%c%c" /* user allocated space */
|
||||
"%c%c" /* user offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
"%c%c" /* host length */
|
||||
"%c%c" /* host allocated space */
|
||||
"%c%c" /* host offset */
|
||||
"%c%c%c%c%c%c" /* 6 zeroes */
|
||||
"%c%c" /* host length */
|
||||
"%c%c" /* host allocated space */
|
||||
"%c%c" /* host offset */
|
||||
"%c%c%c%c%c%c" /* 6 zeroes */
|
||||
|
||||
"\xff\xff" /* message length */
|
||||
"%c%c" /* 2 zeroes */
|
||||
"\xff\xff" /* message length */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
"\x01\x82" /* flags */
|
||||
"%c%c" /* 2 zeroes */
|
||||
"\x01\x82" /* flags */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
/* domain string */
|
||||
/* user string */
|
||||
/* host string */
|
||||
/* LanManager response */
|
||||
/* NT response */
|
||||
,
|
||||
0, /* zero termination */
|
||||
0,0,0, /* type-3 long, the 24 upper bits */
|
||||
/* domain string */
|
||||
/* user string */
|
||||
/* host string */
|
||||
/* LanManager response */
|
||||
/* NT response */
|
||||
,
|
||||
0, /* zero termination */
|
||||
0,0,0, /* type-3 long, the 24 upper bits */
|
||||
|
||||
SHORTPAIR(0x18), /* LanManager response length, twice */
|
||||
SHORTPAIR(0x18),
|
||||
SHORTPAIR(lmrespoff),
|
||||
0x0, 0x0,
|
||||
SHORTPAIR(0x18), /* LanManager response length, twice */
|
||||
SHORTPAIR(0x18),
|
||||
SHORTPAIR(lmrespoff),
|
||||
0x0, 0x0,
|
||||
|
||||
#ifdef USE_NTRESPONSES
|
||||
SHORTPAIR(0x18), /* NT-response length, twice */
|
||||
SHORTPAIR(0x18),
|
||||
SHORTPAIR(0x18), /* NT-response length, twice */
|
||||
SHORTPAIR(0x18),
|
||||
#else
|
||||
0x0, 0x0,
|
||||
0x0, 0x0,
|
||||
0x0, 0x0,
|
||||
0x0, 0x0,
|
||||
#endif
|
||||
SHORTPAIR(ntrespoff),
|
||||
0x0, 0x0,
|
||||
SHORTPAIR(ntrespoff),
|
||||
0x0, 0x0,
|
||||
|
||||
SHORTPAIR(domlen),
|
||||
SHORTPAIR(domlen),
|
||||
SHORTPAIR(domoff),
|
||||
0x0, 0x0,
|
||||
SHORTPAIR(domlen),
|
||||
SHORTPAIR(domlen),
|
||||
SHORTPAIR(domoff),
|
||||
0x0, 0x0,
|
||||
|
||||
SHORTPAIR(userlen),
|
||||
SHORTPAIR(userlen),
|
||||
SHORTPAIR(useroff),
|
||||
0x0, 0x0,
|
||||
SHORTPAIR(userlen),
|
||||
SHORTPAIR(userlen),
|
||||
SHORTPAIR(useroff),
|
||||
0x0, 0x0,
|
||||
|
||||
SHORTPAIR(hostlen),
|
||||
SHORTPAIR(hostlen),
|
||||
SHORTPAIR(hostoff),
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
SHORTPAIR(hostlen),
|
||||
SHORTPAIR(hostlen),
|
||||
SHORTPAIR(hostoff),
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
|
||||
0x0, 0x0,
|
||||
0x0, 0x0,
|
||||
|
||||
0x0, 0x0);
|
||||
0x0, 0x0);
|
||||
|
||||
/* size is now 64 */
|
||||
size=64;
|
||||
|
452
src/init.c
452
src/init.c
@ -47,11 +47,11 @@ so, delete this exception statement from your version. */
|
||||
#include "host.h"
|
||||
#include "netrc.h"
|
||||
#include "progress.h"
|
||||
#include "recur.h" /* for INFINITE_RECURSION */
|
||||
#include "convert.h" /* for convert_cleanup */
|
||||
#include "res.h" /* for res_cleanup */
|
||||
#include "http.h" /* for http_cleanup */
|
||||
#include "retr.h" /* for output_stream */
|
||||
#include "recur.h" /* for INFINITE_RECURSION */
|
||||
#include "convert.h" /* for convert_cleanup */
|
||||
#include "res.h" /* for res_cleanup */
|
||||
#include "http.h" /* for http_cleanup */
|
||||
#include "retr.h" /* for output_stream */
|
||||
|
||||
#ifdef TESTING
|
||||
#include "test.h"
|
||||
@ -109,139 +109,139 @@ static struct {
|
||||
bool (*action) (const char *, const char *, void *);
|
||||
} commands[] = {
|
||||
/* KEEP THIS LIST ALPHABETICALLY SORTED */
|
||||
{ "accept", &opt.accepts, cmd_vector },
|
||||
{ "addhostdir", &opt.add_hostdir, cmd_boolean },
|
||||
{ "alwaysrest", &opt.always_rest, cmd_boolean }, /* deprecated */
|
||||
{ "background", &opt.background, cmd_boolean },
|
||||
{ "backupconverted", &opt.backup_converted, cmd_boolean },
|
||||
{ "backups", &opt.backups, cmd_number },
|
||||
{ "base", &opt.base_href, cmd_string },
|
||||
{ "bindaddress", &opt.bind_address, cmd_string },
|
||||
{ "accept", &opt.accepts, cmd_vector },
|
||||
{ "addhostdir", &opt.add_hostdir, cmd_boolean },
|
||||
{ "alwaysrest", &opt.always_rest, cmd_boolean }, /* deprecated */
|
||||
{ "background", &opt.background, cmd_boolean },
|
||||
{ "backupconverted", &opt.backup_converted, cmd_boolean },
|
||||
{ "backups", &opt.backups, cmd_number },
|
||||
{ "base", &opt.base_href, cmd_string },
|
||||
{ "bindaddress", &opt.bind_address, cmd_string },
|
||||
#ifdef HAVE_SSL
|
||||
{ "cacertificate", &opt.ca_cert, cmd_file },
|
||||
{ "cacertificate", &opt.ca_cert, cmd_file },
|
||||
#endif
|
||||
{ "cache", &opt.allow_cache, cmd_boolean },
|
||||
{ "cache", &opt.allow_cache, cmd_boolean },
|
||||
#ifdef HAVE_SSL
|
||||
{ "cadirectory", &opt.ca_directory, cmd_directory },
|
||||
{ "certificate", &opt.cert_file, cmd_file },
|
||||
{ "certificatetype", &opt.cert_type, cmd_cert_type },
|
||||
{ "checkcertificate", &opt.check_cert, cmd_boolean },
|
||||
{ "cadirectory", &opt.ca_directory, cmd_directory },
|
||||
{ "certificate", &opt.cert_file, cmd_file },
|
||||
{ "certificatetype", &opt.cert_type, cmd_cert_type },
|
||||
{ "checkcertificate", &opt.check_cert, cmd_boolean },
|
||||
#endif
|
||||
{ "connecttimeout", &opt.connect_timeout, cmd_time },
|
||||
{ "connecttimeout", &opt.connect_timeout, cmd_time },
|
||||
{ "contentdisposition", &opt.content_disposition, cmd_boolean },
|
||||
{ "continue", &opt.always_rest, cmd_boolean },
|
||||
{ "convertlinks", &opt.convert_links, cmd_boolean },
|
||||
{ "cookies", &opt.cookies, cmd_boolean },
|
||||
{ "cutdirs", &opt.cut_dirs, cmd_number },
|
||||
{ "continue", &opt.always_rest, cmd_boolean },
|
||||
{ "convertlinks", &opt.convert_links, cmd_boolean },
|
||||
{ "cookies", &opt.cookies, cmd_boolean },
|
||||
{ "cutdirs", &opt.cut_dirs, cmd_number },
|
||||
#ifdef ENABLE_DEBUG
|
||||
{ "debug", &opt.debug, cmd_boolean },
|
||||
{ "debug", &opt.debug, cmd_boolean },
|
||||
#endif
|
||||
{ "deleteafter", &opt.delete_after, cmd_boolean },
|
||||
{ "dirprefix", &opt.dir_prefix, cmd_directory },
|
||||
{ "dirstruct", NULL, cmd_spec_dirstruct },
|
||||
{ "dnscache", &opt.dns_cache, cmd_boolean },
|
||||
{ "dnstimeout", &opt.dns_timeout, cmd_time },
|
||||
{ "domains", &opt.domains, cmd_vector },
|
||||
{ "dotbytes", &opt.dot_bytes, cmd_bytes },
|
||||
{ "dotsinline", &opt.dots_in_line, cmd_number },
|
||||
{ "dotspacing", &opt.dot_spacing, cmd_number },
|
||||
{ "dotstyle", &opt.dot_style, cmd_string },
|
||||
{ "deleteafter", &opt.delete_after, cmd_boolean },
|
||||
{ "dirprefix", &opt.dir_prefix, cmd_directory },
|
||||
{ "dirstruct", NULL, cmd_spec_dirstruct },
|
||||
{ "dnscache", &opt.dns_cache, cmd_boolean },
|
||||
{ "dnstimeout", &opt.dns_timeout, cmd_time },
|
||||
{ "domains", &opt.domains, cmd_vector },
|
||||
{ "dotbytes", &opt.dot_bytes, cmd_bytes },
|
||||
{ "dotsinline", &opt.dots_in_line, cmd_number },
|
||||
{ "dotspacing", &opt.dot_spacing, cmd_number },
|
||||
{ "dotstyle", &opt.dot_style, cmd_string },
|
||||
#ifdef HAVE_SSL
|
||||
{ "egdfile", &opt.egd_file, cmd_file },
|
||||
{ "egdfile", &opt.egd_file, cmd_file },
|
||||
#endif
|
||||
{ "excludedirectories", &opt.excludes, cmd_directory_vector },
|
||||
{ "excludedomains", &opt.exclude_domains, cmd_vector },
|
||||
{ "followftp", &opt.follow_ftp, cmd_boolean },
|
||||
{ "followtags", &opt.follow_tags, cmd_vector },
|
||||
{ "forcehtml", &opt.force_html, cmd_boolean },
|
||||
{ "ftppasswd", &opt.ftp_passwd, cmd_string }, /* deprecated */
|
||||
{ "ftppassword", &opt.ftp_passwd, cmd_string },
|
||||
{ "ftpproxy", &opt.ftp_proxy, cmd_string },
|
||||
{ "ftpuser", &opt.ftp_user, cmd_string },
|
||||
{ "glob", &opt.ftp_glob, cmd_boolean },
|
||||
{ "header", NULL, cmd_spec_header },
|
||||
{ "htmlextension", &opt.html_extension, cmd_boolean },
|
||||
{ "htmlify", NULL, cmd_spec_htmlify },
|
||||
{ "httpkeepalive", &opt.http_keep_alive, cmd_boolean },
|
||||
{ "httppasswd", &opt.http_passwd, cmd_string }, /* deprecated */
|
||||
{ "httppassword", &opt.http_passwd, cmd_string },
|
||||
{ "httpproxy", &opt.http_proxy, cmd_string },
|
||||
{ "httpsproxy", &opt.https_proxy, cmd_string },
|
||||
{ "httpuser", &opt.http_user, cmd_string },
|
||||
{ "ignorecase", &opt.ignore_case, cmd_boolean },
|
||||
{ "ignorelength", &opt.ignore_length, cmd_boolean },
|
||||
{ "ignoretags", &opt.ignore_tags, cmd_vector },
|
||||
{ "includedirectories", &opt.includes, cmd_directory_vector },
|
||||
{ "excludedirectories", &opt.excludes, cmd_directory_vector },
|
||||
{ "excludedomains", &opt.exclude_domains, cmd_vector },
|
||||
{ "followftp", &opt.follow_ftp, cmd_boolean },
|
||||
{ "followtags", &opt.follow_tags, cmd_vector },
|
||||
{ "forcehtml", &opt.force_html, cmd_boolean },
|
||||
{ "ftppasswd", &opt.ftp_passwd, cmd_string }, /* deprecated */
|
||||
{ "ftppassword", &opt.ftp_passwd, cmd_string },
|
||||
{ "ftpproxy", &opt.ftp_proxy, cmd_string },
|
||||
{ "ftpuser", &opt.ftp_user, cmd_string },
|
||||
{ "glob", &opt.ftp_glob, cmd_boolean },
|
||||
{ "header", NULL, cmd_spec_header },
|
||||
{ "htmlextension", &opt.html_extension, cmd_boolean },
|
||||
{ "htmlify", NULL, cmd_spec_htmlify },
|
||||
{ "httpkeepalive", &opt.http_keep_alive, cmd_boolean },
|
||||
{ "httppasswd", &opt.http_passwd, cmd_string }, /* deprecated */
|
||||
{ "httppassword", &opt.http_passwd, cmd_string },
|
||||
{ "httpproxy", &opt.http_proxy, cmd_string },
|
||||
{ "httpsproxy", &opt.https_proxy, cmd_string },
|
||||
{ "httpuser", &opt.http_user, cmd_string },
|
||||
{ "ignorecase", &opt.ignore_case, cmd_boolean },
|
||||
{ "ignorelength", &opt.ignore_length, cmd_boolean },
|
||||
{ "ignoretags", &opt.ignore_tags, cmd_vector },
|
||||
{ "includedirectories", &opt.includes, cmd_directory_vector },
|
||||
#ifdef ENABLE_IPV6
|
||||
{ "inet4only", &opt.ipv4_only, cmd_boolean },
|
||||
{ "inet6only", &opt.ipv6_only, cmd_boolean },
|
||||
{ "inet4only", &opt.ipv4_only, cmd_boolean },
|
||||
{ "inet6only", &opt.ipv6_only, cmd_boolean },
|
||||
#endif
|
||||
{ "input", &opt.input_filename, cmd_file },
|
||||
{ "input", &opt.input_filename, cmd_file },
|
||||
{ "keepsessioncookies", &opt.keep_session_cookies, cmd_boolean },
|
||||
{ "limitrate", &opt.limit_rate, cmd_bytes },
|
||||
{ "loadcookies", &opt.cookies_input, cmd_file },
|
||||
{ "logfile", &opt.lfilename, cmd_file },
|
||||
{ "login", &opt.ftp_user, cmd_string },/* deprecated*/
|
||||
{ "maxredirect", &opt.max_redirect, cmd_number },
|
||||
{ "mirror", NULL, cmd_spec_mirror },
|
||||
{ "netrc", &opt.netrc, cmd_boolean },
|
||||
{ "noclobber", &opt.noclobber, cmd_boolean },
|
||||
{ "noparent", &opt.no_parent, cmd_boolean },
|
||||
{ "noproxy", &opt.no_proxy, cmd_vector },
|
||||
{ "numtries", &opt.ntry, cmd_number_inf },/* deprecated*/
|
||||
{ "outputdocument", &opt.output_document, cmd_file },
|
||||
{ "pagerequisites", &opt.page_requisites, cmd_boolean },
|
||||
{ "passiveftp", &opt.ftp_pasv, cmd_boolean },
|
||||
{ "passwd", &opt.ftp_passwd, cmd_string },/* deprecated*/
|
||||
{ "password", &opt.passwd, cmd_string },
|
||||
{ "postdata", &opt.post_data, cmd_string },
|
||||
{ "postfile", &opt.post_file_name, cmd_file },
|
||||
{ "preferfamily", NULL, cmd_spec_prefer_family },
|
||||
{ "preservepermissions", &opt.preserve_perm, cmd_boolean },
|
||||
{ "limitrate", &opt.limit_rate, cmd_bytes },
|
||||
{ "loadcookies", &opt.cookies_input, cmd_file },
|
||||
{ "logfile", &opt.lfilename, cmd_file },
|
||||
{ "login", &opt.ftp_user, cmd_string },/* deprecated*/
|
||||
{ "maxredirect", &opt.max_redirect, cmd_number },
|
||||
{ "mirror", NULL, cmd_spec_mirror },
|
||||
{ "netrc", &opt.netrc, cmd_boolean },
|
||||
{ "noclobber", &opt.noclobber, cmd_boolean },
|
||||
{ "noparent", &opt.no_parent, cmd_boolean },
|
||||
{ "noproxy", &opt.no_proxy, cmd_vector },
|
||||
{ "numtries", &opt.ntry, cmd_number_inf },/* deprecated*/
|
||||
{ "outputdocument", &opt.output_document, cmd_file },
|
||||
{ "pagerequisites", &opt.page_requisites, cmd_boolean },
|
||||
{ "passiveftp", &opt.ftp_pasv, cmd_boolean },
|
||||
{ "passwd", &opt.ftp_passwd, cmd_string },/* deprecated*/
|
||||
{ "password", &opt.passwd, cmd_string },
|
||||
{ "postdata", &opt.post_data, cmd_string },
|
||||
{ "postfile", &opt.post_file_name, cmd_file },
|
||||
{ "preferfamily", NULL, cmd_spec_prefer_family },
|
||||
{ "preservepermissions", &opt.preserve_perm, cmd_boolean },
|
||||
#ifdef HAVE_SSL
|
||||
{ "privatekey", &opt.private_key, cmd_file },
|
||||
{ "privatekeytype", &opt.private_key_type, cmd_cert_type },
|
||||
{ "privatekey", &opt.private_key, cmd_file },
|
||||
{ "privatekeytype", &opt.private_key_type, cmd_cert_type },
|
||||
#endif
|
||||
{ "progress", &opt.progress_type, cmd_spec_progress },
|
||||
{ "progress", &opt.progress_type, cmd_spec_progress },
|
||||
{ "protocoldirectories", &opt.protocol_directories, cmd_boolean },
|
||||
{ "proxypasswd", &opt.proxy_passwd, cmd_string }, /* deprecated */
|
||||
{ "proxypassword", &opt.proxy_passwd, cmd_string },
|
||||
{ "proxyuser", &opt.proxy_user, cmd_string },
|
||||
{ "quiet", &opt.quiet, cmd_boolean },
|
||||
{ "quota", &opt.quota, cmd_bytes_sum },
|
||||
{ "proxypasswd", &opt.proxy_passwd, cmd_string }, /* deprecated */
|
||||
{ "proxypassword", &opt.proxy_passwd, cmd_string },
|
||||
{ "proxyuser", &opt.proxy_user, cmd_string },
|
||||
{ "quiet", &opt.quiet, cmd_boolean },
|
||||
{ "quota", &opt.quota, cmd_bytes_sum },
|
||||
#ifdef HAVE_SSL
|
||||
{ "randomfile", &opt.random_file, cmd_file },
|
||||
{ "randomfile", &opt.random_file, cmd_file },
|
||||
#endif
|
||||
{ "randomwait", &opt.random_wait, cmd_boolean },
|
||||
{ "readtimeout", &opt.read_timeout, cmd_time },
|
||||
{ "reclevel", &opt.reclevel, cmd_number_inf },
|
||||
{ "recursive", NULL, cmd_spec_recursive },
|
||||
{ "referer", &opt.referer, cmd_string },
|
||||
{ "reject", &opt.rejects, cmd_vector },
|
||||
{ "relativeonly", &opt.relative_only, cmd_boolean },
|
||||
{ "removelisting", &opt.remove_listing, cmd_boolean },
|
||||
{ "restrictfilenames", NULL, cmd_spec_restrict_file_names },
|
||||
{ "retrsymlinks", &opt.retr_symlinks, cmd_boolean },
|
||||
{ "retryconnrefused", &opt.retry_connrefused, cmd_boolean },
|
||||
{ "robots", &opt.use_robots, cmd_boolean },
|
||||
{ "savecookies", &opt.cookies_output, cmd_file },
|
||||
{ "saveheaders", &opt.save_headers, cmd_boolean },
|
||||
{ "randomwait", &opt.random_wait, cmd_boolean },
|
||||
{ "readtimeout", &opt.read_timeout, cmd_time },
|
||||
{ "reclevel", &opt.reclevel, cmd_number_inf },
|
||||
{ "recursive", NULL, cmd_spec_recursive },
|
||||
{ "referer", &opt.referer, cmd_string },
|
||||
{ "reject", &opt.rejects, cmd_vector },
|
||||
{ "relativeonly", &opt.relative_only, cmd_boolean },
|
||||
{ "removelisting", &opt.remove_listing, cmd_boolean },
|
||||
{ "restrictfilenames", NULL, cmd_spec_restrict_file_names },
|
||||
{ "retrsymlinks", &opt.retr_symlinks, cmd_boolean },
|
||||
{ "retryconnrefused", &opt.retry_connrefused, cmd_boolean },
|
||||
{ "robots", &opt.use_robots, cmd_boolean },
|
||||
{ "savecookies", &opt.cookies_output, cmd_file },
|
||||
{ "saveheaders", &opt.save_headers, cmd_boolean },
|
||||
#ifdef HAVE_SSL
|
||||
{ "secureprotocol", &opt.secure_protocol, cmd_spec_secure_protocol },
|
||||
{ "secureprotocol", &opt.secure_protocol, cmd_spec_secure_protocol },
|
||||
#endif
|
||||
{ "serverresponse", &opt.server_response, cmd_boolean },
|
||||
{ "spanhosts", &opt.spanhost, cmd_boolean },
|
||||
{ "spider", &opt.spider, cmd_boolean },
|
||||
{ "strictcomments", &opt.strict_comments, cmd_boolean },
|
||||
{ "timeout", NULL, cmd_spec_timeout },
|
||||
{ "timestamping", &opt.timestamping, cmd_boolean },
|
||||
{ "tries", &opt.ntry, cmd_number_inf },
|
||||
{ "useproxy", &opt.use_proxy, cmd_boolean },
|
||||
{ "user", &opt.user, cmd_string },
|
||||
{ "useragent", NULL, cmd_spec_useragent },
|
||||
{ "verbose", NULL, cmd_spec_verbose },
|
||||
{ "wait", &opt.wait, cmd_time },
|
||||
{ "waitretry", &opt.waitretry, cmd_time }
|
||||
{ "serverresponse", &opt.server_response, cmd_boolean },
|
||||
{ "spanhosts", &opt.spanhost, cmd_boolean },
|
||||
{ "spider", &opt.spider, cmd_boolean },
|
||||
{ "strictcomments", &opt.strict_comments, cmd_boolean },
|
||||
{ "timeout", NULL, cmd_spec_timeout },
|
||||
{ "timestamping", &opt.timestamping, cmd_boolean },
|
||||
{ "tries", &opt.ntry, cmd_number_inf },
|
||||
{ "useproxy", &opt.use_proxy, cmd_boolean },
|
||||
{ "user", &opt.user, cmd_string },
|
||||
{ "useragent", NULL, cmd_spec_useragent },
|
||||
{ "verbose", NULL, cmd_spec_verbose },
|
||||
{ "wait", &opt.wait, cmd_time },
|
||||
{ "waitretry", &opt.waitretry, cmd_time }
|
||||
};
|
||||
|
||||
/* 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 cmp = strcasecmp (cmdname, commands[mid].name);
|
||||
if (cmp < 0)
|
||||
hi = mid - 1;
|
||||
hi = mid - 1;
|
||||
else if (cmp > 0)
|
||||
lo = mid + 1;
|
||||
lo = mid + 1;
|
||||
else
|
||||
return mid;
|
||||
return mid;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@ -339,7 +339,7 @@ home_dir (void)
|
||||
file. */
|
||||
struct passwd *pwd = getpwuid (getuid ());
|
||||
if (!pwd || !pwd->pw_dir)
|
||||
return NULL;
|
||||
return NULL;
|
||||
home = pwd->pw_dir;
|
||||
#else /* WINDOWS */
|
||||
/* Under Windows, if $HOME isn't defined, use the directory where
|
||||
@ -367,11 +367,11 @@ wgetrc_file_name (void)
|
||||
if (env && *env)
|
||||
{
|
||||
if (!file_exists_p (env))
|
||||
{
|
||||
fprintf (stderr, _("%s: WGETRC points to %s, which doesn't exist.\n"),
|
||||
exec_name, env);
|
||||
exit (1);
|
||||
}
|
||||
{
|
||||
fprintf (stderr, _("%s: WGETRC points to %s, which doesn't exist.\n"),
|
||||
exec_name, env);
|
||||
exit (1);
|
||||
}
|
||||
return xstrdup (env);
|
||||
}
|
||||
|
||||
@ -392,7 +392,7 @@ wgetrc_file_name (void)
|
||||
file = NULL;
|
||||
home = ws_mypath ();
|
||||
if (home)
|
||||
file = aprintf ("%s/wget.ini", home);
|
||||
file = aprintf ("%s/wget.ini", home);
|
||||
}
|
||||
#endif /* WINDOWS */
|
||||
|
||||
@ -432,8 +432,8 @@ run_wgetrc (const char *file)
|
||||
if (!fp)
|
||||
{
|
||||
fprintf (stderr, _("%s: Cannot read %s (%s).\n"), exec_name,
|
||||
file, strerror (errno));
|
||||
return true; /* not a fatal error */
|
||||
file, strerror (errno));
|
||||
return true; /* not a fatal error */
|
||||
}
|
||||
enable_tilde_expansion = true;
|
||||
ln = 1;
|
||||
@ -444,31 +444,31 @@ run_wgetrc (const char *file)
|
||||
|
||||
/* Parse the line. */
|
||||
switch (parse_line (line, &com, &val, &comind))
|
||||
{
|
||||
case line_ok:
|
||||
/* If everything is OK, set the value. */
|
||||
if (!setval_internal (comind, com, val))
|
||||
{
|
||||
fprintf (stderr, _("%s: Error in %s at line %d.\n"),
|
||||
exec_name, file, ln);
|
||||
++errcnt;
|
||||
}
|
||||
break;
|
||||
case line_syntax_error:
|
||||
fprintf (stderr, _("%s: Syntax error in %s at line %d.\n"),
|
||||
exec_name, file, ln);
|
||||
++errcnt;
|
||||
break;
|
||||
case line_unknown_command:
|
||||
fprintf (stderr, _("%s: Unknown command `%s' in %s at line %d.\n"),
|
||||
exec_name, com, file, ln);
|
||||
++errcnt;
|
||||
break;
|
||||
case line_empty:
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
{
|
||||
case line_ok:
|
||||
/* If everything is OK, set the value. */
|
||||
if (!setval_internal (comind, com, val))
|
||||
{
|
||||
fprintf (stderr, _("%s: Error in %s at line %d.\n"),
|
||||
exec_name, file, ln);
|
||||
++errcnt;
|
||||
}
|
||||
break;
|
||||
case line_syntax_error:
|
||||
fprintf (stderr, _("%s: Syntax error in %s at line %d.\n"),
|
||||
exec_name, file, ln);
|
||||
++errcnt;
|
||||
break;
|
||||
case line_unknown_command:
|
||||
fprintf (stderr, _("%s: Unknown command `%s' in %s at line %d.\n"),
|
||||
exec_name, com, file, ln);
|
||||
++errcnt;
|
||||
break;
|
||||
case line_empty:
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
xfree_null (com);
|
||||
xfree_null (val);
|
||||
xfree (line);
|
||||
@ -507,7 +507,7 @@ initialize (void)
|
||||
{
|
||||
fprintf (stderr, _("\
|
||||
%s: Warning: Both system and user wgetrc point to `%s'.\n"),
|
||||
exec_name, file);
|
||||
exec_name, file);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@ -527,8 +527,8 @@ initialize (void)
|
||||
static void
|
||||
dehyphen (char *s)
|
||||
{
|
||||
char *t = s; /* t - tortoise */
|
||||
char *h = s; /* h - hare */
|
||||
char *t = s; /* t - tortoise */
|
||||
char *h = s; /* h - hare */
|
||||
while (*h)
|
||||
if (*h == '_' || *h == '-')
|
||||
++h;
|
||||
@ -653,13 +653,13 @@ run_command (const char *opt)
|
||||
{
|
||||
case line_ok:
|
||||
if (!setval_internal (comind, com, val))
|
||||
exit (2);
|
||||
exit (2);
|
||||
xfree (com);
|
||||
xfree (val);
|
||||
break;
|
||||
default:
|
||||
fprintf (stderr, _("%s: Invalid --execute command `%s'\n"),
|
||||
exec_name, opt);
|
||||
exec_name, opt);
|
||||
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 CMP2(p, c0, c1) (TOLOWER((p)[0]) == (c0) \
|
||||
&& TOLOWER((p)[1]) == (c1) \
|
||||
&& (p)[2] == '\0')
|
||||
#define CMP2(p, c0, c1) (TOLOWER((p)[0]) == (c0) \
|
||||
&& TOLOWER((p)[1]) == (c1) \
|
||||
&& (p)[2] == '\0')
|
||||
|
||||
#define CMP3(p, c0, c1, c2) (TOLOWER((p)[0]) == (c0) \
|
||||
&& TOLOWER((p)[1]) == (c1) \
|
||||
&& TOLOWER((p)[2]) == (c2) \
|
||||
&& (p)[3] == '\0')
|
||||
#define CMP3(p, c0, c1, c2) (TOLOWER((p)[0]) == (c0) \
|
||||
&& TOLOWER((p)[1]) == (c1) \
|
||||
&& TOLOWER((p)[2]) == (c2) \
|
||||
&& (p)[3] == '\0')
|
||||
|
||||
|
||||
/* 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
|
||||
{
|
||||
fprintf (stderr,
|
||||
_("%s: %s: Invalid boolean `%s'; use `on' or `off'.\n"),
|
||||
exec_name, com, val);
|
||||
_("%s: %s: Invalid boolean `%s'; use `on' or `off'.\n"),
|
||||
exec_name, com, val);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -721,7 +721,7 @@ cmd_number (const char *com, const char *val, void *place)
|
||||
|| *(int *) place < 0)
|
||||
{
|
||||
fprintf (stderr, _("%s: %s: Invalid number `%s'.\n"),
|
||||
exec_name, com, val);
|
||||
exec_name, com, val);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -779,15 +779,15 @@ cmd_file (const char *com, const char *val, void *place)
|
||||
int homelen;
|
||||
char *home = home_dir ();
|
||||
if (!home)
|
||||
goto noexpand;
|
||||
goto noexpand;
|
||||
|
||||
homelen = strlen (home);
|
||||
while (homelen && ISSEP (home[homelen - 1]))
|
||||
home[--homelen] = '\0';
|
||||
home[--homelen] = '\0';
|
||||
|
||||
/* Skip the leading "~/". */
|
||||
for (++val; ISSEP (*val); val++)
|
||||
;
|
||||
;
|
||||
|
||||
*pstring = concat_strings (home, "/", val, (char *) 0);
|
||||
}
|
||||
@ -798,7 +798,7 @@ cmd_file (const char *com, const char *val, void *place)
|
||||
char *s;
|
||||
for (s = *pstring; *s; s++)
|
||||
if (*s == '\\')
|
||||
*s = '/';
|
||||
*s = '/';
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
@ -855,15 +855,15 @@ cmd_directory_vector (const char *com, const char *val, void *place)
|
||||
|
||||
seps = sepstring (val);
|
||||
for (t = seps; t && *t; t++)
|
||||
{
|
||||
int len = strlen (*t);
|
||||
/* Skip degenerate case of root directory. */
|
||||
if (len > 1)
|
||||
{
|
||||
if ((*t)[len - 1] == '/')
|
||||
(*t)[len - 1] = '\0';
|
||||
}
|
||||
}
|
||||
{
|
||||
int len = strlen (*t);
|
||||
/* Skip degenerate case of root directory. */
|
||||
if (len > 1)
|
||||
{
|
||||
if ((*t)[len - 1] == '/')
|
||||
(*t)[len - 1] = '\0';
|
||||
}
|
||||
}
|
||||
*pvec = merge_vecs (*pvec, seps);
|
||||
}
|
||||
else
|
||||
@ -912,7 +912,7 @@ parse_bytes_helper (const char *val, double *result)
|
||||
break;
|
||||
default:
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@ -952,7 +952,7 @@ cmd_bytes (const char *com, const char *val, void *place)
|
||||
if (!parse_bytes_helper (val, &byte_value))
|
||||
{
|
||||
fprintf (stderr, _("%s: %s: Invalid byte value `%s'\n"),
|
||||
exec_name, com, val);
|
||||
exec_name, com, val);
|
||||
return false;
|
||||
}
|
||||
*(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))
|
||||
{
|
||||
fprintf (stderr, _("%s: %s: Invalid byte value `%s'\n"),
|
||||
exec_name, com, val);
|
||||
exec_name, com, val);
|
||||
return false;
|
||||
}
|
||||
*(SUM_SIZE_INT *) place = (SUM_SIZE_INT) byte_value;
|
||||
@ -996,30 +996,30 @@ cmd_time (const char *com, const char *val, void *place)
|
||||
{
|
||||
err:
|
||||
fprintf (stderr, _("%s: %s: Invalid time period `%s'\n"),
|
||||
exec_name, com, val);
|
||||
exec_name, com, val);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (TOLOWER (end[-1]))
|
||||
{
|
||||
case 's':
|
||||
--end, mult = 1; /* seconds */
|
||||
--end, mult = 1; /* seconds */
|
||||
break;
|
||||
case 'm':
|
||||
--end, mult = 60; /* minutes */
|
||||
--end, mult = 60; /* minutes */
|
||||
break;
|
||||
case 'h':
|
||||
--end, mult = 3600; /* hours */
|
||||
--end, mult = 3600; /* hours */
|
||||
break;
|
||||
case 'd':
|
||||
--end, mult = 86400.0; /* days */
|
||||
--end, mult = 86400.0; /* days */
|
||||
break;
|
||||
case 'w':
|
||||
--end, mult = 604800.0; /* weeks */
|
||||
--end, mult = 604800.0; /* weeks */
|
||||
break;
|
||||
default:
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@ -1087,7 +1087,7 @@ cmd_spec_header (const char *com, const char *val, void *place_ignored)
|
||||
if (!check_user_specified_header (val))
|
||||
{
|
||||
fprintf (stderr, _("%s: %s: Invalid header `%s'.\n"),
|
||||
exec_name, com, val);
|
||||
exec_name, com, val);
|
||||
return false;
|
||||
}
|
||||
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;
|
||||
if (!opt.no_dirstruct)
|
||||
opt.dirstruct = true;
|
||||
opt.dirstruct = true;
|
||||
opt.timestamping = true;
|
||||
opt.reclevel = INFINITE_RECURSION;
|
||||
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))
|
||||
{
|
||||
fprintf (stderr, _("%s: %s: Invalid progress type `%s'.\n"),
|
||||
exec_name, com, val);
|
||||
exec_name, com, val);
|
||||
return false;
|
||||
}
|
||||
xfree_null (opt.progress_type);
|
||||
@ -1176,7 +1176,7 @@ cmd_spec_recursive (const char *com, const char *val, void *place_ignored)
|
||||
else
|
||||
{
|
||||
if (opt.recursive && !opt.no_dirstruct)
|
||||
opt.dirstruct = true;
|
||||
opt.dirstruct = 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"),
|
||||
exec_name, com, val);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (*end)
|
||||
val = end + 1;
|
||||
val = end + 1;
|
||||
}
|
||||
while (*val && *end);
|
||||
|
||||
@ -1268,7 +1268,7 @@ cmd_spec_useragent (const char *com, const char *val, void *place_ignored)
|
||||
if (strchr (val, '\n'))
|
||||
{
|
||||
fprintf (stderr, _("%s: %s: Invalid value `%s'.\n"),
|
||||
exec_name, com, val);
|
||||
exec_name, com, val);
|
||||
return false;
|
||||
}
|
||||
xfree_null (opt.useragent);
|
||||
@ -1321,18 +1321,18 @@ simple_atoi (const char *beg, const char *end, int *dest)
|
||||
if (!negative)
|
||||
for (; p < end && ISDIGIT (*p); p++)
|
||||
{
|
||||
int next = (10 * result) + (*p - '0');
|
||||
if (next < result)
|
||||
return false; /* overflow */
|
||||
result = next;
|
||||
int next = (10 * result) + (*p - '0');
|
||||
if (next < result)
|
||||
return false; /* overflow */
|
||||
result = next;
|
||||
}
|
||||
else
|
||||
for (; p < end && ISDIGIT (*p); p++)
|
||||
{
|
||||
int next = (10 * result) - (*p - '0');
|
||||
if (next > result)
|
||||
return false; /* underflow */
|
||||
result = next;
|
||||
int next = (10 * result) - (*p - '0');
|
||||
if (next > result)
|
||||
return false; /* underflow */
|
||||
result = next;
|
||||
}
|
||||
|
||||
if (p != end)
|
||||
@ -1371,22 +1371,22 @@ simple_atof (const char *beg, const char *end, double *dest)
|
||||
{
|
||||
char ch = *p;
|
||||
if (ISDIGIT (ch))
|
||||
{
|
||||
if (!seen_dot)
|
||||
result = (10 * result) + (ch - '0');
|
||||
else
|
||||
result += (ch - '0') / (divider *= 10);
|
||||
seen_digit = true;
|
||||
}
|
||||
{
|
||||
if (!seen_dot)
|
||||
result = (10 * result) + (ch - '0');
|
||||
else
|
||||
result += (ch - '0') / (divider *= 10);
|
||||
seen_digit = true;
|
||||
}
|
||||
else if (ch == '.')
|
||||
{
|
||||
if (!seen_dot)
|
||||
seen_dot = true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
{
|
||||
if (!seen_dot)
|
||||
seen_dot = true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
if (!seen_digit)
|
||||
return false;
|
||||
@ -1422,14 +1422,14 @@ check_user_specified_header (const char *s)
|
||||
|
||||
static bool
|
||||
decode_string (const char *val, const struct decode_item *items, int itemcount,
|
||||
int *place)
|
||||
int *place)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < itemcount; i++)
|
||||
if (0 == strcasecmp (val, items[i].name))
|
||||
{
|
||||
*place = items[i].code;
|
||||
return true;
|
||||
*place = items[i].code;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
222
src/log.c
222
src/log.c
@ -107,9 +107,9 @@ static bool needs_flushing;
|
||||
static struct log_ln {
|
||||
char static_line[STATIC_LENGTH + 1]; /* statically allocated
|
||||
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. */
|
||||
char *content; /* this points either to malloced_line
|
||||
char *content; /* this points either to malloced_line
|
||||
or to the appropriate static_line.
|
||||
If this is NULL, it means the line
|
||||
has not yet been used. */
|
||||
@ -126,9 +126,9 @@ static bool trailing_line;
|
||||
|
||||
static void check_redirect_output (void);
|
||||
|
||||
#define ROT_ADVANCE(num) do { \
|
||||
if (++num >= SAVED_LOG_LINES) \
|
||||
num = 0; \
|
||||
#define ROT_ADVANCE(num) do { \
|
||||
if (++num >= SAVED_LOG_LINES) \
|
||||
num = 0; \
|
||||
} while (0)
|
||||
|
||||
/* 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;
|
||||
|
||||
if (log_line_current == -1)
|
||||
log_line_current = 0;
|
||||
log_line_current = 0;
|
||||
else
|
||||
free_log_line (log_line_current);
|
||||
free_log_line (log_line_current);
|
||||
ln = log_lines + log_line_current;
|
||||
if (len > STATIC_LENGTH)
|
||||
{
|
||||
ln->malloced_line = strdupdelim (start, end);
|
||||
ln->content = ln->malloced_line;
|
||||
}
|
||||
{
|
||||
ln->malloced_line = strdupdelim (start, end);
|
||||
ln->content = ln->malloced_line;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (ln->static_line, start, len);
|
||||
ln->static_line[len] = '\0';
|
||||
ln->content = ln->static_line;
|
||||
}
|
||||
{
|
||||
memcpy (ln->static_line, start, len);
|
||||
ln->static_line[len] = '\0';
|
||||
ln->content = ln->static_line;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -191,38 +191,38 @@ saved_append_1 (const char *start, const char *end)
|
||||
convert it to malloc(). */
|
||||
struct log_ln *ln = log_lines + log_line_current;
|
||||
if (ln->malloced_line)
|
||||
{
|
||||
/* Resize malloc'ed line and append. */
|
||||
int old_len = strlen (ln->malloced_line);
|
||||
ln->malloced_line = xrealloc (ln->malloced_line, old_len + len + 1);
|
||||
memcpy (ln->malloced_line + old_len, start, len);
|
||||
ln->malloced_line[old_len + len] = '\0';
|
||||
/* might have changed due to realloc */
|
||||
ln->content = ln->malloced_line;
|
||||
}
|
||||
{
|
||||
/* Resize malloc'ed line and append. */
|
||||
int old_len = strlen (ln->malloced_line);
|
||||
ln->malloced_line = xrealloc (ln->malloced_line, old_len + len + 1);
|
||||
memcpy (ln->malloced_line + old_len, start, len);
|
||||
ln->malloced_line[old_len + len] = '\0';
|
||||
/* might have changed due to realloc */
|
||||
ln->content = ln->malloced_line;
|
||||
}
|
||||
else
|
||||
{
|
||||
int old_len = strlen (ln->static_line);
|
||||
if (old_len + len > STATIC_LENGTH)
|
||||
{
|
||||
/* Allocate memory and concatenate the old and the new
|
||||
{
|
||||
int old_len = strlen (ln->static_line);
|
||||
if (old_len + len > STATIC_LENGTH)
|
||||
{
|
||||
/* Allocate memory and concatenate the old and the new
|
||||
contents. */
|
||||
ln->malloced_line = xmalloc (old_len + len + 1);
|
||||
memcpy (ln->malloced_line, ln->static_line,
|
||||
old_len);
|
||||
memcpy (ln->malloced_line + old_len, start, len);
|
||||
ln->malloced_line[old_len + len] = '\0';
|
||||
ln->content = ln->malloced_line;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Just append to the old, statically allocated
|
||||
ln->malloced_line = xmalloc (old_len + len + 1);
|
||||
memcpy (ln->malloced_line, ln->static_line,
|
||||
old_len);
|
||||
memcpy (ln->malloced_line + old_len, start, len);
|
||||
ln->malloced_line[old_len + len] = '\0';
|
||||
ln->content = ln->malloced_line;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Just append to the old, statically allocated
|
||||
contents. */
|
||||
memcpy (ln->static_line + old_len, start, len);
|
||||
ln->static_line[old_len + len] = '\0';
|
||||
ln->content = ln->static_line;
|
||||
}
|
||||
}
|
||||
memcpy (ln->static_line + old_len, start, len);
|
||||
ln->static_line[old_len + len] = '\0';
|
||||
ln->content = ln->static_line;
|
||||
}
|
||||
}
|
||||
}
|
||||
trailing_line = !(end[-1] == '\n');
|
||||
if (!trailing_line)
|
||||
@ -241,9 +241,9 @@ saved_append (const char *s)
|
||||
{
|
||||
const char *end = strchr (s, '\n');
|
||||
if (!end)
|
||||
end = s + strlen (s);
|
||||
end = s + strlen (s);
|
||||
else
|
||||
++end;
|
||||
++end;
|
||||
saved_append_1 (s, end);
|
||||
s = end;
|
||||
}
|
||||
@ -259,22 +259,22 @@ saved_append (const char *s)
|
||||
* LOG_NONVERBOSE - print the message if opt.verbose is zero;
|
||||
|
||||
* LOG_VERBOSE - print the message if opt.verbose is non-zero. */
|
||||
#define CHECK_VERBOSE(x) \
|
||||
switch (x) \
|
||||
{ \
|
||||
case LOG_ALWAYS: \
|
||||
break; \
|
||||
case LOG_NOTQUIET: \
|
||||
if (opt.quiet) \
|
||||
return; \
|
||||
break; \
|
||||
case LOG_NONVERBOSE: \
|
||||
if (opt.verbose || opt.quiet) \
|
||||
return; \
|
||||
break; \
|
||||
case LOG_VERBOSE: \
|
||||
if (!opt.verbose) \
|
||||
return; \
|
||||
#define CHECK_VERBOSE(x) \
|
||||
switch (x) \
|
||||
{ \
|
||||
case LOG_ALWAYS: \
|
||||
break; \
|
||||
case LOG_NOTQUIET: \
|
||||
if (opt.quiet) \
|
||||
return; \
|
||||
break; \
|
||||
case LOG_NONVERBOSE: \
|
||||
if (opt.verbose || opt.quiet) \
|
||||
return; \
|
||||
break; \
|
||||
case LOG_VERBOSE: \
|
||||
if (!opt.verbose) \
|
||||
return; \
|
||||
}
|
||||
|
||||
/* Returns the file descriptor for logging. This is LOGFP, except if
|
||||
@ -337,7 +337,7 @@ struct logvprintf_state {
|
||||
|
||||
static bool
|
||||
log_vprintf_internal (struct logvprintf_state *state, const char *fmt,
|
||||
va_list args)
|
||||
va_list args)
|
||||
{
|
||||
char smallmsg[128];
|
||||
char *write_ptr = smallmsg;
|
||||
@ -378,7 +378,7 @@ log_vprintf_internal (struct logvprintf_state *state, const char *fmt,
|
||||
if (numwritten == -1)
|
||||
{
|
||||
/* Writing failed, and we don't know the needed size. Try
|
||||
again with doubled size. */
|
||||
again with doubled size. */
|
||||
int newsize = available_size << 1;
|
||||
state->bigmsg = xrealloc (state->bigmsg, newsize);
|
||||
state->allocated = newsize;
|
||||
@ -387,7 +387,7 @@ log_vprintf_internal (struct logvprintf_state *state, const char *fmt,
|
||||
else if (numwritten >= available_size)
|
||||
{
|
||||
/* Writing failed, but we know exactly how much space we
|
||||
need. */
|
||||
need. */
|
||||
int newsize = numwritten + 1;
|
||||
state->bigmsg = xrealloc (state->bigmsg, newsize);
|
||||
state->allocated = newsize;
|
||||
@ -434,9 +434,9 @@ log_set_flush (bool flush)
|
||||
else
|
||||
{
|
||||
/* Reenable flushing. If anything was printed in no-flush mode,
|
||||
flush the log now. */
|
||||
flush the log now. */
|
||||
if (needs_flushing)
|
||||
logflush ();
|
||||
logflush ();
|
||||
flush_log_p = true;
|
||||
}
|
||||
}
|
||||
@ -493,15 +493,15 @@ debug_logprintf (const char *fmt, ...)
|
||||
|
||||
check_redirect_output ();
|
||||
if (inhibit_logging)
|
||||
return;
|
||||
return;
|
||||
|
||||
xzero (lpstate);
|
||||
do
|
||||
{
|
||||
va_start (args, fmt);
|
||||
done = log_vprintf_internal (&lpstate, fmt, args);
|
||||
va_end (args);
|
||||
}
|
||||
{
|
||||
va_start (args, fmt);
|
||||
done = log_vprintf_internal (&lpstate, fmt, args);
|
||||
va_end (args);
|
||||
}
|
||||
while (!done);
|
||||
}
|
||||
}
|
||||
@ -516,10 +516,10 @@ log_init (const char *file, bool appendp)
|
||||
{
|
||||
logfp = fopen (file, appendp ? "a" : "w");
|
||||
if (!logfp)
|
||||
{
|
||||
fprintf (stderr, "%s: %s: %s\n", exec_name, file, strerror (errno));
|
||||
exit (1);
|
||||
}
|
||||
{
|
||||
fprintf (stderr, "%s: %s: %s\n", exec_name, file, strerror (errno));
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -533,16 +533,16 @@ log_init (const char *file, bool appendp)
|
||||
|
||||
if (1
|
||||
#ifdef HAVE_ISATTY
|
||||
&& isatty (fileno (logfp))
|
||||
&& isatty (fileno (logfp))
|
||||
#endif
|
||||
)
|
||||
{
|
||||
/* If the output is a TTY, enable save context, i.e. store
|
||||
the most recent several messages ("context") and dump
|
||||
them to a log file in case SIGHUP or SIGUSR1 is received
|
||||
(or Ctrl+Break is pressed under Windows). */
|
||||
save_context_p = true;
|
||||
}
|
||||
)
|
||||
{
|
||||
/* If the output is a TTY, enable save context, i.e. store
|
||||
the most recent several messages ("context") and dump
|
||||
them to a log file in case SIGHUP or SIGUSR1 is received
|
||||
(or Ctrl+Break is pressed under Windows). */
|
||||
save_context_p = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -582,7 +582,7 @@ log_dump_context (void)
|
||||
{
|
||||
struct log_ln *ln = log_lines + num;
|
||||
if (ln->content)
|
||||
fputs (ln->content, fp);
|
||||
fputs (ln->content, fp);
|
||||
ROT_ADVANCE (num);
|
||||
}
|
||||
while (num != log_line_current);
|
||||
@ -643,26 +643,26 @@ copy_and_escape (const char *source, char *dest, char escape, int base)
|
||||
{
|
||||
case 8:
|
||||
while ((c = *from++) != '\0')
|
||||
if (ISPRINT (c))
|
||||
*to++ = c;
|
||||
else
|
||||
{
|
||||
*to++ = escape;
|
||||
*to++ = '0' + (c >> 6);
|
||||
*to++ = '0' + ((c >> 3) & 7);
|
||||
*to++ = '0' + (c & 7);
|
||||
}
|
||||
if (ISPRINT (c))
|
||||
*to++ = c;
|
||||
else
|
||||
{
|
||||
*to++ = escape;
|
||||
*to++ = '0' + (c >> 6);
|
||||
*to++ = '0' + ((c >> 3) & 7);
|
||||
*to++ = '0' + (c & 7);
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
while ((c = *from++) != '\0')
|
||||
if (ISPRINT (c))
|
||||
*to++ = c;
|
||||
else
|
||||
{
|
||||
*to++ = escape;
|
||||
*to++ = XNUM_TO_DIGIT (c >> 4);
|
||||
*to++ = XNUM_TO_DIGIT (c & 0xf);
|
||||
}
|
||||
if (ISPRINT (c))
|
||||
*to++ = c;
|
||||
else
|
||||
{
|
||||
*to++ = escape;
|
||||
*to++ = XNUM_TO_DIGIT (c >> 4);
|
||||
*to++ = XNUM_TO_DIGIT (c & 0xf);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
@ -675,12 +675,12 @@ struct ringel {
|
||||
char *buffer;
|
||||
int size;
|
||||
};
|
||||
static struct ringel ring[RING_SIZE]; /* ring data */
|
||||
static struct ringel ring[RING_SIZE]; /* ring data */
|
||||
|
||||
static const char *
|
||||
escnonprint_internal (const char *str, char escape, int base)
|
||||
{
|
||||
static int ringpos; /* current ring position */
|
||||
static int ringpos; /* current ring position */
|
||||
int nprcnt;
|
||||
|
||||
assert (base == 8 || base == 16);
|
||||
@ -706,8 +706,8 @@ escnonprint_internal (const char *str, char escape, int base)
|
||||
(re)allocate it. */
|
||||
if (r->buffer == NULL || r->size < needed_size)
|
||||
{
|
||||
r->buffer = xrealloc (r->buffer, needed_size);
|
||||
r->size = needed_size;
|
||||
r->buffer = xrealloc (r->buffer, needed_size);
|
||||
r->size = needed_size;
|
||||
}
|
||||
|
||||
copy_and_escape (str, r->buffer, escape, base);
|
||||
@ -781,7 +781,7 @@ redirect_output (void)
|
||||
if (logfp)
|
||||
{
|
||||
fprintf (stderr, _("\n%s received, redirecting output to `%s'.\n"),
|
||||
redirect_request_signal_name, logfile);
|
||||
redirect_request_signal_name, logfile);
|
||||
xfree (logfile);
|
||||
/* Dump the context output to the newly opened log. */
|
||||
log_dump_context ();
|
||||
@ -792,7 +792,7 @@ redirect_output (void)
|
||||
can do but disable printing completely. */
|
||||
fprintf (stderr, _("\n%s received.\n"), redirect_request_signal_name);
|
||||
fprintf (stderr, _("%s: %s; disabling logging.\n"),
|
||||
logfile, strerror (errno));
|
||||
logfile, strerror (errno));
|
||||
inhibit_logging = true;
|
||||
}
|
||||
save_context_p = false;
|
||||
|
@ -159,12 +159,12 @@ fake_fork_child (void)
|
||||
/* See utils:fork_to_background for explanation. */
|
||||
FILE *new_log_fp = unique_create (DEFAULT_LOGFILE, false, &opt.lfilename);
|
||||
if (new_log_fp)
|
||||
{
|
||||
info->logfile_changed = true;
|
||||
strncpy (info->lfilename, opt.lfilename, sizeof (info->lfilename));
|
||||
info->lfilename[sizeof (info->lfilename) - 1] = '\0';
|
||||
fclose (new_log_fp);
|
||||
}
|
||||
{
|
||||
info->logfile_changed = true;
|
||||
strncpy (info->lfilename, opt.lfilename, sizeof (info->lfilename));
|
||||
info->lfilename[sizeof (info->lfilename) - 1] = '\0';
|
||||
fclose (new_log_fp);
|
||||
}
|
||||
}
|
||||
|
||||
UnmapViewOfFile (info);
|
||||
@ -457,14 +457,14 @@ ws_startup (void)
|
||||
if (err != 0)
|
||||
{
|
||||
fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
|
||||
exec_name);
|
||||
exec_name);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (data.wVersion < requested)
|
||||
{
|
||||
fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
|
||||
exec_name);
|
||||
exec_name);
|
||||
WSACleanup ();
|
||||
exit (1);
|
||||
}
|
||||
@ -542,7 +542,7 @@ run_with_timeout (double seconds, void (*fun) (void *), void *arg)
|
||||
thread_arg.arg = arg;
|
||||
thread_arg.ws_error = WSAGetLastError ();
|
||||
thread_hnd = CreateThread (NULL, THREAD_STACK_SIZE, thread_helper,
|
||||
&thread_arg, 0, &thread_id);
|
||||
&thread_arg, 0, &thread_id);
|
||||
if (!thread_hnd)
|
||||
{
|
||||
DEBUGP (("CreateThread() failed; [0x%x]\n", GetLastError ()));
|
||||
@ -553,7 +553,7 @@ run_with_timeout (double seconds, void (*fun) (void *), void *arg)
|
||||
== WAIT_OBJECT_0)
|
||||
{
|
||||
/* 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);
|
||||
DEBUGP (("Winsock error: %d\n", WSAGetLastError ()));
|
||||
rc = false;
|
||||
@ -564,7 +564,7 @@ run_with_timeout (double seconds, void (*fun) (void *), void *arg)
|
||||
rc = true;
|
||||
}
|
||||
|
||||
CloseHandle (thread_hnd); /* Clear-up after TerminateThread(). */
|
||||
CloseHandle (thread_hnd); /* Clear-up after TerminateThread(). */
|
||||
thread_hnd = NULL;
|
||||
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
|
||||
a function that sets errno the way the rest of the code expects. */
|
||||
|
||||
#define WRAP(fun, decl, call) int wrapped_##fun decl { \
|
||||
int retval = fun call; \
|
||||
if (retval < 0) \
|
||||
errno = WSAGetLastError (); \
|
||||
return retval; \
|
||||
#define WRAP(fun, decl, call) int wrapped_##fun decl { \
|
||||
int retval = fun call; \
|
||||
if (retval < 0) \
|
||||
errno = WSAGetLastError (); \
|
||||
return retval; \
|
||||
}
|
||||
|
||||
WRAP (socket, (int domain, int type, int protocol), (domain, type, protocol))
|
||||
|
316
src/netrc.c
316
src/netrc.c
@ -57,7 +57,7 @@ static acc_t *parse_netrc (const char *);
|
||||
You will typically turn it off for HTTP. */
|
||||
void
|
||||
search_netrc (const char *host, const char **acc, const char **passwd,
|
||||
int slack_default)
|
||||
int slack_default)
|
||||
{
|
||||
acc_t *l;
|
||||
static int processed_netrc;
|
||||
@ -72,17 +72,17 @@ search_netrc (const char *host, const char **acc, const char **passwd,
|
||||
netrc_list = NULL;
|
||||
processed_netrc = 1;
|
||||
if (home)
|
||||
{
|
||||
int err;
|
||||
struct_stat buf;
|
||||
char *path = (char *)alloca (strlen (home) + 1
|
||||
+ strlen (NETRC_FILE_NAME) + 1);
|
||||
sprintf (path, "%s/%s", home, NETRC_FILE_NAME);
|
||||
xfree (home);
|
||||
err = stat (path, &buf);
|
||||
if (err == 0)
|
||||
netrc_list = parse_netrc (path);
|
||||
}
|
||||
{
|
||||
int err;
|
||||
struct_stat buf;
|
||||
char *path = (char *)alloca (strlen (home) + 1
|
||||
+ strlen (NETRC_FILE_NAME) + 1);
|
||||
sprintf (path, "%s/%s", home, NETRC_FILE_NAME);
|
||||
xfree (home);
|
||||
err = stat (path, &buf);
|
||||
if (err == 0)
|
||||
netrc_list = parse_netrc (path);
|
||||
}
|
||||
}
|
||||
/* If nothing to do... */
|
||||
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)
|
||||
{
|
||||
if (!l->host)
|
||||
continue;
|
||||
continue;
|
||||
else if (!strcasecmp (l->host, host))
|
||||
break;
|
||||
break;
|
||||
}
|
||||
if (l)
|
||||
{
|
||||
if (*acc)
|
||||
{
|
||||
/* Looking for password in .netrc. */
|
||||
if (!strcmp (l->acc, *acc))
|
||||
*passwd = l->passwd; /* usernames match; password OK */
|
||||
else
|
||||
*passwd = NULL; /* usernames don't match */
|
||||
}
|
||||
else /* NOT *acc */
|
||||
{
|
||||
/* If password was given, use it. The account is l->acc. */
|
||||
*acc = l->acc;
|
||||
if (l->passwd)
|
||||
*passwd = l->passwd;
|
||||
}
|
||||
{
|
||||
/* Looking for password in .netrc. */
|
||||
if (!strcmp (l->acc, *acc))
|
||||
*passwd = l->passwd; /* usernames match; password OK */
|
||||
else
|
||||
*passwd = NULL; /* usernames don't match */
|
||||
}
|
||||
else /* NOT *acc */
|
||||
{
|
||||
/* If password was given, use it. The account is l->acc. */
|
||||
*acc = l->acc;
|
||||
if (l->passwd)
|
||||
*passwd = l->passwd;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!slack_default)
|
||||
return;
|
||||
return;
|
||||
if (*acc)
|
||||
return;
|
||||
return;
|
||||
/* Try looking for the default account. */
|
||||
for (l = netrc_list; l; l = l->next)
|
||||
if (!l->host)
|
||||
break;
|
||||
if (!l->host)
|
||||
break;
|
||||
if (!l)
|
||||
return;
|
||||
return;
|
||||
*acc = l->acc;
|
||||
if (!*passwd)
|
||||
*passwd = l->passwd;
|
||||
*passwd = l->passwd;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -170,7 +170,7 @@ read_whole_line (FILE *fp)
|
||||
length += strlen (line + length);
|
||||
assert (length > 0);
|
||||
if (line[length - 1] == '\n')
|
||||
break;
|
||||
break;
|
||||
/* fgets() guarantees to read the whole line, or to use up the
|
||||
space we've given it. We can double the buffer
|
||||
unconditionally. */
|
||||
@ -212,11 +212,11 @@ maybe_add_to_list (acc_t **newentry, acc_t **list)
|
||||
else
|
||||
{
|
||||
if (a)
|
||||
{
|
||||
/* Add the current machine into our list. */
|
||||
a->next = l;
|
||||
l = a;
|
||||
}
|
||||
{
|
||||
/* Add the current machine into our list. */
|
||||
a->next = l;
|
||||
l = a;
|
||||
}
|
||||
|
||||
/* Allocate a new acc_t structure. */
|
||||
a = xmalloc (sizeof (acc_t));
|
||||
@ -265,7 +265,7 @@ parse_netrc (const char *path)
|
||||
if (!fp)
|
||||
{
|
||||
fprintf (stderr, _("%s: Cannot read %s (%s).\n"), exec_name,
|
||||
path, strerror (errno));
|
||||
path, strerror (errno));
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -284,129 +284,129 @@ parse_netrc (const char *path)
|
||||
|
||||
/* Skip leading whitespace. */
|
||||
while (*p && ISSPACE (*p))
|
||||
p ++;
|
||||
p ++;
|
||||
|
||||
/* If the line is empty, then end any macro definition. */
|
||||
if (last_token == tok_macdef && !*p)
|
||||
/* End of macro if the line is empty. */
|
||||
last_token = tok_nothing;
|
||||
/* End of macro if the line is empty. */
|
||||
last_token = tok_nothing;
|
||||
|
||||
/* If we are defining macros, then skip parsing the line. */
|
||||
while (*p && last_token != tok_macdef)
|
||||
{
|
||||
/* Skip any whitespace. */
|
||||
while (*p && ISSPACE (*p))
|
||||
p ++;
|
||||
{
|
||||
/* Skip any whitespace. */
|
||||
while (*p && ISSPACE (*p))
|
||||
p ++;
|
||||
|
||||
/* Discard end-of-line comments; also, stop processing if
|
||||
the above `while' merely skipped trailing whitespace. */
|
||||
if (*p == '#' || !*p)
|
||||
break;
|
||||
/* Discard end-of-line comments; also, stop processing if
|
||||
the above `while' merely skipped trailing whitespace. */
|
||||
if (*p == '#' || !*p)
|
||||
break;
|
||||
|
||||
/* If the token starts with quotation mark, note this fact,
|
||||
and squash the quotation character */
|
||||
if (*p == '"'){
|
||||
quote = 1;
|
||||
shift_left (p);
|
||||
}
|
||||
/* If the token starts with quotation mark, note this fact,
|
||||
and squash the quotation character */
|
||||
if (*p == '"'){
|
||||
quote = 1;
|
||||
shift_left (p);
|
||||
}
|
||||
|
||||
tok = p;
|
||||
tok = p;
|
||||
|
||||
/* Find the end of the token, handling quotes and escapes. */
|
||||
while (*p && (quote ? *p != '"' : !ISSPACE (*p))){
|
||||
if (*p == '\\')
|
||||
shift_left (p);
|
||||
p ++;
|
||||
}
|
||||
/* Find the end of the token, handling quotes and escapes. */
|
||||
while (*p && (quote ? *p != '"' : !ISSPACE (*p))){
|
||||
if (*p == '\\')
|
||||
shift_left (p);
|
||||
p ++;
|
||||
}
|
||||
|
||||
/* If field was quoted, squash the trailing quotation mark
|
||||
and reset quote flag. */
|
||||
if (quote)
|
||||
{
|
||||
shift_left (p);
|
||||
quote = 0;
|
||||
}
|
||||
/* If field was quoted, squash the trailing quotation mark
|
||||
and reset quote flag. */
|
||||
if (quote)
|
||||
{
|
||||
shift_left (p);
|
||||
quote = 0;
|
||||
}
|
||||
|
||||
/* Null-terminate the token, if it isn't already. */
|
||||
if (*p)
|
||||
*p ++ = '\0';
|
||||
/* Null-terminate the token, if it isn't already. */
|
||||
if (*p)
|
||||
*p ++ = '\0';
|
||||
|
||||
switch (last_token)
|
||||
{
|
||||
case tok_login:
|
||||
if (current)
|
||||
current->acc = xstrdup (tok);
|
||||
else
|
||||
premature_token = "login";
|
||||
break;
|
||||
switch (last_token)
|
||||
{
|
||||
case tok_login:
|
||||
if (current)
|
||||
current->acc = xstrdup (tok);
|
||||
else
|
||||
premature_token = "login";
|
||||
break;
|
||||
|
||||
case tok_machine:
|
||||
/* Start a new machine entry. */
|
||||
maybe_add_to_list (¤t, &retval);
|
||||
current->host = xstrdup (tok);
|
||||
break;
|
||||
case tok_machine:
|
||||
/* Start a new machine entry. */
|
||||
maybe_add_to_list (¤t, &retval);
|
||||
current->host = xstrdup (tok);
|
||||
break;
|
||||
|
||||
case tok_password:
|
||||
if (current)
|
||||
current->passwd = xstrdup (tok);
|
||||
else
|
||||
premature_token = "password";
|
||||
break;
|
||||
case tok_password:
|
||||
if (current)
|
||||
current->passwd = xstrdup (tok);
|
||||
else
|
||||
premature_token = "password";
|
||||
break;
|
||||
|
||||
/* We handle most of tok_macdef above. */
|
||||
case tok_macdef:
|
||||
if (!current)
|
||||
premature_token = "macdef";
|
||||
break;
|
||||
/* We handle most of tok_macdef above. */
|
||||
case tok_macdef:
|
||||
if (!current)
|
||||
premature_token = "macdef";
|
||||
break;
|
||||
|
||||
/* We don't handle the account keyword at all. */
|
||||
case tok_account:
|
||||
if (!current)
|
||||
premature_token = "account";
|
||||
break;
|
||||
/* We don't handle the account keyword at all. */
|
||||
case tok_account:
|
||||
if (!current)
|
||||
premature_token = "account";
|
||||
break;
|
||||
|
||||
/* We handle tok_nothing below this switch. */
|
||||
case tok_nothing:
|
||||
break;
|
||||
}
|
||||
/* We handle tok_nothing below this switch. */
|
||||
case tok_nothing:
|
||||
break;
|
||||
}
|
||||
|
||||
if (premature_token)
|
||||
{
|
||||
fprintf (stderr, _("\
|
||||
if (premature_token)
|
||||
{
|
||||
fprintf (stderr, _("\
|
||||
%s: %s:%d: warning: \"%s\" token appears before any machine name\n"),
|
||||
exec_name, path, ln, premature_token);
|
||||
premature_token = NULL;
|
||||
}
|
||||
exec_name, path, ln, premature_token);
|
||||
premature_token = NULL;
|
||||
}
|
||||
|
||||
if (last_token != tok_nothing)
|
||||
/* We got a value, so reset the token state. */
|
||||
last_token = tok_nothing;
|
||||
else
|
||||
{
|
||||
/* Fetch the next token. */
|
||||
if (!strcmp (tok, "account"))
|
||||
last_token = tok_account;
|
||||
else if (!strcmp (tok, "default"))
|
||||
{
|
||||
maybe_add_to_list (¤t, &retval);
|
||||
}
|
||||
else if (!strcmp (tok, "login"))
|
||||
last_token = tok_login;
|
||||
if (last_token != tok_nothing)
|
||||
/* We got a value, so reset the token state. */
|
||||
last_token = tok_nothing;
|
||||
else
|
||||
{
|
||||
/* Fetch the next token. */
|
||||
if (!strcmp (tok, "account"))
|
||||
last_token = tok_account;
|
||||
else if (!strcmp (tok, "default"))
|
||||
{
|
||||
maybe_add_to_list (¤t, &retval);
|
||||
}
|
||||
else if (!strcmp (tok, "login"))
|
||||
last_token = tok_login;
|
||||
|
||||
else if (!strcmp (tok, "macdef"))
|
||||
last_token = tok_macdef;
|
||||
else if (!strcmp (tok, "macdef"))
|
||||
last_token = tok_macdef;
|
||||
|
||||
else if (!strcmp (tok, "machine"))
|
||||
last_token = tok_machine;
|
||||
else if (!strcmp (tok, "machine"))
|
||||
last_token = tok_machine;
|
||||
|
||||
else if (!strcmp (tok, "password"))
|
||||
last_token = tok_password;
|
||||
else if (!strcmp (tok, "password"))
|
||||
last_token = tok_password;
|
||||
|
||||
else
|
||||
fprintf (stderr, _("%s: %s:%d: unknown token \"%s\"\n"),
|
||||
exec_name, path, ln, tok);
|
||||
}
|
||||
}
|
||||
else
|
||||
fprintf (stderr, _("%s: %s:%d: unknown token \"%s\"\n"),
|
||||
exec_name, path, ln, tok);
|
||||
}
|
||||
}
|
||||
|
||||
xfree (line);
|
||||
}
|
||||
@ -478,7 +478,7 @@ main (int argc, char **argv)
|
||||
if (stat (file, &sb))
|
||||
{
|
||||
fprintf (stderr, _("%s: cannot stat %s: %s\n"), argv[0], file,
|
||||
strerror (errno));
|
||||
strerror (errno));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
@ -488,37 +488,37 @@ main (int argc, char **argv)
|
||||
{
|
||||
/* Skip if we have a target and this isn't it. */
|
||||
if (target && a->host && strcmp (target, a->host))
|
||||
{
|
||||
a = a->next;
|
||||
continue;
|
||||
}
|
||||
{
|
||||
a = a->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!target)
|
||||
{
|
||||
/* Print the host name if we have no target. */
|
||||
if (a->host)
|
||||
fputs (a->host, stdout);
|
||||
else
|
||||
fputs ("DEFAULT", stdout);
|
||||
{
|
||||
/* Print the host name if we have no target. */
|
||||
if (a->host)
|
||||
fputs (a->host, stdout);
|
||||
else
|
||||
fputs ("DEFAULT", stdout);
|
||||
|
||||
fputc (' ', stdout);
|
||||
}
|
||||
fputc (' ', stdout);
|
||||
}
|
||||
|
||||
/* Print the account name. */
|
||||
fputs (a->acc, stdout);
|
||||
|
||||
if (a->passwd)
|
||||
{
|
||||
/* Print the password, if there is any. */
|
||||
fputc (' ', stdout);
|
||||
fputs (a->passwd, stdout);
|
||||
}
|
||||
{
|
||||
/* Print the password, if there is any. */
|
||||
fputc (' ', stdout);
|
||||
fputs (a->passwd, stdout);
|
||||
}
|
||||
|
||||
fputc ('\n', stdout);
|
||||
|
||||
/* Exit if we found the target. */
|
||||
if (target)
|
||||
exit (0);
|
||||
exit (0);
|
||||
a = a->next;
|
||||
}
|
||||
|
||||
|
122
src/openssl.c
122
src/openssl.c
@ -113,8 +113,8 @@ init_prng (void)
|
||||
|
||||
while (RAND_status () == 0 && maxrand-- > 0)
|
||||
{
|
||||
unsigned char rnd = random_number (256);
|
||||
RAND_seed (&rnd, sizeof (rnd));
|
||||
unsigned char rnd = random_number (256);
|
||||
RAND_seed (&rnd, sizeof (rnd));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -169,7 +169,7 @@ ssl_init ()
|
||||
if (RAND_status () != 1)
|
||||
{
|
||||
logprintf (LOG_NOTQUIET,
|
||||
_("Could not seed PRNG; consider using --random-file.\n"));
|
||||
_("Could not seed PRNG; consider using --random-file.\n"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -211,13 +211,13 @@ ssl_init ()
|
||||
|
||||
if (opt.cert_file)
|
||||
if (SSL_CTX_use_certificate_file (ssl_ctx, opt.cert_file,
|
||||
key_type_to_ssl_type (opt.cert_type))
|
||||
!= 1)
|
||||
key_type_to_ssl_type (opt.cert_type))
|
||||
!= 1)
|
||||
goto error;
|
||||
if (opt.private_key)
|
||||
if (SSL_CTX_use_PrivateKey_file (ssl_ctx, opt.private_key,
|
||||
key_type_to_ssl_type (opt.private_key_type))
|
||||
!= 1)
|
||||
key_type_to_ssl_type (opt.private_key_type))
|
||||
!= 1)
|
||||
goto error;
|
||||
|
||||
/* Since fd_write unconditionally assumes partial writes (and
|
||||
@ -238,8 +238,8 @@ ssl_init ()
|
||||
}
|
||||
|
||||
struct openssl_transport_context {
|
||||
SSL *conn; /* SSL connection handle */
|
||||
char *last_error; /* last error printed with openssl_errstr */
|
||||
SSL *conn; /* SSL connection handle */
|
||||
char *last_error; /* last error printed with openssl_errstr */
|
||||
};
|
||||
|
||||
static int
|
||||
@ -251,8 +251,8 @@ openssl_read (int fd, char *buf, int bufsize, void *arg)
|
||||
do
|
||||
ret = SSL_read (conn, buf, bufsize);
|
||||
while (ret == -1
|
||||
&& SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
|
||||
&& errno == EINTR);
|
||||
&& SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
|
||||
&& errno == EINTR);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -265,8 +265,8 @@ openssl_write (int fd, char *buf, int bufsize, void *arg)
|
||||
do
|
||||
ret = SSL_write (conn, buf, bufsize);
|
||||
while (ret == -1
|
||||
&& SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
|
||||
&& errno == EINTR);
|
||||
&& SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
|
||||
&& errno == EINTR);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -291,8 +291,8 @@ openssl_peek (int fd, char *buf, int bufsize, void *arg)
|
||||
do
|
||||
ret = SSL_peek (conn, buf, bufsize);
|
||||
while (ret == -1
|
||||
&& SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
|
||||
&& errno == EINTR);
|
||||
&& SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
|
||||
&& errno == EINTR);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -323,7 +323,7 @@ openssl_errstr (int fd, void *arg)
|
||||
int len = strlen (str);
|
||||
|
||||
/* 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);
|
||||
memcpy (errmsg + msglen, str, len);
|
||||
msglen += len;
|
||||
@ -331,7 +331,7 @@ openssl_errstr (int fd, void *arg)
|
||||
/* Get next error and bail out if there are no more. */
|
||||
errcode = ERR_get_error ();
|
||||
if (errcode == 0)
|
||||
break;
|
||||
break;
|
||||
|
||||
errmsg[msglen++] = ';';
|
||||
errmsg[msglen++] = ' ';
|
||||
@ -406,7 +406,7 @@ ssl_connect (int fd)
|
||||
functions are used for reading, writing, and polling. */
|
||||
fd_register_transport (fd, &openssl_transport, ctx);
|
||||
DEBUGP (("Handshake successful; connected socket %d to SSL handle 0x%0*lx\n",
|
||||
fd, PTR_FORMAT (conn)));
|
||||
fd, PTR_FORMAT (conn)));
|
||||
return true;
|
||||
|
||||
error:
|
||||
@ -417,7 +417,7 @@ ssl_connect (int fd)
|
||||
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
|
||||
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++)
|
||||
if (c == '*')
|
||||
{
|
||||
for (c = TOLOWER (*p); c == '*'; c = TOLOWER (*++p))
|
||||
;
|
||||
for (; *n != '\0'; n++)
|
||||
if (TOLOWER (*n) == c && pattern_match (p, n))
|
||||
return true;
|
||||
for (c = TOLOWER (*p); c == '*'; c = TOLOWER (*++p))
|
||||
;
|
||||
for (; *n != '\0'; n++)
|
||||
if (TOLOWER (*n) == c && pattern_match (p, n))
|
||||
return true;
|
||||
#ifdef ASTERISK_EXCLUDES_DOT
|
||||
else if (*n == '.')
|
||||
return false;
|
||||
else if (*n == '.')
|
||||
return false;
|
||||
#endif
|
||||
return c == '\0';
|
||||
return c == '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (c != TOLOWER (*n))
|
||||
return false;
|
||||
if (c != TOLOWER (*n))
|
||||
return false;
|
||||
}
|
||||
return *n == '\0';
|
||||
}
|
||||
@ -494,9 +494,9 @@ ssl_check_certificate (int fd, const char *host)
|
||||
if (!cert)
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("%s: No certificate presented by %s.\n"),
|
||||
severity, escnonprint (host));
|
||||
severity, escnonprint (host));
|
||||
success = false;
|
||||
goto no_cert; /* must bail out since CERT is NULL */
|
||||
goto no_cert; /* must bail out since CERT is NULL */
|
||||
}
|
||||
|
||||
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 *issuer = X509_NAME_oneline (X509_get_issuer_name (cert), 0, 0);
|
||||
DEBUGP (("certificate:\n subject: %s\n issuer: %s\n",
|
||||
escnonprint (subject), escnonprint (issuer)));
|
||||
escnonprint (subject), escnonprint (issuer)));
|
||||
OPENSSL_free (subject);
|
||||
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);
|
||||
logprintf (LOG_NOTQUIET,
|
||||
_("%s: cannot verify %s's certificate, issued by `%s':\n"),
|
||||
severity, escnonprint (host), escnonprint (issuer));
|
||||
_("%s: cannot verify %s's certificate, issued by `%s':\n"),
|
||||
severity, escnonprint (host), escnonprint (issuer));
|
||||
/* Try to print more user-friendly (and translated) messages for
|
||||
the frequent verification errors. */
|
||||
the frequent verification errors. */
|
||||
switch (vresult)
|
||||
{
|
||||
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
|
||||
logprintf (LOG_NOTQUIET,
|
||||
_(" Unable to locally verify the issuer's authority.\n"));
|
||||
break;
|
||||
case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
|
||||
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
|
||||
logprintf (LOG_NOTQUIET, _(" Self-signed certificate encountered.\n"));
|
||||
break;
|
||||
case X509_V_ERR_CERT_NOT_YET_VALID:
|
||||
logprintf (LOG_NOTQUIET, _(" Issued certificate not yet valid.\n"));
|
||||
break;
|
||||
case X509_V_ERR_CERT_HAS_EXPIRED:
|
||||
logprintf (LOG_NOTQUIET, _(" Issued certificate has expired.\n"));
|
||||
break;
|
||||
default:
|
||||
/* For the less frequent error strings, simply provide the
|
||||
OpenSSL error message. */
|
||||
logprintf (LOG_NOTQUIET, " %s\n",
|
||||
X509_verify_cert_error_string (vresult));
|
||||
}
|
||||
{
|
||||
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
|
||||
logprintf (LOG_NOTQUIET,
|
||||
_(" Unable to locally verify the issuer's authority.\n"));
|
||||
break;
|
||||
case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
|
||||
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
|
||||
logprintf (LOG_NOTQUIET, _(" Self-signed certificate encountered.\n"));
|
||||
break;
|
||||
case X509_V_ERR_CERT_NOT_YET_VALID:
|
||||
logprintf (LOG_NOTQUIET, _(" Issued certificate not yet valid.\n"));
|
||||
break;
|
||||
case X509_V_ERR_CERT_HAS_EXPIRED:
|
||||
logprintf (LOG_NOTQUIET, _(" Issued certificate has expired.\n"));
|
||||
break;
|
||||
default:
|
||||
/* For the less frequent error strings, simply provide the
|
||||
OpenSSL error message. */
|
||||
logprintf (LOG_NOTQUIET, " %s\n",
|
||||
X509_verify_cert_error_string (vresult));
|
||||
}
|
||||
success = false;
|
||||
/* 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.
|
||||
@ -561,25 +561,25 @@ ssl_check_certificate (int fd, const char *host)
|
||||
|
||||
common_name[0] = '\0';
|
||||
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))
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("\
|
||||
%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;
|
||||
}
|
||||
|
||||
if (success)
|
||||
DEBUGP (("X509 certificate successfully verified and matches host %s\n",
|
||||
escnonprint (host)));
|
||||
escnonprint (host)));
|
||||
X509_free (cert);
|
||||
|
||||
no_cert:
|
||||
if (opt.check_cert && !success)
|
||||
logprintf (LOG_NOTQUIET, _("\
|
||||
To connect to %s insecurely, use `--no-check-certificate'.\n"),
|
||||
escnonprint (host));
|
||||
escnonprint (host));
|
||||
|
||||
/* Allow --no-check-cert to disable certificate checking. */
|
||||
return opt.check_cert ? success : true;
|
||||
|
404
src/progress.c
404
src/progress.c
@ -118,18 +118,18 @@ set_progress_implementation (const char *name)
|
||||
for (i = 0; i < countof (implementations); i++, pi++)
|
||||
if (!strncmp (pi->name, name, namelen))
|
||||
{
|
||||
current_impl = pi;
|
||||
current_impl_locked = 0;
|
||||
current_impl = pi;
|
||||
current_impl_locked = 0;
|
||||
|
||||
if (colon)
|
||||
/* We call pi->set_params even if colon is NULL because we
|
||||
want to give the implementation a chance to set up some
|
||||
things it needs to run. */
|
||||
++colon;
|
||||
if (colon)
|
||||
/* We call pi->set_params even if colon is NULL because we
|
||||
want to give the implementation a chance to set up some
|
||||
things it needs to run. */
|
||||
++colon;
|
||||
|
||||
if (pi->set_params)
|
||||
pi->set_params (colon);
|
||||
return;
|
||||
if (pi->set_params)
|
||||
pi->set_params (colon);
|
||||
return;
|
||||
}
|
||||
abort ();
|
||||
}
|
||||
@ -155,7 +155,7 @@ progress_create (wgint initial, wgint total)
|
||||
if (output_redirected)
|
||||
{
|
||||
if (!current_impl_locked)
|
||||
set_progress_implementation (FALLBACK_PROGRESS_IMPLEMENTATION);
|
||||
set_progress_implementation (FALLBACK_PROGRESS_IMPLEMENTATION);
|
||||
output_redirected = 0;
|
||||
}
|
||||
|
||||
@ -194,16 +194,16 @@ progress_finish (void *progress, double dltime)
|
||||
/* Dot-printing. */
|
||||
|
||||
struct dot_progress {
|
||||
wgint initial_length; /* how many bytes have been downloaded
|
||||
previously. */
|
||||
wgint total_length; /* expected total byte count when the
|
||||
download finishes */
|
||||
wgint initial_length; /* how many bytes have been downloaded
|
||||
previously. */
|
||||
wgint total_length; /* expected total byte count when the
|
||||
download finishes */
|
||||
|
||||
int accumulated; /* number of bytes accumulated after
|
||||
the last printed dot */
|
||||
int accumulated; /* number of bytes accumulated after
|
||||
the last printed dot */
|
||||
|
||||
int rows; /* number of rows printed so far */
|
||||
int dots; /* number of dots printed in this row */
|
||||
int rows; /* number of rows printed so far */
|
||||
int dots; /* number of dots printed in this row */
|
||||
|
||||
double last_timer_value;
|
||||
};
|
||||
@ -226,29 +226,29 @@ dot_create (wgint initial, wgint total)
|
||||
wgint skipped = dp->initial_length - remainder;
|
||||
|
||||
if (skipped)
|
||||
{
|
||||
wgint skipped_k = skipped / 1024; /* skipped amount in K */
|
||||
int skipped_k_len = numdigit (skipped_k);
|
||||
if (skipped_k_len < 6)
|
||||
skipped_k_len = 6;
|
||||
{
|
||||
wgint skipped_k = skipped / 1024; /* skipped amount in K */
|
||||
int skipped_k_len = numdigit (skipped_k);
|
||||
if (skipped_k_len < 6)
|
||||
skipped_k_len = 6;
|
||||
|
||||
/* Align the [ skipping ... ] line with the dots. To do
|
||||
that, insert the number of spaces equal to the number of
|
||||
digits in the skipped amount in K. */
|
||||
logprintf (LOG_VERBOSE, _("\n%*s[ skipping %sK ]"),
|
||||
2 + skipped_k_len, "",
|
||||
number_to_static_string (skipped_k));
|
||||
}
|
||||
/* Align the [ skipping ... ] line with the dots. To do
|
||||
that, insert the number of spaces equal to the number of
|
||||
digits in the skipped amount in K. */
|
||||
logprintf (LOG_VERBOSE, _("\n%*s[ skipping %sK ]"),
|
||||
2 + skipped_k_len, "",
|
||||
number_to_static_string (skipped_k));
|
||||
}
|
||||
|
||||
logprintf (LOG_VERBOSE, "\n%6sK",
|
||||
number_to_static_string (skipped / 1024));
|
||||
number_to_static_string (skipped / 1024));
|
||||
for (; remainder >= dot_bytes; remainder -= dot_bytes)
|
||||
{
|
||||
if (dp->dots % opt.dot_spacing == 0)
|
||||
logputs (LOG_VERBOSE, " ");
|
||||
logputs (LOG_VERBOSE, ",");
|
||||
++dp->dots;
|
||||
}
|
||||
{
|
||||
if (dp->dots % opt.dot_spacing == 0)
|
||||
logputs (LOG_VERBOSE, " ");
|
||||
logputs (LOG_VERBOSE, ",");
|
||||
++dp->dots;
|
||||
}
|
||||
assert (dp->dots < opt.dots_in_line);
|
||||
|
||||
dp->accumulated = remainder;
|
||||
@ -284,8 +284,8 @@ print_row_stats (struct dot_progress *dp, double dltime, bool last)
|
||||
if (dp->total_length)
|
||||
{
|
||||
/* Round to floor value to provide gauge how much data *has*
|
||||
been retrieved. 12.8% will round to 12% because the 13% mark
|
||||
has not yet been reached. 100% is only shown when done. */
|
||||
been retrieved. 12.8% will round to 12% because the 13% mark
|
||||
has not yet been reached. 100% is only shown when done. */
|
||||
int percentage = 100.0 * bytes_displayed / dp->total_length;
|
||||
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;
|
||||
rate = calc_rate (bytes_this_row, dltime - dp->last_timer_value, &units);
|
||||
logprintf (LOG_VERBOSE, " %4.*f%c",
|
||||
rate >= 99.95 ? 0 : rate >= 9.995 ? 1 : 2,
|
||||
rate, names[units]);
|
||||
rate >= 99.95 ? 0 : rate >= 9.995 ? 1 : 2,
|
||||
rate, names[units]);
|
||||
dp->last_timer_value = dltime;
|
||||
}
|
||||
|
||||
if (!last)
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
wgint bytes_remaining = dp->total_length - bytes_displayed;
|
||||
/* The quantity downloaded in this download run. */
|
||||
wgint bytes_sofar = bytes_displayed - dp->initial_length;
|
||||
double eta = dltime * bytes_remaining / bytes_sofar;
|
||||
if (eta < INT_MAX - 1)
|
||||
logprintf (LOG_VERBOSE, " %s",
|
||||
eta_to_human_short ((int) (eta + 0.5), true));
|
||||
}
|
||||
{
|
||||
wgint bytes_remaining = dp->total_length - bytes_displayed;
|
||||
/* The quantity downloaded in this download run. */
|
||||
wgint bytes_sofar = bytes_displayed - dp->initial_length;
|
||||
double eta = dltime * bytes_remaining / bytes_sofar;
|
||||
if (eta < INT_MAX - 1)
|
||||
logprintf (LOG_VERBOSE, " %s",
|
||||
eta_to_human_short ((int) (eta + 0.5), true));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* When done, print the total download time */
|
||||
if (dltime >= 10)
|
||||
logprintf (LOG_VERBOSE, "=%s",
|
||||
eta_to_human_short ((int) (dltime + 0.5), true));
|
||||
logprintf (LOG_VERBOSE, "=%s",
|
||||
eta_to_human_short ((int) (dltime + 0.5), true));
|
||||
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)
|
||||
{
|
||||
if (dp->dots == 0)
|
||||
logprintf (LOG_VERBOSE, "\n%6sK",
|
||||
number_to_static_string (dp->rows * ROW_BYTES / 1024));
|
||||
logprintf (LOG_VERBOSE, "\n%6sK",
|
||||
number_to_static_string (dp->rows * ROW_BYTES / 1024));
|
||||
|
||||
if (dp->dots % opt.dot_spacing == 0)
|
||||
logputs (LOG_VERBOSE, " ");
|
||||
logputs (LOG_VERBOSE, " ");
|
||||
logputs (LOG_VERBOSE, ".");
|
||||
|
||||
++dp->dots;
|
||||
if (dp->dots >= opt.dots_in_line)
|
||||
{
|
||||
++dp->rows;
|
||||
dp->dots = 0;
|
||||
{
|
||||
++dp->rows;
|
||||
dp->dots = 0;
|
||||
|
||||
print_row_stats (dp, dltime, false);
|
||||
}
|
||||
print_row_stats (dp, dltime, false);
|
||||
}
|
||||
}
|
||||
|
||||
log_set_flush (true);
|
||||
@ -384,11 +384,11 @@ dot_finish (void *progress, double dltime)
|
||||
|
||||
if (dp->dots == 0)
|
||||
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++)
|
||||
{
|
||||
if (i % opt.dot_spacing == 0)
|
||||
logputs (LOG_VERBOSE, " ");
|
||||
logputs (LOG_VERBOSE, " ");
|
||||
logputs (LOG_VERBOSE, " ");
|
||||
}
|
||||
|
||||
@ -417,7 +417,7 @@ dot_set_params (const char *params)
|
||||
if (!strcasecmp (params, "default"))
|
||||
{
|
||||
/* Default style: 1K dots, 10 dots in a cluster, 50 dots in a
|
||||
line. */
|
||||
line. */
|
||||
opt.dot_bytes = 1024;
|
||||
opt.dot_spacing = 10;
|
||||
opt.dots_in_line = 50;
|
||||
@ -425,7 +425,7 @@ dot_set_params (const char *params)
|
||||
else if (!strcasecmp (params, "binary"))
|
||||
{
|
||||
/* "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_spacing = 16;
|
||||
opt.dots_in_line = 48;
|
||||
@ -433,7 +433,7 @@ dot_set_params (const char *params)
|
||||
else if (!strcasecmp (params, "mega"))
|
||||
{
|
||||
/* "Mega" retrieval, for retrieving very long files; each dot is
|
||||
64K, 8 dots in a cluster, 6 clusters (3M) in a line. */
|
||||
64K, 8 dots in a cluster, 6 clusters (3M) in a line. */
|
||||
opt.dot_bytes = 65536L;
|
||||
opt.dot_spacing = 8;
|
||||
opt.dots_in_line = 48;
|
||||
@ -441,16 +441,16 @@ dot_set_params (const char *params)
|
||||
else if (!strcasecmp (params, "giga"))
|
||||
{
|
||||
/* "Giga" retrieval, for retrieving very very *very* long files;
|
||||
each dot is 1M, 8 dots in a cluster, 4 clusters (32M) in a
|
||||
line. */
|
||||
each dot is 1M, 8 dots in a cluster, 4 clusters (32M) in a
|
||||
line. */
|
||||
opt.dot_bytes = (1L << 20);
|
||||
opt.dot_spacing = 8;
|
||||
opt.dots_in_line = 32;
|
||||
}
|
||||
else
|
||||
fprintf (stderr,
|
||||
_("Invalid dot style specification `%s'; leaving unchanged.\n"),
|
||||
params);
|
||||
_("Invalid dot style specification `%s'; leaving unchanged.\n"),
|
||||
params);
|
||||
}
|
||||
|
||||
/* "Thermometer" (bar) progress. */
|
||||
@ -493,27 +493,27 @@ static volatile sig_atomic_t received_sigwinch;
|
||||
#define ETA_REFRESH_INTERVAL 0.99
|
||||
|
||||
struct bar_progress {
|
||||
wgint initial_length; /* how many bytes have been downloaded
|
||||
previously. */
|
||||
wgint total_length; /* expected total byte count when the
|
||||
download finishes */
|
||||
wgint count; /* bytes downloaded so far */
|
||||
wgint initial_length; /* how many bytes have been downloaded
|
||||
previously. */
|
||||
wgint total_length; /* expected total byte count when the
|
||||
download finishes */
|
||||
wgint count; /* bytes downloaded so far */
|
||||
|
||||
double last_screen_update; /* time of the last screen update,
|
||||
measured since the beginning of
|
||||
download. */
|
||||
double last_screen_update; /* time of the last screen update,
|
||||
measured since the beginning of
|
||||
download. */
|
||||
|
||||
int width; /* screen width we're using at the
|
||||
time the progress gauge was
|
||||
created. this is different from
|
||||
the screen_width global variable in
|
||||
that the latter can be changed by a
|
||||
signal. */
|
||||
char *buffer; /* buffer where the bar "image" is
|
||||
stored. */
|
||||
int tick; /* counter used for drawing the
|
||||
progress bar where the total size
|
||||
is not known. */
|
||||
int width; /* screen width we're using at the
|
||||
time the progress gauge was
|
||||
created. this is different from
|
||||
the screen_width global variable in
|
||||
that the latter can be changed by a
|
||||
signal. */
|
||||
char *buffer; /* buffer where the bar "image" is
|
||||
stored. */
|
||||
int tick; /* counter used for drawing the
|
||||
progress bar where the total size
|
||||
is not known. */
|
||||
|
||||
/* The following variables (kept in a struct for namespace reasons)
|
||||
keep track of recent download speeds. See bar_update() for
|
||||
@ -529,19 +529,19 @@ struct bar_progress {
|
||||
wgint total_bytes;
|
||||
} hist;
|
||||
|
||||
double recent_start; /* timestamp of beginning of current
|
||||
position. */
|
||||
wgint recent_bytes; /* bytes downloaded so far. */
|
||||
double recent_start; /* timestamp of beginning of current
|
||||
position. */
|
||||
wgint recent_bytes; /* bytes downloaded so far. */
|
||||
|
||||
bool stalled; /* set when no data arrives for longer
|
||||
than STALL_START_TIME, then reset
|
||||
when new data arrives. */
|
||||
bool stalled; /* set when no data arrives for longer
|
||||
than STALL_START_TIME, then reset
|
||||
when new data arrives. */
|
||||
|
||||
/* create_image() uses these to make sure that ETA information
|
||||
doesn't flicker. */
|
||||
double last_eta_time; /* time of the last update to download
|
||||
speed and ETA, measured since the
|
||||
beginning of download. */
|
||||
double last_eta_time; /* time of the last update to download
|
||||
speed and ETA, measured since the
|
||||
beginning of download. */
|
||||
int last_eta_value;
|
||||
};
|
||||
|
||||
@ -567,9 +567,9 @@ bar_create (wgint initial, wgint total)
|
||||
{
|
||||
screen_width = determine_screen_width ();
|
||||
if (!screen_width)
|
||||
screen_width = DEFAULT_SCREEN_WIDTH;
|
||||
screen_width = DEFAULT_SCREEN_WIDTH;
|
||||
else if (screen_width < MINIMUM_SCREEN_WIDTH)
|
||||
screen_width = MINIMUM_SCREEN_WIDTH;
|
||||
screen_width = MINIMUM_SCREEN_WIDTH;
|
||||
received_sigwinch = 0;
|
||||
}
|
||||
|
||||
@ -613,15 +613,15 @@ bar_update (void *progress, wgint howmuch, double dltime)
|
||||
int old_width = screen_width;
|
||||
screen_width = determine_screen_width ();
|
||||
if (!screen_width)
|
||||
screen_width = DEFAULT_SCREEN_WIDTH;
|
||||
screen_width = DEFAULT_SCREEN_WIDTH;
|
||||
else if (screen_width < MINIMUM_SCREEN_WIDTH)
|
||||
screen_width = MINIMUM_SCREEN_WIDTH;
|
||||
screen_width = MINIMUM_SCREEN_WIDTH;
|
||||
if (screen_width != old_width)
|
||||
{
|
||||
bp->width = screen_width - 1;
|
||||
bp->buffer = xrealloc (bp->buffer, bp->width + 1);
|
||||
force_screen_update = true;
|
||||
}
|
||||
{
|
||||
bp->width = screen_width - 1;
|
||||
bp->buffer = xrealloc (bp->buffer, bp->width + 1);
|
||||
force_screen_update = true;
|
||||
}
|
||||
received_sigwinch = 0;
|
||||
}
|
||||
|
||||
@ -689,18 +689,18 @@ update_speed_ring (struct bar_progress *bp, wgint howmuch, double dltime)
|
||||
if (howmuch == 0)
|
||||
{
|
||||
/* If we're not downloading anything, we might be stalling,
|
||||
i.e. not downloading anything for an extended period of time.
|
||||
Since 0-reads do not enter the history ring, recent_age
|
||||
effectively measures the time since last read. */
|
||||
i.e. not downloading anything for an extended period of time.
|
||||
Since 0-reads do not enter the history ring, recent_age
|
||||
effectively measures the time since last read. */
|
||||
if (recent_age >= STALL_START_TIME)
|
||||
{
|
||||
/* If we're stalling, reset the ring contents because it's
|
||||
stale and because it will make bar_update stop printing
|
||||
the (bogus) current bandwidth. */
|
||||
bp->stalled = true;
|
||||
xzero (*hist);
|
||||
bp->recent_bytes = 0;
|
||||
}
|
||||
{
|
||||
/* If we're stalling, reset the ring contents because it's
|
||||
stale and because it will make bar_update stop printing
|
||||
the (bogus) current bandwidth. */
|
||||
bp->stalled = true;
|
||||
xzero (*hist);
|
||||
bp->recent_bytes = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -711,10 +711,10 @@ update_speed_ring (struct bar_progress *bp, wgint howmuch, double dltime)
|
||||
{
|
||||
bp->stalled = false;
|
||||
/* "recent_age" includes the the entired stalled period, which
|
||||
could be very long. Don't update the speed ring with that
|
||||
value because the current bandwidth would start too small.
|
||||
Start with an arbitrary (but more reasonable) time value and
|
||||
let it level out. */
|
||||
could be very long. Don't update the speed ring with that
|
||||
value because the current bandwidth would start too small.
|
||||
Start with an arbitrary (but more reasonable) time value and
|
||||
let it level out. */
|
||||
recent_age = 1;
|
||||
}
|
||||
|
||||
@ -747,8 +747,8 @@ update_speed_ring (struct bar_progress *bp, wgint howmuch, double dltime)
|
||||
double sumt = 0, sumb = 0;
|
||||
for (i = 0; i < DLSPEED_HISTORY_SIZE; i++)
|
||||
{
|
||||
sumt += hist->times[i];
|
||||
sumb += hist->bytes[i];
|
||||
sumt += hist->times[i];
|
||||
sumb += hist->bytes[i];
|
||||
}
|
||||
assert (sumb == hist->total_bytes);
|
||||
/* 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
|
||||
}
|
||||
|
||||
#define APPEND_LITERAL(s) do { \
|
||||
memcpy (p, s, sizeof (s) - 1); \
|
||||
p += sizeof (s) - 1; \
|
||||
#define APPEND_LITERAL(s) do { \
|
||||
memcpy (p, s, sizeof (s) - 1); \
|
||||
p += sizeof (s) - 1; \
|
||||
} while (0)
|
||||
|
||||
/* 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);
|
||||
|
||||
if (percentage < 100)
|
||||
sprintf (p, "%2d%% ", percentage);
|
||||
sprintf (p, "%2d%% ", percentage);
|
||||
else
|
||||
strcpy (p, "100%");
|
||||
strcpy (p, "100%");
|
||||
p += 4;
|
||||
}
|
||||
else
|
||||
@ -845,43 +845,43 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
|
||||
begin = p;
|
||||
|
||||
/* Print the initial portion of the download with '+' chars, the
|
||||
rest with '=' and one '>'. */
|
||||
rest with '=' and one '>'. */
|
||||
for (i = 0; i < insz; i++)
|
||||
*p++ = '+';
|
||||
*p++ = '+';
|
||||
dlsz -= insz;
|
||||
if (dlsz > 0)
|
||||
{
|
||||
for (i = 0; i < dlsz - 1; i++)
|
||||
*p++ = '=';
|
||||
*p++ = '>';
|
||||
}
|
||||
{
|
||||
for (i = 0; i < dlsz - 1; i++)
|
||||
*p++ = '=';
|
||||
*p++ = '>';
|
||||
}
|
||||
|
||||
while (p - begin < progress_size)
|
||||
*p++ = ' ';
|
||||
*p++ = ' ';
|
||||
*p++ = ']';
|
||||
}
|
||||
else if (progress_size)
|
||||
{
|
||||
/* 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 i, pos;
|
||||
|
||||
/* Make the star move in two directions. */
|
||||
if (ind < progress_size - 2)
|
||||
pos = ind + 1;
|
||||
pos = ind + 1;
|
||||
else
|
||||
pos = progress_size - (ind - progress_size + 5);
|
||||
pos = progress_size - (ind - progress_size + 5);
|
||||
|
||||
*p++ = '[';
|
||||
for (i = 0; i < progress_size; i++)
|
||||
{
|
||||
if (i == pos - 1) *p++ = '<';
|
||||
else if (i == pos ) *p++ = '=';
|
||||
else if (i == pos + 1) *p++ = '>';
|
||||
else
|
||||
*p++ = ' ';
|
||||
}
|
||||
{
|
||||
if (i == pos - 1) *p++ = '<';
|
||||
else if (i == pos ) *p++ = '=';
|
||||
else if (i == pos + 1) *p++ = '>';
|
||||
else
|
||||
*p++ = ' ';
|
||||
}
|
||||
*p++ = ']';
|
||||
|
||||
++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" };
|
||||
int units = 0;
|
||||
/* 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;
|
||||
double dltime = hist->total_time + (dl_total_time - bp->recent_start);
|
||||
double dlspeed = calc_rate (dlquant, dltime, &units);
|
||||
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);
|
||||
}
|
||||
else
|
||||
@ -911,59 +911,59 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
|
||||
if (!done)
|
||||
{
|
||||
/* " eta ..m ..s"; wait for three seconds before displaying the ETA.
|
||||
That's because the ETA value needs a while to become
|
||||
reliable. */
|
||||
That's because the ETA value needs a while to become
|
||||
reliable. */
|
||||
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
|
||||
per second; doing so would cause flashing without providing
|
||||
any value to the user. */
|
||||
if (bp->total_length != size
|
||||
&& bp->last_eta_value != 0
|
||||
&& dl_total_time - bp->last_eta_time < ETA_REFRESH_INTERVAL)
|
||||
eta = bp->last_eta_value;
|
||||
else
|
||||
{
|
||||
/* Calculate ETA using the average download speed to predict
|
||||
the future speed. If you want to use a speed averaged
|
||||
over a more recent period, replace dl_total_time with
|
||||
hist->total_time and bp->count with hist->total_bytes.
|
||||
I found that doing that results in a very jerky and
|
||||
ultimately unreliable ETA. */
|
||||
wgint bytes_remaining = bp->total_length - size;
|
||||
double eta_ = dl_total_time * bytes_remaining / bp->count;
|
||||
if (eta_ >= INT_MAX - 1)
|
||||
goto skip_eta;
|
||||
eta = (int) (eta_ + 0.5);
|
||||
bp->last_eta_value = eta;
|
||||
bp->last_eta_time = dl_total_time;
|
||||
}
|
||||
/* Don't change the value of ETA more than approximately once
|
||||
per second; doing so would cause flashing without providing
|
||||
any value to the user. */
|
||||
if (bp->total_length != size
|
||||
&& bp->last_eta_value != 0
|
||||
&& dl_total_time - bp->last_eta_time < ETA_REFRESH_INTERVAL)
|
||||
eta = bp->last_eta_value;
|
||||
else
|
||||
{
|
||||
/* Calculate ETA using the average download speed to predict
|
||||
the future speed. If you want to use a speed averaged
|
||||
over a more recent period, replace dl_total_time with
|
||||
hist->total_time and bp->count with hist->total_bytes.
|
||||
I found that doing that results in a very jerky and
|
||||
ultimately unreliable ETA. */
|
||||
wgint bytes_remaining = bp->total_length - size;
|
||||
double eta_ = dl_total_time * bytes_remaining / bp->count;
|
||||
if (eta_ >= INT_MAX - 1)
|
||||
goto skip_eta;
|
||||
eta = (int) (eta_ + 0.5);
|
||||
bp->last_eta_value = eta;
|
||||
bp->last_eta_time = dl_total_time;
|
||||
}
|
||||
|
||||
/* Translation note: "ETA" is English-centric, but this must
|
||||
be short, ideally 3 chars. Abbreviate if necessary. */
|
||||
sprintf (p, _(" eta %s"), eta_to_human_short (eta, false));
|
||||
move_to_end (p);
|
||||
}
|
||||
/* Translation note: "ETA" is English-centric, but this must
|
||||
be short, ideally 3 chars. Abbreviate if necessary. */
|
||||
sprintf (p, _(" eta %s"), eta_to_human_short (eta, false));
|
||||
move_to_end (p);
|
||||
}
|
||||
else if (bp->total_length > 0)
|
||||
{
|
||||
skip_eta:
|
||||
APPEND_LITERAL (" ");
|
||||
}
|
||||
{
|
||||
skip_eta:
|
||||
APPEND_LITERAL (" ");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* When the download is done, print the elapsed time. */
|
||||
|
||||
/* Note to translators: this should not take up more room than
|
||||
available here. Abbreviate if necessary. */
|
||||
available here. Abbreviate if necessary. */
|
||||
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)
|
||||
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
|
||||
sprintf (p, "%ss", print_decimal (dl_total_time));
|
||||
sprintf (p, "%ss", print_decimal (dl_total_time));
|
||||
move_to_end (p);
|
||||
}
|
||||
|
||||
@ -998,24 +998,24 @@ bar_set_params (const char *params)
|
||||
if ((opt.lfilename
|
||||
#ifdef HAVE_ISATTY
|
||||
/* The progress bar doesn't make sense if the output is not a
|
||||
TTY -- when logging to file, it is better to review the
|
||||
dots. */
|
||||
TTY -- when logging to file, it is better to review the
|
||||
dots. */
|
||||
|| !isatty (fileno (stderr))
|
||||
#endif
|
||||
/* Normally we don't depend on terminal type because the
|
||||
progress bar only uses ^M to move the cursor to the
|
||||
beginning of line, which works even on dumb terminals. But
|
||||
Jamie Zawinski reports that ^M and ^H tricks don't work in
|
||||
Emacs shell buffers, and only make a mess. */
|
||||
progress bar only uses ^M to move the cursor to the
|
||||
beginning of line, which works even on dumb terminals. But
|
||||
Jamie Zawinski reports that ^M and ^H tricks don't work in
|
||||
Emacs shell buffers, and only make a mess. */
|
||||
|| (term && 0 == strcmp (term, "emacs"))
|
||||
)
|
||||
&& !current_impl_locked)
|
||||
{
|
||||
/* We're not printing to a TTY, so revert to the fallback
|
||||
display. #### We're recursively calling
|
||||
set_progress_implementation here, which is slightly kludgy.
|
||||
It would be nicer if we provided that function a return value
|
||||
indicating a failure of some sort. */
|
||||
display. #### We're recursively calling
|
||||
set_progress_implementation here, which is slightly kludgy.
|
||||
It would be nicer if we provided that function a return value
|
||||
indicating a failure of some sort. */
|
||||
set_progress_implementation (FALLBACK_PROGRESS_IMPLEMENTATION);
|
||||
return;
|
||||
}
|
||||
@ -1049,7 +1049,7 @@ progress_handle_sigwinch (int sig)
|
||||
static const char *
|
||||
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;
|
||||
const char *space = condensed ? "" : " ";
|
||||
|
||||
|
32
src/ptimer.c
32
src/ptimer.c
@ -33,7 +33,7 @@ so, delete this exception statement from your version. */
|
||||
ptimer_new -- creates a timer.
|
||||
ptimer_reset -- resets the timer's elapsed time to zero.
|
||||
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_destroy -- destroy the timer.
|
||||
ptimer_granularity -- returns the approximate granularity of the timers.
|
||||
@ -81,11 +81,11 @@ so, delete this exception statement from your version. */
|
||||
#undef PTIMER_WINDOWS
|
||||
|
||||
#if defined(WINDOWS) || defined(__CYGWIN__)
|
||||
# define PTIMER_WINDOWS /* use Windows timers */
|
||||
# define PTIMER_WINDOWS /* use Windows timers */
|
||||
#elif _POSIX_TIMERS - 0 > 0
|
||||
# define PTIMER_POSIX /* use POSIX timers (clock_gettime) */
|
||||
# define PTIMER_POSIX /* use POSIX timers (clock_gettime) */
|
||||
#else
|
||||
# define PTIMER_GETTIMEOFDAY /* use gettimeofday */
|
||||
# define PTIMER_GETTIMEOFDAY /* use gettimeofday */
|
||||
#endif
|
||||
|
||||
#ifdef PTIMER_POSIX
|
||||
@ -142,23 +142,23 @@ posix_init (void)
|
||||
{
|
||||
struct timespec r;
|
||||
if (clocks[i].sysconf_name != NO_SYSCONF_CHECK)
|
||||
if (sysconf (clocks[i].sysconf_name) < 0)
|
||||
continue; /* sysconf claims this clock is unavailable */
|
||||
if (sysconf (clocks[i].sysconf_name) < 0)
|
||||
continue; /* sysconf claims this clock is unavailable */
|
||||
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_resolution = (double) r.tv_sec + r.tv_nsec / 1e9;
|
||||
/* Guard against nonsense returned by a broken clock_getres. */
|
||||
if (posix_clock_resolution == 0)
|
||||
posix_clock_resolution = 1e-3;
|
||||
posix_clock_resolution = 1e-3;
|
||||
break;
|
||||
}
|
||||
if (i == countof (clocks))
|
||||
{
|
||||
/* 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"),
|
||||
strerror (errno));
|
||||
strerror (errno));
|
||||
/* Use CLOCK_REALTIME, but invent a plausible resolution. */
|
||||
posix_clock_id = CLOCK_REALTIME;
|
||||
posix_clock_resolution = 1e-3;
|
||||
@ -175,7 +175,7 @@ static inline double
|
||||
posix_diff (ptimer_system_time *pst1, ptimer_system_time *pst2)
|
||||
{
|
||||
return ((pst1->tv_sec - pst2->tv_sec)
|
||||
+ (pst1->tv_nsec - pst2->tv_nsec) / 1e9);
|
||||
+ (pst1->tv_nsec - pst2->tv_nsec) / 1e9);
|
||||
}
|
||||
|
||||
static inline double
|
||||
@ -183,7 +183,7 @@ posix_resolution (void)
|
||||
{
|
||||
return posix_clock_resolution;
|
||||
}
|
||||
#endif /* PTIMER_POSIX */
|
||||
#endif /* PTIMER_POSIX */
|
||||
|
||||
#ifdef PTIMER_GETTIMEOFDAY
|
||||
/* 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)
|
||||
{
|
||||
return ((pst1->tv_sec - pst2->tv_sec)
|
||||
+ (pst1->tv_usec - pst2->tv_usec) / 1e6);
|
||||
+ (pst1->tv_usec - pst2->tv_usec) / 1e6);
|
||||
}
|
||||
|
||||
static inline double
|
||||
@ -219,7 +219,7 @@ gettimeofday_resolution (void)
|
||||
than 1ms. Assume 100 usecs. */
|
||||
return 0.1;
|
||||
}
|
||||
#endif /* PTIMER_GETTIMEOFDAY */
|
||||
#endif /* PTIMER_GETTIMEOFDAY */
|
||||
|
||||
#ifdef PTIMER_WINDOWS
|
||||
/* Elapsed time measurement on Windows: where high-resolution timers
|
||||
@ -290,9 +290,9 @@ windows_resolution (void)
|
||||
if (windows_hires_timers)
|
||||
return 1.0 / windows_hires_freq;
|
||||
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. */
|
||||
|
||||
|
402
src/recur.c
402
src/recur.c
@ -52,13 +52,13 @@ so, delete this exception statement from your version. */
|
||||
/* Functions for maintaining the URL queue. */
|
||||
|
||||
struct queue_element {
|
||||
const char *url; /* the URL to download */
|
||||
const char *referer; /* the referring document */
|
||||
int depth; /* the depth */
|
||||
bool html_allowed; /* whether the document is allowed to
|
||||
be treated as HTML. */
|
||||
const char *url; /* the URL to download */
|
||||
const char *referer; /* the referring document */
|
||||
int depth; /* the depth */
|
||||
bool html_allowed; /* whether the document is allowed to
|
||||
be treated as HTML. */
|
||||
|
||||
struct queue_element *next; /* next element in queue */
|
||||
struct queue_element *next; /* next element in queue */
|
||||
};
|
||||
|
||||
struct url_queue {
|
||||
@ -90,7 +90,7 @@ url_queue_delete (struct url_queue *queue)
|
||||
|
||||
static void
|
||||
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);
|
||||
qel->url = url;
|
||||
@ -119,8 +119,8 @@ url_enqueue (struct url_queue *queue,
|
||||
|
||||
static bool
|
||||
url_dequeue (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 = queue->head;
|
||||
|
||||
@ -146,9 +146,9 @@ url_dequeue (struct url_queue *queue,
|
||||
}
|
||||
|
||||
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,
|
||||
struct url *, struct hash_table *);
|
||||
struct url *, struct hash_table *);
|
||||
|
||||
|
||||
/* 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
|
||||
satisfies the criteria specified by the various command-line
|
||||
options, add it to the queue. */
|
||||
options, add it to the queue. */
|
||||
|
||||
uerr_t
|
||||
retrieve_tree (const char *start_url)
|
||||
@ -190,7 +190,7 @@ retrieve_tree (const char *start_url)
|
||||
if (!start_url_parsed)
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, "%s: %s.\n", start_url,
|
||||
url_error (up_error_code));
|
||||
url_error (up_error_code));
|
||||
return URLERROR;
|
||||
}
|
||||
|
||||
@ -211,176 +211,176 @@ retrieve_tree (const char *start_url)
|
||||
bool dash_p_leaf_HTML = false;
|
||||
|
||||
if (opt.quota && total_downloaded_bytes > opt.quota)
|
||||
break;
|
||||
break;
|
||||
if (status == FWRITEERR)
|
||||
break;
|
||||
break;
|
||||
|
||||
/* Get the next URL from the queue... */
|
||||
|
||||
if (!url_dequeue (queue,
|
||||
(const char **)&url, (const char **)&referer,
|
||||
&depth, &html_allowed))
|
||||
break;
|
||||
(const char **)&url, (const char **)&referer,
|
||||
&depth, &html_allowed))
|
||||
break;
|
||||
|
||||
/* ...and download it. Note that this download is in most cases
|
||||
unconditional, as download_child_p already makes sure a file
|
||||
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
|
||||
URL1 URL2', and a random URL is encountered once under URL1
|
||||
and again under URL2, but at a different (possibly smaller)
|
||||
depth, we want the URL's children to be taken into account
|
||||
the second time. */
|
||||
unconditional, as download_child_p already makes sure a file
|
||||
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
|
||||
URL1 URL2', and a random URL is encountered once under URL1
|
||||
and again under URL2, but at a different (possibly smaller)
|
||||
depth, we want the URL's children to be taken into account
|
||||
the second time. */
|
||||
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",
|
||||
url, file));
|
||||
DEBUGP (("Already downloaded \"%s\", reusing it from \"%s\".\n",
|
||||
url, file));
|
||||
|
||||
if (html_allowed
|
||||
&& downloaded_html_set
|
||||
&& string_set_contains (downloaded_html_set, file))
|
||||
descend = true;
|
||||
}
|
||||
if (html_allowed
|
||||
&& downloaded_html_set
|
||||
&& string_set_contains (downloaded_html_set, file))
|
||||
descend = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
int dt = 0;
|
||||
char *redirected = NULL;
|
||||
{
|
||||
int dt = 0;
|
||||
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
|
||||
&& (dt & RETROKF) && (dt & TEXTHTML))
|
||||
descend = true;
|
||||
if (html_allowed && file && status == RETROK
|
||||
&& (dt & RETROKF) && (dt & TEXTHTML))
|
||||
descend = true;
|
||||
|
||||
if (redirected)
|
||||
{
|
||||
/* We have been redirected, possibly to another host, or
|
||||
different path, or wherever. Check whether we really
|
||||
want to follow it. */
|
||||
if (descend)
|
||||
{
|
||||
if (!descend_redirect_p (redirected, url, depth,
|
||||
start_url_parsed, blacklist))
|
||||
descend = false;
|
||||
else
|
||||
/* Make sure that the old pre-redirect form gets
|
||||
blacklisted. */
|
||||
string_set_add (blacklist, url);
|
||||
}
|
||||
if (redirected)
|
||||
{
|
||||
/* We have been redirected, possibly to another host, or
|
||||
different path, or wherever. Check whether we really
|
||||
want to follow it. */
|
||||
if (descend)
|
||||
{
|
||||
if (!descend_redirect_p (redirected, url, depth,
|
||||
start_url_parsed, blacklist))
|
||||
descend = false;
|
||||
else
|
||||
/* Make sure that the old pre-redirect form gets
|
||||
blacklisted. */
|
||||
string_set_add (blacklist, url);
|
||||
}
|
||||
|
||||
xfree (url);
|
||||
url = redirected;
|
||||
}
|
||||
}
|
||||
xfree (url);
|
||||
url = redirected;
|
||||
}
|
||||
}
|
||||
|
||||
if (opt.spider)
|
||||
{
|
||||
{
|
||||
visited_url (url, referer);
|
||||
}
|
||||
}
|
||||
|
||||
if (descend
|
||||
&& depth >= opt.reclevel && opt.reclevel != INFINITE_RECURSION)
|
||||
{
|
||||
if (opt.page_requisites
|
||||
&& (depth == opt.reclevel || depth == opt.reclevel + 1))
|
||||
{
|
||||
/* When -p is specified, we are allowed to exceed the
|
||||
maximum depth, but only for the "inline" links,
|
||||
i.e. those that are needed to display the page.
|
||||
Originally this could exceed the depth at most by
|
||||
one, but we allow one more level so that the leaf
|
||||
pages that contain frames can be loaded
|
||||
correctly. */
|
||||
dash_p_leaf_HTML = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Either -p wasn't specified or it was and we've
|
||||
already spent the two extra (pseudo-)levels that it
|
||||
affords us, so we need to bail out. */
|
||||
DEBUGP (("Not descending further; at depth %d, max. %d.\n",
|
||||
depth, opt.reclevel));
|
||||
descend = false;
|
||||
}
|
||||
}
|
||||
&& depth >= opt.reclevel && opt.reclevel != INFINITE_RECURSION)
|
||||
{
|
||||
if (opt.page_requisites
|
||||
&& (depth == opt.reclevel || depth == opt.reclevel + 1))
|
||||
{
|
||||
/* When -p is specified, we are allowed to exceed the
|
||||
maximum depth, but only for the "inline" links,
|
||||
i.e. those that are needed to display the page.
|
||||
Originally this could exceed the depth at most by
|
||||
one, but we allow one more level so that the leaf
|
||||
pages that contain frames can be loaded
|
||||
correctly. */
|
||||
dash_p_leaf_HTML = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Either -p wasn't specified or it was and we've
|
||||
already spent the two extra (pseudo-)levels that it
|
||||
affords us, so we need to bail out. */
|
||||
DEBUGP (("Not descending further; at depth %d, max. %d.\n",
|
||||
depth, opt.reclevel));
|
||||
descend = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the downloaded document was HTML, parse it and enqueue the
|
||||
links it contains. */
|
||||
links it contains. */
|
||||
|
||||
if (descend)
|
||||
{
|
||||
bool meta_disallow_follow = false;
|
||||
struct urlpos *children
|
||||
= get_urls_html (file, url, &meta_disallow_follow);
|
||||
{
|
||||
bool meta_disallow_follow = false;
|
||||
struct urlpos *children
|
||||
= get_urls_html (file, url, &meta_disallow_follow);
|
||||
|
||||
if (opt.use_robots && meta_disallow_follow)
|
||||
{
|
||||
free_urlpos (children);
|
||||
children = NULL;
|
||||
}
|
||||
if (opt.use_robots && meta_disallow_follow)
|
||||
{
|
||||
free_urlpos (children);
|
||||
children = NULL;
|
||||
}
|
||||
|
||||
if (children)
|
||||
{
|
||||
struct urlpos *child = children;
|
||||
struct url *url_parsed = url_parsed = url_parse (url, NULL);
|
||||
if (children)
|
||||
{
|
||||
struct urlpos *child = children;
|
||||
struct url *url_parsed = url_parsed = url_parse (url, NULL);
|
||||
char *referer_url = url;
|
||||
bool strip_auth = url_parsed->user;
|
||||
assert (url_parsed != NULL);
|
||||
assert (url_parsed != NULL);
|
||||
|
||||
/* Strip auth info if present */
|
||||
if (strip_auth)
|
||||
referer_url = url_string (url_parsed, URL_AUTH_HIDE);
|
||||
|
||||
for (; child; child = child->next)
|
||||
{
|
||||
if (child->ignore_when_downloading)
|
||||
continue;
|
||||
if (dash_p_leaf_HTML && !child->link_inline_p)
|
||||
continue;
|
||||
if (download_child_p (child, url_parsed, depth, start_url_parsed,
|
||||
blacklist))
|
||||
{
|
||||
url_enqueue (queue, xstrdup (child->url->url),
|
||||
xstrdup (referer_url), depth + 1,
|
||||
child->link_expect_html);
|
||||
/* We blacklist the URL we have enqueued, because we
|
||||
don't want to enqueue (and hence download) the
|
||||
same URL twice. */
|
||||
string_set_add (blacklist, child->url->url);
|
||||
}
|
||||
}
|
||||
for (; child; child = child->next)
|
||||
{
|
||||
if (child->ignore_when_downloading)
|
||||
continue;
|
||||
if (dash_p_leaf_HTML && !child->link_inline_p)
|
||||
continue;
|
||||
if (download_child_p (child, url_parsed, depth, start_url_parsed,
|
||||
blacklist))
|
||||
{
|
||||
url_enqueue (queue, xstrdup (child->url->url),
|
||||
xstrdup (referer_url), depth + 1,
|
||||
child->link_expect_html);
|
||||
/* We blacklist the URL we have enqueued, because we
|
||||
don't want to enqueue (and hence download) the
|
||||
same URL twice. */
|
||||
string_set_add (blacklist, child->url->url);
|
||||
}
|
||||
}
|
||||
|
||||
if (strip_auth)
|
||||
xfree (referer_url);
|
||||
url_free (url_parsed);
|
||||
free_urlpos (children);
|
||||
}
|
||||
}
|
||||
url_free (url_parsed);
|
||||
free_urlpos (children);
|
||||
}
|
||||
}
|
||||
|
||||
if (file
|
||||
&& (opt.delete_after
|
||||
|| opt.spider /* opt.recursive is implicitely true */
|
||||
|| !acceptable (file)))
|
||||
{
|
||||
/* Either --delete-after was specified, or we loaded this
|
||||
(otherwise unneeded because of --spider or rejected by -R)
|
||||
HTML file just to harvest its hyperlinks -- in either case,
|
||||
delete the local file. */
|
||||
DEBUGP (("Removing file due to %s in recursive_retrieve():\n",
|
||||
opt.delete_after ? "--delete-after" :
|
||||
(opt.spider ? "--spider" :
|
||||
"recursive rejection criteria")));
|
||||
logprintf (LOG_VERBOSE,
|
||||
(opt.delete_after || opt.spider
|
||||
? _("Removing %s.\n")
|
||||
: _("Removing %s since it should be rejected.\n")),
|
||||
file);
|
||||
if (unlink (file))
|
||||
logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
|
||||
logputs (LOG_VERBOSE, "\n");
|
||||
register_delete_file (file);
|
||||
}
|
||||
{
|
||||
/* Either --delete-after was specified, or we loaded this
|
||||
(otherwise unneeded because of --spider or rejected by -R)
|
||||
HTML file just to harvest its hyperlinks -- in either case,
|
||||
delete the local file. */
|
||||
DEBUGP (("Removing file due to %s in recursive_retrieve():\n",
|
||||
opt.delete_after ? "--delete-after" :
|
||||
(opt.spider ? "--spider" :
|
||||
"recursive rejection criteria")));
|
||||
logprintf (LOG_VERBOSE,
|
||||
(opt.delete_after || opt.spider
|
||||
? _("Removing %s.\n")
|
||||
: _("Removing %s since it should be rejected.\n")),
|
||||
file);
|
||||
if (unlink (file))
|
||||
logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
|
||||
logputs (LOG_VERBOSE, "\n");
|
||||
register_delete_file (file);
|
||||
}
|
||||
|
||||
xfree (url);
|
||||
xfree_null (referer);
|
||||
@ -394,10 +394,10 @@ retrieve_tree (const char *start_url)
|
||||
int d3;
|
||||
bool d4;
|
||||
while (url_dequeue (queue,
|
||||
(const char **)&d1, (const char **)&d2, &d3, &d4))
|
||||
(const char **)&d1, (const char **)&d2, &d3, &d4))
|
||||
{
|
||||
xfree (d1);
|
||||
xfree_null (d2);
|
||||
xfree (d1);
|
||||
xfree_null (d2);
|
||||
}
|
||||
}
|
||||
url_queue_delete (queue);
|
||||
@ -424,7 +424,7 @@ retrieve_tree (const char *start_url)
|
||||
|
||||
static bool
|
||||
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;
|
||||
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 (opt.spider)
|
||||
{
|
||||
{
|
||||
char *referrer = url_string (parent, URL_AUTH_HIDE_PASSWD);
|
||||
DEBUGP (("download_child_p: parent->url is: `%s'\n", parent->url));
|
||||
visited_url (url, referrer);
|
||||
xfree (referrer);
|
||||
}
|
||||
xfree (referrer);
|
||||
}
|
||||
DEBUGP (("Already on the black list.\n"));
|
||||
goto out;
|
||||
}
|
||||
@ -481,8 +481,8 @@ download_child_p (const struct urlpos *upos, struct url *parent, int depth,
|
||||
if (u_scheme_like_http)
|
||||
if (opt.relative_only && !upos->link_relative_p)
|
||||
{
|
||||
DEBUGP (("It doesn't really look like a relative link.\n"));
|
||||
goto out;
|
||||
DEBUGP (("It doesn't really look like a relative link.\n"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* 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))
|
||||
{
|
||||
if (!subdir_p (start_url_parsed->dir, u->dir))
|
||||
{
|
||||
DEBUGP (("Going to \"%s\" would escape \"%s\" with no_parent on.\n",
|
||||
u->dir, start_url_parsed->dir));
|
||||
goto out;
|
||||
}
|
||||
{
|
||||
DEBUGP (("Going to \"%s\" would escape \"%s\" with no_parent on.\n",
|
||||
u->dir, start_url_parsed->dir));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 (!accdir (u->dir))
|
||||
{
|
||||
DEBUGP (("%s (%s) is excluded/not-included.\n", url, u->dir));
|
||||
goto out;
|
||||
}
|
||||
{
|
||||
DEBUGP (("%s (%s) is excluded/not-included.\n", url, u->dir));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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.) */
|
||||
if (u->file[0] != '\0'
|
||||
&& !(has_html_suffix_p (u->file)
|
||||
/* The exception only applies to non-leaf HTMLs (but -p
|
||||
always implies non-leaf because we can overstep the
|
||||
maximum depth to get the requisites): */
|
||||
&& (/* non-leaf */
|
||||
opt.reclevel == INFINITE_RECURSION
|
||||
/* also non-leaf */
|
||||
|| depth < opt.reclevel - 1
|
||||
/* -p, which implies non-leaf (see above) */
|
||||
|| opt.page_requisites)))
|
||||
/* The exception only applies to non-leaf HTMLs (but -p
|
||||
always implies non-leaf because we can overstep the
|
||||
maximum depth to get the requisites): */
|
||||
&& (/* non-leaf */
|
||||
opt.reclevel == INFINITE_RECURSION
|
||||
/* also non-leaf */
|
||||
|| depth < opt.reclevel - 1
|
||||
/* -p, which implies non-leaf (see above) */
|
||||
|| opt.page_requisites)))
|
||||
{
|
||||
if (!acceptable (u->file))
|
||||
{
|
||||
DEBUGP (("%s (%s) does not match acc/rej rules.\n",
|
||||
url, u->file));
|
||||
goto out;
|
||||
}
|
||||
{
|
||||
DEBUGP (("%s (%s) does not match acc/rej rules.\n",
|
||||
url, u->file));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* 7. */
|
||||
if (schemes_are_similar_p (u->scheme, parent->scheme))
|
||||
if (!opt.spanhost && 0 != strcasecmp (parent->host, u->host))
|
||||
{
|
||||
DEBUGP (("This is not the same hostname as the parent's (%s and %s).\n",
|
||||
u->host, parent->host));
|
||||
goto out;
|
||||
DEBUGP (("This is not the same hostname as the parent's (%s and %s).\n",
|
||||
u->host, parent->host));
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
if (!specs)
|
||||
{
|
||||
char *rfile;
|
||||
if (res_retrieve_file (url, &rfile))
|
||||
{
|
||||
specs = res_parse_from_file (rfile);
|
||||
xfree (rfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If we cannot get real specs, at least produce
|
||||
dummy ones so that we can register them and stop
|
||||
trying to retrieve them. */
|
||||
specs = res_parse ("", 0);
|
||||
}
|
||||
res_register_specs (u->host, u->port, specs);
|
||||
}
|
||||
{
|
||||
char *rfile;
|
||||
if (res_retrieve_file (url, &rfile))
|
||||
{
|
||||
specs = res_parse_from_file (rfile);
|
||||
xfree (rfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If we cannot get real specs, at least produce
|
||||
dummy ones so that we can register them and stop
|
||||
trying to retrieve them. */
|
||||
specs = res_parse ("", 0);
|
||||
}
|
||||
res_register_specs (u->host, u->port, specs);
|
||||
}
|
||||
|
||||
/* 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))
|
||||
{
|
||||
DEBUGP (("Not following %s because robots.txt forbids it.\n", url));
|
||||
string_set_add (blacklist, url);
|
||||
goto out;
|
||||
}
|
||||
{
|
||||
DEBUGP (("Not following %s because robots.txt forbids it.\n", url));
|
||||
string_set_add (blacklist, url);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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
|
||||
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 urlpos *upos;
|
||||
@ -625,7 +625,7 @@ descend_redirect_p (const char *redirected, const char *original, int depth,
|
||||
upos->url = new_parsed;
|
||||
|
||||
success = download_child_p (upos, orig_parsed, depth,
|
||||
start_url_parsed, blacklist);
|
||||
start_url_parsed, blacklist);
|
||||
|
||||
url_free (orig_parsed);
|
||||
url_free (new_parsed);
|
||||
|
480
src/retr.c
480
src/retr.c
@ -99,31 +99,31 @@ limit_bandwidth (wgint bytes, struct ptimer *timer)
|
||||
double slp = expected - delta_t + limit_data.sleep_adjust;
|
||||
double t0, t1;
|
||||
if (slp < 0.2)
|
||||
{
|
||||
DEBUGP (("deferring a %.2f ms sleep (%s/%.2f).\n",
|
||||
slp * 1000, number_to_static_string (limit_data.chunk_bytes),
|
||||
delta_t));
|
||||
return;
|
||||
}
|
||||
{
|
||||
DEBUGP (("deferring a %.2f ms sleep (%s/%.2f).\n",
|
||||
slp * 1000, number_to_static_string (limit_data.chunk_bytes),
|
||||
delta_t));
|
||||
return;
|
||||
}
|
||||
DEBUGP (("\nsleeping %.2f ms for %s bytes, adjust %.2f ms\n",
|
||||
slp * 1000, number_to_static_string (limit_data.chunk_bytes),
|
||||
limit_data.sleep_adjust));
|
||||
slp * 1000, number_to_static_string (limit_data.chunk_bytes),
|
||||
limit_data.sleep_adjust));
|
||||
|
||||
t0 = ptimer_read (timer);
|
||||
xsleep (slp);
|
||||
t1 = ptimer_measure (timer);
|
||||
|
||||
/* Due to scheduling, we probably slept slightly longer (or
|
||||
shorter) than desired. Calculate the difference between the
|
||||
desired and the actual sleep, and adjust the next sleep by
|
||||
that amount. */
|
||||
shorter) than desired. Calculate the difference between the
|
||||
desired and the actual sleep, and adjust the next sleep by
|
||||
that amount. */
|
||||
limit_data.sleep_adjust = slp - (t1 - t0);
|
||||
/* 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)
|
||||
limit_data.sleep_adjust = 0.5;
|
||||
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;
|
||||
@ -140,7 +140,7 @@ limit_bandwidth (wgint bytes, struct ptimer *timer)
|
||||
|
||||
static int
|
||||
write_data (FILE *out, const char *buf, int bufsize, wgint *skip,
|
||||
wgint *written)
|
||||
wgint *written)
|
||||
{
|
||||
if (!out)
|
||||
return 1;
|
||||
@ -155,7 +155,7 @@ write_data (FILE *out, const char *buf, int bufsize, wgint *skip,
|
||||
bufsize -= *skip;
|
||||
*skip = 0;
|
||||
if (bufsize == 0)
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
fwrite (buf, 1, bufsize, out);
|
||||
@ -190,7 +190,7 @@ write_data (FILE *out, const char *buf, int bufsize, wgint *skip,
|
||||
|
||||
int
|
||||
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;
|
||||
|
||||
@ -222,8 +222,8 @@ fd_read_body (int fd, FILE *out, wgint toread, wgint startpos,
|
||||
if (opt.verbose)
|
||||
{
|
||||
/* If we're skipping STARTPOS bytes, pass 0 as the INITIAL
|
||||
argument to progress_create because the indicator doesn't
|
||||
(yet) know about "skipping" data. */
|
||||
argument to progress_create because the indicator doesn't
|
||||
(yet) know about "skipping" data. */
|
||||
progress = progress_create (skip ? 0 : startpos, startpos + toread);
|
||||
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;
|
||||
double tmout = opt.read_timeout;
|
||||
if (progress_interactive)
|
||||
{
|
||||
/* For interactive progress gauges, always specify a ~1s
|
||||
timeout, so that the gauge can be updated regularly even
|
||||
when the data arrives very slowly or stalls. */
|
||||
tmout = 0.95;
|
||||
if (opt.read_timeout)
|
||||
{
|
||||
double waittm;
|
||||
waittm = ptimer_read (timer) - last_successful_read_tm;
|
||||
if (waittm + tmout > opt.read_timeout)
|
||||
{
|
||||
/* Don't let total idle time exceed read timeout. */
|
||||
tmout = opt.read_timeout - waittm;
|
||||
if (tmout < 0)
|
||||
{
|
||||
/* We've already exceeded the timeout. */
|
||||
ret = -1, errno = ETIMEDOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
/* For interactive progress gauges, always specify a ~1s
|
||||
timeout, so that the gauge can be updated regularly even
|
||||
when the data arrives very slowly or stalls. */
|
||||
tmout = 0.95;
|
||||
if (opt.read_timeout)
|
||||
{
|
||||
double waittm;
|
||||
waittm = ptimer_read (timer) - last_successful_read_tm;
|
||||
if (waittm + tmout > opt.read_timeout)
|
||||
{
|
||||
/* Don't let total idle time exceed read timeout. */
|
||||
tmout = opt.read_timeout - waittm;
|
||||
if (tmout < 0)
|
||||
{
|
||||
/* We've already exceeded the timeout. */
|
||||
ret = -1, errno = ETIMEDOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = fd_read (fd, dlbuf, rdsize, tmout);
|
||||
|
||||
if (progress_interactive && ret < 0 && errno == ETIMEDOUT)
|
||||
ret = 0; /* interactive timeout, handled above */
|
||||
ret = 0; /* interactive timeout, handled above */
|
||||
else if (ret <= 0)
|
||||
break; /* EOF or read error */
|
||||
break; /* EOF or read error */
|
||||
|
||||
if (progress || opt.limit_rate)
|
||||
{
|
||||
ptimer_measure (timer);
|
||||
if (ret > 0)
|
||||
last_successful_read_tm = ptimer_read (timer);
|
||||
}
|
||||
{
|
||||
ptimer_measure (timer);
|
||||
if (ret > 0)
|
||||
last_successful_read_tm = ptimer_read (timer);
|
||||
}
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
sum_read += ret;
|
||||
if (!write_data (out, dlbuf, ret, &skip, &sum_written))
|
||||
{
|
||||
ret = -2;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
{
|
||||
sum_read += ret;
|
||||
if (!write_data (out, dlbuf, ret, &skip, &sum_written))
|
||||
{
|
||||
ret = -2;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (opt.limit_rate)
|
||||
limit_bandwidth (ret, timer);
|
||||
limit_bandwidth (ret, timer);
|
||||
|
||||
if (progress)
|
||||
progress_update (progress, ret, ptimer_read (timer));
|
||||
progress_update (progress, ret, ptimer_read (timer));
|
||||
#ifdef WINDOWS
|
||||
if (toread > 0 && !opt.quiet)
|
||||
ws_percenttitle (100.0 *
|
||||
(startpos + sum_read) / (startpos + toread));
|
||||
ws_percenttitle (100.0 *
|
||||
(startpos + sum_read) / (startpos + toread));
|
||||
#endif
|
||||
}
|
||||
if (ret < -1)
|
||||
@ -389,7 +389,7 @@ fd_read_hunk (int fd, hunk_terminator_t terminator, long sizehint, long maxsize)
|
||||
{
|
||||
long bufsize = sizehint;
|
||||
char *hunk = xmalloc (bufsize);
|
||||
int tail = 0; /* tail position in HUNK */
|
||||
int tail = 0; /* tail position in HUNK */
|
||||
|
||||
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);
|
||||
if (pklen < 0)
|
||||
{
|
||||
xfree (hunk);
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
xfree (hunk);
|
||||
return NULL;
|
||||
}
|
||||
end = terminator (hunk, hunk + tail, pklen);
|
||||
if (end)
|
||||
{
|
||||
/* The data contains the terminator: we'll drain the data up
|
||||
to the end of the terminator. */
|
||||
remain = end - (hunk + tail);
|
||||
assert (remain >= 0);
|
||||
if (remain == 0)
|
||||
{
|
||||
/* No more data needs to be read. */
|
||||
hunk[tail] = '\0';
|
||||
return hunk;
|
||||
}
|
||||
if (bufsize - 1 < tail + remain)
|
||||
{
|
||||
bufsize = tail + remain + 1;
|
||||
hunk = xrealloc (hunk, bufsize);
|
||||
}
|
||||
}
|
||||
{
|
||||
/* The data contains the terminator: we'll drain the data up
|
||||
to the end of the terminator. */
|
||||
remain = end - (hunk + tail);
|
||||
assert (remain >= 0);
|
||||
if (remain == 0)
|
||||
{
|
||||
/* No more data needs to be read. */
|
||||
hunk[tail] = '\0';
|
||||
return hunk;
|
||||
}
|
||||
if (bufsize - 1 < tail + remain)
|
||||
{
|
||||
bufsize = tail + remain + 1;
|
||||
hunk = xrealloc (hunk, bufsize);
|
||||
}
|
||||
}
|
||||
else
|
||||
/* No terminator: simply read the data we know is (or should
|
||||
be) available. */
|
||||
remain = pklen;
|
||||
/* No terminator: simply read the data we know is (or should
|
||||
be) available. */
|
||||
remain = pklen;
|
||||
|
||||
/* Now, read the data. Note that we make no assumptions about
|
||||
how much data we'll get. (Some TCP stacks are notorious for
|
||||
read returning less data than the previous MSG_PEEK.) */
|
||||
how much data we'll get. (Some TCP stacks are notorious for
|
||||
read returning less data than the previous MSG_PEEK.) */
|
||||
|
||||
rdlen = fd_read (fd, hunk + tail, remain, 0);
|
||||
if (rdlen < 0)
|
||||
{
|
||||
xfree_null (hunk);
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
xfree_null (hunk);
|
||||
return NULL;
|
||||
}
|
||||
tail += rdlen;
|
||||
hunk[tail] = '\0';
|
||||
|
||||
if (rdlen == 0)
|
||||
{
|
||||
if (tail == 0)
|
||||
{
|
||||
/* EOF without anything having been read */
|
||||
xfree (hunk);
|
||||
errno = 0;
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
/* EOF seen: return the data we've read. */
|
||||
return hunk;
|
||||
}
|
||||
{
|
||||
if (tail == 0)
|
||||
{
|
||||
/* EOF without anything having been read */
|
||||
xfree (hunk);
|
||||
errno = 0;
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
/* EOF seen: return the data we've read. */
|
||||
return hunk;
|
||||
}
|
||||
if (end && rdlen == remain)
|
||||
/* The terminator was seen and the remaining data drained --
|
||||
we got what we came for. */
|
||||
return hunk;
|
||||
/* The terminator was seen and the remaining data drained --
|
||||
we got what we came for. */
|
||||
return hunk;
|
||||
|
||||
/* Keep looping until all the data arrives. */
|
||||
|
||||
if (tail == bufsize - 1)
|
||||
{
|
||||
/* Double the buffer size, but refuse to allocate more than
|
||||
MAXSIZE bytes. */
|
||||
if (maxsize && bufsize >= maxsize)
|
||||
{
|
||||
xfree (hunk);
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
bufsize <<= 1;
|
||||
if (maxsize && bufsize > maxsize)
|
||||
bufsize = maxsize;
|
||||
hunk = xrealloc (hunk, bufsize);
|
||||
}
|
||||
{
|
||||
/* Double the buffer size, but refuse to allocate more than
|
||||
MAXSIZE bytes. */
|
||||
if (maxsize && bufsize >= maxsize)
|
||||
{
|
||||
xfree (hunk);
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
bufsize <<= 1;
|
||||
if (maxsize && bufsize > maxsize)
|
||||
bufsize = maxsize;
|
||||
hunk = xrealloc (hunk, bufsize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -524,8 +524,8 @@ retr_rate (wgint bytes, double secs)
|
||||
/* Use more digits for smaller numbers (regardless of unit used),
|
||||
e.g. "1022", "247", "12.5", "2.38". */
|
||||
sprintf (res, "%.*f %s",
|
||||
dlrate >= 99.95 ? 0 : dlrate >= 9.995 ? 1 : 2,
|
||||
dlrate, rate_names[units]);
|
||||
dlrate >= 99.95 ? 0 : dlrate >= 9.995 ? 1 : 2,
|
||||
dlrate, rate_names[units]);
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -568,21 +568,21 @@ calc_rate (wgint bytes, double secs, int *units)
|
||||
}
|
||||
|
||||
|
||||
#define SUSPEND_POST_DATA do { \
|
||||
post_data_suspended = true; \
|
||||
saved_post_data = opt.post_data; \
|
||||
saved_post_file_name = opt.post_file_name; \
|
||||
opt.post_data = NULL; \
|
||||
opt.post_file_name = NULL; \
|
||||
#define SUSPEND_POST_DATA do { \
|
||||
post_data_suspended = true; \
|
||||
saved_post_data = opt.post_data; \
|
||||
saved_post_file_name = opt.post_file_name; \
|
||||
opt.post_data = NULL; \
|
||||
opt.post_file_name = NULL; \
|
||||
} while (0)
|
||||
|
||||
#define RESTORE_POST_DATA do { \
|
||||
if (post_data_suspended) \
|
||||
{ \
|
||||
opt.post_data = saved_post_data; \
|
||||
opt.post_file_name = saved_post_file_name; \
|
||||
post_data_suspended = false; \
|
||||
} \
|
||||
#define RESTORE_POST_DATA do { \
|
||||
if (post_data_suspended) \
|
||||
{ \
|
||||
opt.post_data = saved_post_data; \
|
||||
opt.post_file_name = saved_post_file_name; \
|
||||
post_data_suspended = false; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static char *getproxy (struct url *);
|
||||
@ -595,7 +595,7 @@ static char *getproxy (struct url *);
|
||||
|
||||
uerr_t
|
||||
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;
|
||||
char *url;
|
||||
@ -603,7 +603,7 @@ retrieve_url (const char *origurl, char **file, char **newloc,
|
||||
int dummy;
|
||||
char *mynewloc, *proxy;
|
||||
struct url *u, *proxy_url;
|
||||
int up_error_code; /* url parse error code */
|
||||
int up_error_code; /* url parse error code */
|
||||
char *local_file;
|
||||
int redirection_count = 0;
|
||||
|
||||
@ -647,21 +647,21 @@ retrieve_url (const char *origurl, char **file, char **newloc,
|
||||
/* Parse the proxy URL. */
|
||||
proxy_url = url_parse (proxy, &up_error_code);
|
||||
if (!proxy_url)
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("Error parsing proxy URL %s: %s.\n"),
|
||||
proxy, url_error (up_error_code));
|
||||
xfree (url);
|
||||
RESTORE_POST_DATA;
|
||||
return PROXERR;
|
||||
}
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("Error parsing proxy URL %s: %s.\n"),
|
||||
proxy, url_error (up_error_code));
|
||||
xfree (url);
|
||||
RESTORE_POST_DATA;
|
||||
return PROXERR;
|
||||
}
|
||||
if (proxy_url->scheme != SCHEME_HTTP && proxy_url->scheme != u->scheme)
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("Error in proxy URL %s: Must be HTTP.\n"), proxy);
|
||||
url_free (proxy_url);
|
||||
xfree (url);
|
||||
RESTORE_POST_DATA;
|
||||
return PROXERR;
|
||||
}
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("Error in proxy URL %s: Must be HTTP.\n"), proxy);
|
||||
url_free (proxy_url);
|
||||
xfree (url);
|
||||
RESTORE_POST_DATA;
|
||||
return PROXERR;
|
||||
}
|
||||
}
|
||||
|
||||
if (u->scheme == SCHEME_HTTP
|
||||
@ -675,24 +675,24 @@ retrieve_url (const char *origurl, char **file, char **newloc,
|
||||
else if (u->scheme == SCHEME_FTP)
|
||||
{
|
||||
/* If this is a redirection, temporarily turn off opt.ftp_glob
|
||||
and opt.recursive, both being undesirable when following
|
||||
redirects. */
|
||||
and opt.recursive, both being undesirable when following
|
||||
redirects. */
|
||||
bool oldrec = recursive, glob = opt.ftp_glob;
|
||||
if (redirection_count)
|
||||
oldrec = glob = false;
|
||||
oldrec = glob = false;
|
||||
|
||||
result = ftp_loop (u, dt, proxy_url, recursive, glob);
|
||||
recursive = oldrec;
|
||||
|
||||
/* There is a possibility of having HTTP being redirected to
|
||||
FTP. In these cases we must decide whether the text is HTML
|
||||
according to the suffix. The HTML suffixes are `.html',
|
||||
`.htm' and a few others, case-insensitive. */
|
||||
FTP. In these cases we must decide whether the text is HTML
|
||||
according to the suffix. The HTML suffixes are `.html',
|
||||
`.htm' and a few others, case-insensitive. */
|
||||
if (redirection_count && local_file && u->scheme == SCHEME_FTP)
|
||||
{
|
||||
if (has_html_suffix_p (local_file))
|
||||
*dt |= TEXTHTML;
|
||||
}
|
||||
{
|
||||
if (has_html_suffix_p (local_file))
|
||||
*dt |= TEXTHTML;
|
||||
}
|
||||
}
|
||||
|
||||
if (proxy_url)
|
||||
@ -710,12 +710,12 @@ retrieve_url (const char *origurl, char **file, char **newloc,
|
||||
assert (mynewloc != NULL);
|
||||
|
||||
if (local_file)
|
||||
xfree (local_file);
|
||||
xfree (local_file);
|
||||
|
||||
/* The HTTP specs only allow absolute URLs to appear in
|
||||
redirects, but a ton of boneheaded webservers and CGIs out
|
||||
there break the rules and use relative URLs, and popular
|
||||
browsers are lenient about this, so wget should be too. */
|
||||
redirects, but a ton of boneheaded webservers and CGIs out
|
||||
there break the rules and use relative URLs, and popular
|
||||
browsers are lenient about this, so wget should be too. */
|
||||
construced_newloc = uri_merge (url, mynewloc);
|
||||
xfree (mynewloc);
|
||||
mynewloc = construced_newloc;
|
||||
@ -723,15 +723,15 @@ retrieve_url (const char *origurl, char **file, char **newloc,
|
||||
/* Now, see if this new location makes sense. */
|
||||
newloc_parsed = url_parse (mynewloc, &up_error_code);
|
||||
if (!newloc_parsed)
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, "%s: %s.\n", escnonprint_uri (mynewloc),
|
||||
url_error (up_error_code));
|
||||
url_free (u);
|
||||
xfree (url);
|
||||
xfree (mynewloc);
|
||||
RESTORE_POST_DATA;
|
||||
return result;
|
||||
}
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, "%s: %s.\n", escnonprint_uri (mynewloc),
|
||||
url_error (up_error_code));
|
||||
url_free (u);
|
||||
xfree (url);
|
||||
xfree (mynewloc);
|
||||
RESTORE_POST_DATA;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Now mynewloc will become newloc_parsed->url, because if the
|
||||
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. */
|
||||
if (++redirection_count > opt.max_redirect)
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("%d redirections exceeded.\n"),
|
||||
opt.max_redirect);
|
||||
url_free (newloc_parsed);
|
||||
url_free (u);
|
||||
xfree (url);
|
||||
xfree (mynewloc);
|
||||
RESTORE_POST_DATA;
|
||||
return WRONGCODE;
|
||||
}
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("%d redirections exceeded.\n"),
|
||||
opt.max_redirect);
|
||||
url_free (newloc_parsed);
|
||||
url_free (u);
|
||||
xfree (url);
|
||||
xfree (mynewloc);
|
||||
RESTORE_POST_DATA;
|
||||
return WRONGCODE;
|
||||
}
|
||||
|
||||
xfree (url);
|
||||
url = mynewloc;
|
||||
@ -758,12 +758,12 @@ retrieve_url (const char *origurl, char **file, char **newloc,
|
||||
u = newloc_parsed;
|
||||
|
||||
/* If we're being redirected from POST, we don't want to POST
|
||||
again. Many requests answer POST with a redirection to an
|
||||
index page; that redirection is clearly a GET. We "suspend"
|
||||
POST data for the duration of the redirections, and restore
|
||||
it when we're done. */
|
||||
again. Many requests answer POST with a redirection to an
|
||||
index page; that redirection is clearly a GET. We "suspend"
|
||||
POST data for the duration of the redirections, and restore
|
||||
it when we're done. */
|
||||
if (!post_data_suspended)
|
||||
SUSPEND_POST_DATA;
|
||||
SUSPEND_POST_DATA;
|
||||
|
||||
goto redirected;
|
||||
}
|
||||
@ -771,13 +771,13 @@ retrieve_url (const char *origurl, char **file, char **newloc,
|
||||
if (local_file)
|
||||
{
|
||||
if (*dt & RETROKF)
|
||||
{
|
||||
register_download (u->url, local_file);
|
||||
if (redirection_count && 0 != strcmp (origurl, u->url))
|
||||
register_redirection (origurl, u->url);
|
||||
if (*dt & TEXTHTML)
|
||||
register_html (u->url, local_file);
|
||||
}
|
||||
{
|
||||
register_download (u->url, local_file);
|
||||
if (redirection_count && 0 != strcmp (origurl, u->url))
|
||||
register_redirection (origurl, u->url);
|
||||
if (*dt & TEXTHTML)
|
||||
register_html (u->url, local_file);
|
||||
}
|
||||
}
|
||||
|
||||
if (file)
|
||||
@ -790,14 +790,14 @@ retrieve_url (const char *origurl, char **file, char **newloc,
|
||||
if (redirection_count)
|
||||
{
|
||||
if (newloc)
|
||||
*newloc = url;
|
||||
*newloc = url;
|
||||
else
|
||||
xfree (url);
|
||||
xfree (url);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (newloc)
|
||||
*newloc = NULL;
|
||||
*newloc = NULL;
|
||||
xfree (url);
|
||||
}
|
||||
|
||||
@ -819,7 +819,7 @@ retrieve_from_file (const char *file, bool html, int *count)
|
||||
struct urlpos *url_list, *cur_url;
|
||||
|
||||
url_list = (html ? get_urls_html (file, NULL, NULL)
|
||||
: get_urls_file (file));
|
||||
: get_urls_file (file));
|
||||
status = RETROK; /* Suppose everything is OK. */
|
||||
*count = 0; /* Reset the URL count. */
|
||||
|
||||
@ -829,38 +829,38 @@ retrieve_from_file (const char *file, bool html, int *count)
|
||||
int dt;
|
||||
|
||||
if (cur_url->ignore_when_downloading)
|
||||
continue;
|
||||
continue;
|
||||
|
||||
if (opt.quota && total_downloaded_bytes > opt.quota)
|
||||
{
|
||||
status = QUOTEXC;
|
||||
break;
|
||||
}
|
||||
{
|
||||
status = QUOTEXC;
|
||||
break;
|
||||
}
|
||||
if ((opt.recursive || opt.page_requisites)
|
||||
&& (cur_url->url->scheme != SCHEME_FTP || getproxy (cur_url->url)))
|
||||
{
|
||||
int old_follow_ftp = opt.follow_ftp;
|
||||
&& (cur_url->url->scheme != SCHEME_FTP || getproxy (cur_url->url)))
|
||||
{
|
||||
int old_follow_ftp = opt.follow_ftp;
|
||||
|
||||
/* Turn opt.follow_ftp on in case of recursive FTP retrieval */
|
||||
if (cur_url->url->scheme == SCHEME_FTP)
|
||||
opt.follow_ftp = 1;
|
||||
|
||||
status = retrieve_tree (cur_url->url->url);
|
||||
/* Turn opt.follow_ftp on in case of recursive FTP retrieval */
|
||||
if (cur_url->url->scheme == SCHEME_FTP)
|
||||
opt.follow_ftp = 1;
|
||||
|
||||
status = retrieve_tree (cur_url->url->url);
|
||||
|
||||
opt.follow_ftp = old_follow_ftp;
|
||||
}
|
||||
opt.follow_ftp = old_follow_ftp;
|
||||
}
|
||||
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))
|
||||
{
|
||||
DEBUGP (("\
|
||||
{
|
||||
DEBUGP (("\
|
||||
Removing file due to --delete-after in retrieve_from_file():\n"));
|
||||
logprintf (LOG_VERBOSE, _("Removing %s.\n"), filename);
|
||||
if (unlink (filename))
|
||||
logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
|
||||
dt &= ~RETROKF;
|
||||
}
|
||||
logprintf (LOG_VERBOSE, _("Removing %s.\n"), filename);
|
||||
if (unlink (filename))
|
||||
logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
|
||||
dt &= ~RETROKF;
|
||||
}
|
||||
|
||||
xfree_null (new_file);
|
||||
xfree_null (filename);
|
||||
@ -901,29 +901,29 @@ sleep_between_retrievals (int count)
|
||||
if (opt.waitretry && count > 1)
|
||||
{
|
||||
/* 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)
|
||||
xsleep (count - 1);
|
||||
xsleep (count - 1);
|
||||
else
|
||||
xsleep (opt.waitretry);
|
||||
xsleep (opt.waitretry);
|
||||
}
|
||||
else if (opt.wait)
|
||||
{
|
||||
if (!opt.random_wait || count > 1)
|
||||
/* If random-wait is not specified, or if we are sleeping
|
||||
between retries of the same download, sleep the fixed
|
||||
interval. */
|
||||
xsleep (opt.wait);
|
||||
/* If random-wait is not specified, or if we are sleeping
|
||||
between retries of the same download, sleep the fixed
|
||||
interval. */
|
||||
xsleep (opt.wait);
|
||||
else
|
||||
{
|
||||
/* Sleep a random amount of time averaging in opt.wait
|
||||
seconds. The sleeping amount ranges from 0.5*opt.wait to
|
||||
1.5*opt.wait. */
|
||||
double waitsecs = (0.5 + random_float ()) * opt.wait;
|
||||
DEBUGP (("sleep_between_retrievals: avg=%f,sleep=%f\n",
|
||||
opt.wait, waitsecs));
|
||||
xsleep (waitsecs);
|
||||
}
|
||||
{
|
||||
/* Sleep a random amount of time averaging in opt.wait
|
||||
seconds. The sleeping amount ranges from 0.5*opt.wait to
|
||||
1.5*opt.wait. */
|
||||
double waitsecs = (0.5 + random_float ()) * opt.wait;
|
||||
DEBUGP (("sleep_between_retrievals: avg=%f,sleep=%f\n",
|
||||
opt.wait, waitsecs));
|
||||
xsleep (waitsecs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -935,7 +935,7 @@ free_urlpos (struct urlpos *l)
|
||||
{
|
||||
struct urlpos *next = l->next;
|
||||
if (l->url)
|
||||
url_free (l->url);
|
||||
url_free (l->url);
|
||||
xfree_null (l->local_name);
|
||||
xfree (l);
|
||||
l = next;
|
||||
|
@ -56,20 +56,20 @@ so, delete this exception statement from your version. */
|
||||
#define xd _sch_isxdigit
|
||||
|
||||
/* Masks. */
|
||||
#define L lo|is |pr /* lower case letter */
|
||||
#define XL lo|is|xd|pr /* lowercase hex digit */
|
||||
#define U up|is |pr /* upper case letter */
|
||||
#define XU up|is|xd|pr /* uppercase hex digit */
|
||||
#define D di |xd|pr /* decimal digit */
|
||||
#define P pn |pr /* punctuation */
|
||||
#define _ pn|is |pr /* underscore */
|
||||
#define L lo|is |pr /* lower case letter */
|
||||
#define XL lo|is|xd|pr /* lowercase hex digit */
|
||||
#define U up|is |pr /* upper case letter */
|
||||
#define XU up|is|xd|pr /* uppercase hex digit */
|
||||
#define D di |xd|pr /* decimal digit */
|
||||
#define P pn |pr /* punctuation */
|
||||
#define _ pn|is |pr /* underscore */
|
||||
|
||||
#define C cn /* control character */
|
||||
#define Z nv |cn /* NUL */
|
||||
#define M nv|sp |cn /* cursor movement: \f \v */
|
||||
#define V vs|sp |cn /* vertical space: \r \n */
|
||||
#define T nv|sp|bl|cn /* tab */
|
||||
#define S nv|sp|bl|pr /* space */
|
||||
#define C cn /* control character */
|
||||
#define Z nv |cn /* NUL */
|
||||
#define M nv|sp |cn /* cursor movement: \f \v */
|
||||
#define V vs|sp |cn /* vertical space: \r \n */
|
||||
#define T nv|sp|bl|cn /* tab */
|
||||
#define S nv|sp|bl|pr /* space */
|
||||
|
||||
/* Are we ASCII? */
|
||||
#if '\n' == 0x0A && ' ' == 0x20 && '0' == 0x30 \
|
||||
|
432
src/snprintf.c
432
src/snprintf.c
@ -106,7 +106,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h> /* for NULL */
|
||||
#include <stdio.h> /* for NULL */
|
||||
|
||||
#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);
|
||||
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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);
|
||||
|
||||
/*
|
||||
@ -158,14 +158,14 @@ static int dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c);
|
||||
#define DP_S_DONE 8
|
||||
|
||||
/* format flags - Bits */
|
||||
#define DP_F_MINUS (1 << 0)
|
||||
#define DP_F_PLUS (1 << 1)
|
||||
#define DP_F_SPACE (1 << 2)
|
||||
#define DP_F_NUM (1 << 3)
|
||||
#define DP_F_ZERO (1 << 4)
|
||||
#define DP_F_UP (1 << 5)
|
||||
#define DP_F_UNSIGNED (1 << 6)
|
||||
#define DP_F_FP_G (1 << 7)
|
||||
#define DP_F_MINUS (1 << 0)
|
||||
#define DP_F_PLUS (1 << 1)
|
||||
#define DP_F_SPACE (1 << 2)
|
||||
#define DP_F_NUM (1 << 3)
|
||||
#define DP_F_ZERO (1 << 4)
|
||||
#define DP_F_UP (1 << 5)
|
||||
#define DP_F_UNSIGNED (1 << 6)
|
||||
#define DP_F_FP_G (1 << 7)
|
||||
|
||||
/* Conversion Flags */
|
||||
#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:
|
||||
if (ch == '%')
|
||||
state = DP_S_FLAGS;
|
||||
state = DP_S_FLAGS;
|
||||
else
|
||||
total += dopr_outch (buffer, &currlen, maxlen, ch);
|
||||
total += dopr_outch (buffer, &currlen, maxlen, ch);
|
||||
ch = *format++;
|
||||
break;
|
||||
case DP_S_FLAGS:
|
||||
switch (ch)
|
||||
{
|
||||
case '-':
|
||||
flags |= DP_F_MINUS;
|
||||
flags |= DP_F_MINUS;
|
||||
ch = *format++;
|
||||
break;
|
||||
break;
|
||||
case '+':
|
||||
flags |= DP_F_PLUS;
|
||||
flags |= DP_F_PLUS;
|
||||
ch = *format++;
|
||||
break;
|
||||
break;
|
||||
case ' ':
|
||||
flags |= DP_F_SPACE;
|
||||
flags |= DP_F_SPACE;
|
||||
ch = *format++;
|
||||
break;
|
||||
break;
|
||||
case '#':
|
||||
flags |= DP_F_NUM;
|
||||
flags |= DP_F_NUM;
|
||||
ch = *format++;
|
||||
break;
|
||||
break;
|
||||
case '0':
|
||||
flags |= DP_F_ZERO;
|
||||
flags |= DP_F_ZERO;
|
||||
ch = *format++;
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
state = DP_S_MIN;
|
||||
break;
|
||||
state = DP_S_MIN;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case DP_S_MIN:
|
||||
if ('0' <= ch && ch <= '9')
|
||||
{
|
||||
min = 10*min + char_to_int (ch);
|
||||
ch = *format++;
|
||||
min = 10*min + char_to_int (ch);
|
||||
ch = *format++;
|
||||
}
|
||||
else if (ch == '*')
|
||||
{
|
||||
min = va_arg (args, int);
|
||||
ch = *format++;
|
||||
state = DP_S_DOT;
|
||||
min = va_arg (args, int);
|
||||
ch = *format++;
|
||||
state = DP_S_DOT;
|
||||
}
|
||||
else
|
||||
state = DP_S_DOT;
|
||||
state = DP_S_DOT;
|
||||
break;
|
||||
case DP_S_DOT:
|
||||
if (ch == '.')
|
||||
{
|
||||
state = DP_S_MAX;
|
||||
ch = *format++;
|
||||
state = DP_S_MAX;
|
||||
ch = *format++;
|
||||
}
|
||||
else
|
||||
state = DP_S_MOD;
|
||||
state = DP_S_MOD;
|
||||
break;
|
||||
case DP_S_MAX:
|
||||
if ('0' <= ch && ch <= '9')
|
||||
{
|
||||
if (max < 0)
|
||||
max = 0;
|
||||
max = 10*max + char_to_int (ch);
|
||||
ch = *format++;
|
||||
if (max < 0)
|
||||
max = 0;
|
||||
max = 10*max + char_to_int (ch);
|
||||
ch = *format++;
|
||||
}
|
||||
else if (ch == '*')
|
||||
{
|
||||
max = va_arg (args, int);
|
||||
ch = *format++;
|
||||
state = DP_S_MOD;
|
||||
max = va_arg (args, int);
|
||||
ch = *format++;
|
||||
state = DP_S_MOD;
|
||||
}
|
||||
else
|
||||
state = DP_S_MOD;
|
||||
state = DP_S_MOD;
|
||||
break;
|
||||
case DP_S_MOD:
|
||||
switch (ch)
|
||||
{
|
||||
case 'h':
|
||||
cflags = DP_C_SHORT;
|
||||
ch = *format++;
|
||||
break;
|
||||
cflags = DP_C_SHORT;
|
||||
ch = *format++;
|
||||
break;
|
||||
case 'l':
|
||||
cflags = DP_C_LONG;
|
||||
ch = *format++;
|
||||
break;
|
||||
cflags = DP_C_LONG;
|
||||
ch = *format++;
|
||||
break;
|
||||
case 'L':
|
||||
cflags = DP_C_LDOUBLE;
|
||||
ch = *format++;
|
||||
break;
|
||||
cflags = DP_C_LDOUBLE;
|
||||
ch = *format++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
break;
|
||||
}
|
||||
if (cflags != DP_C_LONG)
|
||||
state = DP_S_CONV;
|
||||
state = DP_S_CONV;
|
||||
else
|
||||
state = DP_S_MOD_L;
|
||||
state = DP_S_MOD_L;
|
||||
break;
|
||||
case DP_S_MOD_L:
|
||||
switch (ch)
|
||||
{
|
||||
case 'l':
|
||||
cflags = DP_C_LLONG;
|
||||
ch = *format++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
{
|
||||
case 'l':
|
||||
cflags = DP_C_LLONG;
|
||||
ch = *format++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
state = DP_S_CONV;
|
||||
break;
|
||||
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 'i':
|
||||
if (cflags == DP_C_SHORT)
|
||||
value = (short int) va_arg (args, int);
|
||||
else if (cflags == DP_C_LONG)
|
||||
value = va_arg (args, long int);
|
||||
else if (cflags == DP_C_LLONG)
|
||||
value = va_arg (args, LLONG);
|
||||
else
|
||||
value = va_arg (args, int);
|
||||
total += fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
|
||||
break;
|
||||
if (cflags == DP_C_SHORT)
|
||||
value = (short int) va_arg (args, int);
|
||||
else if (cflags == DP_C_LONG)
|
||||
value = va_arg (args, long int);
|
||||
else if (cflags == DP_C_LLONG)
|
||||
value = va_arg (args, LLONG);
|
||||
else
|
||||
value = va_arg (args, int);
|
||||
total += fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
|
||||
break;
|
||||
case 'o':
|
||||
flags |= DP_F_UNSIGNED;
|
||||
if (cflags == DP_C_SHORT)
|
||||
value = (unsigned short int) va_arg (args, unsigned int);
|
||||
else if (cflags == DP_C_LONG)
|
||||
value = va_arg (args, unsigned long int);
|
||||
else if (cflags == DP_C_LLONG)
|
||||
value = va_arg (args, unsigned LLONG);
|
||||
else
|
||||
value = va_arg (args, unsigned int);
|
||||
total += fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
|
||||
break;
|
||||
flags |= DP_F_UNSIGNED;
|
||||
if (cflags == DP_C_SHORT)
|
||||
value = (unsigned short int) va_arg (args, unsigned int);
|
||||
else if (cflags == DP_C_LONG)
|
||||
value = va_arg (args, unsigned long int);
|
||||
else if (cflags == DP_C_LLONG)
|
||||
value = va_arg (args, unsigned LLONG);
|
||||
else
|
||||
value = va_arg (args, unsigned int);
|
||||
total += fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
|
||||
break;
|
||||
case 'u':
|
||||
flags |= DP_F_UNSIGNED;
|
||||
if (cflags == DP_C_SHORT)
|
||||
value = (unsigned short int) va_arg (args, unsigned int);
|
||||
else if (cflags == DP_C_LONG)
|
||||
value = va_arg (args, unsigned long int);
|
||||
else if (cflags == DP_C_LLONG)
|
||||
value = va_arg (args, unsigned LLONG);
|
||||
else
|
||||
value = va_arg (args, unsigned int);
|
||||
total += fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
|
||||
break;
|
||||
flags |= DP_F_UNSIGNED;
|
||||
if (cflags == DP_C_SHORT)
|
||||
value = (unsigned short int) va_arg (args, unsigned int);
|
||||
else if (cflags == DP_C_LONG)
|
||||
value = va_arg (args, unsigned long int);
|
||||
else if (cflags == DP_C_LLONG)
|
||||
value = va_arg (args, unsigned LLONG);
|
||||
else
|
||||
value = va_arg (args, unsigned int);
|
||||
total += fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
|
||||
break;
|
||||
case 'X':
|
||||
flags |= DP_F_UP;
|
||||
flags |= DP_F_UP;
|
||||
case 'x':
|
||||
flags |= DP_F_UNSIGNED;
|
||||
if (cflags == DP_C_SHORT)
|
||||
value = (unsigned short int) va_arg (args, unsigned int);
|
||||
else if (cflags == DP_C_LONG)
|
||||
value = va_arg (args, unsigned long int);
|
||||
else if (cflags == DP_C_LLONG)
|
||||
value = va_arg (args, unsigned LLONG);
|
||||
else
|
||||
value = va_arg (args, unsigned int);
|
||||
total += fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
|
||||
break;
|
||||
flags |= DP_F_UNSIGNED;
|
||||
if (cflags == DP_C_SHORT)
|
||||
value = (unsigned short int) va_arg (args, unsigned int);
|
||||
else if (cflags == DP_C_LONG)
|
||||
value = va_arg (args, unsigned long int);
|
||||
else if (cflags == DP_C_LLONG)
|
||||
value = va_arg (args, unsigned LLONG);
|
||||
else
|
||||
value = va_arg (args, unsigned int);
|
||||
total += fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
|
||||
break;
|
||||
case 'f':
|
||||
if (cflags == DP_C_LDOUBLE)
|
||||
fvalue = va_arg (args, LDOUBLE);
|
||||
else
|
||||
fvalue = va_arg (args, double);
|
||||
total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
|
||||
break;
|
||||
if (cflags == DP_C_LDOUBLE)
|
||||
fvalue = va_arg (args, LDOUBLE);
|
||||
else
|
||||
fvalue = va_arg (args, double);
|
||||
total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
|
||||
break;
|
||||
case 'E':
|
||||
flags |= DP_F_UP;
|
||||
flags |= DP_F_UP;
|
||||
case 'e':
|
||||
if (cflags == DP_C_LDOUBLE)
|
||||
fvalue = va_arg (args, LDOUBLE);
|
||||
else
|
||||
fvalue = va_arg (args, double);
|
||||
total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
|
||||
break;
|
||||
if (cflags == DP_C_LDOUBLE)
|
||||
fvalue = va_arg (args, LDOUBLE);
|
||||
else
|
||||
fvalue = va_arg (args, double);
|
||||
total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
|
||||
break;
|
||||
case 'G':
|
||||
flags |= DP_F_UP;
|
||||
flags |= DP_F_UP;
|
||||
case 'g':
|
||||
flags |= DP_F_FP_G;
|
||||
if (cflags == DP_C_LDOUBLE)
|
||||
fvalue = va_arg (args, LDOUBLE);
|
||||
else
|
||||
fvalue = va_arg (args, double);
|
||||
if (max == 0)
|
||||
/* C99 says: if precision [for %g] is zero, it is taken as one */
|
||||
max = 1;
|
||||
total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
|
||||
break;
|
||||
flags |= DP_F_FP_G;
|
||||
if (cflags == DP_C_LDOUBLE)
|
||||
fvalue = va_arg (args, LDOUBLE);
|
||||
else
|
||||
fvalue = va_arg (args, double);
|
||||
if (max == 0)
|
||||
/* C99 says: if precision [for %g] is zero, it is taken as one */
|
||||
max = 1;
|
||||
total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
|
||||
break;
|
||||
case 'c':
|
||||
total += dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
|
||||
break;
|
||||
total += dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
|
||||
break;
|
||||
case 's':
|
||||
strvalue = va_arg (args, char *);
|
||||
total += fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
|
||||
break;
|
||||
strvalue = va_arg (args, char *);
|
||||
total += fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
|
||||
break;
|
||||
case 'p':
|
||||
strvalue = va_arg (args, void *);
|
||||
total += fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min,
|
||||
strvalue = va_arg (args, void *);
|
||||
total += fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min,
|
||||
max, flags);
|
||||
break;
|
||||
break;
|
||||
case 'n':
|
||||
if (cflags == DP_C_SHORT)
|
||||
{
|
||||
short int *num;
|
||||
num = va_arg (args, short int *);
|
||||
*num = currlen;
|
||||
if (cflags == DP_C_SHORT)
|
||||
{
|
||||
short int *num;
|
||||
num = va_arg (args, short int *);
|
||||
*num = currlen;
|
||||
}
|
||||
else if (cflags == DP_C_LONG)
|
||||
{
|
||||
long int *num;
|
||||
num = va_arg (args, long int *);
|
||||
*num = currlen;
|
||||
else if (cflags == DP_C_LONG)
|
||||
{
|
||||
long int *num;
|
||||
num = va_arg (args, long int *);
|
||||
*num = currlen;
|
||||
}
|
||||
else if (cflags == DP_C_LLONG)
|
||||
{
|
||||
LLONG *num;
|
||||
num = va_arg (args, LLONG *);
|
||||
*num = currlen;
|
||||
else if (cflags == DP_C_LLONG)
|
||||
{
|
||||
LLONG *num;
|
||||
num = va_arg (args, LLONG *);
|
||||
*num = currlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
int *num;
|
||||
num = va_arg (args, int *);
|
||||
*num = currlen;
|
||||
else
|
||||
{
|
||||
int *num;
|
||||
num = va_arg (args, int *);
|
||||
*num = currlen;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case '%':
|
||||
total += dopr_outch (buffer, &currlen, maxlen, ch);
|
||||
break;
|
||||
total += dopr_outch (buffer, &currlen, maxlen, ch);
|
||||
break;
|
||||
case 'w':
|
||||
/* not supported yet, treat as next char */
|
||||
ch = *format++;
|
||||
break;
|
||||
/* not supported yet, treat as next char */
|
||||
ch = *format++;
|
||||
break;
|
||||
default:
|
||||
/* Unknown, skip */
|
||||
break;
|
||||
/* Unknown, skip */
|
||||
break;
|
||||
}
|
||||
ch = *format++;
|
||||
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,
|
||||
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 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) */
|
||||
|
||||
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;
|
||||
unsigned LLONG uvalue;
|
||||
@ -538,10 +538,10 @@ static int fmtint (char *buffer, size_t *currlen, size_t maxlen,
|
||||
}
|
||||
else
|
||||
if (flags & DP_F_PLUS) /* Do a sign (+/i) */
|
||||
signvalue = '+';
|
||||
signvalue = '+';
|
||||
else
|
||||
if (flags & DP_F_SPACE)
|
||||
signvalue = ' ';
|
||||
signvalue = ' ';
|
||||
}
|
||||
|
||||
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,
|
||||
LDOUBLE fvalue, int min, int max, int flags)
|
||||
LDOUBLE fvalue, int min, int max, int flags)
|
||||
{
|
||||
int signvalue = 0;
|
||||
LDOUBLE ufvalue;
|
||||
@ -678,7 +678,7 @@ static int fmtfp (char *buffer, size_t *currlen, size_t maxlen,
|
||||
signvalue = '+';
|
||||
else
|
||||
if (flags & DP_F_SPACE)
|
||||
signvalue = ' ';
|
||||
signvalue = ' ';
|
||||
|
||||
#if 0
|
||||
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 (intpart != 0)
|
||||
{
|
||||
/* For each digit of INTPART, print one less fractional digit. */
|
||||
LLONG temp = intpart;
|
||||
for (temp = intpart; temp != 0; temp /= 10)
|
||||
--max;
|
||||
if (max < 0)
|
||||
max = 0;
|
||||
}
|
||||
{
|
||||
/* For each digit of INTPART, print one less fractional digit. */
|
||||
LLONG temp = intpart;
|
||||
for (temp = intpart; temp != 0; temp /= 10)
|
||||
--max;
|
||||
if (max < 0)
|
||||
max = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* For each leading 0 in fractional part, print one more
|
||||
fractional digit. */
|
||||
LDOUBLE temp;
|
||||
if (ufvalue != 0)
|
||||
for (temp = ufvalue; temp < 0.1; temp *= 10)
|
||||
++max;
|
||||
}
|
||||
{
|
||||
/* For each leading 0 in fractional part, print one more
|
||||
fractional digit. */
|
||||
LDOUBLE temp;
|
||||
if (ufvalue != 0)
|
||||
for (temp = ufvalue; temp < 0.1; temp *= 10)
|
||||
++max;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
#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
|
||||
# define MAX_DIGITS 9 /* just long */
|
||||
# define MAX_DIGITS 9 /* just long */
|
||||
#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. */
|
||||
while (fracpart < mask10 / 10)
|
||||
{
|
||||
++leadingfrac0s;
|
||||
mask10 /= 10;
|
||||
++leadingfrac0s;
|
||||
mask10 /= 10;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SNPRINTF
|
||||
@ -915,8 +915,8 @@ int main (void)
|
||||
NULL
|
||||
};
|
||||
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};
|
||||
0.9996, 1.996, 4.136, 0.00205, 0.0001, 321.000009,
|
||||
0};
|
||||
char *int_fmt[] = {
|
||||
"%-1.5d",
|
||||
"%1.5d",
|
||||
@ -932,20 +932,20 @@ int main (void)
|
||||
long int_nums[] = { -1, 134, 91340, 341, 0203, 0};
|
||||
#if SIZEOF_LONG_LONG != 0
|
||||
char *llong_fmt[] = {
|
||||
"%lld", "%llu",
|
||||
"%-1.5lld", "%-1.5llu",
|
||||
"%1.5lld", "%1.5llu",
|
||||
"%123.9lld", "%123.9llu",
|
||||
"%5.5lld", "%5.5llu",
|
||||
"%10.5lld", "%10.5llu",
|
||||
"% 10.5lld", "% 10.5llu",
|
||||
"%+22.33lld", "%+22.33llu",
|
||||
"%01.3lld", "%01.3llu",
|
||||
"%4lld", "%4llu",
|
||||
"%lld", "%llu",
|
||||
"%-1.5lld", "%-1.5llu",
|
||||
"%1.5lld", "%1.5llu",
|
||||
"%123.9lld", "%123.9llu",
|
||||
"%5.5lld", "%5.5llu",
|
||||
"%10.5lld", "%10.5llu",
|
||||
"% 10.5lld", "% 10.5llu",
|
||||
"%+22.33lld", "%+22.33llu",
|
||||
"%01.3lld", "%01.3llu",
|
||||
"%4lld", "%4llu",
|
||||
NULL
|
||||
};
|
||||
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 */
|
||||
/* random... */
|
||||
-150, 134, 91340, 341,
|
||||
@ -965,9 +965,9 @@ int main (void)
|
||||
sprintf (buf2, fp_fmt[x], fp_nums[y]);
|
||||
if (strcmp (buf1, buf2))
|
||||
{
|
||||
printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
|
||||
fp_fmt[x], buf1, buf2);
|
||||
fail++;
|
||||
printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
|
||||
fp_fmt[x], buf1, buf2);
|
||||
fail++;
|
||||
}
|
||||
num++;
|
||||
}
|
||||
@ -979,9 +979,9 @@ int main (void)
|
||||
sprintf (buf2, int_fmt[x], int_nums[y]);
|
||||
if (strcmp (buf1, buf2))
|
||||
{
|
||||
printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
|
||||
int_fmt[x], buf1, buf2);
|
||||
fail++;
|
||||
printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
|
||||
int_fmt[x], buf1, buf2);
|
||||
fail++;
|
||||
}
|
||||
num++;
|
||||
}
|
||||
@ -994,9 +994,9 @@ int main (void)
|
||||
sprintf (buf2, llong_fmt[x], llong_nums[y]);
|
||||
if (strcmp (buf1, buf2))
|
||||
{
|
||||
printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
|
||||
llong_fmt[x], buf1, buf2);
|
||||
fail++;
|
||||
printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
|
||||
llong_fmt[x], buf1, buf2);
|
||||
fail++;
|
||||
}
|
||||
num++;
|
||||
}
|
||||
|
390
src/utils.c
390
src/utils.c
@ -125,18 +125,18 @@ sepstring (const char *s)
|
||||
while (*s)
|
||||
{
|
||||
if (*s == ',')
|
||||
{
|
||||
res = xrealloc (res, (i + 2) * sizeof (char *));
|
||||
res[i] = strdupdelim (p, s);
|
||||
res[++i] = NULL;
|
||||
++s;
|
||||
/* Skip the blanks following the ','. */
|
||||
while (ISSPACE (*s))
|
||||
++s;
|
||||
p = s;
|
||||
}
|
||||
{
|
||||
res = xrealloc (res, (i + 2) * sizeof (char *));
|
||||
res[i] = strdupdelim (p, s);
|
||||
res[++i] = NULL;
|
||||
++s;
|
||||
/* Skip the blanks following the ','. */
|
||||
while (ISSPACE (*s))
|
||||
++s;
|
||||
p = s;
|
||||
}
|
||||
else
|
||||
++s;
|
||||
++s;
|
||||
}
|
||||
res = xrealloc (res, (i + 2) * sizeof (char *));
|
||||
res[i] = strdupdelim (p, s);
|
||||
@ -167,7 +167,7 @@ aprintf (const char *fmt, ...)
|
||||
ret = vasprintf (&str, fmt, args);
|
||||
va_end (args);
|
||||
if (ret < 0 && errno == ENOMEM)
|
||||
abort (); /* for consistency with xmalloc/xrealloc */
|
||||
abort (); /* for consistency with xmalloc/xrealloc */
|
||||
else if (ret < 0)
|
||||
return NULL;
|
||||
return str;
|
||||
@ -192,13 +192,13 @@ aprintf (const char *fmt, ...)
|
||||
|
||||
/* If the printing worked, return the string. */
|
||||
if (n > -1 && n < size)
|
||||
return str;
|
||||
return str;
|
||||
|
||||
/* Else try again with a larger buffer. */
|
||||
if (n > -1) /* C99 */
|
||||
size = n + 1; /* precisely what is needed */
|
||||
if (n > -1) /* C99 */
|
||||
size = n + 1; /* precisely what is needed */
|
||||
else
|
||||
size <<= 1; /* twice the old size */
|
||||
size <<= 1; /* twice the old size */
|
||||
str = xrealloc (str, size);
|
||||
}
|
||||
#endif /* not HAVE_VASPRINTF */
|
||||
@ -211,7 +211,7 @@ char *
|
||||
concat_strings (const char *str0, ...)
|
||||
{
|
||||
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;
|
||||
|
||||
const char *next_str;
|
||||
@ -226,7 +226,7 @@ concat_strings (const char *str0, ...)
|
||||
{
|
||||
int len = strlen (next_str);
|
||||
if (argcount < countof (saved_lengths))
|
||||
saved_lengths[argcount++] = len;
|
||||
saved_lengths[argcount++] = len;
|
||||
total_length += len;
|
||||
}
|
||||
va_end (args);
|
||||
@ -240,9 +240,9 @@ concat_strings (const char *str0, ...)
|
||||
{
|
||||
int len;
|
||||
if (argcount < countof (saved_lengths))
|
||||
len = saved_lengths[argcount++];
|
||||
len = saved_lengths[argcount++];
|
||||
else
|
||||
len = strlen (next_str);
|
||||
len = strlen (next_str);
|
||||
memcpy (p, next_str, len);
|
||||
p += len;
|
||||
}
|
||||
@ -300,16 +300,16 @@ fork_to_background (void)
|
||||
if (!opt.lfilename)
|
||||
{
|
||||
/* We must create the file immediately to avoid either a race
|
||||
condition (which arises from using unique_name and failing to
|
||||
use fopen_excl) or lying to the user about the log file name
|
||||
(which arises from using unique_name, printing the name, and
|
||||
using fopen_excl later on.) */
|
||||
condition (which arises from using unique_name and failing to
|
||||
use fopen_excl) or lying to the user about the log file name
|
||||
(which arises from using unique_name, printing the name, and
|
||||
using fopen_excl later on.) */
|
||||
FILE *new_log_fp = unique_create (DEFAULT_LOGFILE, false, &opt.lfilename);
|
||||
if (new_log_fp)
|
||||
{
|
||||
logfile_changed = true;
|
||||
fclose (new_log_fp);
|
||||
}
|
||||
{
|
||||
logfile_changed = true;
|
||||
fclose (new_log_fp);
|
||||
}
|
||||
}
|
||||
pid = fork ();
|
||||
if (pid < 0)
|
||||
@ -323,8 +323,8 @@ fork_to_background (void)
|
||||
/* parent, no error */
|
||||
printf (_("Continuing in background, pid %d.\n"), (int) pid);
|
||||
if (logfile_changed)
|
||||
printf (_("Output will be written to `%s'.\n"), opt.lfilename);
|
||||
exit (0); /* #### should we use _exit()? */
|
||||
printf (_("Output will be written to `%s'.\n"), opt.lfilename);
|
||||
exit (0); /* #### should we use _exit()? */
|
||||
}
|
||||
|
||||
/* child: give up the privileges and keep running. */
|
||||
@ -369,8 +369,8 @@ remove_link (const char *file)
|
||||
DEBUGP (("Unlinking %s (symlink).\n", file));
|
||||
err = unlink (file);
|
||||
if (err != 0)
|
||||
logprintf (LOG_VERBOSE, _("Failed to unlink symlink `%s': %s\n"),
|
||||
file, strerror (errno));
|
||||
logprintf (LOG_VERBOSE, _("Failed to unlink symlink `%s': %s\n"),
|
||||
file, strerror (errno));
|
||||
}
|
||||
return err;
|
||||
}
|
||||
@ -502,12 +502,12 @@ unique_create (const char *name, bool binary, char **opened_name)
|
||||
if (opened_name && fp != NULL)
|
||||
{
|
||||
if (fp)
|
||||
*opened_name = uname;
|
||||
*opened_name = uname;
|
||||
else
|
||||
{
|
||||
*opened_name = NULL;
|
||||
xfree (uname);
|
||||
}
|
||||
{
|
||||
*opened_name = NULL;
|
||||
xfree (uname);
|
||||
}
|
||||
}
|
||||
else
|
||||
xfree (uname);
|
||||
@ -572,21 +572,21 @@ make_directory (const char *directory)
|
||||
for (i = (*dir == '/'); 1; ++i)
|
||||
{
|
||||
for (; dir[i] && dir[i] != '/'; i++)
|
||||
;
|
||||
;
|
||||
if (!dir[i])
|
||||
quit = 1;
|
||||
quit = 1;
|
||||
dir[i] = '\0';
|
||||
/* Check whether the directory already exists. Allow creation of
|
||||
of intermediate directories to fail, as the initial path components
|
||||
are not necessarily directories! */
|
||||
of intermediate directories to fail, as the initial path components
|
||||
are not necessarily directories! */
|
||||
if (!file_exists_p (dir))
|
||||
ret = mkdir (dir, 0777);
|
||||
ret = mkdir (dir, 0777);
|
||||
else
|
||||
ret = 0;
|
||||
ret = 0;
|
||||
if (quit)
|
||||
break;
|
||||
break;
|
||||
else
|
||||
dir[i] = '/';
|
||||
dir[i] = '/';
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -657,10 +657,10 @@ acceptable (const char *s)
|
||||
if (opt.accepts)
|
||||
{
|
||||
if (opt.rejects)
|
||||
return (in_acclist ((const char *const *)opt.accepts, s, true)
|
||||
&& !in_acclist ((const char *const *)opt.rejects, s, true));
|
||||
return (in_acclist ((const char *const *)opt.accepts, s, true)
|
||||
&& !in_acclist ((const char *const *)opt.rejects, s, true));
|
||||
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)
|
||||
return !in_acclist ((const char *const *)opt.rejects, s, true);
|
||||
@ -698,15 +698,15 @@ dir_matches_p (char **dirlist, const char *dir)
|
||||
/* Remove leading '/' */
|
||||
char *p = *x + (**x == '/');
|
||||
if (has_wildcards_p (p))
|
||||
{
|
||||
if (matcher (p, dir, FNM_PATHNAME) == 0)
|
||||
break;
|
||||
}
|
||||
{
|
||||
if (matcher (p, dir, FNM_PATHNAME) == 0)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (subdir_p (p, dir))
|
||||
break;
|
||||
}
|
||||
{
|
||||
if (subdir_p (p, dir))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return *x ? true : false;
|
||||
@ -727,12 +727,12 @@ accdir (const char *directory)
|
||||
if (opt.includes)
|
||||
{
|
||||
if (!dir_matches_p (opt.includes, directory))
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
if (opt.excludes)
|
||||
{
|
||||
if (dir_matches_p (opt.excludes, directory))
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -756,14 +756,14 @@ match_tail (const char *string, const char *tail, bool fold_case)
|
||||
if (!fold_case)
|
||||
{
|
||||
for (i = strlen (string), j = strlen (tail); i >= 0 && j >= 0; i--, j--)
|
||||
if (string[i] != tail[j])
|
||||
break;
|
||||
if (string[i] != tail[j])
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = strlen (string), j = strlen (tail); i >= 0 && j >= 0; i--, j--)
|
||||
if (TOLOWER (string[i]) != TOLOWER (tail[j]))
|
||||
break;
|
||||
if (TOLOWER (string[i]) != TOLOWER (tail[j]))
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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++)
|
||||
{
|
||||
if (has_wildcards_p (*accepts))
|
||||
{
|
||||
int res = opt.ignore_case
|
||||
? fnmatch_nocase (*accepts, s, 0) : fnmatch (*accepts, s, 0);
|
||||
/* fnmatch returns 0 if the pattern *does* match the string. */
|
||||
if (res == 0)
|
||||
return true;
|
||||
}
|
||||
{
|
||||
int res = opt.ignore_case
|
||||
? fnmatch_nocase (*accepts, s, 0) : fnmatch (*accepts, s, 0);
|
||||
/* fnmatch returns 0 if the pattern *does* match the string. */
|
||||
if (res == 0)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (backward)
|
||||
{
|
||||
if (match_tail (s, *accepts, opt.ignore_case))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
int cmp = opt.ignore_case
|
||||
? strcasecmp (s, *accepts) : strcmp (s, *accepts);
|
||||
if (cmp == 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
{
|
||||
if (backward)
|
||||
{
|
||||
if (match_tail (s, *accepts, opt.ignore_case))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
int cmp = opt.ignore_case
|
||||
? strcasecmp (s, *accepts) : strcmp (s, *accepts);
|
||||
if (cmp == 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -891,12 +891,12 @@ read_whole_line (FILE *fp)
|
||||
{
|
||||
length += strlen (line + length);
|
||||
if (length == 0)
|
||||
/* Possible for example when reading from a binary file where
|
||||
a line begins with \0. */
|
||||
continue;
|
||||
/* Possible for example when reading from a binary file where
|
||||
a line begins with \0. */
|
||||
continue;
|
||||
|
||||
if (line[length - 1] == '\n')
|
||||
break;
|
||||
break;
|
||||
|
||||
/* fgets() guarantees to read the whole line, or to use up the
|
||||
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
|
||||
efficiency, but at some cost to generality. */
|
||||
fm->content = mmap (NULL, fm->length, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE, fd, 0);
|
||||
MAP_PRIVATE, fd, 0);
|
||||
if (fm->content == (char *)MAP_FAILED)
|
||||
goto mmap_lose;
|
||||
if (!inhibit_close)
|
||||
@ -986,41 +986,41 @@ read_file (const char *file)
|
||||
#endif /* HAVE_MMAP */
|
||||
|
||||
fm->length = 0;
|
||||
size = 512; /* number of bytes fm->contents can
|
||||
size = 512; /* number of bytes fm->contents can
|
||||
hold at any given time. */
|
||||
fm->content = xmalloc (size);
|
||||
while (1)
|
||||
{
|
||||
wgint nread;
|
||||
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,
|
||||
read() refuses to read more than 4K from a file at a
|
||||
single chunk anyway. But other Unixes might optimize it
|
||||
better, and it doesn't *hurt* anything, so I'm leaving
|
||||
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
|
||||
to file size. However, read() can read an amount of data
|
||||
smaller than requested, and it would be unreasonable to
|
||||
double SIZE every time *something* was read. Therefore,
|
||||
we double SIZE only when the length exceeds half of the
|
||||
entire allocated size. */
|
||||
size <<= 1;
|
||||
fm->content = xrealloc (fm->content, size);
|
||||
}
|
||||
size <<= 1;
|
||||
fm->content = xrealloc (fm->content, size);
|
||||
}
|
||||
nread = read (fd, fm->content + fm->length, size - fm->length);
|
||||
if (nread > 0)
|
||||
/* Successful read. */
|
||||
fm->length += nread;
|
||||
/* Successful read. */
|
||||
fm->length += nread;
|
||||
else if (nread < 0)
|
||||
/* Error. */
|
||||
goto lose;
|
||||
/* Error. */
|
||||
goto lose;
|
||||
else
|
||||
/* EOF */
|
||||
break;
|
||||
/* EOF */
|
||||
break;
|
||||
}
|
||||
if (!inhibit_close)
|
||||
close (fd);
|
||||
@ -1069,7 +1069,7 @@ free_vec (char **vec)
|
||||
{
|
||||
char **p = vec;
|
||||
while (*p)
|
||||
xfree (*p++);
|
||||
xfree (*p++);
|
||||
xfree (vec);
|
||||
}
|
||||
}
|
||||
@ -1111,12 +1111,12 @@ merge_vecs (char **v1, char **v2)
|
||||
char **
|
||||
vec_append (char **vec, const char *str)
|
||||
{
|
||||
int cnt; /* count of vector elements, including
|
||||
the one we're about to append */
|
||||
int cnt; /* count of vector elements, including
|
||||
the one we're about to append */
|
||||
if (vec != NULL)
|
||||
{
|
||||
for (cnt = 0; vec[cnt]; cnt++)
|
||||
;
|
||||
;
|
||||
++cnt;
|
||||
}
|
||||
else
|
||||
@ -1216,18 +1216,18 @@ get_grouping_data (const char **sep, const char **grouping)
|
||||
cached_sep = lconv->thousands_sep;
|
||||
cached_grouping = lconv->grouping;
|
||||
if (!*cached_sep)
|
||||
{
|
||||
/* Many locales (such as "C" or "hr_HR") don't specify
|
||||
grouping, which we still want to use it for legibility.
|
||||
In those locales set the sep char to ',', unless that
|
||||
character is used for decimal point, in which case set it
|
||||
to ".". */
|
||||
if (*lconv->decimal_point != ',')
|
||||
cached_sep = ",";
|
||||
else
|
||||
cached_sep = ".";
|
||||
cached_grouping = "\x03";
|
||||
}
|
||||
{
|
||||
/* Many locales (such as "C" or "hr_HR") don't specify
|
||||
grouping, which we still want to use it for legibility.
|
||||
In those locales set the sep char to ',', unless that
|
||||
character is used for decimal point, in which case set it
|
||||
to ".". */
|
||||
if (*lconv->decimal_point != ',')
|
||||
cached_sep = ",";
|
||||
else
|
||||
cached_sep = ".";
|
||||
cached_grouping = "\x03";
|
||||
}
|
||||
initialized = true;
|
||||
}
|
||||
*sep = cached_sep;
|
||||
@ -1278,18 +1278,18 @@ with_thousand_seps (wgint n)
|
||||
*--p = n % 10 + '0';
|
||||
n /= 10;
|
||||
if (n == 0)
|
||||
break;
|
||||
break;
|
||||
/* Prepend SEP to every groupsize'd digit and get new groupsize. */
|
||||
if (++i == groupsize)
|
||||
{
|
||||
if (seplen == 1)
|
||||
*--p = *sep;
|
||||
else
|
||||
memcpy (p -= seplen, sep, seplen);
|
||||
i = 0;
|
||||
if (*atgroup)
|
||||
groupsize = *atgroup++;
|
||||
}
|
||||
{
|
||||
if (seplen == 1)
|
||||
*--p = *sep;
|
||||
else
|
||||
memcpy (p -= seplen, sep, seplen);
|
||||
i = 0;
|
||||
if (*atgroup)
|
||||
groupsize = *atgroup++;
|
||||
}
|
||||
}
|
||||
if (negative)
|
||||
*--p = '-';
|
||||
@ -1319,12 +1319,12 @@ human_readable (HR_NUMTYPE n)
|
||||
/* These suffixes are compatible with those of GNU `ls -lh'. */
|
||||
static char powers[] =
|
||||
{
|
||||
'K', /* kilobyte, 2^10 bytes */
|
||||
'M', /* megabyte, 2^20 bytes */
|
||||
'G', /* gigabyte, 2^30 bytes */
|
||||
'T', /* terabyte, 2^40 bytes */
|
||||
'P', /* petabyte, 2^50 bytes */
|
||||
'E', /* exabyte, 2^60 bytes */
|
||||
'K', /* kilobyte, 2^10 bytes */
|
||||
'M', /* megabyte, 2^20 bytes */
|
||||
'G', /* gigabyte, 2^30 bytes */
|
||||
'T', /* terabyte, 2^40 bytes */
|
||||
'P', /* petabyte, 2^50 bytes */
|
||||
'E', /* exabyte, 2^60 bytes */
|
||||
};
|
||||
static char buf[8];
|
||||
int i;
|
||||
@ -1342,20 +1342,20 @@ human_readable (HR_NUMTYPE n)
|
||||
for (i = 0; i < countof (powers); i++)
|
||||
{
|
||||
/* At each iteration N is greater than the *subsequent* power.
|
||||
That way N/1024.0 produces a decimal number in the units of
|
||||
*this* power. */
|
||||
That way N/1024.0 produces a decimal number in the units of
|
||||
*this* power. */
|
||||
if ((n / 1024) < 1024 || i == countof (powers) - 1)
|
||||
{
|
||||
double val = n / 1024.0;
|
||||
/* Print values smaller than 10 with one decimal digits, and
|
||||
others without any decimals. */
|
||||
snprintf (buf, sizeof (buf), "%.*f%c",
|
||||
val < 10 ? 1 : 0, val, powers[i]);
|
||||
return buf;
|
||||
}
|
||||
{
|
||||
double val = n / 1024.0;
|
||||
/* Print values smaller than 10 with one decimal digits, and
|
||||
others without any decimals. */
|
||||
snprintf (buf, sizeof (buf), "%.*f%c",
|
||||
val < 10 ? 1 : 0, val, powers[i]);
|
||||
return buf;
|
||||
}
|
||||
n /= 1024;
|
||||
}
|
||||
return NULL; /* unreached */
|
||||
return NULL; /* unreached */
|
||||
}
|
||||
|
||||
/* Count the digits in the provided number. Used to allocate space
|
||||
@ -1366,7 +1366,7 @@ numdigit (wgint number)
|
||||
{
|
||||
int cnt = 1;
|
||||
if (number < 0)
|
||||
++cnt; /* accomodate '-' */
|
||||
++cnt; /* accomodate '-' */
|
||||
while ((number /= 10) != 0)
|
||||
++cnt;
|
||||
return cnt;
|
||||
@ -1441,8 +1441,8 @@ number_to_string (char *buffer, wgint number)
|
||||
if (n < 0)
|
||||
{
|
||||
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
|
||||
smaller and handle the last digit separately. */
|
||||
int last_digit = n % 10;
|
||||
@ -1453,7 +1453,7 @@ number_to_string (char *buffer, wgint number)
|
||||
last_digit_char = '0' + last_digit;
|
||||
/* After n is made smaller, -n will not overflow. */
|
||||
n /= 10;
|
||||
}
|
||||
}
|
||||
|
||||
*p++ = '-';
|
||||
n = -n;
|
||||
@ -1585,7 +1585,7 @@ determine_screen_width (void)
|
||||
|
||||
fd = fileno (stderr);
|
||||
if (ioctl (fd, TIOCGWINSZ, &wsz) < 0)
|
||||
return 0; /* most likely ENOTTY */
|
||||
return 0; /* most likely ENOTTY */
|
||||
|
||||
return wsz.ws_col;
|
||||
#elif defined(WINDOWS)
|
||||
@ -1661,9 +1661,9 @@ random_float (void)
|
||||
return drand48 ();
|
||||
#else /* not HAVE_DRAND48 */
|
||||
return ( random_number (10000) / 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 * 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 * 10000.0));
|
||||
#endif /* not HAVE_DRAND48 */
|
||||
}
|
||||
|
||||
@ -1851,8 +1851,8 @@ xsleep (double seconds)
|
||||
if (seconds >= 1)
|
||||
{
|
||||
/* On some systems, usleep cannot handle values larger than
|
||||
1,000,000. If the period is larger than that, use sleep
|
||||
first, then add usleep for subsecond accuracy. */
|
||||
1,000,000. If the period is larger than that, use sleep
|
||||
first, then add usleep for subsecond accuracy. */
|
||||
sleep (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
|
||||
when end of string is reached. */
|
||||
#define NEXT_CHAR(c, p) do { \
|
||||
c = (unsigned char) *p++; \
|
||||
#define NEXT_CHAR(c, p) do { \
|
||||
c = (unsigned char) *p++; \
|
||||
} while (ISSPACE (c))
|
||||
|
||||
#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). */
|
||||
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, /* 10- 19 */
|
||||
-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, 62, -1, -1, -1, 63, 52, 53, /* 40- 49 */
|
||||
54, 55, 56, 57, 58, 59, 60, 61, -1, -1, /* 50- 59 */
|
||||
-1, -1, -1, -1, -1, 0, 1, 2, 3, 4, /* 60- 69 */
|
||||
5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 70- 79 */
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, /* 80- 89 */
|
||||
25, -1, -1, -1, -1, -1, -1, 26, 27, 28, /* 90- 99 */
|
||||
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, /* 100-109 */
|
||||
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, /* 110-119 */
|
||||
49, 50, 51, -1, -1, -1, -1, -1 /* 120-127 */
|
||||
-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, /* 20- 29 */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 30- 39 */
|
||||
-1, -1, -1, 62, -1, -1, -1, 63, 52, 53, /* 40- 49 */
|
||||
54, 55, 56, 57, 58, 59, 60, 61, -1, -1, /* 50- 59 */
|
||||
-1, -1, -1, -1, -1, 0, 1, 2, 3, 4, /* 60- 69 */
|
||||
5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 70- 79 */
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, /* 80- 89 */
|
||||
25, -1, -1, -1, -1, -1, -1, 26, 27, 28, /* 90- 99 */
|
||||
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, /* 100-109 */
|
||||
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, /* 110-119 */
|
||||
49, 50, 51, -1, -1, -1, -1, -1 /* 120-127 */
|
||||
};
|
||||
#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 == '=')
|
||||
@ -1987,36 +1987,36 @@ base64_decode (const char *base64, void *dest)
|
||||
/* Process first byte of a quadruplet. */
|
||||
NEXT_CHAR (c, p);
|
||||
if (!c)
|
||||
break;
|
||||
break;
|
||||
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;
|
||||
|
||||
/* Process second byte of a quadruplet. */
|
||||
NEXT_CHAR (c, p);
|
||||
if (!c)
|
||||
return -1; /* premature EOF while decoding base64 */
|
||||
return -1; /* premature EOF while decoding base64 */
|
||||
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;
|
||||
*q++ = value >> 16;
|
||||
|
||||
/* Process third byte of a quadruplet. */
|
||||
NEXT_CHAR (c, p);
|
||||
if (!c)
|
||||
return -1; /* premature EOF while decoding base64 */
|
||||
return -1; /* premature EOF while decoding base64 */
|
||||
if (!IS_BASE64 (c))
|
||||
return -1; /* illegal char while decoding base64 */
|
||||
return -1; /* illegal char while decoding base64 */
|
||||
|
||||
if (c == '=')
|
||||
{
|
||||
NEXT_CHAR (c, p);
|
||||
if (!c)
|
||||
return -1; /* premature EOF while decoding base64 */
|
||||
if (c != '=')
|
||||
return -1; /* padding `=' expected but not found */
|
||||
continue;
|
||||
}
|
||||
{
|
||||
NEXT_CHAR (c, p);
|
||||
if (!c)
|
||||
return -1; /* premature EOF while decoding base64 */
|
||||
if (c != '=')
|
||||
return -1; /* padding `=' expected but not found */
|
||||
continue;
|
||||
}
|
||||
|
||||
value |= BASE64_CHAR_TO_VALUE (c) << 6;
|
||||
*q++ = 0xff & value >> 8;
|
||||
@ -2024,11 +2024,11 @@ base64_decode (const char *base64, void *dest)
|
||||
/* Process fourth byte of a quadruplet. */
|
||||
NEXT_CHAR (c, p);
|
||||
if (!c)
|
||||
return -1; /* premature EOF while decoding base64 */
|
||||
return -1; /* premature EOF while decoding base64 */
|
||||
if (c == '=')
|
||||
continue;
|
||||
continue;
|
||||
if (!IS_BASE64 (c))
|
||||
return -1; /* illegal char while decoding base64 */
|
||||
return -1; /* illegal char while decoding base64 */
|
||||
|
||||
value |= BASE64_CHAR_TO_VALUE (c);
|
||||
*q++ = 0xff & value;
|
||||
@ -2047,7 +2047,7 @@ base64_decode (const char *base64, void *dest)
|
||||
|
||||
static void
|
||||
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)
|
||||
if (from < to)
|
||||
@ -2059,16 +2059,16 @@ mergesort_internal (void *base, void *temp, size_t size, size_t from, size_t to,
|
||||
i = from;
|
||||
j = mid + 1;
|
||||
for (k = from; (i <= mid) && (j <= to); k++)
|
||||
if (cmpfun (ELT (base, i), ELT (base, j)) <= 0)
|
||||
memcpy (ELT (temp, k), ELT (base, i++), size);
|
||||
else
|
||||
memcpy (ELT (temp, k), ELT (base, j++), size);
|
||||
if (cmpfun (ELT (base, i), ELT (base, j)) <= 0)
|
||||
memcpy (ELT (temp, k), ELT (base, i++), size);
|
||||
else
|
||||
memcpy (ELT (temp, k), ELT (base, j++), size);
|
||||
while (i <= mid)
|
||||
memcpy (ELT (temp, k++), ELT (base, i++), size);
|
||||
memcpy (ELT (temp, k++), ELT (base, i++), size);
|
||||
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++)
|
||||
memcpy (ELT (base, k), ELT (temp, k), size);
|
||||
memcpy (ELT (base, k), ELT (temp, k), size);
|
||||
}
|
||||
#undef ELT
|
||||
}
|
||||
@ -2079,7 +2079,7 @@ mergesort_internal (void *base, void *temp, size_t size, size_t from, size_t to,
|
||||
|
||||
void
|
||||
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)
|
||||
{
|
||||
|
@ -36,7 +36,7 @@ so, delete this exception statement from your version. */
|
||||
|
||||
#include "wget.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
|
||||
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. */
|
||||
log_set_save_context (false);
|
||||
logprintf (LOG_ALWAYS,
|
||||
_("%s: %s: Failed to allocate %ld bytes; memory exhausted.\n"),
|
||||
exec_name, context, attempted_size);
|
||||
_("%s: %s: Failed to allocate %ld bytes; memory exhausted.\n"),
|
||||
exec_name, context, attempted_size);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
@ -208,8 +208,8 @@ static int malloc_count, free_count;
|
||||
|
||||
/* Home-grown hash table of mallocs: */
|
||||
|
||||
#define SZ 100003 /* Prime just over 100,000. Increase
|
||||
it to debug larger Wget runs. */
|
||||
#define SZ 100003 /* Prime just over 100,000. Increase
|
||||
it to debug larger Wget runs. */
|
||||
|
||||
static struct {
|
||||
const void *ptr;
|
||||
@ -269,10 +269,10 @@ unregister_ptr (void *ptr)
|
||||
/* Find the new location for the key. */
|
||||
int j = hash_pointer (ptr2) % SZ;
|
||||
for (; malloc_table[j].ptr != NULL; j = (j + 1) % SZ)
|
||||
if (ptr2 == malloc_table[j].ptr)
|
||||
/* No need to relocate entry at [i]; it's already at or near
|
||||
its hash position. */
|
||||
goto cont_outer;
|
||||
if (ptr2 == malloc_table[j].ptr)
|
||||
/* No need to relocate entry at [i]; it's already at or near
|
||||
its hash position. */
|
||||
goto cont_outer;
|
||||
malloc_table[j] = malloc_table[i];
|
||||
malloc_table[i].ptr = NULL;
|
||||
cont_outer:
|
||||
@ -291,11 +291,11 @@ print_malloc_debug_stats (void)
|
||||
{
|
||||
int i;
|
||||
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++)
|
||||
if (malloc_table[i].ptr != NULL)
|
||||
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 *
|
||||
@ -351,13 +351,13 @@ debugging_free (void *ptr, const char *source_file, int source_line)
|
||||
if (ptr == NULL)
|
||||
{
|
||||
fprintf (stderr, "%s: xfree(NULL) at %s:%d\n",
|
||||
exec_name, source_file, source_line);
|
||||
exec_name, source_file, source_line);
|
||||
abort ();
|
||||
}
|
||||
if (!unregister_ptr (ptr))
|
||||
{
|
||||
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 ();
|
||||
}
|
||||
++free_count;
|
||||
|
Loading…
Reference in New Issue
Block a user