index a6107b4..83effc0 100644 --- a/flist.c +++ b/flist.c @@ -425,8 +425,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, else mode = file->mode; - if ((preserve_devices && IS_DEVICE(mode)) - || (preserve_specials && IS_SPECIAL(mode))) { + if (preserve_devices && IS_DEVICE(mode)) { if (protocol_version < 28) { if (tmp_rdev == rdev) xflags |= XMIT_SAME_RDEV_pre28; @@ -441,6 +440,17 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, if (protocol_version < 30 && (uint32)minor(rdev) <= 0xFFu) xflags |= XMIT_RDEV_MINOR_8_pre30; } + } else if (preserve_specials && IS_SPECIAL(mode)) { + /* Special files don't need an rdev number, so just make + * the historical transmission of the value efficient. */ + if (protocol_version < 28) + xflags |= XMIT_SAME_RDEV_pre28; + else { + rdev = MAKEDEV(major(rdev), 0); + xflags |= XMIT_SAME_RDEV_MAJOR; + if (protocol_version < 30) + xflags |= XMIT_RDEV_MINOR_8_pre30; + } } else if (protocol_version < 28) rdev = MAKEDEV(0, 0); if (!preserve_uid || ((uid_t)F_OWNER(file) == uid && *lastname)) @@ -725,8 +735,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist, uid = F_OWNER(first); if (preserve_gid) gid = F_GROUP(first); - if ((preserve_devices && IS_DEVICE(mode)) - || (preserve_specials && IS_SPECIAL(mode))) { + if (preserve_devices && IS_DEVICE(mode)) { uint32 *devp = F_RDEV_P(first); rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)); extra_len += DEV_EXTRA_CNT * EXTRA_LEN; @@ -801,7 +810,8 @@ static struct file_struct *recv_file_entry(struct file_list *flist, rdev_minor = read_int(f); rdev = MAKEDEV(rdev_major, rdev_minor); } - extra_len += DEV_EXTRA_CNT * EXTRA_LEN; + if (IS_DEVICE(mode)) + extra_len += DEV_EXTRA_CNT * EXTRA_LEN; file_length = 0; } else if (protocol_version < 28) rdev = MAKEDEV(0, 0); @@ -942,8 +952,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist, } } - if ((preserve_devices && IS_DEVICE(mode)) - || (preserve_specials && IS_SPECIAL(mode))) { + if (preserve_devices && IS_DEVICE(mode)) { uint32 *devp = F_RDEV_P(file); DEV_MAJOR(devp) = major(rdev); DEV_MINOR(devp) = minor(rdev); @@ -1257,10 +1266,11 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, #endif #ifdef HAVE_STRUCT_STAT_ST_RDEV - if (IS_DEVICE(st.st_mode) || IS_SPECIAL(st.st_mode)) { + if (IS_DEVICE(st.st_mode)) { tmp_rdev = st.st_rdev; st.st_size = 0; - } + } else if (IS_SPECIAL(st.st_mode)) + st.st_size = 0; #endif file->flags = flags; index 6c7bf89..fb832af 100644 --- a/generator.c +++ b/generator.c @@ -1124,8 +1124,8 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx, } switch (type) { case TYPE_DIR: - break; case TYPE_SPECIAL: + break; case TYPE_DEVICE: devp = F_RDEV_P(file); if (sxp->st.st_rdev != MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp))) @@ -1613,8 +1613,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, if ((am_root && preserve_devices && IS_DEVICE(file->mode)) || (preserve_specials && IS_SPECIAL(file->mode))) { - uint32 *devp = F_RDEV_P(file); - dev_t rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)); + dev_t rdev; + if (IS_DEVICE(file->mode)) { + uint32 *devp = F_RDEV_P(file); + rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)); + } else + rdev = 0; if (statret == 0) { int del_for_flag; if (IS_DEVICE(file->mode)) { @@ -1628,7 +1632,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, } if (statret == 0 && BITS_EQUAL(sx.st.st_mode, file->mode, _S_IFMT) - && sx.st.st_rdev == rdev) { + && (IS_SPECIAL(sx.st.st_mode) || sx.st.st_rdev == rdev)) { /* The device or special file is identical. */ set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT); if (itemizing) index 674d357..63b118a 100644 --- a/xattrs.c +++ b/xattrs.c @@ -989,7 +989,7 @@ int set_stat_xattr(const char *fname, struct file_struct *file, mode_t new_mode) fst.st_mode &= (_S_IFMT | CHMOD_BITS); fmode = new_mode & (_S_IFMT | CHMOD_BITS); - if (IS_DEVICE(fmode) || IS_SPECIAL(fmode)) { + if (IS_DEVICE(fmode)) { uint32 *devp = F_RDEV_P(file); rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)); } else @@ -1000,7 +1000,7 @@ int set_stat_xattr(const char *fname, struct file_struct *file, mode_t new_mode) | (S_ISDIR(fst.st_mode) ? 0700 : 0600); if (fst.st_mode != mode) do_chmod(fname, mode); - if (!IS_DEVICE(fst.st_mode) && !IS_SPECIAL(fst.st_mode)) + if (!IS_DEVICE(fst.st_mode)) fst.st_rdev = 0; /* just in case */ if (mode == fmode && fst.st_rdev == rdev