Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
protocols: remove support for ftp
Baptiste Daroussin committed 3 years ago
commit 2a1d53a4cd2a0d68b17a4ce7534858cec2d7235a
parent fdbf5e0
10 files changed +8 -1353
modified external/libfetch/common.h
@@ -127,7 +127,7 @@ void fetch_cache_put(conn_t *conn, int (*closecb)(conn_t *));
#endif

/*
-
 * I don't really like exporting http_request() and ftp_request(),
+
 * I don't really like exporting http_request()
 * but the HTTP and FTP code occasionally needs to cross-call
 * eachother, and this saves me from adding a lot of special-case code
 * to handle those cases.
@@ -140,8 +140,6 @@ FILE *http_request(struct url *, const char *,
FILE		*http_request_body(struct url *, const char *,
		     struct url_stat *, struct url *, const char *,
		     const char *, const char *);
-
FILE		*ftp_request(struct url *, const char *,
-
		     struct url_stat *, struct url *, const char *);

/*
 * Check whether a particular flag is set
modified external/libfetch/fetch.c
@@ -83,9 +83,7 @@ fetchXGet(struct url *URL, struct url_stat *us, const char *flags)
		us->size = -1;
		us->atime = us->mtime = 0;
	}
-
	if (strcmp(URL->scheme, SCHEME_FTP) == 0)
-
		return (fetchXGetFTP(URL, us, flags));
-
	else if (strcmp(URL->scheme, SCHEME_HTTP) == 0)
+
	if (strcmp(URL->scheme, SCHEME_HTTP) == 0)
		return (fetchXGetHTTP(URL, us, flags));
	else if (strcmp(URL->scheme, SCHEME_HTTPS) == 0)
		return (fetchXGetHTTP(URL, us, flags));
@@ -111,9 +109,7 @@ FILE *
fetchPut(struct url *URL, const char *flags)
{

-
	if (strcmp(URL->scheme, SCHEME_FTP) == 0)
-
		return (fetchPutFTP(URL, flags));
-
	else if (strcmp(URL->scheme, SCHEME_HTTP) == 0)
+
	if (strcmp(URL->scheme, SCHEME_HTTP) == 0)
		return (fetchPutHTTP(URL, flags));
	else if (strcmp(URL->scheme, SCHEME_HTTPS) == 0)
		return (fetchPutHTTP(URL, flags));
@@ -133,9 +129,7 @@ fetchStat(struct url *URL, struct url_stat *us, const char *flags)
		us->size = -1;
		us->atime = us->mtime = 0;
	}
-
	if (strcmp(URL->scheme, SCHEME_FTP) == 0)
-
		return (fetchStatFTP(URL, us, flags));
-
	else if (strcmp(URL->scheme, SCHEME_HTTP) == 0)
+
	if (strcmp(URL->scheme, SCHEME_HTTP) == 0)
		return (fetchStatHTTP(URL, us, flags));
	else if (strcmp(URL->scheme, SCHEME_HTTPS) == 0)
		return (fetchStatHTTP(URL, us, flags));
@@ -151,9 +145,7 @@ struct url_ent *
fetchList(struct url *URL, const char *flags)
{

-
	if (strcmp(URL->scheme, SCHEME_FTP) == 0)
-
		return (fetchListFTP(URL, flags));
-
	else if (strcmp(URL->scheme, SCHEME_HTTP) == 0)
+
	if (strcmp(URL->scheme, SCHEME_HTTP) == 0)
		return (fetchListHTTP(URL, flags));
	else if (strcmp(URL->scheme, SCHEME_HTTPS) == 0)
		return (fetchListHTTP(URL, flags));
deleted external/libfetch/ftp.c
@@ -1,1217 +0,0 @@
-
/*-
-
 * SPDX-License-Identifier: (BSD-3-Clause AND Beerware)
-
 *
-
 * Copyright (c) 1998-2011 Dag-Erling Smørgrav
-
 * All rights reserved.
-
 *
-
 * Redistribution and use in source and binary forms, with or without
-
 * modification, are permitted provided that the following conditions
-
 * are met:
-
 * 1. Redistributions of source code must retain the above copyright
-
 *    notice, this list of conditions and the following disclaimer
-
 *    in this position and unchanged.
-
 * 2. Redistributions in binary form must reproduce the above copyright
-
 *    notice, this list of conditions and the following disclaimer in the
-
 *    documentation and/or other materials provided with the distribution.
-
 * 3. The name of the author may not be used to endorse or promote products
-
 *    derived from this software without specific prior written permission
-
 *
-
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
 */
-

-
#include "bsd_compat.h"
-
__FBSDID("$FreeBSD: head/lib/libfetch/ftp.c 341013 2018-11-27 10:45:14Z des $");
-

-
/*
-
 * Portions of this code were taken from or based on ftpio.c:
-
 *
-
 * ----------------------------------------------------------------------------
-
 * "THE BEER-WARE LICENSE" (Revision 42):
-
 * <phk@FreeBSD.org> wrote this file.  As long as you retain this notice you
-
 * can do whatever you want with this stuff. If we meet some day, and you think
-
 * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
-
 * ----------------------------------------------------------------------------
-
 *
-
 * Major Changelog:
-
 *
-
 * Dag-Erling Smørgrav
-
 * 9 Jun 1998
-
 *
-
 * Incorporated into libfetch
-
 *
-
 * Jordan K. Hubbard
-
 * 17 Jan 1996
-
 *
-
 * Turned inside out. Now returns xfers as new file ids, not as a special
-
 * `state' of FTP_t
-
 *
-
 * $ftpioId: ftpio.c,v 1.30 1998/04/11 07:28:53 phk Exp $
-
 *
-
 */
