Hello community,

here is the log from the commit of package uftpd for openSUSE:Factory checked 
in at 2019-08-27 10:27:44
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/uftpd (Old)
 and      /work/SRC/openSUSE:Factory/.uftpd.new.7948 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "uftpd"

Tue Aug 27 10:27:44 2019 rev:7 rq:726274 version:2.10

Changes:
--------
--- /work/SRC/openSUSE:Factory/uftpd/uftpd.changes      2019-07-30 
12:39:25.914933313 +0200
+++ /work/SRC/openSUSE:Factory/.uftpd.new.7948/uftpd.changes    2019-08-27 
10:27:48.227912562 +0200
@@ -1,0 +2,10 @@
+Mon Aug 26 20:56:41 UTC 2019 - Martin Hauke <[email protected]>
+
+- Update to version 2.10
+  * Add support for TFTP WRQ, i.e. for clients sending files to
+    server
+  * Fix invalid TFTP error codes, now uses custom error string to
+    code 0
+  * Slightly improved debug messages
+
+-------------------------------------------------------------------

Old:
----
  uftpd-2.9.tar.gz

New:
----
  uftpd-2.10.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ uftpd.spec ++++++
--- /var/tmp/diff_new_pack.13v7ay/_old  2019-08-27 10:27:48.687912528 +0200
+++ /var/tmp/diff_new_pack.13v7ay/_new  2019-08-27 10:27:48.691912528 +0200
@@ -18,7 +18,7 @@
 
 
 Name:           uftpd
-Version:        2.9
+Version:        2.10
 Release:        0
 Summary:        A combined TFTP/FTP server
 License:        ISC

++++++ uftpd-2.9.tar.gz -> uftpd-2.10.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uftpd-2.9/ChangeLog.md new/uftpd-2.10/ChangeLog.md
--- old/uftpd-2.9/ChangeLog.md  2019-07-29 10:53:23.000000000 +0200
+++ new/uftpd-2.10/ChangeLog.md 2019-08-15 09:20:03.000000000 +0200
@@ -4,6 +4,18 @@
 All notable changes to the project are documented in this file.
 
 
+[v2.10][] - 2019-08-15
+----------------------
+
+### Changes
+- Issue #25: Add support for TFTP write support (WRQ)
+- Slightly improved debug messages.
+
+### Fixes
+- Minor fix to TFTP error codes, only use standardized codes, and
+  code 0 + custom error message for everything else
+
+
 [v2.9][] - 2019-07-29
 ---------------------
 
@@ -16,7 +28,7 @@
   - Fixes failing `dpkg -P uftpd` due to bug in postrm script
 
 ### Fixes
-- Issue #21: Check for `pkg-config` before lookging for deps.
+- Issue #21: Check for `pkg-config` before looking for deps.
 - Issue #22: Check FTP root security *after* having dropped privs.
   This means no longer having to run with `-o writable` by default
 - Issue #23: FTP command `CWD /` does not work, affects all clients.
@@ -44,7 +56,7 @@
 - Require libuEv v2.2, or later
 
 ### Fixes
-- Issue #17: Issues with relative FTP root when running unpriviliged
+- Issue #17: Issues with relative FTP root when running unprivileged
 
 
 [v2.6][] - 2018-07-03
@@ -90,7 +102,7 @@
 
 ### Changes
 - Handle non-chrooted use-cases better, ensure CWD starts with /
-- Increased default inactivty timer: 20 sec --> 180 sec
+- Increased default inactivity timer: 20 sec --> 180 sec
 - Ensure FTP `PASV` and `PORT` sockets are set non-blocking to prevent
   blocking the event loop
 - [README.md][] updates, add usage section and improve build + install
@@ -175,7 +187,7 @@
 [v2.0][] - 2016-01-22
 ---------------------
 
-Sleak, smart, simple ... UNIX
+Sleek, smart, simple ... UNIX
 
 ### Changes
 - Greatly simplified command line syntax
@@ -220,7 +232,7 @@
 - Major refactor of both FTP and TFTP servers to use libuEv better.
 - Move to use [libite][] v1.0.0 for `strlcpy()`, `strlcat()`, `pidfile()`
   and more.
-- Add proper session timout to TFTP, like what FTP already has.
+- Add proper session timeout to TFTP, like what FTP already has.
 - Add support for `NLST` FTP command, needed for multiple get operations.
   This fixes issue #2, thanks to @oz123 on GitHub for pointing this out!
 - Add support for `FEAT` and `HELP` FTP commands used by some clients.
@@ -301,7 +313,7 @@
 ### Fixes
 - Fix nasty invalid `sizeof()` argument to `recv()` causing uftpd to
   only read 4/8 bytes (32/64 bit arch) at a time from the FTP socket.
-  This should greatly reduce CPU utilisation and improve xfer speeds.
+  This should greatly reduce CPU utilization and improve xfer speeds.
   Found by [Coverity Scan][].
 - Fix minor resource leak in `ftp_session()` when `getsockname()` or
   `getpeername()` fail.  Minor fix because the session exits and the OS
@@ -349,7 +361,7 @@
 - Incompatible changes to the command line arguments, compared to v1.2!
 - Add libuEv as a GIT submodule, handles signals, timers, and all I/O.
 - Refactor all signal handling, timers, and socket `poll()` calls to
-  use libuEv instead.  Much cleaner and maintaiable code as a result.
+  use libuEv instead.  Much cleaner and maintainable code as a result.
 - Clarify copyright claims, not much remains of the original [FtpServer][]
   code, by [Xu Wang][].
 
@@ -424,7 +436,8 @@
   Lines must end in the old `\r\n` format, rather than UNIX `\n`.
 
 
-[UNRELEASED]:    https://github.com/troglobit/uftpd/compare/v2.9...HEAD
+[UNRELEASED]:    https://github.com/troglobit/uftpd/compare/v2.10...HEAD
+[v2.10]:         https://github.com/troglobit/uftpd/compare/v2.9...v2.10
 [v2.9]:          https://github.com/troglobit/uftpd/compare/v2.8...v2.9
 [v2.8]:          https://github.com/troglobit/uftpd/compare/v2.7...v2.8
 [v2.7]:          https://github.com/troglobit/uftpd/compare/v2.6...v2.7
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uftpd-2.9/configure.ac new/uftpd-2.10/configure.ac
--- old/uftpd-2.9/configure.ac  2019-07-29 10:53:23.000000000 +0200
+++ new/uftpd-2.10/configure.ac 2019-08-15 09:20:03.000000000 +0200
@@ -1,4 +1,5 @@
-AC_INIT([uftpd], [2.9], [https://github.com/troglobit/uftpd/issues],, 
[http://troglobit.com/uftpd.html])
+AC_INIT([uftpd], [2.10], [https://github.com/troglobit/uftpd/issues],,
+       [https://troglobit.com/projects/uftpd/])
 AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz])
 AM_SILENT_RULES([yes])
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uftpd-2.9/debian/changelog 
new/uftpd-2.10/debian/changelog
--- old/uftpd-2.9/debian/changelog      2019-07-29 10:53:23.000000000 +0200
+++ new/uftpd-2.10/debian/changelog     2019-08-15 09:20:03.000000000 +0200
@@ -1,3 +1,11 @@
+uftpd (2.10) unstable; urgency=medium
+
+  * Add support for TFTP WRQ, i.e. for clients sending files to server
+  * Fix invalid TFTP error codes, now uses custom error string to code 0
+  * Slightly improved debug messages
+
+ -- Joachim Nilsson <[email protected]>  Thu, 15 Aug 2019 08:59:35 +0200
+
 uftpd (2.9) unstable; urgency=medium
 
   * Check FTP root security after dropping privileges, issue #22
@@ -22,7 +30,7 @@
 uftpd (2.7) unstable; urgency=medium
 
   * Bug fix release
-  * Fix running uftpd as unpriviliged user using a relative FTP root
+  * Fix running uftpd as unprivileged user using a relative FTP root
 
  -- Joachim Nilsson <[email protected]>  Sun, 03 Mar 2019 11:39:03 +0100
 
@@ -73,7 +81,7 @@
 
     A user must now be member of the users group to share files over
     TFTP/FTP.  Simply add a user to 'users' and they can upload their
-    files to /srv/ftp.  The TFT/FTP server itself has no rights to
+    files to /srv/ftp.  The TFTP/FTP server itself has no rights to
     write there.  Add an uploads/ sub-directory with write perms for
     the 'ftp' user if you want to enable anonymous uploads via FTP.
 
@@ -134,7 +142,7 @@
 
   * New upstream release:
     - Fix insecure chroot(), reported by Coverity Scan, CID #54523
-    - Minor updates to README and a new CHANGLOG file
+    - Minor updates to README and a new CHANGELOG file
 
  -- Joachim Nilsson <[email protected]>  Sun,  2 Feb 2015 06:45:06 +0100
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uftpd-2.9/debian/config new/uftpd-2.10/debian/config
--- old/uftpd-2.9/debian/config 2019-07-29 10:53:23.000000000 +0200
+++ new/uftpd-2.10/debian/config        2019-08-15 09:20:03.000000000 +0200
@@ -1,4 +1,6 @@
-#!/bin/sh -e
+#!/bin/sh
+
+set -e
 . /usr/share/debconf/confmodule
 
 db_title uftpd
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uftpd-2.9/debian/control 
new/uftpd-2.10/debian/control
--- old/uftpd-2.9/debian/control        2019-07-29 10:53:23.000000000 +0200
+++ new/uftpd-2.10/debian/control       2019-08-15 09:20:03.000000000 +0200
@@ -4,7 +4,7 @@
 Maintainer: Joachim Nilsson <[email protected]>
 Build-Depends: debhelper (>= 10)
 Standards-Version: 4.3.0
-Homepage: https://troglobit.com/uftpd.html
+Homepage: https://troglobit.com/projects/uftpd/
 
 Package: uftpd
 Architecture: any
@@ -13,12 +13,14 @@
 Provides: ftp-server
 Conflicts: ftp-server, tftpd, tftpd-hpa
 Description: No nonsense TFTP/FTP server
- uftpd is a very simple TFTP and FTP server intended for small and local
- LANs.  It works on the Internet, although it is not recommended, and is
- set up in a read-only configuration by default.  It has no users, no
- configuration file, and is started on-demand by the UNIX inetd super
- server, neatly tcpwrapped for your safety.
+ uftpd is a small and simple TFTP and FTP server intended for LANs.  Its
+ author runs it on the Internet, although this is not recommended.
+ .
+ uftpd is set up in a read-only configuration by default.  It has no
+ users, except for anonymous, no configuration file, and is started
+ on-demand by the UNIX inetd super server, neatly tcpwrapped for your
+ safety.
  .
  Hardcore Internet users and anyone concerned about security should
  probably consider a separate TFTP server and for FTP look at one of:
- vsftpd, proftpd or pure-ftpd.
+ vsftpd, proftpd, or pure-ftpd.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uftpd-2.9/debian/postinst 
new/uftpd-2.10/debian/postinst
--- old/uftpd-2.9/debian/postinst       2019-07-29 10:53:23.000000000 +0200
+++ new/uftpd-2.10/debian/postinst      2019-08-15 09:20:03.000000000 +0200
@@ -1,4 +1,6 @@
-#!/bin/sh -e
+#!/bin/sh
+
+set -e
 
 [ "$1" = "configure" ] || exit 0
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uftpd-2.9/debian/postrm new/uftpd-2.10/debian/postrm
--- old/uftpd-2.9/debian/postrm 2019-07-29 10:53:23.000000000 +0200
+++ new/uftpd-2.10/debian/postrm        2019-08-15 09:20:03.000000000 +0200
@@ -1,4 +1,5 @@
-#!/bin/sh -e
+#!/bin/sh
+set -e
 
 if [ "$1" = "purge" ]; then
        if command -v update-inetd >/dev/null 2>&1; then
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uftpd-2.9/debian/prerm new/uftpd-2.10/debian/prerm
--- old/uftpd-2.9/debian/prerm  2019-07-29 10:53:23.000000000 +0200
+++ new/uftpd-2.10/debian/prerm 2019-08-15 09:20:03.000000000 +0200
@@ -1,4 +1,6 @@
-#!/bin/sh -e
+#!/bin/sh
+
+set -e
 
 update-inetd --pattern 'in.ftpd' --multi --disable ftp
 update-inetd --pattern 'in.tftpd' --multi --disable tftp
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uftpd-2.9/man/uftpd.8 new/uftpd-2.10/man/uftpd.8
--- old/uftpd-2.9/man/uftpd.8   2019-07-29 10:53:23.000000000 +0200
+++ new/uftpd-2.10/man/uftpd.8  2019-08-15 09:20:03.000000000 +0200
@@ -13,9 +13,9 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd Jul 29, 2019
+.Dd Aug 12, 2019
 .Dt UFTPD 8
-.Os "uftpd (2.9)"
+.Os "uftpd (2.10)"
 .Sh NAME
 .Nm uftpd
 .Nd
@@ -23,7 +23,7 @@
 .Sh SYNOPSIS
 .Nm
 .Op Fl hnsv
-.Op Fl l Ar LVL
+.Op Fl l Ar LOG
 .Op Fl o Ar ftp=PORT,tftp=PORT,writable
 .Op Ar PATH
 .Sh DESCRIPTION
@@ -50,7 +50,7 @@
 .Bl -tag -width Ds
 .It Fl h
 Show built-in help text
-.It Fl l Ar LVL
+.It Fl l Ar LOG
 Set log level: none, err, info,
 .Ar notice ,
 debug
@@ -130,7 +130,7 @@
 The FTP server currently supports the following requests.
 The case of the requests is ignored.
 .Bl -column "Request" -offset indent
-.It Request Ta "Description"
+.It Sy Request Ta Sy "Description"
 .It ABOR Ta "abort current transfer"
 .It CDUP Ta "shorthand for CD .. command"
 .It CWD Ta "change working directory"
@@ -174,15 +174,18 @@
 .Pp
 The TFTP server currently supports the following requests.
 .Bl -column "Request" -offset indent
-.It RRQ
-.It ERROR
-.It ACK
+.It Sy Request Ta Sy Description
+.It RRQ     Ta Read Request for file, may have options
+.It WRQ     Ta Write Request for file, may have options
+.It DATA    Ta File data, preceeded by block n:o
+.It ERROR   Ta Error, end of session
+.It ACK     Ta ACKnowledge DATA or WRQ without options
+.It OACK    Ta Option acknowleged, sent as response to RRQ/WRQ
 .El
 .Pp
 .Nm
 supports TFTP blocksize negotiation, according to RFC2348, so full sized
-Ethernet frames can be used, which greatly speeds up transfers.  Support
-for WRQ is not yet implemented, patches welcome!
+Ethernet frames can be used, which greatly speeds up transfers.
 .Pp
 .Sh FILES
 .Bl -tag -width /etc/ftpwelcome -compact
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uftpd-2.9/src/ftpcmd.c new/uftpd-2.10/src/ftpcmd.c
--- old/uftpd-2.9/src/ftpcmd.c  2019-07-29 10:53:23.000000000 +0200
+++ new/uftpd-2.10/src/ftpcmd.c 2019-08-15 09:20:03.000000000 +0200
@@ -127,7 +127,7 @@
                *cmd      = msg;
                *argument = NULL;
 
-               DBG("Recv: [%s], %d bytes", msg, bytes);
+               DBG("Recv: [%s], %zd bytes", msg, bytes);
 
                return 0;
        }
@@ -1023,7 +1023,7 @@
 
        gettimeofday(&tv, NULL);
        if (tv.tv_sec - ctrl->tv.tv_sec > 3) {
-               DBG("Sending %d bytes of %s to %s ...", num, ctrl->file, 
ctrl->clientaddr);
+               DBG("Sending %zd bytes of %s to %s ...", num, ctrl->file, 
ctrl->clientaddr);
                ctrl->tv.tv_sec = tv.tv_sec;
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uftpd-2.9/src/tftpcmd.c new/uftpd-2.10/src/tftpcmd.c
--- old/uftpd-2.9/src/tftpcmd.c 2019-07-29 10:53:23.000000000 +0200
+++ new/uftpd-2.10/src/tftpcmd.c        2019-08-15 09:20:03.000000000 +0200
@@ -19,6 +19,28 @@
 #include <poll.h>
 #include <arpa/tftp.h>
 
+/*
+ * Theory of operation, from RFC1350:
+ *
+ * Client gets file, RRQ:
+ *
+ *      client                     server
+ *        |----------- RRQ ---------->|
+ *        |<--------- DATA -----------|
+ *        |----------- ACK ---------->|
+ *        |                           |
+ *
+ * Client puts file, WRQ:
+ *
+ *      client                     server
+ *        |----------- WRQ ---------->|
+ *        |<---------- ACK -----------|
+ *        |---------- DATA ---------->|
+ *        |<---------- ACK -----------|
+ *        |                           |
+ *
+ */
+
 /* Send @len bytes data in @ctrl->buf */
 static int do_send(ctrl_t *ctrl, size_t len)
 {
@@ -32,7 +54,7 @@
        if (ctrl->th->th_opcode == OACK)
                hdrsz = ctrl->th->th_stuff - ctrl->buf;
 
-       DBG("tftp sending %zd + %zd bytes ...", hdrsz, len);
+       DBG("SND %c: header size: %zd, data len: %zd ...", ctrl->th->th_code, 
hdrsz, len);
        result = sendto(ctrl->sd, ctrl->buf, hdrsz + len, 0, (struct sockaddr 
*)&ctrl->client_sa, salen);
        if (-1 == result)
                return 1;
@@ -67,21 +89,22 @@
        return do_send(ctrl, len);
 }
 
-#if 0 /* TODO, for client op */
-static int send_ACK(ctrl_t *ctrl)
+static int send_ACK(ctrl_t *ctrl, int block)
 {
-       return 0;
+       memset(ctrl->buf, 0, ctrl->bufsz);
+
+       ctrl->th->th_opcode = htons(ACK);
+       ctrl->th->th_block  = htons(block);
+       DBG("ACK block %d", block);
+
+       return do_send(ctrl, 4);
 }
-#endif
 
 /* Acknowledge options sent by client */
 static int send_OACK(ctrl_t *ctrl)
 {
        char *ptr;
 
-       if (!ctrl->tftp_options)
-               return 0;
-
        memset(ctrl->buf, 0, ctrl->bufsz);
 
        /* Create message */
@@ -99,10 +122,13 @@
        return do_send(ctrl, ptr - ctrl->buf);
 }
 
-static int send_ERROR(ctrl_t *ctrl, int code)
+static int send_ERROR(ctrl_t *ctrl, int code, char *str)
 {
-       char   *str = strerror(code);
-       size_t  len = strlen(str);
+       size_t len;
+
+       if (!str)
+               str = strerror(code);
+       len = strlen(str);
 
        memset(ctrl->buf, 0, ctrl->segsize);
 
@@ -110,6 +136,7 @@
        ctrl->th->th_opcode = htons(ERROR);
        ctrl->th->th_code   = htons(code);
        strlcpy(ctrl->th->th_msg, str, len);
+       DBG("ERR %d: %s", code, str);
 
        /* Error is ASCIIZ string, hence +1 */
        return do_send(ctrl, len + 1);
@@ -138,15 +165,15 @@
        return 0;
 }
 
-/* Parse TFTP payload in RRQ to get filename and optional blksize & timeout */
-static int parse_RRQ(ctrl_t *ctrl, char *buf, size_t len)
+/* Parse TFTP payload in WRQ/RRQ for filename and optional blksize+timeout */
+static int parse_RWRQ(ctrl_t *ctrl, char *buf, size_t len)
 {
        size_t opt_len = strlen(buf) + 1;
 
        /* First opt is always filename */
        ctrl->file = strdup(buf);
        if (!ctrl->file)
-               return send_ERROR(ctrl, ENOMEM);
+               return send_ERROR(ctrl, EUNDEF, NULL);
 
        do {
                /* Prepare to read options */
@@ -167,13 +194,17 @@
 
                        if (alloc_buf(ctrl, sz)) {
                                ERR(errno, "Failed reallocating TFTP buffer 
memory");
-                               return send_ERROR(ctrl, ENOMEM);
+                               return send_ERROR(ctrl, EUNDEF, NULL);
                        }
 
+                       DBG("Negotiated blksize %zd", sz);
                        setbit(&ctrl->tftp_options, 1);
                }
        } while (len);
 
+       if (!ctrl->tftp_options)
+               return 0;
+
        return send_OACK(ctrl);
 }
 
@@ -184,18 +215,67 @@
        path = compose_path(ctrl, ctrl->file);
        if (!path) {
                ERR(errno, "%s: Invalid path to file %s", ctrl->clientaddr, 
ctrl->file);
-               return send_ERROR(ctrl, ENOTFOUND);
+               return send_ERROR(ctrl, ENOTFOUND, NULL);
        }
 
        ctrl->fp = fopen(path, "r");
        if (!ctrl->fp) {
                ERR(errno, "%s: Failed opening %s", ctrl->clientaddr, path);
-               return send_ERROR(ctrl, ENOTFOUND);
+               return send_ERROR(ctrl, ENOTFOUND, NULL);
        }
 
        return !send_DATA(ctrl, 0);
 }
 
+static int handle_WRQ(ctrl_t *ctrl)
+{
+       char *path;
+
+       path = compose_path(ctrl, ctrl->file);
+       if (!path) {
+               ERR(errno, "%s: Invalid path to file %s", ctrl->clientaddr, 
ctrl->file);
+               return send_ERROR(ctrl, ENOTFOUND, NULL);
+       }
+
+       ctrl->offset = 1;       /* First expected block */
+       ctrl->fp = fopen(path, "w");
+       if (!ctrl->fp) {
+               ERR(errno, "%s: Failed opening %s", ctrl->clientaddr, path);
+               return send_ERROR(ctrl, ENOTFOUND, NULL);
+       }
+
+       if (ctrl->tftp_options)
+               return 0;
+
+       return send_ACK(ctrl, 0);
+}
+
+static int handle_DATA(ctrl_t *ctrl, size_t len)
+{
+       char errmsg[80];
+       int block;
+
+       block = ntohs(ctrl->th->th_block);
+       if (block != ctrl->offset) {
+               snprintf(errmsg, sizeof(errmsg), "Expected block %ld, "
+                        "got DATA for block %d", ctrl->offset, block);
+               return !send_ERROR(ctrl, EUNDEF, errmsg);
+       }
+
+       DBG("tftp block %d writing %zd bytes ...", ctrl->th->th_block, len);
+       if (len != fwrite(ctrl->th->th_data, sizeof(char), len, ctrl->fp)) {
+               snprintf(errmsg, sizeof(errmsg), "Failed writing file: %s",
+                        strerror(errno));
+               return !send_ERROR(ctrl, ENOSPACE, errmsg);
+       }
+
+       ctrl->offset++;
+       if (send_ACK(ctrl, block) || len < ctrl->segsize)
+               return 0;
+
+       return 1;
+}
+
 /* TODO: Add support for ACK timeout and resend */
 static int handle_ACK(ctrl_t *ctrl, int block)
 {
@@ -243,7 +323,7 @@
        switch (op) {
        case RRQ:
                len -= ctrl->th->th_stuff - ctrl->buf;
-               if (parse_RRQ(ctrl, ctrl->th->th_stuff, len)) {
+               if (parse_RWRQ(ctrl, ctrl->th->th_stuff, len)) {
                        ERR(errno, "Failed parsing TFTP RRQ");
                        active = 0;
                        break;
@@ -253,12 +333,30 @@
                free(ctrl->file);
                break;
 
+       case WRQ:
+               len -= ctrl->th->th_stuff - ctrl->buf;
+               if (parse_RWRQ(ctrl, ctrl->th->th_stuff, len)) {
+                       ERR(errno, "Failed parsing TFTP WRQ");
+                       active = 0;
+                       break;
+               }
+               DBG("tftp WRQ %s from %s:%d", ctrl->file, ctrl->clientaddr, 
port);
+               handle_WRQ(ctrl);
+               free(ctrl->file);
+               break;
+
+       case DATA:              /* Received data after WRQ */
+               DBG("tftp DATA %s from %s:%d", ctrl->file, ctrl->clientaddr, 
port);
+               len -= ctrl->th->th_data - ctrl->buf;
+               active = handle_DATA(ctrl, len);
+               break;
+
        case ERROR:
                DBG("tftp ERROR: %hd", ntohs(ctrl->th->th_code));
                active = 0;
                break;
 
-       case ACK:
+       case ACK:               /* Sent for each DATA we send in a RRQ */
                DBG("tftp ACK, block # %hu", block);
                active = handle_ACK(ctrl, block);
                break;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uftpd-2.9/src/uftpd.h new/uftpd-2.10/src/uftpd.h
--- old/uftpd-2.9/src/uftpd.h   2019-07-29 10:53:23.000000000 +0200
+++ new/uftpd-2.10/src/uftpd.h  2019-08-15 09:20:03.000000000 +0200
@@ -126,7 +126,7 @@
        char     pending;       /* Pending op: LIST, RETR, STOR */
        char     list_mode;     /* Current LIST mode */
        char    *file;          /* Current file name to fetch */
-       off_t    offset;        /* Offset in current file, for REST */
+       off_t    offset;        /* Offset/block in current file, for REST/WRQ */
        FILE    *fp;            /* Current file in operation */
        int      i;             /* i of d_num in 'd' */
        int      d_num;         /* Number of entries in 'd' */


Reply via email to