Module Name:    src
Committed By:   martin
Date:           Sun Oct 13 16:06:37 UTC 2024

Modified Files:
        src/distrib/sets/lists/tests [netbsd-10]: mi
        src/etc/mtree [netbsd-10]: NetBSD.dist.tests
        src/tests/usr.bin [netbsd-10]: Makefile
        src/usr.bin/ftp [netbsd-10]: cmds.c complete.c fetch.c ftp.1 ftp.c
            ftp_var.h main.c progressbar.c ruserpass.c ssl.c util.c
Added Files:
        src/tests/usr.bin/ftp [netbsd-10]: Makefile custom_headers.sh
            t_custom_headers.sh

Log Message:
Pull up following revision(s) (requested by riastradh in ticket #970):

        tests/usr.bin/Makefile: revision 1.42
        usr.bin/ftp/ruserpass.c: revision 1.34
        usr.bin/ftp/main.c: revision 1.130
        usr.bin/ftp/ssl.c: revision 1.17
        usr.bin/ftp/main.c: revision 1.131
        usr.bin/ftp/ssl.c: revision 1.18
        usr.bin/ftp/main.c: revision 1.132
        usr.bin/ftp/ssl.c: revision 1.19
        usr.bin/ftp/main.c: revision 1.133
        distrib/sets/lists/tests/mi: revision 1.1342
        usr.bin/ftp/ftp.1: revision 1.151
        usr.bin/ftp/ftp.1: revision 1.152
        usr.bin/ftp/progressbar.c: revision 1.25
        usr.bin/ftp/ftp.1: revision 1.153
        usr.bin/ftp/progressbar.c: revision 1.26
        usr.bin/ftp/ftp.1: revision 1.155
        usr.bin/ftp/ftp.1: revision 1.156
        usr.bin/ftp/fetch.c: revision 1.239
        usr.bin/ftp/ftp.1: revision 1.157
        usr.bin/ftp/ftp.1: revision 1.158
        usr.bin/ftp/ftp.1: revision 1.159
        usr.bin/ftp/ftp_var.h: revision 1.87
        etc/mtree/NetBSD.dist.tests: revision 1.208
        usr.bin/ftp/ftp_var.h: revision 1.88
        usr.bin/ftp/ftp_var.h: revision 1.89
        usr.bin/ftp/cmds.c: revision 1.142
        usr.bin/ftp/util.c: revision 1.168
        usr.bin/ftp/cmds.c: revision 1.143
        tests/usr.bin/ftp/custom_headers.sh: revision 1.1
        usr.bin/ftp/ssl.c: revision 1.20
        usr.bin/ftp/complete.c: revision 1.48
        tests/usr.bin/ftp/Makefile: revision 1.1
        tests/usr.bin/ftp/t_custom_headers.sh: revision 1.1
        usr.bin/ftp/fetch.c: revision 1.240
        usr.bin/ftp/fetch.c: revision 1.241
        usr.bin/ftp/ftp.c: revision 1.176
        usr.bin/ftp/ftp.c: revision 1.177
        (all via patch)

ftp(1): wording and formatting improvements

Fix grammar issue with "Support values" reported in private mail.
Document all file transfer types in "type" and cross-reference that.
Consistency fixes in describing file transfer parameters and types.

Fix some mandoc -Tlint issues (except "useless macro: Tn").

Add -b <buflen> to specify the buffer size.

ftp: bump FTPBUFLEN from 4kB to 16kB
sourceforge.net returns a 5kB content-security-policy.
Analyzed by mlelstv@ who reports usual limits are between 4kB and 48kB.
default is now 16K

ftp: improve -b documentation

Order -b bufsize in the synopsis.

Document the actual default value.

ftp: improve units used in comments and errors
Use "KiB" instead of "K" in errors.
Clarify related comments.

pass some lint.

PR/58581: Sunil Nimmagadda: Add flag to allow specifying extra http header
fields.

ftp(1): Nix trailing whitespace in man page.
No functional change intended.

PR bin/58581: ftp(1) should allow specifying header fields in http requests
fix markup (h -> H), explain about multiple headers, fix usage (from RVP)

Don't forget the dot, use the intended macro name (I think),
and improve the wording a little.    (All related to the -H option.)
ftp(1): Add test for custom HTTP header fields.

Based on a patch from Sunil Nimmagadda.

PR bin/58581: ftp(1) should allow specifying header fields in http
requests


To generate a diff of this commit:
cvs rdiff -u -r1.1238.2.15 -r1.1238.2.16 src/distrib/sets/lists/tests/mi
cvs rdiff -u -r1.197.2.4 -r1.197.2.5 src/etc/mtree/NetBSD.dist.tests
cvs rdiff -u -r1.37.2.1 -r1.37.2.2 src/tests/usr.bin/Makefile
cvs rdiff -u -r0 -r1.1.2.2 src/tests/usr.bin/ftp/Makefile \
    src/tests/usr.bin/ftp/custom_headers.sh \
    src/tests/usr.bin/ftp/t_custom_headers.sh
cvs rdiff -u -r1.141 -r1.141.6.1 src/usr.bin/ftp/cmds.c
cvs rdiff -u -r1.47 -r1.47.10.1 src/usr.bin/ftp/complete.c
cvs rdiff -u -r1.235.2.2 -r1.235.2.3 src/usr.bin/ftp/fetch.c
cvs rdiff -u -r1.147.2.4 -r1.147.2.5 src/usr.bin/ftp/ftp.1
cvs rdiff -u -r1.174.2.1 -r1.174.2.2 src/usr.bin/ftp/ftp.c
cvs rdiff -u -r1.86 -r1.86.2.1 src/usr.bin/ftp/ftp_var.h
cvs rdiff -u -r1.128.2.1 -r1.128.2.2 src/usr.bin/ftp/main.c
cvs rdiff -u -r1.24 -r1.24.6.1 src/usr.bin/ftp/progressbar.c
cvs rdiff -u -r1.33 -r1.33.86.1 src/usr.bin/ftp/ruserpass.c
cvs rdiff -u -r1.12.2.4 -r1.12.2.5 src/usr.bin/ftp/ssl.c
cvs rdiff -u -r1.164.2.2 -r1.164.2.3 src/usr.bin/ftp/util.c

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

Modified files:

Index: src/distrib/sets/lists/tests/mi
diff -u src/distrib/sets/lists/tests/mi:1.1238.2.15 src/distrib/sets/lists/tests/mi:1.1238.2.16
--- src/distrib/sets/lists/tests/mi:1.1238.2.15	Sun Oct 13 15:05:17 2024
+++ src/distrib/sets/lists/tests/mi	Sun Oct 13 16:06:36 2024
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1238.2.15 2024/10/13 15:05:17 martin Exp $
+# $NetBSD: mi,v 1.1238.2.16 2024/10/13 16:06:36 martin Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -4858,6 +4858,11 @@
 ./usr/tests/usr.bin/fstat/Atffile			tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/fstat/Kyuafile			tests-usr.bin-tests	compattestfile,atf,kyua
 ./usr/tests/usr.bin/fstat/t_fstat			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/ftp					tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/ftp/Atffile				tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/ftp/Kyuafile			tests-usr.bin-tests	compattestfile,atf,kyua
+./usr/tests/usr.bin/ftp/custom_headers.sh		tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/ftp/t_custom_headers		tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/gdb					tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/gdb/Atffile				tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/gdb/Kyuafile			tests-usr.bin-tests	compattestfile,atf,kyua

Index: src/etc/mtree/NetBSD.dist.tests
diff -u src/etc/mtree/NetBSD.dist.tests:1.197.2.4 src/etc/mtree/NetBSD.dist.tests:1.197.2.5
--- src/etc/mtree/NetBSD.dist.tests:1.197.2.4	Thu Sep  5 09:22:44 2024
+++ src/etc/mtree/NetBSD.dist.tests	Sun Oct 13 16:06:36 2024
@@ -1,4 +1,4 @@
-#	$NetBSD: NetBSD.dist.tests,v 1.197.2.4 2024/09/05 09:22:44 martin Exp $
+#	$NetBSD: NetBSD.dist.tests,v 1.197.2.5 2024/10/13 16:06:36 martin Exp $
 
 ./usr/libdata/debug/usr/tests
 ./usr/libdata/debug/usr/tests/atf
@@ -446,6 +446,7 @@
 ./usr/tests/usr.bin/dirname
 ./usr/tests/usr.bin/find
 ./usr/tests/usr.bin/fstat
+./usr/tests/usr.bin/ftp
 ./usr/tests/usr.bin/gdb
 ./usr/tests/usr.bin/grep
 ./usr/tests/usr.bin/gzip

Index: src/tests/usr.bin/Makefile
diff -u src/tests/usr.bin/Makefile:1.37.2.1 src/tests/usr.bin/Makefile:1.37.2.2
--- src/tests/usr.bin/Makefile:1.37.2.1	Thu Sep  5 09:22:42 2024
+++ src/tests/usr.bin/Makefile	Sun Oct 13 16:06:35 2024
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.37.2.1 2024/09/05 09:22:42 martin Exp $
+#	$NetBSD: Makefile,v 1.37.2.2 2024/10/13 16:06:35 martin Exp $
 #
 
 .include <bsd.own.mk>
@@ -6,7 +6,7 @@
 TESTSDIR=       ${TESTSBASE}/usr.bin
 
 TESTS_SUBDIRS=	awk basename bzip2 cc cmp compress config cpio col cut \
-		diff dirname find fstat gdb grep gzip id indent \
+		diff dirname find fstat ftp gdb grep gzip id indent \
 		infocmp jot ld locale m4 make mixerctl mkdep nbperf \
 		netpgpverify patch pkill pr printf pwhash realpath rump_server \
 		shmif_dumpbus shmif_pcapin sdiff sed sort tar tmux tr \

Index: src/usr.bin/ftp/cmds.c
diff -u src/usr.bin/ftp/cmds.c:1.141 src/usr.bin/ftp/cmds.c:1.141.6.1
--- src/usr.bin/ftp/cmds.c:1.141	Wed Jan  6 09:15:59 2021
+++ src/usr.bin/ftp/cmds.c	Sun Oct 13 16:06:36 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: cmds.c,v 1.141 2021/01/06 09:15:59 lukem Exp $	*/
+/*	$NetBSD: cmds.c,v 1.141.6.1 2024/10/13 16:06:36 martin Exp $	*/
 
 /*-
  * Copyright (c) 1996-2021 The NetBSD Foundation, Inc.
@@ -96,7 +96,7 @@
 #if 0
 static char sccsid[] = "@(#)cmds.c	8.6 (Berkeley) 10/9/94";
 #else
-__RCSID("$NetBSD: cmds.c,v 1.141 2021/01/06 09:15:59 lukem Exp $");
+__RCSID("$NetBSD: cmds.c,v 1.141.6.1 2024/10/13 16:06:36 martin Exp $");
 #endif
 #endif /* not lint */
 
@@ -172,7 +172,7 @@ confirm(const char *cmd, const char *fil
 		promptleft = cmd;
 		promptright = file;
 	}
-	while (1) {
+	for (;;) {
 		fprintf(ttyout, "%s %s [anpqy?]? ", promptleft, promptright);
 		(void)fflush(ttyout);
 		if (get_line(stdin, cline, sizeof(cline), &errormsg) < 0) {
@@ -1830,10 +1830,10 @@ account(int argc, char *argv[])
 	memset(ap, 0, strlen(ap));
 }
 
-sigjmp_buf abortprox;
+static sigjmp_buf abortprox;
 
 void
-proxabort(int notused)
+proxabort(int notused __unused)
 {
 
 	sigint_raised = 1;
@@ -1855,7 +1855,7 @@ void
 doproxy(int argc, char *argv[])
 {
 	struct cmd *c;
-	int cmdpos;
+	size_t cmdpos;
 	sigfunc oldintr;
 	char cmdbuf[MAX_C_NAME];
 
@@ -2038,7 +2038,7 @@ setnmap(int argc, char *argv[])
 }
 
 static const char *
-domap(char *dst, size_t dlen, const char *src)
+domap(char *dst, size_t dlen __unused, const char *src)
 {
 	const char *cp1 = src;
 	char *cp2 = mapin;
@@ -2483,11 +2483,11 @@ macdef(int argc, char *argv[])
 		}
 		tmp++;
 	}
-	while (1) {
+	for (;;) {
 		while ((c = getchar()) != '\n' && c != EOF)
 			/* LOOP */;
 		if (c == EOF || getchar() == '\n') {
-			fputs("Macro not defined - 4K buffer exceeded.\n",
+			fputs("Macro not defined - 4 KiB buffer exceeded.\n",
 			    ttyout);
 			code = -1;
 			return;
@@ -2605,7 +2605,8 @@ lpage(int argc, char *argv[])
 void
 page(int argc, char *argv[])
 {
-	int ohash, orestart_point, overbose;
+	int ohash, overbose;
+	off_t orestart_point;
 	size_t len;
 	const char *p;
 	char *pager;
@@ -2627,7 +2628,8 @@ page(int argc, char *argv[])
 	ohash = hash;
 	orestart_point = restart_point;
 	overbose = verbose;
-	hash = restart_point = verbose = 0;
+	hash = verbose = 0;
+	restart_point = 0;
 	recvrequest("RETR", pager, argv[1], "r+", 1, 0);
 	hash = ohash;
 	restart_point = orestart_point;

Index: src/usr.bin/ftp/complete.c
diff -u src/usr.bin/ftp/complete.c:1.47 src/usr.bin/ftp/complete.c:1.47.10.1
--- src/usr.bin/ftp/complete.c:1.47	Mon Jan 28 12:04:16 2019
+++ src/usr.bin/ftp/complete.c	Sun Oct 13 16:06:36 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: complete.c,v 1.47 2019/01/28 12:04:16 christos Exp $	*/
+/*	$NetBSD: complete.c,v 1.47.10.1 2024/10/13 16:06:36 martin Exp $	*/
 
 /*-
  * Copyright (c) 1997-2009 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: complete.c,v 1.47 2019/01/28 12:04:16 christos Exp $");
+__RCSID("$NetBSD: complete.c,v 1.47.10.1 2024/10/13 16:06:36 martin Exp $");
 #endif /* not lint */
 
 /*
@@ -349,7 +349,7 @@ complete_remote(char *word, int list)
  * Generic complete routine
  */
 unsigned char
-complete(EditLine *cel, int ch)
+complete(EditLine *cel, int ch __unused)
 {
 	static char word[FTPBUFLEN];
 	static size_t lastc_argc, lastc_argo;

Index: src/usr.bin/ftp/fetch.c
diff -u src/usr.bin/ftp/fetch.c:1.235.2.2 src/usr.bin/ftp/fetch.c:1.235.2.3
--- src/usr.bin/ftp/fetch.c:1.235.2.2	Mon Jan 15 16:12:08 2024
+++ src/usr.bin/ftp/fetch.c	Sun Oct 13 16:06:36 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: fetch.c,v 1.235.2.2 2024/01/15 16:12:08 martin Exp $	*/
+/*	$NetBSD: fetch.c,v 1.235.2.3 2024/10/13 16:06:36 martin Exp $	*/
 
 /*-
  * Copyright (c) 1997-2015 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: fetch.c,v 1.235.2.2 2024/01/15 16:12:08 martin Exp $");
+__RCSID("$NetBSD: fetch.c,v 1.235.2.3 2024/10/13 16:06:36 martin Exp $");
 #endif /* not lint */
 
 /*
@@ -261,8 +261,8 @@ freeurlinfo(struct urlinfo *ui)
 static int
 auth_url(const char *challenge, char **response, const struct authinfo *auth)
 {
-	const char	*cp, *scheme, *errormsg;
-	char		*ep, *clear, *realm;
+	const char	*cp, *ep, *scheme, *errormsg;
+	char		*clear, *realm;
 	char		 uuser[BUFSIZ], *gotpass;
 	const char	*upass;
 	int		 rval;
@@ -590,7 +590,7 @@ parse_url(const char *url, const char *d
 			    cp, desc, origurl);
 			goto cleanup_parse_url;
 		}
-		ui->portnum = nport;
+		ui->portnum = (in_port_t)nport;
 		tport = cp;
 	} else
 		tport = get_port(ui);
@@ -614,7 +614,7 @@ parse_url(const char *url, const char *d
 	return (0);
 }
 
-sigjmp_buf	httpabort;
+static sigjmp_buf	httpabort;
 
 static int
 ftp_socket(const struct urlinfo *ui, void **ssl, struct authinfo *auth)
@@ -865,6 +865,7 @@ print_get(FETCH *fin, int hasleading, in
     const struct urlinfo *ui)
 {
 	const char *leading = hasleading ? ", " : "  (";
+	struct entry *np;
 
 	if (isproxy) {
 		if (verbose) {
@@ -882,6 +883,10 @@ print_get(FETCH *fin, int hasleading, in
 	print_host(fin, ui);
 	fetch_printf(fin, "Accept: */*\r\n");
 	fetch_printf(fin, "Connection: close\r\n");
+	SLIST_FOREACH(np, &custom_headers, entries) {
+		fetch_printf(fin, "%s\r\n", np->header);
+	}
+
 	if (restart_point) {
 		fputs(leading, ttyout);
 		fetch_printf(fin, "Range: bytes=" LLF "-\r\n",
@@ -1116,15 +1121,17 @@ negotiate_connection(FETCH *fin, const c
     char **auth, struct urlinfo *ui)
 {
 	int			len, hcode, rv;
-	char			buf[FTPBUFLEN], *ep;
+	char			*buf = NULL, *ep;
 	const char		*cp, *token;
 	char			*location, *message;
 
 	*auth = message = location = NULL;
 
+	buf = ftp_malloc(ftp_buflen);
+
 	/* Read the response */
 	ep = buf;
-	switch (getresponse(fin, &ep, sizeof(buf), &hcode)) {
+	switch (getresponse(fin, &ep, ftp_buflen, &hcode)) {
 	case C_CLEANUP:
 		goto cleanup_fetch_url;
 	case C_IMPROPER:
@@ -1137,7 +1144,7 @@ negotiate_connection(FETCH *fin, const c
 	/* Read the rest of the header. */
 
 	for (;;) {
-		if ((rv = getresponseline(fin, buf, sizeof(buf), &len)) != C_OK)
+		if ((rv = getresponseline(fin, buf, ftp_buflen, &len)) != C_OK)
 			goto cleanup_fetch_url;
 		if (len == 0)
 			break;
@@ -1265,6 +1272,7 @@ improper:
 	rv = C_IMPROPER;
 	goto out;
 out:
+	FREEPTR(buf);
 	FREEPTR(message);
 	FREEPTR(location);
 	return rv;
@@ -1279,7 +1287,7 @@ connectmethod(FETCH *fin, const char *ur
 	void *ssl;
 	int hcode, rv;
 	const char *cp;
-	char buf[FTPBUFLEN], *ep;
+	char *buf = NULL, *ep;
 	char *message = NULL;
 
 	print_connect(fin, oui);
@@ -1299,9 +1307,11 @@ connectmethod(FETCH *fin, const char *ur
 	}
 	alarmtimer(0);
 
+	buf = ftp_malloc(ftp_buflen);
+
 	/* Read the response */
 	ep = buf;
-	switch (getresponse(fin, &ep, sizeof(buf), &hcode)) {
+	switch (getresponse(fin, &ep, ftp_buflen, &hcode)) {
 	case C_CLEANUP:
 		goto cleanup_fetch_url;
 	case C_IMPROPER:
@@ -1313,7 +1323,7 @@ connectmethod(FETCH *fin, const char *ur
 
 	for (;;) {
 		int len;
-		if (getresponseline(fin, buf, sizeof(buf), &len) != C_OK)
+		if (getresponseline(fin, buf, ftp_buflen, &len) != C_OK)
 			goto cleanup_fetch_url;
 		if (len == 0)
 			break;
@@ -1364,6 +1374,7 @@ cleanup_fetch_url:
 	rv = C_CLEANUP;
 	goto out;
 out:
+	FREEPTR(buf);
 	FREEPTR(message);
 	return rv;
 }
@@ -1710,7 +1721,7 @@ fetch_url(const char *url, const char *p
 		lastchunk = 0;
 					/* read chunk-size */
 		if (ischunked) {
-			if (fetch_getln(xferbuf, bufsize, fin) == NULL) {
+			if (fetch_getln(xferbuf, (int)bufsize, fin) == NULL) {
 				warnx("Unexpected EOF reading chunk-size");
 				goto cleanup_fetch_url;
 			}
@@ -1753,7 +1764,7 @@ fetch_url(const char *url, const char *p
 			}
 		}
 					/* transfer file or chunk */
-		while (1) {
+		for (;;) {
 			struct timeval then, now, td;
 			volatile off_t bufrem;
 
@@ -1792,7 +1803,7 @@ fetch_url(const char *url, const char *p
 				}
 			}
 			if (rate_get) {
-				while (1) {
+				for (;;) {
 					(void)gettimeofday(&now, NULL);
 					timersub(&now, &then, &td);
 					if (td.tv_sec > 0)
@@ -1806,7 +1817,7 @@ fetch_url(const char *url, const char *p
 					/* read CRLF after chunk*/
  chunkdone:
 		if (ischunked) {
-			if (fetch_getln(xferbuf, bufsize, fin) == NULL) {
+			if (fetch_getln(xferbuf, (int)bufsize, fin) == NULL) {
 				alarmtimer(0);
 				warnx("Unexpected EOF reading chunk CRLF");
 				goto cleanup_fetch_url;
@@ -1890,7 +1901,7 @@ chunkerror:
  * Abort a HTTP retrieval
  */
 static void
-aborthttp(int notused)
+aborthttp(int notused __unused)
 {
 	char msgbuf[100];
 	int len;
@@ -1907,7 +1918,7 @@ aborthttp(int notused)
 }
 
 static void
-timeouthttp(int notused)
+timeouthttp(int notused __unused)
 {
 	char msgbuf[100];
 	int len;
@@ -2269,7 +2280,7 @@ static int
 go_fetch(const char *url, struct urlinfo *rui)
 {
 	char *proxyenv;
-	char *p;
+	const char *p;
 
 #ifndef NO_ABOUT
 	/*

Index: src/usr.bin/ftp/ftp.1
diff -u src/usr.bin/ftp/ftp.1:1.147.2.4 src/usr.bin/ftp/ftp.1:1.147.2.5
--- src/usr.bin/ftp/ftp.1:1.147.2.4	Thu Jun 20 18:04:49 2024
+++ src/usr.bin/ftp/ftp.1	Sun Oct 13 16:06:36 2024
@@ -1,6 +1,6 @@
-.\" 	$NetBSD: ftp.1,v 1.147.2.4 2024/06/20 18:04:49 martin Exp $
+.\" 	$NetBSD: ftp.1,v 1.147.2.5 2024/10/13 16:06:36 martin Exp $
 .\"
-.\" Copyright (c) 1996-2023 The NetBSD Foundation, Inc.
+.\" Copyright (c) 1996-2024 The NetBSD Foundation, Inc.
 .\" All rights reserved.
 .\"
 .\" This code is derived from software contributed to The NetBSD Foundation
@@ -57,7 +57,7 @@
 .\"
 .\"	@(#)ftp.1	8.3 (Berkeley) 10/9/94
 .\"
-.Dd April 17, 2024
+.Dd September 30, 2024
 .Dt FTP 1
 .Os
 .Sh NAME
@@ -66,6 +66,8 @@
 .Sh SYNOPSIS
 .Nm
 .Op Fl 46AadefginpRtVv?
+.Op Fl b Ar bufsize
+.Op Fl H Ar header
 .Op Fl N Ar netrc
 .Op Fl o Ar output
 .Op Fl P Ar port
@@ -201,6 +203,14 @@ implement passive mode properly.
 Causes
 .Nm
 to bypass normal login procedure, and use an anonymous login instead.
+.It Fl b Ar bufsize
+Change the input buffer size to
+.Ar bufsize .
+The default
+.Ar bufsize
+is
+.Dv 16384
+(16 KiB).
 .It Fl d
 Enables debugging.
 .It Fl e
@@ -214,6 +224,17 @@ or
 proxies.
 .It Fl g
 Disables file name globbing.
+.It Fl H Ar header
+Include the provided
+.Ar header
+string as a custom
+.Tn HTTP
+header for an
+.Tn HTTP
+request.
+The
+.Fl H
+option can be repeated to add additional headers.
 .It Fl i
 Turns off interactive prompting during
 multiple file transfers.

Index: src/usr.bin/ftp/ftp.c
diff -u src/usr.bin/ftp/ftp.c:1.174.2.1 src/usr.bin/ftp/ftp.c:1.174.2.2
--- src/usr.bin/ftp/ftp.c:1.174.2.1	Tue May 16 16:26:03 2023
+++ src/usr.bin/ftp/ftp.c	Sun Oct 13 16:06:36 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: ftp.c,v 1.174.2.1 2023/05/16 16:26:03 martin Exp $	*/
+/*	$NetBSD: ftp.c,v 1.174.2.2 2024/10/13 16:06:36 martin Exp $	*/
 
 /*-
  * Copyright (c) 1996-2021 The NetBSD Foundation, Inc.
@@ -92,7 +92,7 @@
 #if 0
 static char sccsid[] = "@(#)ftp.c	8.6 (Berkeley) 10/27/94";
 #else
-__RCSID("$NetBSD: ftp.c,v 1.174.2.1 2023/05/16 16:26:03 martin Exp $");
+__RCSID("$NetBSD: ftp.c,v 1.174.2.2 2024/10/13 16:06:36 martin Exp $");
 #endif
 #endif /* not lint */
 
@@ -123,13 +123,14 @@ __RCSID("$NetBSD: ftp.c,v 1.174.2.1 2023
 
 #include "ftp_var.h"
 
-volatile sig_atomic_t	abrtflag;
-volatile sig_atomic_t	timeoutflag;
+static volatile sig_atomic_t	abrtflag;
+static volatile sig_atomic_t	timeoutflag;
 
-sigjmp_buf	ptabort;
-int	ptabflg;
-int	ptflag = 0;
-char	pasv[BUFSIZ];	/* passive port for proxy data connection */
+static sigjmp_buf	ptabort;
+static int	ptabflg;
+static int	ptflag = 0;
+static char	pasv[BUFSIZ];	/* passive port for proxy data connection */
+size_t	ftp_buflen = FTPBUFLEN;
 
 static int empty(FILE *, FILE *, int);
 __dead static void abort_squared(int);
@@ -154,7 +155,7 @@ struct sockinet {
 #define su_family	si_su.su_sin.sin_family
 #define su_port		si_su.su_sin.sin_port
 
-struct sockinet myctladdr, hisctladdr, data_addr;
+static struct sockinet myctladdr, hisctladdr, data_addr;
 
 char *
 hookup(const char *host, const char *port)
@@ -240,7 +241,7 @@ hookup(const char *host, const char *por
 	res0 = res = NULL;
 
 	len = hisctladdr.su_len;
-	if (getsockname(s, (struct sockaddr *)&myctladdr.si_su, &len) == -1) {
+	if (getsockname(s, (struct sockaddr *)(void *)&myctladdr.si_su, &len) == -1) {
 		warn("Can't determine my address of connection to `%s:%s'",
 		    host, port);
 		code = -1;
@@ -297,7 +298,7 @@ hookup(const char *host, const char *por
 }
 
 void
-cmdabort(int notused)
+cmdabort(int notused __unused)
 {
 	int oerrno = errno;
 
@@ -312,7 +313,7 @@ cmdabort(int notused)
 }
 
 void
-cmdtimeout(int notused)
+cmdtimeout(int notused __unused)
 {
 	int oerrno = errno;
 
@@ -568,10 +569,10 @@ empty(FILE *ecin, FILE *din, int sec)
 	return nr;
 }
 
-sigjmp_buf	xferabort;
+static sigjmp_buf	xferabort;
 
 __dead static void
-abortxfer(int notused)
+abortxfer(int notused __unused)
 {
 	char msgbuf[100];
 	size_t len;
@@ -622,7 +623,7 @@ copy_bytes(int infd, int outfd, char *bu
 	else
 		bufchunk = bufsize;
 
-	while (1) {
+	for (;;) {
 		if (rate_limit) {
 			(void)gettimeofday(&tvthen, NULL);
 		}
@@ -663,7 +664,7 @@ copy_bytes(int infd, int outfd, char *bu
 			}
 		}
 		if (rate_limit) {	/* rate limited; wait if necessary */
-			while (1) {
+			for (;;) {
 				(void)gettimeofday(&tvnow, NULL);
 				timersub(&tvnow, &tvthen, &tvdiff);
 				if (tvdiff.tv_sec > 0)
@@ -775,7 +776,7 @@ sendrequest(const char *cmd, const char 
 
 	if (restart_point &&
 	    (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) {
-		int rc;
+		off_t rc;
 
 		rc = -1;
 		switch (curtype) {
@@ -1517,7 +1518,7 @@ initconn(void)
 		} else
 			goto bad;
 
-		if (ftp_connect(data, (struct sockaddr *)&data_addr.si_su,
+		if (ftp_connect(data, (struct sockaddr *)(void *)&data_addr.si_su,
 		    data_addr.su_len, 1) < 0) {
 			if (activefallback) {
 				(void)close(data);
@@ -1562,7 +1563,7 @@ initconn(void)
 			warn("Can't set SO_REUSEADDR on data connection");
 			goto bad;
 		}
-	if (bind(data, (struct sockaddr *)&data_addr.si_su,
+	if (bind(data, (struct sockaddr *)(void *)&data_addr.si_su,
 	    data_addr.su_len) < 0) {
 		warn("Can't bind for data connection");
 		goto bad;
@@ -1574,7 +1575,7 @@ initconn(void)
 	}
 	len = sizeof(data_addr.si_su);
 	memset((char *)&data_addr, 0, sizeof (data_addr));
-	if (getsockname(data, (struct sockaddr *)&data_addr.si_su, &len) == -1) {
+	if (getsockname(data, (struct sockaddr *)(void *)&data_addr.si_su, &len) == -1) {
 		warn("Can't determine my address of data connection");
 		goto bad;
 	}
@@ -1606,7 +1607,7 @@ initconn(void)
 			if (tmp.su_family == AF_INET6)
 				tmp.si_su.su_sin6.sin6_scope_id = 0;
 #endif
-			if (getnameinfo((struct sockaddr *)&tmp.si_su,
+			if (getnameinfo((struct sockaddr *)(void *)&tmp.si_su,
 			    tmp.su_len, hname, sizeof(hname), sname,
 			    sizeof(sname), NI_NUMERICHOST | NI_NUMERICSERV)) {
 				result = ERROR;
@@ -1729,7 +1730,7 @@ dataconn(const char *lmode)
 	do {
 		(void)gettimeofday(&now, NULL);
 		timersub(&endtime, &now, &td);
-		timeout = td.tv_sec * 1000 + td.tv_usec/1000;
+		timeout = (int)(td.tv_sec * 1000 + td.tv_usec / 1000);
 		if (timeout < 0)
 			timeout = 0;
 		rv = ftp_poll(pfd, 1, timeout);
@@ -1747,7 +1748,7 @@ dataconn(const char *lmode)
 				/* (non-blocking) accept the connection */
 	fromlen = myctladdr.su_len;
 	do {
-		s = accept(data, (struct sockaddr *) &from.si_su, &fromlen);
+		s = accept(data, (struct sockaddr *)(void *)&from.si_su, &fromlen);
 			/* loop until accept !EINTR && !EAGAIN */
 	} while (s == -1 && (errno == EINTR || errno == EAGAIN));
 	if (s == -1) {
@@ -1778,7 +1779,7 @@ dataconn(const char *lmode)
 }
 
 void
-psabort(int notused)
+psabort(int notused __unused)
 {
 	int oerrno = errno;
 
@@ -1876,7 +1877,7 @@ pswitch(int flag)
 }
 
 __dead static void
-abortpt(int notused)
+abortpt(int notused __unused)
 {
 
 	sigint_raised = 1;
@@ -2040,7 +2041,8 @@ gunique(const char *local)
 {
 	static char new[MAXPATHLEN];
 	char *cp = strrchr(local, '/');
-	int d, count=0, len;
+	int d, count = 0;
+	size_t len;
 	char ext = '1';
 
 	if (cp)
@@ -2175,7 +2177,7 @@ ai_unmapped(struct addrinfo *ai)
 	if (ai->ai_addrlen != sizeof(struct sockaddr_in6) ||
 	    sizeof(sin) > ai->ai_addrlen)
 		return;
-	sin6 = (struct sockaddr_in6 *)ai->ai_addr;
+	sin6 = (struct sockaddr_in6 *)(void *)ai->ai_addr;
 	if (!IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
 		return;
 

Index: src/usr.bin/ftp/ftp_var.h
diff -u src/usr.bin/ftp/ftp_var.h:1.86 src/usr.bin/ftp/ftp_var.h:1.86.2.1
--- src/usr.bin/ftp/ftp_var.h:1.86	Fri Sep 10 21:52:17 2021
+++ src/usr.bin/ftp/ftp_var.h	Sun Oct 13 16:06:36 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: ftp_var.h,v 1.86 2021/09/10 21:52:17 rillig Exp $	*/
+/*	$NetBSD: ftp_var.h,v 1.86.2.1 2024/10/13 16:06:36 martin Exp $	*/
 
 /*-
  * Copyright (c) 1996-2009 The NetBSD Foundation, Inc.
@@ -101,6 +101,7 @@
 #endif
 
 #include <sys/param.h>
+#include <sys/queue.h>
 
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -165,11 +166,19 @@ enum {
 	FEAT_max
 };
 
+/*
+ * Custom HTTP headers
+ */
+struct entry {
+	SLIST_ENTRY(entry)	entries;
+	const char		*header;
+};
+SLIST_HEAD(http_headers, entry);
 
 /*
  * Global defines
  */
-#define	FTPBUFLEN	(4 * MAXPATHLEN)
+#define	FTPBUFLEN	(16 * 1024)
 #define	MAX_IN_PORT_T	0xffffU
 
 #define	HASHBYTES	1024	/* default mark for `hash' command */
@@ -320,9 +329,11 @@ GLOBAL	FILE	*cin;
 GLOBAL	FILE	*cout;
 GLOBAL	int	 data;
 
-extern	struct cmd	cmdtab[];
-extern	struct option	optiontab[];
+extern	struct cmd		cmdtab[];
+extern	struct option		optiontab[];
+extern	struct http_headers	custom_headers;
 
+extern	size_t ftp_buflen;
 
 #define	EMPTYSTRING(x)	((x) == NULL || (*(x) == '\0'))
 #define	FREEPTR(x)	if ((x) != NULL) { free(x); (x) = NULL; }

Index: src/usr.bin/ftp/main.c
diff -u src/usr.bin/ftp/main.c:1.128.2.1 src/usr.bin/ftp/main.c:1.128.2.2
--- src/usr.bin/ftp/main.c:1.128.2.1	Tue May 16 16:16:00 2023
+++ src/usr.bin/ftp/main.c	Sun Oct 13 16:06:36 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: main.c,v 1.128.2.1 2023/05/16 16:16:00 martin Exp $	*/
+/*	$NetBSD: main.c,v 1.128.2.2 2024/10/13 16:06:36 martin Exp $	*/
 
 /*-
  * Copyright (c) 1996-2023 The NetBSD Foundation, Inc.
@@ -98,7 +98,7 @@ __COPYRIGHT("@(#) Copyright (c) 1985, 19
 #if 0
 static char sccsid[] = "@(#)main.c	8.6 (Berkeley) 10/9/94";
 #else
-__RCSID("$NetBSD: main.c,v 1.128.2.1 2023/05/16 16:16:00 martin Exp $");
+__RCSID("$NetBSD: main.c,v 1.128.2.2 2024/10/13 16:06:36 martin Exp $");
 #endif
 #endif /* not lint */
 
@@ -134,11 +134,14 @@ static int	usage(void);
 static int	usage_help(void);
 static void	setupoption(const char *, const char *, const char *);
 
+struct http_headers custom_headers;
+
 int
 main(int volatile argc, char **volatile argv)
 {
 	int ch, rval;
 	struct passwd *pw;
+	struct entry *p;
 	char *cp, *ep, *anonpass, *upload_path, *src_addr;
 	const char *anonuser;
 	int dumbterm, isupload;
@@ -267,7 +270,8 @@ main(int volatile argc, char **volatile 
 		}
 	}
 
-	while ((ch = getopt(argc, argv, ":46AadefginN:o:pP:q:r:Rs:tT:u:vVx:")) != -1) {
+	SLIST_INIT(&custom_headers);
+	while ((ch = getopt(argc, argv, ":46Aab:defgH:inN:o:pP:q:r:Rs:tT:u:vVx:")) != -1) {
 		switch (ch) {
 		case '4':
 			family = AF_INET;
@@ -290,6 +294,12 @@ main(int volatile argc, char **volatile 
 			anonftp = 1;
 			break;
 
+		case 'b':
+			ftp_buflen = strtol(optarg, &ep, 0);
+			if (ftp_buflen < 1 || *ep != '\0')
+				errx(1, "Bad buflen value: %s", optarg);
+			break;
+
 		case 'd':
 			options |= SO_DEBUG;
 			ftp_debug++;
@@ -309,6 +319,12 @@ main(int volatile argc, char **volatile 
 			doglob = 0;
 			break;
 
+		case 'H':
+			p = ftp_malloc(sizeof(*p));
+			p->header = ftp_strdup(optarg);
+			SLIST_INSERT_HEAD(&custom_headers, p, entries);
+			break;
+
 		case 'i':
 			interactive = 0;
 			break;
@@ -340,13 +356,13 @@ main(int volatile argc, char **volatile 
 			break;
 
 		case 'q':
-			quit_time = strtol(optarg, &ep, 10);
+			quit_time = (int)strtol(optarg, &ep, 10);
 			if (quit_time < 1 || *ep != '\0')
 				errx(1, "Bad quit value: %s", optarg);
 			break;
 
 		case 'r':
-			retry_connect = strtol(optarg, &ep, 10);
+			retry_connect = (int)strtol(optarg, &ep, 10);
 			if (retry_connect < 1 || *ep != '\0')
 				errx(1, "Bad retry value: %s", optarg);
 			break;
@@ -759,7 +775,8 @@ getcmd(const char *name)
 {
 	const char *p, *q;
 	struct cmd *c, *found;
-	int nmatches, longest;
+	int nmatches;
+	ptrdiff_t longest;
 
 	if (name == NULL)
 		return (0);
@@ -789,7 +806,7 @@ getcmd(const char *name)
  * Slice a string up into argc/argv.
  */
 
-int slrflag;
+static int slrflag;
 
 void
 makeargv(void)
@@ -1063,8 +1080,9 @@ synopsis(FILE * stream)
 	const char * progname = getprogname();
 
 	fprintf(stream,
-"usage: %s [-46AadefginpRtVv] [-N NETRC] [-o OUTPUT] [-P PORT] [-q QUITTIME]\n"
-"           [-r RETRY] [-s SRCADDR] [-T DIR,MAX[,INC]] [-x XFERSIZE]\n"
+"usage: %s [-46AadefginpRtVv] [-H HEADER] [-N NETRC] [-o OUTPUT] [-P PORT]\n"
+"           [-q QUITTIME] [-r RETRY] [-s SRCADDR] [-T DIR,MAX[,INC]]\n"
+"	    [-x XFERSIZE]\n"
 "           [[USER@]HOST [PORT]]\n"
 "           [[USER@]HOST:[PATH][/]]\n"
 "           [file:///PATH]\n"
@@ -1089,6 +1107,7 @@ usage_help(void)
 "  -6            Only use IPv6 addresses\n"
 "  -A            Force active mode\n"
 "  -a            Use anonymous login\n"
+"  -b BUFLEN     Use BUFLEN bytes for fetch buffer\n"
 "  -d            Enable debugging\n"
 "  -e            Disable command-line editing\n"
 "  -f            Force cache reload for FTP or HTTP proxy transfers\n"

Index: src/usr.bin/ftp/progressbar.c
diff -u src/usr.bin/ftp/progressbar.c:1.24 src/usr.bin/ftp/progressbar.c:1.24.6.1
--- src/usr.bin/ftp/progressbar.c:1.24	Wed Jan  6 04:43:14 2021
+++ src/usr.bin/ftp/progressbar.c	Sun Oct 13 16:06:36 2024
@@ -1,7 +1,7 @@
-/*	$NetBSD: progressbar.c,v 1.24 2021/01/06 04:43:14 lukem Exp $	*/
+/*	$NetBSD: progressbar.c,v 1.24.6.1 2024/10/13 16:06:36 martin Exp $	*/
 
 /*-
- * Copyright (c) 1997-2021 The NetBSD Foundation, Inc.
+ * Copyright (c) 1997-2024 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: progressbar.c,v 1.24 2021/01/06 04:43:14 lukem Exp $");
+__RCSID("$NetBSD: progressbar.c,v 1.24.6.1 2024/10/13 16:06:36 martin Exp $");
 #endif /* not lint */
 
 /*
@@ -76,7 +76,7 @@ static void updateprogressmeter(int);
  * SIGALRM handler to update the progress meter
  */
 static void
-updateprogressmeter(int dummy)
+updateprogressmeter(int dummy __unused)
 {
 	int oerrno = errno;
 
@@ -89,17 +89,17 @@ updateprogressmeter(int dummy)
  */
 #if !defined(NO_PROGRESS) || !defined(STANDALONE_PROGRESS)
 static const char * const suffixes[] = {
-	"",	/* 2^0  (byte) */
-	"KiB",	/* 2^10 Kibibyte */
-	"MiB",	/* 2^20 Mebibyte */
-	"GiB",	/* 2^30 Gibibyte */
-	"TiB",	/* 2^40 Tebibyte */
-	"PiB",	/* 2^50 Pebibyte */
-	"EiB",	/* 2^60 Exbibyte */
+	"",	/* 2^0, (byte) */
+	"KiB",	/* 2^10, Kibibyte */
+	"MiB",	/* 2^20, Mebibyte */
+	"GiB",	/* 2^30, Gibibyte */
+	"TiB",	/* 2^40, Tebibyte */
+	"PiB",	/* 2^50, Pebibyte */
+	"EiB",	/* 2^60, Exbibyte */
 #if 0
 		/* The following are not necessary for signed 64-bit off_t */
-	"ZiB",	/* 2^70 Zebibyte */
-	"YiB",	/* 2^80 Yobibyte */
+	"ZiB",	/* 2^70, Zebibyte */
+	"YiB",	/* 2^80, Yobibyte */
 #endif
 };
 #define NSUFFIXES	(int)(sizeof(suffixes) / sizeof(suffixes[0]))
@@ -376,7 +376,7 @@ ptransfer(int siginfo)
  * SIG{INFO,QUIT} handler to print transfer stats if a transfer is in progress
  */
 void
-psummary(int notused)
+psummary(int notused __unused)
 {
 	int oerrno = errno;
 

Index: src/usr.bin/ftp/ruserpass.c
diff -u src/usr.bin/ftp/ruserpass.c:1.33 src/usr.bin/ftp/ruserpass.c:1.33.86.1
--- src/usr.bin/ftp/ruserpass.c:1.33	Tue Apr 17 05:52:04 2007
+++ src/usr.bin/ftp/ruserpass.c	Sun Oct 13 16:06:36 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: ruserpass.c,v 1.33 2007/04/17 05:52:04 lukem Exp $	*/
+/*	$NetBSD: ruserpass.c,v 1.33.86.1 2024/10/13 16:06:36 martin Exp $	*/
 
 /*
  * Copyright (c) 1985, 1993, 1994
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "@(#)ruserpass.c	8.4 (Berkeley) 4/27/95";
 #else
-__RCSID("$NetBSD: ruserpass.c,v 1.33 2007/04/17 05:52:04 lukem Exp $");
+__RCSID("$NetBSD: ruserpass.c,v 1.33.86.1 2024/10/13 16:06:36 martin Exp $");
 #endif
 #endif /* not lint */
 
@@ -247,7 +247,7 @@ ruserpass(const char *host, char **aname
 				tmp++;
 			}
 			if (tmp == macbuf + 4096) {
-				fputs("4K macro buffer exceeded.\n",
+				fputs("4 KiB macro buffer exceeded.\n",
 				    ttyout);
 				goto bad;
 			}

Index: src/usr.bin/ftp/ssl.c
diff -u src/usr.bin/ftp/ssl.c:1.12.2.4 src/usr.bin/ftp/ssl.c:1.12.2.5
--- src/usr.bin/ftp/ssl.c:1.12.2.4	Mon Aug 26 07:28:17 2024
+++ src/usr.bin/ftp/ssl.c	Sun Oct 13 16:06:36 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: ssl.c,v 1.12.2.4 2024/08/26 07:28:17 martin Exp $	*/
+/*	$NetBSD: ssl.c,v 1.12.2.5 2024/10/13 16:06:36 martin Exp $	*/
 
 /*-
  * Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
@@ -35,7 +35,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: ssl.c,v 1.12.2.4 2024/08/26 07:28:17 martin Exp $");
+__RCSID("$NetBSD: ssl.c,v 1.12.2.5 2024/10/13 16:06:36 martin Exp $");
 #endif
 
 #include <err.h>
@@ -113,7 +113,8 @@ fetch_writev(struct fetch_connect *conn,
 			do {
 				(void)gettimeofday(&now, NULL);
 				timersub(&timeout, &now, &delta);
-				timeout_secs = delta.tv_sec * 1000 + delta.tv_usec/1000;
+				timeout_secs = (int)(delta.tv_sec * 1000
+				    + delta.tv_usec / 1000);
 				if (timeout_secs < 0)
 					timeout_secs = 0;
 				rv = ftp_poll(pfd, 1, timeout_secs);
@@ -129,7 +130,7 @@ fetch_writev(struct fetch_connect *conn,
 		errno = 0;
 #ifdef WITH_SSL
 		if (conn->ssl != NULL)
-			len = SSL_write(conn->ssl, iov->iov_base, iov->iov_len);
+			len = SSL_write(conn->ssl, iov->iov_base, (int)iov->iov_len);
 		else
 #endif
 			len = writev(fd, iov, iovcnt);
@@ -177,7 +178,7 @@ fetch_printf(struct fetch_connect *conn,
 	va_list ap;
 	size_t len;
 	char *msg;
-	int r;
+	ssize_t r;
 
 	va_start(ap, fmt);
 	len = vasprintf(&msg, fmt, ap);
@@ -190,7 +191,7 @@ fetch_printf(struct fetch_connect *conn,
 
 	r = fetch_write(msg, len, conn);
 	free(msg);
-	return r;
+	return (int)r;
 }
 
 int
@@ -301,8 +302,8 @@ fetch_close(struct fetch_connect *conn)
 static ssize_t
 fetch_ssl_read(SSL *ssl, void *buf, size_t len)
 {
-	ssize_t rlen;
-	rlen = SSL_read(ssl, buf, len);
+	int rlen;
+	rlen = SSL_read(ssl, buf, (int)len);
 	if (rlen >= 0)
 		return rlen;
 
@@ -376,7 +377,8 @@ fetch_wait(struct fetch_connect *conn, s
 		if (quit_time > 0) {
 			gettimeofday(&now, NULL);
 			timersub(timeout, &now, &delta);
-			timeout_secs = delta.tv_sec * 1000 + delta.tv_usec/1000;
+			timeout_secs = (int)(delta.tv_sec * 1000
+			    + delta.tv_usec / 1000);
 			if (timeout_secs < 0)
 				timeout_secs = 0;
 		} else {
@@ -555,7 +557,7 @@ fetch_getline(struct fetch_connect *conn
 	size_t len;
 	int rv;
 
-	if (fetch_getln(buf, buflen, conn) == NULL) {
+	if (fetch_getln(buf, (int)buflen, conn) == NULL) {
 		if (conn->iseof) {	/* EOF */
 			rv = -2;
 			if (errormsg)
@@ -572,20 +574,20 @@ fetch_getline(struct fetch_connect *conn
 	if (buf[len - 1] == '\n') {	/* clear any trailing newline */
 		buf[--len] = '\0';
 	} else if (len == buflen - 1) {	/* line too long */
-		while (1) {
+		for (;;) {
 			char c;
 			size_t rlen = fetch_read(&c, sizeof(c), 1, conn);
 			if (rlen == 0 || c == '\n')
 				break;
 		}
 		if (errormsg)
-			*errormsg = "Input line is too long";
+			*errormsg = "Input line is too long (specify -b > 16384)";
 		fetch_clearerr(conn);
 		return -3;
 	}
 	if (errormsg)
 		*errormsg = NULL;
-	return len;
+	return (int)len;
 }
 
 #ifdef WITH_SSL
@@ -687,7 +689,8 @@ fetch_start_ssl(int sock, const char *se
 		}
 		(void)gettimeofday(&now, NULL);
 		timersub(&timeout, &now, &delta);
-		timeout_secs = delta.tv_sec * 1000 + delta.tv_usec/1000;
+		timeout_secs = (int)(delta.tv_sec * 1000
+		    + delta.tv_usec / 1000);
 		if (timeout_secs < 0)
 			timeout_secs = 0;
 		rv = ftp_poll(pfd, 1, timeout_secs);

Index: src/usr.bin/ftp/util.c
diff -u src/usr.bin/ftp/util.c:1.164.2.2 src/usr.bin/ftp/util.c:1.164.2.3
--- src/usr.bin/ftp/util.c:1.164.2.2	Tue May 16 16:26:03 2023
+++ src/usr.bin/ftp/util.c	Sun Oct 13 16:06:36 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: util.c,v 1.164.2.2 2023/05/16 16:26:03 martin Exp $	*/
+/*	$NetBSD: util.c,v 1.164.2.3 2024/10/13 16:06:36 martin Exp $	*/
 
 /*-
  * Copyright (c) 1997-2023 The NetBSD Foundation, Inc.
@@ -64,7 +64,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: util.c,v 1.164.2.2 2023/05/16 16:26:03 martin Exp $");
+__RCSID("$NetBSD: util.c,v 1.164.2.3 2024/10/13 16:06:36 martin Exp $");
 #endif /* not lint */
 
 /*
@@ -202,11 +202,11 @@ getremoteinfo(void)
 			/* determine remote system type */
 	if (command("SYST") == COMPLETE) {
 		if (overbose) {
-			int os_len = strcspn(reply_string + 4, " \r\n\t");
+			off_t os_len = strcspn(reply_string + 4, " \r\n\t");
 			if (os_len > 1 && reply_string[4 + os_len - 1] == '.')
 				os_len--;
 			fprintf(ttyout, "Remote system type is %.*s.\n",
-			    os_len, reply_string + 4);
+			    (int)os_len, reply_string + 4);
 		}
 		/*
 		 * Decide whether we should default to bninary.
@@ -311,7 +311,7 @@ cleanuppeer(void)
  * Top-level signal handler for interrupted commands.
  */
 void
-intr(int signo)
+intr(int signo __unused)
 {
 
 	sigint_raised = 1;
@@ -949,7 +949,7 @@ list_vertical(StringList *sl)
  * Update the global ttywidth value, using TIOCGWINSZ.
  */
 void
-setttywidth(int a)
+setttywidth(int a __unused)
 {
 	struct winsize winsize;
 	int oerrno = errno;
@@ -1072,7 +1072,7 @@ strsuftoi(const char *arg)
 	if (val < 0 || val > INT_MAX)
 		return (-1);
 
-	return (val);
+	return (int)(val);
 }
 
 /*
@@ -1314,7 +1314,7 @@ get_line(FILE *stream, char *buf, size_t
 	int	rv, ch;
 	size_t	len;
 
-	if (fgets(buf, buflen, stream) == NULL) {
+	if (fgets(buf, (int)buflen, stream) == NULL) {
 		if (feof(stream)) {	/* EOF */
 			rv = -2;
 			if (errormsg)
@@ -1340,7 +1340,7 @@ get_line(FILE *stream, char *buf, size_t
 	}
 	if (errormsg)
 		*errormsg = NULL;
-	return len;
+	return (int)len;
 }
 
 /*
@@ -1431,7 +1431,8 @@ ftp_connect(int sock, const struct socka
 			if (quit_time > 0) {	/* determine timeout */
 				(void)gettimeofday(&now, NULL);
 				timersub(&endtime, &now, &td);
-				timeout = td.tv_sec * 1000 + td.tv_usec/1000;
+				timeout = (int)(td.tv_sec * 1000
+				    + td.tv_usec / 1000);
 				if (timeout < 0)
 					timeout = 0;
 			} else {

Added files:

Index: src/tests/usr.bin/ftp/Makefile
diff -u /dev/null src/tests/usr.bin/ftp/Makefile:1.1.2.2
--- /dev/null	Sun Oct 13 16:06:37 2024
+++ src/tests/usr.bin/ftp/Makefile	Sun Oct 13 16:06:37 2024
@@ -0,0 +1,15 @@
+# $NetBSD: Makefile,v 1.1.2.2 2024/10/13 16:06:37 martin Exp $
+
+.include <bsd.own.mk>
+
+TESTSDIR=	${TESTSBASE}/usr.bin/ftp
+TESTS_SH=	t_custom_headers
+
+SCRIPTSDIR=	${TESTSDIR}
+SCRIPTS+=	custom_headers.sh
+
+# Keep the .sh suffix because we use it to trigger cgi-bin handling in
+# bozohttpd (rather silly but it's easier that way).
+SCRIPTSNAME_custom_headers.sh=	custom_headers.sh
+
+.include <bsd.test.mk>
Index: src/tests/usr.bin/ftp/custom_headers.sh
diff -u /dev/null src/tests/usr.bin/ftp/custom_headers.sh:1.1.2.2
--- /dev/null	Sun Oct 13 16:06:37 2024
+++ src/tests/usr.bin/ftp/custom_headers.sh	Sun Oct 13 16:06:37 2024
@@ -0,0 +1,36 @@
+#! /bin/sh
+#
+#	$NetBSD: custom_headers.sh,v 1.1.2.2 2024/10/13 16:06:37 martin Exp $
+#
+# Copyright (c) 2024 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Sunil Nimmagadda.
+#
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+#
+
+echo "Content-type: text/plain; charset=utf-8"
+echo ""
+echo "HTTP_X_ORIGIN=$HTTP_X_ORIGIN"
+echo "HTTP_X_RATE_LIMIT=$HTTP_X_RATE_LIMIT"
Index: src/tests/usr.bin/ftp/t_custom_headers.sh
diff -u /dev/null src/tests/usr.bin/ftp/t_custom_headers.sh:1.1.2.2
--- /dev/null	Sun Oct 13 16:06:37 2024
+++ src/tests/usr.bin/ftp/t_custom_headers.sh	Sun Oct 13 16:06:37 2024
@@ -0,0 +1,67 @@
+#	$NetBSD: t_custom_headers.sh,v 1.1.2.2 2024/10/13 16:06:37 martin Exp $
+#
+# Copyright (c) 2024 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Sunil Nimmagadda.
+#
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+#
+
+atf_test_case custom_headers cleanup
+custom_headers_head()
+{
+	atf_require_prog ftp
+	atf_set "descr" "Check for custom HTTP headers"
+}
+
+HTTPD_PID=./.__httpd.pid
+custom_headers_body()
+{
+	# start httpd in daemon mode
+	atf_check -s exit:0 \
+	    /usr/libexec/httpd -P $HTTPD_PID -I 8080 -b -C .sh /bin/sh \
+	    -c "$(atf_get_srcdir)" .
+
+	atf_check \
+	    -o inline:'HTTP_X_ORIGIN=example.com\nHTTP_X_RATE_LIMIT=1000\n' \
+	    ftp -V -o - \
+		-H 'X-Origin: example.com' \
+		-H 'X-Rate-Limit: 1000' \
+		http://127.0.0.1:8080/cgi-bin/custom_headers.sh
+}
+
+custom_headers_cleanup()
+{
+	if [ -f "$HTTPD_PID" ]; then
+		echo kill -9 "$(cat $HTTPD_PID)"
+		kill -9 "$(cat $HTTPD_PID)"
+		echo '# wait for httpd to exit'
+		sleep 1
+	fi
+}
+
+atf_init_test_cases()
+{
+	atf_add_test_case custom_headers
+}

Reply via email to