-

-
#include <sys/param.h>
-
#include <sys/socket.h>
-
#include <netinet/in.h>
-

-
#include <ctype.h>
-
#include <err.h>
-
#include <errno.h>
-
#include <fcntl.h>
-
#include <netdb.h>
-
#include <stdarg.h>
-
#include <stdint.h>
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
#include <time.h>
-
#include <unistd.h>
-

-
#include "fetch.h"
-
#include "common.h"
-
#include "ftperr.h"
-

-
#define FTP_ANONYMOUS_USER	"anonymous"
-

-
#define FTP_CONNECTION_ALREADY_OPEN	125
-
#define FTP_OPEN_DATA_CONNECTION	150
-
#define FTP_OK				200
-
#define FTP_FILE_STATUS			213
-
#define FTP_SERVICE_READY		220
-
#define FTP_TRANSFER_COMPLETE		226
-
#define FTP_PASSIVE_MODE		227
-
#define FTP_LPASSIVE_MODE		228
-
#define FTP_EPASSIVE_MODE		229
-
#define FTP_LOGGED_IN			230
-
#define FTP_FILE_ACTION_OK		250
-
#define FTP_DIRECTORY_CREATED		257 /* multiple meanings */
-
#define FTP_FILE_CREATED		257 /* multiple meanings */
-
#define FTP_WORKING_DIRECTORY		257 /* multiple meanings */
-
#define FTP_NEED_PASSWORD		331
-
#define FTP_NEED_ACCOUNT		332
-
#define FTP_FILE_OK			350
-
#define FTP_SYNTAX_ERROR		500
-
#define FTP_PROTOCOL_ERROR		999
-

-
static struct url cached_host;
-
static conn_t	*cached_connection;
-

-
#define isftpreply(foo)				\
-
	(isdigit((unsigned char)foo[0]) &&	\
-
	    isdigit((unsigned char)foo[1]) &&	\
-
	    isdigit((unsigned char)foo[2]) &&	\
-
	    (foo[3] == ' ' || foo[3] == '\0'))
-
#define isftpinfo(foo) \
-
	(isdigit((unsigned char)foo[0]) &&	\
-
	    isdigit((unsigned char)foo[1]) &&	\
-
	    isdigit((unsigned char)foo[2]) &&	\
-
	    foo[3] == '-')
-

-
/*
-
 * 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 *)(uintptr_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;
-
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LE
-
	sin4->sin_len = sizeof(struct sockaddr_in);
-
#endif
-
}
-

-
/*
-
 * Get server response
-
 */
-
static int
-
ftp_chkerr(conn_t *conn)
-
{
-
	if (fetch_getln(conn) == -1) {
-
		fetch_syserr();
-
		return (-1);
-
	}
-
	if (isftpinfo(conn->buf)) {
-
		while (conn->buflen && !isftpreply(conn->buf)) {
-
			if (fetch_getln(conn) == -1) {
-
				fetch_syserr();
-
				return (-1);
-
			}
-
		}
-
	}
-

-
	while (conn->buflen &&
-
	    isspace((unsigned char)conn->buf[conn->buflen - 1]))
-
		conn->buflen--;
-
	conn->buf[conn->buflen] = '\0';
-

-
	if (!isftpreply(conn->buf)) {
-
		ftp_seterr(FTP_PROTOCOL_ERROR);
-
		return (-1);
-
	}
-

-
	conn->err = (conn->buf[0] - '0') * 100
-
	    + (conn->buf[1] - '0') * 10
-
	    + (conn->buf[2] - '0');
-

-
	return (conn->err);
-
}
-

-
/*
-
 * Send a command and check reply
-
 */
-
static int
-
ftp_cmd(conn_t *conn, 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(conn, msg, len);
-
	free(msg);
-

-
	if (r == -1) {
-
		fetch_syserr();
-
		return (-1);
-
	}
-

-
	return (ftp_chkerr(conn));
-
}
-

-
/*
-
 * Return a pointer to the filename part of a path
-
 */
-
static const char *
-
ftp_filename(const char *file, int *len, int *type)
-
{
-
	const char *s;
-

-
	if ((s = strrchr(file, '/')) == NULL)
-
		s = file;
-
	else
-
		s = s + 1;
-
	*len = strlen(s);
-
	if (*len > 7 && strncmp(s + *len - 7, ";type=", 6) == 0) {
-
		*type = s[*len - 1];
-
		*len -= 7;
-
	} else {
-
		*type = '\0';
-
	}
-
	return (s);
-
}
-

-
/*
-
 * Get current working directory from the reply to a CWD, PWD or CDUP
-
 * command.
-
 */
