summaryrefslogtreecommitdiff
path: root/tftpd/tftpd.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2009-02-02 15:14:27 -0800
committerH. Peter Anvin <hpa@linux.intel.com>2009-02-02 15:14:27 -0800
commit932277c9a5f90d906296a319c0c3e5f36bf2e8b1 (patch)
treee4b6bf022f0db16b1ce11fdfa23d0a46b0bf51c9 /tftpd/tftpd.c
parentfcdd859a7513319f68a5ba1261c0f66ef3a28723 (diff)
downloadtftp-hpa-932277c9a5f90d906296a319c0c3e5f36bf2e8b1.tar.gz
tftpd: implement the "rollover" option
Implement the "rollover" option, to set the rollover block number to anything other than zero. Apparently some idiots have gotten the idea that block numbers should roll over to one, rather than zero.
Diffstat (limited to 'tftpd/tftpd.c')
-rw-r--r--tftpd/tftpd.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/tftpd/tftpd.c b/tftpd/tftpd.c
index 3c96844..f98d52b 100644
--- a/tftpd/tftpd.c
+++ b/tftpd/tftpd.c
@@ -81,6 +81,7 @@ static unsigned long rexmtval = TIMEOUT; /* Basic timeout value */
static unsigned long maxtimeout = TIMEOUT_LIMIT * TIMEOUT;
static int timeout_quit = 0;
static sigjmp_buf timeoutbuf;
+static uint16_t rollover_val = 0;
#define PKTSIZE MAX_SEGSIZE+4
static char buf[PKTSIZE];
@@ -119,6 +120,7 @@ static int set_blksize2(char *, char **);
static int set_tsize(char *, char **);
static int set_timeout(char *, char **);
static int set_utimeout(char *, char **);
+static int set_rollover(char *, char **);
struct options {
const char *o_opt;
@@ -129,6 +131,7 @@ struct options {
{"tsize", set_tsize},
{"timeout", set_timeout},
{"utimeout", set_utimeout},
+ {"rollover", set_rollover},
{NULL, NULL}
};
@@ -1161,6 +1164,23 @@ static int set_blksize2(char *val, char **ret)
}
/*
+ * Set the block number rollover value
+ */
+static int set_rollover(char *val, char **ret)
+{
+ uintmax_t ro;
+ char *vend;
+
+ ro = strtoumax(val, &vend, 10);
+ if (ro > 65535 || *vend)
+ return 0;
+
+ rollover_val = (uint16_t)ro;
+ *ret = val;
+ return 1;
+}
+
+/*
* Return a file size (c.f. RFC2349)
* For netascii mode, we don't know the size ahead of time;
* so reject the option.
@@ -1542,7 +1562,8 @@ static void tftp_sendfile(struct formats *pf, struct tftphdr *oap, int oacklen)
}
}
- block++;
+ if (!++block)
+ block = rollover_val;
} while (size == segsize);
abort:
(void)fclose(file);
@@ -1575,7 +1596,8 @@ static void tftp_recvfile(struct formats *pf, struct tftphdr *oap, int oacklen)
ap->th_block = htons((u_short) block);
acksize = 4;
}
- block++;
+ if (!++block)
+ block = rollover_val;
(void)sigsetjmp(timeoutbuf, 1);
send_ack:
r_timeout = timeout;