NetBSD Problem Report #47276

From www@NetBSD.org  Mon Dec  3 06:49:32 2012
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
	by www.NetBSD.org (Postfix) with ESMTP id D562663E6A5
	for <gnats-bugs@gnats.NetBSD.org>; Mon,  3 Dec 2012 06:49:31 +0000 (UTC)
Message-Id: <20121203064928.387CA63E6A5@www.NetBSD.org>
Date: Mon,  3 Dec 2012 06:49:27 +0000 (UTC)
From: nonakap@gmail.com
Reply-To: nonakap@gmail.com
To: gnats-bugs@NetBSD.org
Subject: ftp(1) is not supported https
X-Send-Pr-Version: www-1.0

>Number:         47276
>Category:       bin
>Synopsis:       ftp(1) is not supported https
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          closed
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Mon Dec 03 06:50:01 +0000 2012
>Closed-Date:    Mon Oct 07 06:54:52 +0000 2013
>Last-Modified:  Fri Oct 31 18:50:03 +0000 2014
>Originator:     NONAKA Kimihiro
>Release:        6.99.15
>Organization:
>Environment:
NetBSD netbsd-vm 6.99.15 NetBSD 6.99.15 (KOHARU) #7: Tue Nov 13 12:08:09 JST 2012  nonaka@netbsd-vm:/usr/obj.i386/sys/arch/i386/compile/KOHARU i386
>Description:
ftp(1) is not supported https.
>How-To-Repeat:
Download a file from https:// using ftp(1).
>Fix:
apply following patch.
(most code from libfetch)

diff --git a/distrib/amd64/cdroms/Makefile.cdrom b/distrib/amd64/cdroms/Makefile.cdrom
index 995099d..a1b68b5 100644
--- a/distrib/amd64/cdroms/Makefile.cdrom
+++ b/distrib/amd64/cdroms/Makefile.cdrom
@@ -55,6 +55,10 @@ CDRUNTIME+=	./usr/sbin/installboot
 CDRUNTIME+=	./usr/sbin/wiconfig
 CDRUNTIME+=	./usr/share/misc/terminfo.cdb
 CDRUNTIME+=	./usr/share/locale
+.if (${MKCRYPTO} != "no")
+CDRUNTIME+=	./usr/lib/libcrypto.so*
+CDRUNTIME+=	./usr/lib/libssl.so*
+.endif

 image_md_pre:
 	${MKDIR} cdrom/libexec/dhcpcd-hooks
diff --git a/distrib/i386/cdroms/Makefile.cdrom b/distrib/i386/cdroms/Makefile.cdrom
index 33c1129..a5eedbd 100644
--- a/distrib/i386/cdroms/Makefile.cdrom
+++ b/distrib/i386/cdroms/Makefile.cdrom
@@ -55,6 +55,10 @@ CDRUNTIME+=	./usr/sbin/installboot
 CDRUNTIME+=	./usr/sbin/wiconfig
 CDRUNTIME+=	./usr/share/misc/terminfo.cdb
 CDRUNTIME+=	./usr/share/locale
+.if (${MKCRYPTO} != "no")
+CDRUNTIME+=	./usr/lib/libcrypto.so*
+CDRUNTIME+=	./usr/lib/libssl.so*
+.endif

 image_md_pre:
 	${MKDIR} cdrom/libexec/dhcpcd-hooks
diff --git a/rescue/list.crypto b/rescue/list.crypto
index 345c445..979c127 100644
--- a/rescue/list.crypto
+++ b/rescue/list.crypto
@@ -7,4 +7,4 @@ PROG	ssh		slogin
 SPECIAL	scp	srcdir	crypto/external/bsd/openssh/bin/scp
 SPECIAL	ssh	srcdir	crypto/external/bsd/openssh/bin/ssh

-LIBS	-lssh -lcrypto
+LIBS	-lssh -lssl -lcrypto
diff --git a/usr.bin/ftp/Makefile b/usr.bin/ftp/Makefile
index d1135ae..fb97dde 100644
--- a/usr.bin/ftp/Makefile
+++ b/usr.bin/ftp/Makefile
@@ -18,6 +18,11 @@ CPPFLAGS+=-DNO_EDITCOMPLETE -DNO_ABOUT -DNO_AUTH -DNO_HELP -DNO_STATUS -DNO_DEBU
 .else
 LDADD+=	-ledit -lterminfo
 DPADD+=	${LIBEDIT} ${LIBTERMINFO}
+.if (${MKCRYPTO} != "no")
+CPPFLAGS+= -DWITH_SSL
+LDADD+= -lssl -lcrypto
+DPADD+= ${LIBSSL} ${LIBCRYPTO}
+.endif
 .endif

 .if (!defined(SMALLPROG) || defined(SMALLPROG_INET6)) && (${USE_INET6} != "no")
diff --git a/usr.bin/ftp/fetch.c b/usr.bin/ftp/fetch.c
index 30087f8..e4f1d17 100644
--- a/usr.bin/ftp/fetch.c
+++ b/usr.bin/ftp/fetch.c
@@ -64,12 +64,24 @@ __RCSID("$NetBSD: fetch.c,v 1.198 2012/07/04 06:09:37 is Exp $");
 #include <unistd.h>
 #include <time.h>

+#ifdef WITH_SSL
+#include <netinet/tcp.h>
+#include <openssl/crypto.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#endif
+
 #include "ftp_var.h"
 #include "version.h"

 typedef enum {
 	UNKNOWN_URL_T=-1,
 	HTTP_URL_T,
+#ifdef WITH_SSL
+	HTTPS_URL_T,
+#endif
 	FTP_URL_T,
 	FILE_URL_T,
 	CLASSIC_URL_T
@@ -100,7 +112,563 @@ static int	redirect_loop;
 #define	FILE_URL	"file://"	/* file URL prefix */
 #define	FTP_URL		"ftp://"	/* ftp URL prefix */
 #define	HTTP_URL	"http://"	/* http URL prefix */
+#ifdef WITH_SSL
+#define	HTTPS_URL	"https://"	/* https URL prefix */
+
+#define	IS_HTTP_TYPE(urltype) \
+	(((urltype) == HTTP_URL_T) || ((urltype) == HTTPS_URL_T))
+
+struct fetch_connect {
+	int			 sd;		/* file/socket descriptor */
+	char			*buf;		/* buffer */
+	size_t			 bufsize;	/* buffer size */
+	size_t			 bufpos;
+	size_t			 buflen;	/* length of buffer contents */
+	struct {				/* data cached after an
+						   interrupted read */
+		char	*buf;
+		size_t	 size;
+		size_t	 pos;
+		size_t	 len;
+	} cache;
+	int 			 issock;
+	int			 iserr;
+	int			 iseof;
+	SSL			*ssl;		/* SSL handle */
+};
+typedef struct fetch_connect fetch_connect_t;
+
+/*
+ * Write a vector to a connection w/ timeout
+ * Note: can modify the iovec.
+ */
+static ssize_t
+fetch_writev(fetch_connect_t *conn, struct iovec *iov, int iovcnt)
+{
+	struct timeval now, timeout, delta;
+	fd_set writefds;
+	ssize_t len, total;
+	int r;
+
+	if (quit_time > 0) {
+		FD_ZERO(&writefds);
+		gettimeofday(&timeout, NULL);
+		timeout.tv_sec += quit_time;
+	}
+
+	total = 0;
+	while (iovcnt > 0) {
+		while (quit_time > 0 && !FD_ISSET(conn->sd, &writefds)) {
+			FD_SET(conn->sd, &writefds);
+			gettimeofday(&now, NULL);
+			delta.tv_sec = timeout.tv_sec - now.tv_sec;
+			delta.tv_usec = timeout.tv_usec - now.tv_usec;
+			if (delta.tv_usec < 0) {
+				delta.tv_usec += 1000000;
+				delta.tv_sec--;
+			}
+			if (delta.tv_sec < 0) {
+				errno = ETIMEDOUT;
+				return (-1);
+			}
+			errno = 0;
+			r = select(conn->sd + 1, NULL, &writefds, NULL, &delta);
+			if (r == -1) {
+				if (errno == EINTR)
+					continue;
+				return (-1);
+			}
+		}
+		errno = 0;
+		if (conn->ssl != NULL)
+			len = SSL_write(conn->ssl, iov->iov_base, iov->iov_len);
+		else
+			len = writev(conn->sd, iov, iovcnt);
+		if (len == 0) {
+			/* we consider a short write a failure */
+			/* XXX perhaps we shouldn't in the SSL case */
+			errno = EPIPE;
+			return (-1);
+		}
+		if (len < 0) {
+			if (errno == EINTR)
+				continue;
+			return (-1);
+		}
+		total += len;
+		while (iovcnt > 0 && len >= (ssize_t)iov->iov_len) {
+			len -= iov->iov_len;
+			iov++;
+			iovcnt--;
+		}
+		if (iovcnt > 0) {
+			iov->iov_len -= len;
+			iov->iov_base = (char *)iov->iov_base + len;
+		}
+	}
+	return (total);
+}
+
+/*
+ * Write to a connection w/ timeout
+ */
+static int
+fetch_write(fetch_connect_t *conn, const char *str, size_t len)
+{
+	struct iovec iov[1];
+
+	iov[0].iov_base = (char *)__UNCONST(str);
+	iov[0].iov_len = len;
+	return (fetch_writev(conn, iov, 1));
+}
+
+/*
+ * Send a formatted line; optionally echo to terminal
+ */
+static int
+fetch_printf(fetch_connect_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;
+		return (-1);
+	}
+
+	r = fetch_write(conn, msg, len);
+	free(msg);
+	return (r);
+}
+
+static int
+fetch_fileno(fetch_connect_t *conn)
+{
+
+	return (conn->sd);
+}
+
+static int
+fetch_error(fetch_connect_t *conn)
+{
+
+	return (conn->iserr);
+}
+static void
+fetch_clearerr(fetch_connect_t *conn)
+{
+
+	conn->iserr = 0;
+}
+
+static int
+fetch_flush(fetch_connect_t *conn)
+{
+	int v;
+
+	if (conn->issock) {
+#ifdef TCP_NOPUSH
+		v = 0;
+		setsockopt(conn->sd, IPPROTO_TCP, TCP_NOPUSH, &v, sizeof(v));
+#endif
+		v = 1;
+		setsockopt(conn->sd, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v));
+	}
+	return (0);
+}
+
+static fetch_connect_t *
+fetch_open(const char *fname, const char *fmode)
+{
+	fetch_connect_t *conn;
+	int fd;
+
+	fd = open(fname, O_RDONLY); /* XXX */
+	if (fd < 0)
+		return (NULL);
+
+	if ((conn = calloc(1, sizeof(*conn))) == NULL) {
+		close(fd);
+		return (NULL);
+	}
+
+	conn->sd = fd;
+	conn->issock = 0;
+	return (conn);
+}
+
+static fetch_connect_t *
+fetch_fdopen(int sd, const char *fmode)
+{
+	fetch_connect_t *conn;
+	int opt = 1;
+
+	if ((conn = calloc(1, sizeof(*conn))) == NULL)
+		return (NULL);
+
+	conn->sd = sd;
+	conn->issock = 1;
+	fcntl(sd, F_SETFD, FD_CLOEXEC);
+	setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
+#ifdef TCP_NOPUSH
+	setsockopt(sd, IPPROTO_TCP, TCP_NOPUSH, &opt, sizeof(opt));
+#endif
+	return (conn);
+}
+
+static int
+fetch_close(fetch_connect_t *conn)
+{
+	int rv = 0;
+
+	if (conn != NULL) {
+		fetch_flush(conn);
+		SSL_free(conn->ssl);
+		rv = close(conn->sd);
+		if (rv < 0) {
+			errno = rv;
+			rv = EOF;
+		}
+		free(conn->cache.buf);
+		free(conn->buf);
+		free(conn);
+	}
+	return (rv);
+}
+
+#define FETCH_READ_WAIT		-2
+#define FETCH_READ_ERROR	-1
+
+static ssize_t
+fetch_ssl_read(SSL *ssl, void *buf, size_t len)
+{
+	ssize_t rlen;
+	int ssl_err;
+
+	rlen = SSL_read(ssl, buf, len);
+	if (rlen < 0) {
+		ssl_err = SSL_get_error(ssl, rlen);
+		if (ssl_err == SSL_ERROR_WANT_READ ||
+		    ssl_err == SSL_ERROR_WANT_WRITE) {
+			return (FETCH_READ_WAIT);
+		}
+		ERR_print_errors_fp(ttyout);
+		return (FETCH_READ_ERROR);
+	}
+	return (rlen);
+}
+
+static ssize_t
+fetch_nonssl_read(int sd, void *buf, size_t len)
+{
+	ssize_t rlen;
+
+	rlen = read(sd, buf, len);
+	if (rlen < 0) {
+		if (errno == EAGAIN || errno == EINTR)
+			return (FETCH_READ_WAIT);
+		return (FETCH_READ_ERROR);
+	}
+	return (rlen);
+}

