diff options
| author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2002-02-05 22:13:51 +0000 | 
|---|---|---|
| committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2002-02-05 22:13:51 +0000 | 
| commit | e19e6098b3beddfc5475b44809c28d8a4e800025 (patch) | |
| tree | cad86b96b05ec19f9c9eb4e26ddb8060f540c83d /lib | |
| parent | 076172c5bcd28ac2fe1ec5909215f06deb990d78 (diff) | |
Notes
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/libfetch/Makefile | 2 | ||||
| -rw-r--r-- | lib/libfetch/common.c | 463 | ||||
| -rw-r--r-- | lib/libfetch/common.h | 13 | ||||
| -rw-r--r-- | lib/libfetch/fetch.c | 451 | ||||
| -rw-r--r-- | lib/libfetch/fetch.h | 44 | ||||
| -rw-r--r-- | lib/libfetch/file.c | 152 | ||||
| -rw-r--r-- | lib/libfetch/ftp.c | 1383 | ||||
| -rw-r--r-- | lib/libfetch/http.c | 1478 | 
8 files changed, 1997 insertions, 1989 deletions
diff --git a/lib/libfetch/Makefile b/lib/libfetch/Makefile index 9dc1b9f03655..c5ec5bc76472 100644 --- a/lib/libfetch/Makefile +++ b/lib/libfetch/Makefile @@ -2,7 +2,7 @@  MAINTAINER=	des@freebsd.org  LIB=		fetch -WARNS?=		2 +WARNS?=		4  CFLAGS+=	-I.  CFLAGS+=	-DINET6  SRCS=		fetch.c common.c ftp.c http.c file.c \ diff --git a/lib/libfetch/common.c b/lib/libfetch/common.c index 88c93a531145..f2a173221cfb 100644 --- a/lib/libfetch/common.c +++ b/lib/libfetch/common.c @@ -53,11 +53,11 @@ __FBSDID("$FreeBSD$");   * Error messages for resolver errors   */  static struct fetcherr _netdb_errlist[] = { -    { EAI_NODATA,	FETCH_RESOLV,	"Host not found" }, -    { EAI_AGAIN,	FETCH_TEMP,	"Transient resolver failure" }, -    { EAI_FAIL,		FETCH_RESOLV,	"Non-recoverable resolver failure" }, -    { EAI_NONAME,	FETCH_RESOLV,	"No address record" }, -    { -1,		FETCH_UNKNOWN,	"Unknown resolver error" } +	{ EAI_NODATA,	FETCH_RESOLV,	"Host not found" }, +	{ EAI_AGAIN,	FETCH_TEMP,	"Transient resolver failure" }, +	{ EAI_FAIL,	FETCH_RESOLV,	"Non-recoverable resolver failure" }, +	{ EAI_NONAME,	FETCH_RESOLV,	"No address record" }, +	{ -1,		FETCH_UNKNOWN,	"Unknown resolver error" }  };  /* End-of-Line */ @@ -72,9 +72,9 @@ static const char ENDL[2] = "\r\n";  static struct fetcherr *  _fetch_finderr(struct fetcherr *p, int e)  { -    while (p->num != -1 && p->num != e) -	p++; -    return p; +	while (p->num != -1 && p->num != e) +		p++; +	return (p);  }  /* @@ -83,9 +83,9 @@ _fetch_finderr(struct fetcherr *p, int e)  void  _fetch_seterr(struct fetcherr *p, int e)  { -    p = _fetch_finderr(p, e); -    fetchLastErrCode = p->cat; -    snprintf(fetchLastErrString, MAXERRSTRING, "%s", p->string); +	p = _fetch_finderr(p, e); +	fetchLastErrCode = p->cat; +	snprintf(fetchLastErrString, MAXERRSTRING, "%s", p->string);  }  /* @@ -94,60 +94,57 @@ _fetch_seterr(struct fetcherr *p, int e)  void  _fetch_syserr(void)  { -    int e; -    e = errno; -     -    switch (errno) { -    case 0: -	fetchLastErrCode = FETCH_OK; -	break; -    case EPERM: -    case EACCES: -    case EROFS: -    case EAUTH: -    case ENEEDAUTH: -	fetchLastErrCode = FETCH_AUTH; -	break; -    case ENOENT: -    case EISDIR: /* XXX */ -	fetchLastErrCode = FETCH_UNAVAIL; -	break; -    case ENOMEM: -	fetchLastErrCode = FETCH_MEMORY; -	break; -    case EBUSY: -    case EAGAIN:	 -	fetchLastErrCode = FETCH_TEMP; -	break; -    case EEXIST: -	fetchLastErrCode = FETCH_EXISTS; -	break; -    case ENOSPC: -	fetchLastErrCode = FETCH_FULL; -	break; -    case EADDRINUSE: -    case EADDRNOTAVAIL: -    case ENETDOWN: -    case ENETUNREACH: -    case ENETRESET: -    case EHOSTUNREACH: -	fetchLastErrCode = FETCH_NETWORK; -	break; -    case ECONNABORTED: -    case ECONNRESET: -	fetchLastErrCode = FETCH_ABORT; -	break; -    case ETIMEDOUT: -	fetchLastErrCode = FETCH_TIMEOUT; -	break; -    case ECONNREFUSED: -    case EHOSTDOWN: -	fetchLastErrCode = FETCH_DOWN; -	break; -    default: -	fetchLastErrCode = FETCH_UNKNOWN; -    } -    snprintf(fetchLastErrString, MAXERRSTRING, "%s", strerror(e)); +	switch (errno) { +	case 0: +		fetchLastErrCode = FETCH_OK; +		break; +	case EPERM: +	case EACCES: +	case EROFS: +	case EAUTH: +	case ENEEDAUTH: +		fetchLastErrCode = FETCH_AUTH; +		break; +	case ENOENT: +	case EISDIR: /* XXX */ +		fetchLastErrCode = FETCH_UNAVAIL; +		break; +	case ENOMEM: +		fetchLastErrCode = FETCH_MEMORY; +		break; +	case EBUSY: +	case EAGAIN: +		fetchLastErrCode = FETCH_TEMP; +		break; +	case EEXIST: +		fetchLastErrCode = FETCH_EXISTS; +		break; +	case ENOSPC: +		fetchLastErrCode = FETCH_FULL; +		break; +	case EADDRINUSE: +	case EADDRNOTAVAIL: +	case ENETDOWN: +	case ENETUNREACH: +	case ENETRESET: +	case EHOSTUNREACH: +		fetchLastErrCode = FETCH_NETWORK; +		break; +	case ECONNABORTED: +	case ECONNRESET: +		fetchLastErrCode = FETCH_ABORT; +		break; +	case ETIMEDOUT: +		fetchLastErrCode = FETCH_TIMEOUT; +		break; +	case ECONNREFUSED: +	case EHOSTDOWN: +		fetchLastErrCode = FETCH_DOWN; +		break; +default: +		fetchLastErrCode = FETCH_UNKNOWN; +	} +	snprintf(fetchLastErrString, MAXERRSTRING, "%s", strerror(errno));  } @@ -157,12 +154,12 @@ _fetch_syserr(void)  void  _fetch_info(const char *fmt, ...)  { -    va_list ap; -     -    va_start(ap, fmt); -    vfprintf(stderr, fmt, ap); -    va_end(ap); -    fputc('\n', stderr); +	va_list ap; + +	va_start(ap, fmt); +	vfprintf(stderr, fmt, ap); +	va_end(ap); +	fputc('\n', stderr);  } @@ -174,15 +171,15 @@ _fetch_info(const char *fmt, ...)  int  _fetch_default_port(const char *scheme)  { -    struct servent *se; - -    if ((se = getservbyname(scheme, "tcp")) != NULL) -	return ntohs(se->s_port); -    if (strcasecmp(scheme, SCHEME_FTP) == 0) -	return FTP_DEFAULT_PORT; -    if (strcasecmp(scheme, SCHEME_HTTP) == 0) -	return HTTP_DEFAULT_PORT; -    return 0; +	struct servent *se; + +	if ((se = getservbyname(scheme, "tcp")) != NULL) +		return (ntohs(se->s_port)); +	if (strcasecmp(scheme, SCHEME_FTP) == 0) +		return (FTP_DEFAULT_PORT); +	if (strcasecmp(scheme, SCHEME_HTTP) == 0) +		return (HTTP_DEFAULT_PORT); +	return (0);  }  /* @@ -191,11 +188,11 @@ _fetch_default_port(const char *scheme)  int  _fetch_default_proxy_port(const char *scheme)  { -    if (strcasecmp(scheme, SCHEME_FTP) == 0) -	return FTP_DEFAULT_PROXY_PORT; -    if (strcasecmp(scheme, SCHEME_HTTP) == 0) -	return HTTP_DEFAULT_PROXY_PORT; -    return 0; +	if (strcasecmp(scheme, SCHEME_FTP) == 0) +		return (FTP_DEFAULT_PROXY_PORT); +	if (strcasecmp(scheme, SCHEME_HTTP) == 0) +		return (HTTP_DEFAULT_PROXY_PORT); +	return (0);  }  /* @@ -204,46 +201,46 @@ _fetch_default_proxy_port(const char *scheme)  int  _fetch_connect(const char *host, int port, int af, int verbose)  { -    char pbuf[10]; -    struct addrinfo hints, *res, *res0; -    int sd, err; - -    DEBUG(fprintf(stderr, "---> %s:%d\n", host, port)); - -    if (verbose) -	_fetch_info("looking up %s", host); -     -    /* look up host name and set up socket address structure */ -    snprintf(pbuf, sizeof(pbuf), "%d", port); -    memset(&hints, 0, sizeof(hints)); -    hints.ai_family = af; -    hints.ai_socktype = SOCK_STREAM; -    hints.ai_protocol = 0; -    if ((err = getaddrinfo(host, pbuf, &hints, &res0)) != 0) { -	_netdb_seterr(err); -	return -1; -    } - -    if (verbose) -	_fetch_info("connecting to %s:%d", host, port); -     -    /* try to connect */ -    for (sd = -1, res = res0; res; res = res->ai_next) { -	if ((sd = socket(res->ai_family, res->ai_socktype, +	char pbuf[10]; +	struct addrinfo hints, *res, *res0; +	int sd, err; + +	DEBUG(fprintf(stderr, "---> %s:%d\n", host, port)); + +	if (verbose) +		_fetch_info("looking up %s", host); + +	/* look up host name and set up socket address structure */ +	snprintf(pbuf, sizeof(pbuf), "%d", port); +	memset(&hints, 0, sizeof(hints)); +	hints.ai_family = af; +	hints.ai_socktype = SOCK_STREAM; +	hints.ai_protocol = 0; +	if ((err = getaddrinfo(host, pbuf, &hints, &res0)) != 0) { +		_netdb_seterr(err); +		return (-1); +	} + +	if (verbose) +		_fetch_info("connecting to %s:%d", host, port); + +	/* try to connect */ +	for (sd = -1, res = res0; res; res = res->ai_next) { +		if ((sd = socket(res->ai_family, res->ai_socktype,  			 res->ai_protocol)) == -1) -	    continue; -	if (connect(sd, res->ai_addr, res->ai_addrlen) != -1) -	    break; -	close(sd); -	sd = -1; -    } -    freeaddrinfo(res0); -    if (sd == -1) { -	_fetch_syserr(); -	return -1; -    } - -    return sd; +			continue; +		if (connect(sd, res->ai_addr, res->ai_addrlen) != -1) +			break; +		close(sd); +		sd = -1; +	} +	freeaddrinfo(res0); +	if (sd == -1) { +		_fetch_syserr(); +		return (-1); +	} + +	return (sd);  } @@ -255,77 +252,77 @@ _fetch_connect(const char *host, int port, int af, int verbose)  int  _fetch_getln(int fd, char **buf, size_t *size, size_t *len)  { -    struct timeval now, timeout, wait; -    fd_set readfds; -    int r; -    char c; -     -    if (*buf == NULL) { -	if ((*buf = malloc(MIN_BUF_SIZE)) == NULL) { -	    errno = ENOMEM; -	    return -1; +	struct timeval now, timeout, wait; +	fd_set readfds; +	int r; +	char c; + +	if (*buf == NULL) { +		if ((*buf = malloc(MIN_BUF_SIZE)) == NULL) { +			errno = ENOMEM; +			return (-1); +		} +		*size = MIN_BUF_SIZE;  	} -	*size = MIN_BUF_SIZE; -    } - -    **buf = '\0'; -    *len = 0; - -    if (fetchTimeout) { -	gettimeofday(&timeout, NULL); -	timeout.tv_sec += fetchTimeout; -	FD_ZERO(&readfds); -    } -     -    do { + +	**buf = '\0'; +	*len = 0; +  	if (fetchTimeout) { -	    FD_SET(fd, &readfds); -	    gettimeofday(&now, NULL); -	    wait.tv_sec = timeout.tv_sec - now.tv_sec; -	    wait.tv_usec = timeout.tv_usec - now.tv_usec; -	    if (wait.tv_usec < 0) { -		wait.tv_usec += 1000000; -		wait.tv_sec--; -	    } -	    if (wait.tv_sec < 0) { -		errno = ETIMEDOUT; -		return -1; -	    } -	    r = select(fd+1, &readfds, NULL, NULL, &wait); -	    if (r == -1) { -		if (errno == EINTR && fetchRestartCalls) -		    continue; -		/* EBADF or EINVAL: shouldn't happen */ -		return -1; -	    } -	    if (!FD_ISSET(fd, &readfds)) -		continue; -	} -	r = read(fd, &c, 1); -	if (r == 0) -	    break; -	if (r == -1) { -	    if (errno == EINTR && fetchRestartCalls) -		continue; -	    /* any other error is bad news */ -	    return -1; +		gettimeofday(&timeout, NULL); +		timeout.tv_sec += fetchTimeout; +		FD_ZERO(&readfds);  	} -	(*buf)[*len] = c; -	*len += 1; -	if (*len == *size) { -	    char *tmp; -	     -	    if ((tmp = realloc(*buf, *size * 2 + 1)) == NULL) { -		errno = ENOMEM; -		return -1; -	    } -	    *buf = tmp; -	    *size = *size * 2 + 1; -	} -    } while (c != '\n'); -     -    DEBUG(fprintf(stderr, "<<< %.*s", (int)*len, *buf)); -    return 0; + +	do { +		if (fetchTimeout) { +			FD_SET(fd, &readfds); +			gettimeofday(&now, NULL); +			wait.tv_sec = timeout.tv_sec - now.tv_sec; +			wait.tv_usec = timeout.tv_usec - now.tv_usec; +			if (wait.tv_usec < 0) { +				wait.tv_usec += 1000000; +				wait.tv_sec--; +			} +			if (wait.tv_sec < 0) { +				errno = ETIMEDOUT; +				return (-1); +			} +			r = select(fd+1, &readfds, NULL, NULL, &wait); +			if (r == -1) { +				if (errno == EINTR && fetchRestartCalls) +					continue; +				/* EBADF or EINVAL: shouldn't happen */ +				return (-1); +			} +			if (!FD_ISSET(fd, &readfds)) +				continue; +		} +		r = read(fd, &c, 1); +		if (r == 0) +			break; +		if (r == -1) { +			if (errno == EINTR && fetchRestartCalls) +				continue; +			/* any other error is bad news */ +			return (-1); +		} +		(*buf)[*len] = c; +		*len += 1; +		if (*len == *size) { +			char *tmp; + +			if ((tmp = realloc(*buf, *size * 2 + 1)) == NULL) { +				errno = ENOMEM; +				return (-1); +			} +			*buf = tmp; +			*size = *size * 2 + 1; +		} +	} while (c != '\n'); + +	DEBUG(fprintf(stderr, "<<< %.*s", (int)*len, *buf)); +	return (0);  } @@ -336,20 +333,20 @@ _fetch_getln(int fd, char **buf, size_t *size, size_t *len)  int  _fetch_putln(int fd, const char *str, size_t len)  { -    struct iovec iov[2]; -    ssize_t wlen; - -    /* XXX should enforce timeout */ -    iov[0].iov_base = (char *)str; -    iov[0].iov_len = len; -    iov[1].iov_base = (char *)ENDL; -    iov[1].iov_len = sizeof ENDL; -    len += sizeof ENDL; -    wlen = writev(fd, iov, 2); -    if (wlen < 0 || (size_t)wlen != len) -	return -1; -    DEBUG(fprintf(stderr, ">>> %s\n", str)); -    return 0; +	struct iovec iov[2]; +	ssize_t wlen; + +	/* XXX should enforce timeout */ +	iov[0].iov_base = (char *)str; +	iov[0].iov_len = len; +	iov[1].iov_base = (char *)ENDL; +	iov[1].iov_len = sizeof ENDL; +	len += sizeof ENDL; +	wlen = writev(fd, iov, 2); +	if (wlen < 0 || (size_t)wlen != len) +		return (-1); +	DEBUG(fprintf(stderr, ">>> %s\n", str)); +	return (0);  } @@ -357,39 +354,39 @@ _fetch_putln(int fd, const char *str, size_t len)  int  _fetch_add_entry(struct url_ent **p, int *size, int *len, -		 const char *name, struct url_stat *us) +    const char *name, struct url_stat *us)  { -    struct url_ent *tmp; +	struct url_ent *tmp; -    if (*p == NULL) { +	if (*p == NULL) {  #define INITIAL_SIZE 8 -	if ((*p = malloc(INITIAL_SIZE * sizeof **p)) == NULL) { -	    errno = ENOMEM; -	    _fetch_syserr(); -	    return -1; -	} -	*size = INITIAL_SIZE; -	*len = 0; +		if ((*p = malloc(INITIAL_SIZE * sizeof **p)) == NULL) { +			errno = ENOMEM; +			_fetch_syserr(); +			return (-1); +		} +		*size = INITIAL_SIZE; +		*len = 0;  #undef INITIAL_SIZE -    } -     -    if (*len >= *size - 1) { -	tmp = realloc(*p, *size * 2 * sizeof **p); -	if (tmp == NULL) { -	    errno = ENOMEM; -	    _fetch_syserr(); -	    return -1;  	} -	*size *= 2; -	*p = tmp; -    } -    tmp = *p + *len; -    snprintf(tmp->name, PATH_MAX, "%s", name); -    bcopy(us, &tmp->stat, sizeof *us); +	if (*len >= *size - 1) { +		tmp = realloc(*p, *size * 2 * sizeof **p); +		if (tmp == NULL) { +			errno = ENOMEM; +			_fetch_syserr(); +			return (-1); +		} +		*size *= 2; +		*p = tmp; +	} + +	tmp = *p + *len; +	snprintf(tmp->name, PATH_MAX, "%s", name); +	bcopy(us, &tmp->stat, sizeof *us); -    (*len)++; -    (++tmp)->name[0] = 0; +	(*len)++; +	(++tmp)->name[0] = 0; -    return 0; +	return (0);  } diff --git a/lib/libfetch/common.h b/lib/libfetch/common.h index 84b2e01478e7..7d93d9668e94 100644 --- a/lib/libfetch/common.h +++ b/lib/libfetch/common.h @@ -38,8 +38,9 @@  /* Structure used for error message lists */  struct fetcherr {   -    const int num, cat; -    const char *string; +	const int	 num; +	const int	 cat; +	const char	*string;  };  void		 _fetch_seterr(struct fetcherr *, int); @@ -51,7 +52,7 @@ int		 _fetch_connect(const char *, int, int, int);  int		 _fetch_getln(int, char **, size_t *, size_t *);  int		 _fetch_putln(int, const char *, size_t);  int		 _fetch_add_entry(struct url_ent **, int *, int *, -				  const char *, struct url_stat *); +		     const char *, struct url_stat *);  #define _ftp_seterr(n)	 _fetch_seterr(_ftp_errlist, n)  #define _http_seterr(n)	 _fetch_seterr(_http_errlist, n) @@ -74,11 +75,9 @@ int		 _fetch_add_entry(struct url_ent **, int *, int *,   * whole lot of trouble.   */  FILE		*_http_request(struct url *, const char *, -			       struct url_stat *, struct url *, -			       const char *); +		     struct url_stat *, struct url *, const char *);  FILE		*_ftp_request(struct url *, const char *, -			      struct url_stat *, struct url *, -			      const char *); +		     struct url_stat *, struct url *, const char *);  /*   * Check whether a particular flag is set diff --git a/lib/libfetch/fetch.c b/lib/libfetch/fetch.c index 66b6fe08b6df..33b978771104 100644 --- a/lib/libfetch/fetch.c +++ b/lib/libfetch/fetch.c @@ -57,10 +57,10 @@ int	 fetchDebug;  #define URL_BAD_SCHEME		2  #define URL_BAD_PORT		3  static struct fetcherr _url_errlist[] = { -    { URL_MALFORMED,	FETCH_URL,	"Malformed URL" }, -    { URL_BAD_SCHEME,	FETCH_URL,	"Invalid URL scheme" }, -    { URL_BAD_PORT,	FETCH_URL,	"Invalid server port" }, -    { -1,		FETCH_UNKNOWN,	"Unknown parser error" } +	{ URL_MALFORMED,	FETCH_URL,	"Malformed URL" }, +	{ URL_BAD_SCHEME,	FETCH_URL,	"Invalid URL scheme" }, +	{ URL_BAD_PORT,		FETCH_URL,	"Invalid server port" }, +	{ -1,			FETCH_UNKNOWN,	"Unknown parser error" }  }; @@ -74,19 +74,19 @@ static struct fetcherr _url_errlist[] = {  FILE *  fetchXGet(struct url *URL, struct url_stat *us, const char *flags)  { -    int direct; - -    direct = CHECK_FLAG('d'); -    if (strcasecmp(URL->scheme, SCHEME_FILE) == 0) -	return fetchXGetFile(URL, us, flags); -    else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0) -	return fetchXGetHTTP(URL, us, flags); -    else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) { -	return fetchXGetFTP(URL, us, flags); -    } else { -	_url_seterr(URL_BAD_SCHEME); -	return NULL; -    } +	int direct; + +	direct = CHECK_FLAG('d'); +	if (strcasecmp(URL->scheme, SCHEME_FILE) == 0) +		return (fetchXGetFile(URL, us, flags)); +	else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0) +		return (fetchXGetHTTP(URL, us, flags)); +	else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) { +		return (fetchXGetFTP(URL, us, flags)); +	} else { +		_url_seterr(URL_BAD_SCHEME); +		return (NULL); +	}  }  /* @@ -96,7 +96,7 @@ fetchXGet(struct url *URL, struct url_stat *us, const char *flags)  FILE *  fetchGet(struct url *URL, const char *flags)  { -    return fetchXGet(URL, NULL, flags); +	return (fetchXGet(URL, NULL, flags));  }  /* @@ -106,19 +106,19 @@ fetchGet(struct url *URL, const char *flags)  FILE *  fetchPut(struct url *URL, const char *flags)  { -    int direct; - -    direct = CHECK_FLAG('d'); -    if (strcasecmp(URL->scheme, SCHEME_FILE) == 0) -	return fetchPutFile(URL, flags); -    else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0) -	return fetchPutHTTP(URL, flags); -    else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) { -	return fetchPutFTP(URL, flags); -    } else { -	_url_seterr(URL_BAD_SCHEME); -	return NULL; -    } +	int direct; + +	direct = CHECK_FLAG('d'); +	if (strcasecmp(URL->scheme, SCHEME_FILE) == 0) +		return (fetchPutFile(URL, flags)); +	else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0) +		return (fetchPutHTTP(URL, flags)); +	else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) { +		return (fetchPutFTP(URL, flags)); +	} else { +		_url_seterr(URL_BAD_SCHEME); +		return (NULL); +	}  }  /* @@ -128,19 +128,17 @@ fetchPut(struct url *URL, const char *flags)  int  fetchStat(struct url *URL, struct url_stat *us, const char *flags)  { -    int direct; - -    direct = CHECK_FLAG('d'); -    if (strcasecmp(URL->scheme, SCHEME_FILE) == 0) -	return fetchStatFile(URL, us, flags); -    else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0) -	return fetchStatHTTP(URL, us, flags); -    else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) { -	return fetchStatFTP(URL, us, flags); -    } else { +	int direct; + +	direct = CHECK_FLAG('d'); +	if (strcasecmp(URL->scheme, SCHEME_FILE) == 0) +		return (fetchStatFile(URL, us, flags)); +	else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0) +		return (fetchStatHTTP(URL, us, flags)); +	else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) +		return (fetchStatFTP(URL, us, flags));  	_url_seterr(URL_BAD_SCHEME); -	return -1; -    } +	return (-1);  }  /* @@ -150,19 +148,17 @@ fetchStat(struct url *URL, struct url_stat *us, const char *flags)  struct url_ent *  fetchList(struct url *URL, const char *flags)  { -    int direct; - -    direct = CHECK_FLAG('d'); -    if (strcasecmp(URL->scheme, SCHEME_FILE) == 0) -	return fetchListFile(URL, flags); -    else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0) -	return fetchListHTTP(URL, flags); -    else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) { -	return fetchListFTP(URL, flags); -    } else { +	int direct; + +	direct = CHECK_FLAG('d'); +	if (strcasecmp(URL->scheme, SCHEME_FILE) == 0) +		return (fetchListFile(URL, flags)); +	else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0) +		return (fetchListHTTP(URL, flags)); +	else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) +		return (fetchListFTP(URL, flags));  	_url_seterr(URL_BAD_SCHEME); -	return NULL; -    } +	return (NULL);  }  /* @@ -171,16 +167,16 @@ fetchList(struct url *URL, const char *flags)  FILE *  fetchXGetURL(const char *URL, struct url_stat *us, const char *flags)  { -    struct url *u; -    FILE *f; - -    if ((u = fetchParseURL(URL)) == NULL) -	return NULL; -     -    f = fetchXGet(u, us, flags); -     -    fetchFreeURL(u); -    return f; +	struct url *u; +	FILE *f; + +	if ((u = fetchParseURL(URL)) == NULL) +		return (NULL); + +	f = fetchXGet(u, us, flags); + +	fetchFreeURL(u); +	return (f);  }  /* @@ -189,7 +185,7 @@ fetchXGetURL(const char *URL, struct url_stat *us, const char *flags)  FILE *  fetchGetURL(const char *URL, const char *flags)  { -    return fetchXGetURL(URL, NULL, flags); +	return (fetchXGetURL(URL, NULL, flags));  }  /* @@ -198,16 +194,16 @@ fetchGetURL(const char *URL, const char *flags)  FILE *  fetchPutURL(const char *URL, const char *flags)  { -    struct url *u; -    FILE *f; -     -    if ((u = fetchParseURL(URL)) == NULL) -	return NULL; -     -    f = fetchPut(u, flags); -     -    fetchFreeURL(u); -    return f; +	struct url *u; +	FILE *f; + +	if ((u = fetchParseURL(URL)) == NULL) +		return (NULL); + +	f = fetchPut(u, flags); + +	fetchFreeURL(u); +	return (f);  }  /* @@ -216,16 +212,16 @@ fetchPutURL(const char *URL, const char *flags)  int  fetchStatURL(const char *URL, struct url_stat *us, const char *flags)  { -    struct url *u; -    int s; +	struct url *u; +	int s; -    if ((u = fetchParseURL(URL)) == NULL) -	return -1; +	if ((u = fetchParseURL(URL)) == NULL) +		return (-1); -    s = fetchStat(u, us, flags); +	s = fetchStat(u, us, flags); -    fetchFreeURL(u); -    return s; +	fetchFreeURL(u); +	return (s);  }  /* @@ -234,16 +230,16 @@ fetchStatURL(const char *URL, struct url_stat *us, const char *flags)  struct url_ent *  fetchListURL(const char *URL, const char *flags)  { -    struct url *u; -    struct url_ent *ue; +	struct url *u; +	struct url_ent *ue; -    if ((u = fetchParseURL(URL)) == NULL) -	return NULL; +	if ((u = fetchParseURL(URL)) == NULL) +		return (NULL); -    ue = fetchList(u, flags); +	ue = fetchList(u, flags); -    fetchFreeURL(u); -    return ue; +	fetchFreeURL(u); +	return (ue);  }  /* @@ -253,39 +249,39 @@ struct url *  fetchMakeURL(const char *scheme, const char *host, int port, const char *doc,      const char *user, const char *pwd)  { -    struct url *u; - -    if (!scheme || (!host && !doc)) { -	_url_seterr(URL_MALFORMED); -	return NULL; -    } -	 -    if (port < 0 || port > 65535) { -	_url_seterr(URL_BAD_PORT); -	return NULL; -    } -     -    /* allocate struct url */ -    if ((u = calloc(1, sizeof *u)) == NULL) { -	_fetch_syserr(); -	return NULL; -    } - -    if ((u->doc = strdup(doc ? doc : "/")) == NULL) { -	_fetch_syserr(); -	free(u); -	return NULL; -    } -     +	struct url *u; + +	if (!scheme || (!host && !doc)) { +		_url_seterr(URL_MALFORMED); +		return (NULL); +	} + +	if (port < 0 || port > 65535) { +		_url_seterr(URL_BAD_PORT); +		return (NULL); +	} + +	/* allocate struct url */ +	if ((u = calloc(1, sizeof *u)) == NULL) { +		_fetch_syserr(); +		return (NULL); +	} + +	if ((u->doc = strdup(doc ? doc : "/")) == NULL) { +		_fetch_syserr(); +		free(u); +		return (NULL); +	} +  #define seturl(x) snprintf(u->x, sizeof u->x, "%s", x) -    seturl(scheme); -    seturl(host); -    seturl(user); -    seturl(pwd); +	seturl(scheme); +	seturl(host); +	seturl(user); +	seturl(pwd);  #undef seturl -    u->port = port; +	u->port = port; -    return u; +	return (u);  }  /* @@ -296,112 +292,113 @@ fetchMakeURL(const char *scheme, const char *host, int port, const char *doc,  struct url *  fetchParseURL(const char *URL)  { -    char *doc; -    const char *p, *q; -    struct url *u; -    int i; - -    /* allocate struct url */ -    if ((u = calloc(1, sizeof *u)) == NULL) { -	_fetch_syserr(); -	return NULL; -    } - -    /* scheme name */ -    if ((p = strstr(URL, ":/"))) { -	snprintf(u->scheme, URL_SCHEMELEN+1, "%.*s", (int)(p - URL), URL); -	URL = ++p; -	/* -	 * Only one slash: no host, leave slash as part of document -	 * Two slashes: host follows, strip slashes -	 */ -	if (URL[1] == '/') -	    URL = (p += 2); -    } else { -	p = URL; -    } -    if (!*URL || *URL == '/' || *URL == '.' || -	(u->scheme[0] == '\0' && -    	    strchr(URL, '/') == NULL && strchr(URL, ':') == NULL)) -	goto nohost; - -    p = strpbrk(URL, "/@"); -    if (p && *p == '@') { -	/* username */ -	for (q = URL, i = 0; (*q != ':') && (*q != '@'); q++) -	    if (i < URL_USERLEN) -		u->user[i++] = *q; -	 -	/* password */ -	if (*q == ':') -	    for (q++, i = 0; (*q != ':') && (*q != '@'); q++) -		if (i < URL_PWDLEN) -		    u->pwd[i++] = *q; -	 -	p++; -    } else { -	p = URL; -    } - -    /* hostname */ +	char *doc; +	const char *p, *q; +	struct url *u; +	int i; + +	/* allocate struct url */ +	if ((u = calloc(1, sizeof *u)) == NULL) { +		_fetch_syserr(); +		return (NULL); +	} + +	/* scheme name */ +	if ((p = strstr(URL, ":/"))) { +		snprintf(u->scheme, URL_SCHEMELEN+1, +		    "%.*s", (int)(p - URL), URL); +		URL = ++p; +		/* +		 * Only one slash: no host, leave slash as part of document +		 * Two slashes: host follows, strip slashes +		 */ +		if (URL[1] == '/') +			URL = (p += 2); +	} else { +		p = URL; +	} +	if (!*URL || *URL == '/' || *URL == '.' || +	    (u->scheme[0] == '\0' && +		strchr(URL, '/') == NULL && strchr(URL, ':') == NULL)) +		goto nohost; + +	p = strpbrk(URL, "/@"); +	if (p && *p == '@') { +		/* username */ +		for (q = URL, i = 0; (*q != ':') && (*q != '@'); q++) +			if (i < URL_USERLEN) +				u->user[i++] = *q; + +		/* password */ +		if (*q == ':') +			for (q++, i = 0; (*q != ':') && (*q != '@'); q++) +				if (i < URL_PWDLEN) +					u->pwd[i++] = *q; + +		p++; +	} else { +		p = URL; +	} + +	/* hostname */  #ifdef INET6 -    if (*p == '[' && (q = strchr(p + 1, ']')) != NULL && -	(*++q == '\0' || *q == '/' || *q == ':')) { -	if ((i = q - p - 2) > MAXHOSTNAMELEN) -	    i = MAXHOSTNAMELEN; -	strncpy(u->host, ++p, i); -	p = q; -    } else +	if (*p == '[' && (q = strchr(p + 1, ']')) != NULL && +	    (*++q == '\0' || *q == '/' || *q == ':')) { +		if ((i = q - p - 2) > MAXHOSTNAMELEN) +			i = MAXHOSTNAMELEN; +		strncpy(u->host, ++p, i); +		p = q; +	} else  #endif -	for (i = 0; *p && (*p != '/') && (*p != ':'); p++) -	    if (i < MAXHOSTNAMELEN) -		u->host[i++] = *p; - -    /* port */ -    if (*p == ':') { -	for (q = ++p; *q && (*q != '/'); q++) -	    if (isdigit(*q)) -		u->port = u->port * 10 + (*q - '0'); -	    else { -		/* invalid port */ -		_url_seterr(URL_BAD_PORT); -		goto ouch; -	    } -	p = q; -    } +		for (i = 0; *p && (*p != '/') && (*p != ':'); p++) +			if (i < MAXHOSTNAMELEN) +				u->host[i++] = *p; + +	/* port */ +	if (*p == ':') { +		for (q = ++p; *q && (*q != '/'); q++) +			if (isdigit(*q)) +				u->port = u->port * 10 + (*q - '0'); +			else { +				/* invalid port */ +				_url_seterr(URL_BAD_PORT); +				goto ouch; +			} +		p = q; +	}  nohost: -    /* document */ -    if (!*p) -	p = "/"; -     -    if (strcasecmp(u->scheme, SCHEME_HTTP) == 0 || -	strcasecmp(u->scheme, SCHEME_HTTPS) == 0) { -	const char hexnums[] = "0123456789abcdef"; - -	/* percent-escape whitespace. */ -	if ((doc = malloc(strlen(p) * 3 + 1)) == NULL) { -	    _fetch_syserr(); -	    goto ouch; -	} -	u->doc = doc; -	while (*p != '\0') { -	    if (!isspace(*p)) { -		*doc++ = *p++; -            } else { -		*doc++ = '%'; -		*doc++ = hexnums[((unsigned int)*p) >> 4]; -		*doc++ = hexnums[((unsigned int)*p) & 0xf]; -		p++; -            } +	/* document */ +	if (!*p) +		p = "/"; + +	if (strcasecmp(u->scheme, SCHEME_HTTP) == 0 || +	    strcasecmp(u->scheme, SCHEME_HTTPS) == 0) { +		const char hexnums[] = "0123456789abcdef"; + +		/* percent-escape whitespace. */ +		if ((doc = malloc(strlen(p) * 3 + 1)) == NULL) { +			_fetch_syserr(); +			goto ouch; +		} +		u->doc = doc; +		while (*p != '\0') { +			if (!isspace(*p)) { +				*doc++ = *p++; +			} else { +				*doc++ = '%'; +				*doc++ = hexnums[((unsigned int)*p) >> 4]; +				*doc++ = hexnums[((unsigned int)*p) & 0xf]; +				p++; +			} +		} +		*doc = '\0'; +	} else if ((u->doc = strdup(p)) == NULL) { +		_fetch_syserr(); +		goto ouch;  	} -	*doc = '\0'; -    } else if ((u->doc = strdup(p)) == NULL) { -	_fetch_syserr(); -	goto ouch; -    } -     -    DEBUG(fprintf(stderr, + +	DEBUG(fprintf(stderr,  		  "scheme:   [%s]\n"  		  "user:     [%s]\n"  		  "password: [%s]\n" @@ -410,12 +407,12 @@ nohost:  		  "document: [%s]\n",  		  u->scheme, u->user, u->pwd,  		  u->host, u->port, u->doc)); -     -    return u; + +	return (u);  ouch: -    free(u); -    return NULL; +	free(u); +	return (NULL);  }  /* @@ -424,6 +421,6 @@ ouch:  void  fetchFreeURL(struct url *u)  { -    free(u->doc); -    free(u); +	free(u->doc); +	free(u);  } diff --git a/lib/libfetch/fetch.h b/lib/libfetch/fetch.h index 3899ccac3cfe..36a1e9a2272c 100644 --- a/lib/libfetch/fetch.h +++ b/lib/libfetch/fetch.h @@ -38,25 +38,25 @@  #define URL_PWDLEN 256  struct url { -    char	 scheme[URL_SCHEMELEN+1]; -    char	 user[URL_USERLEN+1]; -    char	 pwd[URL_PWDLEN+1]; -    char	 host[MAXHOSTNAMELEN+1]; -    int		 port; -    char	*doc; -    off_t	 offset; -    size_t	 length; +	char		 scheme[URL_SCHEMELEN+1]; +	char		 user[URL_USERLEN+1]; +	char		 pwd[URL_PWDLEN+1]; +	char		 host[MAXHOSTNAMELEN+1]; +	int		 port; +	char		*doc; +	off_t		 offset; +	size_t		 length;  };  struct url_stat { -    off_t	 size; -    time_t	 atime; -    time_t	 mtime; +	off_t		 size; +	time_t		 atime; +	time_t		 mtime;  };  struct url_ent { -    char	 name[PATH_MAX]; -    struct url_stat stat; +	char		 name[PATH_MAX]; +	struct url_stat	 stat;  };  /* Recognized schemes */ @@ -121,22 +121,26 @@ struct url_ent	*fetchList(struct url *, const char *);  /* URL parsing */  struct url	*fetchMakeURL(const char *, const char *, int, -			const char *, const char *, const char *); +		     const char *, const char *, const char *);  struct url	*fetchParseURL(const char *);  void		 fetchFreeURL(struct url *);  /* Authentication */  typedef int (*auth_t)(struct url *); -extern auth_t	 fetchAuthMethod; +extern auth_t		 fetchAuthMethod;  /* Last error code */ -extern int	 fetchLastErrCode; +extern int		 fetchLastErrCode;  #define MAXERRSTRING 256 -extern char	 fetchLastErrString[MAXERRSTRING]; -extern int	 fetchTimeout; -extern int	 fetchRestartCalls; +extern char		 fetchLastErrString[MAXERRSTRING]; + +/* I/O timeout */ +extern int		 fetchTimeout; + +/* Restart interrupted syscalls */ +extern int		 fetchRestartCalls;  /* Extra verbosity */ -extern int	 fetchDebug; +extern int		 fetchDebug;  #endif diff --git a/lib/libfetch/file.c b/lib/libfetch/file.c index 73ff4d2bb1d3..085f23254e59 100644 --- a/lib/libfetch/file.c +++ b/lib/libfetch/file.c @@ -42,105 +42,105 @@ __FBSDID("$FreeBSD$");  FILE *  fetchXGetFile(struct url *u, struct url_stat *us, const char *flags)  { -    FILE *f; -     -    if (us && fetchStatFile(u, us, flags) == -1) -	return NULL; -     -    f = fopen(u->doc, "r"); -     -    if (f == NULL) -	_fetch_syserr(); - -    if (u->offset && fseeko(f, u->offset, SEEK_SET) == -1) { -	fclose(f); -	_fetch_syserr(); -    } -     -    return f; +	FILE *f; + +	if (us && fetchStatFile(u, us, flags) == -1) +		return (NULL); + +	f = fopen(u->doc, "r"); + +	if (f == NULL) +		_fetch_syserr(); + +	if (u->offset && fseeko(f, u->offset, SEEK_SET) == -1) { +		fclose(f); +		_fetch_syserr(); +	} + +	return (f);  }  FILE *  fetchGetFile(struct url *u, const char *flags)  { -    return fetchXGetFile(u, NULL, flags);     +	return (fetchXGetFile(u, NULL, flags));  }  FILE *  fetchPutFile(struct url *u, const char *flags)  { -    FILE *f; -     -    if (CHECK_FLAG('a')) -	f = fopen(u->doc, "a"); -    else -	f = fopen(u->doc, "w+"); -     -    if (f == NULL) -	_fetch_syserr(); -     -    if (u->offset && fseeko(f, u->offset, SEEK_SET) == -1) { -	fclose(f); -	_fetch_syserr(); -    } -     -    return f; +	FILE *f; + +	if (CHECK_FLAG('a')) +		f = fopen(u->doc, "a"); +	else +		f = fopen(u->doc, "w+"); + +	if (f == NULL) +		_fetch_syserr(); + +	if (u->offset && fseeko(f, u->offset, SEEK_SET) == -1) { +		fclose(f); +		_fetch_syserr(); +	} + +	return (f);  }  static int  _fetch_stat_file(const char *fn, struct url_stat *us)  { -    struct stat sb; - -    us->size = -1; -    us->atime = us->mtime = 0; -    if (stat(fn, &sb) == -1) { -	_fetch_syserr(); -	return -1; -    } -    us->size = sb.st_size; -    us->atime = sb.st_atime; -    us->mtime = sb.st_mtime; -    return 0; +	struct stat sb; + +	us->size = -1; +	us->atime = us->mtime = 0; +	if (stat(fn, &sb) == -1) { +		_fetch_syserr(); +		return (-1); +	} +	us->size = sb.st_size; +	us->atime = sb.st_atime; +	us->mtime = sb.st_mtime; +	return (0);  }  int  fetchStatFile(struct url *u, struct url_stat *us, const char *flags __unused)  { -    return _fetch_stat_file(u->doc, us); +	return (_fetch_stat_file(u->doc, us));  }  struct url_ent *  fetchListFile(struct url *u, const char *flags __unused)  { -    DIR *dir; -    struct dirent *de; -    struct url_stat us; -    struct url_ent *ue; -    int size, len; -    char fn[PATH_MAX], *p; -    int l; - -    if ((dir = opendir(u->doc)) == NULL) { -	_fetch_syserr(); -	return NULL; -    } - -    ue = NULL; -    strncpy(fn, u->doc, sizeof fn - 2); -    fn[sizeof fn - 2] = 0; -    strcat(fn, "/"); -    p = strchr(fn, 0); -    l = sizeof fn - strlen(fn) - 1; -     -    while ((de = readdir(dir)) != NULL) { -	strncpy(p, de->d_name, l - 1); -	p[l - 1] = 0; -	if (_fetch_stat_file(fn, &us) == -1) -	    /* should I return a partial result, or abort? */ -	    break; -	_fetch_add_entry(&ue, &size, &len, de->d_name, &us); -    } -     -    return ue; +	struct dirent *de; +	struct url_stat us; +	struct url_ent *ue; +	int size, len; +	char fn[PATH_MAX], *p; +	DIR *dir; +	int l; + +	if ((dir = opendir(u->doc)) == NULL) { +		_fetch_syserr(); +		return (NULL); +	} + +	ue = NULL; +	strncpy(fn, u->doc, sizeof fn - 2); +	fn[sizeof fn - 2] = 0; +	strcat(fn, "/"); +	p = strchr(fn, 0); +	l = sizeof fn - strlen(fn) - 1; + +	while ((de = readdir(dir)) != NULL) { +		strncpy(p, de->d_name, l - 1); +		p[l - 1] = 0; +		if (_fetch_stat_file(fn, &us) == -1) +			/* should I return a partial result, or abort? */ +			break; +		_fetch_add_entry(&ue, &size, &len, de->d_name, &us); +	} + +	return (ue);  } diff --git a/lib/libfetch/ftp.c b/lib/libfetch/ftp.c index 36e95c31cf7e..89452e803776 100644 --- a/lib/libfetch/ftp.c +++ b/lib/libfetch/ftp.c @@ -96,37 +96,40 @@ __FBSDID("$FreeBSD$");  #define FTP_PROTOCOL_ERROR		999  static struct url cached_host; -static int cached_socket; +static int	 cached_socket; -static char *last_reply; -static size_t lr_size, lr_length; -static int last_code; +static char	*last_reply; +static size_t	 lr_size; +static size_t	 lr_length; +static int	 last_code;  #define isftpreply(foo) (isdigit(foo[0]) && isdigit(foo[1]) \  			 && isdigit(foo[2]) \ -                         && (foo[3] == ' ' || foo[3] == '\0')) +			 && (foo[3] == ' ' || foo[3] == '\0'))  #define isftpinfo(foo) (isdigit(foo[0]) && isdigit(foo[1]) \  			&& isdigit(foo[2]) && foo[3] == '-') -/* translate IPv4 mapped IPv6 address to IPv4 address */ +/* + * Translate IPv4 mapped IPv6 address to IPv4 address + */  static void  unmappedaddr(struct sockaddr_in6 *sin6)  { -    struct sockaddr_in *sin4; -    u_int32_t addr; -    int port; - -    if (sin6->sin6_family != AF_INET6 || -	!IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) -	return; -    sin4 = (struct sockaddr_in *)sin6; -    addr = *(u_int32_t *)&sin6->sin6_addr.s6_addr[12]; -    port = sin6->sin6_port; -    memset(sin4, 0, sizeof(struct sockaddr_in)); -    sin4->sin_addr.s_addr = addr; -    sin4->sin_port = port; -    sin4->sin_family = AF_INET; -    sin4->sin_len = sizeof(struct sockaddr_in); +	struct sockaddr_in *sin4; +	u_int32_t addr; +	int port; + +	if (sin6->sin6_family != AF_INET6 || +	    !IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) +		return; +	sin4 = (struct sockaddr_in *)sin6; +	addr = *(u_int32_t *)&sin6->sin6_addr.s6_addr[12]; +	port = sin6->sin6_port; +	memset(sin4, 0, sizeof(struct sockaddr_in)); +	sin4->sin_addr.s_addr = addr; +	sin4->sin_port = port; +	sin4->sin_family = AF_INET; +	sin4->sin_len = sizeof(struct sockaddr_in);  }  /* @@ -135,33 +138,34 @@ unmappedaddr(struct sockaddr_in6 *sin6)  static int  _ftp_chkerr(int cd)  { -    if (_fetch_getln(cd, &last_reply, &lr_size, &lr_length) == -1) { -	_fetch_syserr(); -	return -1; -    } -    if (isftpinfo(last_reply)) { -	while (lr_length && !isftpreply(last_reply)) { -	    if (_fetch_getln(cd, &last_reply, &lr_size, &lr_length) == -1) { +	if (_fetch_getln(cd, &last_reply, &lr_size, &lr_length) == -1) {  		_fetch_syserr(); -		return -1; -	    } +		return (-1); +	} +	if (isftpinfo(last_reply)) { +		while (lr_length && !isftpreply(last_reply)) { +			if (_fetch_getln(cd, &last_reply, +			    &lr_size, &lr_length) == -1) { +				_fetch_syserr(); +				return (-1); +			} +		}  	} -    } - -    while (lr_length && isspace(last_reply[lr_length-1])) -	lr_length--; -    last_reply[lr_length] = 0; -     -    if (!isftpreply(last_reply)) { -	_ftp_seterr(FTP_PROTOCOL_ERROR); -	return -1; -    } - -    last_code = (last_reply[0] - '0') * 100 -	+ (last_reply[1] - '0') * 10 -	+ (last_reply[2] - '0'); - -    return last_code; + +	while (lr_length && isspace(last_reply[lr_length-1])) +		lr_length--; +	last_reply[lr_length] = 0; + +	if (!isftpreply(last_reply)) { +		_ftp_seterr(FTP_PROTOCOL_ERROR); +		return (-1); +	} + +	last_code = (last_reply[0] - '0') * 100 +	    + (last_reply[1] - '0') * 10 +	    + (last_reply[2] - '0'); + +	return (last_code);  }  /* @@ -170,30 +174,30 @@ _ftp_chkerr(int cd)  static int  _ftp_cmd(int cd, const char *fmt, ...)  { -    va_list ap; -    size_t len; -    char *msg; -    int r; - -    va_start(ap, fmt); -    len = vasprintf(&msg, fmt, ap); -    va_end(ap); -     -    if (msg == NULL) { -	errno = ENOMEM; -	_fetch_syserr(); -	return -1; -    } -     -    r = _fetch_putln(cd, msg, len); -    free(msg); -     -    if (r == -1) { -	_fetch_syserr(); -	return -1; -    } -     -    return _ftp_chkerr(cd); +	va_list ap; +	size_t len; +	char *msg; +	int r; + +	va_start(ap, fmt); +	len = vasprintf(&msg, fmt, ap); +	va_end(ap); + +	if (msg == NULL) { +		errno = ENOMEM; +		_fetch_syserr(); +		return (-1); +	} + +	r = _fetch_putln(cd, msg, len); +	free(msg); + +	if (r == -1) { +		_fetch_syserr(); +		return (-1); +	} + +	return (_ftp_chkerr(cd));  }  /* @@ -202,34 +206,34 @@ _ftp_cmd(int cd, const char *fmt, ...)  static const char *  _ftp_filename(const char *file)  { -    char *s; -     -    if ((s = strrchr(file, '/')) == NULL) -	return file; -    else -	return s + 1; +	char *s; + +	if ((s = strrchr(file, '/')) == NULL) +		return (file); +	else +		return (s + 1);  }  /* - * Change working directory to the directory that contains the - * specified file. + * Change working directory to the directory that contains the specified + * file.   */  static int  _ftp_cwd(int cd, const char *file)  { -    char *s; -    int e; - -    if ((s = strrchr(file, '/')) == NULL || s == file) { -	e = _ftp_cmd(cd, "CWD /"); -    } else { -	e = _ftp_cmd(cd, "CWD %.*s", s - file, file); -    } -    if (e != FTP_FILE_ACTION_OK) { -	_ftp_seterr(e); -	return -1; -    } -    return 0; +	char *s; +	int e; + +	if ((s = strrchr(file, '/')) == NULL || s == file) { +		e = _ftp_cmd(cd, "CWD /"); +	} else { +		e = _ftp_cmd(cd, "CWD %.*s", s - file, file); +	} +	if (e != FTP_FILE_ACTION_OK) { +		_ftp_seterr(e); +		return (-1); +	} +	return (0);  }  /* @@ -238,208 +242,209 @@ _ftp_cwd(int cd, const char *file)  static int  _ftp_stat(int cd, const char *file, struct url_stat *us)  { -    char *ln; -    const char *s; -    struct tm tm; -    time_t t; -    int e; - -    us->size = -1; -    us->atime = us->mtime = 0; -     -    if ((s = strrchr(file, '/')) == NULL) -	s = file; -    else -	++s; -     -    if ((e = _ftp_cmd(cd, "SIZE %s", s)) != FTP_FILE_STATUS) { -	_ftp_seterr(e); -	return -1; -    } -    for (ln = last_reply + 4; *ln && isspace(*ln); ln++) -	/* nothing */ ; -    for (us->size = 0; *ln && isdigit(*ln); ln++) -	us->size = us->size * 10 + *ln - '0'; -    if (*ln && !isspace(*ln)) { -	_ftp_seterr(FTP_PROTOCOL_ERROR); -	us->size = -1; -	return -1; -    } -    if (us->size == 0) +	char *ln; +	const char *s; +	struct tm tm; +	time_t t; +	int e; +  	us->size = -1; -    DEBUG(fprintf(stderr, "size: [%lld]\n", (long long)us->size)); - -    if ((e = _ftp_cmd(cd, "MDTM %s", s)) != FTP_FILE_STATUS) { -	_ftp_seterr(e); -	return -1; -    } -    for (ln = last_reply + 4; *ln && isspace(*ln); ln++) -	/* nothing */ ; -    switch (strspn(ln, "0123456789")) { -    case 14: -	break; -    case 15: -	ln++; -	ln[0] = '2'; -	ln[1] = '0'; -	break; -    default: -	_ftp_seterr(FTP_PROTOCOL_ERROR); -	return -1; -    } -    if (sscanf(ln, "%04d%02d%02d%02d%02d%02d", -	       &tm.tm_year, &tm.tm_mon, &tm.tm_mday, -	       &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { -	_ftp_seterr(FTP_PROTOCOL_ERROR); -	return -1; -    } -    tm.tm_mon--; -    tm.tm_year -= 1900; -    tm.tm_isdst = -1; -    t = timegm(&tm); -    if (t == (time_t)-1) -	t = time(NULL); -    us->mtime = t; -    us->atime = t; -    DEBUG(fprintf(stderr, "last modified: [%04d-%02d-%02d %02d:%02d:%02d]\n", -		  tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, -		  tm.tm_hour, tm.tm_min, tm.tm_sec)); -    return 0; +	us->atime = us->mtime = 0; + +	if ((s = strrchr(file, '/')) == NULL) +		s = file; +	else +		++s; + +	if ((e = _ftp_cmd(cd, "SIZE %s", s)) != FTP_FILE_STATUS) { +		_ftp_seterr(e); +		return (-1); +	} +	for (ln = last_reply + 4; *ln && isspace(*ln); ln++) +		/* nothing */ ; +	for (us->size = 0; *ln && isdigit(*ln); ln++) +		us->size = us->size * 10 + *ln - '0'; +	if (*ln && !isspace(*ln)) { +		_ftp_seterr(FTP_PROTOCOL_ERROR); +		us->size = -1; +		return (-1); +	} +	if (us->size == 0) +		us->size = -1; +	DEBUG(fprintf(stderr, "size: [%lld]\n", (long long)us->size)); + +	if ((e = _ftp_cmd(cd, "MDTM %s", s)) != FTP_FILE_STATUS) { +		_ftp_seterr(e); +		return (-1); +	} +	for (ln = last_reply + 4; *ln && isspace(*ln); ln++) +		/* nothing */ ; +	switch (strspn(ln, "0123456789")) { +	case 14: +		break; +	case 15: +		ln++; +		ln[0] = '2'; +		ln[1] = '0'; +		break; +	default: +		_ftp_seterr(FTP_PROTOCOL_ERROR); +		return (-1); +	} +	if (sscanf(ln, "%04d%02d%02d%02d%02d%02d", +	    &tm.tm_year, &tm.tm_mon, &tm.tm_mday, +	    &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { +		_ftp_seterr(FTP_PROTOCOL_ERROR); +		return (-1); +	} +	tm.tm_mon--; +	tm.tm_year -= 1900; +	tm.tm_isdst = -1; +	t = timegm(&tm); +	if (t == (time_t)-1) +		t = time(NULL); +	us->mtime = t; +	us->atime = t; +	DEBUG(fprintf(stderr, +	    "last modified: [%04d-%02d-%02d %02d:%02d:%02d]\n", +	    tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, +	    tm.tm_hour, tm.tm_min, tm.tm_sec)); +	return (0);  }  /*   * I/O functions for FTP   */  struct ftpio { -    int		 csd;		/* Control socket descriptor */ -    int		 dsd;		/* Data socket descriptor */ -    int		 dir;		/* Direction */ -    int		 eof;		/* EOF reached */ -    int		 err;		/* Error code */ +	int	 csd;		/* Control socket descriptor */ +	int	 dsd;		/* Data socket descriptor */ +	int	 dir;		/* Direction */ +	int	 eof;		/* EOF reached */ +	int	 err;		/* Error code */  }; -static int	_ftp_readfn(void *, char *, int); -static int	_ftp_writefn(void *, const char *, int); -static fpos_t	_ftp_seekfn(void *, fpos_t, int); -static int	_ftp_closefn(void *); +static int	 _ftp_readfn(void *, char *, int); +static int	 _ftp_writefn(void *, const char *, int); +static fpos_t	 _ftp_seekfn(void *, fpos_t, int); +static int	 _ftp_closefn(void *);  static int  _ftp_readfn(void *v, char *buf, int len)  { -    struct ftpio *io; -    int r; - -    io = (struct ftpio *)v; -    if (io == NULL) { -	errno = EBADF; -	return -1; -    } -    if (io->csd == -1 || io->dsd == -1 || io->dir == O_WRONLY) { -	errno = EBADF; -	return -1; -    } -    if (io->err) { -	errno = io->err; -	return -1; -    } -    if (io->eof) -	return 0; -    r = read(io->dsd, buf, len); -    if (r > 0) -	return r; -    if (r == 0) { -	io->eof = 1; -	return 0; -    } -    if (errno != EINTR) -	io->err = errno; -    return -1; +	struct ftpio *io; +	int r; + +	io = (struct ftpio *)v; +	if (io == NULL) { +		errno = EBADF; +		return (-1); +	} +	if (io->csd == -1 || io->dsd == -1 || io->dir == O_WRONLY) { +		errno = EBADF; +		return (-1); +	} +	if (io->err) { +		errno = io->err; +		return (-1); +	} +	if (io->eof) +		return (0); +	r = read(io->dsd, buf, len); +	if (r > 0) +		return (r); +	if (r == 0) { +		io->eof = 1; +		return (0); +	} +	if (errno != EINTR) +		io->err = errno; +	return (-1);  }  static int  _ftp_writefn(void *v, const char *buf, int len)  { -    struct ftpio *io; -    int w; -     -    io = (struct ftpio *)v; -    if (io == NULL) { -	errno = EBADF; -	return -1; -    } -    if (io->csd == -1 || io->dsd == -1 || io->dir == O_RDONLY) { -	errno = EBADF; -	return -1; -    } -    if (io->err) { -	errno = io->err; -	return -1; -    } -    w = write(io->dsd, buf, len); -    if (w >= 0) -	return w; -    if (errno != EINTR) -	io->err = errno; -    return -1; +	struct ftpio *io; +	int w; + +	io = (struct ftpio *)v; +	if (io == NULL) { +		errno = EBADF; +		return (-1); +	} +	if (io->csd == -1 || io->dsd == -1 || io->dir == O_RDONLY) { +		errno = EBADF; +		return (-1); +	} +	if (io->err) { +		errno = io->err; +		return (-1); +	} +	w = write(io->dsd, buf, len); +	if (w >= 0) +		return (w); +	if (errno != EINTR) +		io->err = errno; +	return (-1);  }  static fpos_t  _ftp_seekfn(void *v, fpos_t pos __unused, int whence __unused)  { -    struct ftpio *io; -     -    io = (struct ftpio *)v; -    if (io == NULL) { -	errno = EBADF; -	return -1; -    } -    errno = ESPIPE; -    return -1; +	struct ftpio *io; + +	io = (struct ftpio *)v; +	if (io == NULL) { +		errno = EBADF; +		return (-1); +	} +	errno = ESPIPE; +	return (-1);  }  static int  _ftp_closefn(void *v)  { -    struct ftpio *io; -    int r; - -    io = (struct ftpio *)v; -    if (io == NULL) { -	errno = EBADF; -	return -1; -    } -    if (io->dir == -1) -	return 0; -    if (io->csd == -1 || io->dsd == -1) { -	errno = EBADF; -	return -1; -    } -    close(io->dsd); -    io->dir = -1; -    io->dsd = -1; -    DEBUG(fprintf(stderr, "Waiting for final status\n")); -    r = _ftp_chkerr(io->csd); -    close(io->csd); -    free(io); -    return (r == FTP_TRANSFER_COMPLETE) ? 0 : -1; +	struct ftpio *io; +	int r; + +	io = (struct ftpio *)v; +	if (io == NULL) { +		errno = EBADF; +		return (-1); +	} +	if (io->dir == -1) +		return (0); +	if (io->csd == -1 || io->dsd == -1) { +		errno = EBADF; +		return (-1); +	} +	close(io->dsd); +	io->dir = -1; +	io->dsd = -1; +	DEBUG(fprintf(stderr, "Waiting for final status\n")); +	r = _ftp_chkerr(io->csd); +	close(io->csd); +	free(io); +	return (r == FTP_TRANSFER_COMPLETE) ? 0 : -1;  }  static FILE *  _ftp_setup(int csd, int dsd, int mode)  { -    struct ftpio *io; -    FILE *f; - -    if ((io = malloc(sizeof *io)) == NULL) -	return NULL; -    io->csd = dup(csd); -    io->dsd = dsd; -    io->dir = mode; -    io->eof = io->err = 0; -    f = funopen(io, _ftp_readfn, _ftp_writefn, _ftp_seekfn, _ftp_closefn); -    if (f == NULL) -	free(io); -    return f; +	struct ftpio *io; +	FILE *f; + +	if ((io = malloc(sizeof *io)) == NULL) +		return (NULL); +	io->csd = dup(csd); +	io->dsd = dsd; +	io->dir = mode; +	io->eof = io->err = 0; +	f = funopen(io, _ftp_readfn, _ftp_writefn, _ftp_seekfn, _ftp_closefn); +	if (f == NULL) +		free(io); +	return (f);  }  /* @@ -447,268 +452,268 @@ _ftp_setup(int csd, int dsd, int mode)   */  static FILE *  _ftp_transfer(int cd, const char *oper, const char *file, -	      int mode, off_t offset, const char *flags) +    int mode, off_t offset, const char *flags)  { -    struct sockaddr_storage sa; -    struct sockaddr_in6 *sin6; -    struct sockaddr_in *sin4; -    int low, pasv, verbose; -    int e, sd = -1; -    socklen_t l; -    char *s; -    FILE *df; - -    /* check flags */ -    low = CHECK_FLAG('l'); -    pasv = CHECK_FLAG('p'); -    verbose = CHECK_FLAG('v'); - -    /* passive mode */ -    if (!pasv) -	pasv = ((s = getenv("FTP_PASSIVE_MODE")) != NULL && -		strncasecmp(s, "no", 2) != 0); - -    /* find our own address, bind, and listen */ -    l = sizeof sa; -    if (getsockname(cd, (struct sockaddr *)&sa, &l) == -1) -	goto sysouch; -    if (sa.ss_family == AF_INET6) -	unmappedaddr((struct sockaddr_in6 *)&sa); - -    /* open data socket */ -    if ((sd = socket(sa.ss_family, SOCK_STREAM, IPPROTO_TCP)) == -1) { -	_fetch_syserr(); -	return NULL; -    } -     -    if (pasv) { -	u_char addr[64]; -	char *ln, *p; -	unsigned int i; -	int port; -	 -	/* send PASV command */ -	if (verbose) -	    _fetch_info("setting passive mode"); -	switch (sa.ss_family) { -	case AF_INET: -	    if ((e = _ftp_cmd(cd, "PASV")) != FTP_PASSIVE_MODE) -		goto ouch; -	    break; -	case AF_INET6: -	    if ((e = _ftp_cmd(cd, "EPSV")) != FTP_EPASSIVE_MODE) { -		if (e == -1) -		    goto ouch; -		if ((e = _ftp_cmd(cd, "LPSV")) != FTP_LPASSIVE_MODE) -		    goto ouch; -	    } -	    break; -	default: -	    e = FTP_PROTOCOL_ERROR; /* XXX: error code should be prepared */ -	    goto ouch; -	} - -	/* -	 * Find address and port number. The reply to the PASV command -         * is IMHO the one and only weak point in the FTP protocol. -	 */ -	ln = last_reply; -      	switch (e) { -	case FTP_PASSIVE_MODE: -	case FTP_LPASSIVE_MODE: -	    for (p = ln + 3; *p && !isdigit(*p); p++) -		/* nothing */ ; -	    if (!*p) { -		e = FTP_PROTOCOL_ERROR; -		goto ouch; -	    } -	    l = (e == FTP_PASSIVE_MODE ? 6 : 21); -	    for (i = 0; *p && i < l; i++, p++) -		addr[i] = strtol(p, &p, 10); -	    if (i < l) { -		e = FTP_PROTOCOL_ERROR; -		goto ouch; -	    } -	    break; -	case FTP_EPASSIVE_MODE: -	    for (p = ln + 3; *p && *p != '('; p++) -		/* nothing */ ; -	    if (!*p) { -		e = FTP_PROTOCOL_ERROR; -		goto ouch; -	    } -	    ++p; -	    if (sscanf(p, "%c%c%c%d%c", &addr[0], &addr[1], &addr[2], -		       &port, &addr[3]) != 5 || -		addr[0] != addr[1] || -		addr[0] != addr[2] || addr[0] != addr[3]) { -		e = FTP_PROTOCOL_ERROR; -		goto ouch; -	    } -	    break; -	} - -	/* seek to required offset */ -	if (offset) -	    if (_ftp_cmd(cd, "REST %lu", (u_long)offset) != FTP_FILE_OK) -		goto sysouch; -	 -	/* construct sockaddr for data socket */ +	struct sockaddr_storage sa; +	struct sockaddr_in6 *sin6; +	struct sockaddr_in *sin4; +	int low, pasv, verbose; +	int e, sd = -1; +	socklen_t l; +	char *s; +	FILE *df; + +	/* check flags */ +	low = CHECK_FLAG('l'); +	pasv = CHECK_FLAG('p'); +	verbose = CHECK_FLAG('v'); + +	/* passive mode */ +	if (!pasv) +		pasv = ((s = getenv("FTP_PASSIVE_MODE")) != NULL && +		    strncasecmp(s, "no", 2) != 0); + +	/* find our own address, bind, and listen */  	l = sizeof sa; -	if (getpeername(cd, (struct sockaddr *)&sa, &l) == -1) -	    goto sysouch; +	if (getsockname(cd, (struct sockaddr *)&sa, &l) == -1) +		goto sysouch;  	if (sa.ss_family == AF_INET6) -	    unmappedaddr((struct sockaddr_in6 *)&sa); -	switch (sa.ss_family) { -	case AF_INET6: -	    sin6 = (struct sockaddr_in6 *)&sa; -	    if (e == FTP_EPASSIVE_MODE) -		sin6->sin6_port = htons(port); -	    else { -		bcopy(addr + 2, (char *)&sin6->sin6_addr, 16); -		bcopy(addr + 19, (char *)&sin6->sin6_port, 2); -	    } -	    break; -	case AF_INET: -	    sin4 = (struct sockaddr_in *)&sa; -	    if (e == FTP_EPASSIVE_MODE) -		sin4->sin_port = htons(port); -	    else { -		bcopy(addr, (char *)&sin4->sin_addr, 4); -		bcopy(addr + 4, (char *)&sin4->sin_port, 2); -	    } -	    break; -	default: -	    e = FTP_PROTOCOL_ERROR; /* XXX: error code should be prepared */ -	    break; +		unmappedaddr((struct sockaddr_in6 *)&sa); + +	/* open data socket */ +	if ((sd = socket(sa.ss_family, SOCK_STREAM, IPPROTO_TCP)) == -1) { +		_fetch_syserr(); +		return (NULL);  	} -	/* connect to data port */ -	if (verbose) -	    _fetch_info("opening data connection"); -	if (connect(sd, (struct sockaddr *)&sa, sa.ss_len) == -1) -	    goto sysouch; - -	/* make the server initiate the transfer */ -	if (verbose) -	    _fetch_info("initiating transfer"); -	e = _ftp_cmd(cd, "%s %s", oper, _ftp_filename(file)); -	if (e != FTP_CONNECTION_ALREADY_OPEN && e != FTP_OPEN_DATA_CONNECTION) -	    goto ouch; -	 -    } else { -	u_int32_t a; -	u_short p; -	int arg, d; -	char *ap; -	char hname[INET6_ADDRSTRLEN]; -	 -	switch (sa.ss_family) { -	case AF_INET6: -	    ((struct sockaddr_in6 *)&sa)->sin6_port = 0; +	if (pasv) { +		u_char addr[64]; +		char *ln, *p; +		unsigned int i; +		int port; + +		/* send PASV command */ +		if (verbose) +			_fetch_info("setting passive mode"); +		switch (sa.ss_family) { +		case AF_INET: +			if ((e = _ftp_cmd(cd, "PASV")) != FTP_PASSIVE_MODE) +				goto ouch; +			break; +		case AF_INET6: +			if ((e = _ftp_cmd(cd, "EPSV")) != FTP_EPASSIVE_MODE) { +				if (e == -1) +					goto ouch; +				if ((e = _ftp_cmd(cd, "LPSV")) != FTP_LPASSIVE_MODE) +					goto ouch; +			} +			break; +		default: +			e = FTP_PROTOCOL_ERROR; /* XXX: error code should be prepared */ +			goto ouch; +		} + +		/* +		 * Find address and port number. The reply to the PASV command +		 * is IMHO the one and only weak point in the FTP protocol. +		 */ +		ln = last_reply; +		switch (e) { +		case FTP_PASSIVE_MODE: +		case FTP_LPASSIVE_MODE: +			for (p = ln + 3; *p && !isdigit(*p); p++) +				/* nothing */ ; +			if (!*p) { +				e = FTP_PROTOCOL_ERROR; +				goto ouch; +			} +			l = (e == FTP_PASSIVE_MODE ? 6 : 21); +			for (i = 0; *p && i < l; i++, p++) +				addr[i] = strtol(p, &p, 10); +			if (i < l) { +				e = FTP_PROTOCOL_ERROR; +				goto ouch; +			} +			break; +		case FTP_EPASSIVE_MODE: +			for (p = ln + 3; *p && *p != '('; p++) +				/* nothing */ ; +			if (!*p) { +				e = FTP_PROTOCOL_ERROR; +				goto ouch; +			} +			++p; +			if (sscanf(p, "%c%c%c%d%c", &addr[0], &addr[1], &addr[2], +				&port, &addr[3]) != 5 || +			    addr[0] != addr[1] || +			    addr[0] != addr[2] || addr[0] != addr[3]) { +				e = FTP_PROTOCOL_ERROR; +				goto ouch; +			} +			break; +		} + +		/* seek to required offset */ +		if (offset) +			if (_ftp_cmd(cd, "REST %lu", (u_long)offset) != FTP_FILE_OK) +				goto sysouch; + +		/* construct sockaddr for data socket */ +		l = sizeof sa; +		if (getpeername(cd, (struct sockaddr *)&sa, &l) == -1) +			goto sysouch; +		if (sa.ss_family == AF_INET6) +			unmappedaddr((struct sockaddr_in6 *)&sa); +		switch (sa.ss_family) { +		case AF_INET6: +			sin6 = (struct sockaddr_in6 *)&sa; +			if (e == FTP_EPASSIVE_MODE) +				sin6->sin6_port = htons(port); +			else { +				bcopy(addr + 2, (char *)&sin6->sin6_addr, 16); +				bcopy(addr + 19, (char *)&sin6->sin6_port, 2); +			} +			break; +		case AF_INET: +			sin4 = (struct sockaddr_in *)&sa; +			if (e == FTP_EPASSIVE_MODE) +				sin4->sin_port = htons(port); +			else { +				bcopy(addr, (char *)&sin4->sin_addr, 4); +				bcopy(addr + 4, (char *)&sin4->sin_port, 2); +			} +			break; +		default: +			e = FTP_PROTOCOL_ERROR; /* XXX: error code should be prepared */ +			break; +		} + +		/* connect to data port */ +		if (verbose) +			_fetch_info("opening data connection"); +		if (connect(sd, (struct sockaddr *)&sa, sa.ss_len) == -1) +			goto sysouch; + +		/* make the server initiate the transfer */ +		if (verbose) +			_fetch_info("initiating transfer"); +		e = _ftp_cmd(cd, "%s %s", oper, _ftp_filename(file)); +		if (e != FTP_CONNECTION_ALREADY_OPEN && e != FTP_OPEN_DATA_CONNECTION) +			goto ouch; + +	} else { +		u_int32_t a; +		u_short p; +		int arg, d; +		char *ap; +		char hname[INET6_ADDRSTRLEN]; + +		switch (sa.ss_family) { +		case AF_INET6: +			((struct sockaddr_in6 *)&sa)->sin6_port = 0;  #ifdef IPV6_PORTRANGE -	    arg = low ? IPV6_PORTRANGE_DEFAULT : IPV6_PORTRANGE_HIGH; -	    if (setsockopt(sd, IPPROTO_IPV6, IPV6_PORTRANGE, -			   (char *)&arg, sizeof(arg)) == -1) -		goto sysouch; +			arg = low ? IPV6_PORTRANGE_DEFAULT : IPV6_PORTRANGE_HIGH; +			if (setsockopt(sd, IPPROTO_IPV6, IPV6_PORTRANGE, +				(char *)&arg, sizeof(arg)) == -1) +				goto sysouch;  #endif -	    break; -	case AF_INET: -	    ((struct sockaddr_in *)&sa)->sin_port = 0; -	    arg = low ? IP_PORTRANGE_DEFAULT : IP_PORTRANGE_HIGH; -	    if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE, -			   (char *)&arg, sizeof arg) == -1) -		goto sysouch; -	    break; -	} -	if (verbose) -	    _fetch_info("binding data socket"); -	if (bind(sd, (struct sockaddr *)&sa, sa.ss_len) == -1) -	    goto sysouch; -	if (listen(sd, 1) == -1) -	    goto sysouch; - -	/* find what port we're on and tell the server */ -	if (getsockname(sd, (struct sockaddr *)&sa, &l) == -1) -	    goto sysouch; -	switch (sa.ss_family) { -	case AF_INET: -	    sin4 = (struct sockaddr_in *)&sa; -	    a = ntohl(sin4->sin_addr.s_addr); -	    p = ntohs(sin4->sin_port); -	    e = _ftp_cmd(cd, "PORT %d,%d,%d,%d,%d,%d", -			 (a >> 24) & 0xff, (a >> 16) & 0xff, -			 (a >> 8) & 0xff, a & 0xff, -			 (p >> 8) & 0xff, p & 0xff); -	    break; -	case AF_INET6: +			break; +		case AF_INET: +			((struct sockaddr_in *)&sa)->sin_port = 0; +			arg = low ? IP_PORTRANGE_DEFAULT : IP_PORTRANGE_HIGH; +			if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE, +				(char *)&arg, sizeof arg) == -1) +				goto sysouch; +			break; +		} +		if (verbose) +			_fetch_info("binding data socket"); +		if (bind(sd, (struct sockaddr *)&sa, sa.ss_len) == -1) +			goto sysouch; +		if (listen(sd, 1) == -1) +			goto sysouch; + +		/* find what port we're on and tell the server */ +		if (getsockname(sd, (struct sockaddr *)&sa, &l) == -1) +			goto sysouch; +		switch (sa.ss_family) { +		case AF_INET: +			sin4 = (struct sockaddr_in *)&sa; +			a = ntohl(sin4->sin_addr.s_addr); +			p = ntohs(sin4->sin_port); +			e = _ftp_cmd(cd, "PORT %d,%d,%d,%d,%d,%d", +			    (a >> 24) & 0xff, (a >> 16) & 0xff, +			    (a >> 8) & 0xff, a & 0xff, +			    (p >> 8) & 0xff, p & 0xff); +			break; +		case AF_INET6:  #define UC(b)	(((int)b)&0xff) -	    e = -1; -	    sin6 = (struct sockaddr_in6 *)&sa; -	    if (getnameinfo((struct sockaddr *)&sa, sa.ss_len, -			    hname, sizeof(hname), -			    NULL, 0, NI_NUMERICHOST) == 0) { -		e = _ftp_cmd(cd, "EPRT |%d|%s|%d|", 2, hname, -			     htons(sin6->sin6_port)); -		if (e == -1) -		    goto ouch; -	    } -	    if (e != FTP_OK) { -		ap = (char *)&sin6->sin6_addr; -		e = _ftp_cmd(cd, -     "LPRT %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", -			     6, 16, -			     UC(ap[0]), UC(ap[1]), UC(ap[2]), UC(ap[3]), -			     UC(ap[4]), UC(ap[5]), UC(ap[6]), UC(ap[7]), -			     UC(ap[8]), UC(ap[9]), UC(ap[10]), UC(ap[11]), -			     UC(ap[12]), UC(ap[13]), UC(ap[14]), UC(ap[15]), -			     2, -			     (ntohs(sin6->sin6_port) >> 8) & 0xff, -			     ntohs(sin6->sin6_port)        & 0xff); -	    } -	    break; -	default: -	    e = FTP_PROTOCOL_ERROR; /* XXX: error code should be prepared */ -	    goto ouch; +			e = -1; +			sin6 = (struct sockaddr_in6 *)&sa; +			if (getnameinfo((struct sockaddr *)&sa, sa.ss_len, +				hname, sizeof(hname), +				NULL, 0, NI_NUMERICHOST) == 0) { +				e = _ftp_cmd(cd, "EPRT |%d|%s|%d|", 2, hname, +				    htons(sin6->sin6_port)); +				if (e == -1) +					goto ouch; +			} +			if (e != FTP_OK) { +				ap = (char *)&sin6->sin6_addr; +				e = _ftp_cmd(cd, +				    "LPRT %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", +				    6, 16, +				    UC(ap[0]), UC(ap[1]), UC(ap[2]), UC(ap[3]), +				    UC(ap[4]), UC(ap[5]), UC(ap[6]), UC(ap[7]), +				    UC(ap[8]), UC(ap[9]), UC(ap[10]), UC(ap[11]), +				    UC(ap[12]), UC(ap[13]), UC(ap[14]), UC(ap[15]), +				    2, +				    (ntohs(sin6->sin6_port) >> 8) & 0xff, +				    ntohs(sin6->sin6_port)        & 0xff); +			} +			break; +		default: +			e = FTP_PROTOCOL_ERROR; /* XXX: error code should be prepared */ +			goto ouch; +		} +		if (e != FTP_OK) +			goto ouch; + +		/* seek to required offset */ +		if (offset) +			if (_ftp_cmd(cd, "REST %lu", (u_long)offset) != FTP_FILE_OK) +				goto sysouch; + +		/* make the server initiate the transfer */ +		if (verbose) +			_fetch_info("initiating transfer"); +		e = _ftp_cmd(cd, "%s %s", oper, _ftp_filename(file)); +		if (e != FTP_OPEN_DATA_CONNECTION) +			goto ouch; + +		/* accept the incoming connection and go to town */ +		if ((d = accept(sd, NULL, NULL)) == -1) +			goto sysouch; +		close(sd); +		sd = d;  	} -	if (e != FTP_OK) -	    goto ouch; -	/* seek to required offset */ -	if (offset) -	    if (_ftp_cmd(cd, "REST %lu", (u_long)offset) != FTP_FILE_OK) +	if ((df = _ftp_setup(cd, sd, mode)) == NULL)  		goto sysouch; -	 -	/* make the server initiate the transfer */ -	if (verbose) -	    _fetch_info("initiating transfer"); -	e = _ftp_cmd(cd, "%s %s", oper, _ftp_filename(file)); -	if (e != FTP_OPEN_DATA_CONNECTION) -	    goto ouch; -	 -	/* accept the incoming connection and go to town */ -	if ((d = accept(sd, NULL, NULL)) == -1) -	    goto sysouch; -	close(sd); -	sd = d; -    } - -    if ((df = _ftp_setup(cd, sd, mode)) == NULL) -	goto sysouch; -    return df; +	return (df);  sysouch: -    _fetch_syserr(); -    if (sd >= 0) -	close(sd); -    return NULL; +	_fetch_syserr(); +	if (sd >= 0) +		close(sd); +	return (NULL);  ouch: -    if (e != -1) -	_ftp_seterr(e); -    if (sd >= 0) -	close(sd); -    return NULL; +	if (e != -1) +		_ftp_seterr(e); +	if (sd >= 0) +		close(sd); +	return (NULL);  }  /* @@ -717,44 +722,44 @@ ouch:  static int  _ftp_authenticate(int cd, struct url *url, struct url *purl)  { -    const char *user, *pwd, *logname; -    char pbuf[MAXHOSTNAMELEN + MAXLOGNAME + 1]; -    int e, len; - -    /* XXX FTP_AUTH, and maybe .netrc */ -     -    /* send user name and password */ -    user = url->user; -    if (!user || !*user) -	user = getenv("FTP_LOGIN"); -    if (!user || !*user) -	user = FTP_ANONYMOUS_USER; -    if (purl && url->port == _fetch_default_port(url->scheme)) -	e = _ftp_cmd(cd, "USER %s@%s", user, url->host); -    else if (purl) -	e = _ftp_cmd(cd, "USER %s@%s@%d", user, url->host, url->port); -    else -	e = _ftp_cmd(cd, "USER %s", user); -     -    /* did the server request a password? */ -    if (e == FTP_NEED_PASSWORD) { -	pwd = url->pwd; -	if (!pwd || !*pwd) -	    pwd = getenv("FTP_PASSWORD"); -	if (!pwd || !*pwd) { -	    if ((logname = getlogin()) == 0) -		logname = FTP_ANONYMOUS_USER; -	    if ((len = snprintf(pbuf, MAXLOGNAME + 1, "%s@", logname)) < 0) -		len = 0; -	    else if (len > MAXLOGNAME) -	        len = MAXLOGNAME; -	    gethostname(pbuf + len, sizeof pbuf - len); -	    pwd = pbuf; +	const char *user, *pwd, *logname; +	char pbuf[MAXHOSTNAMELEN + MAXLOGNAME + 1]; +	int e, len; + +	/* XXX FTP_AUTH, and maybe .netrc */ + +	/* send user name and password */ +	user = url->user; +	if (!user || !*user) +		user = getenv("FTP_LOGIN"); +	if (!user || !*user) +		user = FTP_ANONYMOUS_USER; +	if (purl && url->port == _fetch_default_port(url->scheme)) +		e = _ftp_cmd(cd, "USER %s@%s", user, url->host); +	else if (purl) +		e = _ftp_cmd(cd, "USER %s@%s@%d", user, url->host, url->port); +	else +		e = _ftp_cmd(cd, "USER %s", user); + +	/* did the server request a password? */ +	if (e == FTP_NEED_PASSWORD) { +		pwd = url->pwd; +		if (!pwd || !*pwd) +			pwd = getenv("FTP_PASSWORD"); +		if (!pwd || !*pwd) { +			if ((logname = getlogin()) == 0) +				logname = FTP_ANONYMOUS_USER; +			if ((len = snprintf(pbuf, MAXLOGNAME + 1, "%s@", logname)) < 0) +				len = 0; +			else if (len > MAXLOGNAME) +				len = MAXLOGNAME; +			gethostname(pbuf + len, sizeof pbuf - len); +			pwd = pbuf; +		} +		e = _ftp_cmd(cd, "PASS %s", pwd);  	} -	e = _ftp_cmd(cd, "PASS %s", pwd); -    } -     -    return e; + +	return (e);  }  /* @@ -763,63 +768,63 @@ _ftp_authenticate(int cd, struct url *url, struct url *purl)  static int  _ftp_connect(struct url *url, struct url *purl, const char *flags)  { -    int cd, e, direct, verbose; +	int cd, e, direct, verbose;  #ifdef INET6 -    int af = AF_UNSPEC; +	int af = AF_UNSPEC;  #else -    int af = AF_INET; +	int af = AF_INET;  #endif -    direct = CHECK_FLAG('d'); -    verbose = CHECK_FLAG('v'); -    if (CHECK_FLAG('4')) -	af = AF_INET; -    else if (CHECK_FLAG('6')) -	af = AF_INET6; - -    if (direct) -	purl = NULL; -     -    /* check for proxy */ -    if (purl) { -	/* XXX proxy authentication! */ -	cd = _fetch_connect(purl->host, purl->port, af, verbose); -    } else { -	/* no proxy, go straight to target */ -	cd = _fetch_connect(url->host, url->port, af, verbose); -	purl = NULL; -    } - -    /* check connection */ -    if (cd == -1) { -	_fetch_syserr(); -	return NULL; -    } - -    /* expect welcome message */ -    if ((e = _ftp_chkerr(cd)) != FTP_SERVICE_READY) -	goto fouch; -     -    /* authenticate */ -    if ((e = _ftp_authenticate(cd, url, purl)) != FTP_LOGGED_IN) -	goto fouch; -     -    /* might as well select mode and type at once */ +	direct = CHECK_FLAG('d'); +	verbose = CHECK_FLAG('v'); +	if (CHECK_FLAG('4')) +		af = AF_INET; +	else if (CHECK_FLAG('6')) +		af = AF_INET6; + +	if (direct) +		purl = NULL; + +	/* check for proxy */ +	if (purl) { +		/* XXX proxy authentication! */ +		cd = _fetch_connect(purl->host, purl->port, af, verbose); +	} else { +		/* no proxy, go straight to target */ +		cd = _fetch_connect(url->host, url->port, af, verbose); +		purl = NULL; +	} + +	/* check connection */ +	if (cd == -1) { +		_fetch_syserr(); +		return (NULL); +	} + +	/* expect welcome message */ +	if ((e = _ftp_chkerr(cd)) != FTP_SERVICE_READY) +		goto fouch; + +	/* authenticate */ +	if ((e = _ftp_authenticate(cd, url, purl)) != FTP_LOGGED_IN) +		goto fouch; + +	/* might as well select mode and type at once */  #ifdef FTP_FORCE_STREAM_MODE -    if ((e = _ftp_cmd(cd, "MODE S")) != FTP_OK) /* default is S */ -	goto fouch; +	if ((e = _ftp_cmd(cd, "MODE S")) != FTP_OK) /* default is S */ +		goto fouch;  #endif -    if ((e = _ftp_cmd(cd, "TYPE I")) != FTP_OK) /* default is A */ -	goto fouch; +	if ((e = _ftp_cmd(cd, "TYPE I")) != FTP_OK) /* default is A */ +		goto fouch; + +	/* done */ +	return (cd); -    /* done */ -    return cd; -      fouch: -    if (e != -1) -	_ftp_seterr(e); -    close(cd); -    return NULL; +	if (e != -1) +		_ftp_seterr(e); +	close(cd); +	return (NULL);  }  /* @@ -828,8 +833,8 @@ fouch:  static void  _ftp_disconnect(int cd)  { -    (void)_ftp_cmd(cd, "QUIT"); -    close(cd); +	(void)_ftp_cmd(cd, "QUIT"); +	close(cd);  }  /* @@ -838,7 +843,7 @@ _ftp_disconnect(int cd)  static int  _ftp_isconnected(struct url *url)  { -    return (cached_socket +	return (cached_socket  	    && (strcmp(url->host, cached_host.host) == 0)  	    && (strcmp(url->user, cached_host.user) == 0)  	    && (strcmp(url->pwd, cached_host.pwd) == 0) @@ -851,29 +856,29 @@ _ftp_isconnected(struct url *url)  static int  _ftp_cached_connect(struct url *url, struct url *purl, const char *flags)  { -    int e, cd; - -    cd = -1; -     -    /* set default port */ -    if (!url->port) -	url->port = _fetch_default_port(url->scheme); -     -    /* try to use previously cached connection */ -    if (_ftp_isconnected(url)) { -	e = _ftp_cmd(cached_socket, "NOOP"); -	if (e == FTP_OK || e == FTP_SYNTAX_ERROR) -	    return cached_socket; -    } - -    /* connect to server */ -    if ((cd = _ftp_connect(url, purl, flags)) == -1) -	return -1; -    if (cached_socket) -	_ftp_disconnect(cached_socket); -    cached_socket = cd; -    memcpy(&cached_host, url, sizeof *url); -    return cd; +	int e, cd; + +	cd = -1; + +	/* set default port */ +	if (!url->port) +		url->port = _fetch_default_port(url->scheme); + +	/* try to use previously cached connection */ +	if (_ftp_isconnected(url)) { +		e = _ftp_cmd(cached_socket, "NOOP"); +		if (e == FTP_OK || e == FTP_SYNTAX_ERROR) +			return (cached_socket); +	} + +	/* connect to server */ +	if ((cd = _ftp_connect(url, purl, flags)) == -1) +		return (-1); +	if (cached_socket) +		_ftp_disconnect(cached_socket); +	cached_socket = cd; +	memcpy(&cached_host, url, sizeof *url); +	return (cd);  }  /* @@ -882,26 +887,26 @@ _ftp_cached_connect(struct url *url, struct url *purl, const char *flags)  static struct url *  _ftp_get_proxy(void)  { -    struct url *purl; -    char *p; -     -    if (((p = getenv("FTP_PROXY")) || (p = getenv("ftp_proxy")) || -	 (p = getenv("HTTP_PROXY")) || (p = getenv("http_proxy"))) && -	*p && (purl = fetchParseURL(p)) != NULL) { -	if (!*purl->scheme) { -	    if (getenv("FTP_PROXY") || getenv("ftp_proxy")) -		strcpy(purl->scheme, SCHEME_FTP); -	    else -		strcpy(purl->scheme, SCHEME_HTTP); +	struct url *purl; +	char *p; + +	if (((p = getenv("FTP_PROXY")) || (p = getenv("ftp_proxy")) || +		(p = getenv("HTTP_PROXY")) || (p = getenv("http_proxy"))) && +	    *p && (purl = fetchParseURL(p)) != NULL) { +		if (!*purl->scheme) { +			if (getenv("FTP_PROXY") || getenv("ftp_proxy")) +				strcpy(purl->scheme, SCHEME_FTP); +			else +				strcpy(purl->scheme, SCHEME_HTTP); +		} +		if (!purl->port) +			purl->port = _fetch_default_proxy_port(purl->scheme); +		if (strcasecmp(purl->scheme, SCHEME_FTP) == 0 || +		    strcasecmp(purl->scheme, SCHEME_HTTP) == 0) +			return (purl); +		fetchFreeURL(purl);  	} -	if (!purl->port) -	    purl->port = _fetch_default_proxy_port(purl->scheme); -	if (strcasecmp(purl->scheme, SCHEME_FTP) == 0 || -	    strcasecmp(purl->scheme, SCHEME_HTTP) == 0) -	    return purl; -	fetchFreeURL(purl); -    } -    return NULL; +	return (NULL);  }  /* @@ -909,49 +914,49 @@ _ftp_get_proxy(void)   */  FILE *  _ftp_request(struct url *url, const char *op, struct url_stat *us, -	     struct url *purl, const char *flags) +    struct url *purl, const char *flags)  { -    int cd, oflag; -     -    /* check if we should use HTTP instead */ -    if (purl && strcasecmp(purl->scheme, SCHEME_HTTP) == 0) { +	int cd, oflag; + +	/* check if we should use HTTP instead */ +	if (purl && strcasecmp(purl->scheme, SCHEME_HTTP) == 0) { +		if (strcmp(op, "STAT") == 0) +			return (_http_request(url, "HEAD", us, purl, flags)); +		else if (strcmp(op, "RETR") == 0) +			return (_http_request(url, "GET", us, purl, flags)); +		/* +		 * Our HTTP code doesn't support PUT requests yet, so try +		 * a direct connection. +		 */ +	} + +	/* connect to server */ +	cd = _ftp_cached_connect(url, purl, flags); +	if (purl) +		fetchFreeURL(purl); +	if (cd == NULL) +		return (NULL); + +	/* change directory */ +	if (_ftp_cwd(cd, url->doc) == -1) +		return (NULL); + +	/* stat file */ +	if (us && _ftp_stat(cd, url->doc, us) == -1 +	    && fetchLastErrCode != FETCH_PROTO +	    && fetchLastErrCode != FETCH_UNAVAIL) +		return (NULL); + +	/* just a stat */  	if (strcmp(op, "STAT") == 0) -	    return _http_request(url, "HEAD", us, purl, flags); -	else if (strcmp(op, "RETR") == 0) -	    return _http_request(url, "GET", us, purl, flags); -	/* -	 * Our HTTP code doesn't support PUT requests yet, so try a -	 * direct connection. -	 */ -    } - -    /* connect to server */ -    cd = _ftp_cached_connect(url, purl, flags); -    if (purl) -	fetchFreeURL(purl); -    if (cd == NULL) -	return NULL; -     -    /* change directory */ -    if (_ftp_cwd(cd, url->doc) == -1) -	return NULL; -     -    /* stat file */ -    if (us && _ftp_stat(cd, url->doc, us) == -1 -	&& fetchLastErrCode != FETCH_PROTO -	&& fetchLastErrCode != FETCH_UNAVAIL) -	return NULL; - -    /* just a stat */ -    if (strcmp(op, "STAT") == 0) -	return (FILE *)1; /* bogus return value */ -    if (strcmp(op, "STOR") == 0 || strcmp(op, "APPE") == 0) -	oflag = O_WRONLY; -    else -	oflag = O_RDONLY; -     -    /* initiate the transfer */ -    return _ftp_transfer(cd, op, url->doc, oflag, url->offset, flags); +		return (FILE *)1; /* bogus return value */ +	if (strcmp(op, "STOR") == 0 || strcmp(op, "APPE") == 0) +		oflag = O_WRONLY; +	else +		oflag = O_RDONLY; + +	/* initiate the transfer */ +	return (_ftp_transfer(cd, op, url->doc, oflag, url->offset, flags));  }  /* @@ -960,7 +965,7 @@ _ftp_request(struct url *url, const char *op, struct url_stat *us,  FILE *  fetchXGetFTP(struct url *url, struct url_stat *us, const char *flags)  { -    return _ftp_request(url, "RETR", us, _ftp_get_proxy(), flags); +	return (_ftp_request(url, "RETR", us, _ftp_get_proxy(), flags));  }  /* @@ -969,7 +974,7 @@ fetchXGetFTP(struct url *url, struct url_stat *us, const char *flags)  FILE *  fetchGetFTP(struct url *url, const char *flags)  { -    return fetchXGetFTP(url, NULL, flags); +	return (fetchXGetFTP(url, NULL, flags));  }  /* @@ -979,8 +984,8 @@ FILE *  fetchPutFTP(struct url *url, const char *flags)  { -    return _ftp_request(url, CHECK_FLAG('a') ? "APPE" : "STOR", NULL, -			_ftp_get_proxy(), flags); +	return _ftp_request(url, CHECK_FLAG('a') ? "APPE" : "STOR", NULL, +	    _ftp_get_proxy(), flags);  }  /* @@ -989,10 +994,10 @@ fetchPutFTP(struct url *url, const char *flags)  int  fetchStatFTP(struct url *url, struct url_stat *us, const char *flags)  { -     -    if (_ftp_request(url, "STAT", us, _ftp_get_proxy(), flags) == NULL) -	return -1; -    return 0; + +	if (_ftp_request(url, "STAT", us, _ftp_get_proxy(), flags) == NULL) +		return (-1); +	return (0);  }  /* @@ -1001,6 +1006,6 @@ fetchStatFTP(struct url *url, struct url_stat *us, const char *flags)  struct url_ent *  fetchListFTP(struct url *url __unused, const char *flags __unused)  { -    warnx("fetchListFTP(): not implemented"); -    return NULL; +	warnx("fetchListFTP(): not implemented"); +	return (NULL);  } diff --git a/lib/libfetch/http.c b/lib/libfetch/http.c index 04b7964612fe..eed12f2022e8 100644 --- a/lib/libfetch/http.c +++ b/lib/libfetch/http.c @@ -46,7 +46,7 @@ __FBSDID("$FreeBSD$");   * no representations about the suitability of this software for any   * purpose.  It is provided "as is" without express or implied   * warranty. - *  + *   * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS   * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF @@ -80,7 +80,7 @@ __FBSDID("$FreeBSD$");  #include "common.h"  #include "httperr.h" -extern char *__progname; /* XXX not portable */ +extern char	*__progname; /* XXX not portable */  /* Maximum number of redirects to follow */  #define MAX_REDIRECT 5 @@ -96,28 +96,28 @@ extern char *__progname; /* XXX not portable */  #define HTTP_PROTOCOL_ERROR	999  #define HTTP_REDIRECT(xyz) ((xyz) == HTTP_MOVED_PERM \ -                            || (xyz) == HTTP_MOVED_TEMP \ -                            || (xyz) == HTTP_SEE_OTHER) +			    || (xyz) == HTTP_MOVED_TEMP \ +			    || (xyz) == HTTP_SEE_OTHER)  #define HTTP_ERROR(xyz) ((xyz) > 400 && (xyz) < 599) - +  /*****************************************************************************   * I/O functions for decoding chunked streams   */  struct cookie  { -    int		 fd; -    char	*buf; -    size_t	 b_size; -    ssize_t	 b_len; -    int		 b_pos; -    int		 eof; -    int		 error; -    size_t	 chunksize; +	int		 fd; +	char		*buf; +	size_t		 b_size; +	ssize_t		 b_len; +	int		 b_pos; +	int		 eof; +	int		 error; +	size_t		 chunksize;  #ifndef NDEBUG -    size_t	 total; +	size_t		 total;  #endif  }; @@ -127,36 +127,42 @@ struct cookie  static int  _http_new_chunk(struct cookie *c)  { -    char *p; -     -    if (_fetch_getln(c->fd, &c->buf, &c->b_size, &c->b_len) == -1) -	return -1; -     -    if (c->b_len < 2 || !ishexnumber(*c->buf)) -	return -1; -     -    for (p = c->buf; !isspace(*p) && *p != ';' && p < c->buf + c->b_len; ++p) -	if (!ishexnumber(*p)) -	    return -1; -	else if (isdigit(*p)) -	    c->chunksize = c->chunksize * 16 + *p - '0'; -	else -	    c->chunksize = c->chunksize * 16 + 10 + tolower(*p) - 'a'; -     +	char *p; + +	if (_fetch_getln(c->fd, &c->buf, &c->b_size, &c->b_len) == -1) +		return (-1); + +	if (c->b_len < 2 || !ishexnumber(*c->buf)) +		return (-1); + +	for (p = c->buf; !isspace(*p) && p < c->buf + c->b_len; ++p) { +		if (*p == ';') +			break; +		if (!ishexnumber(*p)) +			return (-1); +		if (isdigit(*p)) { +			c->chunksize = c->chunksize * 16 + +			    *p - '0'; +		} else { +			c->chunksize = c->chunksize * 16 + +			    10 + tolower(*p) - 'a'; +		} +	} +  #ifndef NDEBUG -    if (fetchDebug) { -	c->total += c->chunksize; -	if (c->chunksize == 0) -	    fprintf(stderr, "_http_fillbuf(): " -		    "end of last chunk\n"); -	else -	    fprintf(stderr, "_http_fillbuf(): " -		    "new chunk: %lu (%lu)\n", -		    (unsigned long)c->chunksize, (unsigned long)c->total); -    } +	if (fetchDebug) { +		c->total += c->chunksize; +		if (c->chunksize == 0) +			fprintf(stderr, "_http_fillbuf(): " +			    "end of last chunk\n"); +		else +			fprintf(stderr, "_http_fillbuf(): " +			    "new chunk: %lu (%lu)\n", +			    (unsigned long)c->chunksize, (unsigned long)c->total); +	}  #endif -     -    return c->chunksize; + +	return (c->chunksize);  }  /* @@ -165,45 +171,45 @@ _http_new_chunk(struct cookie *c)  static int  _http_fillbuf(struct cookie *c)  { -    if (c->error) -	return -1; -    if (c->eof) -	return 0; -     -    if (c->chunksize == 0) { -	switch (_http_new_chunk(c)) { -	case -1: -	    c->error = 1; -	    return -1; -	case 0: -	    c->eof = 1; -	    return 0; +	if (c->error) +		return (-1); +	if (c->eof) +		return (0); + +	if (c->chunksize == 0) { +		switch (_http_new_chunk(c)) { +		case -1: +			c->error = 1; +			return (-1); +		case 0: +			c->eof = 1; +			return (0); +		}  	} -    } - -    if (c->b_size < c->chunksize) { -	char *tmp; - -	if ((tmp = realloc(c->buf, c->chunksize)) == NULL) -	    return -1; -	c->buf = tmp; -	c->b_size = c->chunksize; -    } -     -    if ((c->b_len = read(c->fd, c->buf, c->chunksize)) == -1) -	return -1; -    c->chunksize -= c->b_len; -     -    if (c->chunksize == 0) { -	char endl; -	if (read(c->fd, &endl, 1) == -1 || -	    read(c->fd, &endl, 1) == -1) -	    return -1; -    } -     -    c->b_pos = 0; -     -    return c->b_len; + +	if (c->b_size < c->chunksize) { +		char *tmp; + +		if ((tmp = realloc(c->buf, c->chunksize)) == NULL) +			return (-1); +		c->buf = tmp; +		c->b_size = c->chunksize; +	} + +	if ((c->b_len = read(c->fd, c->buf, c->chunksize)) == -1) +		return (-1); +	c->chunksize -= c->b_len; + +	if (c->chunksize == 0) { +		char endl; +		if (read(c->fd, &endl, 1) == -1 || +		    read(c->fd, &endl, 1) == -1) +			return (-1); +	} + +	c->b_pos = 0; + +	return (c->b_len);  }  /* @@ -212,29 +218,29 @@ _http_fillbuf(struct cookie *c)  static int  _http_readfn(void *v, char *buf, int len)  { -    struct cookie *c = (struct cookie *)v; -    int l, pos; - -    if (c->error) -	return -1; -    if (c->eof) -	return 0; - -    for (pos = 0; len > 0; pos += l, len -= l) { -	/* empty buffer */ -	if (!c->buf || c->b_pos == c->b_len) -	    if (_http_fillbuf(c) < 1) -		break; -	l = c->b_len - c->b_pos; -	if (len < l) -	    l = len; -	bcopy(c->buf + c->b_pos, buf + pos, l); -	c->b_pos += l; -    } - -    if (!pos && c->error) -	return -1; -    return pos; +	struct cookie *c = (struct cookie *)v; +	int l, pos; + +	if (c->error) +		return (-1); +	if (c->eof) +		return (0); + +	for (pos = 0; len > 0; pos += l, len -= l) { +		/* empty buffer */ +		if (!c->buf || c->b_pos == c->b_len) +			if (_http_fillbuf(c) < 1) +				break; +		l = c->b_len - c->b_pos; +		if (len < l) +			l = len; +		bcopy(c->buf + c->b_pos, buf + pos, l); +		c->b_pos += l; +	} + +	if (!pos && c->error) +		return (-1); +	return (pos);  }  /* @@ -243,9 +249,9 @@ _http_readfn(void *v, char *buf, int len)  static int  _http_writefn(void *v, const char *buf, int len)  { -    struct cookie *c = (struct cookie *)v; -     -    return write(c->fd, buf, len); +	struct cookie *c = (struct cookie *)v; + +	return (write(c->fd, buf, len));  }  /* @@ -254,14 +260,14 @@ _http_writefn(void *v, const char *buf, int len)  static int  _http_closefn(void *v)  { -    struct cookie *c = (struct cookie *)v; -    int r; - -    r = close(c->fd); -    if (c->buf) -	free(c->buf); -    free(c); -    return r; +	struct cookie *c = (struct cookie *)v; +	int r; + +	r = close(c->fd); +	if (c->buf) +		free(c->buf); +	free(c); +	return (r);  }  /* @@ -270,58 +276,59 @@ _http_closefn(void *v)  static FILE *  _http_funopen(int fd)  { -    struct cookie *c; -    FILE *f; - -    if ((c = calloc(1, sizeof *c)) == NULL) { -	_fetch_syserr(); -	return NULL; -    } -    c->fd = fd; -    if (!(f = funopen(c, _http_readfn, _http_writefn, NULL, _http_closefn))) { -	_fetch_syserr(); -	free(c); -	return NULL; -    } -    return f; +	struct cookie *c; +	FILE *f; + +	if ((c = calloc(1, sizeof *c)) == NULL) { +		_fetch_syserr(); +		return (NULL); +	} +	c->fd = fd; +	f = funopen(c, _http_readfn, _http_writefn, NULL, _http_closefn); +	if (f == NULL) { +		_fetch_syserr(); +		free(c); +		return (NULL); +	} +	return (f);  } - +  /*****************************************************************************   * Helper functions for talking to the server and parsing its replies   */  /* Header types */  typedef enum { -    hdr_syserror = -2, -    hdr_error = -1, -    hdr_end = 0, -    hdr_unknown = 1, -    hdr_content_length, -    hdr_content_range, -    hdr_last_modified, -    hdr_location, -    hdr_transfer_encoding, -    hdr_www_authenticate +	hdr_syserror = -2, +	hdr_error = -1, +	hdr_end = 0, +	hdr_unknown = 1, +	hdr_content_length, +	hdr_content_range, +	hdr_last_modified, +	hdr_location, +	hdr_transfer_encoding, +	hdr_www_authenticate  } hdr_t;  /* Names of interesting headers */  static struct { -    hdr_t	 num; -    const char	*name; +	hdr_t		 num; +	const char	*name;  } hdr_names[] = { -    { hdr_content_length,	"Content-Length" }, -    { hdr_content_range,	"Content-Range" }, -    { hdr_last_modified,	"Last-Modified" }, -    { hdr_location,		"Location" }, -    { hdr_transfer_encoding,	"Transfer-Encoding" }, -    { hdr_www_authenticate,	"WWW-Authenticate" }, -    { hdr_unknown,		NULL }, +	{ hdr_content_length,		"Content-Length" }, +	{ hdr_content_range,		"Content-Range" }, +	{ hdr_last_modified,		"Last-Modified" }, +	{ hdr_location,			"Location" }, +	{ hdr_transfer_encoding,	"Transfer-Encoding" }, +	{ hdr_www_authenticate,		"WWW-Authenticate" }, +	{ hdr_unknown,			NULL },  }; -static char	*reply_buf; -static size_t	 reply_size; -static size_t	 reply_length; +static char		*reply_buf; +static size_t		 reply_size; +static size_t		 reply_length;  /*   * Send a formatted line; optionally echo to terminal @@ -329,30 +336,30 @@ static size_t	 reply_length;  static int  _http_cmd(int fd, const char *fmt, ...)  { -    va_list ap; -    size_t len; -    char *msg; -    int r; - -    va_start(ap, fmt); -    len = vasprintf(&msg, fmt, ap); -    va_end(ap); -     -    if (msg == NULL) { -	errno = ENOMEM; -	_fetch_syserr(); -	return -1; -    } -     -    r = _fetch_putln(fd, msg, len); -    free(msg); -     -    if (r == -1) { -	_fetch_syserr(); -	return -1; -    } -     -    return 0; +	va_list ap; +	size_t len; +	char *msg; +	int r; + +	va_start(ap, fmt); +	len = vasprintf(&msg, fmt, ap); +	va_end(ap); + +	if (msg == NULL) { +		errno = ENOMEM; +		_fetch_syserr(); +		return (-1); +	} + +	r = _fetch_putln(fd, msg, len); +	free(msg); + +	if (r == -1) { +		_fetch_syserr(); +		return (-1); +	} + +	return (0);  }  /* @@ -361,50 +368,47 @@ _http_cmd(int fd, const char *fmt, ...)  static int  _http_get_reply(int fd)  { -    char *p; -     -    if (_fetch_getln(fd, &reply_buf, &reply_size, &reply_length) == -1) -	return -1; -    /* -     * A valid status line looks like "HTTP/m.n xyz reason" where m -     * and n are the major and minor protocol version numbers and xyz -     * is the reply code. -     * Unfortunately, there are servers out there (NCSA 1.5.1, to name -     * just one) that do not send a version number, so we can't rely -     * on finding one, but if we do, insist on it being 1.0 or 1.1. -     * We don't care about the reason phrase. -     */ -    if (strncmp(reply_buf, "HTTP", 4) != 0) -	return HTTP_PROTOCOL_ERROR; -    p = reply_buf + 4; -    if (*p == '/') { -	if (p[1] != '1' || p[2] != '.' || (p[3] != '0' && p[3] != '1')) -	    return HTTP_PROTOCOL_ERROR; -	p += 4; -    } -    if (*p != ' '	 -	|| !isdigit(p[1]) -	|| !isdigit(p[2]) -	|| !isdigit(p[3])) -	return HTTP_PROTOCOL_ERROR; -     -    return ((p[1] - '0') * 100 + (p[2] - '0') * 10 + (p[3] - '0')); +	char *p; + +	if (_fetch_getln(fd, &reply_buf, &reply_size, &reply_length) == -1) +		return (-1); +	/* +	 * A valid status line looks like "HTTP/m.n xyz reason" where m +	 * and n are the major and minor protocol version numbers and xyz +	 * is the reply code. +	 * Unfortunately, there are servers out there (NCSA 1.5.1, to name +	 * just one) that do not send a version number, so we can't rely +	 * on finding one, but if we do, insist on it being 1.0 or 1.1. +	 * We don't care about the reason phrase. +	 */ +	if (strncmp(reply_buf, "HTTP", 4) != 0) +		return (HTTP_PROTOCOL_ERROR); +	p = reply_buf + 4; +	if (*p == '/') { +		if (p[1] != '1' || p[2] != '.' || (p[3] != '0' && p[3] != '1')) +			return (HTTP_PROTOCOL_ERROR); +		p += 4; +	} +	if (*p != ' ' || !isdigit(p[1]) || !isdigit(p[2]) || !isdigit(p[3])) +		return (HTTP_PROTOCOL_ERROR); + +	return ((p[1] - '0') * 100 + (p[2] - '0') * 10 + (p[3] - '0'));  }  /* - * Check a header; if the type matches the given string, return a - * pointer to the beginning of the value. + * Check a header; if the type matches the given string, return a pointer + * to the beginning of the value.   */  static const char *  _http_match(const char *str, const char *hdr)  { -    while (*str && *hdr && tolower(*str++) == tolower(*hdr++)) -	/* nothing */; -    if (*str || *hdr != ':') -	return NULL; -    while (*hdr && isspace(*++hdr)) -	/* nothing */; -    return hdr; +	while (*str && *hdr && tolower(*str++) == tolower(*hdr++)) +		/* nothing */; +	if (*str || *hdr != ':') +		return (NULL); +	while (*hdr && isspace(*++hdr)) +		/* nothing */; +	return (hdr);  }  /* @@ -413,25 +417,25 @@ _http_match(const char *str, const char *hdr)  static hdr_t  _http_next_header(int fd, const char **p)  { -    int i; -     -    if (_fetch_getln(fd, &reply_buf, &reply_size, &reply_length) == -1) -	return hdr_syserror; -    while (reply_length && isspace(reply_buf[reply_length-1])) -	reply_length--; -    reply_buf[reply_length] = 0; -    if (reply_length == 0) -	return hdr_end; -    /* -     * We could check for malformed headers but we don't really care. -     * A valid header starts with a token immediately followed by a -     * colon; a token is any sequence of non-control, non-whitespace -     * characters except "()<>@,;:\\\"{}". -     */ -    for (i = 0; hdr_names[i].num != hdr_unknown; i++) -	if ((*p = _http_match(hdr_names[i].name, reply_buf)) != NULL) -	    return hdr_names[i].num; -    return hdr_unknown; +	int i; + +	if (_fetch_getln(fd, &reply_buf, &reply_size, &reply_length) == -1) +		return (hdr_syserror); +	while (reply_length && isspace(reply_buf[reply_length-1])) +		reply_length--; +	reply_buf[reply_length] = 0; +	if (reply_length == 0) +	return (hdr_end); +	/* +	 * We could check for malformed headers but we don't really care. +	 * A valid header starts with a token immediately followed by a +	 * colon; a token is any sequence of non-control, non-whitespace +	 * characters except "()<>@,;:\\\"{}". +	 */ +	for (i = 0; hdr_names[i].num != hdr_unknown; i++) +		if ((*p = _http_match(hdr_names[i].name, reply_buf)) != NULL) +			return (hdr_names[i].num); +	return (hdr_unknown);  }  /* @@ -440,22 +444,22 @@ _http_next_header(int fd, const char **p)  static int  _http_parse_mtime(const char *p, time_t *mtime)  { -    char locale[64], *r; -    struct tm tm; - -    strncpy(locale, setlocale(LC_TIME, NULL), sizeof locale); -    setlocale(LC_TIME, "C"); -    r = strptime(p, "%a, %d %b %Y %H:%M:%S GMT", &tm); -    /* XXX should add support for date-2 and date-3 */ -    setlocale(LC_TIME, locale); -    if (r == NULL) -	return -1; -    DEBUG(fprintf(stderr, "last modified: [%04d-%02d-%02d " +	char locale[64], *r; +	struct tm tm; + +	strncpy(locale, setlocale(LC_TIME, NULL), sizeof locale); +	setlocale(LC_TIME, "C"); +	r = strptime(p, "%a, %d %b %Y %H:%M:%S GMT", &tm); +	/* XXX should add support for date-2 and date-3 */ +	setlocale(LC_TIME, locale); +	if (r == NULL) +		return (-1); +	DEBUG(fprintf(stderr, "last modified: [%04d-%02d-%02d "  		  "%02d:%02d:%02d]\n",  		  tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,  		  tm.tm_hour, tm.tm_min, tm.tm_sec)); -    *mtime = timegm(&tm); -    return 0; +	*mtime = timegm(&tm); +	return (0);  }  /* @@ -464,16 +468,16 @@ _http_parse_mtime(const char *p, time_t *mtime)  static int  _http_parse_length(const char *p, off_t *length)  { -    off_t len; -     -    for (len = 0; *p && isdigit(*p); ++p) -	len = len * 10 + (*p - '0'); -    if (*p) -	return -1; -    DEBUG(fprintf(stderr, "content length: [%lld]\n", -		  (long long)len)); -    *length = len; -    return 0; +	off_t len; + +	for (len = 0; *p && isdigit(*p); ++p) +		len = len * 10 + (*p - '0'); +	if (*p) +		return (-1); +	DEBUG(fprintf(stderr, "content length: [%lld]\n", +	    (long long)len)); +	*length = len; +	return (0);  }  /* @@ -482,31 +486,31 @@ _http_parse_length(const char *p, off_t *length)  static int  _http_parse_range(const char *p, off_t *offset, off_t *length, off_t *size)  { -    off_t first, last, len; - -    if (strncasecmp(p, "bytes ", 6) != 0) -	return -1; -    for (first = 0, p += 6; *p && isdigit(*p); ++p) -	first = first * 10 + *p - '0'; -    if (*p != '-') -	return -1; -    for (last = 0, ++p; *p && isdigit(*p); ++p) -	last = last * 10 + *p - '0'; -    if (first > last || *p != '/') -	return -1; -    for (len = 0, ++p; *p && isdigit(*p); ++p) -	len = len * 10 + *p - '0'; -    if (*p || len < last - first + 1) -	return -1; -    DEBUG(fprintf(stderr, "content range: [%lld-%lld/%lld]\n", -		  (long long)first, (long long)last, (long long)len)); -    *offset = first; -    *length = last - first + 1; -    *size = len; -    return 0; +	off_t first, last, len; + +	if (strncasecmp(p, "bytes ", 6) != 0) +		return (-1); +	for (first = 0, p += 6; *p && isdigit(*p); ++p) +		first = first * 10 + *p - '0'; +	if (*p != '-') +		return (-1); +	for (last = 0, ++p; *p && isdigit(*p); ++p) +		last = last * 10 + *p - '0'; +	if (first > last || *p != '/') +		return (-1); +	for (len = 0, ++p; *p && isdigit(*p); ++p) +		len = len * 10 + *p - '0'; +	if (*p || len < last - first + 1) +		return (-1); +	DEBUG(fprintf(stderr, "content range: [%lld-%lld/%lld]\n", +	    (long long)first, (long long)last, (long long)len)); +	*offset = first; +	*length = last - first + 1; +	*size = len; +	return (0);  } - +  /*****************************************************************************   * Helper functions for authorization   */ @@ -515,56 +519,56 @@ _http_parse_range(const char *p, off_t *offset, off_t *length, off_t *size)   * Base64 encoding   */  static char * -_http_base64(char *src) +_http_base64(const char *src)  { -    static const char base64[] = -	"ABCDEFGHIJKLMNOPQRSTUVWXYZ" -	"abcdefghijklmnopqrstuvwxyz" -	"0123456789+/"; -    char *str, *dst; -    size_t l; -    int t, r; - -    l = strlen(src); -    if ((str = malloc(((l + 2) / 3) * 4)) == NULL) -	return NULL; -    dst = str; -    r = 0; -     -    while (l >= 3) { -	t = (src[0] << 16) | (src[1] << 8) | src[2]; -	dst[0] = base64[(t >> 18) & 0x3f]; -	dst[1] = base64[(t >> 12) & 0x3f]; -	dst[2] = base64[(t >> 6) & 0x3f]; -	dst[3] = base64[(t >> 0) & 0x3f]; -	src += 3; l -= 3; -	dst += 4; r += 4; -    } - -    switch (l) { -    case 2: -	t = (src[0] << 16) | (src[1] << 8); -	dst[0] = base64[(t >> 18) & 0x3f]; -	dst[1] = base64[(t >> 12) & 0x3f]; -	dst[2] = base64[(t >> 6) & 0x3f]; -	dst[3] = '='; -	dst += 4; -	r += 4; -	break; -    case 1: -	t = src[0] << 16; -	dst[0] = base64[(t >> 18) & 0x3f]; -	dst[1] = base64[(t >> 12) & 0x3f]; -	dst[2] = dst[3] = '='; -	dst += 4; -	r += 4; -	break; -    case 0: -	break; -    } - -    *dst = 0; -    return str; +	static const char base64[] = +	    "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +	    "abcdefghijklmnopqrstuvwxyz" +	    "0123456789+/"; +	char *str, *dst; +	size_t l; +	int t, r; + +	l = strlen(src); +	if ((str = malloc(((l + 2) / 3) * 4)) == NULL) +		return (NULL); +	dst = str; +	r = 0; + +	while (l >= 3) { +		t = (src[0] << 16) | (src[1] << 8) | src[2]; +		dst[0] = base64[(t >> 18) & 0x3f]; +		dst[1] = base64[(t >> 12) & 0x3f]; +		dst[2] = base64[(t >> 6) & 0x3f]; +		dst[3] = base64[(t >> 0) & 0x3f]; +		src += 3; l -= 3; +		dst += 4; r += 4; +	} + +	switch (l) { +	case 2: +		t = (src[0] << 16) | (src[1] << 8); +		dst[0] = base64[(t >> 18) & 0x3f]; +		dst[1] = base64[(t >> 12) & 0x3f]; +		dst[2] = base64[(t >> 6) & 0x3f]; +		dst[3] = '='; +		dst += 4; +		r += 4; +		break; +	case 1: +		t = src[0] << 16; +		dst[0] = base64[(t >> 18) & 0x3f]; +		dst[1] = base64[(t >> 12) & 0x3f]; +		dst[2] = dst[3] = '='; +		dst += 4; +		r += 4; +		break; +	case 0: +		break; +	} + +	*dst = 0; +	return (str);  }  /* @@ -573,20 +577,20 @@ _http_base64(char *src)  static int  _http_basic_auth(int fd, const char *hdr, const char *usr, const char *pwd)  { -    char *upw, *auth; -    int r; - -    DEBUG(fprintf(stderr, "usr: [%s]\n", usr)); -    DEBUG(fprintf(stderr, "pwd: [%s]\n", pwd)); -    if (asprintf(&upw, "%s:%s", usr, pwd) == -1) -	return -1; -    auth = _http_base64(upw); -    free(upw); -    if (auth == NULL) -	return -1; -    r = _http_cmd(fd, "%s: Basic %s", hdr, auth); -    free(auth); -    return r; +	char *upw, *auth; +	int r; + +	DEBUG(fprintf(stderr, "usr: [%s]\n", usr)); +	DEBUG(fprintf(stderr, "pwd: [%s]\n", pwd)); +	if (asprintf(&upw, "%s:%s", usr, pwd) == -1) +		return (-1); +	auth = _http_base64(upw); +	free(upw); +	if (auth == NULL) +		return (-1); +	r = _http_cmd(fd, "%s: Basic %s", hdr, auth); +	free(auth); +	return (r);  }  /* @@ -595,126 +599,128 @@ _http_basic_auth(int fd, const char *hdr, const char *usr, const char *pwd)  static int  _http_authorize(int fd, const char *hdr, const char *p)  { -    /* basic authorization */ -    if (strncasecmp(p, "basic:", 6) == 0) { -	char *user, *pwd, *str; -	int r; - -	/* skip realm */ -	for (p += 6; *p && *p != ':'; ++p) -	    /* nothing */ ; -	if (!*p || strchr(++p, ':') == NULL) -	    return -1; -	if ((str = strdup(p)) == NULL) -	    return -1; /* XXX */ -	user = str; -	pwd = strchr(str, ':'); -	*pwd++ = '\0'; -	r = _http_basic_auth(fd, hdr, user, pwd); -	free(str); -	return r; -    } -    return -1; +	/* basic authorization */ +	if (strncasecmp(p, "basic:", 6) == 0) { +		char *user, *pwd, *str; +		int r; + +		/* skip realm */ +		for (p += 6; *p && *p != ':'; ++p) +			/* nothing */ ; +		if (!*p || strchr(++p, ':') == NULL) +			return (-1); +		if ((str = strdup(p)) == NULL) +			return (-1); /* XXX */ +		user = str; +		pwd = strchr(str, ':'); +		*pwd++ = '\0'; +		r = _http_basic_auth(fd, hdr, user, pwd); +		free(str); +		return (r); +	} +	return (-1);  } - +  /*****************************************************************************   * Helper functions for connecting to a server or proxy   */  /* - * Connect to the correct HTTP server or proxy.  + * Connect to the correct HTTP server or proxy.   */  static int  _http_connect(struct url *URL, struct url *purl, const char *flags)  { -    int verbose; -    int af, fd; -     +	int verbose; +	int af, fd; +  #ifdef INET6 -    af = AF_UNSPEC; +	af = AF_UNSPEC;  #else -    af = AF_INET; -#endif -     -    verbose = CHECK_FLAG('v'); -    if (CHECK_FLAG('4'))  	af = AF_INET; +#endif + +	verbose = CHECK_FLAG('v'); +	if (CHECK_FLAG('4')) +		af = AF_INET;  #ifdef INET6 -    else if (CHECK_FLAG('6')) -	af = AF_INET6; +	else if (CHECK_FLAG('6')) +		af = AF_INET6;  #endif -    if (purl) { -	URL = purl; -    } else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) { -	/* can't talk http to an ftp server */ -	/* XXX should set an error code */ -	return -1; -    } -     -    if ((fd = _fetch_connect(URL->host, URL->port, af, verbose)) == -1) -	/* _fetch_connect() has already set an error code */ -	return -1; -    return fd; +	if (purl) { +		URL = purl; +	} else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) { +		/* can't talk http to an ftp server */ +		/* XXX should set an error code */ +		return (-1); +	} + +	if ((fd = _fetch_connect(URL->host, URL->port, af, verbose)) == -1) +		/* _fetch_connect() has already set an error code */ +		return (-1); +	return (fd);  }  static struct url *  _http_get_proxy(void)  { -    struct url *purl; -    char *p; -     -    if (((p = getenv("HTTP_PROXY")) || (p = getenv("http_proxy"))) && -	(purl = fetchParseURL(p))) { -	if (!*purl->scheme) -	    strcpy(purl->scheme, SCHEME_HTTP); -	if (!purl->port) -	    purl->port = _fetch_default_proxy_port(purl->scheme); -	if (strcasecmp(purl->scheme, SCHEME_HTTP) == 0) -	    return purl; -	fetchFreeURL(purl); -    } -    return NULL; +	struct url *purl; +	char *p; + +	if (((p = getenv("HTTP_PROXY")) || (p = getenv("http_proxy"))) && +	    (purl = fetchParseURL(p))) { +		if (!*purl->scheme) +			strcpy(purl->scheme, SCHEME_HTTP); +		if (!purl->port) +			purl->port = _fetch_default_proxy_port(purl->scheme); +		if (strcasecmp(purl->scheme, SCHEME_HTTP) == 0) +			return (purl); +		fetchFreeURL(purl); +	} +	return (NULL);  }  static void  _http_print_html(FILE *out, FILE *in)  { -    size_t len; -    char *line, *p, *q; -    int comment, tag; - -    comment = tag = 0; -    while ((line = fgetln(in, &len)) != NULL) { -	while (len && isspace(line[len - 1])) -	    --len; -	for (p = q = line; q < line + len; ++q) { -	    if (comment && *q == '-') { -		if (q + 2 < line + len && strcmp(q, "-->") == 0) { -		    tag = comment = 0; -		    q += 2; +	size_t len; +	char *line, *p, *q; +	int comment, tag; + +	comment = tag = 0; +	while ((line = fgetln(in, &len)) != NULL) { +		while (len && isspace(line[len - 1])) +			--len; +		for (p = q = line; q < line + len; ++q) { +			if (comment && *q == '-') { +				if (q + 2 < line + len && +				    strcmp(q, "-->") == 0) { +					tag = comment = 0; +					q += 2; +				} +			} else if (tag && !comment && *q == '>') { +				p = q + 1; +				tag = 0; +			} else if (!tag && *q == '<') { +				if (q > p) +					fwrite(p, q - p, 1, out); +				tag = 1; +				if (q + 3 < line + len && +				    strcmp(q, "<!--") == 0) { +					comment = 1; +					q += 3; +				} +			}  		} -	    } if (tag && !comment && *q == '>') { -		p = q + 1; -		tag = 0; -	    } else if (!tag && *q == '<') { -		if (q > p) -		    fwrite(p, q - p, 1, out); -		tag = 1; -		if (q + 3 < line + len && strcmp(q, "<!--") == 0) { -		    comment = 1; -		    q += 3; -		} -	    } +		if (!tag && q > p) +			fwrite(p, q - p, 1, out); +		fputc('\n', out);  	} -	if (!tag && q > p) -	    fwrite(p, q - p, 1, out); -	fputc('\n', out); -    }  } - +  /*****************************************************************************   * Core   */ @@ -724,326 +730,326 @@ _http_print_html(FILE *out, FILE *in)   */  FILE *  _http_request(struct url *URL, const char *op, struct url_stat *us, -	      struct url *purl, const char *flags) +    struct url *purl, const char *flags)  { -    struct url *url, *new; -    int chunked, direct, need_auth, noredirect, verbose; -    int code, fd, i, n; -    off_t offset, clength, length, size; -    time_t mtime; -    const char *p; -    FILE *f; -    hdr_t h; -    char *host; +	struct url *url, *new; +	int chunked, direct, need_auth, noredirect, verbose; +	int code, fd, i, n; +	off_t offset, clength, length, size; +	time_t mtime; +	const char *p; +	FILE *f; +	hdr_t h; +	char *host;  #ifdef INET6 -    char hbuf[MAXHOSTNAMELEN + 1]; +	char hbuf[MAXHOSTNAMELEN + 1];  #endif -    direct = CHECK_FLAG('d'); -    noredirect = CHECK_FLAG('A'); -    verbose = CHECK_FLAG('v'); - -    if (direct && purl) { -	fetchFreeURL(purl); -	purl = NULL; -    } -     -    /* try the provided URL first */ -    url = URL; - -    /* if the A flag is set, we only get one try */ -    n = noredirect ? 1 : MAX_REDIRECT; -    i = 0; - -    need_auth = 0; -    do { -	new = NULL; -	chunked = 0; -	offset = 0; -	clength = -1; -	length = -1; -	size = -1; -	mtime = 0; -	 -	/* check port */ -	if (!url->port) -	    url->port = _fetch_default_port(url->scheme); -     -	/* were we redirected to an FTP URL? */ -	if (purl == NULL && strcmp(url->scheme, SCHEME_FTP) == 0) { -	    if (strcmp(op, "GET") == 0) -		return _ftp_request(url, "RETR", us, purl, flags); -	    else if (strcmp(op, "HEAD") == 0) -		return _ftp_request(url, "STAT", us, purl, flags); +	direct = CHECK_FLAG('d'); +	noredirect = CHECK_FLAG('A'); +	verbose = CHECK_FLAG('v'); + +	if (direct && purl) { +		fetchFreeURL(purl); +		purl = NULL;  	} -	 -	/* connect to server or proxy */ -	if ((fd = _http_connect(url, purl, flags)) == -1) -	    goto ouch; -	host = url->host; +	/* try the provided URL first */ +	url = URL; + +	/* if the A flag is set, we only get one try */ +	n = noredirect ? 1 : MAX_REDIRECT; +	i = 0; + +	need_auth = 0; +	do { +		new = NULL; +		chunked = 0; +		offset = 0; +		clength = -1; +		length = -1; +		size = -1; +		mtime = 0; + +		/* check port */ +		if (!url->port) +			url->port = _fetch_default_port(url->scheme); + +		/* were we redirected to an FTP URL? */ +		if (purl == NULL && strcmp(url->scheme, SCHEME_FTP) == 0) { +			if (strcmp(op, "GET") == 0) +				return (_ftp_request(url, "RETR", us, purl, flags)); +			else if (strcmp(op, "HEAD") == 0) +				return (_ftp_request(url, "STAT", us, purl, flags)); +		} + +		/* connect to server or proxy */ +		if ((fd = _http_connect(url, purl, flags)) == -1) +			goto ouch; + +		host = url->host;  #ifdef INET6 -	if (strchr(url->host, ':')) { -	    snprintf(hbuf, sizeof(hbuf), "[%s]", url->host); -	    host = hbuf; -	} +		if (strchr(url->host, ':')) { +			snprintf(hbuf, sizeof(hbuf), "[%s]", url->host); +			host = hbuf; +		}  #endif -	/* send request */ -	if (verbose) -	    _fetch_info("requesting %s://%s:%d%s", -			url->scheme, host, url->port, url->doc); -	if (purl) { -	    _http_cmd(fd, "%s %s://%s:%d%s HTTP/1.1", -		      op, url->scheme, host, url->port, url->doc); -	} else { -	    _http_cmd(fd, "%s %s HTTP/1.1", -		      op, url->doc); -	} +		/* send request */ +		if (verbose) +			_fetch_info("requesting %s://%s:%d%s", +			    url->scheme, host, url->port, url->doc); +		if (purl) { +			_http_cmd(fd, "%s %s://%s:%d%s HTTP/1.1", +			    op, url->scheme, host, url->port, url->doc); +		} else { +			_http_cmd(fd, "%s %s HTTP/1.1", +			    op, url->doc); +		} -	/* virtual host */ -	if (url->port == _fetch_default_port(url->scheme)) -	    _http_cmd(fd, "Host: %s", host); -	else -	    _http_cmd(fd, "Host: %s:%d", host, url->port); -	 -	/* proxy authorization */ -	if (purl) { -	    if (*purl->user || *purl->pwd) -		_http_basic_auth(fd, "Proxy-Authorization", -				 purl->user, purl->pwd); -	    else if ((p = getenv("HTTP_PROXY_AUTH")) != NULL && *p != '\0') -		_http_authorize(fd, "Proxy-Authorization", p); -	} -	 -	/* server authorization */ -	if (need_auth || *url->user || *url->pwd) { -	    if (*url->user || *url->pwd) -		_http_basic_auth(fd, "Authorization", url->user, url->pwd); -	    else if ((p = getenv("HTTP_AUTH")) != NULL && *p != '\0') -		_http_authorize(fd, "Authorization", p); -	    else if (fetchAuthMethod && fetchAuthMethod(url) == 0) { -		_http_basic_auth(fd, "Authorization", url->user, url->pwd); -	    } else { -		_http_seterr(HTTP_NEED_AUTH); -		goto ouch; -	    } -	} +		/* virtual host */ +		if (url->port == _fetch_default_port(url->scheme)) +			_http_cmd(fd, "Host: %s", host); +		else +			_http_cmd(fd, "Host: %s:%d", host, url->port); + +		/* proxy authorization */ +		if (purl) { +			if (*purl->user || *purl->pwd) +				_http_basic_auth(fd, "Proxy-Authorization", +				    purl->user, purl->pwd); +			else if ((p = getenv("HTTP_PROXY_AUTH")) != NULL && *p != '\0') +				_http_authorize(fd, "Proxy-Authorization", p); +		} + +		/* server authorization */ +		if (need_auth || *url->user || *url->pwd) { +			if (*url->user || *url->pwd) +				_http_basic_auth(fd, "Authorization", url->user, url->pwd); +			else if ((p = getenv("HTTP_AUTH")) != NULL && *p != '\0') +				_http_authorize(fd, "Authorization", p); +			else if (fetchAuthMethod && fetchAuthMethod(url) == 0) { +				_http_basic_auth(fd, "Authorization", url->user, url->pwd); +			} else { +				_http_seterr(HTTP_NEED_AUTH); +				goto ouch; +			} +		} + +		/* other headers */ +		if ((p = getenv("HTTP_USER_AGENT")) != NULL && *p != '\0') +			_http_cmd(fd, "User-Agent: %s", p); +		else +			_http_cmd(fd, "User-Agent: %s " _LIBFETCH_VER, __progname); +		if (url->offset) +			_http_cmd(fd, "Range: bytes=%lld-", (long long)url->offset); +		_http_cmd(fd, "Connection: close"); +		_http_cmd(fd, ""); + +		/* get reply */ +		switch ((code = _http_get_reply(fd))) { +		case HTTP_OK: +		case HTTP_PARTIAL: +			/* fine */ +			break; +		case HTTP_MOVED_PERM: +		case HTTP_MOVED_TEMP: +		case HTTP_SEE_OTHER: +			/* +			 * Not so fine, but we still have to read the headers to +			 * get the new location. +			 */ +			break; +		case HTTP_NEED_AUTH: +			if (need_auth) { +				/* +				 * We already sent out authorization code, so there's +				 * nothing more we can do. +				 */ +				_http_seterr(code); +				goto ouch; +			} +			/* try again, but send the password this time */ +			if (verbose) +				_fetch_info("server requires authorization"); +			break; +		case HTTP_NEED_PROXY_AUTH: +			/* +			 * If we're talking to a proxy, we already sent our proxy +			 * authorization code, so there's nothing more we can do. +			 */ +			_http_seterr(code); +			goto ouch; +		case HTTP_PROTOCOL_ERROR: +			/* fall through */ +		case -1: +			_fetch_syserr(); +			goto ouch; +		default: +			_http_seterr(code); +			if (!verbose) +				goto ouch; +			/* fall through so we can get the full error message */ +		} + +		/* get headers */ +		do { +			switch ((h = _http_next_header(fd, &p))) { +			case hdr_syserror: +				_fetch_syserr(); +				goto ouch; +			case hdr_error: +				_http_seterr(HTTP_PROTOCOL_ERROR); +				goto ouch; +			case hdr_content_length: +				_http_parse_length(p, &clength); +				break; +			case hdr_content_range: +				_http_parse_range(p, &offset, &length, &size); +				break; +			case hdr_last_modified: +				_http_parse_mtime(p, &mtime); +				break; +			case hdr_location: +				if (!HTTP_REDIRECT(code)) +					break; +				if (new) +					free(new); +				if (verbose) +					_fetch_info("%d redirect to %s", code, p); +				if (*p == '/') +					/* absolute path */ +					new = fetchMakeURL(url->scheme, url->host, url->port, p, +					    url->user, url->pwd); +				else +					new = fetchParseURL(p); +				if (new == NULL) { +					/* XXX should set an error code */ +					DEBUG(fprintf(stderr, "failed to parse new URL\n")); +					goto ouch; +				} +				if (!*new->user && !*new->pwd) { +					strcpy(new->user, url->user); +					strcpy(new->pwd, url->pwd); +				} +				new->offset = url->offset; +				new->length = url->length; +				break; +			case hdr_transfer_encoding: +				/* XXX weak test*/ +				chunked = (strcasecmp(p, "chunked") == 0); +				break; +			case hdr_www_authenticate: +				if (code != HTTP_NEED_AUTH) +					break; +				/* if we were smarter, we'd check the method and realm */ +				break; +			case hdr_end: +				/* fall through */ +			case hdr_unknown: +				/* ignore */ +				break; +			} +		} while (h > hdr_end); + +		/* we have a hit or an error */ +		if (code == HTTP_OK || code == HTTP_PARTIAL || HTTP_ERROR(code)) +			break; + +		/* we need to provide authentication */ +		if (code == HTTP_NEED_AUTH) { +			need_auth = 1; +			close(fd); +			fd = -1; +			continue; +		} -	/* other headers */ -	if ((p = getenv("HTTP_USER_AGENT")) != NULL && *p != '\0') -	    _http_cmd(fd, "User-Agent: %s", p); -	else -	    _http_cmd(fd, "User-Agent: %s " _LIBFETCH_VER, __progname); -	if (url->offset) -	    _http_cmd(fd, "Range: bytes=%lld-", (long long)url->offset); -	_http_cmd(fd, "Connection: close"); -	_http_cmd(fd, ""); - -	/* get reply */ -	switch ((code = _http_get_reply(fd))) { -	case HTTP_OK: -	case HTTP_PARTIAL: -	    /* fine */ -	    break; -	case HTTP_MOVED_PERM: -	case HTTP_MOVED_TEMP: -	case HTTP_SEE_OTHER: -	    /* -	     * Not so fine, but we still have to read the headers to -	     * get the new location. -	     */ -	    break; -	case HTTP_NEED_AUTH: -	    if (need_auth) { -		/* -		 * We already sent out authorization code, so there's -		 * nothing more we can do. -		 */ +		/* all other cases: we got a redirect */ +		need_auth = 0; +		close(fd); +		fd = -1; +		if (!new) { +			DEBUG(fprintf(stderr, "redirect with no new location\n")); +			break; +		} +		if (url != URL) +			fetchFreeURL(url); +		url = new; +	} while (++i < n); + +	/* we failed, or ran out of retries */ +	if (fd == -1) {  		_http_seterr(code);  		goto ouch; -	    } -	    /* try again, but send the password this time */ -	    if (verbose) -		_fetch_info("server requires authorization"); -	    break; -	case HTTP_NEED_PROXY_AUTH: -	    /* -	     * If we're talking to a proxy, we already sent our proxy -	     * authorization code, so there's nothing more we can do. -	     */ -	    _http_seterr(code); -	    goto ouch; -	case HTTP_PROTOCOL_ERROR: -	    /* fall through */ -	case -1: -	    _fetch_syserr(); -	    goto ouch; -	default: -	    _http_seterr(code); -	    if (!verbose) +	} + +	DEBUG(fprintf(stderr, "offset %lld, length %lld," +		  " size %lld, clength %lld\n", +		  (long long)offset, (long long)length, +		  (long long)size, (long long)clength)); + +	/* check for inconsistencies */ +	if (clength != -1 && length != -1 && clength != length) { +		_http_seterr(HTTP_PROTOCOL_ERROR);  		goto ouch; -	    /* fall through so we can get the full error message */  	} -	 -	/* get headers */ -	do { -	    switch ((h = _http_next_header(fd, &p))) { -	    case hdr_syserror: -		_fetch_syserr(); +	if (clength == -1) +		clength = length; +	if (clength != -1) +		length = offset + clength; +	if (length != -1 && size != -1 && length != size) { +		_http_seterr(HTTP_PROTOCOL_ERROR);  		goto ouch; -	    case hdr_error: +	} +	if (size == -1) +		size = length; + +	/* fill in stats */ +	if (us) { +		us->size = size; +		us->atime = us->mtime = mtime; +	} + +	/* too far? */ +	if (offset > URL->offset) {  		_http_seterr(HTTP_PROTOCOL_ERROR);  		goto ouch; -	    case hdr_content_length: -		_http_parse_length(p, &clength); -		break; -	    case hdr_content_range: -		_http_parse_range(p, &offset, &length, &size); -		break; -	    case hdr_last_modified: -		_http_parse_mtime(p, &mtime); -		break; -	    case hdr_location: -		if (!HTTP_REDIRECT(code)) -		    break; -		if (new) -		    free(new); -		if (verbose) -		    _fetch_info("%d redirect to %s", code, p); -		if (*p == '/') -		    /* absolute path */ -		    new = fetchMakeURL(url->scheme, url->host, url->port, p, -				       url->user, url->pwd); -		else -		    new = fetchParseURL(p); -		if (new == NULL) { -		    /* XXX should set an error code */ -		    DEBUG(fprintf(stderr, "failed to parse new URL\n")); -		    goto ouch; -		} -		if (!*new->user && !*new->pwd) { -		    strcpy(new->user, url->user); -		    strcpy(new->pwd, url->pwd); -		} -		new->offset = url->offset; -		new->length = url->length; -		break; -	    case hdr_transfer_encoding:	 -		/* XXX weak test*/ -		chunked = (strcasecmp(p, "chunked") == 0); -		break; -	    case hdr_www_authenticate: -		if (code != HTTP_NEED_AUTH) -		    break; -		/* if we were smarter, we'd check the method and realm */ -		break; -	    case hdr_end: -		/* fall through */ -	    case hdr_unknown: -		/* ignore */ -		break; -	    } -	} while (h > hdr_end); - -	/* we have a hit or an error */ -	if (code == HTTP_OK || code == HTTP_PARTIAL || HTTP_ERROR(code)) -	    break; - -	/* we need to provide authentication */ -	if (code == HTTP_NEED_AUTH) { -	    need_auth = 1; -	    close(fd); -	    fd = -1; -	    continue;  	} -	 -	/* all other cases: we got a redirect */ -	need_auth = 0; -	close(fd); -	fd = -1; -	if (!new) { -	    DEBUG(fprintf(stderr, "redirect with no new location\n")); -	    break; + +	/* report back real offset and size */ +	URL->offset = offset; +	URL->length = clength; + +	/* wrap it up in a FILE */ +	if ((f = chunked ? _http_funopen(fd) : fdopen(fd, "r")) == NULL) { +		_fetch_syserr(); +		goto ouch;  	} +  	if (url != URL) -	    fetchFreeURL(url); -	url = new; -    } while (++i < n); +		fetchFreeURL(url); +	if (purl) +		fetchFreeURL(purl); + +	if (HTTP_ERROR(code)) { +		_http_print_html(stderr, f); +		fclose(f); +		f = NULL; +	} -    /* we failed, or ran out of retries */ -    if (fd == -1) { -	_http_seterr(code); -	goto ouch; -    } +	return (f); -    DEBUG(fprintf(stderr, "offset %lld, length %lld," -		  " size %lld, clength %lld\n", -		  (long long)offset, (long long)length, -		  (long long)size, (long long)clength)); -     -    /* check for inconsistencies */ -    if (clength != -1 && length != -1 && clength != length) { -	_http_seterr(HTTP_PROTOCOL_ERROR); -	goto ouch; -    } -    if (clength == -1) -	clength = length; -    if (clength != -1) -	length = offset + clength; -    if (length != -1 && size != -1 && length != size) { -	_http_seterr(HTTP_PROTOCOL_ERROR); -	goto ouch; -    } -    if (size == -1) -	size = length; - -    /* fill in stats */ -    if (us) { -	us->size = size; -	us->atime = us->mtime = mtime; -    } -     -    /* too far? */ -    if (offset > URL->offset) { -	_http_seterr(HTTP_PROTOCOL_ERROR); -	goto ouch; -    } - -    /* report back real offset and size */ -    URL->offset = offset; -    URL->length = clength; -     -    /* wrap it up in a FILE */ -    if ((f = chunked ? _http_funopen(fd) : fdopen(fd, "r")) == NULL) { -	_fetch_syserr(); -	goto ouch; -    } - -    if (url != URL) -	fetchFreeURL(url); -    if (purl) -	fetchFreeURL(purl); - -    if (HTTP_ERROR(code)) { -	_http_print_html(stderr, f); -	fclose(f); -	f = NULL; -    } -     -    return f; - - ouch: -    if (url != URL) -	fetchFreeURL(url); -    if (purl) -	fetchFreeURL(purl); -    if (fd != -1) -	close(fd); -    return NULL; +ouch: +	if (url != URL) +		fetchFreeURL(url); +	if (purl) +		fetchFreeURL(purl); +	if (fd != -1) +		close(fd); +	return (NULL);  } - +  /*****************************************************************************   * Entry points   */ @@ -1054,7 +1060,7 @@ _http_request(struct url *URL, const char *op, struct url_stat *us,  FILE *  fetchXGetHTTP(struct url *URL, struct url_stat *us, const char *flags)  { -    return _http_request(URL, "GET", us, _http_get_proxy(), flags); +	return (_http_request(URL, "GET", us, _http_get_proxy(), flags));  }  /* @@ -1063,7 +1069,7 @@ fetchXGetHTTP(struct url *URL, struct url_stat *us, const char *flags)  FILE *  fetchGetHTTP(struct url *URL, const char *flags)  { -    return fetchXGetHTTP(URL, NULL, flags); +	return (fetchXGetHTTP(URL, NULL, flags));  }  /* @@ -1072,8 +1078,8 @@ fetchGetHTTP(struct url *URL, const char *flags)  FILE *  fetchPutHTTP(struct url *URL __unused, const char *flags __unused)  { -    warnx("fetchPutHTTP(): not implemented"); -    return NULL; +	warnx("fetchPutHTTP(): not implemented"); +	return (NULL);  }  /* @@ -1082,12 +1088,12 @@ fetchPutHTTP(struct url *URL __unused, const char *flags __unused)  int  fetchStatHTTP(struct url *URL, struct url_stat *us, const char *flags)  { -    FILE *f; -     -    if ((f = _http_request(URL, "HEAD", us, _http_get_proxy(), flags)) == NULL) -	return -1; -    fclose(f); -    return 0; +	FILE *f; + +	if ((f = _http_request(URL, "HEAD", us, _http_get_proxy(), flags)) == NULL) +		return (-1); +	fclose(f); +	return (0);  }  /* @@ -1096,6 +1102,6 @@ fetchStatHTTP(struct url *URL, struct url_stat *us, const char *flags)  struct url_ent *  fetchListHTTP(struct url *url __unused, const char *flags __unused)  { -    warnx("fetchListHTTP(): not implemented"); -    return NULL; +	warnx("fetchListHTTP(): not implemented"); +	return (NULL);  }  | 
