Updated to apply cleanly.
[rsync-patches.git] / owner-group-mod.diff
1 This patch implements an idiom where two -o options cause rsync
2 to try to set the owner information even if we're not running as
3 UID 0.  Similarly, two -g options cause rsync to try to set all
4 groups, even if they weren't returned by getgroups().  E.g.:
5
6     rsync -avoogg host:/from/ /to/
7
8 --- orig/compat.c       2005-02-01 10:39:22
9 +++ compat.c    2004-09-09 01:59:08
10 @@ -28,8 +28,11 @@
11  int remote_protocol = 0;
12  
13  extern int verbose;
14 +extern int am_root;
15  extern int am_server;
16  extern int am_sender;
17 +extern int preserve_uid;
18 +extern int preserve_gid;
19  extern int read_batch;
20  extern int checksum_seed;
21  extern int protocol_version;
22 @@ -81,4 +84,11 @@ void setup_protocol(int f_out,int f_in)
23         } else {
24                 checksum_seed = read_int(f_in);
25         }
26 +
27 +       if (am_root) {
28 +               if (preserve_uid)
29 +                       preserve_uid = 2;
30 +               if (preserve_gid)
31 +                       preserve_gid = 2;
32 +       }
33  }
34 --- orig/options.c      2005-02-01 10:39:22
35 +++ options.c   2004-09-09 01:59:08
36 @@ -384,8 +384,8 @@ static struct poptOption long_options[] 
37    {"no-whole-file",    0,  POPT_ARG_VAL,    &whole_file, 0, 0, 0 },
38    {"copy-unsafe-links", 0, POPT_ARG_NONE,   &copy_unsafe_links, 0, 0, 0 },
39    {"perms",           'p', POPT_ARG_NONE,   &preserve_perms, 0, 0, 0 },
40 -  {"owner",           'o', POPT_ARG_NONE,   &preserve_uid, 0, 0, 0 },
41 -  {"group",           'g', POPT_ARG_NONE,   &preserve_gid, 0, 0, 0 },
42 +  {"owner",           'o', POPT_ARG_NONE,   0,               'o', 0, 0 },
43 +  {"group",           'g', POPT_ARG_NONE,   0,               'g', 0, 0 },
44    {"devices",         'D', POPT_ARG_NONE,   &preserve_devices, 0, 0, 0 },
45    {"times",           't', POPT_ARG_NONE,   &preserve_times, 0, 0, 0 },
46    {"omit-dir-times",  'O', POPT_ARG_NONE,   &omit_dir_times, 0, 0, 0 },
47 @@ -690,6 +690,14 @@ int parse_arguments(int *argc, const cha
48                         usage(FINFO);
49                         exit_cleanup(0);
50  
51 +               case 'o':
52 +                       preserve_uid++;
53 +                       break;
54 +
55 +               case 'g':
56 +                       preserve_gid++;
57 +                       break;
58 +
59                 case 'v':
60                         verbose++;
61                         break;
62 @@ -901,8 +909,8 @@ int parse_arguments(int *argc, const cha
63  #endif
64                 preserve_perms = 1;
65                 preserve_times = 1;
66 -               preserve_gid = 1;
67 -               preserve_uid = 1;
68 +               preserve_uid |= 1;
69 +               preserve_gid |= 1;
70                 preserve_devices = 1;
71         }
72  
73 @@ -1144,10 +1152,16 @@ void server_options(char **args,int *arg
74  
75         if (preserve_hard_links)
76                 argstr[x++] = 'H';
77 -       if (preserve_uid)
78 +       if (preserve_uid) {
79                 argstr[x++] = 'o';
80 -       if (preserve_gid)
81 +               if (preserve_uid > 1)
82 +                       argstr[x++] = 'o';
83 +       }
84 +       if (preserve_gid) {
85                 argstr[x++] = 'g';
86 +               if (preserve_gid > 1)
87 +                       argstr[x++] = 'g';
88 +       }
89         if (preserve_devices)
90                 argstr[x++] = 'D';
91         if (preserve_times)
92 --- orig/rsync.c        2005-02-01 10:39:22
93 +++ rsync.c     2005-02-01 10:46:04
94 @@ -26,7 +26,6 @@ extern int verbose;
95  extern int dry_run;
96  extern int preserve_times;
97  extern int omit_dir_times;
98 -extern int am_root;
99  extern int am_server;
100  extern int am_sender;
101  extern int am_generator;
102 @@ -181,7 +180,7 @@ int set_perms(char *fname,struct file_st
103                 updated = 1;
104         }
105  
106 -       change_uid = am_root && preserve_uid && st->st_uid != file->uid;
107 +       change_uid = preserve_uid > 1 && st->st_uid != file->uid;
108         change_gid = preserve_gid && file->gid != GID_NONE
109                 && st->st_gid != file->gid;
110  #if !HAVE_LCHOWN && !CHOWN_MODIFIES_SYMLINK
111 --- orig/uidlist.c      2005-01-28 19:08:20
112 +++ uidlist.c   2004-09-09 01:59:08
113 @@ -35,7 +35,6 @@ extern int verbose;
114  extern int preserve_uid;
115  extern int preserve_gid;
116  extern int numeric_ids;
117 -extern int am_root;
118  
119  struct idlist {
120         struct idlist *next;
121 @@ -177,7 +176,7 @@ static struct idlist *recv_add_gid(int i
122         int id2 = name ? map_gid(id, name) : id;
123         struct idlist *node;
124  
125 -       if (!am_root && !is_in_group(id2))
126 +       if (preserve_gid < 2 && !is_in_group(id2))
127                 id2 = GID_NONE;
128         node = add_to_list(&gidlist, id, name, id2);
129  
130 @@ -339,11 +338,11 @@ void recv_uid_list(int f, struct file_li
131  
132         /* now convert the uid/gid of all files in the list to the mapped
133          * uid/gid */
134 -       if (am_root && preserve_uid && !numeric_ids) {
135 +       if (preserve_uid > 1 && !numeric_ids) {
136                 for (i = 0; i < flist->count; i++)
137                         flist->files[i]->uid = match_uid(flist->files[i]->uid);
138         }
139 -       if (preserve_gid && (!am_root || !numeric_ids)) {
140 +       if (preserve_gid && (preserve_gid < 2 || !numeric_ids)) {
141                 for (i = 0; i < flist->count; i++)
142                         flist->files[i]->gid = match_gid(flist->files[i]->gid);
143         }