From e6fc5c5cabd210317ac6acae185416eeaf2a83d9 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Fri, 10 Feb 2023 14:23:34 +0100 Subject: [PATCH 2/5] tqftpserv: add seek option parsing Actual handling will be added in follow-up commits as rsize is also not currently handled, and both are quite interconnected. --- tqftpserv.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/tqftpserv.c b/tqftpserv.c index 9d1a2b3..eed99a1 100644 --- a/tqftpserv.c +++ b/tqftpserv.c @@ -67,6 +67,7 @@ struct tftp_client { size_t rsize; size_t wsize; unsigned int timeoutms; + off_t seek; }; static struct list_head readers = LIST_INIT(readers); @@ -117,7 +118,8 @@ static int tftp_send_ack(int sock, int block) } static int tftp_send_oack(int sock, size_t *blocksize, size_t *tsize, - size_t *wsize, unsigned int *timeoutms, size_t *rsize) + size_t *wsize, unsigned int *timeoutms, size_t *rsize, + off_t *seek) { char buf[512]; char *p = buf; @@ -171,6 +173,15 @@ static int tftp_send_oack(int sock, size_t *blocksize, size_t *tsize, *p++ = '\0'; } + if (seek) { + strcpy(p, "seek"); + p += 5; + + n = sprintf(p, "%zd", *seek); + p += n; + *p++ = '\0'; + } + return send(sock, buf, p - buf, 0); } @@ -197,7 +208,7 @@ static int tftp_send_error(int sock, int code, const char *msg) static void parse_options(const char *buf, size_t len, size_t *blksize, ssize_t *tsize, size_t *wsize, unsigned int *timeoutms, - size_t *rsize) + size_t *rsize, off_t *seek) { const char *opt, *value; const char *p = buf; @@ -217,6 +228,7 @@ static void parse_options(const char *buf, size_t len, size_t *blksize, * tsize: total size - request to get file size in bytes * rsize: read size - how many bytes to send, not full file * wsize: window size - how many blocks to send without ACK + * seek: offset from beginning of file in bytes to start reading */ if (!strcmp(opt, "blksize")) { *blksize = atoi(value); @@ -228,6 +240,8 @@ static void parse_options(const char *buf, size_t len, size_t *blksize, *rsize = atoi(value); } else if (!strcmp(opt, "wsize")) { *wsize = atoi(value); + } else if (!strcmp(opt, "seek")) { + *seek = atoi(value); } else { printf("[TQFTP] Ignoring unknown option '%s' with value '%s'\n", opt, value); } @@ -246,6 +260,7 @@ static void handle_rrq(const char *buf, size_t len, struct sockaddr_qrtr *sq) unsigned int timeoutms = 1000; size_t rsize = 0; size_t wsize = 0; + off_t seek = 0; bool do_oack = false; int sock; int ret; @@ -270,7 +285,7 @@ static void handle_rrq(const char *buf, size_t len, struct sockaddr_qrtr *sq) if (p < buf + len) { do_oack = true; parse_options(p, len - (p - buf), &blksize, &tsize, &wsize, - &timeoutms, &rsize); + &timeoutms, &rsize, &seek); } sock = qrtr_open(0); @@ -307,6 +322,7 @@ static void handle_rrq(const char *buf, size_t len, struct sockaddr_qrtr *sq) client->rsize = rsize; client->wsize = wsize; client->timeoutms = timeoutms; + client->seek = seek; // printf("[TQFTP] new reader added\n"); @@ -317,7 +333,8 @@ static void handle_rrq(const char *buf, size_t len, struct sockaddr_qrtr *sq) tsize ? (size_t*)&tsize : NULL, wsize ? &wsize : NULL, &client->timeoutms, - rsize ? &rsize: NULL); + rsize ? &rsize : NULL, + seek ? &seek : NULL); } else { tftp_send_data(client, 1, 0); } @@ -334,6 +351,7 @@ static void handle_wrq(const char *buf, size_t len, struct sockaddr_qrtr *sq) unsigned int timeoutms = 1000; size_t rsize = 0; size_t wsize = 0; + off_t seek = 0; bool do_oack = false; int sock; int ret; @@ -354,7 +372,7 @@ static void handle_wrq(const char *buf, size_t len, struct sockaddr_qrtr *sq) if (p < buf + len) { do_oack = true; parse_options(p, len - (p - buf), &blksize, &tsize, &wsize, - &timeoutms, &rsize); + &timeoutms, &rsize, &seek); } fd = translate_open(filename, O_WRONLY | O_CREAT); @@ -386,6 +404,7 @@ static void handle_wrq(const char *buf, size_t len, struct sockaddr_qrtr *sq) client->rsize = rsize; client->wsize = wsize; client->timeoutms = timeoutms; + client->seek = seek; // printf("[TQFTP] new writer added\n"); @@ -396,7 +415,8 @@ static void handle_wrq(const char *buf, size_t len, struct sockaddr_qrtr *sq) tsize ? (size_t*)&tsize : NULL, wsize ? &wsize : NULL, &client->timeoutms, - rsize ? &rsize: NULL); + rsize ? &rsize : NULL, + seek ? &seek : NULL); } else { tftp_send_data(client, 1, 0); } -- 2.44.0