Module Name:    src
Committed By:   christos
Date:           Thu Apr  4 00:36:09 UTC 2019

Modified Files:
        src/usr.bin/ftp: fetch.c ssl.c ssl.h

Log Message:
Make fetch_read() return size_t like fread() does. It is bogus to
have one backing implementation that returns different values and
types than the other.  Handle error setting properly; i.e. bail
out if the internal read returned an error. Now we get a proper
error message when the the server resets our connection instead of
a warning that the right failed with an invalid argument.

The server used for testing was:
        http://capeweather.dyndns.org:8080/graphs/3474.png
Which seems to be unreliable :-)


To generate a diff of this commit:
cvs rdiff -u -r1.230 -r1.231 src/usr.bin/ftp/fetch.c
cvs rdiff -u -r1.6 -r1.7 src/usr.bin/ftp/ssl.c
cvs rdiff -u -r1.3 -r1.4 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.

Modified files:

Index: src/usr.bin/ftp/fetch.c
diff -u src/usr.bin/ftp/fetch.c:1.230 src/usr.bin/ftp/fetch.c:1.231
--- src/usr.bin/ftp/fetch.c:1.230	Sat Feb 10 21:51:58 2018
+++ src/usr.bin/ftp/fetch.c	Wed Apr  3 20:36:09 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: fetch.c,v 1.230 2018/02/11 02:51:58 christos Exp $	*/
+/*	$NetBSD: fetch.c,v 1.231 2019/04/04 00:36:09 christos 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.230 2018/02/11 02:51:58 christos Exp $");
+__RCSID("$NetBSD: fetch.c,v 1.231 2019/04/04 00:36:09 christos Exp $");
 #endif /* not lint */
 
 /*
@@ -1640,10 +1640,14 @@ fetch_url(const char *url, const char *p
 			if (ischunked)
 				bufrem = MIN(chunksize, bufrem);
 			while (bufrem > 0) {
+				size_t nr = MIN((off_t)bufsize, bufrem);
 				flen = fetch_read(xferbuf, sizeof(char),
-				    MIN((off_t)bufsize, bufrem), fin);
-				if (flen <= 0)
+				    nr, fin);
+				if (flen == 0) {
+					if (fetch_error(fin))
+						goto chunkerror;
 					goto chunkdone;
+				}
 				bytes += flen;
 				bufrem -= flen;
 				if (fwrite(xferbuf, sizeof(char), flen, fout)
@@ -1694,7 +1698,7 @@ fetch_url(const char *url, const char *p
 	} while (ischunked);
 
 /* XXX: deal with optional trailer & CRLF here? */
-
+chunkerror:
 	if (hash && !progress && bytes > 0) {
 		if (bytes < mark)
 			(void)putc('#', ttyout);

Index: src/usr.bin/ftp/ssl.c
diff -u src/usr.bin/ftp/ssl.c:1.6 src/usr.bin/ftp/ssl.c:1.7
--- src/usr.bin/ftp/ssl.c:1.6	Tue Feb  6 14:26:02 2018
+++ src/usr.bin/ftp/ssl.c	Wed Apr  3 20:36:09 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: ssl.c,v 1.6 2018/02/06 19:26:02 christos Exp $	*/
+/*	$NetBSD: ssl.c,v 1.7 2019/04/04 00:36:09 christos Exp $	*/
 
 /*-
  * Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
@@ -34,7 +34,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: ssl.c,v 1.6 2018/02/06 19:26:02 christos Exp $");
+__RCSID("$NetBSD: ssl.c,v 1.7 2019/04/04 00:36:09 christos Exp $");
 #endif
 
 #include <time.h>
@@ -348,7 +348,7 @@ fetch_cache_data(struct fetch_connect *c
 	return 0;
 }
 
-ssize_t
+size_t
 fetch_read(void *ptr, size_t size, size_t nmemb, struct fetch_connect *conn)
 {
 	struct timeval now, timeout, delta;
@@ -408,6 +408,7 @@ fetch_read(void *ptr, size_t size, size_
 		else
 			rlen = fetch_nonssl_read(conn->sd, buf, len);
 		if (rlen == 0) {
+			conn->iseof = 1;
 			break;
 		} else if (rlen > 0) {
 			len -= rlen;
@@ -415,9 +416,10 @@ fetch_read(void *ptr, size_t size, size_
 			total += rlen;
 			continue;
 		} else if (rlen == FETCH_READ_ERROR) {
+			conn->iserr = errno;
 			if (errno == EINTR)
 				fetch_cache_data(conn, start, total);
-			return -1;
+			return 0;
 		}
 		FD_ZERO(&readfds);
 		while (!FD_ISSET(conn->sd, &readfds)) {
@@ -425,8 +427,8 @@ fetch_read(void *ptr, size_t size, size_
 			if (quit_time > 0) {
 				gettimeofday(&now, NULL);
 				if (!timercmp(&timeout, &now, >)) {
-					errno = ETIMEDOUT;
-					return -1;
+					conn->iserr = ETIMEDOUT;
+					return 0;
 				}
 				timersub(&timeout, &now, &delta);
 			}
@@ -435,7 +437,8 @@ fetch_read(void *ptr, size_t size, size_
 				quit_time > 0 ? &delta : NULL) < 0) {
 				if (errno == EINTR)
 					continue;
-				return -1;
+				conn->iserr = errno;
+				return 0;
 			}
 		}
 	}
@@ -451,7 +454,7 @@ char *
 fetch_getln(char *str, int size, struct fetch_connect *conn)
 {
 	size_t tmpsize;
-	ssize_t len;
+	size_t len;
 	char c;
 
 	if (conn->buf == NULL) {
@@ -474,13 +477,12 @@ fetch_getln(char *str, int size, struct 
 	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;
+			if (conn->iserr)
+				return NULL;
+			if (conn->iseof)
+				break;
+			abort();
 		}
 		conn->buf[conn->buflen++] = c;
 		if (conn->buflen == conn->bufsize) {
@@ -532,8 +534,8 @@ fetch_getline(struct fetch_connect *conn
 	} 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')
+			size_t rlen = fetch_read(&c, sizeof(c), 1, conn);
+			if (rlen == 0 || c == '\n')
 				break;
 		}
 		if (errormsg)

Index: src/usr.bin/ftp/ssl.h
diff -u src/usr.bin/ftp/ssl.h:1.3 src/usr.bin/ftp/ssl.h:1.4
--- src/usr.bin/ftp/ssl.h:1.3	Sat Sep 12 15:38:42 2015
+++ src/usr.bin/ftp/ssl.h	Wed Apr  3 20:36:09 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: ssl.h,v 1.3 2015/09/12 19:38:42 wiz Exp $	*/
+/*	$NetBSD: ssl.h,v 1.4 2019/04/04 00:36:09 christos Exp $	*/
 
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@ int fetch_flush(struct fetch_connect *);
 struct fetch_connect *fetch_open(const char *, const char *);
 struct fetch_connect *fetch_fdopen(int, const char *);
 int fetch_close(struct fetch_connect *);
-ssize_t fetch_read(void *, size_t, size_t, struct fetch_connect *);
+size_t fetch_read(void *, size_t, size_t, struct fetch_connect *);
 char *fetch_getln(char *, int, struct fetch_connect *);
 int fetch_getline(struct fetch_connect *, char *, size_t, const char **);
 void fetch_set_ssl(struct fetch_connect *, void *);

Reply via email to