git: 92570f67c791 - main - tftp: Correctly propagate transfer errors.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 10 Mar 2023 13:29:18 UTC
The branch main has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=92570f67c7911126ce742a3dfe1b97046091ed0e commit 92570f67c7911126ce742a3dfe1b97046091ed0e Author: Dag-Erling Smørgrav <des@FreeBSD.org> AuthorDate: 2023-03-10 13:24:28 +0000 Commit: Dag-Erling Smørgrav <des@FreeBSD.org> CommitDate: 2023-03-10 13:25:16 +0000 tftp: Correctly propagate transfer errors. Sponsored by: Klara, Inc. Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D38958 --- usr.bin/tftp/main.c | 14 +++++++++----- usr.bin/tftp/tftp.c | 44 +++++++++++++++++++++++--------------------- usr.bin/tftp/tftp.h | 5 ++--- 3 files changed, 34 insertions(+), 29 deletions(-) diff --git a/usr.bin/tftp/main.c b/usr.bin/tftp/main.c index 05d8b31331f6..9cc18fbb0d5b 100644 --- a/usr.bin/tftp/main.c +++ b/usr.bin/tftp/main.c @@ -84,7 +84,7 @@ typedef struct sockaddr_storage peeraddr; static int connected; static char mode[32]; static jmp_buf toplevel; -volatile int txrx_error; +static int txrx_error; static int peer; #define MAX_MARGV 20 @@ -501,7 +501,8 @@ put(int argc, char *argv[]) if (verbose) printf("putting %s to %s:%s [%s]\n", cp, hostname, targ, mode); - xmitfile(peer, port, fd, targ, mode); + if (xmitfile(peer, port, fd, targ, mode)) + txrx_error = 1; close(fd); return; } @@ -529,7 +530,8 @@ put(int argc, char *argv[]) if (verbose) printf("putting %s to %s:%s [%s]\n", argv[n], hostname, path, mode); - xmitfile(peer, port, fd, path, mode); + if (xmitfile(peer, port, fd, path, mode) != 0) + txrx_error = 1; close(fd); free(path); @@ -605,7 +607,8 @@ get(int argc, char *argv[]) if (verbose) printf("getting from %s:%s to %s [%s]\n", hostname, src, cp, mode); - recvfile(peer, port, fd, src, mode); + if (recvfile(peer, port, fd, src, mode) != 0) + txrx_error = 1; break; } cp = tail(src); /* new .. jdg */ @@ -617,7 +620,8 @@ get(int argc, char *argv[]) if (verbose) printf("getting from %s:%s to %s [%s]\n", hostname, src, cp, mode); - recvfile(peer, port, fd, src, mode); + if (recvfile(peer, port, fd, src, mode) != 0) + txrx_error = 1; } } diff --git a/usr.bin/tftp/tftp.c b/usr.bin/tftp/tftp.c index 31fefd8f22e2..d5f36e77d853 100644 --- a/usr.bin/tftp/tftp.c +++ b/usr.bin/tftp/tftp.c @@ -68,11 +68,11 @@ __FBSDID("$FreeBSD$"); /* * Send the requested file. */ -void +int xmitfile(int peer, char *port, int fd, char *name, char *mode) { struct tftphdr *rp; - int n, i; + int n, i, ret = 0; uint16_t block; struct sockaddr_storage serv; /* valid server port number */ char recvbuffer[MAXPKTSIZE]; @@ -102,7 +102,7 @@ xmitfile(int peer, char *port, int fd, char *name, char *mode) n = send_wrq(peer, name, mode); if (n > 0) { printf("Cannot send WRQ packet\n"); - return; + return -1; } /* @@ -131,11 +131,11 @@ xmitfile(int peer, char *port, int fd, char *name, char *mode) } if (i == 12) { printf("Transfer timed out.\n"); - return; + return -1; } if (rp->th_opcode == ERROR) { printf("Got ERROR, aborted\n"); - return; + return -1; } /* @@ -146,7 +146,7 @@ xmitfile(int peer, char *port, int fd, char *name, char *mode) if (!options_rfc_enabled) { printf("Got OACK while options are not enabled!\n"); send_error(peer, EBADOP); - return; + return -1; } parse_options(peer, rp->th_stuff, n + 2); @@ -154,29 +154,29 @@ xmitfile(int peer, char *port, int fd, char *name, char *mode) if (read_init(fd, NULL, mode) < 0) { warn("read_init()"); - return; + return -1; } block = 1; - tftp_send(peer, &block, &tftp_stats); + if (tftp_send(peer, &block, &tftp_stats) != 0) + ret = -1; read_close(); if (tftp_stats.amount > 0) printstats("Sent", verbose, &tftp_stats); - - txrx_error = 1; + return ret; } /* * Receive a file. */ -void +int recvfile(int peer, char *port, int fd, char *name, char *mode) { struct tftphdr *rp; uint16_t block; char recvbuffer[MAXPKTSIZE]; - int n, i; + int n, i, ret = 0; struct tftp_stats tftp_stats; stats_init(&tftp_stats); @@ -202,7 +202,7 @@ recvfile(int peer, char *port, int fd, char *name, char *mode) n = send_rrq(peer, name, mode); if (n > 0) { printf("Cannot send RRQ packet\n"); - return; + return -1; } /* @@ -231,16 +231,16 @@ recvfile(int peer, char *port, int fd, char *name, char *mode) } if (i == 12) { printf("Transfer timed out.\n"); - return; + return -1; } if (rp->th_opcode == ERROR) { tftp_log(LOG_ERR, "Error code %d: %s", rp->th_code, rp->th_msg); - return; + return -1; } if (write_init(fd, NULL, mode) < 0) { warn("write_init"); - return; + return -1; } /* @@ -251,7 +251,7 @@ recvfile(int peer, char *port, int fd, char *name, char *mode) if (!options_rfc_enabled) { printf("Got OACK while options are not enabled!\n"); send_error(peer, EBADOP); - return; + return -1; } parse_options(peer, rp->th_stuff, n + 2); @@ -259,16 +259,18 @@ recvfile(int peer, char *port, int fd, char *name, char *mode) n = send_ack(peer, 0); if (n > 0) { printf("Cannot send ACK on OACK.\n"); - return; + return -1; } block = 0; - tftp_receive(peer, &block, &tftp_stats, NULL, 0); + if (tftp_receive(peer, &block, &tftp_stats, NULL, 0) != 0) + ret = -1; } else { block = 1; - tftp_receive(peer, &block, &tftp_stats, rp, n); + if (tftp_receive(peer, &block, &tftp_stats, rp, n) != 0) + ret = -1; } if (tftp_stats.amount > 0) printstats("Received", verbose, &tftp_stats); - return; + return ret; } diff --git a/usr.bin/tftp/tftp.h b/usr.bin/tftp/tftp.h index 26e5652d0fdd..680ea2ea4fb6 100644 --- a/usr.bin/tftp/tftp.h +++ b/usr.bin/tftp/tftp.h @@ -32,9 +32,8 @@ * $FreeBSD$ */ -void recvfile(int peer, char *port, int fd, char *name, char *mode); -void xmitfile(int peer, char *port, int fd, char *name, char *mode); +int recvfile(int peer, char *port, int fd, char *name, char *mode); +int xmitfile(int peer, char *port, int fd, char *name, char *mode); extern int verbose; extern int maxtimeout; -extern volatile int txrx_error;