+/*
+ * Cache some data that was read from a socket but cannot be immediately
+ * returned because of an interrupted system call.
+ */
+static int
+fetch_cache_data(fetch_connect_t *conn, char *src, size_t nbytes)
+{
+
+	if (conn->cache.size < nbytes) {
+		char *tmp = realloc(conn->cache.buf, nbytes);
+		if (tmp == NULL)
+			return (-1);
+
+		conn->cache.buf = tmp;
+		conn->cache.size = nbytes;
+	}
+
+	memcpy(conn->cache.buf, src, nbytes);
+	conn->cache.len = nbytes;
+	conn->cache.pos = 0;
+	return (0);
+}
+
+static ssize_t
+fetch_read(void *ptr, size_t size, size_t nmemb, fetch_connect_t *conn)
+{
+	struct timeval now, timeout, delta;
+	fd_set readfds;
+	ssize_t rlen, total;
+	size_t len;
+	char *start, *buf;
+
+	if (quit_time > 0) {
+		gettimeofday(&timeout, NULL);
+		timeout.tv_sec += quit_time;
+	}
+
+	total = 0;
+	start = buf = ptr;
+	len = size * nmemb;
+
+	if (conn->cache.len > 0) {
+		/*
+		 * The last invocation of fetch_read was interrupted by a
+		 * signal after some data had been read from the socket. Copy
+		 * the cached data into the supplied buffer before trying to
+		 * read from the socket again.
+		 */
+		total = (conn->cache.len < len) ? conn->cache.len : len;
+		memcpy(buf, conn->cache.buf, total);
+
+		conn->cache.len -= total;
+		conn->cache.pos += total;
+		len -= total;
+		buf += total;
+	}
+
+	while (len > 0) {
+		/*
+		 * The socket is non-blocking.  Instead of the canonical
+		 * select() -> read(), we do the following:
+		 *
+		 * 1) call read() or SSL_read().
+		 * 2) if an error occurred, return -1.
+		 * 3) if we received data but we still expect more,
+		 *    update our counters and loop.
+		 * 4) if read() or SSL_read() signaled EOF, return.
+		 * 5) if we did not receive any data but we're not at EOF,
+		 *    call select().
+		 *
+		 * In the SSL case, this is necessary because if we
+		 * receive a close notification, we have to call
+		 * SSL_read() one additional time after we've read
+		 * everything we received.
+		 *
+		 * In the non-SSL case, it may improve performance (very
+		 * slightly) when reading small amounts of data.
+		 */
+		if (conn->ssl != NULL)
+			rlen = fetch_ssl_read(conn->ssl, buf, len);
+		else
+			rlen = fetch_nonssl_read(conn->sd, buf, len);
+		if (rlen == 0) {
+			break;
+		} else if (rlen > 0) {
+			len -= rlen;
+			buf += rlen;
+			total += rlen;
+			continue;
+		} else if (rlen == FETCH_READ_ERROR) {
+			if (errno == EINTR)
+				fetch_cache_data(conn, start, total);
+			return (-1);
+		}
+		FD_ZERO(&readfds);
+		while (!FD_ISSET(conn->sd, &readfds)) {
+			FD_SET(conn->sd, &readfds);
+			if (quit_time > 0) {
+				gettimeofday(&now, NULL);
+				if (!timercmp(&timeout, &now, >)) {
+					errno = ETIMEDOUT;
+					return (-1);
+				}
+				timersub(&timeout, &now, &delta);
+			}
+			errno = 0;
+			if (select(conn->sd + 1, &readfds, NULL, NULL,
+				quit_time > 0 ? &delta : NULL) < 0) {
+				if (errno == EINTR)
+					continue;
+				return (-1);
+			}
+		}
+	}
+	return (total);
+}
+
+#define MIN_BUF_SIZE 1024
+
+/*
+ * Read a line of text from a connection w/ timeout
+ */
+static char *
+fetch_getln(char *str, int size, fetch_connect_t *conn)
+{
+	size_t tmpsize;
+	ssize_t len;
+	char c;
+
+	if (conn->buf == NULL) {
+		if ((conn->buf = malloc(MIN_BUF_SIZE)) == NULL) {
+			errno = ENOMEM;
+			conn->iserr = 1;
+			return (NULL);
+		}
+		conn->bufsize = MIN_BUF_SIZE;
+	}
+
+	if (conn->iserr || conn->iseof)
+		return (NULL);
+
+	if (conn->buflen - conn->bufpos > 0)
+		goto done;
+
+	conn->buf[0] = '\0';
+	conn->bufpos = 0;
+	conn->buflen = 0;
+	do {
+		len = fetch_read(&c, sizeof(c), 1, conn);
+		if (len == -1) {
+			conn->iserr = 1;
+			return (NULL);
+		}
+		if (len == 0) {
+			conn->iseof = 1;
+			break;
+		}
+		conn->buf[conn->buflen++] = c;
+		if (conn->buflen == conn->bufsize) {
+			char *tmp = conn->buf;
+			tmpsize = conn->bufsize * 2 + 1;
+			if ((tmp = realloc(tmp, tmpsize)) == NULL) {
+				errno = ENOMEM;
+				conn->iserr = 1;
+				return (NULL);
+			}
+			conn->buf = tmp;
+			conn->bufsize = tmpsize;
+		}
+	} while (c != '\n');
+
+	if (conn->buflen == 0)
+		return (NULL);
+ done:
+	tmpsize = MIN(size - 1, (int)(conn->buflen - conn->bufpos));
+	memcpy(str, conn->buf + conn->bufpos, tmpsize);
+	str[tmpsize] = '\0';
+	conn->bufpos += tmpsize;
+	return (str);
+}
+
+static int
+fetch_getline(fetch_connect_t *conn, char *buf, size_t buflen,
+    const char **errormsg)
+{
+	size_t len;
+	int rv;
+
+	if (fetch_getln(buf, buflen, conn) == NULL) {
+		if (conn->iseof) {	/* EOF */
+			rv = -2;
+			if (errormsg)
+				*errormsg = "\nEOF received";
+		} else {		/* error */
+			rv = -1;
+			if (errormsg)
+				*errormsg = "Error encountered";
+		}
+		fetch_clearerr(conn);
+		return (rv);
+	}
+	len = strlen(buf);
+	if (buf[len - 1] == '\n') {	/* clear any trailing newline */
+		buf[--len] = '\0';
+	} else if (len == buflen - 1) {	/* line too long */
+		while (1) {
+			char c;
+			ssize_t rlen = fetch_read(&c, sizeof(c), 1, conn);
+			if (rlen <= 0 || c == '\n')
+				break;
+		}
+		if (errormsg)
+			*errormsg = "Input line is too long";
+		fetch_clearerr(conn);
+		return (-3);
+	}
+	if (errormsg)
+		*errormsg = NULL;
+	return (len);
+}
+
+static SSL *
+fetch_start_ssl(int sock)
+{
+	SSL *ssl;
+	SSL_CTX *ctx;
+	int ret, ssl_err;
+
+	/* Init the SSL library and context */
+	if (!SSL_library_init()){
+		fprintf(ttyout, "SSL library init failed\n");
+		return (NULL);
+	}
+
+	SSL_load_error_strings();
+
+	ctx = SSL_CTX_new(SSLv23_client_method());
+	SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
+
+	ssl = SSL_new(ctx);
+	if (ssl == NULL){
+		fprintf(ttyout, "SSL context creation failed\n");
+		SSL_CTX_free(ctx);
+		return (NULL);
+	}
+	SSL_set_fd(ssl, sock);
+	while ((ret = SSL_connect(ssl)) == -1) {
+		ssl_err = SSL_get_error(ssl, ret);
+		if (ssl_err != SSL_ERROR_WANT_READ &&
+		    ssl_err != SSL_ERROR_WANT_WRITE) {
+			ERR_print_errors_fp(ttyout);
+			SSL_free(ssl);
+			return (NULL);
+		}
+	}
+
+	if (ftp_debug && verbose) {
+		X509 *cert;
+		X509_NAME *name;
+		char *str;
+
+		fprintf(ttyout, "SSL connection established using %s\n",
+		    SSL_get_cipher(ssl));
+		cert = SSL_get_peer_certificate(ssl);
+		name = X509_get_subject_name(cert);
+		str = X509_NAME_oneline(name, 0, 0);
+		fprintf(ttyout, "Certificate subject: %s\n", str);
+		free(str);
+		name = X509_get_issuer_name(cert);
+		str = X509_NAME_oneline(name, 0, 0);
+		fprintf(ttyout, "Certificate issuer: %s\n", str);
+		free(str);
+	}
+
+	return (ssl);
+}
+
+#else	/* !WITH_SSL */
+#define	IS_HTTP_TYPE(urltype)	((urltype) == HTTP_URL_T)
+typedef FILE fetch_connect_t;
+#define	fetch_printf	fprintf
+#define	fetch_fileno	fileno
+#define	fetch_error	ferror
+#define	fetch_flush	fflush
+#define	fetch_open	fopen
+#define	fetch_fdopen	fdopen
+#define	fetch_close	fclose
+#define	fetch_read	fread
+#define	fetch_getln	fgets
+#define	fetch_getline	get_line
+#endif	/* !WITH_SSL */

 /*
  * Determine if token is the next word in buf (case insensitive).
@@ -346,6 +914,13 @@ parse_url(const char *url, const char *desc, url_t *utype,
 	} else if (STRNEQUAL(url, FILE_URL)) {
 		url += sizeof(FILE_URL) - 1;
 		*utype = FILE_URL_T;
+#ifdef WITH_SSL
+	} else if (STRNEQUAL(url, HTTPS_URL)) {
+		url += sizeof(HTTPS_URL) - 1;
+		*utype = HTTPS_URL_T;
+		*portnum = HTTPS_PORT;
+		tport = httpsport;
+#endif
 	} else {
 		warnx("Invalid %s `%s'", desc, url);
  cleanup_parse_url:
@@ -498,17 +1073,21 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
 	char			*puser, *ppass, *useragent;
 	off_t			hashbytes, rangestart, rangeend, entitylen;
 	int			(*volatile closefunc)(FILE *);
-	FILE			*volatile fin;
+	fetch_connect_t		*volatile fin;
 	FILE			*volatile fout;
 	time_t			mtime;
 	url_t			urltype;
 	in_port_t		portnum;
+#ifdef WITH_SSL
+	SSL			*ssl;
+#endif

 	DPRINTF("fetch_url: `%s' proxyenv `%s'\n", url, STRorNULL(proxyenv));

 	oldintr = oldintp = NULL;
 	closefunc = NULL;
-	fin = fout = NULL;
+	fin = NULL;
+	fout = NULL;
 	s = -1;
 	savefile = NULL;
 	auth = location = message = NULL;
@@ -531,7 +1110,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
 			rval = fetch_ftp(url);
 			goto cleanup_fetch_url;
 		}
-		if (urltype != HTTP_URL_T || outfile == NULL)  {
+		if (!IS_HTTP_TYPE(urltype) || outfile == NULL)  {
 			warnx("Invalid URL (no file after host) `%s'", url);
 			goto cleanup_fetch_url;
 		}
@@ -571,17 +1150,17 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
 	}
 	if (urltype == FILE_URL_T) {		/* file:// URLs */
 		direction = "copied";
-		fin = fopen(decodedpath, "r");
+		fin = fetch_open(decodedpath, "r");
 		if (fin == NULL) {
 			warn("Can't open `%s'", decodedpath);
 			goto cleanup_fetch_url;
 		}
-		if (fstat(fileno(fin), &sb) == 0) {
+		if (fstat(fetch_fileno(fin), &sb) == 0) {
 			mtime = sb.st_mtime;
 			filesize = sb.st_size;
 		}
 		if (restart_point) {
-			if (lseek(fileno(fin), restart_point, SEEK_SET) < 0) {
+			if (lseek(fetch_fileno(fin), restart_point, SEEK_SET) < 0) {
 				warn("Can't seek to restart `%s'",
 				    decodedpath);
 				goto cleanup_fetch_url;
@@ -594,12 +1173,15 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
 				    (LLT)restart_point);
 			fputs("\n", ttyout);
 		}
+		if (0 == rcvbuf_size) {
+			rcvbuf_size = 8 * 1024; /* XXX */
+		}
 	} else {				/* ftp:// or http:// URLs */
 		const char *leading;
 		int hasleading;

 		if (proxyenv == NULL) {
-			if (urltype == HTTP_URL_T)
+			if (IS_HTTP_TYPE(urltype))
 				proxyenv = getoptionvalue("http_proxy");
 			else if (urltype == FTP_URL_T)
 				proxyenv = getoptionvalue("ftp_proxy");
@@ -660,7 +1242,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
 				    &ppath) == -1)
 					goto cleanup_fetch_url;

-				if ((purltype != HTTP_URL_T
+				if ((!IS_HTTP_TYPE(purltype)
 				     && purltype != FTP_URL_T) ||
 				    EMPTYSTRING(phost) ||
 				    (! EMPTYSTRING(ppath)
@@ -690,6 +1272,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
 				FREEPTR(path);
 				path = ftp_strdup(url);
 				FREEPTR(ppath);
+				urltype = purltype;
 			}
 		} /* ! EMPTYSTRING(proxyenv) */

@@ -709,6 +1292,9 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
 			host = res0->ai_canonname;

 		s = -1;
+#ifdef WITH_SSL
+		ssl = NULL;
+#endif
 		for (res = res0; res; res = res->ai_next) {
 			char	hname[NI_MAXHOST], sname[NI_MAXSERV];

@@ -741,6 +1327,16 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
 				continue;
 			}

+#ifdef WITH_SSL
+			if (urltype == HTTPS_URL_T) {
+				if ((ssl = fetch_start_ssl(s)) == NULL) {
+					close(s);
+					s = -1;
+					continue;
+				}
+			}
+#endif
+
 			/* success */
 			break;
 		}
@@ -750,7 +1346,11 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
 			goto cleanup_fetch_url;
 		}

-		fin = fdopen(s, "r+");
+		fin = fetch_fdopen(s, "r+");
+#ifdef WITH_SSL
+		if (urltype == HTTPS_URL_T)
+			fin->ssl = ssl;
+#endif
 		/*
 		 * Construct and send the request.
 		 */
@@ -765,11 +1365,11 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
 				leading = ", ";
 				hasleading++;
 			}
-			fprintf(fin, "GET %s HTTP/1.0\r\n", path);
+			fetch_printf(fin, "GET %s HTTP/1.0\r\n", path);
 			if (flushcache)
-				fprintf(fin, "Pragma: no-cache\r\n");
+				fetch_printf(fin, "Pragma: no-cache\r\n");
 		} else {
-			fprintf(fin, "GET %s HTTP/1.1\r\n", path);
+			fetch_printf(fin, "GET %s HTTP/1.1\r\n", path);
 			if (strchr(host, ':')) {
 				char *h, *p;

@@ -782,18 +1382,23 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
 				    (p = strchr(h, '%')) != NULL) {
 					*p = '\0';
 				}
-				fprintf(fin, "Host: [%s]", h);
+				fetch_printf(fin, "Host: [%s]", h);
 				free(h);
 			} else
-				fprintf(fin, "Host: %s", host);
+				fetch_printf(fin, "Host: %s", host);
+#ifdef WITH_SSL
+			if ((urltype == HTTP_URL_T && portnum != HTTP_PORT) ||
+			    (urltype == HTTPS_URL_T && portnum != HTTPS_PORT))
+#else
 			if (portnum != HTTP_PORT)
-				fprintf(fin, ":%u", portnum);
-			fprintf(fin, "\r\n");
-			fprintf(fin, "Accept: */*\r\n");
-			fprintf(fin, "Connection: close\r\n");
+#endif
+				fetch_printf(fin, ":%u", portnum);
+			fetch_printf(fin, "\r\n");
+			fetch_printf(fin, "Accept: */*\r\n");
+			fetch_printf(fin, "Connection: close\r\n");
 			if (restart_point) {
 				fputs(leading, ttyout);
-				fprintf(fin, "Range: bytes=" LLF "-\r\n",
+				fprintf(ttyout, "Range: bytes=" LLF "-\r\n",
 				    (LLT)restart_point);
 				fprintf(ttyout, "restarting at " LLF,
 				    (LLT)restart_point);
@@ -801,12 +1406,12 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
 				hasleading++;
 			}
 			if (flushcache)
-				fprintf(fin, "Cache-Control: no-cache\r\n");
+				fetch_printf(fin, "Cache-Control: no-cache\r\n");
 		}
 		if ((useragent=getenv("FTPUSERAGENT")) != NULL) {
-			fprintf(fin, "User-Agent: %s\r\n", useragent);
+			fetch_printf(fin, "User-Agent: %s\r\n", useragent);
 		} else {
-			fprintf(fin, "User-Agent: %s/%s\r\n",
+			fetch_printf(fin, "User-Agent: %s/%s\r\n",
 			    FTP_PRODUCT, FTP_VERSION);
 		}
 		if (wwwauth) {
@@ -816,7 +1421,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
 				leading = ", ";
 				hasleading++;
 			}
-			fprintf(fin, "Authorization: %s\r\n", wwwauth);
+			fetch_printf(fin, "Authorization: %s\r\n", wwwauth);
 		}
 		if (proxyauth) {
 			if (verbose) {
@@ -825,18 +1430,18 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
 				leading = ", ";
 				hasleading++;
 			}
-			fprintf(fin, "Proxy-Authorization: %s\r\n", proxyauth);
+			fetch_printf(fin, "Proxy-Authorization: %s\r\n", proxyauth);
 		}
 		if (verbose && hasleading)
 			fputs(")\n", ttyout);
-		fprintf(fin, "\r\n");
-		if (fflush(fin) == EOF) {
+		fetch_printf(fin, "\r\n");
+		if (fetch_flush(fin) == EOF) {
 			warn("Writing HTTP request");
 			goto cleanup_fetch_url;
 		}

 				/* Read the response */
-		len = get_line(fin, buf, sizeof(buf), &errormsg);
+		len = fetch_getline(fin, buf, sizeof(buf), &errormsg);
 		if (len < 0) {
 			if (*errormsg == '\n')
 				errormsg++;
@@ -860,7 +1465,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)

 				/* Read the rest of the header. */
 		while (1) {
-			len = get_line(fin, buf, sizeof(buf), &errormsg);
+			len = fetch_getline(fin, buf, sizeof(buf), &errormsg);
 			if (len < 0) {
 				if (*errormsg == '\n')
 					errormsg++;
@@ -1148,7 +1753,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
 		lastchunk = 0;
 					/* read chunk-size */
 		if (ischunked) {
-			if (fgets(xferbuf, bufsize, fin) == NULL) {
+			if (fetch_getln(xferbuf, bufsize, fin) == NULL) {
 				warnx("Unexpected EOF reading chunk-size");
 				goto cleanup_fetch_url;
 			}
@@ -1201,7 +1806,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
 			if (ischunked)
 				bufrem = MIN(chunksize, bufrem);
 			while (bufrem > 0) {
-				flen = fread(xferbuf, sizeof(char),
+				flen = fetch_read(xferbuf, sizeof(char),
 				    MIN((off_t)bufsize, bufrem), fin);
 				if (flen <= 0)
 					goto chunkdone;
@@ -1240,7 +1845,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
 					/* read CRLF after chunk*/
  chunkdone:
 		if (ischunked) {
-			if (fgets(xferbuf, bufsize, fin) == NULL) {
+			if (fetch_getln(xferbuf, bufsize, fin) == NULL) {
 				warnx("Unexpected EOF reading chunk CRLF");
 				goto cleanup_fetch_url;
 			}
@@ -1260,7 +1865,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
 			(void)putc('#', ttyout);
 		(void)putc('\n', ttyout);
 	}
-	if (ferror(fin)) {
+	if (fetch_error(fin)) {
 		warn("Reading file");
 		goto cleanup_fetch_url;
 	}
@@ -1297,7 +1902,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
 	if (oldintp)
 		(void)xsignal(SIGPIPE, oldintp);
 	if (fin != NULL)
-		fclose(fin);
+		fetch_close(fin);
 	else if (s != -1)
 		close(s);
 	if (closefunc != NULL && fout != NULL)
@@ -1729,7 +2334,11 @@ go_fetch(const char *url)
 	/*
 	 * Check for file:// and http:// URLs.
 	 */
-	if (STRNEQUAL(url, HTTP_URL) || STRNEQUAL(url, FILE_URL))
+	if (STRNEQUAL(url, HTTP_URL)
+#ifdef WITH_SSL
+	    || STRNEQUAL(url, HTTPS_URL)
+#endif
+	    || STRNEQUAL(url, FILE_URL))
 		return (fetch_url(url, NULL, NULL, NULL));

 	/*
diff --git a/usr.bin/ftp/ftp_var.h b/usr.bin/ftp/ftp_var.h
index db501cf..8199b78 100644
--- a/usr.bin/ftp/ftp_var.h
+++ b/usr.bin/ftp/ftp_var.h
@@ -177,6 +177,7 @@ enum {

 #define	FTP_PORT	21	/* default if ! getservbyname("ftp/tcp") */
 #define	HTTP_PORT	80	/* default if ! getservbyname("http/tcp") */
+#define	HTTPS_PORT	443	/* default if ! getservbyname("https/tcp") */
 #ifndef	GATE_PORT
 #define	GATE_PORT	21	/* default if ! getservbyname("ftpgate/tcp") */
 #endif
@@ -273,6 +274,9 @@ GLOBAL	char   *username;	/* name of user logged in as. (dynamic) */
 GLOBAL	sa_family_t family;	/* address family to use for connections */
 GLOBAL	const char *ftpport;	/* port number to use for FTP connections */
 GLOBAL	const char *httpport;	/* port number to use for HTTP connections */
+#ifdef WITH_SSL
+GLOBAL	const char *httpsport;	/* port number to use for HTTPS connections */
+#endif
 GLOBAL	const char *gateport;	/* port number to use for gateftp connections */
 GLOBAL	struct addrinfo *bindai; /* local address to bind as */

diff --git a/usr.bin/ftp/main.c b/usr.bin/ftp/main.c
index 58234ee..c0f692b 100644
--- a/usr.bin/ftp/main.c
+++ b/usr.bin/ftp/main.c
@@ -150,6 +150,9 @@ main(int volatile argc, char **volatile argv)

 	ftpport = "ftp";
 	httpport = "http";
+#ifdef WITH_SSL
+	httpsport = "https";
+#endif
 	gateport = NULL;
 	cp = getenv("FTPSERVERPORT");
 	if (cp != NULL)
@@ -1044,6 +1047,9 @@ usage(void)
 "           [[user@]host [port]] [host:path[/]] [file:///file]\n"
 "           [ftp://[user[:pass]@]host[:port]/path[/]]\n"
 "           [http://[user[:pass]@]host[:port]/path] [...]\n"
+#ifdef WITH_SSL
+"           [https://[user[:pass]@]host[:port]/path] [...]\n"
+#endif
 "       %s -u URL file [...]\n", progname, progname);
 	exit(1);
 }

>Release-Note:

>Audit-Trail:
From: Julian Djamil Fagir <gnrp@komkon2.de>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: bin/47276: ftp(1) is not supported https
Date: Mon, 3 Dec 2012 22:53:58 +0100

 --Sig_/W1oj4Liohx1RBc+1fUBng/o
 Content-Type: text/plain; charset=US-ASCII
 Content-Transfer-Encoding: quoted-printable

 Hi,

 On Mon,  3 Dec 2012 06:50:04 +0000 (UTC) nonakap@gmail.com wrote:
 > >Fix:
 > apply following patch.
 > (most code from libfetch)

 are there any licencing issue with it then? I mean, there's a large portion
 of it and no licence text, should that be copied as well?
 And: Can't you include libfetch directly and use it? We already have it in
 tree.

 Regards, Julian

 --Sig_/W1oj4Liohx1RBc+1fUBng/o
 Content-Type: application/pgp-signature; name=signature.asc
 Content-Disposition: attachment; filename=signature.asc

 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.19 (NetBSD)

 iEYEARECAAYFAlC9H3sACgkQc7h7cu1Hpp4/8gCdHjTth2NvlzhDW2J/gMgPoEBp
 5SQAn2tdup4+kc4969mY4I4w849mBVO/
 =rD72
 -----END PGP SIGNATURE-----

 --Sig_/W1oj4Liohx1RBc+1fUBng/o--

From: NONAKA Kimihiro <nonakap@gmail.com>
To: gnats-bugs@netbsd.org
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: bin/47276: ftp(1) is not supported https
Date: Tue, 4 Dec 2012 13:02:24 +0900

 --e89a8f923f3aff7bb104cffeee57
 Content-Type: text/plain; charset=ISO-8859-1

 Hi,

 2012/12/4 Julian Djamil Fagir <gnrp@komkon2.de>

 >  > apply following patch.
 >  > (most code from libfetch)
 >
 >  are there any licencing issue with it then? I mean, there's a large portion
 >  of it and no licence text, should that be copied as well?

 I think as you say, should be added license notice to source too.
 I update patch.

 >  And: Can't you include libfetch directly and use it? We already have it in
 >  tree.

 non https portion is already implemented in ftp(1).

 Regards,
 --
 NONAKA Kimihiro

 --e89a8f923f3aff7bb104cffeee57
 Content-Type: application/octet-stream; name="tnftp-https-20121204.diff"
 Content-Disposition: attachment; filename="tnftp-https-20121204.diff"
 Content-Transfer-Encoding: base64
 X-Attachment-Id: f_haahdztk0

 ZGlmZiAtLWdpdCBhL2Rpc3RyaWIvYW1kNjQvY2Ryb21zL01ha2VmaWxlLmNkcm9tIGIvZGlzdHJp
 Yi9hbWQ2NC9jZHJvbXMvTWFrZWZpbGUuY2Ryb20KaW5kZXggOTk1MDk5ZC4uYTFiNjhiNSAxMDA2
 NDQKLS0tIGEvZGlzdHJpYi9hbWQ2NC9jZHJvbXMvTWFrZWZpbGUuY2Ryb20KKysrIGIvZGlzdHJp
 Yi9hbWQ2NC9jZHJvbXMvTWFrZWZpbGUuY2Ryb20KQEAgLTU1LDYgKzU1LDEwIEBAIENEUlVOVElN
 RSs9CS4vdXNyL3NiaW4vaW5zdGFsbGJvb3QKIENEUlVOVElNRSs9CS4vdXNyL3NiaW4vd2ljb25m
 aWcKIENEUlVOVElNRSs9CS4vdXNyL3NoYXJlL21pc2MvdGVybWluZm8uY2RiCiBDRFJVTlRJTUUr
 PQkuL3Vzci9zaGFyZS9sb2NhbGUKKy5pZiAoJHtNS0NSWVBUT30gIT0gIm5vIikKK0NEUlVOVElN
 RSs9CS4vdXNyL2xpYi9saWJjcnlwdG8uc28qCitDRFJVTlRJTUUrPQkuL3Vzci9saWIvbGlic3Ns
 LnNvKgorLmVuZGlmCiAKIGltYWdlX21kX3ByZToKIAkke01LRElSfSBjZHJvbS9saWJleGVjL2Ro
 Y3BjZC1ob29rcwpkaWZmIC0tZ2l0IGEvZGlzdHJpYi9pMzg2L2Nkcm9tcy9NYWtlZmlsZS5jZHJv
 bSBiL2Rpc3RyaWIvaTM4Ni9jZHJvbXMvTWFrZWZpbGUuY2Ryb20KaW5kZXggMzNjMTEyOS4uYTVl
 ZWRiZCAxMDA2NDQKLS0tIGEvZGlzdHJpYi9pMzg2L2Nkcm9tcy9NYWtlZmlsZS5jZHJvbQorKysg
 Yi9kaXN0cmliL2kzODYvY2Ryb21zL01ha2VmaWxlLmNkcm9tCkBAIC01NSw2ICs1NSwxMCBAQCBD
 RFJVTlRJTUUrPQkuL3Vzci9zYmluL2luc3RhbGxib290CiBDRFJVTlRJTUUrPQkuL3Vzci9zYmlu
 L3dpY29uZmlnCiBDRFJVTlRJTUUrPQkuL3Vzci9zaGFyZS9taXNjL3Rlcm1pbmZvLmNkYgogQ0RS
 VU5USU1FKz0JLi91c3Ivc2hhcmUvbG9jYWxlCisuaWYgKCR7TUtDUllQVE99ICE9ICJubyIpCitD
 RFJVTlRJTUUrPQkuL3Vzci9saWIvbGliY3J5cHRvLnNvKgorQ0RSVU5USU1FKz0JLi91c3IvbGli
 L2xpYnNzbC5zbyoKKy5lbmRpZgogCiBpbWFnZV9tZF9wcmU6CiAJJHtNS0RJUn0gY2Ryb20vbGli
 ZXhlYy9kaGNwY2QtaG9va3MKZGlmZiAtLWdpdCBhL3Jlc2N1ZS9saXN0LmNyeXB0byBiL3Jlc2N1
 ZS9saXN0LmNyeXB0bwppbmRleCAzNDVjNDQ1Li45NzljMTI3IDEwMDY0NAotLS0gYS9yZXNjdWUv
 bGlzdC5jcnlwdG8KKysrIGIvcmVzY3VlL2xpc3QuY3J5cHRvCkBAIC03LDQgKzcsNCBAQCBQUk9H
 CXNzaAkJc2xvZ2luCiBTUEVDSUFMCXNjcAlzcmNkaXIJY3J5cHRvL2V4dGVybmFsL2JzZC9vcGVu
 c3NoL2Jpbi9zY3AKIFNQRUNJQUwJc3NoCXNyY2RpcgljcnlwdG8vZXh0ZXJuYWwvYnNkL29wZW5z
 c2gvYmluL3NzaAogCi1MSUJTCS1sc3NoIC1sY3J5cHRvCitMSUJTCS1sc3NoIC1sc3NsIC1sY3J5
 cHRvCmRpZmYgLS1naXQgYS91c3IuYmluL2Z0cC9NYWtlZmlsZSBiL3Vzci5iaW4vZnRwL01ha2Vm
 aWxlCmluZGV4IGQxMTM1YWUuLmZiOTdkZGUgMTAwNjQ0Ci0tLSBhL3Vzci5iaW4vZnRwL01ha2Vm
 aWxlCisrKyBiL3Vzci5iaW4vZnRwL01ha2VmaWxlCkBAIC0xOCw2ICsxOCwxMSBAQCBDUFBGTEFH
 Uys9LUROT19FRElUQ09NUExFVEUgLUROT19BQk9VVCAtRE5PX0FVVEggLUROT19IRUxQIC1ETk9f
 U1RBVFVTIC1ETk9fREVCVQogLmVsc2UKIExEQUREKz0JLWxlZGl0IC1sdGVybWluZm8KIERQQURE
 Kz0JJHtMSUJFRElUfSAke0xJQlRFUk1JTkZPfQorLmlmICgke01LQ1JZUFRPfSAhPSAibm8iKQor
 Q1BQRkxBR1MrPSAtRFdJVEhfU1NMCitMREFERCs9IC1sc3NsIC1sY3J5cHRvCitEUEFERCs9ICR7
 TElCU1NMfSAke0xJQkNSWVBUT30KKy5lbmRpZgogLmVuZGlmCiAKIC5pZiAoIWRlZmluZWQoU01B
 TExQUk9HKSB8fCBkZWZpbmVkKFNNQUxMUFJPR19JTkVUNikpICYmICgke1VTRV9JTkVUNn0gIT0g
 Im5vIikKZGlmZiAtLWdpdCBhL3Vzci5iaW4vZnRwL2ZldGNoLmMgYi91c3IuYmluL2Z0cC9mZXRj
 aC5jCmluZGV4IDMwMDg3ZjguLmRkZDFjNzkgMTAwNjQ0Ci0tLSBhL3Vzci5iaW4vZnRwL2ZldGNo
 LmMKKysrIGIvdXNyLmJpbi9mdHAvZmV0Y2guYwpAQCAtMzIsNiArMzIsMzcgQEAKICAqIFBPU1NJ
 QklMSVRZIE9GIFNVQ0ggREFNQUdFLgogICovCiAKKy8qLQorICogQ29weXJpZ2h0IChjKSAxOTk4
 LTIwMDQgRGFnLUVybGluZyBDb8OvZGFuIFNtw7hyZ3JhdgorICogQ29weXJpZ2h0IChjKSAyMDA4
 LCAyMDEwIEpvZXJnIFNvbm5lbmJlcmdlciA8am9lcmdATmV0QlNELm9yZz4KKyAqIEFsbCByaWdo
 dHMgcmVzZXJ2ZWQuCisgKgorICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5k
 IGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisgKiBtb2RpZmljYXRpb24sIGFyZSBwZXJt
 aXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKKyAqIGFyZSBtZXQ6
 CisgKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFi
 b3ZlIGNvcHlyaWdodAorICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQg
 dGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisgKiAgICBpbiB0aGlzIHBvc2l0aW9uIGFuZCB1bmNo
 YW5nZWQuCisgKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1
 Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAorICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0
 aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQorICogICAgZG9jdW1lbnRh
 dGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlv
 bi4KKyAqIDMuIFRoZSBuYW1lIG9mIHRoZSBhdXRob3IgbWF5IG5vdCBiZSB1c2VkIHRvIGVuZG9y
 c2Ugb3IgcHJvbW90ZSBwcm9kdWN0cworICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUg
 d2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24KKyAqCisgKiBUSElTIFNP
 RlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBBVVRIT1IgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVT
 UyBPUgorICogSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBU
 TywgVEhFIElNUExJRUQgV0FSUkFOVElFUworICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRO
 RVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4KKyAqIElOIE5PIEVW
 RU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwK
 KyAqIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1B
 R0VTIChJTkNMVURJTkcsIEJVVAorICogTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNV
 QlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorICogREFUQSwgT1IgUFJP
 RklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5Z
 CisgKiBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElB
 QklMSVRZLCBPUiBUT1JUCisgKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBB
 UklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YKKyAqIFRISVMgU09GVFdBUkUsIEVW
 RU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisgKgorICog
 JEZyZWVCU0Q6IGNvbW1vbi5jLHYgMS41MyAyMDA3LzEyLzE5IDAwOjI2OjM2IGRlcyBFeHAgJAor
 ICovCisKICNpbmNsdWRlIDxzeXMvY2RlZnMuaD4KICNpZm5kZWYgbGludAogX19SQ1NJRCgiJE5l
 dEJTRDogZmV0Y2guYyx2IDEuMTk4IDIwMTIvMDcvMDQgMDY6MDk6MzcgaXMgRXhwICQiKTsKQEAg
 LTY0LDEyICs5NSwyNCBAQCBfX1JDU0lEKCIkTmV0QlNEOiBmZXRjaC5jLHYgMS4xOTggMjAxMi8w
 Ny8wNCAwNjowOTozNyBpcyBFeHAgJCIpOwogI2luY2x1ZGUgPHVuaXN0ZC5oPgogI2luY2x1ZGUg
 PHRpbWUuaD4KIAorI2lmZGVmIFdJVEhfU1NMCisjaW5jbHVkZSA8bmV0aW5ldC90Y3AuaD4KKyNp
 bmNsdWRlIDxvcGVuc3NsL2NyeXB0by5oPgorI2luY2x1ZGUgPG9wZW5zc2wveDUwOS5oPgorI2lu
 Y2x1ZGUgPG9wZW5zc2wvcGVtLmg+CisjaW5jbHVkZSA8b3BlbnNzbC9zc2wuaD4KKyNpbmNsdWRl
 IDxvcGVuc3NsL2Vyci5oPgorI2VuZGlmCisKICNpbmNsdWRlICJmdHBfdmFyLmgiCiAjaW5jbHVk
 ZSAidmVyc2lvbi5oIgogCiB0eXBlZGVmIGVudW0gewogCVVOS05PV05fVVJMX1Q9LTEsCiAJSFRU
 UF9VUkxfVCwKKyNpZmRlZiBXSVRIX1NTTAorCUhUVFBTX1VSTF9ULAorI2VuZGlmCiAJRlRQX1VS
 TF9ULAogCUZJTEVfVVJMX1QsCiAJQ0xBU1NJQ19VUkxfVApAQCAtMTAwLDcgKzE0Myw1NjYgQEAg
 c3RhdGljIGludAlyZWRpcmVjdF9sb29wOwogI2RlZmluZQlGSUxFX1VSTAkiZmlsZTovLyIJLyog
 ZmlsZSBVUkwgcHJlZml4ICovCiAjZGVmaW5lCUZUUF9VUkwJCSJmdHA6Ly8iCS8qIGZ0cCBVUkwg
 cHJlZml4ICovCiAjZGVmaW5lCUhUVFBfVVJMCSJodHRwOi8vIgkvKiBodHRwIFVSTCBwcmVmaXgg
 Ki8KKyNpZmRlZiBXSVRIX1NTTAorI2RlZmluZQlIVFRQU19VUkwJImh0dHBzOi8vIgkvKiBodHRw
 cyBVUkwgcHJlZml4ICovCisKKyNkZWZpbmUJSVNfSFRUUF9UWVBFKHVybHR5cGUpIFwKKwkoKCh1
 cmx0eXBlKSA9PSBIVFRQX1VSTF9UKSB8fCAoKHVybHR5cGUpID09IEhUVFBTX1VSTF9UKSkKKwor
 c3RydWN0IGZldGNoX2Nvbm5lY3QgeworCWludAkJCSBzZDsJCS8qIGZpbGUvc29ja2V0IGRlc2Ny
 aXB0b3IgKi8KKwljaGFyCQkJKmJ1ZjsJCS8qIGJ1ZmZlciAqLworCXNpemVfdAkJCSBidWZzaXpl
 OwkvKiBidWZmZXIgc2l6ZSAqLworCXNpemVfdAkJCSBidWZwb3M7CS8qIHBvc2l0aW9uIG9mIGJ1
 ZmZlciAqLworCXNpemVfdAkJCSBidWZsZW47CS8qIGxlbmd0aCBvZiBidWZmZXIgY29udGVudHMg
 Ki8KKwlzdHJ1Y3QgewkJCQkvKiBkYXRhIGNhY2hlZCBhZnRlciBhbgorCQkJCQkJICAgaW50ZXJy
 dXB0ZWQgcmVhZCAqLworCQljaGFyCSpidWY7CisJCXNpemVfdAkgc2l6ZTsKKwkJc2l6ZV90CSBw
 b3M7CisJCXNpemVfdAkgbGVuOworCX0gY2FjaGU7CisJaW50IAkJCSBpc3NvY2s7CisJaW50CQkJ
 IGlzZXJyOworCWludAkJCSBpc2VvZjsKKwlTU0wJCQkqc3NsOwkJLyogU1NMIGhhbmRsZSAqLwor
 fTsKK3R5cGVkZWYgc3RydWN0IGZldGNoX2Nvbm5lY3QgZmV0Y2hfY29ubmVjdF90OwogCisvKgor
 ICogV3JpdGUgYSB2ZWN0b3IgdG8gYSBjb25uZWN0aW9uIHcvIHRpbWVvdXQKKyAqIE5vdGU6IGNh
 biBtb2RpZnkgdGhlIGlvdmVjLgorICovCitzdGF0aWMgc3NpemVfdAorZmV0Y2hfd3JpdGV2KGZl
 dGNoX2Nvbm5lY3RfdCAqY29ubiwgc3RydWN0IGlvdmVjICppb3YsIGludCBpb3ZjbnQpCit7CisJ
 c3RydWN0IHRpbWV2YWwgbm93LCB0aW1lb3V0LCBkZWx0YTsKKwlmZF9zZXQgd3JpdGVmZHM7CisJ
 c3NpemVfdCBsZW4sIHRvdGFsOworCWludCByOworCisJaWYgKHF1aXRfdGltZSA+IDApIHsKKwkJ
 RkRfWkVSTygmd3JpdGVmZHMpOworCQlnZXR0aW1lb2ZkYXkoJnRpbWVvdXQsIE5VTEwpOworCQl0
 aW1lb3V0LnR2X3NlYyArPSBxdWl0X3RpbWU7CisJfQorCisJdG90YWwgPSAwOworCXdoaWxlIChp
 b3ZjbnQgPiAwKSB7CisJCXdoaWxlIChxdWl0X3RpbWUgPiAwICYmICFGRF9JU1NFVChjb25uLT5z
 ZCwgJndyaXRlZmRzKSkgeworCQkJRkRfU0VUKGNvbm4tPnNkLCAmd3JpdGVmZHMpOworCQkJZ2V0
 dGltZW9mZGF5KCZub3csIE5VTEwpOworCQkJZGVsdGEudHZfc2VjID0gdGltZW91dC50dl9zZWMg
 LSBub3cudHZfc2VjOworCQkJZGVsdGEudHZfdXNlYyA9IHRpbWVvdXQudHZfdXNlYyAtIG5vdy50
 dl91c2VjOworCQkJaWYgKGRlbHRhLnR2X3VzZWMgPCAwKSB7CisJCQkJZGVsdGEudHZfdXNlYyAr
 PSAxMDAwMDAwOworCQkJCWRlbHRhLnR2X3NlYy0tOworCQkJfQorCQkJaWYgKGRlbHRhLnR2X3Nl
 YyA8IDApIHsKKwkJCQllcnJubyA9IEVUSU1FRE9VVDsKKwkJCQlyZXR1cm4gKC0xKTsKKwkJCX0K
 KwkJCWVycm5vID0gMDsKKwkJCXIgPSBzZWxlY3QoY29ubi0+c2QgKyAxLCBOVUxMLCAmd3JpdGVm
 ZHMsIE5VTEwsICZkZWx0YSk7CisJCQlpZiAociA9PSAtMSkgeworCQkJCWlmIChlcnJubyA9PSBF
 SU5UUikKKwkJCQkJY29udGludWU7CisJCQkJcmV0dXJuICgtMSk7CisJCQl9CisJCX0KKwkJZXJy
 bm8gPSAwOworCQlpZiAoY29ubi0+c3NsICE9IE5VTEwpCisJCQlsZW4gPSBTU0xfd3JpdGUoY29u
 bi0+c3NsLCBpb3YtPmlvdl9iYXNlLCBpb3YtPmlvdl9sZW4pOworCQllbHNlCisJCQlsZW4gPSB3
 cml0ZXYoY29ubi0+c2QsIGlvdiwgaW92Y250KTsKKwkJaWYgKGxlbiA9PSAwKSB7CisJCQkvKiB3
 ZSBjb25zaWRlciBhIHNob3J0IHdyaXRlIGEgZmFpbHVyZSAqLworCQkJLyogWFhYIHBlcmhhcHMg
 d2Ugc2hvdWxkbid0IGluIHRoZSBTU0wgY2FzZSAqLworCQkJZXJybm8gPSBFUElQRTsKKwkJCXJl
 dHVybiAoLTEpOworCQl9CisJCWlmIChsZW4gPCAwKSB7CisJCQlpZiAoZXJybm8gPT0gRUlOVFIp
 CisJCQkJY29udGludWU7CisJCQlyZXR1cm4gKC0xKTsKKwkJfQorCQl0b3RhbCArPSBsZW47CisJ
 CXdoaWxlIChpb3ZjbnQgPiAwICYmIGxlbiA+PSAoc3NpemVfdClpb3YtPmlvdl9sZW4pIHsKKwkJ
 CWxlbiAtPSBpb3YtPmlvdl9sZW47CisJCQlpb3YrKzsKKwkJCWlvdmNudC0tOworCQl9CisJCWlm
 IChpb3ZjbnQgPiAwKSB7CisJCQlpb3YtPmlvdl9sZW4gLT0gbGVuOworCQkJaW92LT5pb3ZfYmFz
 ZSA9IChjaGFyICopaW92LT5pb3ZfYmFzZSArIGxlbjsKKwkJfQorCX0KKwlyZXR1cm4gKHRvdGFs
 KTsKK30KKworLyoKKyAqIFdyaXRlIHRvIGEgY29ubmVjdGlvbiB3LyB0aW1lb3V0CisgKi8KK3N0
 YXRpYyBpbnQKK2ZldGNoX3dyaXRlKGZldGNoX2Nvbm5lY3RfdCAqY29ubiwgY29uc3QgY2hhciAq
 c3RyLCBzaXplX3QgbGVuKQoreworCXN0cnVjdCBpb3ZlYyBpb3ZbMV07CisKKwlpb3ZbMF0uaW92
 X2Jhc2UgPSAoY2hhciAqKV9fVU5DT05TVChzdHIpOworCWlvdlswXS5pb3ZfbGVuID0gbGVuOwor
 CXJldHVybiAoZmV0Y2hfd3JpdGV2KGNvbm4sIGlvdiwgMSkpOworfQorCisvKgorICogU2VuZCBh
 IGZvcm1hdHRlZCBsaW5lOyBvcHRpb25hbGx5IGVjaG8gdG8gdGVybWluYWwKKyAqLworc3RhdGlj
 IGludAorZmV0Y2hfcHJpbnRmKGZldGNoX2Nvbm5lY3RfdCAqY29ubiwgY29uc3QgY2hhciAqZm10
 LCAuLi4pCit7CisJdmFfbGlzdCBhcDsKKwlzaXplX3QgbGVuOworCWNoYXIgKm1zZzsKKwlpbnQg
 cjsKKworCXZhX3N0YXJ0KGFwLCBmbXQpOworCWxlbiA9IHZhc3ByaW50ZigmbXNnLCBmbXQsIGFw
 KTsKKwl2YV9lbmQoYXApOworCisJaWYgKG1zZyA9PSBOVUxMKSB7CisJCWVycm5vID0gRU5PTUVN
 OworCQlyZXR1cm4gKC0xKTsKKwl9CisKKwlyID0gZmV0Y2hfd3JpdGUoY29ubiwgbXNnLCBsZW4p
 OworCWZyZWUobXNnKTsKKwlyZXR1cm4gKHIpOworfQorCitzdGF0aWMgaW50CitmZXRjaF9maWxl
 bm8oZmV0Y2hfY29ubmVjdF90ICpjb25uKQoreworCisJcmV0dXJuIChjb25uLT5zZCk7Cit9CisK
 K3N0YXRpYyBpbnQKK2ZldGNoX2Vycm9yKGZldGNoX2Nvbm5lY3RfdCAqY29ubikKK3sKKworCXJl
 dHVybiAoY29ubi0+aXNlcnIpOworfQorCitzdGF0aWMgdm9pZAorZmV0Y2hfY2xlYXJlcnIoZmV0
 Y2hfY29ubmVjdF90ICpjb25uKQoreworCisJY29ubi0+aXNlcnIgPSAwOworfQorCitzdGF0aWMg
 aW50CitmZXRjaF9mbHVzaChmZXRjaF9jb25uZWN0X3QgKmNvbm4pCit7CisJaW50IHY7CisKKwlp
 ZiAoY29ubi0+aXNzb2NrKSB7CisjaWZkZWYgVENQX05PUFVTSAorCQl2ID0gMDsKKwkJc2V0c29j
 a29wdChjb25uLT5zZCwgSVBQUk9UT19UQ1AsIFRDUF9OT1BVU0gsICZ2LCBzaXplb2YodikpOwor
 I2VuZGlmCisJCXYgPSAxOworCQlzZXRzb2Nrb3B0KGNvbm4tPnNkLCBJUFBST1RPX1RDUCwgVENQ
 X05PREVMQVksICZ2LCBzaXplb2YodikpOworCX0KKwlyZXR1cm4gKDApOworfQorCisvKkFSR1NV
 U0VEKi8KK3N0YXRpYyBmZXRjaF9jb25uZWN0X3QgKgorZmV0Y2hfb3Blbihjb25zdCBjaGFyICpm
 bmFtZSwgY29uc3QgY2hhciAqZm1vZGUpCit7CisJZmV0Y2hfY29ubmVjdF90ICpjb25uOworCWlu
 dCBmZDsKKworCWZkID0gb3BlbihmbmFtZSwgT19SRE9OTFkpOyAvKiBYWFg6IGZtb2RlICovCisJ
 aWYgKGZkIDwgMCkKKwkJcmV0dXJuIChOVUxMKTsKKworCWlmICgoY29ubiA9IGNhbGxvYygxLCBz
 aXplb2YoKmNvbm4pKSkgPT0gTlVMTCkgeworCQljbG9zZShmZCk7CisJCXJldHVybiAoTlVMTCk7
 CisJfQorCisJY29ubi0+c2QgPSBmZDsKKwljb25uLT5pc3NvY2sgPSAwOworCXJldHVybiAoY29u
 bik7Cit9CisKKy8qQVJHU1VTRUQqLworc3RhdGljIGZldGNoX2Nvbm5lY3RfdCAqCitmZXRjaF9m
 ZG9wZW4oaW50IHNkLCBjb25zdCBjaGFyICpmbW9kZSkKK3sKKwlmZXRjaF9jb25uZWN0X3QgKmNv
 bm47CisJaW50IG9wdCA9IDE7CisKKwlpZiAoKGNvbm4gPSBjYWxsb2MoMSwgc2l6ZW9mKCpjb25u
 KSkpID09IE5VTEwpCisJCXJldHVybiAoTlVMTCk7CisKKwljb25uLT5zZCA9IHNkOworCWNvbm4t
 Pmlzc29jayA9IDE7CisJZmNudGwoc2QsIEZfU0VURkQsIEZEX0NMT0VYRUMpOworCXNldHNvY2tv
 cHQoc2QsIFNPTF9TT0NLRVQsIFNPX05PU0lHUElQRSwgJm9wdCwgc2l6ZW9mKG9wdCkpOworI2lm
 ZGVmIFRDUF9OT1BVU0gKKwlzZXRzb2Nrb3B0KHNkLCBJUFBST1RPX1RDUCwgVENQX05PUFVTSCwg
 Jm9wdCwgc2l6ZW9mKG9wdCkpOworI2VuZGlmCisJcmV0dXJuIChjb25uKTsKK30KKworc3RhdGlj
 IGludAorZmV0Y2hfY2xvc2UoZmV0Y2hfY29ubmVjdF90ICpjb25uKQoreworCWludCBydiA9IDA7
 CisKKwlpZiAoY29ubiAhPSBOVUxMKSB7CisJCWZldGNoX2ZsdXNoKGNvbm4pOworCQlTU0xfZnJl
 ZShjb25uLT5zc2wpOworCQlydiA9IGNsb3NlKGNvbm4tPnNkKTsKKwkJaWYgKHJ2IDwgMCkgewor
 CQkJZXJybm8gPSBydjsKKwkJCXJ2ID0gRU9GOworCQl9CisJCWZyZWUoY29ubi0+Y2FjaGUuYnVm
 KTsKKwkJZnJlZShjb25uLT5idWYpOworCQlmcmVlKGNvbm4pOworCX0KKwlyZXR1cm4gKHJ2KTsK
 K30KKworI2RlZmluZSBGRVRDSF9SRUFEX1dBSVQJCS0yCisjZGVmaW5lIEZFVENIX1JFQURfRVJS
 T1IJLTEKKworc3RhdGljIHNzaXplX3QKK2ZldGNoX3NzbF9yZWFkKFNTTCAqc3NsLCB2b2lkICpi
 dWYsIHNpemVfdCBsZW4pCit7CisJc3NpemVfdCBybGVuOworCWludCBzc2xfZXJyOworCisJcmxl
 biA9IFNTTF9yZWFkKHNzbCwgYnVmLCBsZW4pOworCWlmIChybGVuIDwgMCkgeworCQlzc2xfZXJy
 ID0gU1NMX2dldF9lcnJvcihzc2wsIHJsZW4pOworCQlpZiAoc3NsX2VyciA9PSBTU0xfRVJST1Jf
 V0FOVF9SRUFEIHx8CisJCSAgICBzc2xfZXJyID09IFNTTF9FUlJPUl9XQU5UX1dSSVRFKSB7CisJ
 CQlyZXR1cm4gKEZFVENIX1JFQURfV0FJVCk7CisJCX0KKwkJRVJSX3ByaW50X2Vycm9yc19mcCh0
 dHlvdXQpOworCQlyZXR1cm4gKEZFVENIX1JFQURfRVJST1IpOworCX0KKwlyZXR1cm4gKHJsZW4p
 OworfQorCitzdGF0aWMgc3NpemVfdAorZmV0Y2hfbm9uc3NsX3JlYWQoaW50IHNkLCB2b2lkICpi
 dWYsIHNpemVfdCBsZW4pCit7CisJc3NpemVfdCBybGVuOworCisJcmxlbiA9IHJlYWQoc2QsIGJ1
 ZiwgbGVuKTsKKwlpZiAocmxlbiA8IDApIHsKKwkJaWYgKGVycm5vID09IEVBR0FJTiB8fCBlcnJu
 byA9PSBFSU5UUikKKwkJCXJldHVybiAoRkVUQ0hfUkVBRF9XQUlUKTsKKwkJcmV0dXJuIChGRVRD
 SF9SRUFEX0VSUk9SKTsKKwl9CisJcmV0dXJuIChybGVuKTsKK30KKworLyoKKyAqIENhY2hlIHNv
 bWUgZGF0YSB0aGF0IHdhcyByZWFkIGZyb20gYSBzb2NrZXQgYnV0IGNhbm5vdCBiZSBpbW1lZGlh
 dGVseQorICogcmV0dXJuZWQgYmVjYXVzZSBvZiBhbiBpbnRlcnJ1cHRlZCBzeXN0ZW0gY2FsbC4K
 KyAqLworc3RhdGljIGludAorZmV0Y2hfY2FjaGVfZGF0YShmZXRjaF9jb25uZWN0X3QgKmNvbm4s
 IGNoYXIgKnNyYywgc2l6ZV90IG5ieXRlcykKK3sKKworCWlmIChjb25uLT5jYWNoZS5zaXplIDwg
 bmJ5dGVzKSB7CisJCWNoYXIgKnRtcCA9IHJlYWxsb2MoY29ubi0+Y2FjaGUuYnVmLCBuYnl0ZXMp
 OworCQlpZiAodG1wID09IE5VTEwpCisJCQlyZXR1cm4gKC0xKTsKKworCQljb25uLT5jYWNoZS5i
 dWYgPSB0bXA7CisJCWNvbm4tPmNhY2hlLnNpemUgPSBuYnl0ZXM7CisJfQorCisJbWVtY3B5KGNv
 bm4tPmNhY2hlLmJ1Ziwgc3JjLCBuYnl0ZXMpOworCWNvbm4tPmNhY2hlLmxlbiA9IG5ieXRlczsK
 Kwljb25uLT5jYWNoZS5wb3MgPSAwOworCXJldHVybiAoMCk7Cit9CisKK3N0YXRpYyBzc2l6ZV90
 CitmZXRjaF9yZWFkKHZvaWQgKnB0ciwgc2l6ZV90IHNpemUsIHNpemVfdCBubWVtYiwgZmV0Y2hf
 Y29ubmVjdF90ICpjb25uKQoreworCXN0cnVjdCB0aW1ldmFsIG5vdywgdGltZW91dCwgZGVsdGE7
 CisJZmRfc2V0IHJlYWRmZHM7CisJc3NpemVfdCBybGVuLCB0b3RhbDsKKwlzaXplX3QgbGVuOwor
 CWNoYXIgKnN0YXJ0LCAqYnVmOworCisJaWYgKHF1aXRfdGltZSA+IDApIHsKKwkJZ2V0dGltZW9m
 ZGF5KCZ0aW1lb3V0LCBOVUxMKTsKKwkJdGltZW91dC50dl9zZWMgKz0gcXVpdF90aW1lOworCX0K
 KworCXRvdGFsID0gMDsKKwlzdGFydCA9IGJ1ZiA9IHB0cjsKKwlsZW4gPSBzaXplICogbm1lbWI7
 CisKKwlpZiAoY29ubi0+Y2FjaGUubGVuID4gMCkgeworCQkvKgorCQkgKiBUaGUgbGFzdCBpbnZv
 Y2F0aW9uIG9mIGZldGNoX3JlYWQgd2FzIGludGVycnVwdGVkIGJ5IGEKKwkJICogc2lnbmFsIGFm
 dGVyIHNvbWUgZGF0YSBoYWQgYmVlbiByZWFkIGZyb20gdGhlIHNvY2tldC4gQ29weQorCQkgKiB0
 aGUgY2FjaGVkIGRhdGEgaW50byB0aGUgc3VwcGxpZWQgYnVmZmVyIGJlZm9yZSB0cnlpbmcgdG8K
 KwkJICogcmVhZCBmcm9tIHRoZSBzb2NrZXQgYWdhaW4uCisJCSAqLworCQl0b3RhbCA9IChjb25u
 LT5jYWNoZS5sZW4gPCBsZW4pID8gY29ubi0+Y2FjaGUubGVuIDogbGVuOworCQltZW1jcHkoYnVm
 LCBjb25uLT5jYWNoZS5idWYsIHRvdGFsKTsKKworCQljb25uLT5jYWNoZS5sZW4gLT0gdG90YWw7
 CisJCWNvbm4tPmNhY2hlLnBvcyArPSB0b3RhbDsKKwkJbGVuIC09IHRvdGFsOworCQlidWYgKz0g
 dG90YWw7CisJfQorCisJd2hpbGUgKGxlbiA+IDApIHsKKwkJLyoKKwkJICogVGhlIHNvY2tldCBp
 cyBub24tYmxvY2tpbmcuICBJbnN0ZWFkIG9mIHRoZSBjYW5vbmljYWwKKwkJICogc2VsZWN0KCkg
 LT4gcmVhZCgpLCB3ZSBkbyB0aGUgZm9sbG93aW5nOgorCQkgKgorCQkgKiAxKSBjYWxsIHJlYWQo
 KSBvciBTU0xfcmVhZCgpLgorCQkgKiAyKSBpZiBhbiBlcnJvciBvY2N1cnJlZCwgcmV0dXJuIC0x
 LgorCQkgKiAzKSBpZiB3ZSByZWNlaXZlZCBkYXRhIGJ1dCB3ZSBzdGlsbCBleHBlY3QgbW9yZSwK
 KwkJICogICAgdXBkYXRlIG91ciBjb3VudGVycyBhbmQgbG9vcC4KKwkJICogNCkgaWYgcmVhZCgp
 IG9yIFNTTF9yZWFkKCkgc2lnbmFsZWQgRU9GLCByZXR1cm4uCisJCSAqIDUpIGlmIHdlIGRpZCBu
 b3QgcmVjZWl2ZSBhbnkgZGF0YSBidXQgd2UncmUgbm90IGF0IEVPRiwKKwkJICogICAgY2FsbCBz
 ZWxlY3QoKS4KKwkJICoKKwkJICogSW4gdGhlIFNTTCBjYXNlLCB0aGlzIGlzIG5lY2Vzc2FyeSBi
 ZWNhdXNlIGlmIHdlCisJCSAqIHJlY2VpdmUgYSBjbG9zZSBub3RpZmljYXRpb24sIHdlIGhhdmUg
 dG8gY2FsbAorCQkgKiBTU0xfcmVhZCgpIG9uZSBhZGRpdGlvbmFsIHRpbWUgYWZ0ZXIgd2UndmUg
 cmVhZAorCQkgKiBldmVyeXRoaW5nIHdlIHJlY2VpdmVkLgorCQkgKgorCQkgKiBJbiB0aGUgbm9u
 LVNTTCBjYXNlLCBpdCBtYXkgaW1wcm92ZSBwZXJmb3JtYW5jZSAodmVyeQorCQkgKiBzbGlnaHRs
 eSkgd2hlbiByZWFkaW5nIHNtYWxsIGFtb3VudHMgb2YgZGF0YS4KKwkJICovCisJCWlmIChjb25u
 LT5zc2wgIT0gTlVMTCkKKwkJCXJsZW4gPSBmZXRjaF9zc2xfcmVhZChjb25uLT5zc2wsIGJ1Ziwg
 bGVuKTsKKwkJZWxzZQorCQkJcmxlbiA9IGZldGNoX25vbnNzbF9yZWFkKGNvbm4tPnNkLCBidWYs
 IGxlbik7CisJCWlmIChybGVuID09IDApIHsKKwkJCWJyZWFrOworCQl9IGVsc2UgaWYgKHJsZW4g
 PiAwKSB7CisJCQlsZW4gLT0gcmxlbjsKKwkJCWJ1ZiArPSBybGVuOworCQkJdG90YWwgKz0gcmxl
 bjsKKwkJCWNvbnRpbnVlOworCQl9IGVsc2UgaWYgKHJsZW4gPT0gRkVUQ0hfUkVBRF9FUlJPUikg
 eworCQkJaWYgKGVycm5vID09IEVJTlRSKQorCQkJCWZldGNoX2NhY2hlX2RhdGEoY29ubiwgc3Rh
 cnQsIHRvdGFsKTsKKwkJCXJldHVybiAoLTEpOworCQl9CisJCUZEX1pFUk8oJnJlYWRmZHMpOwor
 CQl3aGlsZSAoIUZEX0lTU0VUKGNvbm4tPnNkLCAmcmVhZGZkcykpIHsKKwkJCUZEX1NFVChjb25u
 LT5zZCwgJnJlYWRmZHMpOworCQkJaWYgKHF1aXRfdGltZSA+IDApIHsKKwkJCQlnZXR0aW1lb2Zk
 YXkoJm5vdywgTlVMTCk7CisJCQkJaWYgKCF0aW1lcmNtcCgmdGltZW91dCwgJm5vdywgPikpIHsK
 KwkJCQkJZXJybm8gPSBFVElNRURPVVQ7CisJCQkJCXJldHVybiAoLTEpOworCQkJCX0KKwkJCQl0
 aW1lcnN1YigmdGltZW91dCwgJm5vdywgJmRlbHRhKTsKKwkJCX0KKwkJCWVycm5vID0gMDsKKwkJ
 CWlmIChzZWxlY3QoY29ubi0+c2QgKyAxLCAmcmVhZGZkcywgTlVMTCwgTlVMTCwKKwkJCQlxdWl0
 X3RpbWUgPiAwID8gJmRlbHRhIDogTlVMTCkgPCAwKSB7CisJCQkJaWYgKGVycm5vID09IEVJTlRS
 KQorCQkJCQljb250aW51ZTsKKwkJCQlyZXR1cm4gKC0xKTsKKwkJCX0KKwkJfQorCX0KKwlyZXR1
 cm4gKHRvdGFsKTsKK30KKworI2RlZmluZSBNSU5fQlVGX1NJWkUgMTAyNAorCisvKgorICogUmVh
 ZCBhIGxpbmUgb2YgdGV4dCBmcm9tIGEgY29ubmVjdGlvbiB3LyB0aW1lb3V0CisgKi8KK3N0YXRp
 YyBjaGFyICoKK2ZldGNoX2dldGxuKGNoYXIgKnN0ciwgaW50IHNpemUsIGZldGNoX2Nvbm5lY3Rf
 dCAqY29ubikKK3sKKwlzaXplX3QgdG1wc2l6ZTsKKwlzc2l6ZV90IGxlbjsKKwljaGFyIGM7CisK
 KwlpZiAoY29ubi0+YnVmID09IE5VTEwpIHsKKwkJaWYgKChjb25uLT5idWYgPSBtYWxsb2MoTUlO
 X0JVRl9TSVpFKSkgPT0gTlVMTCkgeworCQkJZXJybm8gPSBFTk9NRU07CisJCQljb25uLT5pc2Vy
 ciA9IDE7CisJCQlyZXR1cm4gKE5VTEwpOworCQl9CisJCWNvbm4tPmJ1ZnNpemUgPSBNSU5fQlVG
 X1NJWkU7CisJfQorCisJaWYgKGNvbm4tPmlzZXJyIHx8IGNvbm4tPmlzZW9mKQorCQlyZXR1cm4g
 KE5VTEwpOworCisJaWYgKGNvbm4tPmJ1ZmxlbiAtIGNvbm4tPmJ1ZnBvcyA+IDApCisJCWdvdG8g
 ZG9uZTsKKworCWNvbm4tPmJ1ZlswXSA9ICdcMCc7CisJY29ubi0+YnVmcG9zID0gMDsKKwljb25u
 LT5idWZsZW4gPSAwOworCWRvIHsKKwkJbGVuID0gZmV0Y2hfcmVhZCgmYywgc2l6ZW9mKGMpLCAx
 LCBjb25uKTsKKwkJaWYgKGxlbiA9PSAtMSkgeworCQkJY29ubi0+aXNlcnIgPSAxOworCQkJcmV0
 dXJuIChOVUxMKTsKKwkJfQorCQlpZiAobGVuID09IDApIHsKKwkJCWNvbm4tPmlzZW9mID0gMTsK
 KwkJCWJyZWFrOworCQl9CisJCWNvbm4tPmJ1Zltjb25uLT5idWZsZW4rK10gPSBjOworCQlpZiAo
 Y29ubi0+YnVmbGVuID09IGNvbm4tPmJ1ZnNpemUpIHsKKwkJCWNoYXIgKnRtcCA9IGNvbm4tPmJ1
 ZjsKKwkJCXRtcHNpemUgPSBjb25uLT5idWZzaXplICogMiArIDE7CisJCQlpZiAoKHRtcCA9IHJl
 YWxsb2ModG1wLCB0bXBzaXplKSkgPT0gTlVMTCkgeworCQkJCWVycm5vID0gRU5PTUVNOworCQkJ
 CWNvbm4tPmlzZXJyID0gMTsKKwkJCQlyZXR1cm4gKE5VTEwpOworCQkJfQorCQkJY29ubi0+YnVm
 ID0gdG1wOworCQkJY29ubi0+YnVmc2l6ZSA9IHRtcHNpemU7CisJCX0KKwl9IHdoaWxlIChjICE9
 ICdcbicpOworCisJaWYgKGNvbm4tPmJ1ZmxlbiA9PSAwKQorCQlyZXR1cm4gKE5VTEwpOworIGRv
 bmU6CisJdG1wc2l6ZSA9IE1JTihzaXplIC0gMSwgKGludCkoY29ubi0+YnVmbGVuIC0gY29ubi0+
 YnVmcG9zKSk7CisJbWVtY3B5KHN0ciwgY29ubi0+YnVmICsgY29ubi0+YnVmcG9zLCB0bXBzaXpl
 KTsKKwlzdHJbdG1wc2l6ZV0gPSAnXDAnOworCWNvbm4tPmJ1ZnBvcyArPSB0bXBzaXplOworCXJl
 dHVybiAoc3RyKTsKK30KKworc3RhdGljIGludAorZmV0Y2hfZ2V0bGluZShmZXRjaF9jb25uZWN0
 X3QgKmNvbm4sIGNoYXIgKmJ1Ziwgc2l6ZV90IGJ1ZmxlbiwKKyAgICBjb25zdCBjaGFyICoqZXJy
 b3Jtc2cpCit7CisJc2l6ZV90IGxlbjsKKwlpbnQgcnY7CisKKwlpZiAoZmV0Y2hfZ2V0bG4oYnVm
 LCBidWZsZW4sIGNvbm4pID09IE5VTEwpIHsKKwkJaWYgKGNvbm4tPmlzZW9mKSB7CS8qIEVPRiAq
 LworCQkJcnYgPSAtMjsKKwkJCWlmIChlcnJvcm1zZykKKwkJCQkqZXJyb3Jtc2cgPSAiXG5FT0Yg
 cmVjZWl2ZWQiOworCQl9IGVsc2UgewkJLyogZXJyb3IgKi8KKwkJCXJ2ID0gLTE7CisJCQlpZiAo
 ZXJyb3Jtc2cpCisJCQkJKmVycm9ybXNnID0gIkVycm9yIGVuY291bnRlcmVkIjsKKwkJfQorCQlm
 ZXRjaF9jbGVhcmVycihjb25uKTsKKwkJcmV0dXJuIChydik7CisJfQorCWxlbiA9IHN0cmxlbihi
 dWYpOworCWlmIChidWZbbGVuIC0gMV0gPT0gJ1xuJykgewkvKiBjbGVhciBhbnkgdHJhaWxpbmcg
 bmV3bGluZSAqLworCQlidWZbLS1sZW5dID0gJ1wwJzsKKwl9IGVsc2UgaWYgKGxlbiA9PSBidWZs
 ZW4gLSAxKSB7CS8qIGxpbmUgdG9vIGxvbmcgKi8KKwkJd2hpbGUgKDEpIHsKKwkJCWNoYXIgYzsK
 KwkJCXNzaXplX3QgcmxlbiA9IGZldGNoX3JlYWQoJmMsIHNpemVvZihjKSwgMSwgY29ubik7CisJ
 CQlpZiAocmxlbiA8PSAwIHx8IGMgPT0gJ1xuJykKKwkJCQlicmVhazsKKwkJfQorCQlpZiAoZXJy
 b3Jtc2cpCisJCQkqZXJyb3Jtc2cgPSAiSW5wdXQgbGluZSBpcyB0b28gbG9uZyI7CisJCWZldGNo
 X2NsZWFyZXJyKGNvbm4pOworCQlyZXR1cm4gKC0zKTsKKwl9CisJaWYgKGVycm9ybXNnKQorCQkq
 ZXJyb3Jtc2cgPSBOVUxMOworCXJldHVybiAobGVuKTsKK30KKworc3RhdGljIFNTTCAqCitmZXRj
 aF9zdGFydF9zc2woaW50IHNvY2spCit7CisJU1NMICpzc2w7CisJU1NMX0NUWCAqY3R4OworCWlu
 dCByZXQsIHNzbF9lcnI7CisKKwkvKiBJbml0IHRoZSBTU0wgbGlicmFyeSBhbmQgY29udGV4dCAq
 LworCWlmICghU1NMX2xpYnJhcnlfaW5pdCgpKXsKKwkJZnByaW50Zih0dHlvdXQsICJTU0wgbGli
 cmFyeSBpbml0IGZhaWxlZFxuIik7CisJCXJldHVybiAoTlVMTCk7CisJfQorCisJU1NMX2xvYWRf
 ZXJyb3Jfc3RyaW5ncygpOworCisJY3R4ID0gU1NMX0NUWF9uZXcoU1NMdjIzX2NsaWVudF9tZXRo
 b2QoKSk7CisJU1NMX0NUWF9zZXRfbW9kZShjdHgsIFNTTF9NT0RFX0FVVE9fUkVUUlkpOworCisJ
 c3NsID0gU1NMX25ldyhjdHgpOworCWlmIChzc2wgPT0gTlVMTCl7CisJCWZwcmludGYodHR5b3V0
 LCAiU1NMIGNvbnRleHQgY3JlYXRpb24gZmFpbGVkXG4iKTsKKwkJU1NMX0NUWF9mcmVlKGN0eCk7
 CisJCXJldHVybiAoTlVMTCk7CisJfQorCVNTTF9zZXRfZmQoc3NsLCBzb2NrKTsKKwl3aGlsZSAo
 KHJldCA9IFNTTF9jb25uZWN0KHNzbCkpID09IC0xKSB7CisJCXNzbF9lcnIgPSBTU0xfZ2V0X2Vy
 cm9yKHNzbCwgcmV0KTsKKwkJaWYgKHNzbF9lcnIgIT0gU1NMX0VSUk9SX1dBTlRfUkVBRCAmJgor
 CQkgICAgc3NsX2VyciAhPSBTU0xfRVJST1JfV0FOVF9XUklURSkgeworCQkJRVJSX3ByaW50X2Vy
 cm9yc19mcCh0dHlvdXQpOworCQkJU1NMX2ZyZWUoc3NsKTsKKwkJCXJldHVybiAoTlVMTCk7CisJ
 CX0KKwl9CisKKwlpZiAoZnRwX2RlYnVnICYmIHZlcmJvc2UpIHsKKwkJWDUwOSAqY2VydDsKKwkJ
 WDUwOV9OQU1FICpuYW1lOworCQljaGFyICpzdHI7CisKKwkJZnByaW50Zih0dHlvdXQsICJTU0wg
 Y29ubmVjdGlvbiBlc3RhYmxpc2hlZCB1c2luZyAlc1xuIiwKKwkJICAgIFNTTF9nZXRfY2lwaGVy
 KHNzbCkpOworCQljZXJ0ID0gU1NMX2dldF9wZWVyX2NlcnRpZmljYXRlKHNzbCk7CisJCW5hbWUg
 PSBYNTA5X2dldF9zdWJqZWN0X25hbWUoY2VydCk7CisJCXN0ciA9IFg1MDlfTkFNRV9vbmVsaW5l
 KG5hbWUsIDAsIDApOworCQlmcHJpbnRmKHR0eW91dCwgIkNlcnRpZmljYXRlIHN1YmplY3Q6ICVz
 XG4iLCBzdHIpOworCQlmcmVlKHN0cik7CisJCW5hbWUgPSBYNTA5X2dldF9pc3N1ZXJfbmFtZShj
 ZXJ0KTsKKwkJc3RyID0gWDUwOV9OQU1FX29uZWxpbmUobmFtZSwgMCwgMCk7CisJCWZwcmludGYo
 dHR5b3V0LCAiQ2VydGlmaWNhdGUgaXNzdWVyOiAlc1xuIiwgc3RyKTsKKwkJZnJlZShzdHIpOwor
 CX0KKworCXJldHVybiAoc3NsKTsKK30KKworI2Vsc2UJLyogIVdJVEhfU1NMICovCisjZGVmaW5l
 CUlTX0hUVFBfVFlQRSh1cmx0eXBlKQkoKHVybHR5cGUpID09IEhUVFBfVVJMX1QpCit0eXBlZGVm
 IEZJTEUgZmV0Y2hfY29ubmVjdF90OworI2RlZmluZQlmZXRjaF9wcmludGYJZnByaW50ZgorI2Rl
 ZmluZQlmZXRjaF9maWxlbm8JZmlsZW5vCisjZGVmaW5lCWZldGNoX2Vycm9yCWZlcnJvcgorI2Rl
 ZmluZQlmZXRjaF9mbHVzaAlmZmx1c2gKKyNkZWZpbmUJZmV0Y2hfb3Blbglmb3BlbgorI2RlZmlu
 ZQlmZXRjaF9mZG9wZW4JZmRvcGVuCisjZGVmaW5lCWZldGNoX2Nsb3NlCWZjbG9zZQorI2RlZmlu
 ZQlmZXRjaF9yZWFkCWZyZWFkCisjZGVmaW5lCWZldGNoX2dldGxuCWZnZXRzCisjZGVmaW5lCWZl
 dGNoX2dldGxpbmUJZ2V0X2xpbmUKKyNlbmRpZgkvKiAhV0lUSF9TU0wgKi8KIAogLyoKICAqIERl
 dGVybWluZSBpZiB0b2tlbiBpcyB0aGUgbmV4dCB3b3JkIGluIGJ1ZiAoY2FzZSBpbnNlbnNpdGl2
 ZSkuCkBAIC0zNDYsNiArOTQ4LDEzIEBAIHBhcnNlX3VybChjb25zdCBjaGFyICp1cmwsIGNvbnN0
 IGNoYXIgKmRlc2MsIHVybF90ICp1dHlwZSwKIAl9IGVsc2UgaWYgKFNUUk5FUVVBTCh1cmwsIEZJ
 TEVfVVJMKSkgewogCQl1cmwgKz0gc2l6ZW9mKEZJTEVfVVJMKSAtIDE7CiAJCSp1dHlwZSA9IEZJ
 TEVfVVJMX1Q7CisjaWZkZWYgV0lUSF9TU0wKKwl9IGVsc2UgaWYgKFNUUk5FUVVBTCh1cmwsIEhU
 VFBTX1VSTCkpIHsKKwkJdXJsICs9IHNpemVvZihIVFRQU19VUkwpIC0gMTsKKwkJKnV0eXBlID0g
 SFRUUFNfVVJMX1Q7CisJCSpwb3J0bnVtID0gSFRUUFNfUE9SVDsKKwkJdHBvcnQgPSBodHRwc3Bv
 cnQ7CisjZW5kaWYKIAl9IGVsc2UgewogCQl3YXJueCgiSW52YWxpZCAlcyBgJXMnIiwgZGVzYywg
 dXJsKTsKICBjbGVhbnVwX3BhcnNlX3VybDoKQEAgLTQ5OCwxNyArMTEwNywyMSBAQCBmZXRjaF91
 cmwoY29uc3QgY2hhciAqdXJsLCBjb25zdCBjaGFyICpwcm94eWVudiwgY2hhciAqcHJveHlhdXRo
 LCBjaGFyICp3d3dhdXRoKQogCWNoYXIJCQkqcHVzZXIsICpwcGFzcywgKnVzZXJhZ2VudDsKIAlv
 ZmZfdAkJCWhhc2hieXRlcywgcmFuZ2VzdGFydCwgcmFuZ2VlbmQsIGVudGl0eWxlbjsKIAlpbnQJ
 CQkoKnZvbGF0aWxlIGNsb3NlZnVuYykoRklMRSAqKTsKLQlGSUxFCQkJKnZvbGF0aWxlIGZpbjsK
 KwlmZXRjaF9jb25uZWN0X3QJCSp2b2xhdGlsZSBmaW47CiAJRklMRQkJCSp2b2xhdGlsZSBmb3V0
 OwogCXRpbWVfdAkJCW10aW1lOwogCXVybF90CQkJdXJsdHlwZTsKIAlpbl9wb3J0X3QJCXBvcnRu
 dW07CisjaWZkZWYgV0lUSF9TU0wKKwlTU0wJCQkqc3NsOworI2VuZGlmCiAKIAlEUFJJTlRGKCJm
 ZXRjaF91cmw6IGAlcycgcHJveHllbnYgYCVzJ1xuIiwgdXJsLCBTVFJvck5VTEwocHJveHllbnYp
 KTsKIAogCW9sZGludHIgPSBvbGRpbnRwID0gTlVMTDsKIAljbG9zZWZ1bmMgPSBOVUxMOwotCWZp
 biA9IGZvdXQgPSBOVUxMOworCWZpbiA9IE5VTEw7CisJZm91dCA9IE5VTEw7CiAJcyA9IC0xOwog
 CXNhdmVmaWxlID0gTlVMTDsKIAlhdXRoID0gbG9jYXRpb24gPSBtZXNzYWdlID0gTlVMTDsKQEAg
 LTUzMSw3ICsxMTQ0LDcgQEAgZmV0Y2hfdXJsKGNvbnN0IGNoYXIgKnVybCwgY29uc3QgY2hhciAq
 cHJveHllbnYsIGNoYXIgKnByb3h5YXV0aCwgY2hhciAqd3d3YXV0aCkKIAkJCXJ2YWwgPSBmZXRj
 aF9mdHAodXJsKTsKIAkJCWdvdG8gY2xlYW51cF9mZXRjaF91cmw7CiAJCX0KLQkJaWYgKHVybHR5
 cGUgIT0gSFRUUF9VUkxfVCB8fCBvdXRmaWxlID09IE5VTEwpICB7CisJCWlmICghSVNfSFRUUF9U
 WVBFKHVybHR5cGUpIHx8IG91dGZpbGUgPT0gTlVMTCkgIHsKIAkJCXdhcm54KCJJbnZhbGlkIFVS
 TCAobm8gZmlsZSBhZnRlciBob3N0KSBgJXMnIiwgdXJsKTsKIAkJCWdvdG8gY2xlYW51cF9mZXRj
 aF91cmw7CiAJCX0KQEAgLTU3MSwxNyArMTE4NCwxNyBAQCBmZXRjaF91cmwoY29uc3QgY2hhciAq
 dXJsLCBjb25zdCBjaGFyICpwcm94eWVudiwgY2hhciAqcHJveHlhdXRoLCBjaGFyICp3d3dhdXRo
 KQogCX0KIAlpZiAodXJsdHlwZSA9PSBGSUxFX1VSTF9UKSB7CQkvKiBmaWxlOi8vIFVSTHMgKi8K
 IAkJZGlyZWN0aW9uID0gImNvcGllZCI7Ci0JCWZpbiA9IGZvcGVuKGRlY29kZWRwYXRoLCAiciIp
 OworCQlmaW4gPSBmZXRjaF9vcGVuKGRlY29kZWRwYXRoLCAiciIpOwogCQlpZiAoZmluID09IE5V
 TEwpIHsKIAkJCXdhcm4oIkNhbid0IG9wZW4gYCVzJyIsIGRlY29kZWRwYXRoKTsKIAkJCWdvdG8g
 Y2xlYW51cF9mZXRjaF91cmw7CiAJCX0KLQkJaWYgKGZzdGF0KGZpbGVubyhmaW4pLCAmc2IpID09
 IDApIHsKKwkJaWYgKGZzdGF0KGZldGNoX2ZpbGVubyhmaW4pLCAmc2IpID09IDApIHsKIAkJCW10
 aW1lID0gc2Iuc3RfbXRpbWU7CiAJCQlmaWxlc2l6ZSA9IHNiLnN0X3NpemU7CiAJCX0KIAkJaWYg
 KHJlc3RhcnRfcG9pbnQpIHsKLQkJCWlmIChsc2VlayhmaWxlbm8oZmluKSwgcmVzdGFydF9wb2lu
 dCwgU0VFS19TRVQpIDwgMCkgeworCQkJaWYgKGxzZWVrKGZldGNoX2ZpbGVubyhmaW4pLCByZXN0
 YXJ0X3BvaW50LCBTRUVLX1NFVCkgPCAwKSB7CiAJCQkJd2FybigiQ2FuJ3Qgc2VlayB0byByZXN0
 YXJ0IGAlcyciLAogCQkJCSAgICBkZWNvZGVkcGF0aCk7CiAJCQkJZ290byBjbGVhbnVwX2ZldGNo
 X3VybDsKQEAgLTU5NCwxMiArMTIwNywxNSBAQCBmZXRjaF91cmwoY29uc3QgY2hhciAqdXJsLCBj
 b25zdCBjaGFyICpwcm94eWVudiwgY2hhciAqcHJveHlhdXRoLCBjaGFyICp3d3dhdXRoKQogCQkJ
 CSAgICAoTExUKXJlc3RhcnRfcG9pbnQpOwogCQkJZnB1dHMoIlxuIiwgdHR5b3V0KTsKIAkJfQor
 CQlpZiAoMCA9PSByY3ZidWZfc2l6ZSkgeworCQkJcmN2YnVmX3NpemUgPSA4ICogMTAyNDsgLyog
 WFhYICovCisJCX0KIAl9IGVsc2UgewkJCQkvKiBmdHA6Ly8gb3IgaHR0cDovLyBVUkxzICovCiAJ
 CWNvbnN0IGNoYXIgKmxlYWRpbmc7CiAJCWludCBoYXNsZWFkaW5nOwogCiAJCWlmIChwcm94eWVu
 diA9PSBOVUxMKSB7Ci0JCQlpZiAodXJsdHlwZSA9PSBIVFRQX1VSTF9UKQorCQkJaWYgKElTX0hU
 VFBfVFlQRSh1cmx0eXBlKSkKIAkJCQlwcm94eWVudiA9IGdldG9wdGlvbnZhbHVlKCJodHRwX3By
 b3h5Iik7CiAJCQllbHNlIGlmICh1cmx0eXBlID09IEZUUF9VUkxfVCkKIAkJCQlwcm94eWVudiA9
 IGdldG9wdGlvbnZhbHVlKCJmdHBfcHJveHkiKTsKQEAgLTY2MCw3ICsxMjc2LDcgQEAgZmV0Y2hf
 dXJsKGNvbnN0IGNoYXIgKnVybCwgY29uc3QgY2hhciAqcHJveHllbnYsIGNoYXIgKnByb3h5YXV0
 aCwgY2hhciAqd3d3YXV0aCkKIAkJCQkgICAgJnBwYXRoKSA9PSAtMSkKIAkJCQkJZ290byBjbGVh
 bnVwX2ZldGNoX3VybDsKIAotCQkJCWlmICgocHVybHR5cGUgIT0gSFRUUF9VUkxfVAorCQkJCWlm
 ICgoIUlTX0hUVFBfVFlQRShwdXJsdHlwZSkKIAkJCQkgICAgICYmIHB1cmx0eXBlICE9IEZUUF9V
 UkxfVCkgfHwKIAkJCQkgICAgRU1QVFlTVFJJTkcocGhvc3QpIHx8CiAJCQkJICAgICghIEVNUFRZ
 U1RSSU5HKHBwYXRoKQpAQCAtNjkwLDYgKzEzMDYsNyBAQCBmZXRjaF91cmwoY29uc3QgY2hhciAq
 dXJsLCBjb25zdCBjaGFyICpwcm94eWVudiwgY2hhciAqcHJveHlhdXRoLCBjaGFyICp3d3dhdXRo
 KQogCQkJCUZSRUVQVFIocGF0aCk7CiAJCQkJcGF0aCA9IGZ0cF9zdHJkdXAodXJsKTsKIAkJCQlG
 UkVFUFRSKHBwYXRoKTsKKwkJCQl1cmx0eXBlID0gcHVybHR5cGU7CiAJCQl9CiAJCX0gLyogISBF
 TVBUWVNUUklORyhwcm94eWVudikgKi8KIApAQCAtNzA5LDYgKzEzMjYsOSBAQCBmZXRjaF91cmwo
 Y29uc3QgY2hhciAqdXJsLCBjb25zdCBjaGFyICpwcm94eWVudiwgY2hhciAqcHJveHlhdXRoLCBj
 aGFyICp3d3dhdXRoKQogCQkJaG9zdCA9IHJlczAtPmFpX2Nhbm9ubmFtZTsKIAogCQlzID0gLTE7
 CisjaWZkZWYgV0lUSF9TU0wKKwkJc3NsID0gTlVMTDsKKyNlbmRpZgogCQlmb3IgKHJlcyA9IHJl
 czA7IHJlczsgcmVzID0gcmVzLT5haV9uZXh0KSB7CiAJCQljaGFyCWhuYW1lW05JX01BWEhPU1Rd
 LCBzbmFtZVtOSV9NQVhTRVJWXTsKIApAQCAtNzQxLDYgKzEzNjEsMTYgQEAgZmV0Y2hfdXJsKGNv
 bnN0IGNoYXIgKnVybCwgY29uc3QgY2hhciAqcHJveHllbnYsIGNoYXIgKnByb3h5YXV0aCwgY2hh
 ciAqd3d3YXV0aCkKIAkJCQljb250aW51ZTsKIAkJCX0KIAorI2lmZGVmIFdJVEhfU1NMCisJCQlp
 ZiAodXJsdHlwZSA9PSBIVFRQU19VUkxfVCkgeworCQkJCWlmICgoc3NsID0gZmV0Y2hfc3RhcnRf
 c3NsKHMpKSA9PSBOVUxMKSB7CisJCQkJCWNsb3NlKHMpOworCQkJCQlzID0gLTE7CisJCQkJCWNv
 bnRpbnVlOworCQkJCX0KKwkJCX0KKyNlbmRpZgorCiAJCQkvKiBzdWNjZXNzICovCiAJCQlicmVh
 azsKIAkJfQpAQCAtNzUwLDcgKzEzODAsMTEgQEAgZmV0Y2hfdXJsKGNvbnN0IGNoYXIgKnVybCwg
 Y29uc3QgY2hhciAqcHJveHllbnYsIGNoYXIgKnByb3h5YXV0aCwgY2hhciAqd3d3YXV0aCkKIAkJ
 CWdvdG8gY2xlYW51cF9mZXRjaF91cmw7CiAJCX0KIAotCQlmaW4gPSBmZG9wZW4ocywgInIrIik7
 CisJCWZpbiA9IGZldGNoX2Zkb3BlbihzLCAicisiKTsKKyNpZmRlZiBXSVRIX1NTTAorCQlpZiAo
 dXJsdHlwZSA9PSBIVFRQU19VUkxfVCkKKwkJCWZpbi0+c3NsID0gc3NsOworI2VuZGlmCiAJCS8q
 CiAJCSAqIENvbnN0cnVjdCBhbmQgc2VuZCB0aGUgcmVxdWVzdC4KIAkJICovCkBAIC03NjUsMTEg
 KzEzOTksMTEgQEAgZmV0Y2hfdXJsKGNvbnN0IGNoYXIgKnVybCwgY29uc3QgY2hhciAqcHJveHll
 bnYsIGNoYXIgKnByb3h5YXV0aCwgY2hhciAqd3d3YXV0aCkKIAkJCQlsZWFkaW5nID0gIiwgIjsK
 IAkJCQloYXNsZWFkaW5nKys7CiAJCQl9Ci0JCQlmcHJpbnRmKGZpbiwgIkdFVCAlcyBIVFRQLzEu
 MFxyXG4iLCBwYXRoKTsKKwkJCWZldGNoX3ByaW50ZihmaW4sICJHRVQgJXMgSFRUUC8xLjBcclxu
 IiwgcGF0aCk7CiAJCQlpZiAoZmx1c2hjYWNoZSkKLQkJCQlmcHJpbnRmKGZpbiwgIlByYWdtYTog
 bm8tY2FjaGVcclxuIik7CisJCQkJZmV0Y2hfcHJpbnRmKGZpbiwgIlByYWdtYTogbm8tY2FjaGVc
 clxuIik7CiAJCX0gZWxzZSB7Ci0JCQlmcHJpbnRmKGZpbiwgIkdFVCAlcyBIVFRQLzEuMVxyXG4i
 LCBwYXRoKTsKKwkJCWZldGNoX3ByaW50ZihmaW4sICJHRVQgJXMgSFRUUC8xLjFcclxuIiwgcGF0
 aCk7CiAJCQlpZiAoc3RyY2hyKGhvc3QsICc6JykpIHsKIAkJCQljaGFyICpoLCAqcDsKIApAQCAt
 NzgyLDE4ICsxNDE2LDIzIEBAIGZldGNoX3VybChjb25zdCBjaGFyICp1cmwsIGNvbnN0IGNoYXIg
 KnByb3h5ZW52LCBjaGFyICpwcm94eWF1dGgsIGNoYXIgKnd3d2F1dGgpCiAJCQkJICAgIChwID0g
 c3RyY2hyKGgsICclJykpICE9IE5VTEwpIHsKIAkJCQkJKnAgPSAnXDAnOwogCQkJCX0KLQkJCQlm
 cHJpbnRmKGZpbiwgIkhvc3Q6IFslc10iLCBoKTsKKwkJCQlmZXRjaF9wcmludGYoZmluLCAiSG9z
 dDogWyVzXSIsIGgpOwogCQkJCWZyZWUoaCk7CiAJCQl9IGVsc2UKLQkJCQlmcHJpbnRmKGZpbiwg
 Ikhvc3Q6ICVzIiwgaG9zdCk7CisJCQkJZmV0Y2hfcHJpbnRmKGZpbiwgIkhvc3Q6ICVzIiwgaG9z
 dCk7CisjaWZkZWYgV0lUSF9TU0wKKwkJCWlmICgodXJsdHlwZSA9PSBIVFRQX1VSTF9UICYmIHBv
 cnRudW0gIT0gSFRUUF9QT1JUKSB8fAorCQkJICAgICh1cmx0eXBlID09IEhUVFBTX1VSTF9UICYm
 IHBvcnRudW0gIT0gSFRUUFNfUE9SVCkpCisjZWxzZQogCQkJaWYgKHBvcnRudW0gIT0gSFRUUF9Q
 T1JUKQotCQkJCWZwcmludGYoZmluLCAiOiV1IiwgcG9ydG51bSk7Ci0JCQlmcHJpbnRmKGZpbiwg
 IlxyXG4iKTsKLQkJCWZwcmludGYoZmluLCAiQWNjZXB0OiAqLypcclxuIik7Ci0JCQlmcHJpbnRm
 KGZpbiwgIkNvbm5lY3Rpb246IGNsb3NlXHJcbiIpOworI2VuZGlmCisJCQkJZmV0Y2hfcHJpbnRm
 KGZpbiwgIjoldSIsIHBvcnRudW0pOworCQkJZmV0Y2hfcHJpbnRmKGZpbiwgIlxyXG4iKTsKKwkJ
 CWZldGNoX3ByaW50ZihmaW4sICJBY2NlcHQ6ICovKlxyXG4iKTsKKwkJCWZldGNoX3ByaW50Zihm
 aW4sICJDb25uZWN0aW9uOiBjbG9zZVxyXG4iKTsKIAkJCWlmIChyZXN0YXJ0X3BvaW50KSB7CiAJ
 CQkJZnB1dHMobGVhZGluZywgdHR5b3V0KTsKLQkJCQlmcHJpbnRmKGZpbiwgIlJhbmdlOiBieXRl
 cz0iIExMRiAiLVxyXG4iLAorCQkJCWZwcmludGYodHR5b3V0LCAiUmFuZ2U6IGJ5dGVzPSIgTExG
 ICItXHJcbiIsCiAJCQkJICAgIChMTFQpcmVzdGFydF9wb2ludCk7CiAJCQkJZnByaW50Zih0dHlv
 dXQsICJyZXN0YXJ0aW5nIGF0ICIgTExGLAogCQkJCSAgICAoTExUKXJlc3RhcnRfcG9pbnQpOwpA
 QCAtODAxLDEyICsxNDQwLDEyIEBAIGZldGNoX3VybChjb25zdCBjaGFyICp1cmwsIGNvbnN0IGNo
 YXIgKnByb3h5ZW52LCBjaGFyICpwcm94eWF1dGgsIGNoYXIgKnd3d2F1dGgpCiAJCQkJaGFzbGVh
 ZGluZysrOwogCQkJfQogCQkJaWYgKGZsdXNoY2FjaGUpCi0JCQkJZnByaW50ZihmaW4sICJDYWNo
 ZS1Db250cm9sOiBuby1jYWNoZVxyXG4iKTsKKwkJCQlmZXRjaF9wcmludGYoZmluLCAiQ2FjaGUt
 Q29udHJvbDogbm8tY2FjaGVcclxuIik7CiAJCX0KIAkJaWYgKCh1c2VyYWdlbnQ9Z2V0ZW52KCJG
 VFBVU0VSQUdFTlQiKSkgIT0gTlVMTCkgewotCQkJZnByaW50ZihmaW4sICJVc2VyLUFnZW50OiAl
 c1xyXG4iLCB1c2VyYWdlbnQpOworCQkJZmV0Y2hfcHJpbnRmKGZpbiwgIlVzZXItQWdlbnQ6ICVz
 XHJcbiIsIHVzZXJhZ2VudCk7CiAJCX0gZWxzZSB7Ci0JCQlmcHJpbnRmKGZpbiwgIlVzZXItQWdl
 bnQ6ICVzLyVzXHJcbiIsCisJCQlmZXRjaF9wcmludGYoZmluLCAiVXNlci1BZ2VudDogJXMvJXNc
 clxuIiwKIAkJCSAgICBGVFBfUFJPRFVDVCwgRlRQX1ZFUlNJT04pOwogCQl9CiAJCWlmICh3d3dh
 dXRoKSB7CkBAIC04MTYsNyArMTQ1NSw3IEBAIGZldGNoX3VybChjb25zdCBjaGFyICp1cmwsIGNv
 bnN0IGNoYXIgKnByb3h5ZW52LCBjaGFyICpwcm94eWF1dGgsIGNoYXIgKnd3d2F1dGgpCiAJCQkJ
 bGVhZGluZyA9ICIsICI7CiAJCQkJaGFzbGVhZGluZysrOwogCQkJfQotCQkJZnByaW50ZihmaW4s
 ICJBdXRob3JpemF0aW9uOiAlc1xyXG4iLCB3d3dhdXRoKTsKKwkJCWZldGNoX3ByaW50ZihmaW4s
 ICJBdXRob3JpemF0aW9uOiAlc1xyXG4iLCB3d3dhdXRoKTsKIAkJfQogCQlpZiAocHJveHlhdXRo
 KSB7CiAJCQlpZiAodmVyYm9zZSkgewpAQCAtODI1LDE4ICsxNDY0LDE4IEBAIGZldGNoX3VybChj
 b25zdCBjaGFyICp1cmwsIGNvbnN0IGNoYXIgKnByb3h5ZW52LCBjaGFyICpwcm94eWF1dGgsIGNo
 YXIgKnd3d2F1dGgpCiAJCQkJbGVhZGluZyA9ICIsICI7CiAJCQkJaGFzbGVhZGluZysrOwogCQkJ
 fQotCQkJZnByaW50ZihmaW4sICJQcm94eS1BdXRob3JpemF0aW9uOiAlc1xyXG4iLCBwcm94eWF1
 dGgpOworCQkJZmV0Y2hfcHJpbnRmKGZpbiwgIlByb3h5LUF1dGhvcml6YXRpb246ICVzXHJcbiIs
 IHByb3h5YXV0aCk7CiAJCX0KIAkJaWYgKHZlcmJvc2UgJiYgaGFzbGVhZGluZykKIAkJCWZwdXRz
 KCIpXG4iLCB0dHlvdXQpOwotCQlmcHJpbnRmKGZpbiwgIlxyXG4iKTsKLQkJaWYgKGZmbHVzaChm
 aW4pID09IEVPRikgeworCQlmZXRjaF9wcmludGYoZmluLCAiXHJcbiIpOworCQlpZiAoZmV0Y2hf
 Zmx1c2goZmluKSA9PSBFT0YpIHsKIAkJCXdhcm4oIldyaXRpbmcgSFRUUCByZXF1ZXN0Iik7CiAJ
 CQlnb3RvIGNsZWFudXBfZmV0Y2hfdXJsOwogCQl9CiAKIAkJCQkvKiBSZWFkIHRoZSByZXNwb25z
 ZSAqLwotCQlsZW4gPSBnZXRfbGluZShmaW4sIGJ1Ziwgc2l6ZW9mKGJ1ZiksICZlcnJvcm1zZyk7
 CisJCWxlbiA9IGZldGNoX2dldGxpbmUoZmluLCBidWYsIHNpemVvZihidWYpLCAmZXJyb3Jtc2cp
 OwogCQlpZiAobGVuIDwgMCkgewogCQkJaWYgKCplcnJvcm1zZyA9PSAnXG4nKQogCQkJCWVycm9y
 bXNnKys7CkBAIC04NjAsNyArMTQ5OSw3IEBAIGZldGNoX3VybChjb25zdCBjaGFyICp1cmwsIGNv
 bnN0IGNoYXIgKnByb3h5ZW52LCBjaGFyICpwcm94eWF1dGgsIGNoYXIgKnd3d2F1dGgpCiAKIAkJ
 CQkvKiBSZWFkIHRoZSByZXN0IG9mIHRoZSBoZWFkZXIuICovCiAJCXdoaWxlICgxKSB7Ci0JCQls
 ZW4gPSBnZXRfbGluZShmaW4sIGJ1Ziwgc2l6ZW9mKGJ1ZiksICZlcnJvcm1zZyk7CisJCQlsZW4g
 PSBmZXRjaF9nZXRsaW5lKGZpbiwgYnVmLCBzaXplb2YoYnVmKSwgJmVycm9ybXNnKTsKIAkJCWlm
 IChsZW4gPCAwKSB7CiAJCQkJaWYgKCplcnJvcm1zZyA9PSAnXG4nKQogCQkJCQllcnJvcm1zZysr
 OwpAQCAtMTE0OCw3ICsxNzg3LDcgQEAgZmV0Y2hfdXJsKGNvbnN0IGNoYXIgKnVybCwgY29uc3Qg
 Y2hhciAqcHJveHllbnYsIGNoYXIgKnByb3h5YXV0aCwgY2hhciAqd3d3YXV0aCkKIAkJbGFzdGNo
 dW5rID0gMDsKIAkJCQkJLyogcmVhZCBjaHVuay1zaXplICovCiAJCWlmIChpc2NodW5rZWQpIHsK
 LQkJCWlmIChmZ2V0cyh4ZmVyYnVmLCBidWZzaXplLCBmaW4pID09IE5VTEwpIHsKKwkJCWlmIChm
 ZXRjaF9nZXRsbih4ZmVyYnVmLCBidWZzaXplLCBmaW4pID09IE5VTEwpIHsKIAkJCQl3YXJueCgi
 VW5leHBlY3RlZCBFT0YgcmVhZGluZyBjaHVuay1zaXplIik7CiAJCQkJZ290byBjbGVhbnVwX2Zl
 dGNoX3VybDsKIAkJCX0KQEAgLTEyMDEsNyArMTg0MCw3IEBAIGZldGNoX3VybChjb25zdCBjaGFy
 ICp1cmwsIGNvbnN0IGNoYXIgKnByb3h5ZW52LCBjaGFyICpwcm94eWF1dGgsIGNoYXIgKnd3d2F1
 dGgpCiAJCQlpZiAoaXNjaHVua2VkKQogCQkJCWJ1ZnJlbSA9IE1JTihjaHVua3NpemUsIGJ1ZnJl
 bSk7CiAJCQl3aGlsZSAoYnVmcmVtID4gMCkgewotCQkJCWZsZW4gPSBmcmVhZCh4ZmVyYnVmLCBz
 aXplb2YoY2hhciksCisJCQkJZmxlbiA9IGZldGNoX3JlYWQoeGZlcmJ1Ziwgc2l6ZW9mKGNoYXIp
 LAogCQkJCSAgICBNSU4oKG9mZl90KWJ1ZnNpemUsIGJ1ZnJlbSksIGZpbik7CiAJCQkJaWYgKGZs
 ZW4gPD0gMCkKIAkJCQkJZ290byBjaHVua2RvbmU7CkBAIC0xMjQwLDcgKzE4NzksNyBAQCBmZXRj
 aF91cmwoY29uc3QgY2hhciAqdXJsLCBjb25zdCBjaGFyICpwcm94eWVudiwgY2hhciAqcHJveHlh
 dXRoLCBjaGFyICp3d3dhdXRoKQogCQkJCQkvKiByZWFkIENSTEYgYWZ0ZXIgY2h1bmsqLwogIGNo
 dW5rZG9uZToKIAkJaWYgKGlzY2h1bmtlZCkgewotCQkJaWYgKGZnZXRzKHhmZXJidWYsIGJ1ZnNp
 emUsIGZpbikgPT0gTlVMTCkgeworCQkJaWYgKGZldGNoX2dldGxuKHhmZXJidWYsIGJ1ZnNpemUs
 IGZpbikgPT0gTlVMTCkgewogCQkJCXdhcm54KCJVbmV4cGVjdGVkIEVPRiByZWFkaW5nIGNodW5r
 IENSTEYiKTsKIAkJCQlnb3RvIGNsZWFudXBfZmV0Y2hfdXJsOwogCQkJfQpAQCAtMTI2MCw3ICsx
 ODk5LDcgQEAgZmV0Y2hfdXJsKGNvbnN0IGNoYXIgKnVybCwgY29uc3QgY2hhciAqcHJveHllbnYs
 IGNoYXIgKnByb3h5YXV0aCwgY2hhciAqd3d3YXV0aCkKIAkJCSh2b2lkKXB1dGMoJyMnLCB0dHlv
 dXQpOwogCQkodm9pZClwdXRjKCdcbicsIHR0eW91dCk7CiAJfQotCWlmIChmZXJyb3IoZmluKSkg
 eworCWlmIChmZXRjaF9lcnJvcihmaW4pKSB7CiAJCXdhcm4oIlJlYWRpbmcgZmlsZSIpOwogCQln
 b3RvIGNsZWFudXBfZmV0Y2hfdXJsOwogCX0KQEAgLTEyOTcsNyArMTkzNiw3IEBAIGZldGNoX3Vy
 bChjb25zdCBjaGFyICp1cmwsIGNvbnN0IGNoYXIgKnByb3h5ZW52LCBjaGFyICpwcm94eWF1dGgs
 IGNoYXIgKnd3d2F1dGgpCiAJaWYgKG9sZGludHApCiAJCSh2b2lkKXhzaWduYWwoU0lHUElQRSwg
 b2xkaW50cCk7CiAJaWYgKGZpbiAhPSBOVUxMKQotCQlmY2xvc2UoZmluKTsKKwkJZmV0Y2hfY2xv
 c2UoZmluKTsKIAllbHNlIGlmIChzICE9IC0xKQogCQljbG9zZShzKTsKIAlpZiAoY2xvc2VmdW5j
 ICE9IE5VTEwgJiYgZm91dCAhPSBOVUxMKQpAQCAtMTcyOSw3ICsyMzY4LDExIEBAIGdvX2ZldGNo
 KGNvbnN0IGNoYXIgKnVybCkKIAkvKgogCSAqIENoZWNrIGZvciBmaWxlOi8vIGFuZCBodHRwOi8v
 IFVSTHMuCiAJICovCi0JaWYgKFNUUk5FUVVBTCh1cmwsIEhUVFBfVVJMKSB8fCBTVFJORVFVQUwo
 dXJsLCBGSUxFX1VSTCkpCisJaWYgKFNUUk5FUVVBTCh1cmwsIEhUVFBfVVJMKQorI2lmZGVmIFdJ
 VEhfU1NMCisJICAgIHx8IFNUUk5FUVVBTCh1cmwsIEhUVFBTX1VSTCkKKyNlbmRpZgorCSAgICB8
 fCBTVFJORVFVQUwodXJsLCBGSUxFX1VSTCkpCiAJCXJldHVybiAoZmV0Y2hfdXJsKHVybCwgTlVM
 TCwgTlVMTCwgTlVMTCkpOwogCiAJLyoKZGlmZiAtLWdpdCBhL3Vzci5iaW4vZnRwL2Z0cF92YXIu
 aCBiL3Vzci5iaW4vZnRwL2Z0cF92YXIuaAppbmRleCBkYjUwMWNmLi44MTk5Yjc4IDEwMDY0NAot
 LS0gYS91c3IuYmluL2Z0cC9mdHBfdmFyLmgKKysrIGIvdXNyLmJpbi9mdHAvZnRwX3Zhci5oCkBA
 IC0xNzcsNiArMTc3LDcgQEAgZW51bSB7CiAKICNkZWZpbmUJRlRQX1BPUlQJMjEJLyogZGVmYXVs
 dCBpZiAhIGdldHNlcnZieW5hbWUoImZ0cC90Y3AiKSAqLwogI2RlZmluZQlIVFRQX1BPUlQJODAJ
 LyogZGVmYXVsdCBpZiAhIGdldHNlcnZieW5hbWUoImh0dHAvdGNwIikgKi8KKyNkZWZpbmUJSFRU
 UFNfUE9SVAk0NDMJLyogZGVmYXVsdCBpZiAhIGdldHNlcnZieW5hbWUoImh0dHBzL3RjcCIpICov
 CiAjaWZuZGVmCUdBVEVfUE9SVAogI2RlZmluZQlHQVRFX1BPUlQJMjEJLyogZGVmYXVsdCBpZiAh
 IGdldHNlcnZieW5hbWUoImZ0cGdhdGUvdGNwIikgKi8KICNlbmRpZgpAQCAtMjczLDYgKzI3NCw5
 IEBAIEdMT0JBTAljaGFyICAgKnVzZXJuYW1lOwkvKiBuYW1lIG9mIHVzZXIgbG9nZ2VkIGluIGFz
 LiAoZHluYW1pYykgKi8KIEdMT0JBTAlzYV9mYW1pbHlfdCBmYW1pbHk7CS8qIGFkZHJlc3MgZmFt
 aWx5IHRvIHVzZSBmb3IgY29ubmVjdGlvbnMgKi8KIEdMT0JBTAljb25zdCBjaGFyICpmdHBwb3J0
 OwkvKiBwb3J0IG51bWJlciB0byB1c2UgZm9yIEZUUCBjb25uZWN0aW9ucyAqLwogR0xPQkFMCWNv
 bnN0IGNoYXIgKmh0dHBwb3J0OwkvKiBwb3J0IG51bWJlciB0byB1c2UgZm9yIEhUVFAgY29ubmVj
 dGlvbnMgKi8KKyNpZmRlZiBXSVRIX1NTTAorR0xPQkFMCWNvbnN0IGNoYXIgKmh0dHBzcG9ydDsJ
 LyogcG9ydCBudW1iZXIgdG8gdXNlIGZvciBIVFRQUyBjb25uZWN0aW9ucyAqLworI2VuZGlmCiBH
 TE9CQUwJY29uc3QgY2hhciAqZ2F0ZXBvcnQ7CS8qIHBvcnQgbnVtYmVyIHRvIHVzZSBmb3IgZ2F0
 ZWZ0cCBjb25uZWN0aW9ucyAqLwogR0xPQkFMCXN0cnVjdCBhZGRyaW5mbyAqYmluZGFpOyAvKiBs
 b2NhbCBhZGRyZXNzIHRvIGJpbmQgYXMgKi8KIApkaWZmIC0tZ2l0IGEvdXNyLmJpbi9mdHAvbWFp
 bi5jIGIvdXNyLmJpbi9mdHAvbWFpbi5jCmluZGV4IDU4MjM0ZWUuLmMwZjY5MmIgMTAwNjQ0Ci0t
 LSBhL3Vzci5iaW4vZnRwL21haW4uYworKysgYi91c3IuYmluL2Z0cC9tYWluLmMKQEAgLTE1MCw2
 ICsxNTAsOSBAQCBtYWluKGludCB2b2xhdGlsZSBhcmdjLCBjaGFyICoqdm9sYXRpbGUgYXJndikK
 IAogCWZ0cHBvcnQgPSAiZnRwIjsKIAlodHRwcG9ydCA9ICJodHRwIjsKKyNpZmRlZiBXSVRIX1NT
 TAorCWh0dHBzcG9ydCA9ICJodHRwcyI7CisjZW5kaWYKIAlnYXRlcG9ydCA9IE5VTEw7CiAJY3Ag
 PSBnZXRlbnYoIkZUUFNFUlZFUlBPUlQiKTsKIAlpZiAoY3AgIT0gTlVMTCkKQEAgLTEwNDQsNiAr
 MTA0Nyw5IEBAIHVzYWdlKHZvaWQpCiAiICAgICAgICAgICBbW3VzZXJAXWhvc3QgW3BvcnRdXSBb
 aG9zdDpwYXRoWy9dXSBbZmlsZTovLy9maWxlXVxuIgogIiAgICAgICAgICAgW2Z0cDovL1t1c2Vy
 WzpwYXNzXUBdaG9zdFs6cG9ydF0vcGF0aFsvXV1cbiIKICIgICAgICAgICAgIFtodHRwOi8vW3Vz
 ZXJbOnBhc3NdQF1ob3N0Wzpwb3J0XS9wYXRoXSBbLi4uXVxuIgorI2lmZGVmIFdJVEhfU1NMCisi
 ICAgICAgICAgICBbaHR0cHM6Ly9bdXNlcls6cGFzc11AXWhvc3RbOnBvcnRdL3BhdGhdIFsuLi5d
 XG4iCisjZW5kaWYKICIgICAgICAgJXMgLXUgVVJMIGZpbGUgWy4uLl1cbiIsIHByb2duYW1lLCBw
 cm9nbmFtZSk7CiAJZXhpdCgxKTsKIH0K
 --e89a8f923f3aff7bb104cffeee57--

From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/47276 CVS commit: src/usr.bin/ftp
Date: Fri, 21 Dec 2012 13:07:37 -0500

 Module Name:	src
 Committed By:	christos
 Date:		Fri Dec 21 18:07:37 UTC 2012

 Modified Files:
 	src/usr.bin/ftp: Makefile fetch.c ftp_var.h main.c
 Added Files:
 	src/usr.bin/ftp: ssl.c ssl.h

 Log Message:
 PR/47276: Add https support


 To generate a diff of this commit:
 cvs rdiff -u -r1.35 -r1.36 src/usr.bin/ftp/Makefile
 cvs rdiff -u -r1.198 -r1.199 src/usr.bin/ftp/fetch.c
 cvs rdiff -u -r1.81 -r1.82 src/usr.bin/ftp/ftp_var.h
 cvs rdiff -u -r1.120 -r1.121 src/usr.bin/ftp/main.c
 cvs rdiff -u -r0 -r1.1 src/usr.bin/ftp/ssl.c src/usr.bin/ftp/ssl.h

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/47276 CVS commit: src/rescue
Date: Fri, 21 Dec 2012 13:09:39 -0500

 Module Name:	src
 Committed By:	christos
 Date:		Fri Dec 21 18:09:39 UTC 2012

 Modified Files:
 	src/rescue: list.crypto

 Log Message:
 PR/47276: ftp has ssl support now.


 To generate a diff of this commit:
 cvs rdiff -u -r1.8 -r1.9 src/rescue/list.crypto

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/47276 CVS commit: src/distrib/amd64/cdroms
Date: Fri, 21 Dec 2012 13:11:11 -0500

 Module Name:	src
 Committed By:	christos
 Date:		Fri Dec 21 18:11:11 UTC 2012

 Modified Files:
 	src/distrib/amd64/cdroms: Makefile.cdrom

 Log Message:
 PR/47276: ftp has https support now


 To generate a diff of this commit:
 cvs rdiff -u -r1.7 -r1.8 src/distrib/amd64/cdroms/Makefile.cdrom

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/47276 CVS commit: src/distrib/i386/cdroms
Date: Fri, 21 Dec 2012 13:13:23 -0500

 Module Name:	src
 Committed By:	christos
 Date:		Fri Dec 21 18:13:22 UTC 2012

 Modified Files:
 	src/distrib/i386/cdroms: Makefile.cdrom

 Log Message:
 PR/47276: ftp has https support now


 To generate a diff of this commit:
 cvs rdiff -u -r1.27 -r1.28 src/distrib/i386/cdroms/Makefile.cdrom

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Izumi Tsutsui" <tsutsui@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/47276 CVS commit: src/distrib/sparc64/cdroms/installcd
Date: Sat, 22 Dec 2012 17:51:19 +0000

 Module Name:	src
 Committed By:	tsutsui
 Date:		Sat Dec 22 17:51:19 UTC 2012

 Modified Files:
 	src/distrib/sparc64/cdroms/installcd: Makefile

 Log Message:
 Sync with amd64 and i386 installcds:
 >> PR/47276: ftp has https support now
 (i.e. now libcrypto and libssl are required in non-crunched installcd)


 To generate a diff of this commit:
 cvs rdiff -u -r1.15 -r1.16 src/distrib/sparc64/cdroms/installcd/Makefile

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: open->closed
State-Changed-By: dholland@NetBSD.org
State-Changed-When: Mon, 07 Oct 2013 06:54:52 +0000
State-Changed-Why:
Fixed.


From: "S.P.Zeidler" <spz@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/47276 CVS commit: pkgsrc/net/tnftp/files
Date: Fri, 31 Oct 2014 18:47:26 +0000

 Module Name:	pkgsrc
 Committed By:	spz
 Date:		Fri Oct 31 18:47:26 UTC 2014

 Update of /cvsroot/pkgsrc/net/tnftp/files
 In directory ivanova.netbsd.org:/tmp/cvs-serv2789

 Log Message:
 Fri Oct 31 04:07:38 UTC 2014    lukem

         * Release as "tnftp 20141031".

         * Merge NetBSD usr.bin/ftp from 20130220 to 20141026:
                 - Don't pay attention to special characters if they don't
                   come from the command line (from jmcneill).
                   Fixes CVE-2014-8517.
                 - pr/34796: Hauke Fath: ftp does not timeout on http fetches.

 Sun May  5 13:51:47 UTC 2013    lukem

         * Release as "tnftp 20130505"

         * Implement --enable-ssl (and --with-openssl) to enable
           https:// fetch support.

         * Merge NetBSD ftp from 20090520 to 20130220.  Changes:
                 - https:// support.
                   NetBSD problem report 47276 from NONAKA Kimihiro.
                 - Allow -R to restart non-existent ftp:// URIs.
                 - Don't assume AF_INET support is available.
                   FreeBSD problem report 162661.
                 - Parse HTTP 'Date' entries in the `C' locale rather than the
                   user's.
                   NetBSD problem report 42917 from KAMADA Ken'ichi.
                 - Improve error handling when parsing of URI scheme.
                 - Silence connection warnings to multi-homed hosts in
                   non-verbose mode.
                 - Fix compile warnings.
                 - In ftpvis(), prevent incomplete escape sequences at end of
                   dst, and ensure NUL-termination of dst.
                   Fix from Uwe Stuehler and Stefan Sperling, via Marc Balmer.
                 - When using the response to SYST to decide whether to
                   default to 'binary' be a lot less specific.

         * Replace glob with newer copy from NetBSD that does not suffer
           from DoS exhaustion attacks.
           Fix in NetBSD from Maksymilian Arciemowicz.  See CVE-2011-0418

 Tue Jan 12 06:58:15 UTC 2010    lukem

         * Release as "tnftp 20100108"

         * Rename onoff() argument "bool" to "val".

 Tue Jan  5 09:12:01 UTC 2010    lukem

         * If ARG_MAX isn't defined, use the result from sysconf(_SC_ARG_MAX).
           Fixes build when using newer glibc.

         * Add libnetbsd.la to the LIBADD for libedit.
           Fix provided by Adam Sampson.

 Mon Jan  4 06:28:07 UTC 2010    lukem

         * Distribute various files not shipped by default automake rules,
           to use 'make dist' instead of 'cvs export'.

 Wed Dec 30 00:12:47 UTC 2009    lukem

         * Release as "tnftp 20091122"

 Sun Nov 15 10:14:44 UTC 2009    lukem

         * Merge NetBSD ftp from 20090520 to 20090915.  Change:
                 - Rename internal getline() to get_line() to avoid
                   conflict with libc with former.
                 - Avoid a NULL dereference in an error message.

 Sat Nov 14 09:21:19 UTC 2009    lukem

         * Convert to automake & libtool.

 Sat Jun  6 07:17:38 UTC 2009    lukem

         * Release as "tnftp 20090606"

 Fri May 22 01:11:15 UTC 2009    lukem

         * configure fixes:
           - Add the time.h headers to accheck_includes, for the strptime check.
           - Remove the check for el_init in libedit; we're always replacing
             the library and the presence of strvis() in some versions
             confuses other checks.

 Wed May 20 13:47:43 UTC 2009    lukem

         * Release as "tnftp 20090520"

         * Merge NetBSD ftp from 20070722 to 20090520.  Changes:
             - Only attempt to el_parse() a command unknown by the default
               parser if editing is enabled.
               Fixes pr 38589.
             - Turn off the alarmtimer before resetting the SIGALRM handler
               back to SIG_DFL.
               Fixes pr 35630.
             - Add epsv6 and epsv to disable extended passive mode for ipv6 or
               both ipv4 and ipv6 respectively.  This hack is due to our
               friends a Juniper Networks who break epsv in ipv6.
               Should be fixed in ScreenOS 6.2.X.
             - Improve parsing of chunked transfer chunks per RFC2616:
               - more stringent chunk-size parsing
               - ignore optional trailing ';chunk-ext' stuff, instead of barfing
               - detect EOF before final \r\n.
             - Use the service name to getaddrinfo() (along with the host
               name), so that features such as DNS Service Discovery have a
               better chance of working.
               Display the service name in various status & error messages.
             - Don't getservbyname() the :port component of a URL; RFC 3986
               says it's just an unsigned number, not a service name.
             - Fix numerous WARNS=4 issues (-Wcast-qual -Wsign-compare).
             - Fix -Wshadow issues
             - Update copyrights
             - Remove clause 3 and 4 from TNF licenses
             - Rename HAVE_STRUCT_SOCKADDR_SA_LEN to
               HAVE_STRUCT_SOCKADDR_IN_SIN_LEN to accurately reflect the
               structure member being used.
             - Use AF_INET instead of AF_UNSPEC as the default family if
               !defined(INET6).

         * configure improvements:
           - Style tweaks.
           - Use AC_LANG_PROGRAM() instead of AC_LANG_SOURCE()
           - Add a check for strptime() requiring separators between
             conversions, and use our replacement one if it does.

 Sat Dec 20 15:28:24 UTC 2008    lukem

         * configure improvements:
           - Move IPv6 check from tnftp.h to configure.ac (as per tnftpd).
           - Rework option descriptions.
           - Highlight when tests are for a specific option.
           - Move configuration results to the end of the file.
           - Display $prefix in configure results.

 Fri Aug 15 03:03:36 UTC 2008    lukem

         * Add a "Configuration results" display at the end of configure.
           Cosmetic tweaks.

 Fri Feb 29 09:45:56 UTC 2008    lukem

         * Support @EXEEXT@ for Cygwin (etc).

 Status:

 Vendor Tag:	tnftp
 Release Tags:	tnftp-20141031

 C pkgsrc/net/tnftp/files/ChangeLog
 N pkgsrc/net/tnftp/files/Makefile.am
 C pkgsrc/net/tnftp/files/todo
 U pkgsrc/net/tnftp/files/README
 C pkgsrc/net/tnftp/files/tnftp.h
 C pkgsrc/net/tnftp/files/aclocal.m4
 U pkgsrc/net/tnftp/files/INSTALL
 C pkgsrc/net/tnftp/files/THANKS
 U pkgsrc/net/tnftp/files/NEWS
 N pkgsrc/net/tnftp/files/tnftp_config.h.in
 C pkgsrc/net/tnftp/files/Makefile.in
 C pkgsrc/net/tnftp/files/configure
 C pkgsrc/net/tnftp/files/COPYING
 C pkgsrc/net/tnftp/files/configure.ac
 N pkgsrc/net/tnftp/files/buildaux/lt~obsolete.m4
 N pkgsrc/net/tnftp/files/buildaux/config.guess
 N pkgsrc/net/tnftp/files/buildaux/ltmain.sh
 N pkgsrc/net/tnftp/files/buildaux/install-sh
 N pkgsrc/net/tnftp/files/buildaux/ax_check_openssl.m4
 N pkgsrc/net/tnftp/files/buildaux/ltoptions.m4
 N pkgsrc/net/tnftp/files/buildaux/ltversion.m4
 N pkgsrc/net/tnftp/files/buildaux/ltsugar.m4
 N pkgsrc/net/tnftp/files/buildaux/missing
 N pkgsrc/net/tnftp/files/buildaux/depcomp
 N pkgsrc/net/tnftp/files/buildaux/config.sub
 N pkgsrc/net/tnftp/files/buildaux/libtool.m4
 C pkgsrc/net/tnftp/files/src/progressbar.c
 N pkgsrc/net/tnftp/files/src/Makefile.am
 C pkgsrc/net/tnftp/files/src/extern.h
 C pkgsrc/net/tnftp/files/src/util.c
 C pkgsrc/net/tnftp/files/src/domacro.c
 C pkgsrc/net/tnftp/files/src/ftp.c
 U pkgsrc/net/tnftp/files/src/ruserpass.c
 C pkgsrc/net/tnftp/files/src/version.h
 N pkgsrc/net/tnftp/files/src/ssl.c
 C pkgsrc/net/tnftp/files/src/fetch.c
 C pkgsrc/net/tnftp/files/src/progressbar.h
 N pkgsrc/net/tnftp/files/src/ssl.h
 C pkgsrc/net/tnftp/files/src/Makefile.in
 C pkgsrc/net/tnftp/files/src/cmds.c
 C pkgsrc/net/tnftp/files/src/ftp_var.h
 C pkgsrc/net/tnftp/files/src/ftp.1
 C pkgsrc/net/tnftp/files/src/cmdtab.c
 C pkgsrc/net/tnftp/files/src/complete.c
 C pkgsrc/net/tnftp/files/src/main.c
 U pkgsrc/net/tnftp/files/libnetbsd/getnameinfo.c
 U pkgsrc/net/tnftp/files/libnetbsd/strerror.c
 N pkgsrc/net/tnftp/files/libnetbsd/Makefile.am
 U pkgsrc/net/tnftp/files/libnetbsd/fseeko.c
 U pkgsrc/net/tnftp/files/libnetbsd/inet_ntop.c
 U pkgsrc/net/tnftp/files/libnetbsd/strlcpy.c
 U pkgsrc/net/tnftp/files/libnetbsd/timegm.c
 U pkgsrc/net/tnftp/files/libnetbsd/inet_pton.c
 C pkgsrc/net/tnftp/files/libnetbsd/strvis.c
 U pkgsrc/net/tnftp/files/libnetbsd/strdup.c
 U pkgsrc/net/tnftp/files/libnetbsd/strunvis.c
 U pkgsrc/net/tnftp/files/libnetbsd/snprintf.c
 U pkgsrc/net/tnftp/files/libnetbsd/err.c
 C pkgsrc/net/tnftp/files/libnetbsd/strptime.c
 C pkgsrc/net/tnftp/files/libnetbsd/utimes.c
 U pkgsrc/net/tnftp/files/libnetbsd/getaddrinfo.c
 C pkgsrc/net/tnftp/files/libnetbsd/sl_init.c
 U pkgsrc/net/tnftp/files/libnetbsd/ftpvis.h
 C pkgsrc/net/tnftp/files/libnetbsd/setprogname.c
 C pkgsrc/net/tnftp/files/libnetbsd/glob.c
 C pkgsrc/net/tnftp/files/libnetbsd/dirname.c
 U pkgsrc/net/tnftp/files/libnetbsd/mkstemp.c
 U pkgsrc/net/tnftp/files/libnetbsd/strtoll.c
 C pkgsrc/net/tnftp/files/libnetbsd/ftpglob.h
 U pkgsrc/net/tnftp/files/libnetbsd/strlcat.c
 C pkgsrc/net/tnftp/files/libnetbsd/usleep.c
 C pkgsrc/net/tnftp/files/libnetbsd/Makefile.in
 U pkgsrc/net/tnftp/files/libnetbsd/strsep.c
 C pkgsrc/net/tnftp/files/libnetbsd/fgetln.c
 C pkgsrc/net/tnftp/files/libedit/filecomplete.h
 N pkgsrc/net/tnftp/files/libedit/Makefile.am
 U pkgsrc/net/tnftp/files/libedit/hist.h
 U pkgsrc/net/tnftp/files/libedit/refresh.c
 U pkgsrc/net/tnftp/files/libedit/chared.c
 U pkgsrc/net/tnftp/files/libedit/hist.c
 U pkgsrc/net/tnftp/files/libedit/tokenizer.c
 U pkgsrc/net/tnftp/files/libedit/sys.h
 U pkgsrc/net/tnftp/files/libedit/el.c
 U pkgsrc/net/tnftp/files/libedit/prompt.h
 U pkgsrc/net/tnftp/files/libedit/makelist.in
 U pkgsrc/net/tnftp/files/libedit/search.h
 U pkgsrc/net/tnftp/files/libedit/key.h
 U pkgsrc/net/tnftp/files/libedit/sig.c
 U pkgsrc/net/tnftp/files/libedit/search.c
 U pkgsrc/net/tnftp/files/libedit/term.c
 U pkgsrc/net/tnftp/files/libedit/term.h
 U pkgsrc/net/tnftp/files/libedit/editrc.5
 U pkgsrc/net/tnftp/files/libedit/chared.h
 C pkgsrc/net/tnftp/files/libedit/filecomplete.c
 U pkgsrc/net/tnftp/files/libedit/key.c
 C pkgsrc/net/tnftp/files/libedit/readline.c
 U pkgsrc/net/tnftp/files/libedit/sig.h
 C pkgsrc/net/tnftp/files/libedit/Makefile.in
 U pkgsrc/net/tnftp/files/libedit/parse.c
 U pkgsrc/net/tnftp/files/libedit/common.c
 U pkgsrc/net/tnftp/files/libedit/parse.h
 U pkgsrc/net/tnftp/files/libedit/prompt.c
 U pkgsrc/net/tnftp/files/libedit/emacs.c
 U pkgsrc/net/tnftp/files/libedit/el.h
 U pkgsrc/net/tnftp/files/libedit/history.c
 U pkgsrc/net/tnftp/files/libedit/tty.h
 U pkgsrc/net/tnftp/files/libedit/map.h
 U pkgsrc/net/tnftp/files/libedit/refresh.h
 U pkgsrc/net/tnftp/files/libedit/vi.c
 U pkgsrc/net/tnftp/files/libedit/map.c
 U pkgsrc/net/tnftp/files/libedit/editline.3
 U pkgsrc/net/tnftp/files/libedit/tty.c
 U pkgsrc/net/tnftp/files/libedit/histedit.h
 C pkgsrc/net/tnftp/files/libedit/read.h
 U pkgsrc/net/tnftp/files/libedit/read.c
 C pkgsrc/net/tnftp/files/libedit/readline/readline.h

 41 conflicts created by this import.
 Use the following command to help the merge:

 	cvs checkout -jtnftp:yesterday -jtnftp pkgsrc/net/tnftp/files

>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.