Fixed failing hunks.
[rsync/rsync-patches.git] / id-pair.diff
CommitLineData
6801e52b
WD
1This attempts to accomplish some per-file memory-savings by moving the
2uid+gid items out of the file-list (since their values are common to
3multiple file-list entries) and replacing them with an index to an
4array of structures.
5
6This only saves 4 bytes per file (not counting the overhead of the array).
7
8This probably needs a hashing algorithm to be added if the uid+gid list
9gets to be really large.
10
9a7eef96
WD
11--- old/flist.c
12+++ new/flist.c
4a65fe72 13@@ -60,6 +60,7 @@ extern int protocol_version;
6801e52b 14 extern int sanitize_paths;
4a65fe72 15 extern const char *io_write_phase;
6801e52b
WD
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];
4a65fe72 21@@ -363,14 +364,14 @@ static void send_file_entry(struct file_
6801e52b 22 }
4a65fe72
WD
23 } else if (protocol_version < 28)
24 rdev = makedev(0, 0);
6801e52b
WD
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
4a65fe72 40@@ -623,8 +624,7 @@ static struct file_struct *receive_file_
6801e52b
WD
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;
4a65fe72 50@@ -875,8 +875,7 @@ struct file_struct *make_file(char *fnam
6801e52b
WD
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) {
4a65fe72 60@@ -944,8 +943,7 @@ struct file_struct *make_file(char *fnam
6801e52b
WD
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;
4a65fe72 70@@ -1389,7 +1387,7 @@ struct file_list *recv_file_list(int f)
6801e52b
WD
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)
4a65fe72 79@@ -1705,13 +1703,15 @@ static void output_flist(struct file_lis
6801e52b
WD
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);
9a7eef96
WD
101--- old/generator.c
102+++ new/generator.c
4a65fe72 103@@ -91,6 +91,7 @@ extern dev_t filesystem_dev;
6801e52b
WD
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
4a65fe72 111@@ -326,10 +327,12 @@ int unchanged_attrs(struct file_struct *
6801e52b
WD
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;
4a65fe72 126@@ -342,6 +345,8 @@ void itemize(struct file_struct *file, i
6801e52b
WD
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;
9a7eef96
WD
135@@ -351,10 +356,10 @@ void itemize(struct file_struct *file, i
136 iflags |= ITEM_REPORT_TIME;
137 if ((file->mode & CHMOD_BITS) != (st->st_mode & CHMOD_BITS))
6801e52b
WD
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;
9a7eef96
WD
149--- old/rsync.c
150+++ new/rsync.c
151@@ -49,6 +49,7 @@ extern int inplace;
6801e52b
WD
152 extern int keep_dirlinks;
153 extern int make_backups;
154 extern struct stats stats;
155+extern struct id_pair *id_pairs;
156
9a7eef96
WD
157 #if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
158 iconv_t ic_chck = (iconv_t)-1;
159@@ -116,6 +117,8 @@ int set_file_attrs(char *fname, struct f
6801e52b
WD
160 int updated = 0;
161 STRUCT_STAT st2;
162 int change_uid, change_gid;
163+ uid_t uid;
164+ gid_t gid;
165
166 if (!st) {
167 if (dry_run)
9a7eef96 168@@ -148,9 +151,11 @@ int set_file_attrs(char *fname, struct f
6801e52b
WD
169 updated = 1;
170 }
171
172- change_uid = am_root && preserve_uid && st->st_uid != file->uid;
173- change_gid = preserve_gid && file->gid != GID_NONE
174- && st->st_gid != file->gid;
175+ uid = id_pairs[file->id_ndx].uid;
176+ gid = id_pairs[file->id_ndx].gid;
177+ change_uid = am_root && preserve_uid && st->st_uid != uid;
178+ change_gid = preserve_gid && gid != GID_NONE
179+ && st->st_gid != gid;
180 #if !defined HAVE_LCHOWN && !defined CHOWN_MODIFIES_SYMLINK
181 if (S_ISLNK(st->st_mode))
182 ;
9a7eef96 183@@ -162,18 +167,18 @@ int set_file_attrs(char *fname, struct f
6801e52b
WD
184 rprintf(FINFO,
185 "set uid of %s from %ld to %ld\n",
186 fname,
187- (long)st->st_uid, (long)file->uid);
188+ (long)st->st_uid, (long)uid);
189 }
190 if (change_gid) {
191 rprintf(FINFO,
192 "set gid of %s from %ld to %ld\n",
193 fname,
194- (long)st->st_gid, (long)file->gid);
195+ (long)st->st_gid, (long)gid);
196 }
197 }
198 if (do_lchown(fname,
199- change_uid ? file->uid : st->st_uid,
200- change_gid ? file->gid : st->st_gid) != 0) {
201+ change_uid ? uid : st->st_uid,
202+ change_gid ? gid : st->st_gid) != 0) {
203 /* shouldn't have attempted to change uid or gid
204 * unless have the privilege */
205 rsyserr(FERROR, errno, "%s %s failed",
9a7eef96
WD
206--- old/rsync.h
207+++ new/rsync.h
6801e52b
WD
208@@ -493,6 +493,11 @@ struct hlink {
209 int hlindex;
210 };
211
212+struct id_pair {
213+ uid_t uid;
214+ gid_t gid;
215+};
216+
217 #define F_DEV link_u.idev->dev
218 #define F_INODE link_u.idev->inode
219
220@@ -517,8 +522,7 @@ struct file_struct {
221 struct hlink *links;
222 } link_u;
223 time_t modtime;
224- uid_t uid;
225- gid_t gid;
226+ int id_ndx;
227 mode_t mode;
228 uchar flags; /* this item MUST remain last */
229 };
9a7eef96
WD
230--- old/uidlist.c
231+++ new/uidlist.c
6801e52b
WD
232@@ -37,6 +37,8 @@ extern int preserve_gid;
233 extern int numeric_ids;
234 extern int am_root;
235
236+struct id_pair *id_pairs;
237+
238 struct idlist {
239 struct idlist *next;
240 int id, id2;
241@@ -46,6 +48,8 @@ struct idlist {
242 static struct idlist *uidlist;
243 static struct idlist *gidlist;
244
245+static int pair_cnt = 0, pair_alloc = 0;
246+
247 static struct idlist *add_to_list(struct idlist **root, int id, char *name,
248 int id2)
249 {
250@@ -307,7 +311,7 @@ void send_uid_list(int f)
251
252 /* recv a complete uid/gid mapping from the peer and map the uid/gid
253 * in the file list to local names */
254-void recv_uid_list(int f, struct file_list *flist)
255+void recv_uid_list(int f)
256 {
257 int id, i;
258 char *name;
259@@ -338,11 +342,40 @@ void recv_uid_list(int f, struct file_li
260
261 /* Now convert all the uids/gids from sender values to our values. */
262 if (am_root && preserve_uid && !numeric_ids) {
263- for (i = 0; i < flist->count; i++)
264- flist->files[i]->uid = match_uid(flist->files[i]->uid);
265+ for (i = 0; i < pair_cnt; i++)
266+ id_pairs[i].uid = match_uid(id_pairs[i].uid);
267 }
268 if (preserve_gid && (!am_root || !numeric_ids)) {
269- for (i = 0; i < flist->count; i++)
270- flist->files[i]->gid = match_gid(flist->files[i]->gid);
271+ for (i = 0; i < pair_cnt; i++)
272+ id_pairs[i].gid = match_gid(id_pairs[i].gid);
273 }
274 }
275+
276+int id_pair(uid_t uid, gid_t gid)
277+{
278+ static int j = 0;
279+
280+ if (pair_cnt) {
281+ int start = j;
282+ /* We start our search where we left off because
283+ * the IDs usually come in clumps. */
284+ do {
285+ if (uid == id_pairs[j].uid && gid == id_pairs[j].gid)
286+ return j;
287+ if (++j == pair_cnt)
288+ j = 0;
289+ } while (j != start);
290+ }
291+
292+ if (pair_cnt == pair_alloc) {
293+ pair_alloc += 128;
294+ id_pairs = realloc_array(id_pairs, struct id_pair,
295+ pair_alloc);
296+ }
297+
298+ j = pair_cnt++;
299+ id_pairs[j].uid = uid;
300+ id_pairs[j].gid = gid;
301+
302+ return j;
303+}