Promoted to rsync.
authorWayne Davison <wayne@opencoder.net>
Sun, 27 Mar 2022 21:39:45 +0000 (14:39 -0700)
committerWayne Davison <wayne@opencoder.net>
Sun, 27 Mar 2022 21:39:45 +0000 (14:39 -0700)
copy-devices.diff [deleted file]

diff --git a/copy-devices.diff b/copy-devices.diff
deleted file mode 100644 (file)
index 1fe9868..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-This patch adds the --copy-devices option, which will try to copy
-the data inside a device instead of duplicating the device node.
-
-To use this patch, run these commands for a successful build:
-
-    patch -p1 <patches/copy-devices.diff
-    ./prepare-source
-    ./configure                      (optional if already run)
-    make
-
-based-on: 8977815f5d70d1b6747837b41e7e0b5bd672ef01
-diff --git a/flist.c b/flist.c
---- a/flist.c
-+++ b/flist.c
-@@ -43,6 +43,7 @@ extern int use_qsort;
- extern int xfer_dirs;
- extern int filesfrom_fd;
- extern int one_file_system;
-+extern int copy_devices;
- extern int copy_dirlinks;
- extern int preserve_uid;
- extern int preserve_gid;
-@@ -700,6 +701,7 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
-       int alloc_len, basename_len, linkname_len;
-       int extra_len = file_extra_cnt * EXTRA_LEN;
-       int first_hlink_ndx = -1;
-+      char real_ISREG_entry;
-       int64 file_length;
- #ifdef CAN_SET_NSEC
-       uint32 modtime_nsec;
-@@ -814,6 +816,7 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
-                               linkname_len = strlen(F_SYMLINK(first)) + 1;
-                       else
-                               linkname_len = 0;
-+                      real_ISREG_entry = S_ISREG(mode) ? 1 : 0;
-                       goto create_object;
-               }
-       }
-@@ -941,10 +944,20 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
- #endif
-               linkname_len = 0;
-+      if (copy_devices && IS_DEVICE(mode)) {
-+              /* This is impossible in the official release, but some pre-release patches
-+               * didn't convert the device into a file before sending, so we'll do it here
-+               * (even though the length is typically 0 and any checksum data is zeros). */
-+              mode = S_IFREG | (mode & ACCESSPERMS);
-+              modtime = time(NULL); /* The mtime on the device is not up-to-date, so set it to "now". */
-+              real_ISREG_entry = 0;
-+      } else
-+              real_ISREG_entry = S_ISREG(mode) ? 1 : 0;
-+
- #ifdef SUPPORT_HARD_LINKS
-   create_object:
-       if (preserve_hard_links) {
--              if (protocol_version < 28 && S_ISREG(mode))
-+              if (protocol_version < 28 && real_ISREG_entry)
-                       xflags |= XMIT_HLINKED;
-               if (xflags & XMIT_HLINKED)
-                       extra_len += (inc_recurse+1) * EXTRA_LEN;
-@@ -1160,8 +1173,8 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
-       }
- #endif
--      if (always_checksum && (S_ISREG(mode) || protocol_version < 28)) {
--              if (S_ISREG(mode))
-+      if (always_checksum && (real_ISREG_entry || protocol_version < 28)) {
-+              if (real_ISREG_entry)
-                       bp = F_SUM(file);
-               else {
-                       /* Prior to 28, we get a useless set of nulls. */
-@@ -1360,6 +1373,18 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
-       linkname_len = 0;
- #endif
-+      if (copy_devices && am_sender && IS_DEVICE(st.st_mode)) {
-+              if (st.st_size == 0) {
-+                      int fd = do_open(fname, O_RDONLY, 0);
-+                      if (fd >= 0) {
-+                              st.st_size = get_device_size(fd, fname);
-+                              close(fd);
-+                      }
-+              }
-+              st.st_mode = S_IFREG | (st.st_mode & ACCESSPERMS);
-+              st.st_mtime = time(NULL); /* The mtime on the device is not up-to-date, so set it to "now". */
-+      }
-+
- #ifdef ST_MTIME_NSEC
-       if (st.ST_MTIME_NSEC && protocol_version >= 31)
-               extra_len += EXTRA_LEN;
-diff --git a/options.c b/options.c
---- a/options.c
-+++ b/options.c
-@@ -47,6 +47,7 @@ int append_mode = 0;
- int keep_dirlinks = 0;
- int copy_dirlinks = 0;
- int copy_links = 0;
-+int copy_devices = 0;
- int write_devices = 0;
- int preserve_links = 0;
- int preserve_hard_links = 0;
-@@ -656,6 +657,7 @@ static struct poptOption long_options[] = {
-   {"no-D",             0,  POPT_ARG_NONE,   0, OPT_NO_D, 0, 0 },
-   {"devices",          0,  POPT_ARG_VAL,    &preserve_devices, 1, 0, 0 },
-   {"no-devices",       0,  POPT_ARG_VAL,    &preserve_devices, 0, 0, 0 },
-+  {"copy-devices",     0,  POPT_ARG_NONE,   &copy_devices, 0, 0, 0 },
-   {"write-devices",    0,  POPT_ARG_VAL,    &write_devices, 1, 0, 0 },
-   {"no-write-devices", 0,  POPT_ARG_VAL,    &write_devices, 0, 0, 0 },
-   {"specials",         0,  POPT_ARG_VAL,    &preserve_specials, 1, 0, 0 },
-@@ -949,6 +951,7 @@ static void set_refuse_options(void)
-                || strcmp("iconv", longName) == 0
-                || strcmp("no-iconv", longName) == 0
-                || strcmp("checksum-seed", longName) == 0
-+               || strcmp("copy-devices", longName) == 0 /* disable wild-match (it gets refused below) */
-                || strcmp("write-devices", longName) == 0 /* disable wild-match (it gets refused below) */
-                || strcmp("log-format", longName) == 0 /* aka out-format (NOT log-file-format) */
-                || strcmp("sender", longName) == 0
-@@ -960,6 +963,7 @@ static void set_refuse_options(void)
-       assert(list_end != NULL);
-       if (am_daemon) { /* Refused by default, but can be accepted via a negated exact match. */
-+              parse_one_refuse_match(0, "copy-devices", list_end);
-               parse_one_refuse_match(0, "write-devices", list_end);
-       }
-@@ -2917,6 +2921,9 @@ void server_options(char **args, int *argc_p)
-       else if (remove_source_files)
-               args[ac++] = "--remove-sent-files";
-+      if (copy_devices && !am_sender)
-+              args[ac++] = "--copy-devices";
-+
-       if (preallocate_files && am_sender)
-               args[ac++] = "--preallocate";
-diff --git a/rsync.1.md b/rsync.1.md
---- a/rsync.1.md
-+++ b/rsync.1.md
-@@ -373,6 +373,8 @@ has its own detailed description later in this manpage.
- --owner, -o              preserve owner (super-user only)
- --group, -g              preserve group
- --devices                preserve device files (super-user only)
-+--copy-devices           copy device contents as a regular file
-+--write-devices          write to devices as files (implies --inplace)
- --specials               preserve special files
- -D                       same as --devices --specials
- --times, -t              preserve modification times
-@@ -385,7 +387,6 @@ has its own detailed description later in this manpage.
- --fake-super             store/recover privileged attrs using xattrs
- --sparse, -S             turn sequences of nulls into sparse blocks
- --preallocate            allocate dest files before writing them
----write-devices          write to devices as files (implies --inplace)
- --dry-run, -n            perform a trial run with no changes made
- --whole-file, -W         copy files whole (w/o delta-xfer algorithm)
- --checksum-choice=STR    choose the checksum algorithm (aka --cc)
-@@ -1473,6 +1474,14 @@ your home directory (remove the '=' for that).
-     The `-D` option is equivalent to "[`--devices`](#opt)
-     [`--specials`](#opt)".
-+0.  `--copy-devices`
-+
-+    This tells rsync to treat a device on the sending side as a regular file,
-+    allowing it to be copied to a normal destination file (or another device
-+    if `--write-devices` was also specifed).
-+
-+    This option is refused by default by an rsync daemon.
-+
- 0.  `--write-devices`
-     This tells rsync to treat a device on the receiving side as a regular file,
-diff --git a/rsyncd.conf.5.md b/rsyncd.conf.5.md
---- a/rsyncd.conf.5.md
-+++ b/rsyncd.conf.5.md
-@@ -933,9 +933,10 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
-     If you are un-refusing the compress option, you may want to match
-     "`!compress*`" if you also want to allow the `--compress-level` option.
--    Note that the "write-devices" option is refused by default, but can be
--    explicitly accepted with "`!write-devices`".  The options "log-file" and
--    "log-file-format" are forcibly refused and cannot be accepted.
-+    Note that the "copy-devices" & "write-devices" options are refused by
-+    default, but they can be explicitly accepted with "`!copy-devices`" and/or
-+    "`!write-devices`".  The options "log-file" and "log-file-format" are
-+    forcibly refused and cannot be accepted.
-     Here are all the options that are not matched by wild-cards:
-diff --git a/sender.c b/sender.c
---- a/sender.c
-+++ b/sender.c
-@@ -37,6 +37,7 @@ extern int io_error;
- extern int flist_eof;
- extern int whole_file;
- extern int allowed_lull;
-+extern int copy_devices;
- extern int preserve_xattrs;
- extern int protocol_version;
- extern int remove_source_files;
-@@ -366,6 +367,15 @@ void send_files(int f_in, int f_out)
-                       exit_cleanup(RERR_FILEIO);
-               }
-+              if (IS_DEVICE(st.st_mode)) {
-+                      if (!copy_devices) {
-+                              rprintf(FERROR, "attempt to copy device contents without --copy-devices\n");
-+                              exit_cleanup(RERR_PROTOCOL);
-+                      }
-+                      if (st.st_size == 0)
-+                              st.st_size = get_device_size(fd, fname);
-+              }
-+
-               if (append_mode > 0 && st.st_size < F_LENGTH(file)) {
-                       rprintf(FWARNING, "skipped diminished file: %s\n",
-                               full_fname(fname));