Moved one fsync() call.
[rsync-patches.git] / omit-dir-changes.diff
1 This patch from Antti Tapaninen added the --omit-dir-changes option, which
2 tells rsync to not affect any attributes on the directories in the transfer.
3
4 To use this patch, run these commands for a successful build:
5
6     patch -p1 <patches/omit-dir-changes.diff
7     ./configure                              (optional if already run)
8     make
9
10 --- old/generator.c
11 +++ new/generator.c
12 @@ -45,6 +45,7 @@ extern int preserve_uid;
13  extern int preserve_gid;
14  extern int preserve_times;
15  extern int omit_dir_times;
16 +extern int omit_dir_changes;
17  extern int delete_mode;
18  extern int delete_before;
19  extern int delete_during;
20 @@ -544,6 +545,7 @@ void itemize(const char *fname, struct f
21                 int keep_time = !preserve_times ? 0
22                     : S_ISDIR(file->mode) ? !omit_dir_times
23                     : !S_ISLNK(file->mode);
24 +               int omit_changes = omit_dir_changes && S_ISDIR(sxp->st.st_mode);
25  
26                 if (S_ISREG(file->mode) && F_LENGTH(file) != sxp->st.st_size)
27                         iflags |= ITEM_REPORT_SIZE;
28 @@ -554,10 +556,11 @@ void itemize(const char *fname, struct f
29                         iflags |= ITEM_REPORT_TIME;
30                 if (!BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS))
31                         iflags |= ITEM_REPORT_PERMS;
32 -               if (preserve_uid && am_root && F_UID(file) != sxp->st.st_uid)
33 +               if (preserve_uid && am_root && !omit_changes
34 +                && F_UID(file) != sxp->st.st_uid)
35                         iflags |= ITEM_REPORT_OWNER;
36 -               if (preserve_gid && F_GID(file) != GID_NONE
37 -                   && sxp->st.st_gid != F_GID(file))
38 +               if (preserve_gid && !omit_changes
39 +                && F_GID(file) != GID_NONE && sxp->st.st_gid != F_GID(file))
40                         iflags |= ITEM_REPORT_GROUP;
41  #ifdef SUPPORT_ACLS
42                 if (preserve_acls && !S_ISLNK(file->mode)) {
43 @@ -1193,7 +1196,7 @@ static void recv_generator(char *fname, 
44                                 statret = -1;
45                         new_root_dir = 0;
46                 }
47 -               if (!preserve_perms) { /* See comment in non-dir code below. */
48 +               if (!preserve_perms || omit_dir_changes) { /* See comment in non-dir code below. */
49                         file->mode = dest_mode(file->mode, sx.st.st_mode,
50                                                dflt_perms, statret == 0);
51                 }
52 --- old/options.c
53 +++ new/options.c
54 @@ -55,6 +55,7 @@ int preserve_uid = 0;
55  int preserve_gid = 0;
56  int preserve_times = 0;
57  int omit_dir_times = 0;
58 +int omit_dir_changes = 0;
59  int update_only = 0;
60  int cvs_exclude = 0;
61  int dry_run = 0;
62 @@ -317,6 +318,7 @@ void usage(enum logcode F)
63    rprintf(F," -D                          same as --devices --specials\n");
64    rprintf(F," -t, --times                 preserve times\n");
65    rprintf(F," -O, --omit-dir-times        omit directories when preserving times\n");
66 +  rprintf(F,"     --omit-dir-changes      omit directories when preserving any attributes\n");
67    rprintf(F,"     --super                 receiver attempts super-user activities\n");
68    rprintf(F," -S, --sparse                handle sparse files efficiently\n");
69    rprintf(F," -n, --dry-run               show what would have been transferred\n");
70 @@ -437,6 +439,7 @@ static struct poptOption long_options[] 
71    {"no-times",         0,  POPT_ARG_VAL,    &preserve_times, 0, 0, 0 },
72    {"no-t",             0,  POPT_ARG_VAL,    &preserve_times, 0, 0, 0 },
73    {"omit-dir-times",  'O', POPT_ARG_VAL,    &omit_dir_times, 2, 0, 0 },
74 +  {"omit-dir-changes", 0,  POPT_ARG_NONE,   &omit_dir_changes, 0, 0, 0 },
75    {"modify-window",    0,  POPT_ARG_INT,    &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
76    {"super",            0,  POPT_ARG_VAL,    &am_root, 2, 0, 0 },
77    {"no-super",         0,  POPT_ARG_VAL,    &am_root, 0, 0, 0 },
78 @@ -1322,6 +1325,9 @@ int parse_arguments(int *argc, const cha
79                         "P *%s", backup_suffix);
80                 parse_rule(&filter_list, backup_dir_buf, 0, 0);
81         }
82 +
83 +       if (omit_dir_changes)
84 +               omit_dir_times = 2;
85         if (make_backups && !backup_dir)
86                 omit_dir_times = 1;
87  
88 @@ -1551,6 +1557,8 @@ void server_options(char **args,int *arg
89                         argstr[x++] = 'm';
90                 if (omit_dir_times == 2)
91                         argstr[x++] = 'O';
92 +               if (omit_dir_changes == 1)
93 +                       args[ac++] = "--omit-dir-changes";
94         } else {
95                 if (copy_links)
96                         argstr[x++] = 'L';
97 --- old/rsync.c
98 +++ new/rsync.c
99 @@ -36,6 +36,7 @@ extern int preserve_perms;
100  extern int preserve_executability;
101  extern int preserve_times;
102  extern int omit_dir_times;
103 +extern int omit_dir_changes;
104  extern int am_root;
105  extern int am_server;
106  extern int am_sender;
107 @@ -275,9 +276,11 @@ int set_file_attrs(char *fname, struct f
108                         updated = 1;
109         }
110  
111 -       change_uid = am_root && preserve_uid && sxp->st.st_uid != F_UID(file);
112 +       change_uid = am_root && preserve_uid && sxp->st.st_uid != F_UID(file)
113 +               && !(omit_dir_changes && S_ISDIR(sxp->st.st_mode));
114         change_gid = preserve_gid && F_GID(file) != GID_NONE
115 -               && sxp->st.st_gid != F_GID(file);
116 +               && sxp->st.st_gid != F_GID(file)
117 +               && !(omit_dir_changes && S_ISDIR(sxp->st.st_mode));
118  #if !defined HAVE_LCHOWN && !defined CHOWN_MODIFIES_SYMLINK
119         if (S_ISLNK(sxp->st.st_mode))
120                 ;