tftp: Correctly propagate transfer errors.
Sponsored by: Klara, Inc. Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D38958
This commit is contained in:
parent
36242fc0e5
commit
92570f67c7
@ -84,7 +84,7 @@ typedef struct sockaddr_storage peeraddr;
|
|||||||
static int connected;
|
static int connected;
|
||||||
static char mode[32];
|
static char mode[32];
|
||||||
static jmp_buf toplevel;
|
static jmp_buf toplevel;
|
||||||
volatile int txrx_error;
|
static int txrx_error;
|
||||||
static int peer;
|
static int peer;
|
||||||
|
|
||||||
#define MAX_MARGV 20
|
#define MAX_MARGV 20
|
||||||
@ -501,7 +501,8 @@ put(int argc, char *argv[])
|
|||||||
if (verbose)
|
if (verbose)
|
||||||
printf("putting %s to %s:%s [%s]\n",
|
printf("putting %s to %s:%s [%s]\n",
|
||||||
cp, hostname, targ, mode);
|
cp, hostname, targ, mode);
|
||||||
xmitfile(peer, port, fd, targ, mode);
|
if (xmitfile(peer, port, fd, targ, mode))
|
||||||
|
txrx_error = 1;
|
||||||
close(fd);
|
close(fd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -529,7 +530,8 @@ put(int argc, char *argv[])
|
|||||||
if (verbose)
|
if (verbose)
|
||||||
printf("putting %s to %s:%s [%s]\n",
|
printf("putting %s to %s:%s [%s]\n",
|
||||||
argv[n], hostname, path, mode);
|
argv[n], hostname, path, mode);
|
||||||
xmitfile(peer, port, fd, path, mode);
|
if (xmitfile(peer, port, fd, path, mode) != 0)
|
||||||
|
txrx_error = 1;
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
free(path);
|
free(path);
|
||||||
@ -605,7 +607,8 @@ get(int argc, char *argv[])
|
|||||||
if (verbose)
|
if (verbose)
|
||||||
printf("getting from %s:%s to %s [%s]\n",
|
printf("getting from %s:%s to %s [%s]\n",
|
||||||
hostname, src, cp, mode);
|
hostname, src, cp, mode);
|
||||||
recvfile(peer, port, fd, src, mode);
|
if (recvfile(peer, port, fd, src, mode) != 0)
|
||||||
|
txrx_error = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cp = tail(src); /* new .. jdg */
|
cp = tail(src); /* new .. jdg */
|
||||||
@ -617,7 +620,8 @@ get(int argc, char *argv[])
|
|||||||
if (verbose)
|
if (verbose)
|
||||||
printf("getting from %s:%s to %s [%s]\n",
|
printf("getting from %s:%s to %s [%s]\n",
|
||||||
hostname, src, cp, mode);
|
hostname, src, cp, mode);
|
||||||
recvfile(peer, port, fd, src, mode);
|
if (recvfile(peer, port, fd, src, mode) != 0)
|
||||||
|
txrx_error = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,11 +68,11 @@ __FBSDID("$FreeBSD$");
|
|||||||
/*
|
/*
|
||||||
* Send the requested file.
|
* Send the requested file.
|
||||||
*/
|
*/
|
||||||
void
|
int
|
||||||
xmitfile(int peer, char *port, int fd, char *name, char *mode)
|
xmitfile(int peer, char *port, int fd, char *name, char *mode)
|
||||||
{
|
{
|
||||||
struct tftphdr *rp;
|
struct tftphdr *rp;
|
||||||
int n, i;
|
int n, i, ret = 0;
|
||||||
uint16_t block;
|
uint16_t block;
|
||||||
struct sockaddr_storage serv; /* valid server port number */
|
struct sockaddr_storage serv; /* valid server port number */
|
||||||
char recvbuffer[MAXPKTSIZE];
|
char recvbuffer[MAXPKTSIZE];
|
||||||
@ -102,7 +102,7 @@ xmitfile(int peer, char *port, int fd, char *name, char *mode)
|
|||||||
n = send_wrq(peer, name, mode);
|
n = send_wrq(peer, name, mode);
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
printf("Cannot send WRQ packet\n");
|
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) {
|
if (i == 12) {
|
||||||
printf("Transfer timed out.\n");
|
printf("Transfer timed out.\n");
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
if (rp->th_opcode == ERROR) {
|
if (rp->th_opcode == ERROR) {
|
||||||
printf("Got ERROR, aborted\n");
|
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) {
|
if (!options_rfc_enabled) {
|
||||||
printf("Got OACK while options are not enabled!\n");
|
printf("Got OACK while options are not enabled!\n");
|
||||||
send_error(peer, EBADOP);
|
send_error(peer, EBADOP);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_options(peer, rp->th_stuff, n + 2);
|
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) {
|
if (read_init(fd, NULL, mode) < 0) {
|
||||||
warn("read_init()");
|
warn("read_init()");
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
block = 1;
|
block = 1;
|
||||||
tftp_send(peer, &block, &tftp_stats);
|
if (tftp_send(peer, &block, &tftp_stats) != 0)
|
||||||
|
ret = -1;
|
||||||
|
|
||||||
read_close();
|
read_close();
|
||||||
if (tftp_stats.amount > 0)
|
if (tftp_stats.amount > 0)
|
||||||
printstats("Sent", verbose, &tftp_stats);
|
printstats("Sent", verbose, &tftp_stats);
|
||||||
|
return ret;
|
||||||
txrx_error = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Receive a file.
|
* Receive a file.
|
||||||
*/
|
*/
|
||||||
void
|
int
|
||||||
recvfile(int peer, char *port, int fd, char *name, char *mode)
|
recvfile(int peer, char *port, int fd, char *name, char *mode)
|
||||||
{
|
{
|
||||||
struct tftphdr *rp;
|
struct tftphdr *rp;
|
||||||
uint16_t block;
|
uint16_t block;
|
||||||
char recvbuffer[MAXPKTSIZE];
|
char recvbuffer[MAXPKTSIZE];
|
||||||
int n, i;
|
int n, i, ret = 0;
|
||||||
struct tftp_stats tftp_stats;
|
struct tftp_stats tftp_stats;
|
||||||
|
|
||||||
stats_init(&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);
|
n = send_rrq(peer, name, mode);
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
printf("Cannot send RRQ packet\n");
|
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) {
|
if (i == 12) {
|
||||||
printf("Transfer timed out.\n");
|
printf("Transfer timed out.\n");
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
if (rp->th_opcode == ERROR) {
|
if (rp->th_opcode == ERROR) {
|
||||||
tftp_log(LOG_ERR, "Error code %d: %s", rp->th_code, rp->th_msg);
|
tftp_log(LOG_ERR, "Error code %d: %s", rp->th_code, rp->th_msg);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (write_init(fd, NULL, mode) < 0) {
|
if (write_init(fd, NULL, mode) < 0) {
|
||||||
warn("write_init");
|
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) {
|
if (!options_rfc_enabled) {
|
||||||
printf("Got OACK while options are not enabled!\n");
|
printf("Got OACK while options are not enabled!\n");
|
||||||
send_error(peer, EBADOP);
|
send_error(peer, EBADOP);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_options(peer, rp->th_stuff, n + 2);
|
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);
|
n = send_ack(peer, 0);
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
printf("Cannot send ACK on OACK.\n");
|
printf("Cannot send ACK on OACK.\n");
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
block = 0;
|
block = 0;
|
||||||
tftp_receive(peer, &block, &tftp_stats, NULL, 0);
|
if (tftp_receive(peer, &block, &tftp_stats, NULL, 0) != 0)
|
||||||
|
ret = -1;
|
||||||
} else {
|
} else {
|
||||||
block = 1;
|
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)
|
if (tftp_stats.amount > 0)
|
||||||
printstats("Received", verbose, &tftp_stats);
|
printstats("Received", verbose, &tftp_stats);
|
||||||
return;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -32,9 +32,8 @@
|
|||||||
* $FreeBSD$
|
* $FreeBSD$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void recvfile(int peer, char *port, int fd, char *name, char *mode);
|
int recvfile(int peer, char *port, int fd, char *name, char *mode);
|
||||||
void xmitfile(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 verbose;
|
||||||
extern int maxtimeout;
|
extern int maxtimeout;
|
||||||
extern volatile int txrx_error;
|
|
||||||
|
Loading…
Reference in New Issue
Block a user