The branch main has been updated by des:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=92570f67c7911126ce742a3dfe1b97046091ed0e

commit 92570f67c7911126ce742a3dfe1b97046091ed0e
Author:     Dag-Erling Smørgrav <[email protected]>
AuthorDate: 2023-03-10 13:24:28 +0000
Commit:     Dag-Erling Smørgrav <[email protected]>
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;

Reply via email to