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/libfetch/ftp.c | |
| parent | 076172c5bcd28ac2fe1ec5909215f06deb990d78 (diff) | |
Notes
Diffstat (limited to 'lib/libfetch/ftp.c')
| -rw-r--r-- | lib/libfetch/ftp.c | 1383 | 
1 files changed, 694 insertions, 689 deletions
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);  }  | 