-
static int
-
ftp_pwd(conn_t *conn, char *pwd, size_t pwdlen)
-
{
-
	char *src, *dst, *end;
-
	int q;
-

-
	if (conn->err != FTP_WORKING_DIRECTORY &&
-
	    conn->err != FTP_FILE_ACTION_OK)
-
		return (FTP_PROTOCOL_ERROR);
-
	end = conn->buf + conn->buflen;
-
	src = conn->buf + 4;
-
	if (src >= end || *src++ != '"')
-
		return (FTP_PROTOCOL_ERROR);
-
	for (q = 0, dst = pwd; src < end && pwdlen--; ++src) {
-
		if (!q && *src == '"')
-
			q = 1;
-
		else if (q && *src != '"')
-
			break;
-
		else if (q)
-
			*dst++ = '"', q = 0;
-
		else
-
			*dst++ = *src;
-
	}
-
	if (!pwdlen)
-
		return (FTP_PROTOCOL_ERROR);
-
	*dst = '\0';
-
#if 0
-
	DEBUGF("pwd: [%s]\n", pwd);
-
#endif
-
	return (FTP_OK);
-
}
-

-
/*
-
 * Change working directory to the directory that contains the specified
-
 * file.
-
 */
-
static int
-
ftp_cwd(conn_t *conn, const char *file)
-
{
-
	const char *beg, *end;
-
	char pwd[PATH_MAX];
-
	int e, i, len;
-

-
	/* If no slashes in name, no need to change dirs. */
-
	if ((end = strrchr(file, '/')) == NULL)
-
		return (0);
-
	if ((e = ftp_cmd(conn, "PWD")) != FTP_WORKING_DIRECTORY ||
-
	    (e = ftp_pwd(conn, pwd, sizeof(pwd))) != FTP_OK) {
-
		ftp_seterr(e);
-
		return (-1);
-
	}
-
	for (;;) {
-
		len = strlen(pwd);
-

-
		/* Look for a common prefix between PWD and dir to fetch. */
-
		for (i = 0; i <= len && i <= end - file; ++i)
-
			if (pwd[i] != file[i])
-
				break;
-
#if 0
-
		DEBUGF("have: [%.*s|%s]\n", i, pwd, pwd + i);
-
		DEBUGF("want: [%.*s|%s]\n", i, file, file + i);
-
#endif
-
		/* Keep going up a dir until we have a matching prefix. */
-
		if (pwd[i] == '\0' && (file[i - 1] == '/' || file[i] == '/'))
-
			break;
-
		if ((e = ftp_cmd(conn, "CDUP")) != FTP_FILE_ACTION_OK ||
-
		    (e = ftp_cmd(conn, "PWD")) != FTP_WORKING_DIRECTORY ||
-
		    (e = ftp_pwd(conn, pwd, sizeof(pwd))) != FTP_OK) {
-
			ftp_seterr(e);
-
			return (-1);
-
		}
-
	}
-

-
#ifdef FTP_COMBINE_CWDS
-
	/* Skip leading slashes, even "////". */
-
	for (beg = file + i; beg < end && *beg == '/'; ++beg, ++i)
-
		/* nothing */ ;
-

-
	/* If there is no trailing dir, we're already there. */
-
	if (beg >= end)
-
		return (0);
-

-
	/* Change to the directory all in one chunk (e.g., foo/bar/baz). */
-
	e = ftp_cmd(conn, "CWD %.*s", (int)(end - beg), beg);
-
	if (e == FTP_FILE_ACTION_OK)
-
		return (0);
-
#endif /* FTP_COMBINE_CWDS */
-

-
	/* That didn't work so go back to legacy behavior (multiple CWDs). */
-
	for (beg = file + i; beg < end; beg = file + i + 1) {
-
		while (*beg == '/')
-
			++beg, ++i;
-
		for (++i; file + i < end && file[i] != '/'; ++i)
-
			/* nothing */ ;
-
		e = ftp_cmd(conn, "CWD %.*s", file + i - beg, beg);
-
		if (e != FTP_FILE_ACTION_OK) {
-
			ftp_seterr(e);
-
			return (-1);
-
		}
-
	}
-
	return (0);
-
}
-

-
/*
-
 * Set transfer mode and data type
-
 */
-
static int
-
ftp_mode_type(conn_t *conn, int mode, int type)
-
{
-
	int e;
-

-
	switch (mode) {
-
	case 0:
-
	case 's':
-
		mode = 'S';
-
	case 'S':
-
		break;
-
	default:
-
		return (FTP_PROTOCOL_ERROR);
-
	}
-
	if ((e = ftp_cmd(conn, "MODE %c", mode)) != FTP_OK) {
-
		if (mode == 'S') {
-
			/*
-
			 * Stream mode is supposed to be the default - so
-
			 * much so that some servers not only do not
-
			 * support any other mode, but do not support the
-
			 * MODE command at all.
-
			 *
-
			 * If "MODE S" fails, it is unlikely that we
-
			 * previously succeeded in setting a different
-
			 * mode.  Therefore, we simply hope that the
-
			 * server is already in the correct mode, and
-
			 * silently ignore the failure.
-
			 */
-
		} else {
-
			return (e);
-
		}
-
	}
-

-
	switch (type) {
-
	case 0:
-
	case 'i':
-
		type = 'I';
-
	case 'I':
-
		break;
-
	case 'a':
-
		type = 'A';
-
	case 'A':
-
		break;
-
	case 'd':
-
		type = 'D';
-
	case 'D':
-
		/* can't handle yet */
-
	default:
-
		return (FTP_PROTOCOL_ERROR);
-
	}
-
	if ((e = ftp_cmd(conn, "TYPE %c", type)) != FTP_OK)
-
		return (e);
-

-
	return (FTP_OK);
-
}
-

