This fixes a couple of problems in tftp_recvfile: 1) A superfluous ACK was sent if the transfer had been terminated abnormally (due to a received ERROR or an I/O error). 2) Sending of the last ACK was neither traced nor checked for errors. --- tftp/tftp.c | 15 ++++++++++----- 1 files changed, 10 insertions(+), 5 deletions(-) diff --git a/tftp/tftp.c b/tftp/tftp.c index d15da22..5dbaf20 100644 --- a/tftp/tftp.c +++ b/tftp/tftp.c @@ -258,16 +258,21 @@ void tftp_recvfile(int fd, const char *name, const char *mode) size = writeit(file, &dp, n - 4, convert); if (size < 0) { nak(errno + 100, NULL); - break; + goto abort; } amount += size; } while (size == SEGSIZE); - abort: /* ok to ack, since user */ - ap->th_opcode = htons((u_short) ACK); /* has seen err msg */ + /* send last ACK */ + ap->th_opcode = htons((u_short) ACK); ap->th_block = htons((u_short) block); - (void)sendto(f, ackbuf, 4, 0, (struct sockaddr *)&peeraddr, - SOCKLEN(&peeraddr)); + size = 4; + if (trace) + tpacket("sent", ap, size); + if (sendto(f, ackbuf, size, 0, &peeraddr.sa, + SOCKLEN(&peeraddr)) != size) + perror("tftp: sendto"); write_behind(file, convert); /* flush last buffer */ + abort: fclose(file); stopclock(); if (amount > 0) -- 1.7.4 ------------qzp8x1kZJP8rlRW0yN7vuY--