misc improvements:
-initialize errno to 0 before receiving -minimal allowed packet size is 4 (empty data packet) -Be nice to the TFTP server - tell it that the transfer is finished (additinal ACK at EOF, ERROR otherwise). Otherwise, it will linger around and retransmit. This can be left out (TFTP_NOTERMINATE) if we are really short on space.
This commit is contained in:
parent
1442b419df
commit
04682788a9
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: tftp.c,v 1.4 1997/09/17 16:57:07 drochner Exp $ */
|
/* $NetBSD: tftp.c,v 1.5 1998/05/14 18:26:47 drochner Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1996
|
* Copyright (c) 1996
|
||||||
|
@ -96,9 +96,11 @@ recvtftp(d, pkt, len, tleft)
|
||||||
{
|
{
|
||||||
struct tftphdr *t;
|
struct tftphdr *t;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
len = readudp(d, pkt, len, tleft);
|
len = readudp(d, pkt, len, tleft);
|
||||||
|
|
||||||
if (len < 8)
|
if (len < 4)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
t = (struct tftphdr *) pkt;
|
t = (struct tftphdr *) pkt;
|
||||||
|
@ -200,9 +202,8 @@ tftp_getnextblock(h)
|
||||||
struct tftphdr *t;
|
struct tftphdr *t;
|
||||||
|
|
||||||
wbuf.t.th_opcode = htons((u_short) ACK);
|
wbuf.t.th_opcode = htons((u_short) ACK);
|
||||||
wtail = (char *) &wbuf.t.th_block;
|
|
||||||
wbuf.t.th_block = htons((u_short) h->currblock);
|
wbuf.t.th_block = htons((u_short) h->currblock);
|
||||||
wtail += 2;
|
wtail = (char *) &wbuf.t.th_data;
|
||||||
|
|
||||||
t = &h->lastdata.t;
|
t = &h->lastdata.t;
|
||||||
|
|
||||||
|
@ -221,6 +222,30 @@ tftp_getnextblock(h)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef TFTP_NOTERMINATE
|
||||||
|
static void
|
||||||
|
tftp_terminate(h)
|
||||||
|
struct tftp_handle *h;
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
u_char header[HEADER_SIZE];
|
||||||
|
struct tftphdr t;
|
||||||
|
} wbuf;
|
||||||
|
char *wtail;
|
||||||
|
|
||||||
|
if (h->islastblock) {
|
||||||
|
wbuf.t.th_opcode = htons((u_short) ACK);
|
||||||
|
wbuf.t.th_block = htons((u_short) h->currblock);
|
||||||
|
} else {
|
||||||
|
wbuf.t.th_opcode = htons((u_short) ERROR);
|
||||||
|
wbuf.t.th_code = htons((u_short) ENOSPACE); /* ??? */
|
||||||
|
}
|
||||||
|
wtail = (char *) &wbuf.t.th_data;
|
||||||
|
|
||||||
|
(void) sendudp(h->iodesc, &wbuf.t, wtail - (char *) &wbuf.t);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
tftp_open(path, f)
|
tftp_open(path, f)
|
||||||
char *path;
|
char *path;
|
||||||
|
@ -268,9 +293,13 @@ tftp_read(f, addr, size, resid)
|
||||||
|
|
||||||
needblock = tftpfile->off / SEGSIZE + 1;
|
needblock = tftpfile->off / SEGSIZE + 1;
|
||||||
|
|
||||||
if (tftpfile->currblock > needblock) /* seek backwards */
|
if (tftpfile->currblock > needblock) { /* seek backwards */
|
||||||
|
#ifndef TFTP_NOTERMINATE
|
||||||
|
tftp_terminate(tftpfile);
|
||||||
|
#endif
|
||||||
tftp_makereq(tftpfile); /* no error check, it worked
|
tftp_makereq(tftpfile); /* no error check, it worked
|
||||||
* for open */
|
* for open */
|
||||||
|
}
|
||||||
|
|
||||||
while (tftpfile->currblock < needblock) {
|
while (tftpfile->currblock < needblock) {
|
||||||
int res;
|
int res;
|
||||||
|
@ -278,7 +307,8 @@ tftp_read(f, addr, size, resid)
|
||||||
res = tftp_getnextblock(tftpfile);
|
res = tftp_getnextblock(tftpfile);
|
||||||
if (res) { /* no answer */
|
if (res) { /* no answer */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("tftp: read error\n");
|
printf("tftp: read error (block %d->%d)\n",
|
||||||
|
tftpfile->currblock, needblock);
|
||||||
#endif
|
#endif
|
||||||
return (res);
|
return (res);
|
||||||
}
|
}
|
||||||
|
@ -330,10 +360,13 @@ tftp_close(f)
|
||||||
struct tftp_handle *tftpfile;
|
struct tftp_handle *tftpfile;
|
||||||
tftpfile = (struct tftp_handle *) f->f_fsdata;
|
tftpfile = (struct tftp_handle *) f->f_fsdata;
|
||||||
|
|
||||||
|
#ifdef TFTP_NOTERMINATE
|
||||||
/* let it time out ... */
|
/* let it time out ... */
|
||||||
|
#else
|
||||||
|
tftp_terminate(tftpfile);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (tftpfile)
|
free(tftpfile, sizeof(*tftpfile));
|
||||||
free(tftpfile, sizeof(*tftpfile));
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue