Fix handling of skipped elements on the very first element transmitted.
authorclaudio <claudio@openbsd.org>
Wed, 27 Dec 2023 17:22:25 +0000 (17:22 +0000)
committerclaudio <claudio@openbsd.org>
Wed, 27 Dec 2023 17:22:25 +0000 (17:22 +0000)
rsync compares e.g. the first mtime against 0, if the mtime is the epoch
then rsync will skip this field and openrsync will choke when receiving it.
So if there is no first element but a FLIST_XYZ_SAME flag is use 0 as
value.
Problem noticed by job@
OK tb@ job@ and yoda@ for fixing the if statements

usr.bin/rsync/flist.c

index 2b79f34..cdc9f1d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: flist.c,v 1.37 2022/12/26 19:16:02 jmc Exp $ */
+/*     $OpenBSD: flist.c,v 1.38 2023/12/27 17:22:25 claudio Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2019 Florian Obser <florian@openbsd.org>
@@ -442,7 +442,7 @@ flist_recv_name(struct sess *sess, int fd, struct flist *f, uint8_t flags,
         * than byte-size.
         */
 
-       if (FLIST_NAME_SAME & flags) {
+       if (flags & FLIST_NAME_SAME) {
                if (!io_read_byte(sess, fd, &bval)) {
                        ERRX1("io_read_byte");
                        return 0;
@@ -452,7 +452,7 @@ flist_recv_name(struct sess *sess, int fd, struct flist *f, uint8_t flags,
 
        /* Get the (possibly-remaining) filename length. */
 
-       if (FLIST_NAME_LONG & flags) {
+       if (flags & FLIST_NAME_LONG) {
                if (!io_read_size(sess, fd, &pathlen)) {
                        ERRX1("io_read_size");
                        return 0;
@@ -479,7 +479,7 @@ flist_recv_name(struct sess *sess, int fd, struct flist *f, uint8_t flags,
        }
        f->path[len] = '\0';
 
-       if (FLIST_NAME_SAME & flags)
+       if (flags & FLIST_NAME_SAME)
                memcpy(f->path, last, partial);
 
        if (!io_read_buf(sess, fd, f->path + partial, pathlen)) {
@@ -633,44 +633,41 @@ flist_recv(struct sess *sess, int fd, struct flist **flp, size_t *sz)
 
                /* Read the modification time. */
 
-               if (!(FLIST_TIME_SAME & flag)) {
+               if (!(flag & FLIST_TIME_SAME)) {
                        if (!io_read_uint(sess, fd, &uival)) {
                                ERRX1("io_read_uint");
                                goto out;
                        }
                        ff->st.mtime = uival;   /* beyond 2038 */
                } else if (fflast == NULL) {
-                       ERRX("same time without last entry");
-                       goto out;
+                       ff->st.mtime = 0;
                }  else
                        ff->st.mtime = fflast->st.mtime;
 
                /* Read the file mode. */
 
-               if (!(FLIST_MODE_SAME & flag)) {
+               if (!(flag & FLIST_MODE_SAME)) {
                        if (!io_read_uint(sess, fd, &uival)) {
                                ERRX1("io_read_uint");
                                goto out;
                        }
                        ff->st.mode = uival;
                } else if (fflast == NULL) {
-                       ERRX("same mode without last entry");
-                       goto out;
+                       ff->st.mode = 0;
                } else
                        ff->st.mode = fflast->st.mode;
 
                /* Conditional part: uid. */
 
                if (sess->opts->preserve_uids) {
-                       if (!(FLIST_UID_SAME & flag)) {
+                       if (!(flag & FLIST_UID_SAME)) {
                                if (!io_read_uint(sess, fd, &uival)) {
                                        ERRX1("io_read_int");
                                        goto out;
                                }
                                ff->st.uid = uival;
                        } else if (fflast == NULL) {
-                               ERRX("same uid without last entry");
-                               goto out;
+                               ff->st.uid = 0;
                        } else
                                ff->st.uid = fflast->st.uid;
                }
@@ -678,15 +675,14 @@ flist_recv(struct sess *sess, int fd, struct flist **flp, size_t *sz)
                /* Conditional part: gid. */
 
                if (sess->opts->preserve_gids) {
-                       if (!(FLIST_GID_SAME & flag)) {
+                       if (!(flag & FLIST_GID_SAME)) {
                                if (!io_read_uint(sess, fd, &uival)) {
                                        ERRX1("io_read_uint");
                                        goto out;
                                }
                                ff->st.gid = uival;
                        } else if (fflast == NULL) {
-                               ERRX("same gid without last entry");
-                               goto out;
+                               ff->st.gid = 0;
                        } else
                                ff->st.gid = fflast->st.gid;
                }
@@ -697,15 +693,14 @@ flist_recv(struct sess *sess, int fd, struct flist **flp, size_t *sz)
                    S_ISCHR(ff->st.mode))) ||
                    (sess->opts->specials && (S_ISFIFO(ff->st.mode) ||
                    S_ISSOCK(ff->st.mode)))) {
-                       if (!(FLIST_RDEV_SAME & flag)) {
+                       if (!(flag & FLIST_RDEV_SAME)) {
                                if (!io_read_int(sess, fd, &ival)) {
                                        ERRX1("io_read_int");
                                        goto out;
                                }
                                ff->st.rdev = ival;
                        } else if (fflast == NULL) {
-                               ERRX("same device without last entry");
-                               goto out;
+                               ff->st.rdev = 0;
                        } else
                                ff->st.rdev = fflast->st.rdev;
                }