A working implementation that uses a pthread to start the receiver
[rsync/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-11-14 21:24:47
9 +++ compat.c    2005-12-03 01:28:51
10 @@ -28,11 +28,14 @@
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 inplace;
18  extern int fuzzy_basis;
19  extern int read_batch;
20 +extern int preserve_uid;
21 +extern int preserve_gid;
22  extern int checksum_seed;
23  extern int basis_dir_cnt;
24  extern int protocol_version;
25 @@ -107,4 +110,11 @@ void setup_protocol(int f_out,int f_in)
26         } else {
27                 checksum_seed = read_int(f_in);
28         }
29 +
30 +       if (am_root) {
31 +               if (preserve_uid)
32 +                       preserve_uid = 3;
33 +               if (preserve_gid)
34 +                       preserve_gid = 3;
35 +       }
36  }
37 --- orig/options.c      2005-11-15 18:21:22
38 +++ options.c   2005-12-03 01:28:45
39 @@ -404,10 +404,10 @@ static struct poptOption long_options[] 
40    {"no-t",             0,  POPT_ARG_VAL,    &preserve_times, 0, 0, 0 },
41    {"omit-dir-times",  'O', POPT_ARG_VAL,    &omit_dir_times, 2, 0, 0 },
42    {"modify-window",    0,  POPT_ARG_INT,    &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
43 -  {"owner",           'o', POPT_ARG_VAL,    &preserve_uid, 1, 0, 0 },
44 +  {"owner",           'o', POPT_ARG_NONE,   0, 'o', 0, 0 },
45    {"no-owner",         0,  POPT_ARG_VAL,    &preserve_uid, 0, 0, 0 },
46    {"no-o",             0,  POPT_ARG_VAL,    &preserve_uid, 0, 0, 0 },
47 -  {"group",           'g', POPT_ARG_VAL,    &preserve_gid, 1, 0, 0 },
48 +  {"group",           'g', POPT_ARG_NONE,   0, 'g', 0, 0 },
49    {"no-group",         0,  POPT_ARG_VAL,    &preserve_gid, 0, 0, 0 },
50    {"no-g",             0,  POPT_ARG_VAL,    &preserve_gid, 0, 0, 0 },
51    {"devices",         'D', POPT_ARG_VAL,    &preserve_devices, 1, 0, 0 },
52 @@ -872,8 +872,8 @@ int parse_arguments(int *argc, const cha
53  #endif
54                         preserve_perms = 1;
55                         preserve_times = 1;
56 -                       preserve_gid = 1;
57 -                       preserve_uid = 1;
58 +                       preserve_uid |= 1;
59 +                       preserve_gid |= 1;
60                         preserve_devices = 1;
61                         break;
62  
63 @@ -881,6 +881,14 @@ int parse_arguments(int *argc, const cha
64                         usage(FINFO);
65                         exit_cleanup(0);
66  
67 +               case 'o':
68 +                       preserve_uid += 2;
69 +                       break;
70 +
71 +               case 'g':
72 +                       preserve_gid += 2;
73 +                       break;
74 +
75                 case 'v':
76                         verbose++;
77                         break;
78 @@ -1432,10 +1440,16 @@ void server_options(char **args,int *arg
79  
80         if (preserve_hard_links)
81                 argstr[x++] = 'H';
82 -       if (preserve_uid)
83 +       if (preserve_uid) {
84                 argstr[x++] = 'o';
85 -       if (preserve_gid)
86 +               if (preserve_uid > 2)
87 +                       argstr[x++] = 'o';
88 +       }
89 +       if (preserve_gid) {
90                 argstr[x++] = 'g';
91 +               if (preserve_gid > 2)
92 +                       argstr[x++] = 'g';
93 +       }
94         if (preserve_devices)
95                 argstr[x++] = 'D';
96         if (preserve_times)
97 --- orig/rsync.c        2005-07-27 23:31:12
98 +++ rsync.c     2005-12-03 01:29:17
99 @@ -27,7 +27,6 @@ extern int dry_run;
100  extern int daemon_log_format_has_i;
101  extern int preserve_times;
102  extern int omit_dir_times;
103 -extern int am_root;
104  extern int am_server;
105  extern int am_sender;
106  extern int am_generator;
107 @@ -82,7 +81,7 @@ int set_perms(char *fname,struct file_st
108                         updated = 1;
109         }
110  
111 -       change_uid = am_root && preserve_uid && st->st_uid != file->uid;
112 +       change_uid = preserve_uid > 2 && st->st_uid != file->uid;
113         change_gid = preserve_gid && file->gid != GID_NONE
114                 && st->st_gid != file->gid;
115  #if !defined HAVE_LCHOWN && !defined CHOWN_MODIFIES_SYMLINK
116 --- orig/uidlist.c      2005-11-10 16:58:36
117 +++ uidlist.c   2005-12-03 01:29:52
118 @@ -35,7 +35,6 @@ extern int verbose;
119  extern int preserve_uid;
120  extern int preserve_gid;
121  extern int numeric_ids;
122 -extern int am_root;
123  
124  struct idlist {
125         struct idlist *next;
126 @@ -177,7 +176,7 @@ static struct idlist *recv_add_gid(int i
127         int id2 = name ? map_gid(id, name) : id;
128         struct idlist *node;
129  
130 -       if (!am_root && !is_in_group(id2))
131 +       if (preserve_gid < 3 && !is_in_group(id2))
132                 id2 = GID_NONE;
133         node = add_to_list(&gidlist, id, name, id2);
134  
135 @@ -338,11 +337,11 @@ void recv_uid_list(int f, struct file_li
136  
137         /* now convert the uid/gid of all files in the list to the mapped
138          * uid/gid */
139 -       if (am_root && preserve_uid && !numeric_ids) {
140 +       if (preserve_uid > 2 && !numeric_ids) {
141                 for (i = 0; i < flist->count; i++)
142                         flist->files[i]->uid = match_uid(flist->files[i]->uid);
143         }
144 -       if (preserve_gid && (!am_root || !numeric_ids)) {
145 +       if (preserve_gid && (preserve_gid < 3 || !numeric_ids)) {
146                 for (i = 0; i < flist->count; i++)
147                         flist->files[i]->gid = match_gid(flist->files[i]->gid);
148         }