-
/*
-
 * Request and parse file stats
-
 */
-
static int
-
ftp_stat(conn_t *conn, const char *file, struct url_stat *us)
-
{
-
	char *ln;
-
	const char *filename;
-
	int filenamelen, type;
-
	struct tm tm;
-
	time_t t;
-
	int e;
-

-
	us->size = -1;
-
	us->atime = us->mtime = 0;
-

-
	filename = ftp_filename(file, &filenamelen, &type);
-

-
	if ((e = ftp_mode_type(conn, 0, type)) != FTP_OK) {
-
		ftp_seterr(e);
-
		return (-1);
-
	}
-

-
	e = ftp_cmd(conn, "SIZE %.*s", filenamelen, filename);
-
	if (e != FTP_FILE_STATUS) {
-
		ftp_seterr(e);
-
		return (-1);
-
	}
-
	for (ln = conn->buf + 4; *ln && isspace((unsigned char)*ln); ln++)
-
		/* nothing */ ;
-
	for (us->size = 0; *ln && isdigit((unsigned char)*ln); ln++)
-
		us->size = us->size * 10 + *ln - '0';
-
	if (*ln && !isspace((unsigned char)*ln)) {
-
		ftp_seterr(FTP_PROTOCOL_ERROR);
-
		us->size = -1;
-
		return (-1);
-
	}
-
	if (us->size == 0)
-
		us->size = -1;
-
	DEBUGF("size: [%lld]\n", (long long)us->size);
-

-
	e = ftp_cmd(conn, "MDTM %.*s", filenamelen, filename);
-
	if (e != FTP_FILE_STATUS) {
-
		ftp_seterr(e);
-
		return (-1);
-
	}
-
	for (ln = conn->buf + 4; *ln && isspace((unsigned char)*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;
-
	DEBUGF("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 {
-
	conn_t	*cconn;		/* Control connection */
-
	conn_t	*dconn;		/* Data connection */
-
	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 off_t	 ftp_seekfn(void *, off_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->cconn == NULL || io->dconn == NULL || io->dir == O_WRONLY) {
-
		errno = EBADF;
-
		return (-1);
-
	}
-
	if (io->err) {
-
		errno = io->err;
-
		return (-1);
-
	}
-
	if (io->eof)
-
		return (0);
-
	r = fetch_read(io->dconn, 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->cconn == NULL || io->dconn == NULL || io->dir == O_RDONLY) {
-
		errno = EBADF;
-
		return (-1);
-
	}
-
	if (io->err) {
-
		errno = io->err;
-
		return (-1);
-
	}
-
	w = fetch_write(io->dconn, buf, len);
-
	if (w >= 0)
-
		return (w);
-
	if (errno != EINTR)
-
		io->err = errno;
-
	return (-1);
-
}
-

-
static off_t
-
ftp_seekfn(void *v, off_t pos __unused, int whence __unused)
-
{
-
	struct ftpio *io;
-

-
	io = (struct ftpio *)v;
-
	if (io == NULL) {
-
		errno = EBADF;
-
		return ((off_t)-1);
-
	}
-
	errno = ESPIPE;
-
	return ((off_t)-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->cconn == NULL || io->dconn == NULL) {
-
		errno = EBADF;
-
		return (-1);
-
	}
-
	fetch_close(io->dconn);
-
	io->dir = -1;
-
	io->dconn = NULL;
-
	DEBUGF("Waiting for final status\n");
-
	r = ftp_chkerr(io->cconn);
-
	if (io->cconn == cached_connection && io->cconn->ref == 1)
-
		cached_connection = NULL;
-
	fetch_close(io->cconn);
-
	free(io);
-
	return (r == FTP_TRANSFER_COMPLETE) ? 0 : -1;
-
}
-

-
static FILE *
-
ftp_setup(conn_t *cconn, conn_t *dconn, int mode)
-
{
-
	struct ftpio *io;
-
	FILE *f;
-

-
	if (cconn == NULL || dconn == NULL)
-
		return (NULL);
-
	if ((io = malloc(sizeof(*io))) == NULL)
-
		return (NULL);
-
	io->cconn = cconn;
-
	io->dconn = dconn;
-
	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);
-
}
-

-
/*
-
 * Transfer file
-
 */
-
static FILE *
-
ftp_transfer(conn_t *conn, const char *oper, const char *file,
-
    int mode, off_t offset, const char *flags)
-
{
-
	struct sockaddr_storage sa;
-
	struct sockaddr_in6 *sin6;
-
	struct sockaddr_in *sin4;
-
	const char *bindaddr;
-
	const char *filename;
-
	int filenamelen, type;
-
	int pasv, verbose;
-
	int e, sd = -1;
-
	socklen_t l;
-
	char *s;
-
	FILE *df;
-

-
	/* check flags */
-
	pasv = CHECK_FLAG('p') || !CHECK_FLAG('P');
-
	verbose = CHECK_FLAG('v');
-

-
	/* passive mode */
-
	if ((s = getenv("FTP_PASSIVE_MODE")) != NULL)
-
		pasv = (strncasecmp(s, "no", 2) != 0);
-

-
	/* isolate filename */
-
	filename = ftp_filename(file, &filenamelen, &type);
-

-
	/* set transfer mode and data type */
-
	if ((e = ftp_mode_type(conn, 0, type)) != FTP_OK)
-
		goto ouch;
-

-
	/* find our own address, bind, and listen */
-
	l = sizeof(sa);
-
	if (getsockname(conn->sd, (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(conn, "PASV")) != FTP_PASSIVE_MODE)
-
				goto ouch;
-
			break;
-
		case AF_INET6:
-
			if ((e = ftp_cmd(conn, "EPSV")) != FTP_EPASSIVE_MODE) {
-
				if (e == -1)
-
					goto ouch;
-
				if ((e = ftp_cmd(conn, "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 = conn->buf;
-
		switch (e) {
-
		case FTP_PASSIVE_MODE:
-
		case FTP_LPASSIVE_MODE:
-
			for (p = ln + 3; *p && !isdigit((unsigned char)*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(conn, "REST %lu", (u_long)offset) != FTP_FILE_OK)
-
				goto sysouch;
-

-
		/* construct sockaddr for data socket */
-
		l = sizeof(sa);
-
		if (getpeername(conn->sd, (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 {
-
				memcpy(&sin6->sin6_addr, addr + 2, 16);
-
				memcpy(&sin6->sin6_port, addr + 19, 2);
-
			}
-
			break;
-
		case AF_INET:
-
			sin4 = (struct sockaddr_in *)&sa;
-
			if (e == FTP_EPASSIVE_MODE)
-
				sin4->sin_port = htons(port);
-
			else {
-
				memcpy(&sin4->sin_addr, addr, 4);
-
				memcpy(&sin4->sin_port, addr + 4, 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");
-
		bindaddr = getenv("FETCH_BIND_ADDRESS");
-
		if (bindaddr != NULL && *bindaddr != '\0' &&
-
		    (e = fetch_bind(sd, sa.ss_family, bindaddr)) != 0)
-
			goto ouch;
-
		if (connect(sd, (struct sockaddr *)&sa, l) == -1)
-
			goto sysouch;
-

-
		/* make the server initiate the transfer */
-
		if (verbose)
-
			fetch_info("initiating transfer");
-
		e = ftp_cmd(conn, "%s %.*s", oper, filenamelen, filename);
-
		if (e != FTP_CONNECTION_ALREADY_OPEN && e != FTP_OPEN_DATA_CONNECTION)
-
			goto ouch;
-

-
	} else {
-
		u_int32_t a;
-
		u_short p;
-
#if defined(IPV6_PORTRANGE) || defined(IP_PORTRANGE)
-
		int arg;
-
		int low = CHECK_FLAG('l');
-
#endif
-
		int 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;
-
#endif
-
			break;
-
		case AF_INET:
-
			((struct sockaddr_in *)&sa)->sin_port = 0;
-
#ifdef IP_PORTRANGE
-
			arg = low ? IP_PORTRANGE_DEFAULT : IP_PORTRANGE_HIGH;
-
			if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE,
-
				(char *)&arg, sizeof(arg)) == -1)
-
				goto sysouch;
-
#endif
-
			break;
-
		}
-
		if (verbose)
-
			fetch_info("binding data socket");
-
		if (bind(sd, (struct sockaddr *)&sa, l) == -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(conn, "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;
-
			sin6->sin6_scope_id = 0;
-
			if (getnameinfo((struct sockaddr *)&sa, l,
-
				hname, sizeof(hname),
-
				NULL, 0, NI_NUMERICHOST) == 0) {
-
				e = ftp_cmd(conn, "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(conn,
-
				    "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(conn, "REST %ju", (uintmax_t)offset) != FTP_FILE_OK)
-
				goto sysouch;
-

-
		/* make the server initiate the transfer */
-
		if (verbose)
-
			fetch_info("initiating transfer");
-
		e = ftp_cmd(conn, "%s %.*s", oper, filenamelen, filename);
-
		if (e != FTP_CONNECTION_ALREADY_OPEN && 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(conn, fetch_reopen(sd), mode)) == NULL)
-
		goto sysouch;
-
	return (df);
-

-
sysouch:
-
	fetch_syserr();
-
	if (sd >= 0)
-
		close(sd);
-
	return (NULL);
-

-
ouch:
-
	if (e != -1)
-
		ftp_seterr(e);
-
	if (sd >= 0)
-
		close(sd);
-
	return (NULL);
-
}
-

-
/*
-
 * Authenticate
-
 */
-
static int
-
ftp_authenticate(conn_t *conn, 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 */
-
	if (url->user[0] == '\0')
-
		fetch_netrc_auth(url);
-
	user = url->user;
-
	if (*user == '\0')
-
		if ((user = getenv("FTP_LOGIN")) != NULL)
-
			DEBUGF("FTP_LOGIN=%s\n", user);
-
	if (user == NULL || *user == '\0')
-
		user = FTP_ANONYMOUS_USER;
-
	if (purl && url->port == fetch_default_port(url->scheme))
-
		e = ftp_cmd(conn, "USER %s@%s", user, url->host);
-
	else if (purl)
-
		e = ftp_cmd(conn, "USER %s@%s@%d", user, url->host, url->port);
-
	else
-
		e = ftp_cmd(conn, "USER %s", user);
-

-
	/* did the server request a password? */
-
	if (e == FTP_NEED_PASSWORD) {
-
		pwd = url->pwd;
-
		if (*pwd == '\0')
-
			if ((pwd = getenv("FTP_PASSWORD")) != NULL)
-
				DEBUGF("FTP_PASSWORD=%s\n", pwd);
-
		if (pwd == NULL || *pwd == '\0') {
-
			if ((logname = getlogin()) == NULL)
-
				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(conn, "PASS %s", pwd);
-
	}
-

-
	return (e);
-
}
-

-
/*
-
 * Log on to FTP server
-
 */
-
static conn_t *
-
ftp_connect(struct url *url, struct url *purl, const char *flags)
-
{
-
	conn_t *conn;
-
	int e, direct, verbose;
-
#ifdef INET6
-
	int af = AF_UNSPEC;
-
#else
-
	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! */
-
		conn = fetch_connect(purl, af, verbose);
-
	} else {
-
		/* no proxy, go straight to target */
-
		conn = fetch_connect(url, af, verbose);
-
		purl = NULL;
-
	}
-

-
	/* check connection */
-
	if (conn == NULL)
-
		/* fetch_connect() has already set an error code */
-
		return (NULL);
-

-
	/* expect welcome message */
-
	if ((e = ftp_chkerr(conn)) != FTP_SERVICE_READY)
-
		goto fouch;
-

-
	/* authenticate */
-
	if ((e = ftp_authenticate(conn, url, purl)) != FTP_LOGGED_IN)
-
		goto fouch;
-

-
	/* TODO: Request extended features supported, if any (RFC 3659). */
-

-
	/* done */
-
	return (conn);
-

-
fouch:
-
	if (e != -1)
-
		ftp_seterr(e);
-
	fetch_close(conn);
-
	return (NULL);
-
}
-

-
/*
-
 * Disconnect from server
-
 */
-
static void
-
ftp_disconnect(conn_t *conn)
-
{
-
	(void)ftp_cmd(conn, "QUIT");
-
	if (conn == cached_connection && conn->ref == 1)
-
		cached_connection = NULL;
-
	fetch_close(conn);
-
}
-

-
/*
-
 * Check if we're already connected
-
 */
-
static int
-
ftp_isconnected(struct url *url)
-
{
-
	return (cached_connection
-
	    && (strcmp(url->host, cached_host.host) == 0)
-
	    && (strcmp(url->user, cached_host.user) == 0)
-
	    && (strcmp(url->pwd, cached_host.pwd) == 0)
-
	    && (url->port == cached_host.port));
-
}
-

-
/*
-
 * Check the cache, reconnect if no luck
-
 */
-
static conn_t *
-
ftp_cached_connect(struct url *url, struct url *purl, const char *flags)
-
{
-
	conn_t *conn;
-
	int e;
-

-
	/* 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_connection, "NOOP");
-
		if (e == FTP_OK || e == FTP_SYNTAX_ERROR)
-
			return (fetch_ref(cached_connection));
-
	}
-

-
	/* connect to server */
-
	if ((conn = ftp_connect(url, purl, flags)) == NULL)
-
		return (NULL);
-
	if (cached_connection)
-
		ftp_disconnect(cached_connection);
-
	cached_connection = fetch_ref(conn);
-
	memcpy(&cached_host, url, sizeof(*url));
-
	return (conn);
-
}
-

-
/*
-
 * Check the proxy settings
-
 */
-
static struct url *
-
ftp_get_proxy(struct url * url, const char *flags)
-
{
-
	struct url *purl;
-
	char *p;
-

-
	if (flags != NULL && strchr(flags, 'd') != NULL)
-
		return (NULL);
-
	if (fetch_no_proxy_match(url->host))
-
		return (NULL);
-
	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 (strcmp(purl->scheme, SCHEME_FTP) == 0 ||
-
		    strcmp(purl->scheme, SCHEME_HTTP) == 0)
-
			return (purl);
-
		fetchFreeURL(purl);
-
	}
-
	return (NULL);
-
}
-

-
/*
-
 * Process an FTP request
-
 */
-
FILE *
-
ftp_request(struct url *url, const char *op, struct url_stat *us,
-
    struct url *purl, const char *flags)
-
{
-
	conn_t *conn;
-
	int oflag;
-

-
	/* check if we should use HTTP instead */
-
	if (purl && (strcmp(purl->scheme, SCHEME_HTTP) == 0 ||
-
	    strcmp(purl->scheme, SCHEME_HTTPS) == 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 */
-
	conn = ftp_cached_connect(url, purl, flags);
-
	if (purl)
-
		fetchFreeURL(purl);
-
	if (conn == NULL)
-
		return (NULL);
-

-
	/* change directory */
-
	if (ftp_cwd(conn, url->doc) == -1)
-
		goto errsock;
-

-
	/* stat file */
-
	if (us && ftp_stat(conn, url->doc, us) == -1
-
	    && fetchLastErrCode != FETCH_PROTO
-
	    && fetchLastErrCode != FETCH_UNAVAIL)
-
		goto errsock;
-

-
	/* just a stat */
-
	if (strcmp(op, "STAT") == 0) {
-
		--conn->ref;
-
		ftp_disconnect(conn);
-
		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(conn, op, url->doc, oflag, url->offset, flags));
-

-
errsock:
-
	ftp_disconnect(conn);
-
	return (NULL);
-
}
-

-
/*
-
 * Get and stat file
-
 */
-
FILE *
-
fetchXGetFTP(struct url *url, struct url_stat *us, const char *flags)
-
{
-
	return (ftp_request(url, "RETR", us, ftp_get_proxy(url, flags), flags));
-
}
-

-
/*
-
 * Get file
-
 */
-
FILE *
-
fetchGetFTP(struct url *url, const char *flags)
-
{
-
	return (fetchXGetFTP(url, NULL, flags));
-
}
-

-
/*
-
 * Put file
-
 */
-
FILE *
-
fetchPutFTP(struct url *url, const char *flags)
-
{
-
	return (ftp_request(url, CHECK_FLAG('a') ? "APPE" : "STOR", NULL,
-
	    ftp_get_proxy(url, flags), flags));
-
}
-

-
/*
-
 * Get file stats
-
 */
-
int
-
fetchStatFTP(struct url *url, struct url_stat *us, const char *flags)
-
{
-
	FILE *f;
-

-
	f = ftp_request(url, "STAT", us, ftp_get_proxy(url, flags), flags);
-
	if (f == NULL)
-
		return (-1);
-
	/*
-
	 * When op is "STAT", ftp_request() will return either NULL or
-
	 * (FILE *)1, never a valid FILE *, so we mustn't fclose(f) before
-
	 * returning, as it would cause a segfault.
-
	 */
-
	return (0);
-
}
-

-
/*
-
 * List a directory
-
 */
-
struct url_ent *
-
fetchListFTP(struct url *url __unused, const char *flags __unused)
-
{
-
	warnx("fetchListFTP(): not implemented");
-
	return (NULL);
-
}
deleted external/libfetch/ftp.errors
@@ -1,47 +0,0 @@
-
# $FreeBSD: head/lib/libfetch/ftp.errors 106190 2002-10-30 06:06:16Z des $
-
#
-
# This list is taken from RFC 959.
-
# It probably needs a going over.
-
#
-
110 OK		Restart marker reply
-
120 TEMP	Service ready in a few minutes
-
125 OK		Data connection already open; transfer starting
-
150 OK		File status okay; about to open data connection
-
200 OK		Command okay
-
202 PROTO	Command not implemented, superfluous at this site
-
211 INFO	System status, or system help reply
-
212 INFO	Directory status
-
213 INFO	File status
-
214 INFO	Help message
-
215 INFO	Set system type
-
220 OK		Service ready for new user
-
221 OK		Service closing control connection
-
225 OK		Data connection open; no transfer in progress
-
226 OK		Requested file action successful
-
227 OK		Entering Passive Mode
-
229 OK		Entering Extended Passive Mode
-
230 OK		User logged in, proceed
-
250 OK		Requested file action okay, completed
-
257 OK		File/directory created
-
331 AUTH	User name okay, need password
-
332 AUTH	Need account for login
-
350 OK		Requested file action pending further information
-
421 DOWN	Service not available, closing control connection
-
425 NETWORK	Can't open data connection
-
426 ABORT	Connection closed; transfer aborted
-
450 UNAVAIL	File unavailable (e.g., file busy)
-
451 SERVER	Requested action aborted: local error in processing
-
452 FULL	Insufficient storage space in system
-
500 PROTO	Syntax error, command unrecognized
-
501 PROTO	Syntax error in parameters or arguments
-
502 PROTO	Command not implemented
-
503 PROTO	Bad sequence of commands
-
504 PROTO	Command not implemented for that parameter
-
530 AUTH	Not logged in
-
532 AUTH	Need account for storing files
-
535 PROTO	Bug in MediaHawk Video Kernel FTP server
-
550 UNAVAIL	File unavailable (e.g., file not found, no access)
-
551 PROTO	Requested action aborted. Page type unknown
-
552 FULL	Exceeded storage allocation
-
553 EXISTS	File name not allowed
-
999 PROTO	Protocol error
deleted external/libfetch/ftperr.h
@@ -1,45 +0,0 @@
-
static struct fetcherr ftp_errlist[] = {
-
    { 110, FETCH_OK, "Restart marker reply" },
-
    { 120, FETCH_TEMP, "Service ready in a few minutes" },
-
    { 125, FETCH_OK, "Data connection already open; transfer starting" },
-
    { 150, FETCH_OK, "File status okay; about to open data connection" },
-
    { 200, FETCH_OK, "Command okay" },
-
    { 202, FETCH_PROTO, "Command not implemented, superfluous at this site" },
-
    { 211, FETCH_INFO, "System status, or system help reply" },
-
    { 212, FETCH_INFO, "Directory status" },
-
    { 213, FETCH_INFO, "File status" },
-
    { 214, FETCH_INFO, "Help message" },
-
    { 215, FETCH_INFO, "Set system type" },
-
    { 220, FETCH_OK, "Service ready for new user" },
-
    { 221, FETCH_OK, "Service closing control connection" },
-
    { 225, FETCH_OK, "Data connection open; no transfer in progress" },
-
    { 226, FETCH_OK, "Requested file action successful" },
-
    { 227, FETCH_OK, "Entering Passive Mode" },
-
    { 229, FETCH_OK, "Entering Extended Passive Mode" },
-
    { 230, FETCH_OK, "User logged in, proceed" },
-
    { 250, FETCH_OK, "Requested file action okay, completed" },
-
    { 257, FETCH_OK, "File/directory created" },
-
    { 331, FETCH_AUTH, "User name okay, need password" },
-
    { 332, FETCH_AUTH, "Need account for login" },
-
    { 350, FETCH_OK, "Requested file action pending further information" },
-
    { 421, FETCH_DOWN, "Service not available, closing control connection" },
-
    { 425, FETCH_NETWORK, "Can't open data connection" },
-
    { 426, FETCH_ABORT, "Connection closed; transfer aborted" },
-
    { 450, FETCH_UNAVAIL, "File unavailable (e.g., file busy)" },
-
    { 451, FETCH_SERVER, "Requested action aborted: local error in processing" },
-
    { 452, FETCH_FULL, "Insufficient storage space in system" },
-
    { 500, FETCH_PROTO, "Syntax error, command unrecognized" },
-
    { 501, FETCH_PROTO, "Syntax error in parameters or arguments" },
-
    { 502, FETCH_PROTO, "Command not implemented" },
-
    { 503, FETCH_PROTO, "Bad sequence of commands" },
-
    { 504, FETCH_PROTO, "Command not implemented for that parameter" },
-
    { 530, FETCH_AUTH, "Not logged in" },
-
    { 532, FETCH_AUTH, "Need account for storing files" },
-
    { 535, FETCH_PROTO, "Bug in MediaHawk Video Kernel FTP server" },
-
    { 550, FETCH_UNAVAIL, "File unavailable (e.g., file not found, no access)" },
-
    { 551, FETCH_PROTO, "Requested action aborted. Page type unknown" },
-
    { 552, FETCH_FULL, "Exceeded storage allocation" },
-
    { 553, FETCH_EXISTS, "File name not allowed" },
-
    { 999, FETCH_PROTO, "Protocol error" },
-
    { -1, FETCH_UNKNOWN, "Unknown FTP error" }
-
};
modified external/libfetch/http.c
@@ -1622,14 +1622,6 @@ http_request_body(struct url *URL, const char *op, struct url_stat *us,
		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 ((conn = http_connect(url, purl, flags, &cached)) == NULL)
			goto ouch;
modified libpkg/fetch.c
@@ -77,22 +77,6 @@ static struct fetcher {
		fetch_open,
	},
	{
-
		"pkg+ftps",
-
		fetch_open,
-
	},
-
	{
-
		"pkg+ftp",
-
		fetch_open,
-
	},
-
	{
-
		"ftps",
-
		fetch_open,
-
	},
-
	{
-
		"ftp",
-
		fetch_open,
-
	},
-
	{
		"file",
		file_open,
	},
@@ -206,7 +190,7 @@ pkg_fetch_file_to_fd(struct pkg_repo *repo, const char *url, int dest,
	 * /usr/sbin/pkg in various releases so we can't just drop it.
         *
         * Instead, introduce new pkg+http://, pkg+https://,
-
	 * pkg+ssh://, pkg+ftp://, pkg+file:// to support the
+
	 * pkg+ssh://, pkg+file:// to support the
	 * SRV-style server discovery, and also to allow eg. Firefox
	 * to run pkg-related stuff given a pkg+foo:// URL.
	 *
modified libpkg/fetch_libfetch.c
@@ -122,8 +122,7 @@ fetch_connect(struct pkg_repo *repo, struct url *u)

	while (repo->fh == NULL) {
		if (repo != NULL && repo->mirror_type == SRV &&
-
		    (strncmp(u->scheme, "http", 4) == 0
-
		     || strcmp(u->scheme, "ftp") == 0)) {
+
		    (strncmp(u->scheme, "http", 4) == 0)) {
			if (repo->srv == NULL) {
				snprintf(zone, sizeof(zone),
				    "_%s._tcp.%s", u->scheme, u->host);
modified libpkg/pkg_config.c
@@ -397,7 +397,7 @@ static struct config_entry c[] = {
	{
		PKG_ARRAY,
		"VALID_URL_SCHEME",
-
		"pkg+http,pkg+https,https,http,file,ssh,ftp,ftps,pkg+ssh,pkg+ftp,pkg+ftps,tcp",
+
		"pkg+http,pkg+https,https,http,file,ssh,tcp",
	},
	{
		PKG_BOOL,
modified src/add.c
@@ -46,7 +46,6 @@ is_url(const char * const pattern)
{
	if (strncmp(pattern, "http://", 7) == 0 ||
		strncmp(pattern, "https://", 8) == 0 ||
-
		strncmp(pattern, "ftp://", 6) == 0 ||
		strncmp(pattern, "file://", 7) == 0)
		return (EPKG_OK);