summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net-ftp/ftp/ChangeLog17
-rw-r--r--net-ftp/ftp/files/digest-ftp-0.17-r41
-rw-r--r--net-ftp/ftp/files/netkit-ftp-0.17-acct.patch15
-rw-r--r--net-ftp/ftp/files/netkit-ftp-0.17-custom-cflags.patch18
-rw-r--r--net-ftp/ftp/files/netkit-ftp-0.17-ipv6.patch826
-rw-r--r--net-ftp/ftp/files/netkit-ftp-0.17-locale.patch21
-rw-r--r--net-ftp/ftp/files/netkit-ftp-0.17-runique_mget.patch16
-rw-r--r--net-ftp/ftp/files/netkit-ftp-0.17-security.patch14
-rw-r--r--net-ftp/ftp/files/netkit-ftp-0.17-ssl-0.2.patch1177
-rw-r--r--net-ftp/ftp/ftp-0.17-r3.ebuild4
-rw-r--r--net-ftp/ftp/ftp-0.17-r4.ebuild49
11 files changed, 2154 insertions, 4 deletions
diff --git a/net-ftp/ftp/ChangeLog b/net-ftp/ftp/ChangeLog
index 7a4d14192eae..eb2d14c5d67e 100644
--- a/net-ftp/ftp/ChangeLog
+++ b/net-ftp/ftp/ChangeLog
@@ -1,6 +1,19 @@
# ChangeLog for net-ftp/ftp
-# Copyright 2002-2004 Gentoo Foundation; Distributed under the GPL v2
-# $Header: /var/cvsroot/gentoo-x86/net-ftp/ftp/ChangeLog,v 1.16 2004/06/24 22:45:04 agriffis Exp $
+# Copyright 1999-2005 Gentoo Foundation; Distributed under the GPL v2
+# $Header: /var/cvsroot/gentoo-x86/net-ftp/ftp/ChangeLog,v 1.17 2005/02/12 00:18:41 vapier Exp $
+
+*ftp-0.17-r4 (11 Feb 2005)
+
+ 11 Feb 2005; Mike Frysinger <vapier@gentoo.org>
+ +files/netkit-ftp-0.17-acct.patch,
+ +files/netkit-ftp-0.17-custom-cflags.patch,
+ +files/netkit-ftp-0.17-ipv6.patch, +files/netkit-ftp-0.17-locale.patch,
+ +files/netkit-ftp-0.17-runique_mget.patch,
+ +files/netkit-ftp-0.17-security.patch,
+ +files/netkit-ftp-0.17-ssl-0.2.patch, +ftp-0.17-r4.ebuild:
+ Add a bunch of misc patches from Fedora. Add a tweaked ipv6 patch #47507 by
+ Jasmin Buchert. Touchup the ssl patch and include -z option fix by Andreas
+ Kling #81586.
20 Feb 2004; Aron Griffis <agriffis@gentoo.org> ftp-0.17-r3.ebuild:
stable on alpha
diff --git a/net-ftp/ftp/files/digest-ftp-0.17-r4 b/net-ftp/ftp/files/digest-ftp-0.17-r4
new file mode 100644
index 000000000000..d98bdd29a960
--- /dev/null
+++ b/net-ftp/ftp/files/digest-ftp-0.17-r4
@@ -0,0 +1 @@
+MD5 94441610c9b86ef45c4c6ec609444060 netkit-ftp-0.17.tar.gz 53934
diff --git a/net-ftp/ftp/files/netkit-ftp-0.17-acct.patch b/net-ftp/ftp/files/netkit-ftp-0.17-acct.patch
new file mode 100644
index 000000000000..f679b80b35a6
--- /dev/null
+++ b/net-ftp/ftp/files/netkit-ftp-0.17-acct.patch
@@ -0,0 +1,15 @@
+Ripped from Fedora
+https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=17353
+
+--- netkit-ftp-0.17/ftp/ftp.c.acct Sun Jan 21 00:08:29 2001
++++ netkit-ftp-0.17/ftp/ftp.c Sun Jan 21 00:09:04 2001
+@@ -254,7 +254,8 @@
+ if (n == CONTINUE) {
+ aflag++;
+ /* fflush(stdout); */
+- zacct = getpass("Account:");
++ if(zacct==NULL)
++ zacct = getpass("Account:");
+ n = command("ACCT %s", zacct);
+ }
+ if (n != COMPLETE) {
diff --git a/net-ftp/ftp/files/netkit-ftp-0.17-custom-cflags.patch b/net-ftp/ftp/files/netkit-ftp-0.17-custom-cflags.patch
new file mode 100644
index 000000000000..22805dc4da85
--- /dev/null
+++ b/net-ftp/ftp/files/netkit-ftp-0.17-custom-cflags.patch
@@ -0,0 +1,18 @@
+--- netkit-ftp-0.17/configure.orig 2005-02-11 19:04:49.000000000 -0500
++++ netkit-ftp-0.17/configure 2005-02-11 19:05:02.000000000 -0500
+@@ -120,7 +120,6 @@
+ $CC -O2 __conftest.c -o __conftest
+ ) >/dev/null 2>&1; then
+ echo 'yes'
+- CFLAGS="$CFLAGS -O2"
+ else
+ echo 'no'
+ echo -n "Checking if $CC accepts -O... "
+@@ -128,7 +127,6 @@
+ $CC -O __conftest.c -o __conftest
+ ) >/dev/null 2>&1; then
+ echo 'yes'
+- CFLAGS="$CFLAGS -O"
+ else
+ echo 'no'
+ fi
diff --git a/net-ftp/ftp/files/netkit-ftp-0.17-ipv6.patch b/net-ftp/ftp/files/netkit-ftp-0.17-ipv6.patch
new file mode 100644
index 000000000000..defc6d1db049
--- /dev/null
+++ b/net-ftp/ftp/files/netkit-ftp-0.17-ipv6.patch
@@ -0,0 +1,826 @@
+IPv6 patch originally from http://linux-ipv6.org/ but adapted by Jasmin Buchert
+to work with our SSL patch
+
+http://bugs.gentoo.org/show_bug.cgi?id=47507
+
+--- netkit-ftp-old/ChangeLog
++++ netkit-ftp-new/ChangeLog
+@@ -1,3 +1,6 @@
++28-Nov-2000:
++ IPv6 support. (Hiroyuki YAMAMORI <h-yamamo@db3.so-net.ne.jp>)
++
+ 8-Jul-2000:
+ Fix misused printf-function call (not %n-exploitable though).
+
+--- netkit-ftp-old/configure
++++ netkit-ftp-new/configure
+@@ -26,1 +26,2 @@
+ --with-c-compiler=cc Program for compiling C source [guessed]
++ --enable-ipv6 Enable IPv6 support
+@@ -42,1 +43,4 @@
+ --without-readline|--disable-readline) WITHOUT_READLINE=1;;
++ --disable-ipv6) ENABLE_IPV6=no;;
++ --enable-ipv6=*) ENABLE_IPV6=`echo $1 | sed 's/^[^=]*=//'`;;
++ --enable-ipv6) ENABLE_IPV6=yes;;
+@@ -146,6 +152,40 @@
+ rm -f __conftest*
+
+ ##################################################
++## Enable IPv6
++echo -n "Whether to enable IPv6 support... "
++if [ x"$ENABLE_IPV6" = x"yes" ]; then
++ echo yes
++ CFLAGS="$CFLAGS -DINET6"
++else
++ echo no
++fi
++
++## Search IPv6 Library / Headers
++if [ x"$ENABLE_IPV6" = x"yes" ]; then
++ echo -n "Search for IPv6 library... "
++ inet6libdirs="/usr/local/v6/lib /usr/local/lib /usr /usr/inet6/lib"
++ inet6libs="inet6"
++ inet6found=no
++ for inet6libdir in $inet6libdirs; do
++ for inet6lib in $inet6libs; do
++ if [ -d $inet6libdir ] && [ -f $inet6libdir/lib$inet6lib.a ]; then
++ inet6found=yes
++ break 2
++ fi
++ done
++ done
++ if [ x"$inet6found" = x"yes" ]; then
++ echo "$inet6libdir/lib$inet6lib.a"
++ LIBS="$LIBS -L$inet6libdir -l$inet6lib"
++ else
++ echo "not found"
++ fi
++fi
++
++rm -f __conftest*
++
++##################################################
+
+ echo -n 'Checking for BSD signal semantics... '
+ cat <<EOF >__conftest.c
+--- netkit-ftp-old/ftp/Makefile
++++ netkit-ftp-new/ftp/Makefile
+@@ -19,10 +19,13 @@
+ cmds.o glob.o: glob.h
+
+ install: ftp
++ install -d $(INSTALLROOT)$(BINDIR)
+ install -s -m$(BINMODE) ftp $(INSTALLROOT)$(BINDIR)
+ ln -sf ftp $(INSTALLROOT)$(BINDIR)/pftp
++ install -d $(INSTALLROOT)$(MANDIR)/man1
+ install -m$(MANMODE) ftp.1 $(INSTALLROOT)$(MANDIR)/man1
+ ln -sf ftp.1 $(INSTALLROOT)$(MANDIR)/man1/pftp.1
++ install -d $(INSTALLROOT)$(MANDIR)/man5
+ install -m$(MANMODE) netrc.5 $(INSTALLROOT)$(MANDIR)/man5
+
+ clean:
+--- netkit-ftp-old/ftp/cmds.c
++++ netkit-ftp-new/ftp/cmds.c
+@@ -1,3 +1,5 @@
++/* $USAGI$ */
++
+ /*
+ * Copyright (c) 1985, 1989 Regents of the University of California.
+ * All rights reserved.
+@@ -190,7 +192,7 @@
+ setpeer(int argc, char *argv[])
+ {
+ char *host;
+- unsigned short port;
++ char *port;
+
+ if (connected) {
+ printf("Already connected to %s, use close first.\n",
+@@ -205,7 +207,7 @@
+ code = -1;
+ return;
+ }
+- port = ftp_port;
++ port = NULL;
+ if (argc > 2) {
+ #ifdef USE_SSL
+ /* not really an SSL enhancement but something that
+@@ -233,20 +235,15 @@
+ }
+ } else
+ #endif /* USE_SSL */
+- port = atoi(argv[2]);
+- if (port < 1) {
+- printf("%s: bad port number-- %s\n", argv[1], argv[2]);
+- printf ("usage: %s host-name [port]\n", argv[0]);
+- code = -1;
+- return;
+- }
+- port = htons(port);
++ port = argv[2];
+ }
+ host = hookup(argv[1], port);
+ if (host) {
+ int overbose;
+
+ connected = 1;
++ try_epsv = 1;
++ try_eprt = 1;
+ /*
+ * Set up defaults for FTP.
+ */
+--- netkit-ftp-old/ftp/ftp.c
++++ netkit-ftp-new/ftp/ftp.c
+@@ -10,6 +10,37 @@
+ *
+ */
+
++/* $USAGI$ */
++
++/*
++ * Copyright (C) 1997 and 1998 WIDE Project.
++ * 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.
++ * 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. Neither the name of the project nor the names of its contributors
++ * may be used to endorse or promote products derived from this software
++ * without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
++*/
++
+ /*
+ * Copyright (c) 1985, 1989 Regents of the University of California.
+ * All rights reserved.
+@@ -75,14 +106,38 @@
+ #include "ftp_var.h"
+ #include "cmds.h"
+
++#ifdef _USAGI
++#include "version.h"
++#else
+ #include "../version.h"
++#endif
++
++union sockunion {
++ struct sockinet {
++ u_short si_family;
++ u_short si_port;
++ } su_si;
++ struct sockaddr su_sa;
++ struct sockaddr_in su_sin;
++#ifdef INET6
++ struct sockaddr_in6 su_sin6;
++#endif
++};
++#define su_family su_sa.sa_family
++#define su_port su_si.si_port
++
++#ifdef INET6
++#define ex_af2prot(a) (a == AF_INET ? 1 : (a == AF_INET6 ? 2 : 0))
++#else
++#define ex_af2prot(a) (a == AF_INET ? 1 : 0)
++#endif
+
+ int data = -1;
+ off_t restart_point = 0;
+
+-static struct sockaddr_in hisctladdr;
+-static struct sockaddr_in data_addr;
+-static struct sockaddr_in myctladdr;
++static union sockunion hisctladdr;
++static union sockunion data_addr;
++static union sockunion myctladdr;
+ static int ptflag = 0;
+ static sigjmp_buf recvabort;
+ static sigjmp_buf sendabort;
+@@ -119,79 +174,119 @@
+ static FILE *dataconn(const char *);
+
+ char *
+-hookup(char *host, int port)
++hookup(const char *host, const char *port)
+ {
+- register struct hostent *hp = 0;
+- int s, tos;
++ int s, tos, error;
+ socklen_t len;
+ static char hostnamebuf[256];
+-
++ struct addrinfo hints, *res, *res0;
++ char hbuf[MAXHOSTNAMELEN], pbuf[NI_MAXSERV];
++ char *cause = "ftp: unknown";
++
++ if (port) {
++ strncpy(pbuf, port, sizeof(pbuf) - 1);
++ pbuf[sizeof(pbuf) - 1] = '\0';
++ } else {
++ sprintf(pbuf, "%d", ntohs(ftp_port));
++ }
+ memset(&hisctladdr, 0, sizeof(hisctladdr));
+- if (inet_aton(host, &hisctladdr.sin_addr)) {
+- hisctladdr.sin_family = AF_INET;
+- strncpy(hostnamebuf, host, sizeof(hostnamebuf));
+- hostnamebuf[sizeof(hostnamebuf)-1]=0;
+- }
+- else {
+- hp = gethostbyname(host);
+- if (hp == NULL) {
+- fprintf(stderr, "ftp: %s: ", host);
+- herror((char *)NULL);
+- code = -1;
+- return((char *) 0);
++ memset(&hints, 0, sizeof(hints));
++ hints.ai_flags = AI_CANONNAME;
++ hints.ai_socktype = SOCK_STREAM;
++ error = getaddrinfo(host, pbuf, &hints, &res0);
++ if (error) {
++ if (port) {
++ strcpy(hbuf, " ");
++ } else {
++ hbuf[0] = '\0';
++ pbuf[0] = '\0';
+ }
+- hisctladdr.sin_family = hp->h_addrtype;
+- if (hp->h_length > (int)sizeof(hisctladdr.sin_addr)) {
+- hp->h_length = sizeof(hisctladdr.sin_addr);
+- }
+- memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0], hp->h_length);
+- (void) strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf));
+- hostnamebuf[sizeof(hostnamebuf)-1] = 0;
+- }
+- hostname = hostnamebuf;
+- s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
+- if (s < 0) {
+- perror("ftp: socket");
++ fprintf(stderr, "ftp: %s%s%s: %s\n", host, hbuf, pbuf,
++ gai_strerror(error));
+ code = -1;
+ return (0);
+ }
+- hisctladdr.sin_port = port;
+- while (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) {
+- if (hp && hp->h_addr_list[1]) {
+- int oerrno = errno;
+-
+- fprintf(stderr, "ftp: connect to address %s: ",
+- inet_ntoa(hisctladdr.sin_addr));
+- errno = oerrno;
+- perror((char *) 0);
+- hp->h_addr_list++;
+- memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0],
+- hp->h_length);
+- fprintf(stdout, "Trying %s...\n",
+- inet_ntoa(hisctladdr.sin_addr));
+- (void) close(s);
+- s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
+- if (s < 0) {
+- perror("ftp: socket");
+- code = -1;
+- return (0);
+- }
++
++ if (res0->ai_canonname) {
++ struct addrinfo h, *a;
++ memset(&h, 0, sizeof(h));
++ h.ai_family = PF_UNSPEC;
++ h.ai_socktype = SOCK_STREAM;
++ h.ai_flags = AI_NUMERICHOST;
++ if (!getaddrinfo(res0->ai_canonname, NULL, &h, &a)) {
++ strncpy(hostnamebuf, res0->ai_canonname, sizeof(hostnamebuf));
++ freeaddrinfo(a);
++ } else
++ strncpy(hostnamebuf, host, sizeof(hostnamebuf));
++ }
++ else
++ strncpy(hostnamebuf, host, sizeof(hostnamebuf));
++ hostnamebuf[sizeof(hostnamebuf) - 1] = '\0';
++ hostname = hostnamebuf;
++
++ s = -1;
++ for (res = res0; res; res = res->ai_next) {
++ if (!ex_af2prot(res->ai_family)) {
++ cause = "ftp: mismatch address family";
++ errno = EPROTONOSUPPORT;
++ continue;
++ }
++ if ((size_t)res->ai_addrlen > sizeof(hisctladdr)) {
++ cause = "ftp: mismatch struct sockaddr size";
++ errno = EPROTO;
++ continue;
++ }
++ if (getnameinfo(res->ai_addr, res->ai_addrlen,
++ hbuf, sizeof(hbuf), NULL, 0,
++ NI_NUMERICHOST))
++ strcpy(hbuf, "???");
++ if (res0->ai_next) /* if we have multiple possibilities */
++ fprintf(stdout, "Trying %s...\n", hbuf);
++ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
++ if (s < 0) {
++ cause = "ftp: socket";
++ continue;
++ }
++ while ((error = connect(s, res->ai_addr, res->ai_addrlen)) < 0
++ && errno == EINTR) {
++ ;
++ }
++ if (error) {
++ /* this "if" clause is to prevent print warning twice */
++ if (res->ai_next) {
++ fprintf(stderr,
++ "ftp: connect to address %s\n", hbuf);
++ perror("");
++ }
++ cause = "ftp: connect";
++ close(s);
++ s = -1;
+ continue;
+ }
+- perror("ftp: connect");
++ /* finally we got one */
++ break;
++ }
++ if (s < 0) {
++ perror(cause);
+ code = -1;
+- goto bad;
++ freeaddrinfo(res0);
++ return NULL;
+ }
+- len = sizeof (myctladdr);
++ len = res->ai_addrlen;
++ memcpy(&hisctladdr, res->ai_addr, len);
++ freeaddrinfo(res0);
+ if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) {
+ perror("ftp: getsockname");
+ code = -1;
+ goto bad;
+ }
+ #ifdef IP_TOS
++ if (hisctladdr.su_family == AF_INET)
++ {
+ tos = IPTOS_LOWDELAY;
+ if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
+ perror("ftp: setsockopt TOS (ignored)");
++ }
+ #endif
+ cin = fdopen(s, "r");
+ cout = fdopen(s, "w");
+@@ -205,7 +300,7 @@
+ goto bad;
+ }
+ if (verbose)
+- printf("Connected to %s.\n", hostname);
++ printf("Connected to %s (%s).\n", hostname, hbuf);
+ if (getreply(0) > 2) { /* read startup message from server */
+ if (cin)
+ (void) fclose(cin);
+@@ -442,8 +537,10 @@
+ }
+ if (dig < 4 && isdigit(c))
+ code = code * 10 + (c - '0');
+- if (!pflag && code == 227)
++ if (!pflag && (code == 227 || code == 228))
+ pflag = 1;
++ else if (!pflag && code == 229)
++ pflag = 100;
+ if (dig > 4 && pflag == 1 && isdigit(c))
+ pflag = 2;
+ if (pflag == 2) {
+@@ -455,6 +552,8 @@
+ pflag = 3;
+ }
+ }
++ if (pflag == 100 && c == '(')
++ pflag = 2;
+ if (dig == 4 && c == '-') {
+ if (continuation)
+ code = 0;
+@@ -1207,15 +1306,25 @@
+ static int
+ initconn(void)
+ {
+- register char *p, *a;
++ u_char *p, *a;
+ int result, tmpno = 0;
+ socklen_t len;
+ int on = 1;
+- int tos;
+- u_long a1,a2,a3,a4,p1,p2;
+-
++ int tos, error = 0;
++ u_int ad[16], po[2], af, alen, plen;
++ char *pasvcmd = NULL;
++ char hbuf[MAXHOSTNAMELEN], pbuf[NI_MAXSERV];
++
++#ifdef INET6
++ if (myctladdr.su_family == AF_INET6
++ && (IN6_IS_ADDR_LINKLOCAL(&myctladdr.su_sin6.sin6_addr)
++ || IN6_IS_ADDR_SITELOCAL(&myctladdr.su_sin6.sin6_addr))) {
++ fprintf(stderr, "use of scoped address can be troublesome\n");
++ }
++#endif
+ if (passivemode) {
+- data = socket(AF_INET, SOCK_STREAM, 0);
++ data_addr = hisctladdr;
++ data = socket(data_addr.su_family, SOCK_STREAM, 0);
+ if (data < 0) {
+ perror("ftp: socket");
+ return(1);
+@@ -1224,31 +1333,177 @@
+ setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on,
+ sizeof (on)) < 0)
+ perror("ftp: setsockopt (ignored)");
+- if (command("PASV") != COMPLETE) {
++ switch (data_addr.su_family) {
++ case AF_INET:
++#if 0
++ if (try_epsv) {
++ result = command(pasvcmd = "EPSV 1");
++ if (code / 10 == 22 && code != 229) {
++ fprintf(stderr,
++ "wrong server: return code must be 229\n");
++ result = COMPLETE + 1;
++ }
++ } else {
++#endif
++ result = COMPLETE + 1;
++
++ if (result != COMPLETE) {
++ try_epsv = 0;
++ result = command(pasvcmd = "PASV");
++ }
++ break;
++#ifdef INET6
++ case AF_INET6:
++ if (try_epsv) {
++ result = command(pasvcmd = "EPSV 2");
++ if (code / 10 == 22 && code != 229) {
++ fprintf(stderr,
++ "wrong server: return code must be 229\n");
++ result = COMPLETE + 1;
++ }
++ } else {
++ result = COMPLETE + 1;
++ }
++ if (result != COMPLETE) {
++ try_epsv = 0;
++ result = command(pasvcmd = "LPSV");
++ }
++ break;
++#endif
++ default:
++ result = COMPLETE + 1;
++ break;
++ }
++ if (result != COMPLETE) {
+ printf("Passive mode refused.\n");
+- return(1);
++ goto bad;
+ }
+
++#define pack2(var) \
++ (((var[0] & 0xff) << 8) | ((var[1] & 0xff) << 0))
++#define pack4(var) \
++ ((((var)[0] & 0xff) << 24) | (((var)[1] & 0xff) << 16) | \
++ (((var)[2] & 0xff) << 8) | (((var)[3] & 0xff) << 0))
++
+ /*
+ * What we've got at this point is a string of comma separated
+ * one-byte unsigned integer values, separated by commas.
+- * The first four are the an IP address. The fifth is the MSB
+- * of the port number, the sixth is the LSB. From that we'll
+- * prepare a sockaddr_in.
+ */
+-
+- if (sscanf(pasv,"%ld,%ld,%ld,%ld,%ld,%ld",
+- &a1,&a2,&a3,&a4,&p1,&p2)
+- != 6)
+- {
+- printf("Passive mode address scan failure. Shouldn't happen!\n");
+- return(1);
++ error = 0;
++ if (strcmp(pasvcmd, "PASV") == 0) {
++ if (data_addr.su_family != AF_INET) {
++ error = 2;
++ goto psv_done;
++ }
++ if (code / 10 == 22 && code != 227) {
++ error = 227;
++ goto psv_done;
++ }
++ if (sscanf(pasv, "%u,%u,%u,%u,%u,%u",
++ &ad[0], &ad[1], &ad[2], &ad[3],
++ &po[0], &po[1]) != 6) {
++ error = 1;
++ goto psv_done;
++ }
++ data_addr.su_sin.sin_addr.s_addr = htonl(pack4(ad));
++ data_addr.su_port = htons(pack2(po));
++ } else
++ if (strcmp(pasvcmd, "LPSV") == 0) {
++ if (code / 10 == 22 && code != 228) {
++ error = 228;
++ goto psv_done;
++ }
++ switch (data_addr.su_family) {
++ case AF_INET:
++ if (sscanf(pasv, "%u,%u,%u,%u,%u,%u,%u,%u,%u",
++ &af, &alen,
++ &ad[0], &ad[1], &ad[2], &ad[3],
++ &plen, &po[0], &po[1]) != 9) {
++ error = 1;
++ goto psv_done;
++ }
++ if (af != 4 || alen != 4 || plen != 2) {
++ error = 2;
++ goto psv_done;
++ }
++ data_addr.su_sin.sin_addr.s_addr =
++ htonl(pack4(ad));
++ data_addr.su_port = htons(pack2(po));
++ break;
++#ifdef INET6
++ case AF_INET6:
++ if (sscanf(pasv,
++ "%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u",
++ &af, &alen,
++ &ad[0], &ad[1], &ad[2], &ad[3],
++ &ad[4], &ad[5], &ad[6], &ad[7],
++ &ad[8], &ad[9], &ad[10], &ad[11],
++ &ad[12], &ad[13], &ad[14], &ad[15],
++ &plen, &po[0], &po[1]) != 21) {
++ error = 1;
++ goto psv_done;
++ }
++ if (af != 6 || alen != 16 || plen != 2) {
++ error = 2;
++ goto psv_done;
++ }
++ data_addr.su_sin6.sin6_addr.s6_addr32[0] =
++ htonl(pack4(ad));
++ data_addr.su_sin6.sin6_addr.s6_addr32[1] =
++ htonl(pack4(ad+4));
++ data_addr.su_sin6.sin6_addr.s6_addr32[2] =
++ htonl(pack4(ad+8));
++ data_addr.su_sin6.sin6_addr.s6_addr32[3] =
++ htonl(pack4(ad+12));
++ data_addr.su_port = htons(pack2(po));
++ break;
++#endif
++ default:
++ error = 1;
++ }
++ } else if (strncmp(pasvcmd, "EPSV", 4) == 0) {
++ char delim[4];
++ u_int epsvpo;
++
++ if (code / 10 == 22 && code != 229) {
++ error = 229;
++ goto psv_done;
++ }
++ if (sscanf(pasv, "%c%c%c%u%c", &delim[0], &delim[1],
++ &delim[2], &epsvpo, &delim[3]) != 5) {
++ error = 1;
++ goto psv_done;
++ }
++ if (delim[0] != delim[1] || delim[0] != delim[2]
++ || delim[0] != delim[3]) {
++ error = 1;
++ goto psv_done;
++ }
++ data_addr.su_port = htons(epsvpo);
++ } else {
++ error = 1;
++ }
++psv_done:
++ switch (error) {
++ case 0:
++ break;
++ case 1:
++ fprintf(stderr,
++ "Passive mode address scan failure. Shouldn't happen!\n");
++ goto bad;
++ case 2:
++ fprintf(stderr,
++ "Passive mode AF mismatch. Shouldn't happen!\n");
++ goto bad;
++ case 227:
++ case 228:
++ case 229:
++ fprintf(stderr,
++ "wrong server: return code must be %d\n", error);
++ goto bad;
++ default:
++ fprintf(stderr, "Bug\n");
+ }
+-
+- data_addr.sin_family = AF_INET;
+- data_addr.sin_addr.s_addr = htonl((a1 << 24) | (a2 << 16) |
+- (a3 << 8) | a4);
+- data_addr.sin_port = htons((p1 << 8) | p2);
+
+ if (connect(data, (struct sockaddr *) &data_addr,
+ sizeof(data_addr))<0) {
+@@ -1256,20 +1511,23 @@
+ return(1);
+ }
+ #ifdef IP_TOS
++ if (data_addr.su_family == AF_INET)
++ {
+ tos = IPTOS_THROUGHPUT;
+ if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&tos,
+ sizeof(tos)) < 0)
+ perror("ftp: setsockopt TOS (ignored)");
++ }
+ #endif
+ return(0);
+ }
+ noport:
+ data_addr = myctladdr;
+ if (sendport)
+- data_addr.sin_port = 0; /* let system pick one */
++ data_addr.su_port = 0; /* let system pick one */
+ if (data != -1)
+ (void) close(data);
+- data = socket(AF_INET, SOCK_STREAM, 0);
++ data = socket(data_addr.su_family, SOCK_STREAM, 0);
+ if (data < 0) {
+ perror("ftp: socket");
+ if (tmpno)
+@@ -1296,13 +1554,47 @@
+ if (listen(data, 1) < 0)
+ perror("ftp: listen");
+ if (sendport) {
+- a = (char *)&data_addr.sin_addr;
+- p = (char *)&data_addr.sin_port;
+-#define UC(b) (((int)b)&0xff)
+- result =
+- command("PORT %d,%d,%d,%d,%d,%d",
+- UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
+- UC(p[0]), UC(p[1]));
++ af = ex_af2prot(data_addr.su_family);
++ if (try_eprt && af > 1) { /* only IPv6 */
++ if (getnameinfo((struct sockaddr *)&data_addr, len,
++ hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
++ NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
++ result = command("EPRT |%d|%s|%s|",
++ af, hbuf, pbuf);
++ if (result != COMPLETE) {
++ try_eprt = 0;
++ }
++ } else {
++ result = ERROR;
++ }
++ } else {
++ result = COMPLETE + 1;
++ }
++ if (result == COMPLETE)
++ goto prt_done;
++
++ p = (u_char *)&data_addr.su_port;
++ switch (data_addr.su_family) {
++ case AF_INET:
++ a = (u_char *)&data_addr.su_sin.sin_addr;
++ result = command("PORT %u,%u,%u,%u,%u,%u",
++ a[0], a[1], a[2], a[3], p[0], p[1]);
++ break;
++#ifdef INET6
++ case AF_INET6:
++ a = (u_char *)&data_addr.su_sin6.sin6_addr;
++ result = command(
++ "LPRT 6,16,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,2,%d,%d",
++ a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7],
++ a[8], a[9],a[10],a[11],a[12],a[13],a[14],a[15],
++ p[0], p[1]);
++ break;
++#endif
++ default:
++ result = COMPLETE + 1; /* xxx */
++ }
++
++ prt_done:
+ if (result == ERROR && sendport == -1) {
+ sendport = 0;
+ tmpno = 1;
+@@ -1313,9 +1605,12 @@
+ if (tmpno)
+ sendport = 1;
+ #ifdef IP_TOS
++ if (data_addr.su_family == AF_INET)
++ {
+ on = IPTOS_THROUGHPUT;
+ if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
+ perror("ftp: setsockopt TOS (ignored)");
++ }
+ #endif
+ return (0);
+ bad:
+@@ -1328,7 +1623,7 @@
+ static FILE *
+ dataconn(const char *lmode)
+ {
+- struct sockaddr_in from;
++ union sockunion from;
+ int s, tos;
+ socklen_t fromlen = sizeof(from);
+ int ret;
+@@ -1345,9 +1640,12 @@
+ (void) close(data);
+ data = s;
+ #ifdef IP_TOS
++ if (from.su_family == AF_INET)
++ {
+ tos = IPTOS_THROUGHPUT;
+ if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
+ perror("ftp: setsockopt TOS (ignored)");
++ }
+ #endif
+
+ #ifdef USE_SSL
+@@ -1470,8 +1768,8 @@
+ static struct comvars {
+ int connect;
+ char name[MAXHOSTNAMELEN];
+- struct sockaddr_in mctl;
+- struct sockaddr_in hctl;
++ union sockunion mctl;
++ union sockunion hctl;
+ FILE *in;
+ FILE *out;
+ int tpe;
+@@ -1509,7 +1807,7 @@
+ connected = op->connect;
+ if (hostname) {
+ (void) strncpy(ip->name, hostname, sizeof(ip->name) - 1);
+- ip->name[strlen(ip->name)] = '\0';
++ ip->name[sizeof(ip->name) - 1] = '\0';
+ }
+ else {
+ ip->name[0] = 0;
+@@ -1538,18 +1836,18 @@
+ ip->ntflg = ntflag;
+ ntflag = op->ntflg;
+ (void) strncpy(ip->nti, ntin, 16);
+- (ip->nti)[strlen(ip->nti)] = '\0';
++ (ip->nti)[16] = '\0'; /* shouldn't use strlen */
+ (void) strcpy(ntin, op->nti);
+ (void) strncpy(ip->nto, ntout, 16);
+- (ip->nto)[strlen(ip->nto)] = '\0';
++ (ip->nto)[16] = '\0';
+ (void) strcpy(ntout, op->nto);
+ ip->mapflg = mapflag;
+ mapflag = op->mapflg;
+ (void) strncpy(ip->mi, mapin, MAXPATHLEN - 1);
+- (ip->mi)[strlen(ip->mi)] = '\0';
++ (ip->mi)[MAXPATHLEN - 1] = '\0';
+ (void) strcpy(mapin, op->mi);
+ (void) strncpy(ip->mo, mapout, MAXPATHLEN - 1);
+- (ip->mo)[strlen(ip->mo)] = '\0';
++ (ip->mo)[MAXPATHLEN - 1] = '\0';
+ (void) strcpy(mapout, op->mo);
+ (void) signal(SIGINT, oldintr);
+ if (abrtflag) {
+--- netkit-ftp-old/ftp/ftp_var.h
++++ netkit-ftp-new/ftp/ftp_var.h
+@@ -1,3 +1,5 @@
++/* $USAGI$ */
++
+ /*
+ * Copyright (c) 1985, 1989 Regents of the University of California.
+ * All rights reserved.
+@@ -112,6 +114,8 @@
+ Extern int mflag; /* flag: if != 0, then active multi command */
+
+ Extern int options; /* used during socket creation */
++Extern int try_epsv; /* try EPSV for this session */
++Extern int try_eprt; /* try EPRT for this session */
+
+ /*
+ * Format of command table.
+@@ -140,7 +144,7 @@
+ Extern char macbuf[4096];
+ #define MACBUF_SIZE 4096
+
+-char *hookup(char *host, int port);
++char *hookup(const char *host, const char *port);
+ struct cmd *getcmd(const char *);
+ char **makeargv(int *pargc, char **parg);
+ int dologin(const char *host);
diff --git a/net-ftp/ftp/files/netkit-ftp-0.17-locale.patch b/net-ftp/ftp/files/netkit-ftp-0.17-locale.patch
new file mode 100644
index 000000000000..57a10d85e353
--- /dev/null
+++ b/net-ftp/ftp/files/netkit-ftp-0.17-locale.patch
@@ -0,0 +1,21 @@
+ripped from Fedora
+https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=142265
+
+--- netkit-ftp-0.17/ftp/main.c.locale 2004-12-15 16:52:14.504193752 +0000
++++ netkit-ftp-0.17/ftp/main.c 2004-12-15 16:52:51.719133655 +0000
+@@ -51,6 +51,7 @@
+
+ /* #include <arpa/ftp.h> <--- unused? */
+
++#include <locale.h>
+ #include <signal.h>
+ #include <unistd.h>
+ #include <string.h>
+@@ -109,6 +110,7 @@
+
+ tick = 0;
+
++ setlocale (LC_ALL, "");
+ sp = getservbyname("ftp", "tcp");
+ if (sp == 0) {
+ fprintf(stderr, "ftp: ftp/tcp: unknown service\n");
diff --git a/net-ftp/ftp/files/netkit-ftp-0.17-runique_mget.patch b/net-ftp/ftp/files/netkit-ftp-0.17-runique_mget.patch
new file mode 100644
index 000000000000..249238c0521f
--- /dev/null
+++ b/net-ftp/ftp/files/netkit-ftp-0.17-runique_mget.patch
@@ -0,0 +1,16 @@
+ripped from Fedora
+https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=79367
+
+--- netkit-ftp-0.17/ftp/ftp.c.runique_mget 2004-12-07 12:05:49.360133092 +0100
++++ netkit-ftp-0.17/ftp/ftp.c 2004-12-07 12:06:48.480883902 +0100
+@@ -923,7 +923,9 @@
+ return;
+ }
+ }
+- else if (runique && (local = gunique(local)) == NULL) {
++ else if (runique && (strcmp(cmd, "NLST") != 0) &&
++ (local = gunique(local)) == NULL)
++ {
+ (void) signal(SIGINT, oldintr);
+ code = -1;
+ return;
diff --git a/net-ftp/ftp/files/netkit-ftp-0.17-security.patch b/net-ftp/ftp/files/netkit-ftp-0.17-security.patch
new file mode 100644
index 000000000000..376c1b5caa65
--- /dev/null
+++ b/net-ftp/ftp/files/netkit-ftp-0.17-security.patch
@@ -0,0 +1,14 @@
+ripped from Fedora
+
+diff -urN netkit-ftp-0.17-pre20000412/ftp/ftp.c netkit-ftp-0.17-pre20000412.new/ftp/ftp.c
+--- netkit-ftp-0.17-pre20000412/ftp/ftp.c Mon Dec 13 21:33:20 1999
++++ netkit-ftp-0.17-pre20000412.new/ftp/ftp.c Wed Aug 16 14:12:50 2000
+@@ -883,7 +883,7 @@
+ }
+ if (fstat(fileno(fout), &st) < 0 || st.st_blksize == 0)
+ st.st_blksize = BUFSIZ;
+- if (st.st_blksize > bufsize) {
++ if ((unsigned)st.st_blksize > bufsize) {
+ if (buf)
+ (void) free(buf);
+ buf = malloc((unsigned)st.st_blksize);
diff --git a/net-ftp/ftp/files/netkit-ftp-0.17-ssl-0.2.patch b/net-ftp/ftp/files/netkit-ftp-0.17-ssl-0.2.patch
new file mode 100644
index 000000000000..9ba6f5291a71
--- /dev/null
+++ b/net-ftp/ftp/files/netkit-ftp-0.17-ssl-0.2.patch
@@ -0,0 +1,1177 @@
+--- netkit-ftp-0.17/configure
++++ netkit-ftp-0.17+ssl-0.2/configure
+@@ -26,6 +26,7 @@
+ --binmode=mode Mode for binaries [755]
+ --manmode=mode Mode for manual pages [644]
+ --with-c-compiler=cc Program for compiling C source [guessed]
++ --enable-ssl Enable SSL support
+ EOF
+ exit 0;;
+ --verbose) ;;
+@@ -39,6 +40,8 @@
+ --manmode=*) MANMODE=`echo $1 | sed 's/^[^=]*=//'` ;;
+ --with-c-compiler=*) CC=`echo $1 | sed 's/^[^=]*=//'` ;;
+ --without-readline|--disable-readline) WITHOUT_READLINE=1;;
++ --disable-ssl) ENABLE_SSL=no;;
++ --enable-ssl) ENABLE_SSL=yes;;
+ *) echo "Unrecognized option: $1"; exit 1;;
+ esac
+ shift
+@@ -152,3 +155,17 @@
+ rm -f __conftest*
+
++##################################################
++## Enable SSL
++echo -n "Whether to enable SSL support... "
++if [ x"$ENABLE_SSL" = x"yes" ]; then
++ echo yes
++ CFLAGS="$CFLAGS -DUSE_SSL"
++else
++ echo no
++fi
++
++## we should do tests here, but screw it, i'm lazy :P
++LIBS="$LIBS -lssl -lcrypto"
++
++
+ ##################################################
+--- netkit-ftp-0.17/ftp/cmds.c
++++ netkit-ftp-0.17+ssl-0.2/ftp/cmds.c
+@@ -207,6 +207,32 @@
+ }
+ port = ftp_port;
+ if (argc > 2) {
++#ifdef USE_SSL
++ /* not really an SSL enhancement but something that
++ * should have always been here --tjh
++ */
++ if (!isdigit(argv[2][0])) {
++ struct servent *destsp;
++
++ destsp = getservbyname(argv[2], "tcp");
++
++ /* if lookup fails for ssl-ftp we fallback to
++ * the default (unofficial) port number
++ */
++ if ((strcmp(argv[2],"ssl-ftp")==0) && (destsp==NULL))
++ port = 150;
++ else {
++ if (destsp == NULL ) {
++ printf("%s: bad port name-- %s\n",argv[1],argv[2]);
++ printf ("usage: %s host-name [port]\n",argv[0]);
++ code = -1;
++ return;
++ } else {
++ port = ntohs(destsp->s_port);
++ }
++ }
++ } else
++#endif /* USE_SSL */
+ port = atoi(argv[2]);
+ if (port < 1) {
+ printf("%s: bad port number-- %s\n", argv[1], argv[2]);
+--- netkit-ftp-0.17/ftp/ftp.1
++++ netkit-ftp-0.17+ssl-0.2/ftp/ftp.1
+@@ -97,6 +97,52 @@
+ as report on data transfer statistics.
+ .It Fl d
+ Enables debugging.
++.It Fl z Ar option
++Set SSL (Secure Socket Layer) parameters. The default is to negotiate
++via ftp protocoll if SSL is availlable at server side and then to
++switch it on. In this mode you can connect to both conventional and
++SSL enhanced ftpd's.
++.Pp
++The SSL parameters are:
++.Bl -tag -width Fl
++.It Ic Ar debug
++Send SSL related debugging information to stderr.
++.It Ic Ar authdebug
++Enable authentication debugging.
++.It Ic Ar ssl
++Negotiate SSL at first, then use ftp protocol. ftp protocol
++negotiation goes encrypted. (Not yet implemented)
++.It Ic Ar nossl, Ar !ssl
++switch of SSL negotiation
++.It Ic Ar certrequired
++client certificate is mandatory
++.It Ic Ar secure
++Don't switch back to unencrypted mode (no SSL) if SSL is not available.
++.It Ic Ar verbose
++Be verbose about certificates etc.
++.It Ic Ar verify=int
++.\" TODO
++Set the SSL verify flags (SSL_VERIFY_* in
++.Ar ssl/ssl.h
++).
++.\" TODO
++.It Ic Ar cert=cert_file
++.\" TODO
++Use the certificate(s) in
++.Ar cert_file .
++.It Ic Ar key=key_file
++.\" TODO
++Use the key(s) in
++.Ar key_file .
++.It Ic Ar cipher=ciph_list
++.\" TODO
++Set the preferred ciphers to
++.Ar ciph_list .
++.\" TODO: possible values; comma-separated list?
++(See
++.Ar ssl/ssl.h
++).
++.El
+ .El
+ .Pp
+ The client host with which
+--- netkit-ftp-0.17/ftp/ftp.c
++++ netkit-ftp-0.17+ssl-0.2/ftp/ftp.c
+@@ -1,3 +1,15 @@
++/*
++ * The modifications to support SSLeay were done by Tim Hudson
++ * tjh@cryptsoft.com
++ *
++ * You can do whatever you like with these patches except pretend that
++ * you wrote them.
++ *
++ * Email ssl-users-request@lists.cryptsoft.com to get instructions on how to
++ * join the mailing list that discusses SSLeay and also these patches.
++ *
++ */
++
+ /*
+ * Copyright (c) 1985, 1989 Regents of the University of California.
+ * All rights reserved.
+@@ -77,6 +89,17 @@
+ static sigjmp_buf ptabort;
+ static int ptabflg = 0;
+ static int abrtflag = 0;
++#ifdef USE_SSL
++static int pdata = -1;
++static int
++auth_user(char *u,char *p);
++static int
++ssl_getc(SSL *ssl_con);
++static int
++ssl_putc_flush(SSL *ssl_con);
++static int
++ssl_putc(SSL *ssl_con, int oneint);
++#endif
+
+ void lostpeer(int);
+ extern int connected;
+@@ -243,14 +266,7 @@
+ else
+ luser = tmp;
+ }
+- n = command("USER %s", luser);
+- if (n == CONTINUE) {
+- if (pass == NULL) {
+- /* fflush(stdout); */
+- pass = getpass("Password:");
+- }
+- n = command("PASS %s", pass);
+- }
++ n = auth_user(luser,pass);
+ if (n == CONTINUE) {
+ aflag++;
+ /* fflush(stdout); */
+@@ -296,6 +312,9 @@
+ va_list ap;
+ int r;
+ void (*oldintr)(int);
++#ifdef USE_SSL
++ char outputbuf[2048]; /* allow for a 2k command string */
++#endif /* USE_SSL */
+
+ abrtflag = 0;
+ if (debug) {
+@@ -316,10 +335,27 @@
+ }
+ oldintr = signal(SIGINT, cmdabort);
+ va_start(ap, fmt);
++#ifdef USE_SSL
++ /* assemble the output into a buffer */
++ vsprintf(outputbuf,fmt,ap);
++ strcat(outputbuf,"\r\n");
++ if (ssl_active_flag) {
++ SSL_write(ssl_con,outputbuf,strlen(outputbuf));
++ } else {
++ fprintf(cout,"%s",outputbuf);
++ fflush(cout);
++ }
++#else /* !USE_SSL */
+ vfprintf(cout, fmt, ap);
++#endif /* USE_SSL */
+ va_end(ap);
++
++#ifndef USE_SSL
++ /* we don't need this as we concatenated it above */
+ fprintf(cout, "\r\n");
+ (void) fflush(cout);
++#endif /* !USE_SSL */
++
+ cpend = 1;
+ r = getreply(!strcmp(fmt, "QUIT"));
+ if (abrtflag && oldintr != SIG_IGN)
+@@ -343,25 +379,39 @@
+ int pflag = 0;
+ size_t px = 0;
+ size_t psize = sizeof(pasv);
++ char buf[16];
+
+ oldintr = signal(SIGINT, cmdabort);
+ for (;;) {
+ dig = n = code = 0;
+ cp = reply_string;
+- while ((c = getc(cin)) != '\n') {
++ while ((c = GETC(cin)) != '\n') {
+ if (c == IAC) { /* handle telnet commands */
+- switch (c = getc(cin)) {
++ switch (c = GETC(cin)) {
+ case WILL:
+ case WONT:
+- c = getc(cin);
+- fprintf(cout, "%c%c%c", IAC, DONT, c);
+- (void) fflush(cout);
++ c = GETC(cin);
++ sprintf(buf,
++ "%c%c%c", IAC, DONT, c);
++#ifdef USE_SSL
++ if (ssl_active_flag)
++ SSL_write(ssl_con,buf,3);
++ else
++#endif /* !USE_SSL */
++ fwrite(buf,3,1,cout);
++ (void) FFLUSH(cout);
+ break;
+ case DO:
+ case DONT:
+- c = getc(cin);
+- fprintf(cout, "%c%c%c", IAC, WONT, c);
+- (void) fflush(cout);
++ c = GETC(cin);
++ sprintf(buf, "%c%c%c", IAC, WONT, c);
++#ifdef USE_SSL
++ if (ssl_active_flag)
++ SSL_write(ssl_con,buf,3);
++ else
++#endif /* !USE_SSL */
++ fwrite(buf,3,1,cout);
++ (void) FFLUSH(cout);
+ break;
+ default:
+ break;
+@@ -600,9 +650,18 @@
+ errno = d = 0;
+ while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) {
+ bytes += c;
++#ifdef USE_SSL
++ if (ssl_data_active_flag) {
++ for (bufp = buf; c > 0; c -= d, bufp += d)
++ if ((d = SSL_write(ssl_data_con, bufp, c)) <= 0)
++ break;
++ } else
++#endif /* !USE_SSL */
++ {
+ for (bufp = buf; c > 0; c -= d, bufp += d)
+ if ((d = write(fileno(dout), bufp, c)) <= 0)
+ break;
++ }
+ if (hash) {
+ while (bytes >= hashbytes) {
+ (void) putchar('#');
+@@ -654,16 +713,17 @@
+ }
+ if (ferror(dout))
+ break;
+- (void) putc('\r', dout);
++ (void) DATAPUTC('\r', dout);
+ bytes++;
+ }
+- (void) putc(c, dout);
++ (void) DATAPUTC(c, dout);
+ bytes++;
+ /* if (c == '\r') { */
+ /* (void) putc('\0', dout); (* this violates rfc */
+ /* bytes++; */
+ /* } */
+ }
++ DATAFLUSH(dout);
+ if (hash) {
+ if (bytes < hashbytes)
+ (void) putchar('#');
+@@ -688,6 +748,15 @@
+ if (closefunc != NULL)
+ (*closefunc)(fin);
+ (void) fclose(dout);
++
++#ifdef USE_SSL
++ if (ssl_data_active_flag && (ssl_data_con!=NULL)) {
++ SSL_free(ssl_data_con);
++ ssl_data_active_flag=0;
++ ssl_data_con=NULL;
++ }
++#endif /* USE_SSL */
++
+ /* closes data as well, so discard it */
+ data = -1;
+ (void) getreply(0);
+@@ -714,6 +783,15 @@
+ (void) close(data);
+ data = -1;
+ }
++
++#ifdef USE_SSL
++ if (ssl_data_active_flag && (ssl_data_con!=NULL)) {
++ SSL_free(ssl_data_con);
++ ssl_data_active_flag=0;
++ ssl_data_con=NULL;
++ }
++#endif /* USE_SSL */
++
+ (void) getreply(0);
+ code = -1;
+ if (closefunc != NULL && fin != NULL)
+@@ -908,6 +986,33 @@
+ return;
+ }
+ errno = d = 0;
++#ifdef USE_SSL
++ if (ssl_data_active_flag) {
++ while ((c = SSL_read(ssl_data_con, buf, bufsize)) > 0) {
++ if ((d = write(fileno(fout), buf, c)) != c)
++ break;
++ bytes += c;
++ if (hash) {
++ while (bytes >= hashbytes) {
++ (void) putchar('#');
++ hashbytes += HASHBYTES;
++ }
++ (void) fflush(stdout);
++ }
++ }
++ if ( c < -1 ) {
++ static char errbuf[1024];
++
++ sprintf(errbuf,"ftp: SSL_read DATA error %s\n",
++ ERR_error_string(ERR_get_error(),NULL));
++
++ /* tell the user ... who else */
++ fprintf(stderr,"%s", errbuf);
++ fflush(stderr);
++ }
++ } else
++#endif /* !USE_SSL */
++ {
+ while ((c = read(fileno(din), buf, bufsize)) > 0) {
+ if ((d = write(fileno(fout), buf, c)) != c)
+ break;
+@@ -927,6 +1032,7 @@
+ hashbytes += TICKBYTES;
+ }
+ }
++ }
+ if (hash && bytes > 0) {
+ if (bytes < HASHBYTES)
+ (void) putchar('#');
+@@ -973,7 +1079,7 @@
+ return;
+ }
+ }
+- while ((c = getc(din)) != EOF) {
++ while ((c = DATAGETC(din)) != EOF) {
+ if (c == '\n')
+ bare_lfs++;
+ while (c == '\r') {
+@@ -991,7 +1097,7 @@
+ hashbytes += TICKBYTES;
+ }
+ bytes++;
+- if ((c = getc(din)) != '\n' || tcrflag) {
++ if ((c = DATAGETC(din)) != '\n' || tcrflag) {
+ if (ferror(fout))
+ goto break2;
+ (void) putc('\r', fout);
+@@ -1039,6 +1145,15 @@
+ (void) signal(SIGPIPE, oldintp);
+ (void) gettimeofday(&stop, (struct timezone *)0);
+ (void) fclose(din);
++
++#ifdef USE_SSL
++ if (ssl_data_active_flag && (ssl_data_con!=NULL)) {
++ SSL_free(ssl_data_con);
++ ssl_data_active_flag=0;
++ ssl_data_con=NULL;
++ }
++#endif /* USE_SSL */
++
+ /* closes data as well, so discard it */
+ data = -1;
+ (void) getreply(0);
+@@ -1071,6 +1186,15 @@
+ (void) close(data);
+ data = -1;
+ }
++
++#ifdef USE_SSL
++ if (ssl_data_active_flag && (ssl_data_con!=NULL)) {
++ SSL_free(ssl_data_con);
++ ssl_data_active_flag=0;
++ ssl_data_con=NULL;
++ }
++#endif /* USE_SSL */
++
+ if (bytes > 0)
+ ptransfer("received", bytes, &start, &stop);
+ (void) signal(SIGINT, oldintr);
+@@ -1207,6 +1331,7 @@
+ struct sockaddr_in from;
+ int s, tos;
+ socklen_t fromlen = sizeof(from);
++ int ret;
+
+ if (passivemode)
+ return (fdopen(data, lmode));
+@@ -1224,6 +1349,67 @@
+ if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
+ perror("ftp: setsockopt TOS (ignored)");
+ #endif
++
++#ifdef USE_SSL
++ ssl_data_active_flag=0;
++ if (ssl_active_flag && ssl_encrypt_data) {
++ /* do SSL */
++ if (ssl_data_con!=NULL) {
++ SSL_free(ssl_data_con);
++ ssl_data_con=NULL;
++ }
++ ssl_data_con=(SSL *)SSL_new(ssl_ctx);
++
++ SSL_set_fd(ssl_data_con,data);
++ set_ssl_trace(ssl_data_con);
++
++ SSL_set_verify(ssl_data_con,ssl_verify_flag,NULL);
++
++ /* this is the "magic" call that makes
++ * this quick assuming Eric has this going
++ * okay! ;-)
++ */
++ SSL_copy_session_id(ssl_data_con,ssl_con);
++
++ /* we are doing I/O and not using select so
++ * it is "safe" to read ahead
++ */
++ /* SSL_set_read_ahead(ssl_data_con,1); */
++
++ if (debug) {
++ fprintf(stderr,"===>START SSL connect on DATA\n");
++ fflush(stderr);
++ }
++
++ if ((ret=SSL_connect(ssl_data_con))<=0) {
++ static char errbuf[1024];
++
++ sprintf(errbuf,"ftp: SSL_connect DATA error %d - %s\n",
++ ret,ERR_error_string(ERR_get_error(),NULL));
++
++ /* tell the user ... who else */
++ fprintf(stderr,"%s", errbuf);
++ fflush(stderr);
++
++ /* abort time methinks ... */
++ close(data);
++ return NULL;
++ } else {
++ if (ssl_debug_flag) {
++ BIO_printf(bio_err,"[SSL DATA Cipher %s]\n",
++ SSL_get_cipher(ssl_con));
++ }
++ ssl_data_active_flag=1;
++ }
++
++ if (debug) {
++ fprintf(stderr,"===>DONE SSL connect on DATA %d\n",data);
++ fflush(stderr);
++ }
++
++ }
++#endif /* USE_SSL */
++
+ return (fdopen(data, lmode));
+ }
+
+@@ -1609,3 +1795,142 @@
+ }
+ (void) getreply(0);
+ }
++
++static int
++auth_user(char *u,char *p)
++{
++ int n;
++
++#ifdef USE_SSL
++ if (ssl_enabled) {
++ n = command("AUTH SSL");
++ if (n == ERROR) { /* do normal USER/PASS */
++ printf("SSL not available\n");
++ /* spit the dummy as we will only talk ssl
++ * when running in "secure" mode
++ */
++ if (ssl_secure_flag)
++ return ERROR;
++ } else if (n == CONTINUE || n == COMPLETE) {
++ /* do SSL */
++ ssl_con=(SSL *)SSL_new(ssl_ctx);
++
++ SSL_set_fd(ssl_con,fileno(cout));
++ set_ssl_trace(ssl_con);
++
++ SSL_set_verify(ssl_con,ssl_verify_flag,NULL);
++
++ /* Add in any certificates if you want to here ... */
++ if (my_ssl_cert_file) {
++ if (!SSL_use_certificate_file(ssl_con, my_ssl_cert_file,
++ X509_FILETYPE_PEM)) {
++ fprintf(stderr,"%s: ",my_ssl_cert_file);
++ ERR_print_errors_fp(stderr);
++ exit(1);
++ } else {
++ if (!my_ssl_key_file)
++ my_ssl_key_file = my_ssl_cert_file;
++ if (!SSL_use_RSAPrivateKey_file(ssl_con, my_ssl_key_file,
++ X509_FILETYPE_PEM)) {
++ fprintf(stderr,"%s: ", my_ssl_key_file);
++ ERR_print_errors_fp(stderr);
++ exit(1);
++ }
++ }
++ }
++
++ if (SSL_connect(ssl_con)<=0) {
++ static char errbuf[1024];
++
++ sprintf(errbuf,"ftp: SSL_connect error %s\n",
++ ERR_error_string(ERR_get_error(),NULL));
++ perror(errbuf);
++ /* abort time methinks ... */
++ exit(1);
++ } else {
++ fprintf(stderr,"[SSL Cipher %s]\n",SSL_get_cipher(ssl_con));
++ fflush(stderr);
++ ssl_active_flag=1;
++ }
++
++ n = command("USER %s",u);
++ if (n == CONTINUE) {
++ if(p == NULL)
++ p = getpass("Password:");
++ n = command("PASS %s",p);
++ }
++ return (n);
++ }
++ }
++#endif /* USE_SSL */
++ n = command("USER %s",u);
++ if (n == CONTINUE) {
++ if(p == NULL)
++ p = getpass("Password:");
++ n = command("PASS %s",p);
++ }
++ return(n);
++}
++
++#ifdef USE_SSL
++
++/* we really shouldn't have code like this! --tjh */
++static int
++ssl_getc(SSL *ssl_con)
++{
++ char onebyte;
++ int ret;
++
++ if ((ret=SSL_read(ssl_con,&onebyte,1))!=1) {
++ /* we want to know this stuff! */
++ if (ssl_debug_flag || (ret!=0)) {
++ fprintf(stderr,"ssl_getc: SSL_read failed %d = %d\n",ret,errno);
++ fflush(stderr);
++ }
++ return -1;
++ } else {
++ if (ssl_debug_flag) {
++ BIO_printf(bio_err,"ssl_getc: SSL_read %d (%c) ",onebyte & 0xff,isprint(onebyte)?onebyte:'.');
++ }
++ return onebyte & 0xff;
++ }
++}
++
++
++/* got back to this an implemented some rather "simple" buffering */
++static char putc_buf[BUFSIZ];
++static int putc_buf_pos=0;
++
++static int
++ssl_putc_flush(SSL *ssl_con)
++{
++ if (putc_buf_pos>0) {
++ if (SSL_write(ssl_con,putc_buf,putc_buf_pos)!=putc_buf_pos) {
++ if (ssl_debug_flag) {
++ BIO_printf(bio_err,"ssl_putc_flush: WRITE FAILED\n");
++ }
++ putc_buf_pos=0;
++ return -1;
++ }
++ }
++ putc_buf_pos=0;
++ return 0;
++}
++
++int
++ssl_putc(SSL *ssl_con,int oneint)
++{
++ char onebyte;
++
++ onebyte = oneint & 0xff;
++
++ /* make sure there is space */
++ if (putc_buf_pos>=BUFSIZ)
++ if (ssl_putc_flush(ssl_con)!=0)
++ return EOF;
++ putc_buf[putc_buf_pos++]=onebyte;
++
++ return onebyte;
++}
++
++#endif /* USE_SSL */
+--- netkit-ftp-0.17/ftp/ftp_var.h
++++ netkit-ftp-0.17+ssl-0.2/ftp/ftp_var.h
+@@ -158,3 +158,6 @@
+ void setpeer(int argc, char *argv[]);
+ void quit(void);
+ void changetype(int newtype, int show);
++
++#include "sslapp.h"
++#include "ssl_port.h"
+--- netkit-ftp-0.17/ftp/main.c
++++ netkit-ftp-0.17+ssl-0.2/ftp/main.c
+@@ -1,3 +1,15 @@
++/*
++ * The modifications to support SSLeay were done by Tim Hudson
++ * tjh@cryptsoft.com
++ *
++ * You can do whatever you like with these patches except pretend that
++ * you wrote them.
++ *
++ * Email ssl-users-request@lists.cryptsoft.com to get instructions on how to
++ * join the mailing list that discusses SSLeay and also these patches.
++ *
++ */
++
+ /*
+ * Copyright (c) 1985, 1989 Regents of the University of California.
+ * All rights reserved.
+@@ -82,6 +94,75 @@
+ static void cmdscanner(int top);
+ static char *slurpstring(void);
+
++#ifdef USE_SSL
++
++/* icky way of doing things ... */
++#include "sslapp.c"
++
++/*
++#include "ssl_err.h"
++*/
++
++SSL *ssl_con;
++SSL *ssl_data_con;
++int ssl_data_active_flag=0;
++
++/* for the moment this is a compile time option only --tjh */
++int ssl_encrypt_data=1;
++int ssl_enabled=1;
++
++char *my_ssl_key_file=NULL;
++char *my_ssl_cert_file=NULL;
++
++BIO *bio_err=NULL;
++
++static long
++bio_dump_cb(BIO *bio,
++ int cmd,
++ char *argp,
++ int argi,
++ long argl,
++ long ret)
++ {
++ BIO *out;
++
++/*
++ out=(BIO *)BIO_get_callback_arg(bio);
++*/
++ out=bio_err;
++ if (out == NULL) return(ret);
++
++ if (cmd == (BIO_CB_READ|BIO_CB_RETURN))
++ {
++ BIO_printf(out,"read from %08X (%d bytes => %ld (%X))\n",
++ bio,argi,ret,ret);
++ BIO_dump(out,argp,(int)ret);
++ BIO_flush(out);
++ }
++ else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN))
++ {
++ BIO_printf(out,"write to %08X (%d bytes => %ld (%X))\n",
++ bio,argi,ret,ret);
++ BIO_dump(out,argp,(int)ret);
++ BIO_flush(out);
++ }
++ return( (cmd & BIO_CB_RETURN) ? ret : 1);
++ }
++
++int
++set_ssl_trace(SSL *con)
++{
++ if (con!=NULL) {
++ if (ssl_debug_flag) {
++ BIO_set_callback(SSL_get_rbio(con),bio_dump_cb);
++ BIO_set_callback_arg(SSL_get_rbio(con),bio_err);
++ }
++ }
++ return 0;
++}
++
++#endif /* USE_SSL */
++
+ static
+ void
+ usage(void)
+@@ -106,6 +187,7 @@
+ int top;
+ struct passwd *pw = NULL;
+ char homedir[MAXPATHLEN];
++ char *optarg;
+
+ tick = 0;
+
+@@ -134,6 +216,7 @@
+
+ argc--, argv++;
+ while (argc > 0 && **argv == '-') {
++ optarg=*(argv+1);
+ for (cp = *argv + 1; *cp; cp++)
+ switch (*cp) {
+
+@@ -174,6 +257,48 @@
+ usage();
+ exit(0);
+
++#ifdef USE_SSL
++ case 'z':
++ if (!optarg) {
++ fprintf(stderr, "ftp: the -z option requires an argument\n");
++ exit(1);
++ }
++ if (strcmp(optarg, "debug") == 0 ) {
++ ssl_debug_flag=1;
++ }
++ if (strcmp(optarg, "ssl") == 0 ) {
++ ssl_only_flag=1;
++ }
++ /* disable *all* ssl stuff */
++ if ( (strcmp(optarg, "!ssl") == 0 ) ||
++ (strcmp(optarg, "nossl") == 0 ) ) {
++ ssl_enabled=0;
++ }
++ if (strcmp(optarg, "secure") == 0 ) {
++ ssl_secure_flag=1;
++ }
++ if (strcmp(optarg, "certsok") == 0 ) {
++ ssl_certsok_flag=1;
++ }
++ if (strcmp(optarg, "verbose") == 0 ) {
++ ssl_verbose_flag=1;
++ }
++ if (strncmp(optarg, "verify=", strlen("verify=")) == 0 ) {
++ ssl_verify_flag=atoi(optarg+strlen("verify="));
++ }
++ if (strncmp(optarg, "cert=", strlen("cert=")) == 0 ) {
++ my_ssl_cert_file=optarg+strlen("cert=");
++ }
++ if (strncmp(optarg, "key=", strlen("key=")) == 0 ) {
++ my_ssl_key_file=optarg+strlen("key=");
++ }
++
++ /* we have swallowed an extra arg */
++ argc--;
++ argv++;
++ break;
++#endif /* USE_SSL */
++
+ default:
+ fprintf(stdout,
+ "ftp: %c: unknown option\n", *cp);
+@@ -202,6 +323,18 @@
+ homedir[sizeof(homedir)-1] = 0;
+ home = homedir;
+ }
++
++#ifdef USE_SSL
++ if (ssl_enabled) {
++ if (!do_ssleay_init(0)) {
++ fprintf(stderr,"ftp: SSLeay initialisation failed\n");
++ fflush(stderr);
++ ERR_print_errors_fp(stderr);
++ exit(1);
++ }
++ }
++#endif /* USE_SSL */
++
+ if (argc > 0) {
+ if (sigsetjmp(toplevel, 1))
+ exit(0);
+--- netkit-ftp-0.17/ftp/ssl_port.h
++++ netkit-ftp-0.17+ssl-0.2/ftp/ssl_port.h
+@@ -0,0 +1,85 @@
++/* ssl_port.h - standard porting things
++ *
++ * The modifications to support SSLeay were done by Tim Hudson
++ * tjh@mincom.oz.au
++ *
++ * You can do whatever you like with these patches except pretend that
++ * you wrote them.
++ *
++ * Email ssl-users-request@mincom.oz.au to get instructions on how to
++ * join the mailing list that discusses SSLeay and also these patches.
++ *
++ */
++
++#ifndef HEADER_SSL_PORT_H
++#define HEADER_SSL_PORT_H
++
++#ifdef USE_SSL
++
++#include <stdio.h>
++
++#define OLDPROTO NOPROTO
++#define NOPROTO
++#include <openssl/buffer.h>
++#undef NOPROTO
++#define NOPROTO OLDPROTO
++
++#include <openssl/x509.h>
++#include <openssl/ssl.h>
++#include <openssl/err.h>
++
++extern SSL *ssl_con;
++extern SSL_CTX *ssl_ctx;
++extern int ssl_debug_flag;
++extern int ssl_only_flag;
++extern int ssl_active_flag;
++extern int ssl_verify_flag;
++extern int ssl_secure_flag;
++extern int ssl_enabled;
++
++extern int ssl_encrypt_data;
++extern SSL *ssl_data_con;
++extern int ssl_data_active_flag;
++
++extern char *my_ssl_cert_file;
++extern char *my_ssl_key_file;
++extern int ssl_certsok_flag;
++
++extern int set_ssl_trace(SSL *s);
++
++extern FILE *cin, *cout;
++
++#define is_ssl_fd(X,Y) ( (SSL_get_fd((X))==0) || \
++ (SSL_get_fd((X))==1) || \
++ (SSL_get_fd((X))==pdata) || \
++ (SSL_get_fd((X))==(Y)) \
++ )
++
++#define is_ssl_fp(X,Y) ( ( (SSL_get_fd((X))==0) && (fileno((Y))==0) ) || \
++ ( (SSL_get_fd((X))==1) && (fileno((Y))==1) ) || \
++ ( (SSL_get_fd((X))==pdata) && \
++ (fileno((Y))==pdata) ) || \
++ (SSL_get_fd((X))==fileno(Y)) \
++ )
++
++/* these macros make things much easier to handle ... */
++
++#define FFLUSH(X) (ssl_active_flag && (((X)==cin)||((X)==cout)) ? 1 : fflush((X)) )
++
++#define GETC(X) (ssl_active_flag && (((X)==cin)||((X)==cout)) ? ssl_getc(ssl_con) : getc((X)) )
++
++#define DATAGETC(X) (ssl_data_active_flag && ((fileno(X)==data)||(fileno(X)==pdata)) ? ssl_getc(ssl_data_con) : getc((X)) )
++#define DATAPUTC(X,Y) (ssl_data_active_flag && ((fileno(Y)==data)||(fileno(Y)==pdata)) ? ssl_putc(ssl_data_con,(X)) : putc((X),(Y)) )
++#define DATAFLUSH(X) (ssl_data_active_flag && ((fileno(X)==data)||(fileno(X)==pdata)) ? ssl_putc_flush(ssl_data_con) : fflush((X)) )
++
++#else
++
++#define GETC(X) getc((X))
++#define DATAGETC(X) getc((X))
++#define DATAPUTC(X,Y) putc((X),(Y))
++#define DATAFLUSH(X) fflush((X))
++#define FFLUSH(X) fflush((X))
++
++#endif /* USE_SSL */
++
++#endif /* HEADER_SSL_PORT_H */
+--- netkit-ftp-0.17/ftp/sslapp.c
++++ netkit-ftp-0.17+ssl-0.2/ftp/sslapp.c
+@@ -0,0 +1,186 @@
++/* sslapp.c - ssl application code */
++
++/*
++ * The modifications to support SSLeay were done by Tim Hudson
++ * tjh@cryptsoft.com
++ *
++ * You can do whatever you like with these patches except pretend that
++ * you wrote them.
++ *
++ * Email ssl-users-request@lists.cryptsoft.com to get instructions on how to
++ * join the mailing list that discusses SSLeay and also these patches.
++ *
++ */
++
++#ifdef USE_SSL
++
++#include "sslapp.h"
++
++SSL_CTX *ssl_ctx;
++SSL *ssl_con;
++int ssl_debug_flag=0;
++int ssl_only_flag=0;
++int ssl_active_flag=0;
++int ssl_verify_flag=SSL_VERIFY_NONE;
++int ssl_secure_flag=0;
++int ssl_certsok_flag=0;
++int ssl_cert_required=0;
++int ssl_verbose_flag=0;
++int ssl_disabled_flag=0;
++char *ssl_cert_file=NULL;
++char *ssl_key_file=NULL;
++char *ssl_cipher_list=NULL;
++char *ssl_log_file=NULL;
++
++/* fwd decl */
++static void
++client_info_callback(SSL *s, int where, int ret);
++
++int
++do_ssleay_init(int server)
++{
++ char *p;
++
++ /* make sure we have somewhere we can log errors to */
++ if (bio_err==NULL) {
++ if ((bio_err=BIO_new(BIO_s_file()))!=NULL) {
++ if (ssl_log_file==NULL)
++ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE);
++ else {
++ if (BIO_write_filename(bio_err,ssl_log_file)<=0) {
++ /* not a lot we can do */
++ }
++ }
++ }
++ }
++
++ /* rather simple things these days ... the old SSL_LOG and SSL_ERR
++ * vars are long gone now SSLeay8 has rolled around and we have
++ * a clean interface for doing things
++ */
++ if (ssl_debug_flag)
++ BIO_printf(bio_err,"SSL_DEBUG_FLAG on\r\n");
++
++
++ /* init things so we will get meaningful error messages
++ * rather than numbers
++ */
++ SSL_load_error_strings();
++
++ SSLeay_add_ssl_algorithms();
++ ssl_ctx=(SSL_CTX *)SSL_CTX_new(SSLv23_method());
++
++ /* we may require a temp 512 bit RSA key because of the
++ * wonderful way export things work ... if so we generate
++ * one now!
++ */
++ if (server) {
++ if (SSL_CTX_need_tmp_RSA(ssl_ctx)) {
++ RSA *rsa;
++
++ if (ssl_debug_flag)
++ BIO_printf(bio_err,"Generating temp (512 bit) RSA key ...\r\n");
++ rsa=RSA_generate_key(512,RSA_F4,NULL,NULL);
++ if (ssl_debug_flag)
++ BIO_printf(bio_err,"Generation of temp (512 bit) RSA key done\r\n");
++
++ if (!SSL_CTX_set_tmp_rsa(ssl_ctx,rsa)) {
++ BIO_printf(bio_err,"Failed to assign generated temp RSA key!\r\n");
++ }
++ RSA_free(rsa);
++ if (ssl_debug_flag)
++ BIO_printf(bio_err,"Assigned temp (512 bit) RSA key\r\n");
++ }
++ }
++
++ /* also switch on all the interoperability and bug
++ * workarounds so that we will communicate with people
++ * that cannot read poorly written specs :-)
++ */
++ SSL_CTX_set_options(ssl_ctx,SSL_OP_ALL);
++
++ /* the user can set whatever ciphers they want to use */
++ if (ssl_cipher_list==NULL) {
++ p=getenv("SSL_CIPHER");
++ if (p!=NULL)
++ SSL_CTX_set_cipher_list(ssl_ctx,p);
++ } else
++ SSL_CTX_set_cipher_list(ssl_ctx,ssl_cipher_list);
++
++ /* for verbose we use the 0.6.x info callback that I got
++ * eric to finally add into the code :-) --tjh
++ */
++ if (ssl_verbose_flag) {
++ SSL_CTX_set_info_callback(ssl_ctx,client_info_callback);
++ }
++
++ /* Add in any certificates if you want to here ... */
++ if (ssl_cert_file) {
++ if (!SSL_CTX_use_certificate_file(ssl_ctx, ssl_cert_file,
++ X509_FILETYPE_PEM)) {
++ BIO_printf(bio_err,"Error loading %s: ",ssl_cert_file);
++ ERR_print_errors(bio_err);
++ BIO_printf(bio_err,"\r\n");
++ return(0);
++ } else {
++ if (!ssl_key_file)
++ ssl_key_file = ssl_cert_file;
++ if (!SSL_CTX_use_RSAPrivateKey_file(ssl_ctx, ssl_key_file,
++ X509_FILETYPE_PEM)) {
++ BIO_printf(bio_err,"Error loading %s: ",ssl_key_file);
++ ERR_print_errors(bio_err);
++ BIO_printf(bio_err,"\r\n");
++ return(0);
++ }
++ }
++ }
++
++ /* make sure we will find certificates in the standard
++ * location ... otherwise we don't look anywhere for
++ * these things which is going to make client certificate
++ * exchange rather useless :-)
++ */
++ SSL_CTX_set_default_verify_paths(ssl_ctx);
++
++ /* now create a connection */
++ ssl_con=(SSL *)SSL_new(ssl_ctx);
++ SSL_set_verify(ssl_con,ssl_verify_flag,NULL);
++
++#if 0
++ SSL_set_verify(ssl_con,ssl_verify_flag,client_verify_callback);
++#endif
++
++ return(1);
++}
++
++
++static void
++client_info_callback(SSL *s, int where, int ret)
++{
++ if (where==SSL_CB_CONNECT_LOOP) {
++ BIO_printf(bio_err,"SSL_connect:%s %s\r\n",
++ SSL_state_string(s),SSL_state_string_long(s));
++ } else if (where==SSL_CB_CONNECT_EXIT) {
++ if (ret == 0) {
++ BIO_printf(bio_err,"SSL_connect:failed in %s %s\r\n",
++ SSL_state_string(s),SSL_state_string_long(s));
++ } else if (ret < 0) {
++ BIO_printf(bio_err,"SSL_connect:error in %s %s\r\n",
++ SSL_state_string(s),SSL_state_string_long(s));
++ }
++ }
++}
++
++
++#else /* !USE_SSL */
++
++/* something here to stop warnings if we build without SSL support */
++static int dummy_func()
++{
++ int i;
++
++ i++;
++}
++
++#endif /* USE_SSL */
++
+--- netkit-ftp-0.17/ftp/sslapp.h
++++ netkit-ftp-0.17+ssl-0.2/ftp/sslapp.h
+@@ -0,0 +1,63 @@
++/* sslapp.h - ssl application code */
++
++/*
++ * The modifications to support SSLeay were done by Tim Hudson
++ * tjh@cryptsoft.com
++ *
++ * You can do whatever you like with these patches except pretend that
++ * you wrote them.
++ *
++ * Email ssl-users-request@mincom.oz.au to get instructions on how to
++ * join the mailing list that discusses SSLeay and also these patches.
++ *
++ */
++
++#ifdef USE_SSL
++
++#include <stdio.h>
++
++#include <openssl/crypto.h>
++
++#define SSL_set_pref_cipher(c,n) SSL_set_cipher_list(c,n)
++#define ONELINE_NAME(X) X509_NAME_oneline(X,NULL,0)
++
++#define OLDPROTO NOPROTO
++#define NOPROTO
++#include <openssl/bio.h>
++#undef NOPROTO
++#define NOPROTO OLDPROTO
++#undef OLDPROTO
++#include <openssl/buffer.h>
++
++#include <openssl/x509.h>
++#include <openssl/ssl.h>
++#include <openssl/err.h>
++
++extern BIO *bio_err;
++extern SSL *ssl_con;
++extern SSL_CTX *ssl_ctx;
++extern int ssl_debug_flag;
++extern int ssl_only_flag;
++extern int ssl_active_flag;
++extern int ssl_verify_flag;
++extern int ssl_secure_flag;
++extern int ssl_verbose_flag;
++extern int ssl_disabled_flag;
++extern int ssl_cert_required;
++extern int ssl_certsok_flag;
++
++extern char *ssl_log_file;
++extern char *ssl_cert_file;
++extern char *ssl_key_file;
++extern char *ssl_cipher_list;
++
++/* we hide all the initialisation code in a separate file now */
++extern int do_ssleay_init(int server);
++
++/*extern int display_connect_details();
++extern int server_verify_callback();
++extern int client_verify_callback();*/
++
++#endif /* USE_SSL */
++
++
diff --git a/net-ftp/ftp/ftp-0.17-r3.ebuild b/net-ftp/ftp/ftp-0.17-r3.ebuild
index c6e2056532a0..1b9ef2fa0b15 100644
--- a/net-ftp/ftp/ftp-0.17-r3.ebuild
+++ b/net-ftp/ftp/ftp-0.17-r3.ebuild
@@ -1,6 +1,6 @@
-# Copyright 1999-2004 Gentoo Foundation
+# Copyright 1999-2005 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/net-ftp/ftp/ftp-0.17-r3.ebuild,v 1.14 2004/06/24 22:45:04 agriffis Exp $
+# $Header: /var/cvsroot/gentoo-x86/net-ftp/ftp/ftp-0.17-r3.ebuild,v 1.15 2005/02/12 00:18:41 vapier Exp $
inherit eutils
diff --git a/net-ftp/ftp/ftp-0.17-r4.ebuild b/net-ftp/ftp/ftp-0.17-r4.ebuild
new file mode 100644
index 000000000000..6c756cf04cff
--- /dev/null
+++ b/net-ftp/ftp/ftp-0.17-r4.ebuild
@@ -0,0 +1,49 @@
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/net-ftp/ftp/ftp-0.17-r4.ebuild,v 1.1 2005/02/12 00:18:41 vapier Exp $
+
+inherit eutils
+
+MY_P=netkit-${P}
+S=${WORKDIR}/${MY_P}
+DESCRIPTION="Standard Linux FTP client"
+HOMEPAGE="http://www.hcs.harvard.edu/~dholland/computers/netkit.html"
+SRC_URI="ftp://ftp.uk.linux.org/pub/linux/Networking/netkit/${MY_P}.tar.gz"
+
+LICENSE="as-is"
+SLOT="0"
+KEYWORDS="~alpha ~amd64 ~arm ~hppa ~ia64 ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86"
+IUSE="ssl ipv6"
+
+RDEPEND=">=sys-libs/ncurses-5.2
+ ssl? ( dev-libs/openssl )"
+DEPEND="${RDEPEND}
+ >=sys-apps/sed-4"
+
+src_unpack() {
+ unpack ${A}
+ cd ${S}
+ epatch ${FILESDIR}/${MY_P}-ssl-0.2.patch
+ epatch ${FILESDIR}/${MY_P}-ipv6.patch #47507
+ epatch ${FILESDIR}/${MY_P}-acct.patch #fedora
+ epatch ${FILESDIR}/${MY_P}-locale.patch #fedora
+ epatch ${FILESDIR}/${MY_P}-runique_mget.patch #fedora
+ epatch ${FILESDIR}/${MY_P}-security.patch #fedora
+ epatch ${FILESDIR}/${MY_P}-custom-cflags.patch
+}
+
+src_compile() {
+ ./configure \
+ --prefix=/usr \
+ $(use_enable ssl) \
+ $(use_enable ipv6) \
+ ${EXTRA_ECONF} \
+ || die "configure failed"
+ emake || die "make failed"
+}
+
+src_install() {
+ dobin ftp/ftp || die
+ doman ftp/ftp.1 ftp/netrc.5
+ dodoc ChangeLog README BUGS
+}