1 After applying this patch and running configure, you MUST run this
7 --- orig/flist.c 2006-01-24 19:03:06
8 +++ flist.c 2006-01-24 22:40:04
9 @@ -50,6 +50,7 @@ extern int preserve_perms;
10 extern int preserve_devices;
11 extern int preserve_uid;
12 extern int preserve_gid;
13 +extern int preserve_atimes;
14 extern int relative_paths;
15 extern int implied_dirs;
16 extern int copy_links;
17 @@ -83,7 +84,13 @@ void init_flist(void)
20 /* Figure out how big the file_struct is without trailing padding */
21 - file_struct_len = offsetof(struct file_struct, flags) + sizeof f.flags;
22 + if (preserve_atimes)
23 + file_struct_len = offsetof(struct file_struct, fl4g5);
25 + file_struct_len = offsetof(struct file_struct, atime);
26 + /* The "flags" uchar is no longer accessed directly, so I
27 + * mangled the name to fl4g5 as a reminder. */
28 + file_struct_len += sizeof f.fl4g5;
29 checksum_len = protocol_version < 21 ? 2 : MD4_SUM_LENGTH;
32 @@ -139,16 +146,18 @@ static void list_file_entry(struct file_
35 if (preserve_links && S_ISLNK(f->mode)) {
36 - rprintf(FINFO, "%s %11.0f %s %s -> %s\n",
37 + rprintf(FINFO, "%s %11.0f %s %s %s -> %s\n",
39 (double)f->length, timestring(f->modtime),
40 + preserve_atimes ? timestring(f->atime) : "",
41 f_name(f, NULL), f->u.link);
45 - rprintf(FINFO, "%s %11.0f %s %s\n",
46 + rprintf(FINFO, "%s %11.0f %s %s %s\n",
48 (double)f->length, timestring(f->modtime),
49 + preserve_atimes ? timestring(f->atime) : "",
53 @@ -310,6 +319,7 @@ static void send_file_entry(struct file_
56 static time_t modtime;
57 + static time_t atime;
61 @@ -325,7 +335,7 @@ static void send_file_entry(struct file_
65 - modtime = 0, mode = 0;
66 + modtime = 0, atime = 0, mode = 0;
67 dev = 0, rdev = makedev(0, 0);
70 @@ -337,7 +347,7 @@ static void send_file_entry(struct file_
74 - flags = file->flags & XMIT_TOP_DIR;
75 + flags = FFLAGS(file) & XMIT_TOP_DIR;
77 if (file->mode == mode)
78 flags |= XMIT_SAME_MODE;
79 @@ -374,6 +384,12 @@ static void send_file_entry(struct file_
80 flags |= XMIT_SAME_TIME;
82 modtime = file->modtime;
83 + if (preserve_atimes && !S_ISDIR(mode)) {
84 + if (file->atime == atime)
85 + flags |= XMIT_SAME_ATIME;
87 + atime = file->atime;
90 #ifdef SUPPORT_HARD_LINKS
91 if (file->link_u.idev) {
92 @@ -427,6 +443,8 @@ static void send_file_entry(struct file_
93 write_int(f, modtime);
94 if (!(flags & XMIT_SAME_MODE))
95 write_int(f, to_wire_mode(mode));
96 + if (preserve_atimes && !S_ISDIR(mode) && !(flags & XMIT_SAME_ATIME))
97 + write_int(f, atime);
98 if (preserve_uid && !(flags & XMIT_SAME_UID)) {
101 @@ -494,6 +512,7 @@ static struct file_struct *receive_file_
102 unsigned short flags, int f)
104 static time_t modtime;
105 + static time_t atime;
109 @@ -512,7 +531,7 @@ static struct file_struct *receive_file_
110 struct file_struct *file;
113 - modtime = 0, mode = 0;
114 + modtime = 0, atime = 0, mode = 0;
115 dev = 0, rdev = makedev(0, 0);
118 @@ -568,6 +587,8 @@ static struct file_struct *receive_file_
119 modtime = (time_t)read_int(f);
120 if (!(flags & XMIT_SAME_MODE))
121 mode = from_wire_mode(read_int(f));
122 + if (preserve_atimes && !S_ISDIR(mode) && !(flags & XMIT_SAME_ATIME))
123 + atime = (time_t)read_int(f);
125 if (chmod_modes && !S_ISLNK(mode))
126 mode = tweak_mode(mode, chmod_modes);
127 @@ -623,6 +644,8 @@ static struct file_struct *receive_file_
128 file->length = file_length;
130 file->ids = id_pair(uid, gid);
131 + if (preserve_atimes)
132 + file->atime = atime;
135 file->dirname = lastdir = bp;
136 @@ -648,12 +671,12 @@ static struct file_struct *receive_file_
137 && lastname[del_hier_name_len-1] == '.'
138 && lastname[del_hier_name_len-2] == '/')
139 del_hier_name_len -= 2;
140 - file->flags |= FLAG_TOP_DIR | FLAG_DEL_HERE;
141 + FFLAGS(file) |= FLAG_TOP_DIR | FLAG_DEL_HERE;
142 } else if (in_del_hier) {
143 if (!relative_paths || !del_hier_name_len
144 || (l1 >= del_hier_name_len
145 && lastname[del_hier_name_len] == '/'))
146 - file->flags |= FLAG_DEL_HERE;
147 + FFLAGS(file) |= FLAG_DEL_HERE;
151 @@ -874,11 +897,13 @@ struct file_struct *make_file(char *fnam
152 memset(bp, 0, file_struct_len);
153 bp += file_struct_len;
155 - file->flags = flags;
156 + FFLAGS(file) = flags;
157 file->modtime = st.st_mtime;
158 file->length = st.st_size;
159 file->mode = st.st_mode;
160 file->ids = id_pair(st.st_uid, st.st_gid);
161 + if (preserve_atimes)
162 + file->atime = st.st_atime;
164 #ifdef SUPPORT_HARD_LINKS
165 if (flist && flist->hlink_pool) {
166 @@ -989,7 +1014,7 @@ static void send_if_directory(int f, str
167 char is_dot_dir = fbuf[ol-1] == '.' && (ol == 1 || fbuf[ol-2] == '/');
169 if (S_ISDIR(file->mode)
170 - && !(file->flags & FLAG_MOUNT_POINT) && f_name(file, fbuf)) {
171 + && !(FFLAGS(file) & FLAG_MOUNT_POINT) && f_name(file, fbuf)) {
173 unsigned int len = strlen(fbuf);
174 if (len > 1 && fbuf[len-1] == '/')
175 @@ -1567,8 +1592,9 @@ static void clean_flist(struct file_list
177 /* Make sure that if we unduplicate '.', that we don't
178 * lose track of a user-specified top directory. */
179 - flist->files[keep]->flags |= flist->files[drop]->flags
180 - & (FLAG_TOP_DIR|FLAG_DEL_HERE);
181 + FFLAGS(flist->files[keep])
182 + |= FFLAGS(flist->files[drop])
183 + & (FLAG_TOP_DIR|FLAG_DEL_HERE);
185 clear_file(drop, flist);
187 @@ -1630,7 +1656,7 @@ static void output_flist(struct file_lis
188 file->dirname ? file->dirname : "",
189 file->dirname ? "/" : "", NS(file->basename),
190 S_ISDIR(file->mode) ? "/" : "", (int)file->mode,
191 - (double)file->length, uidbuf, gidbuf, file->flags);
192 + (double)file->length, uidbuf, gidbuf, FFLAGS(file));
196 --- orig/generator.c 2006-01-24 19:03:07
197 +++ generator.c 2006-01-24 22:29:56
198 @@ -43,6 +43,7 @@ extern int preserve_perms;
199 extern int preserve_uid;
200 extern int preserve_gid;
201 extern int preserve_times;
202 +extern int preserve_atimes;
203 extern int omit_dir_times;
204 extern int delete_before;
205 extern int delete_during;
206 @@ -89,6 +90,7 @@ extern dev_t filesystem_dev;
207 extern char *backup_dir;
208 extern char *backup_suffix;
209 extern int backup_suffix_len;
210 +extern unsigned int file_struct_len;
211 extern struct file_list *the_file_list;
212 extern struct filter_list_struct server_filter_list;
214 @@ -183,7 +185,7 @@ static int delete_item(char *fname, int
215 for (j = dirlist->count; j--; ) {
216 struct file_struct *fp = dirlist->files[j];
218 - if (fp->flags & FLAG_MOUNT_POINT)
219 + if (FFLAGS(fp) & FLAG_MOUNT_POINT)
222 strlcpy(p, fp->basename, remainder);
223 @@ -261,7 +263,7 @@ static void delete_in_dir(struct file_li
224 filt_array[cur_depth] = push_local_filters(fbuf, dlen);
226 if (one_file_system) {
227 - if (file->flags & FLAG_TOP_DIR)
228 + if (FFLAGS(file) & FLAG_TOP_DIR)
229 filesystem_dev = stp->st_dev;
230 else if (filesystem_dev != stp->st_dev)
232 @@ -273,7 +275,7 @@ static void delete_in_dir(struct file_li
233 * from the filesystem. */
234 for (i = dirlist->count; i--; ) {
235 struct file_struct *fp = dirlist->files[i];
236 - if (!fp->basename || fp->flags & FLAG_MOUNT_POINT)
237 + if (!fp->basename || FFLAGS(fp) & FLAG_MOUNT_POINT)
239 if (flist_find(flist, fp) < 0) {
241 @@ -300,11 +302,11 @@ static void do_delete_pass(struct file_l
242 for (j = 0; j < flist->count; j++) {
243 struct file_struct *file = flist->files[j];
245 - if (!(file->flags & FLAG_DEL_HERE))
246 + if (!(FFLAGS(file) & FLAG_DEL_HERE))
250 - if (verbose > 1 && file->flags & FLAG_TOP_DIR)
251 + if (verbose > 1 && FFLAGS(file) & FLAG_TOP_DIR)
252 rprintf(FINFO, "deleting in %s\n", fbuf);
254 if (link_stat(fbuf, &st, keep_dirlinks) < 0
255 @@ -346,8 +348,11 @@ void itemize(struct file_struct *file, i
256 iflags |= ITEM_REPORT_SIZE;
257 if ((iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !keep_time
258 && (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
259 - || (keep_time && cmp_modtime(file->modtime, st->st_mtime) != 0))
260 + || (keep_time && cmp_time(file->modtime, st->st_mtime) != 0))
261 iflags |= ITEM_REPORT_TIME;
262 + if (preserve_atimes && !S_ISDIR(file->mode) && !S_ISLNK(file->mode)
263 + && cmp_time(file->atime, st->st_atime) != 0)
264 + iflags |= ITEM_REPORT_ATIME;
266 && (file->mode & CHMOD_BITS) != (st->st_mode & CHMOD_BITS))
267 iflags |= ITEM_REPORT_PERMS;
268 @@ -396,7 +401,7 @@ int unchanged_file(char *fn, struct file
272 - return cmp_modtime(st->st_mtime, file->modtime) == 0;
273 + return cmp_time(st->st_mtime, file->modtime) == 0;
277 @@ -550,13 +555,13 @@ static int find_fuzzy(struct file_struct
280 if (!S_ISREG(fp->mode) || !fp->length
281 - || fp->flags & FLAG_NO_FUZZY)
282 + || FFLAGS(fp) & FLAG_NO_FUZZY)
287 if (fp->length == file->length
288 - && cmp_modtime(fp->modtime, file->modtime) == 0) {
289 + && cmp_time(fp->modtime, file->modtime) == 0) {
292 "fuzzy size/modtime match for %s\n",
293 @@ -632,7 +637,7 @@ static int try_dests_reg(struct file_str
294 if (!unchanged_attrs(file, stp))
296 if ((always_checksum || ignore_times)
297 - && cmp_modtime(stp->st_mtime, file->modtime))
298 + && cmp_time(stp->st_mtime, file->modtime))
302 @@ -894,7 +899,7 @@ static void recv_generator(char *fname,
303 && verbose && code && f_out != -1)
304 rprintf(code, "%s/\n", fname);
305 if (delete_during && f_out != -1 && !phase && dry_run < 2
306 - && (file->flags & FLAG_DEL_HERE))
307 + && (FFLAGS(file) & FLAG_DEL_HERE))
308 delete_in_dir(the_file_list, fname, file, &st);
311 @@ -1071,7 +1076,7 @@ static void recv_generator(char *fname,
314 if (update_only && statret == 0
315 - && cmp_modtime(st.st_mtime, file->modtime) > 0) {
316 + && cmp_time(st.st_mtime, file->modtime) > 0) {
318 rprintf(FINFO, "%s is newer\n", fname);
320 @@ -1174,7 +1179,7 @@ static void recv_generator(char *fname,
322 int j = flist_find(fuzzy_dirlist, file);
323 if (j >= 0) /* don't use changing file as future fuzzy basis */
324 - fuzzy_dirlist->files[j]->flags |= FLAG_NO_FUZZY;
325 + FFLAGS(fuzzy_dirlist->files[j]) |= FLAG_NO_FUZZY;
329 --- orig/hlink.c 2006-01-14 20:27:09
330 +++ hlink.c 2006-01-24 19:17:58
331 @@ -26,6 +26,7 @@ extern int link_dest;
332 extern int make_backups;
333 extern int log_format_has_i;
334 extern char *basis_dir[];
335 +extern unsigned int file_struct_len;
336 extern struct file_list *the_file_list;
338 #ifdef SUPPORT_HARD_LINKS
339 @@ -86,10 +87,10 @@ static void link_idev_data(void)
340 FPTR(cur)->link_u.links = pool_talloc(hlink_pool,
341 struct hlink, 1, "hlink_list");
343 - FPTR(head)->flags |= FLAG_HLINK_TOL;
344 + FFLAGS(FPTR(head)) |= FLAG_HLINK_TOL;
345 FPTR(cur)->F_HLINDEX = to;
346 FPTR(cur)->F_NEXT = head;
347 - FPTR(cur)->flags |= FLAG_HLINK_EOL;
348 + FFLAGS(FPTR(cur)) |= FLAG_HLINK_EOL;
349 hlink_list[to++] = head;
351 FPTR(cur)->link_u.links = NULL;
352 @@ -175,7 +176,7 @@ int hard_link_check(struct file_struct *
354 #ifdef SUPPORT_HARD_LINKS
356 - if (skip && !(file->flags & FLAG_HLINK_EOL))
357 + if (skip && !(FFLAGS(file) & FLAG_HLINK_EOL))
358 head = hlink_list[file->F_HLINDEX] = file->F_NEXT;
360 head = hlink_list[file->F_HLINDEX];
361 @@ -270,8 +271,8 @@ void hard_link_cluster(struct file_struc
362 file->F_HLINDEX = FINISHED_LINK;
363 if (link_stat(f_name(file, hlink1), &st1, 0) < 0)
365 - if (!(file->flags & FLAG_HLINK_TOL)) {
366 - while (!(file->flags & FLAG_HLINK_EOL)) {
367 + if (!(FFLAGS(file) & FLAG_HLINK_TOL)) {
368 + while (!(FFLAGS(file) & FLAG_HLINK_EOL)) {
372 @@ -286,6 +287,6 @@ void hard_link_cluster(struct file_struc
373 maybe_hard_link(file, ndx, hlink2, statret, &st2,
374 hlink1, &st1, itemizing, code);
375 file->F_HLINDEX = FINISHED_LINK;
376 - } while (!(file->flags & FLAG_HLINK_EOL));
377 + } while (!(FFLAGS(file) & FLAG_HLINK_EOL));
380 --- orig/log.c 2006-01-24 22:24:32
381 +++ log.c 2006-01-24 22:50:01
382 @@ -38,6 +38,7 @@ extern int module_id;
383 extern int msg_fd_out;
384 extern int protocol_version;
385 extern int preserve_times;
386 +extern int preserve_atimes;
387 extern int log_format_has_i;
388 extern int log_format_has_o_or_i;
389 extern int daemon_log_format_has_o_or_i;
390 @@ -542,10 +543,12 @@ static void log_formatted(enum logcode c
391 n[3] = !(iflags & ITEM_REPORT_SIZE) ? '.' : 's';
392 n[4] = !(iflags & ITEM_REPORT_TIME) ? '.'
393 : !preserve_times || S_ISLNK(file->mode) ? 'T' : 't';
394 - n[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p';
395 - n[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o';
396 - n[7] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g';
398 + n[5] = !(iflags & ITEM_REPORT_ATIME) ? '.'
399 + : S_ISLNK(file->mode) ? 'U' : 'u';
400 + n[6] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p';
401 + n[7] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o';
402 + n[8] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g';
405 if (iflags & (ITEM_IS_NEW|ITEM_MISSING_DATA)) {
406 char ch = iflags & ITEM_IS_NEW ? '+' : '?';
407 --- orig/options.c 2006-01-23 18:48:23
408 +++ options.c 2006-01-24 22:53:18
409 @@ -50,6 +50,7 @@ int preserve_uid = 0;
410 int preserve_gid = 0;
411 int preserve_times = 0;
412 int omit_dir_times = 0;
413 +int preserve_atimes = 0;
417 @@ -291,8 +292,9 @@ void usage(enum logcode F)
418 rprintf(F," -o, --owner preserve owner (root only)\n");
419 rprintf(F," -g, --group preserve group\n");
420 rprintf(F," -D, --devices preserve devices (root only)\n");
421 - rprintf(F," -t, --times preserve times\n");
422 - rprintf(F," -O, --omit-dir-times omit directories when preserving times\n");
423 + rprintf(F," -t, --times preserve modify times\n");
424 + rprintf(F," -O, --omit-dir-times omit directories when preserving modify times\n");
425 + rprintf(F," -U, --atimes preserve access (use) times\n");
426 rprintf(F," --chmod=CHMOD change destination permissions\n");
427 rprintf(F," -S, --sparse handle sparse files efficiently\n");
428 rprintf(F," -n, --dry-run show what would have been transferred\n");
429 @@ -400,6 +402,9 @@ static struct poptOption long_options[]
430 {"times", 't', POPT_ARG_VAL, &preserve_times, 1, 0, 0 },
431 {"no-times", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 },
432 {"no-t", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 },
433 + {"atimes", 'U', POPT_ARG_VAL, &preserve_atimes, 1, 0, 0 },
434 + {"no-atimes", 0, POPT_ARG_VAL, &preserve_atimes, 0, 0, 0 },
435 + {"no-k", 0, POPT_ARG_VAL, &preserve_atimes, 0, 0, 0 },
436 {"omit-dir-times", 'O', POPT_ARG_VAL, &omit_dir_times, 2, 0, 0 },
437 {"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
438 {"owner", 'o', POPT_ARG_VAL, &preserve_uid, 1, 0, 0 },
439 @@ -1468,6 +1473,8 @@ void server_options(char **args,int *arg
443 + if (preserve_atimes)
445 if (omit_dir_times == 2 && am_sender)
448 --- orig/rsync.c 2006-01-24 19:03:07
449 +++ rsync.c 2005-07-28 00:17:37
450 @@ -27,6 +27,7 @@ extern int dry_run;
451 extern int daemon_log_format_has_i;
452 extern int preserve_times;
453 extern int omit_dir_times;
454 +extern int preserve_atimes;
456 extern int am_server;
457 extern int am_sender;
458 @@ -56,6 +57,7 @@ int set_perms(char *fname,struct file_st
461 int change_uid, change_gid;
462 + time_t atime, mtime;
466 @@ -70,16 +72,29 @@ int set_perms(char *fname,struct file_st
468 if (!preserve_times || (S_ISDIR(st->st_mode) && omit_dir_times))
469 flags |= PERMS_SKIP_MTIME;
470 + if (!preserve_atimes || S_ISDIR(st->st_mode))
471 + flags |= PERMS_SKIP_ATIME;
472 if (!(flags & PERMS_SKIP_MTIME)
473 - && cmp_modtime(st->st_mtime, file->modtime) != 0) {
474 - int ret = set_modtime(fname, file->modtime, st->st_mode);
475 + && cmp_time(st->st_mtime, file->modtime) != 0) {
476 + mtime = file->modtime;
479 + mtime = st->st_mtime;
480 + if (!(flags & PERMS_SKIP_ATIME)
481 + && cmp_time(st->st_atime, file->atime) != 0) {
482 + atime = file->atime;
485 + atime = st->st_atime;
487 + int ret = set_times(fname, mtime, atime, st->st_mode);
489 rsyserr(FERROR, errno, "failed to set times on %s",
493 - if (ret == 0) /* ret == 1 if symlink could not be set */
495 + if (ret > 0) /* ret == 1 if symlink could not be set */
499 change_uid = am_root && preserve_uid && st->st_uid != file->ids->uid;
500 --- orig/rsync.h 2006-01-24 19:03:07
501 +++ rsync.h 2006-01-24 22:38:08
503 #define XMIT_HAS_IDEV_DATA (1<<9)
504 #define XMIT_SAME_DEV (1<<10)
505 #define XMIT_RDEV_MINOR_IS_SMALL (1<<11)
506 +#define XMIT_SAME_ATIME (1<<12)
508 /* These flags are used in the live flist data. */
512 #define PERMS_REPORT (1<<0)
513 #define PERMS_SKIP_MTIME (1<<1)
514 +#define PERMS_SKIP_ATIME (1<<2)
517 #define NORMAL_FLUSH 0
519 #define FNAMECMP_FUZZY 0x83
521 /* For use by the itemize_changes code */
522 +#define ITEM_REPORT_ATIME (1<<0)
523 #define ITEM_REPORT_CHECKSUM (1<<1)
524 #define ITEM_REPORT_SIZE (1<<2)
525 #define ITEM_REPORT_TIME (1<<3)
526 @@ -524,9 +527,12 @@ struct file_struct {
530 - uchar flags; /* this item MUST remain last */
531 + time_t atime; /* this MUST be second to last */
532 + uchar fl4g5; /* this item MUST remain last */
535 +#define FFLAGS(f) ((uchar*)(f))[file_struct_len-1]
538 * Start the flist array at FLIST_START entries and grow it
539 * by doubling until FLIST_LINEAR then grow by FLIST_LINEAR
540 --- orig/rsync.yo 2006-01-24 22:19:58
541 +++ rsync.yo 2006-01-24 22:54:23
542 @@ -319,8 +319,9 @@ to the detailed description below for a
543 -o, --owner preserve owner (root only)
544 -g, --group preserve group
545 -D, --devices preserve devices (root only)
546 - -t, --times preserve times
547 - -O, --omit-dir-times omit directories when preserving times
548 + -t, --times preserve modify times
549 + -O, --omit-dir-times omit directories when preserving mod-times
550 + -U, --atimes preserve access (use) times
551 --chmod=CHMOD change destination permissions
552 -S, --sparse handle sparse files efficiently
553 -n, --dry-run show what would have been transferred
554 @@ -711,6 +712,12 @@ it is preserving modification times (see
555 the directories on the receiving side, it is a good idea to use bf(-O).
556 This option is inferred if you use bf(--backup) without bf(--backup-dir).
558 +dit(bf(-U, --atimes)) This tells rsync to set the access (use) times of the
559 +destination files to the same value as the source files. Note that the
560 +reading of the source file may update the atime of the source files, so
561 +repeated rsync runs with --atimes may be needed if you want to force the
562 +access-time values to be 100% identical on the two systems.
564 dit(bf(--chmod)) This options tells rsync to apply the listed "chmod" pattern
565 to the permission of the files on the destination. In addition to the normal
566 parsing rules specified in the chmod manpage, you can specify an item that
567 @@ -1219,9 +1226,13 @@ quote(itemize(
568 by the file transfer.
569 it() A bf(t) means the modification time is different and is being updated
570 to the sender's value (requires bf(--times)). An alternate value of bf(T)
571 - means that the time will be set to the transfer time, which happens
572 + means that the modify time will be set to the transfer time, which happens
573 anytime a symlink is transferred, or when a file or device is transferred
575 + it() A bf(u) means the access (use) time is different and is being updated to
576 + the sender's value (requires bf(--atimes)). An alternate value of bf(U)
577 + means that the access time will be set to the transfer time, which happens
578 + anytime a symlink is transferred.
579 it() A bf(p) means the permissions are different and are being updated to
580 the sender's value (requires bf(--perms)).
581 it() An bf(o) means the owner is different and is being updated to the
582 --- orig/sender.c 2006-01-14 20:27:10
583 +++ sender.c 2006-01-24 18:10:23
584 @@ -38,6 +38,7 @@ extern int do_progress;
587 extern int write_batch;
588 +extern unsigned int file_struct_len;
589 extern struct stats stats;
590 extern struct file_list *the_file_list;
591 extern char *log_format;
592 @@ -126,7 +127,7 @@ void successful_send(int ndx)
594 file = the_file_list->files[ndx];
595 /* The generator might tell us about symlinks we didn't send. */
596 - if (!(file->flags & FLAG_SENT) && !S_ISLNK(file->mode))
597 + if (!(FFLAGS(file) & FLAG_SENT) && !S_ISLNK(file->mode))
599 if (file->dir.root) {
600 offset = stringjoin(fname, sizeof fname,
601 @@ -370,7 +371,7 @@ void send_files(struct file_list *flist,
602 rprintf(FINFO, "sender finished %s\n", fname);
604 /* Flag that we actually sent this entry. */
605 - file->flags |= FLAG_SENT;
606 + FFLAGS(file) |= FLAG_SENT;
608 make_backups = save_make_backups;
610 --- orig/testsuite/atimes.test 2006-01-24 22:54:53
611 +++ testsuite/atimes.test 2006-01-24 22:54:53
615 +# Test rsync copying atimes
617 +. "$suitedir/rsync.fns"
623 +touch "$fromdir/foo"
624 +touch -a -t 200102031717.42 "$fromdir/foo"
628 +checkit "$RSYNC -rtUgvvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
630 +# The script would have aborted on error, so getting here means we've won.
632 --- orig/testsuite/devices.test 2006-01-24 22:24:32
633 +++ testsuite/devices.test 2006-01-24 22:32:30
634 @@ -55,14 +55,14 @@ touch -r "$fromdir/block" "$fromdir/bloc
635 $RSYNC -ai "$fromdir/block" "$todir/block2" \
637 cat <<EOT >"$chkfile"
641 diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed"
643 $RSYNC -ai "$fromdir/block2" "$todir/block" \
645 cat <<EOT >"$chkfile"
649 diff $diffopt "$chkfile" "$outfile" || test_fail "test 2 failed"
651 @@ -71,7 +71,7 @@ sleep 1
652 $RSYNC -Di "$fromdir/block3" "$todir/block" \
654 cat <<EOT >"$chkfile"
658 diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed"
660 @@ -79,15 +79,15 @@ $RSYNC -aiHvv "$fromdir/" "$todir/" \
663 cat <<EOT >"$chkfile"
668 -hD++++++ block2.5 => block3
677 +hD+++++++ block2.5 => block3
683 if test ! -b "$fromdir/block2.5"; then
684 sed -e '/block2\.5/d' \
685 --- orig/testsuite/itemize.test 2006-01-24 22:24:32
686 +++ testsuite/itemize.test 2006-01-24 22:32:03
687 @@ -44,14 +44,14 @@ ln "$fromdir/foo/config1" "$fromdir/foo/
688 $RSYNC -iplr "$fromdir/" "$todir/" \
690 cat <<EOT >"$chkfile"
693 ->f++++++ bar/baz/rsync
695 ->f++++++ foo/config1
696 ->f++++++ foo/config2
698 -cL++++++ foo/sym -> ../bar/baz/rsync
701 +>f+++++++ bar/baz/rsync
703 +>f+++++++ foo/config1
704 +>f+++++++ foo/config2
706 +cL+++++++ foo/sym -> ../bar/baz/rsync
708 diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed"
710 @@ -63,10 +63,10 @@ chmod 601 "$fromdir/foo/config2"
711 $RSYNC -iplrH "$fromdir/" "$todir/" \
713 cat <<EOT >"$chkfile"
714 ->f..T... bar/baz/rsync
715 ->f..T... foo/config1
716 ->f.sTp.. foo/config2
717 -hf..T... foo/extra => foo/config1
718 +>f..T.... bar/baz/rsync
719 +>f..T.... foo/config1
720 +>f.sT.p.. foo/config2
721 +hf..T.... foo/extra => foo/config1
723 diff $diffopt "$chkfile" "$outfile" || test_fail "test 2 failed"
725 @@ -83,11 +83,11 @@ chmod 777 "$todir/bar/baz/rsync"
726 $RSYNC -iplrtc "$fromdir/" "$todir/" \
728 cat <<EOT >"$chkfile"
729 -.f..tp.. bar/baz/rsync
731 -.f..t... foo/config1
732 ->fcstp.. foo/config2
733 -cL..T... foo/sym -> ../bar/baz/rsync
734 +.f..t.p.. bar/baz/rsync
736 +.f..t.... foo/config1
737 +>fcst.p.. foo/config2
738 +cL..T.... foo/sym -> ../bar/baz/rsync
740 diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed"
742 @@ -112,15 +112,15 @@ $RSYNC -ivvplrtH "$fromdir/" "$todir/" \
745 cat <<EOT >"$chkfile"
749 -.f...p.. bar/baz/rsync
752 ->f..t... foo/config2
754 -.L foo/sym -> ../bar/baz/rsync
758 +.f....p.. bar/baz/rsync
761 +>f..t.... foo/config2
763 +.L foo/sym -> ../bar/baz/rsync
765 diff $diffopt "$chkfile" "$outfile" || test_fail "test 5 failed"
767 @@ -139,8 +139,8 @@ touch "$todir/foo/config2"
768 $RSYNC -iplrtH "$fromdir/" "$todir/" \
770 cat <<EOT >"$chkfile"
771 -.f...p.. foo/config1
772 ->f..t... foo/config2
773 +.f....p.. foo/config1
774 +>f..t.... foo/config2
776 diff $diffopt "$chkfile" "$outfile" || test_fail "test 7 failed"
778 @@ -149,15 +149,15 @@ $RSYNC -ivvplrtH --copy-dest="$lddir" "$
781 cat <<EOT >"$chkfile"
789 -hf foo/extra => foo/config1
790 -cL..T... foo/sym -> ../bar/baz/rsync
798 +hf foo/extra => foo/config1
799 +cL..T.... foo/sym -> ../bar/baz/rsync
801 diff $diffopt "$chkfile" "$outfile" || test_fail "test 8 failed"
803 @@ -165,11 +165,11 @@ rm -rf "$todir"
804 $RSYNC -iplrtH --copy-dest="$lddir" "$fromdir/" "$todir/" \
806 cat <<EOT >"$chkfile"
811 -hf foo/extra => foo/config1
816 +hf foo/extra => foo/config1
818 diff $diffopt "$chkfile" "$outfile" || test_fail "test 9 failed"
820 @@ -196,15 +196,15 @@ $RSYNC -ivvplrtH --link-dest="$lddir" "$
823 cat <<EOT >"$chkfile"
831 -hf foo/extra => foo/config1
832 -hL foo/sym -> ../bar/baz/rsync
840 +hf foo/extra => foo/config1
841 +hL foo/sym -> ../bar/baz/rsync
843 diff $diffopt "$chkfile" "$outfile" || test_fail "test 11 failed"
845 @@ -212,10 +212,10 @@ rm -rf "$todir"
846 $RSYNC -iplrtH --link-dest="$lddir" "$fromdir/" "$todir/" \
848 cat <<EOT >"$chkfile"
858 diff $diffopt "$chkfile" "$outfile" || test_fail "test 12 failed"
860 @@ -243,14 +243,14 @@ filter_outfile
861 # TODO fix really-old problem when combining -H with --compare-dest:
862 # missing output for foo/extra hard-link (and it might not be updated)!
863 cat <<EOT >"$chkfile"
871 -.L foo/sym -> ../bar/baz/rsync
879 +.L foo/sym -> ../bar/baz/rsync
881 diff $diffopt "$chkfile" "$outfile" || test_fail "test 14 failed"
883 @@ -258,10 +258,10 @@ rm -rf "$todir"
884 $RSYNC -iplrtH --compare-dest="$lddir" "$fromdir/" "$todir/" \
886 cat <<EOT >"$chkfile"
896 diff $diffopt "$chkfile" "$outfile" || test_fail "test 15 failed"
898 --- orig/testsuite/rsync.fns 2005-06-10 21:33:28
899 +++ testsuite/rsync.fns 2005-07-28 00:41:20
900 @@ -50,7 +50,7 @@ printmsg() {
904 - find "$@" -print | sort | sed 's/ /\\ /g' | xargs "$TOOLDIR/tls"
905 + find "$@" -print | sort | sed 's/ /\\ /g' | xargs "$TOOLDIR/tls" $TLS_ARGS
909 @@ -158,6 +158,10 @@ checkit() {
910 # We can just write everything to stdout/stderr, because the
911 # wrapper hides it unless there is a problem.
913 + if test x$TLS_ARGS = x--atime; then
914 + ( cd "$2" && rsync_ls_lR . ) > "$tmpdir/ls-from"
917 echo "Running: \"$1\""
920 @@ -165,10 +169,13 @@ checkit() {
924 + if test x$TLS_ARGS != x--atime; then
925 + ( cd "$2" && rsync_ls_lR . ) > "$tmpdir/ls-from"
929 echo "check how the directory listings compare with diff:"
931 - ( cd "$2" && rsync_ls_lR . ) > "$tmpdir/ls-from"
932 ( cd "$3" && rsync_ls_lR . ) > "$tmpdir/ls-to"
933 diff $diffopt "$tmpdir/ls-from" "$tmpdir/ls-to" || failed=YES
935 --- orig/tls.c 2005-09-24 17:40:31
936 +++ tls.c 2005-03-23 17:49:48
943 #define PROGRAM "tls"
945 @@ -48,6 +49,7 @@ int read_only = 1;
947 int preserve_perms = 0;
949 +static int display_atime = 0;
951 static void failed(char const *what, char const *where)
953 @@ -56,14 +58,29 @@ static void failed(char const *what, cha
957 +static void storetime(char *dest, time_t t)
960 + struct tm *mt = gmtime(&t);
962 + sprintf(dest, "%04d-%02d-%02d %02d:%02d:%02d ",
963 + (int)mt->tm_year + 1900,
964 + (int)mt->tm_mon + 1,
974 static void list_file(const char *fname)
977 char permbuf[PERMSTRING_SIZE];
984 if (do_lstat(fname, &buf) < 0)
985 @@ -96,19 +113,8 @@ static void list_file(const char *fname)
987 permstring(permbuf, buf.st_mode);
989 - if (buf.st_mtime) {
990 - mt = gmtime(&buf.st_mtime);
992 - sprintf(datebuf, "%04d-%02d-%02d %02d:%02d:%02d",
993 - (int)mt->tm_year + 1900,
994 - (int)mt->tm_mon + 1,
1000 - strcpy(datebuf, " ");
1002 + storetime(mtimebuf, buf.st_mtime);
1003 + storetime(atimebuf, buf.st_atime);
1005 /* TODO: Perhaps escape special characters in fname? */
1007 @@ -119,24 +125,55 @@ static void list_file(const char *fname)
1008 (long)minor(buf.st_rdev));
1009 } else /* NB: use double for size since it might not fit in a long. */
1010 printf("%12.0f", (double)buf.st_size);
1011 - printf(" %6ld.%-6ld %6ld %s %s%s\n",
1012 + printf(" %6ld.%-6ld %6ld %s%s%s%s\n",
1013 (long)buf.st_uid, (long)buf.st_gid, (long)buf.st_nlink,
1014 - datebuf, fname, linkbuf);
1015 + mtimebuf, display_atime && !S_ISDIR(buf.st_mode) ? atimebuf : "",
1019 +static struct poptOption long_options[] = {
1020 + /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
1021 + {"atime", 'u', POPT_ARG_NONE, &display_atime, 0, 0, 0},
1022 + {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0},
1026 +static void tls_usage(int ret)
1028 + fprintf(stderr, "usage: " PROGRAM " [--atime | -u] DIR ...\n"
1029 + "Trivial file listing program for portably checking rsync\n");
1034 main(int argc, char *argv[])
1037 - fprintf(stderr, "usage: " PROGRAM " DIR ...\n"
1038 - "Trivial file listing program for portably checking rsync\n");
1041 + const char **extra_args;
1044 + pc = poptGetContext(PROGRAM, argc, (const char **)argv,
1046 + while ((opt = poptGetNextOpt(pc)) != -1) {
1053 + poptBadOption(pc, POPT_BADOPTION_NOALIAS),
1054 + poptStrerror(opt));
1059 - for (argv++; *argv; argv++) {
1062 + extra_args = poptGetArgs(pc);
1063 + if (*extra_args == NULL)
1066 + for (; *extra_args; extra_args++)
1067 + list_file(*extra_args);
1068 + poptFreeContext(pc);
1072 --- orig/util.c 2006-01-20 00:12:48
1073 +++ util.c 2006-01-14 08:20:29
1074 @@ -130,7 +130,7 @@ void overflow_exit(char *str)
1078 -int set_modtime(char *fname, time_t modtime, mode_t mode)
1079 +int set_times(char *fname, time_t modtime, time_t atime, mode_t mode)
1081 #if !defined HAVE_LUTIMES || !defined HAVE_UTIMES
1083 @@ -138,9 +138,13 @@ int set_modtime(char *fname, time_t modt
1087 - rprintf(FINFO, "set modtime of %s to (%ld) %s",
1088 + char mtimebuf[200];
1090 + strlcpy(mtimebuf, timestring(modtime), sizeof mtimebuf);
1092 + "set modtime, atime of %s to (%ld) %s, (%ld) %s\n",
1093 fname, (long)modtime,
1094 - asctime(localtime(&modtime)));
1095 + mtimebuf, (long)atime, timestring(atime));
1099 @@ -149,7 +153,7 @@ int set_modtime(char *fname, time_t modt
1102 struct timeval t[2];
1103 - t[0].tv_sec = time(NULL);
1104 + t[0].tv_sec = atime;
1106 t[1].tv_sec = modtime;
1108 @@ -160,12 +164,12 @@ int set_modtime(char *fname, time_t modt
1109 return utimes(fname, t);
1110 #elif defined HAVE_UTIMBUF
1111 struct utimbuf tbuf;
1112 - tbuf.actime = time(NULL);
1113 + tbuf.actime = atime;
1114 tbuf.modtime = modtime;
1115 return utime(fname,&tbuf);
1116 #elif defined HAVE_UTIME
1118 - t[0] = time(NULL);
1121 return utime(fname,t);
1123 @@ -1175,8 +1179,8 @@ int msleep(int t)
1127 - * Determine if two file modification times are equivalent (either
1128 - * exact or in the modification timestamp window established by
1129 + * Determine if two file times are equivalent (either
1130 + * exact or in the timestamp window established by
1133 * @retval 0 if the times should be treated as the same
1134 @@ -1185,7 +1189,7 @@ int msleep(int t)
1136 * @retval -1 if the 2nd is later
1138 -int cmp_modtime(time_t file1, time_t file2)
1139 +int cmp_time(time_t file1, time_t file2)
1141 if (file2 > file1) {
1142 if (file2 - file1 <= modify_window)