Fixed failing hunks.
[rsync/rsync-patches.git] / id-pair.diff
1 This attempts to accomplish some per-file memory-savings by moving the
2 uid+gid items out of the file-list (since their values are common to
3 multiple file-list entries) and replacing them with an index to an
4 array of structures.
5
6 This only saves 4 bytes per file (not counting the overhead of the array).
7
8 This probably needs a hashing algorithm to be added if the uid+gid list
9 gets to be really large.
10
11 --- old/flist.c
12 +++ new/flist.c
13 @@ -54,6 +54,7 @@ extern int copy_unsafe_links;
14  extern int protocol_version;
15  extern int sanitize_paths;
16  extern struct stats stats;
17 +extern struct id_pair *id_pairs;
18  extern struct file_list *the_file_list;
19  
20  extern char curr_dir[MAXPATHLEN];
21 @@ -347,14 +348,14 @@ static void send_file_entry(struct file_
22                 }
23         } else if (protocol_version < 28)
24                 rdev = MAKEDEV(0, 0);
25 -       if (file->uid == uid)
26 +       if (id_pairs[file->id_ndx].uid == uid)
27                 flags |= XMIT_SAME_UID;
28         else
29 -               uid = file->uid;
30 -       if (file->gid == gid)
31 +               uid = id_pairs[file->id_ndx].uid;
32 +       if (id_pairs[file->id_ndx].gid == gid)
33                 flags |= XMIT_SAME_GID;
34         else
35 -               gid = file->gid;
36 +               gid = id_pairs[file->id_ndx].gid;
37         if (file->modtime == modtime)
38                 flags |= XMIT_SAME_TIME;
39         else
40 @@ -605,8 +606,7 @@ static struct file_struct *receive_file_
41         file->modtime = modtime;
42         file->length = file_length;
43         file->mode = mode;
44 -       file->uid = uid;
45 -       file->gid = gid;
46 +       file->id_ndx = id_pair(uid, gid);
47  
48         if (dirname_len) {
49                 file->dirname = lastdir = bp;
50 @@ -857,8 +857,7 @@ struct file_struct *make_file(char *fnam
51         file->modtime = st.st_mtime;
52         file->length = st.st_size;
53         file->mode = st.st_mode;
54 -       file->uid = st.st_uid;
55 -       file->gid = st.st_gid;
56 +       file->id_ndx = id_pair(st.st_uid, st.st_gid);
57  
58  #ifdef SUPPORT_HARD_LINKS
59         if (flist && flist->hlink_pool) {
60 @@ -926,8 +925,7 @@ struct file_struct *make_file(char *fnam
61                         file->modtime = st2.st_mtime;
62                         file->length = st2.st_size;
63                         file->mode = st2.st_mode;
64 -                       file->uid = st2.st_uid;
65 -                       file->gid = st2.st_gid;
66 +                       file->id_ndx = id_pair(st2.st_uid, st2.st_gid);
67                         file->u.link = NULL;
68                 } else
69                         file->mode = save_mode;
70 @@ -1377,7 +1375,7 @@ struct file_list *recv_file_list(int f)
71         clean_flist(flist, relative_paths, 1);
72  
73         if (f >= 0) {
74 -               recv_uid_list(f, flist);
75 +               recv_uid_list(f);
76  
77                 /* Recv the io_error flag */
78                 if (lp_ignore_errors(module_id) || ignore_errors)
79 @@ -1693,13 +1691,15 @@ static void output_flist(struct file_lis
80  
81         for (i = 0; i < flist->count; i++) {
82                 file = flist->files[i];
83 -               if ((am_root || am_sender) && preserve_uid)
84 -                       sprintf(uidbuf, " uid=%ld", (long)file->uid);
85 -               else
86 +               if ((am_root || am_sender) && preserve_uid) {
87 +                       sprintf(uidbuf, " uid=%ld",
88 +                               (long)id_pairs[file->id_ndx].uid);
89 +               } else
90                         *uidbuf = '\0';
91 -               if (preserve_gid && file->gid != GID_NONE)
92 -                       sprintf(gidbuf, " gid=%ld", (long)file->gid);
93 -               else
94 +               if (preserve_gid && id_pairs[file->id_ndx].gid != GID_NONE) {
95 +                       sprintf(gidbuf, " gid=%ld",
96 +                               (long)id_pairs[file->id_ndx].gid);
97 +               } else
98                         *gidbuf = '\0';
99                 if (!am_sender)
100                         sprintf(depthbuf, "%d", file->dir.depth);
101 --- old/generator.c
102 +++ new/generator.c
103 @@ -89,6 +89,7 @@ extern dev_t filesystem_dev;
104  extern char *backup_dir;
105  extern char *backup_suffix;
106  extern int backup_suffix_len;
107 +extern struct id_pair *id_pairs;
108  extern struct file_list *the_file_list;
109  extern struct filter_list_struct server_filter_list;
110  
111 @@ -322,10 +323,12 @@ int unchanged_attrs(struct file_struct *
112          && (st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS))
113                 return 0;
114  
115 -       if (am_root && preserve_uid && st->st_uid != file->uid)
116 +       if (am_root && preserve_uid
117 +        && st->st_uid != id_pairs[file->id_ndx].uid)
118                 return 0;
119  
120 -       if (preserve_gid && file->gid != GID_NONE && st->st_gid != file->gid)
121 +       if (preserve_gid && id_pairs[file->id_ndx].gid != GID_NONE
122 +        && st->st_gid != id_pairs[file->id_ndx].gid)
123                 return 0;
124  
125         return 1;
126 @@ -338,6 +341,8 @@ void itemize(struct file_struct *file, i
127                 int keep_time = !preserve_times ? 0
128                     : S_ISDIR(file->mode) ? !omit_dir_times
129                     : !S_ISLNK(file->mode);
130 +               uid_t uid = id_pairs[file->id_ndx].uid;
131 +               gid_t gid = id_pairs[file->id_ndx].gid;
132  
133                 if (S_ISREG(file->mode) && file->length != st->st_size)
134                         iflags |= ITEM_REPORT_SIZE;
135 @@ -347,10 +352,10 @@ void itemize(struct file_struct *file, i
136                         iflags |= ITEM_REPORT_TIME;
137                 if ((file->mode & CHMOD_BITS) != (st->st_mode & CHMOD_BITS))
138                         iflags |= ITEM_REPORT_PERMS;
139 -               if (preserve_uid && am_root && file->uid != st->st_uid)
140 +               if (preserve_uid && am_root && uid != st->st_uid)
141                         iflags |= ITEM_REPORT_OWNER;
142 -               if (preserve_gid && file->gid != GID_NONE
143 -                   && st->st_gid != file->gid)
144 +               if (preserve_gid && gid != GID_NONE
145 +                   && st->st_gid != gid)
146                         iflags |= ITEM_REPORT_GROUP;
147         } else
148                 iflags |= ITEM_IS_NEW;
149 --- old/log.c
150 +++ new/log.c
151 @@ -46,6 +46,7 @@ extern char *auth_user;
152  extern char *stdout_format;
153  extern char *logfile_format;
154  extern char *logfile_name;
155 +extern struct id_pair *id_pairs;
156  #if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
157  extern iconv_t ic_chck;
158  #endif
159 @@ -471,16 +472,16 @@ static void log_formatted(enum logcode c
160                 case 'U':
161                         strlcat(fmt, "ld", sizeof fmt);
162                         snprintf(buf2, sizeof buf2, fmt,
163 -                                (long)file->uid);
164 +                                (long)id_pairs[file->id_ndx].uid);
165                         n = buf2;
166                         break;
167                 case 'G':
168 -                       if (file->gid == GID_NONE)
169 +                       if (id_pairs[file->id_ndx].gid == GID_NONE)
170                                 n = "DEFAULT";
171                         else {
172                                 strlcat(fmt, "ld", sizeof fmt);
173                                 snprintf(buf2, sizeof buf2, fmt,
174 -                                        (long)file->gid);
175 +                                        (long)id_pairs[file->id_ndx].gid);
176                                 n = buf2;
177                         }
178                         break;
179 --- old/rsync.c
180 +++ new/rsync.c
181 @@ -49,6 +49,7 @@ extern int keep_dirlinks;
182  extern int make_backups;
183  extern mode_t orig_umask;
184  extern struct stats stats;
185 +extern struct id_pair *id_pairs;
186  extern struct chmod_mode_struct *daemon_chmod_modes;
187  
188  #if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
189 @@ -127,6 +128,8 @@ int set_file_attrs(char *fname, struct f
190         int updated = 0;
191         STRUCT_STAT st2;
192         int change_uid, change_gid;
193 +       uid_t uid;
194 +       gid_t gid;
195  
196         if (!st) {
197                 if (dry_run)
198 @@ -159,9 +162,11 @@ int set_file_attrs(char *fname, struct f
199                         updated = 1;
200         }
201  
202 -       change_uid = am_root && preserve_uid && st->st_uid != file->uid;
203 -       change_gid = preserve_gid && file->gid != GID_NONE
204 -               && st->st_gid != file->gid;
205 +       uid = id_pairs[file->id_ndx].uid;
206 +       gid = id_pairs[file->id_ndx].gid;
207 +       change_uid = am_root && preserve_uid && st->st_uid != uid;
208 +       change_gid = preserve_gid && gid != GID_NONE
209 +               && st->st_gid != gid;
210  #if !defined HAVE_LCHOWN && !defined CHOWN_MODIFIES_SYMLINK
211         if (S_ISLNK(st->st_mode))
212                 ;
213 @@ -173,18 +178,18 @@ int set_file_attrs(char *fname, struct f
214                                 rprintf(FINFO,
215                                         "set uid of %s from %ld to %ld\n",
216                                         fname,
217 -                                       (long)st->st_uid, (long)file->uid);
218 +                                       (long)st->st_uid, (long)uid);
219                         }
220                         if (change_gid) {
221                                 rprintf(FINFO,
222                                         "set gid of %s from %ld to %ld\n",
223                                         fname,
224 -                                       (long)st->st_gid, (long)file->gid);
225 +                                       (long)st->st_gid, (long)gid);
226                         }
227                 }
228                 if (do_lchown(fname,
229 -                   change_uid ? file->uid : st->st_uid,
230 -                   change_gid ? file->gid : st->st_gid) != 0) {
231 +                   change_uid ? uid : st->st_uid,
232 +                   change_gid ? gid : st->st_gid) != 0) {
233                         /* shouldn't have attempted to change uid or gid
234                          * unless have the privilege */
235                         rsyserr(FERROR, errno, "%s %s failed",
236 --- old/rsync.h
237 +++ new/rsync.h
238 @@ -502,6 +502,11 @@ struct hlink {
239         int hlindex;
240  };
241  
242 +struct id_pair {
243 +       uid_t uid;
244 +       gid_t gid;
245 +};
246 +
247  #define F_DEV  link_u.idev->dev
248  #define F_INODE        link_u.idev->inode
249  
250 @@ -526,8 +531,7 @@ struct file_struct {
251                 struct hlink *links;
252         } link_u;
253         time_t modtime;
254 -       uid_t uid;
255 -       gid_t gid;
256 +       int id_ndx;
257         mode_t mode;
258         uchar flags;    /* this item MUST remain last */
259  };
260 --- old/uidlist.c
261 +++ new/uidlist.c
262 @@ -38,6 +38,8 @@ extern int preserve_gid;
263  extern int numeric_ids;
264  extern int am_root;
265  
266 +struct id_pair *id_pairs;
267 +
268  struct idlist {
269         struct idlist *next;
270         int id, id2;
271 @@ -47,6 +49,8 @@ struct idlist {
272  static struct idlist *uidlist;
273  static struct idlist *gidlist;
274  
275 +static int pair_cnt = 0, pair_alloc = 0;
276 +
277  static struct idlist *add_to_list(struct idlist **root, int id, char *name,
278                                   int id2)
279  {
280 @@ -308,7 +312,7 @@ void send_uid_list(int f)
281  
282  /* recv a complete uid/gid mapping from the peer and map the uid/gid
283   * in the file list to local names */
284 -void recv_uid_list(int f, struct file_list *flist)
285 +void recv_uid_list(int f)
286  {
287         int id, i;
288         char *name;
289 @@ -339,11 +343,40 @@ void recv_uid_list(int f, struct file_li
290  
291         /* Now convert all the uids/gids from sender values to our values. */
292         if (am_root && preserve_uid && !numeric_ids) {
293 -               for (i = 0; i < flist->count; i++)
294 -                       flist->files[i]->uid = match_uid(flist->files[i]->uid);
295 +               for (i = 0; i < pair_cnt; i++)
296 +                       id_pairs[i].uid = match_uid(id_pairs[i].uid);
297         }
298         if (preserve_gid && (!am_root || !numeric_ids)) {
299 -               for (i = 0; i < flist->count; i++)
300 -                       flist->files[i]->gid = match_gid(flist->files[i]->gid);
301 +               for (i = 0; i < pair_cnt; i++)
302 +                       id_pairs[i].gid = match_gid(id_pairs[i].gid);
303         }
304  }
305 +
306 +int id_pair(uid_t uid, gid_t gid)
307 +{
308 +       static int j = 0;
309 +
310 +       if (pair_cnt) {
311 +               int start = j;
312 +               /* We start our search where we left off because
313 +                * the IDs usually come in clumps. */
314 +               do {
315 +                       if (uid == id_pairs[j].uid && gid == id_pairs[j].gid)
316 +                               return j;
317 +                       if (++j == pair_cnt)
318 +                               j = 0;
319 +               } while (j != start);
320 +       }
321 +
322 +       if (pair_cnt == pair_alloc) {
323 +               pair_alloc += 128;
324 +               id_pairs = realloc_array(id_pairs, struct id_pair,
325 +                                         pair_alloc);
326 +       }
327 +
328 +       j = pair_cnt++;
329 +       id_pairs[j].uid = uid;
330 +       id_pairs[j].gid = gid;
331 +
332 +       return j;
333 +}