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 *);