Changed the short option from -A to -k (since acls.diff uses -A).
[rsync/rsync-patches.git] / atimes.diff
CommitLineData
8a529471
WD
1After applying this patch and running configure, you MUST run this
2command before "make":
3
4 make proto
5
6
93ca4d27 7--- orig/batch.c 2006-01-14 08:14:29
13bed3dd 8+++ batch.c 2004-07-03 20:15:41
610969d1 9@@ -225,6 +225,8 @@ void show_flist(int index, struct file_s
43581f16
WD
10 rprintf(FINFO, "flist->flags=%#x\n", fptr[i]->flags);
11 rprintf(FINFO, "flist->modtime=%#lx\n",
12 (long unsigned) fptr[i]->modtime);
13+ rprintf(FINFO, "flist->atime=%#lx\n",
14+ (long unsigned) fptr[i]->atime);
15 rprintf(FINFO, "flist->length=%.0f\n",
16 (double) fptr[i]->length);
17 rprintf(FINFO, "flist->mode=%#o\n", (int) fptr[i]->mode);
bd68c3c2
WD
18--- orig/flist.c 2006-01-17 02:15:59
19+++ flist.c 2006-01-17 02:42:04
81c32ffd
WD
20@@ -50,6 +50,7 @@ extern int preserve_perms;
21 extern int preserve_devices;
22 extern int preserve_uid;
23 extern int preserve_gid;
24+extern int preserve_atimes;
25 extern int relative_paths;
a5e0f697 26 extern int implied_dirs;
43581f16 27 extern int copy_links;
bd68c3c2 28@@ -139,16 +140,18 @@ static void list_file_entry(struct file_
43581f16 29
09fb8f03 30 #ifdef SUPPORT_LINKS
43581f16
WD
31 if (preserve_links && S_ISLNK(f->mode)) {
32- rprintf(FINFO, "%s %11.0f %s %s -> %s\n",
33+ rprintf(FINFO, "%s %11.0f %s %s %s -> %s\n",
34 perms,
f3e2725a 35 (double)f->length, timestring(f->modtime),
2ae38ef5 36+ timestring(f->atime),
bd68c3c2 37 f_name(f, NULL), f->u.link);
43581f16
WD
38 } else
39 #endif
896c61d0 40 {
43581f16
WD
41- rprintf(FINFO, "%s %11.0f %s %s\n",
42+ rprintf(FINFO, "%s %11.0f %s %s %s\n",
43 perms,
f3e2725a 44 (double)f->length, timestring(f->modtime),
2ae38ef5 45+ timestring(f->atime),
bd68c3c2 46 f_name(f, NULL));
896c61d0 47 }
43581f16 48 }
bd68c3c2 49@@ -310,6 +313,7 @@ void send_file_entry(struct file_struct
43581f16
WD
50 {
51 unsigned short flags;
52 static time_t modtime;
53+ static time_t atime;
54 static mode_t mode;
ba50e96c 55 static int64 dev;
43581f16 56 static dev_t rdev;
bd68c3c2 57@@ -325,7 +329,7 @@ void send_file_entry(struct file_struct
43581f16
WD
58
59 if (!file) {
60 write_byte(f, 0);
61- modtime = 0, mode = 0;
62+ modtime = 0, atime = 0, mode = 0;
63 dev = 0, rdev = makedev(0, 0);
64 rdev_major = 0;
65 uid = 0, gid = 0;
bd68c3c2 66@@ -374,6 +378,12 @@ void send_file_entry(struct file_struct
43581f16
WD
67 flags |= XMIT_SAME_TIME;
68 else
69 modtime = file->modtime;
81c32ffd 70+ if (preserve_atimes && !S_ISDIR(mode)) {
43581f16
WD
71+ if (file->atime == atime)
72+ flags |= XMIT_SAME_ATIME;
73+ else
74+ atime = file->atime;
75+ }
76
09fb8f03 77 #ifdef SUPPORT_HARD_LINKS
43581f16 78 if (file->link_u.idev) {
bd68c3c2 79@@ -427,6 +437,8 @@ void send_file_entry(struct file_struct
43581f16
WD
80 write_int(f, modtime);
81 if (!(flags & XMIT_SAME_MODE))
82 write_int(f, to_wire_mode(mode));
81c32ffd 83+ if (preserve_atimes && !S_ISDIR(mode) && !(flags & XMIT_SAME_ATIME))
43581f16
WD
84+ write_int(f, atime);
85 if (preserve_uid && !(flags & XMIT_SAME_UID)) {
86 if (!numeric_ids)
87 add_uid(uid);
bd68c3c2 88@@ -494,6 +506,7 @@ static struct file_struct *receive_file_
09fb8f03 89 unsigned short flags, int f)
43581f16
WD
90 {
91 static time_t modtime;
92+ static time_t atime;
93 static mode_t mode;
ba50e96c 94 static int64 dev;
43581f16 95 static dev_t rdev;
bd68c3c2 96@@ -512,7 +525,7 @@ static struct file_struct *receive_file_
43581f16
WD
97 struct file_struct *file;
98
a7219d20 99 if (!flist) {
43581f16
WD
100- modtime = 0, mode = 0;
101+ modtime = 0, atime = 0, mode = 0;
102 dev = 0, rdev = makedev(0, 0);
103 rdev_major = 0;
104 uid = 0, gid = 0;
bd68c3c2 105@@ -568,6 +581,8 @@ static struct file_struct *receive_file_
43581f16
WD
106 modtime = (time_t)read_int(f);
107 if (!(flags & XMIT_SAME_MODE))
108 mode = from_wire_mode(read_int(f));
81c32ffd 109+ if (preserve_atimes && !S_ISDIR(mode) && !(flags & XMIT_SAME_ATIME))
43581f16
WD
110+ atime = (time_t)read_int(f);
111
112 if (preserve_uid && !(flags & XMIT_SAME_UID))
113 uid = (uid_t)read_int(f);
bd68c3c2 114@@ -618,6 +633,7 @@ static struct file_struct *receive_file_
43581f16 115
9a21ad72 116 file->flags = 0;
43581f16
WD
117 file->modtime = modtime;
118+ file->atime = atime;
119 file->length = file_length;
120 file->mode = mode;
121 file->uid = uid;
bd68c3c2 122@@ -864,6 +880,7 @@ struct file_struct *make_file(char *fnam
43581f16
WD
123
124 file->flags = flags;
125 file->modtime = st.st_mtime;
126+ file->atime = st.st_atime;
127 file->length = st.st_size;
610969d1
WD
128 if (chmod_modes && am_sender && (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode)))
129 file->mode = tweak_mode(st.st_mode, chmod_modes);
bd68c3c2 130--- orig/generator.c 2006-01-14 20:27:09
f20eb450 131+++ generator.c 2005-12-15 23:05:32
81c32ffd
WD
132@@ -44,6 +44,7 @@ extern int preserve_uid;
133 extern int preserve_gid;
134 extern int preserve_times;
135 extern int omit_dir_times;
136+extern int preserve_atimes;
137 extern int delete_before;
138 extern int delete_during;
139 extern int delete_after;
f20eb450
WD
140@@ -343,10 +344,18 @@ void itemize(struct file_struct *file, i
141
142 if (S_ISREG(file->mode) && file->length != st->st_size)
143 iflags |= ITEM_REPORT_SIZE;
144- if ((iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !keep_time
145- && (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
146- || (keep_time && cmp_modtime(file->modtime, st->st_mtime) != 0))
147+ if (iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !keep_time
148+ && (!(iflags & ITEM_XNAME_FOLLOWS) || *xname)) {
149 iflags |= ITEM_REPORT_TIME;
150+ if (!preserve_atimes && !S_ISDIR(file->mode))
151+ iflags |= ITEM_REPORT_ATIME;
152+ } else {
153+ if (keep_time && cmp_time(file->modtime, st->st_mtime) != 0)
81c32ffd 154+ iflags |= ITEM_REPORT_TIME;
f20eb450
WD
155+ if (preserve_atimes && !S_ISDIR(file->mode)
156+ && cmp_time(file->atime, st->st_atime) != 0)
157+ iflags |= ITEM_REPORT_ATIME;
158+ }
159 if (preserve_perms
160 && (file->mode & CHMOD_BITS) != (st->st_mode & CHMOD_BITS))
161 iflags |= ITEM_REPORT_PERMS;
162@@ -395,7 +404,7 @@ int unchanged_file(char *fn, struct file
8cec1ead 163 if (ignore_times)
43581f16 164 return 0;
43581f16 165
8cec1ead
WD
166- return cmp_modtime(st->st_mtime, file->modtime) == 0;
167+ return cmp_time(st->st_mtime, file->modtime) == 0;
43581f16
WD
168 }
169
170
f20eb450 171@@ -555,7 +564,7 @@ static int find_fuzzy(struct file_struct
81c32ffd
WD
172 name = fp->basename;
173
174 if (fp->length == file->length
175- && cmp_modtime(fp->modtime, file->modtime) == 0) {
176+ && cmp_time(fp->modtime, file->modtime) == 0) {
177 if (verbose > 4) {
178 rprintf(FINFO,
179 "fuzzy size/modtime match for %s\n",
93ca4d27 180@@ -1068,7 +1077,7 @@ static void recv_generator(char *fname,
43581f16
WD
181 }
182
044bc34a 183 if (update_only && statret == 0
8cec1ead
WD
184- && cmp_modtime(st.st_mtime, file->modtime) > 0) {
185+ && cmp_time(st.st_mtime, file->modtime) > 0) {
43581f16 186 if (verbose > 1)
93ca4d27 187 rprintf(FINFO, "%s is newer\n", fname);
43581f16 188 return;
bd68c3c2 189--- orig/log.c 2006-01-17 02:16:40
f20eb450 190+++ log.c 2005-12-15 23:05:44
81c32ffd
WD
191@@ -38,6 +38,7 @@ extern int module_id;
192 extern int msg_fd_out;
193 extern int protocol_version;
194 extern int preserve_times;
195+extern int preserve_atimes;
f20eb450 196 extern int log_format_has_i;
81c32ffd
WD
197 extern int log_format_has_o_or_i;
198 extern int daemon_log_format_has_o_or_i;
bd68c3c2 199@@ -542,11 +543,14 @@ static void log_formatted(enum logcode c
81c32ffd
WD
200 n[4] = !(iflags & ITEM_REPORT_TIME) ? '.'
201 : !preserve_times || IS_DEVICE(file->mode)
202 || S_ISLNK(file->mode) ? 'T' : 't';
203- n[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p';
204- n[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o';
205- n[7] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g';
206- n[8] = !(iflags & ITEM_REPORT_XATTRS) ? '.' : 'a';
207- n[9] = '\0';
208+ n[5] = !(iflags & ITEM_REPORT_ATIME) ? '.'
209+ : !preserve_atimes || IS_DEVICE(file->mode)
210+ || S_ISLNK(file->mode) ? 'A' : 'a';
211+ n[6] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p';
212+ n[7] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o';
213+ n[8] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g';
214+ n[9] = !(iflags & ITEM_REPORT_XATTRS) ? '.' : 'a';
215+ n[10] = '\0';
216
217 if (iflags & (ITEM_IS_NEW|ITEM_MISSING_DATA)) {
218 char ch = iflags & ITEM_IS_NEW ? '+' : '?';
93ca4d27 219--- orig/options.c 2006-01-14 08:14:30
610969d1
WD
220+++ options.c 2005-11-07 04:32:19
221@@ -50,6 +50,7 @@ int preserve_uid = 0;
43581f16
WD
222 int preserve_gid = 0;
223 int preserve_times = 0;
9a21ad72 224 int omit_dir_times = 0;
81c32ffd 225+int preserve_atimes = 0;
43581f16
WD
226 int update_only = 0;
227 int cvs_exclude = 0;
228 int dry_run = 0;
f20eb450 229@@ -293,8 +294,9 @@ void usage(enum logcode F)
81c32ffd 230 rprintf(F," -o, --owner preserve owner (root only)\n");
43581f16
WD
231 rprintf(F," -g, --group preserve group\n");
232 rprintf(F," -D, --devices preserve devices (root only)\n");
81c32ffd
WD
233- rprintf(F," -t, --times preserve times\n");
234- rprintf(F," -O, --omit-dir-times omit directories when preserving times\n");
235+ rprintf(F," -t, --times preserve modify times\n");
236+ rprintf(F," -O, --omit-dir-times omit directories when preserving modify times\n");
58070e2e 237+ rprintf(F," -k, --atimes preserve (keep) access times\n");
610969d1 238 rprintf(F," --chmod=CHMOD change destination permissions\n");
43581f16
WD
239 rprintf(F," -S, --sparse handle sparse files efficiently\n");
240 rprintf(F," -n, --dry-run show what would have been transferred\n");
f20eb450 241@@ -402,6 +404,9 @@ static struct poptOption long_options[]
489b0a72
WD
242 {"times", 't', POPT_ARG_VAL, &preserve_times, 1, 0, 0 },
243 {"no-times", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 },
244 {"no-t", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 },
58070e2e 245+ {"atimes", 'k', POPT_ARG_VAL, &preserve_atimes, 1, 0, 0 },
489b0a72 246+ {"no-atimes", 0, POPT_ARG_VAL, &preserve_atimes, 0, 0, 0 },
58070e2e 247+ {"no-k", 0, POPT_ARG_VAL, &preserve_atimes, 0, 0, 0 },
52f25864 248 {"omit-dir-times", 'O', POPT_ARG_VAL, &omit_dir_times, 2, 0, 0 },
489b0a72
WD
249 {"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
250 {"owner", 'o', POPT_ARG_VAL, &preserve_uid, 1, 0, 0 },
93ca4d27 251@@ -1442,6 +1447,8 @@ void server_options(char **args,int *arg
43581f16
WD
252 argstr[x++] = 'D';
253 if (preserve_times)
254 argstr[x++] = 't';
81c32ffd 255+ if (preserve_atimes)
58070e2e 256+ argstr[x++] = 'k';
52f25864 257 if (omit_dir_times == 2 && am_sender)
9a21ad72 258 argstr[x++] = 'O';
43581f16 259 if (preserve_perms)
93ca4d27 260--- orig/rsync.c 2006-01-14 08:14:31
81c32ffd 261+++ rsync.c 2005-07-28 00:17:37
a5e0f697
WD
262@@ -27,6 +27,7 @@ extern int dry_run;
263 extern int daemon_log_format_has_i;
43581f16 264 extern int preserve_times;
9a21ad72 265 extern int omit_dir_times;
81c32ffd 266+extern int preserve_atimes;
43581f16 267 extern int am_root;
a7219d20 268 extern int am_server;
43581f16 269 extern int am_sender;
36bbf3d1 270@@ -56,6 +57,7 @@ int set_perms(char *fname,struct file_st
9a21ad72
WD
271 int updated = 0;
272 STRUCT_STAT st2;
273 int change_uid, change_gid;
274+ time_t atime, mtime;
275
276 if (!st) {
277 if (dry_run)
81c32ffd 278@@ -70,16 +72,29 @@ int set_perms(char *fname,struct file_st
9a21ad72 279
9e355bf1 280 if (!preserve_times || (S_ISDIR(st->st_mode) && omit_dir_times))
8a529471 281 flags |= PERMS_SKIP_MTIME;
81c32ffd
WD
282+ if (!preserve_atimes || S_ISDIR(st->st_mode))
283+ flags |= PERMS_SKIP_ATIME;
9a21ad72 284 if (!(flags & PERMS_SKIP_MTIME)
8a529471 285- && cmp_modtime(st->st_mtime, file->modtime) != 0) {
9e355bf1 286- int ret = set_modtime(fname, file->modtime, st->st_mode);
9a21ad72
WD
287+ && cmp_time(st->st_mtime, file->modtime) != 0) {
288+ mtime = file->modtime;
9e355bf1 289+ updated = 1;
9a21ad72
WD
290+ } else
291+ mtime = st->st_mtime;
81c32ffd
WD
292+ if (!(flags & PERMS_SKIP_ATIME)
293+ && cmp_time(st->st_atime, file->atime) != 0) {
294+ atime = file->atime;
295+ updated = 1;
296+ } else
297+ atime = st->st_atime;
9e355bf1
WD
298+ if (updated) {
299+ int ret = set_times(fname, mtime, atime, st->st_mode);
300 if (ret < 0) {
301 rsyserr(FERROR, errno, "failed to set times on %s",
302 full_fname(fname));
303 return 0;
304 }
305- if (ret == 0) /* ret == 1 if symlink could not be set */
306- updated = 1;
307+ if (ret > 0) /* ret == 1 if symlink could not be set */
308+ updated = 0;
43581f16
WD
309 }
310
311 change_uid = am_root && preserve_uid && st->st_uid != file->uid;
bd68c3c2 312--- orig/rsync.h 2006-01-14 20:27:10
81c32ffd 313+++ rsync.h 2005-07-28 00:04:51
43581f16
WD
314@@ -54,6 +54,7 @@
315 #define XMIT_HAS_IDEV_DATA (1<<9)
316 #define XMIT_SAME_DEV (1<<10)
317 #define XMIT_RDEV_MINOR_IS_SMALL (1<<11)
318+#define XMIT_SAME_ATIME (1<<12)
319
320 /* These flags are used in the live flist data. */
321
610969d1 322@@ -119,6 +120,7 @@
8a529471
WD
323
324 #define PERMS_REPORT (1<<0)
325 #define PERMS_SKIP_MTIME (1<<1)
326+#define PERMS_SKIP_ATIME (1<<2)
327
328 #define FULL_FLUSH 1
329 #define NORMAL_FLUSH 0
f20eb450
WD
330@@ -135,6 +137,7 @@
331 #define FNAMECMP_FUZZY 0x83
81c32ffd
WD
332
333 /* For use by the itemize_changes code */
334+#define ITEM_REPORT_ATIME (1<<0)
335 #define ITEM_REPORT_CHECKSUM (1<<1)
336 #define ITEM_REPORT_SIZE (1<<2)
337 #define ITEM_REPORT_TIME (1<<3)
bd68c3c2 338@@ -517,6 +520,7 @@ struct file_struct {
43581f16
WD
339 struct hlink *links;
340 } link_u;
341 time_t modtime;
342+ time_t atime;
343 uid_t uid;
344 gid_t gid;
345 mode_t mode;
93ca4d27 346--- orig/rsync.yo 2006-01-14 08:14:31
610969d1 347+++ rsync.yo 2005-11-07 04:34:55
9d95bd65 348@@ -319,8 +319,9 @@ to the detailed description below for a
81c32ffd
WD
349 -o, --owner preserve owner (root only)
350 -g, --group preserve group
43581f16 351 -D, --devices preserve devices (root only)
81c32ffd 352- -t, --times preserve times
610969d1 353- -O, --omit-dir-times omit directories when preserving times
81c32ffd 354+ -t, --times preserve modify times
610969d1 355+ -O, --omit-dir-times omit directories when preserving mod-times
58070e2e 356+ -k, --atimes preserve access times
610969d1 357 --chmod=CHMOD change destination permissions
43581f16
WD
358 -S, --sparse handle sparse files efficiently
359 -n, --dry-run show what would have been transferred
93ca4d27 360@@ -711,6 +712,12 @@ it is preserving modification times (see
a7219d20 361 the directories on the receiving side, it is a good idea to use bf(-O).
333b8af4 362 This option is inferred if you use bf(--backup) without bf(--backup-dir).
7b675ff5 363
58070e2e
WD
364+dit(bf(-k, --atimes)) This tells rsync to keep the access times of the
365+destination files the same value as the source files. Note that the
81c32ffd
WD
366+reading of the source file may update the atime of the source files, so
367+repeated rsync runs with --atimes may be needed if you want to force the
368+access-time values to be 100% identical on the two systems.
7b675ff5 369+
610969d1
WD
370 dit(bf(--chmod)) This options tells rsync to apply the listed "chmod" pattern
371 to the permission of the files on the destination. In addition to the normal
372 parsing rules specified in the chmod manpage, you can specify an item that
93ca4d27 373@@ -1160,7 +1167,7 @@ changes that are being made to each file
81c32ffd
WD
374 This is exactly the same as specifying bf(--log-format='%i %n%L').
375
376 The "%i" escape has a cryptic output that is 9 letters long. The general
377-format is like the string bf(UXcstpoga)), where bf(U) is replaced by the
378+format is like the string bf(UXcstapogx)), where bf(U) is replaced by the
379 kind of update being done, bf(X) is replaced by the file-type, and the
380 other letters represent attributes that may be output if they are being
381 modified.
93ca4d27 382@@ -1199,17 +1206,22 @@ quote(itemize(
81c32ffd
WD
383 by the file transfer.
384 it() A bf(t) means the modification time is different and is being updated
385 to the sender's value (requires bf(--times)). An alternate value of bf(T)
386- means that the time will be set to the transfer time, which happens
387+ means that the modify time will be set to the transfer time, which happens
388 anytime a symlink is transferred, or when a file or device is transferred
389 without bf(--times).
390+ it() A bf(a) means the access time is different and is being updated to
391+ the sender's value (requires bf(--atimes)). An alternate value of bf(A)
392+ means that the access time will be set to the transfer time, which happens
393+ anytime a symlink is transferred, or when a file or device is transferred
394+ without bf(--atimes).
395 it() A bf(p) means the permissions are different and are being updated to
396 the sender's value (requires bf(--perms)).
397 it() An bf(o) means the owner is different and is being updated to the
398 sender's value (requires bf(--owner) and root privileges).
399 it() A bf(g) means the group is different and is being updated to the
400 sender's value (requires bf(--group) and the authority to set the group).
401- it() The bf(a) is reserved for a future enhanced version that supports
402- extended file attributes, such as ACLs.
403+ it() The bf(x) is reserved for a future enhanced version that supports
404+ extended file attributes.
405 ))
406
407 One other output is possible: when deleting files, the "%i" will output
408--- orig/testsuite/atimes.test 2004-06-30 00:06:23
409+++ testsuite/atimes.test 2004-06-30 00:06:23
13bed3dd
WD
410@@ -0,0 +1,19 @@
411+#! /bin/sh
412+
413+# Test rsync copying atimes
414+
415+. "$suitedir/rsync.fns"
416+
417+set -x
418+
419+mkdir "$fromdir"
420+
421+touch "$fromdir/foo"
422+touch -a -t 200102031717.42 "$fromdir/foo"
423+
424+TLS_ARGS=--atime
425+
426+checkit "$RSYNC -rtAgvvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
427+
428+# The script would have aborted on error, so getting here means we've won.
429+exit 0
f20eb450
WD
430--- orig/testsuite/itemize.test 2005-12-15 23:00:49
431+++ testsuite/itemize.test 2005-12-15 23:11:34
81c32ffd
WD
432@@ -44,14 +44,14 @@ ln "$fromdir/foo/config1" "$fromdir/foo/
433 $RSYNC -iplr "$fromdir/" "$todir/" \
434 | tee "$outfile"
435 cat <<EOT >"$chkfile"
436-cd+++++++ bar/
437-cd+++++++ bar/baz/
438->f+++++++ bar/baz/rsync
439-cd+++++++ foo/
440->f+++++++ foo/config1
441->f+++++++ foo/config2
442->f+++++++ foo/extra
443-cL+++++++ foo/sym -> ../bar/baz/rsync
444+cd++++++++ bar/
445+cd++++++++ bar/baz/
446+>f++++++++ bar/baz/rsync
447+cd++++++++ foo/
448+>f++++++++ foo/config1
449+>f++++++++ foo/config2
450+>f++++++++ foo/extra
451+cL++++++++ foo/sym -> ../bar/baz/rsync
452 EOT
453 diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed"
454
455@@ -63,10 +63,10 @@ chmod 601 "$fromdir/foo/config2"
456 $RSYNC -iplrH "$fromdir/" "$todir/" \
457 | tee "$outfile"
458 cat <<EOT >"$chkfile"
459->f..T.... bar/baz/rsync
460->f..T.... foo/config1
461->f.sTp... foo/config2
462-hf..T.... foo/extra => foo/config1
463+>f..TA.... bar/baz/rsync
464+>f..TA.... foo/config1
465+>f.sTAp... foo/config2
466+hf..TA.... foo/extra => foo/config1
467 EOT
468 diff $diffopt "$chkfile" "$outfile" || test_fail "test 2 failed"
469
470@@ -83,11 +83,11 @@ chmod 777 "$todir/bar/baz/rsync"
471 $RSYNC -iplrtc "$fromdir/" "$todir/" \
472 | tee "$outfile"
473 cat <<EOT >"$chkfile"
474-.f..tp... bar/baz/rsync
475-.d..t.... foo/
476-.f..t.... foo/config1
477->fcstp... foo/config2
478-cL..T.... foo/sym -> ../bar/baz/rsync
479+.f..t.p... bar/baz/rsync
480+.d..t..... foo/
481+.f..t..... foo/config1
482+>fcst.p... foo/config2
483+cL..TA.... foo/sym -> ../bar/baz/rsync
484 EOT
485 diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed"
486
487@@ -112,15 +112,15 @@ $RSYNC -ivvplrtH "$fromdir/" "$todir/" \
488 | tee "$outfile"
489 filter_outfile
490 cat <<EOT >"$chkfile"
491-.d ./
492-.d bar/
493-.d bar/baz/
494-.f...p... bar/baz/rsync
495-.d foo/
496-.f foo/config1
497->f..t.... foo/config2
498-hf foo/extra
499-.L foo/sym -> ../bar/baz/rsync
500+.d ./
501+.d bar/
502+.d bar/baz/
503+.f....p... bar/baz/rsync
504+.d foo/
505+.f foo/config1
506+>f..t..... foo/config2
507+hf foo/extra
508+.L foo/sym -> ../bar/baz/rsync
509 EOT
510 diff $diffopt "$chkfile" "$outfile" || test_fail "test 5 failed"
511
512@@ -139,8 +139,8 @@ touch "$todir/foo/config2"
513 $RSYNC -iplrtH "$fromdir/" "$todir/" \
514 | tee "$outfile"
515 cat <<EOT >"$chkfile"
516-.f...p... foo/config1
517->f..t.... foo/config2
518+.f....p... foo/config1
519+>f..t..... foo/config2
520 EOT
521 diff $diffopt "$chkfile" "$outfile" || test_fail "test 7 failed"
522
523@@ -149,15 +149,15 @@ $RSYNC -ivvplrtH --copy-dest="$lddir" "$
524 | tee "$outfile"
525 filter_outfile
526 cat <<EOT >"$chkfile"
527-.d..t.... ./
528-cd+++++++ bar/
529-cd+++++++ bar/baz/
f20eb450 530-cf bar/baz/rsync
81c32ffd 531-cd+++++++ foo/
f20eb450
WD
532-cf foo/config1
533-cf foo/config2
534-hf foo/extra => foo/config1
535-cL..T.... foo/sym -> ../bar/baz/rsync
81c32ffd
WD
536+.d..t..... ./
537+cd++++++++ bar/
538+cd++++++++ bar/baz/
f20eb450 539+cf bar/baz/rsync
81c32ffd 540+cd++++++++ foo/
f20eb450
WD
541+cf foo/config1
542+cf foo/config2
543+hf foo/extra => foo/config1
544+cL..T..... foo/sym -> ../bar/baz/rsync
81c32ffd
WD
545 EOT
546 diff $diffopt "$chkfile" "$outfile" || test_fail "test 8 failed"
547
f20eb450
WD
548@@ -165,11 +165,11 @@ rm -rf "$todir"
549 $RSYNC -iplrtH --copy-dest="$lddir" "$fromdir/" "$todir/" \
81c32ffd
WD
550 | tee "$outfile"
551 cat <<EOT >"$chkfile"
552-.d..t.... ./
553-cd+++++++ bar/
554-cd+++++++ bar/baz/
555-cd+++++++ foo/
f20eb450 556-hf foo/extra => foo/config1
81c32ffd
WD
557+.d..t..... ./
558+cd++++++++ bar/
559+cd++++++++ bar/baz/
560+cd++++++++ foo/
f20eb450 561+hf foo/extra => foo/config1
81c32ffd
WD
562 EOT
563 diff $diffopt "$chkfile" "$outfile" || test_fail "test 9 failed"
564
f20eb450
WD
565@@ -196,15 +196,15 @@ $RSYNC -ivvplrtH --link-dest="$lddir" "$
566 | tee "$outfile"
567 filter_outfile
568 cat <<EOT >"$chkfile"
569-.d..t.... ./
570-cd+++++++ bar/
571-cd+++++++ bar/baz/
572-hf bar/baz/rsync
573-cd+++++++ foo/
574-hf foo/config1
575-hf foo/config2
576-hf foo/extra => foo/config1
577-hL foo/sym -> ../bar/baz/rsync
578+.d..t..... ./
579+cd++++++++ bar/
580+cd++++++++ bar/baz/
581+hf bar/baz/rsync
582+cd++++++++ foo/
583+hf foo/config1
584+hf foo/config2
585+hf foo/extra => foo/config1
586+hL foo/sym -> ../bar/baz/rsync
587 EOT
588 diff $diffopt "$chkfile" "$outfile" || test_fail "test 11 failed"
589
590@@ -212,10 +212,10 @@ rm -rf "$todir"
591 $RSYNC -iplrtH --link-dest="$lddir" "$fromdir/" "$todir/" \
592 | tee "$outfile"
593 cat <<EOT >"$chkfile"
594-.d..t.... ./
595-cd+++++++ bar/
596-cd+++++++ bar/baz/
597-cd+++++++ foo/
598+.d..t..... ./
599+cd++++++++ bar/
600+cd++++++++ bar/baz/
601+cd++++++++ foo/
602 EOT
603 diff $diffopt "$chkfile" "$outfile" || test_fail "test 12 failed"
604
605@@ -243,14 +243,14 @@ filter_outfile
606 # TODO fix really-old problem when combining -H with --compare-dest:
607 # missing output for foo/extra hard-link (and it might not be updated)!
608 cat <<EOT >"$chkfile"
609-.d..t.... ./
610-cd+++++++ bar/
611-cd+++++++ bar/baz/
612-.f bar/baz/rsync
613-cd+++++++ foo/
614-.f foo/config1
615-.f foo/config2
616-.L foo/sym -> ../bar/baz/rsync
617+.d..t..... ./
618+cd++++++++ bar/
619+cd++++++++ bar/baz/
620+.f bar/baz/rsync
621+cd++++++++ foo/
622+.f foo/config1
623+.f foo/config2
624+.L foo/sym -> ../bar/baz/rsync
625 EOT
626 diff $diffopt "$chkfile" "$outfile" || test_fail "test 14 failed"
627
628@@ -258,10 +258,10 @@ rm -rf "$todir"
629 $RSYNC -iplrtH --compare-dest="$lddir" "$fromdir/" "$todir/" \
630 | tee "$outfile"
631 cat <<EOT >"$chkfile"
632-.d..t.... ./
633-cd+++++++ bar/
634-cd+++++++ bar/baz/
635-cd+++++++ foo/
636+.d..t..... ./
637+cd++++++++ bar/
638+cd++++++++ bar/baz/
639+cd++++++++ foo/
640 EOT
641 diff $diffopt "$chkfile" "$outfile" || test_fail "test 15 failed"
642
9e355bf1 643--- orig/testsuite/rsync.fns 2005-06-10 21:33:28
81c32ffd 644+++ testsuite/rsync.fns 2005-07-28 00:41:20
13bed3dd
WD
645@@ -50,7 +50,7 @@ printmsg() {
646
647
648 rsync_ls_lR() {
b78a6aba
WD
649- find "$@" -print | sort | sed 's/ /\\ /g' | xargs "$TOOLDIR/tls"
650+ find "$@" -print | sort | sed 's/ /\\ /g' | xargs "$TOOLDIR/tls" $TLS_ARGS
13bed3dd
WD
651 }
652
653 rsync_getgroups() {
81c32ffd 654@@ -158,6 +158,10 @@ checkit() {
13bed3dd
WD
655 # We can just write everything to stdout/stderr, because the
656 # wrapper hides it unless there is a problem.
657
81c32ffd
WD
658+ if test x$TLS_ARGS = x--atime; then
659+ ( cd "$2" && rsync_ls_lR . ) > "$tmpdir/ls-from"
660+ fi
13bed3dd
WD
661+
662 echo "Running: \"$1\""
663 eval "$1"
664 status=$?
81c32ffd
WD
665@@ -165,10 +169,13 @@ checkit() {
666 failed="YES";
667 fi
668
669+ if test x$TLS_ARGS != x--atime; then
670+ ( cd "$2" && rsync_ls_lR . ) > "$tmpdir/ls-from"
671+ fi
672+
13bed3dd 673 echo "-------------"
b78a6aba
WD
674 echo "check how the directory listings compare with diff:"
675 echo ""
13bed3dd 676- ( cd "$2" && rsync_ls_lR . ) > "$tmpdir/ls-from"
b78a6aba
WD
677 ( cd "$3" && rsync_ls_lR . ) > "$tmpdir/ls-to"
678 diff $diffopt "$tmpdir/ls-from" "$tmpdir/ls-to" || failed=YES
4da25dad 679
9d95bd65 680--- orig/tls.c 2005-09-24 17:40:31
c0be1af2 681+++ tls.c 2005-03-23 17:49:48
43581f16
WD
682@@ -39,6 +39,7 @@
683
684
685 #include "rsync.h"
686+#include "popt.h"
687
688 #define PROGRAM "tls"
689
690@@ -48,6 +49,7 @@ int read_only = 1;
691 int list_only = 0;
692 int preserve_perms = 0;
693
694+static int display_atime = 0;
695
fe6407b5
WD
696 static void failed(char const *what, char const *where)
697 {
698@@ -56,14 +58,29 @@ static void failed(char const *what, cha
699 exit(1);
43581f16
WD
700 }
701
702+static void storetime(char *dest, time_t t)
703+{
704+ if (t) {
705+ struct tm *mt = gmtime(&t);
706
707+ sprintf(dest, "%04d-%02d-%02d %02d:%02d:%02d ",
9d95bd65
WD
708+ (int)mt->tm_year + 1900,
709+ (int)mt->tm_mon + 1,
710+ (int)mt->tm_mday,
711+ (int)mt->tm_hour,
712+ (int)mt->tm_min,
713+ (int)mt->tm_sec);
43581f16
WD
714+ } else {
715+ strcpy(dest, " ");
716+ }
717+}
718
fe6407b5 719 static void list_file(const char *fname)
43581f16
WD
720 {
721 STRUCT_STAT buf;
722 char permbuf[PERMSTRING_SIZE];
723- struct tm *mt;
724- char datebuf[50];
725+ char mtimebuf[50];
726+ char atimebuf[50];
727 char linkbuf[4096];
728
ba50e96c
WD
729 if (do_lstat(fname, &buf) < 0)
730@@ -96,19 +113,8 @@ static void list_file(const char *fname)
43581f16
WD
731
732 permstring(permbuf, buf.st_mode);
733
734- if (buf.st_mtime) {
735- mt = gmtime(&buf.st_mtime);
736-
737- sprintf(datebuf, "%04d-%02d-%02d %02d:%02d:%02d",
9d95bd65
WD
738- (int)mt->tm_year + 1900,
739- (int)mt->tm_mon + 1,
740- (int)mt->tm_mday,
741- (int)mt->tm_hour,
742- (int)mt->tm_min,
743- (int)mt->tm_sec);
43581f16
WD
744- } else {
745- strcpy(datebuf, " ");
746- }
747+ storetime(mtimebuf, buf.st_mtime);
748+ storetime(atimebuf, buf.st_atime);
749
750 /* TODO: Perhaps escape special characters in fname? */
751
ba50e96c 752@@ -119,24 +125,55 @@ static void list_file(const char *fname)
43581f16
WD
753 (long)minor(buf.st_rdev));
754 } else /* NB: use double for size since it might not fit in a long. */
755 printf("%12.0f", (double)buf.st_size);
756- printf(" %6ld.%-6ld %6ld %s %s%s\n",
757+ printf(" %6ld.%-6ld %6ld %s%s%s%s\n",
758 (long)buf.st_uid, (long)buf.st_gid, (long)buf.st_nlink,
759- datebuf, fname, linkbuf);
c0be1af2 760+ mtimebuf, display_atime && !S_ISDIR(buf.st_mode) ? atimebuf : "",
43581f16
WD
761+ fname, linkbuf);
762 }
763
764+static struct poptOption long_options[] = {
765+ /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
766+ {"atime", 'u', POPT_ARG_NONE, &display_atime, 0, 0, 0},
767+ {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0},
768+ {0,0,0,0,0,0,0}
769+};
770+
771+static void tls_usage(int ret)
772+{
773+ fprintf(stderr, "usage: " PROGRAM " [--atime | -u] DIR ...\n"
774+ "Trivial file listing program for portably checking rsync\n");
775+ exit(ret);
776+}
777
778 int
779 main(int argc, char *argv[])
780 {
781- if (argc < 2) {
fe6407b5
WD
782- fprintf(stderr, "usage: " PROGRAM " DIR ...\n"
783- "Trivial file listing program for portably checking rsync\n");
43581f16
WD
784- return 1;
785+ poptContext pc;
786+ const char **extra_args;
787+ int opt;
788+
789+ pc = poptGetContext(PROGRAM, argc, (const char **)argv,
790+ long_options, 0);
791+ while ((opt = poptGetNextOpt(pc)) != -1) {
792+ switch (opt) {
793+ case 'h':
794+ tls_usage(0);
795+ default:
796+ fprintf(stderr,
797+ "%s: %s\n",
798+ poptBadOption(pc, POPT_BADOPTION_NOALIAS),
799+ poptStrerror(opt));
800+ tls_usage(1);
801+ }
802 }
803
804- for (argv++; *argv; argv++) {
fe6407b5 805- list_file(*argv);
43581f16
WD
806- }
807+ extra_args = poptGetArgs(pc);
808+ if (*extra_args == NULL)
809+ tls_usage(1);
810+
811+ for (; *extra_args; extra_args++)
812+ list_file(*extra_args);
813+ poptFreeContext(pc);
814
815 return 0;
816 }
93ca4d27
WD
817--- orig/util.c 2006-01-14 08:14:31
818+++ util.c 2006-01-14 08:20:29
f20eb450 819@@ -130,7 +130,7 @@ void overflow_exit(char *str)
43581f16
WD
820
821
822
9e355bf1
WD
823-int set_modtime(char *fname, time_t modtime, mode_t mode)
824+int set_times(char *fname, time_t modtime, time_t atime, mode_t mode)
43581f16 825 {
9e355bf1
WD
826 #if !defined HAVE_LUTIMES || !defined HAVE_UTIMES
827 if (S_ISLNK(mode))
f20eb450 828@@ -138,9 +138,13 @@ int set_modtime(char *fname, time_t modt
9e355bf1
WD
829 #endif
830
43581f16
WD
831 if (verbose > 2) {
832- rprintf(FINFO, "set modtime of %s to (%ld) %s",
833+ char mtimebuf[200];
43581f16 834+
125d7fca 835+ strlcpy(mtimebuf, timestring(modtime), sizeof mtimebuf);
43581f16
WD
836+ rprintf(FINFO,
837+ "set modtime, atime of %s to (%ld) %s, (%ld) %s\n",
93ca4d27 838 fname, (long)modtime,
43581f16 839- asctime(localtime(&modtime)));
9e355bf1 840+ mtimebuf, (long)atime, timestring(atime));
43581f16
WD
841 }
842
ba50e96c 843 if (dry_run)
f20eb450 844@@ -149,7 +153,7 @@ int set_modtime(char *fname, time_t modt
43581f16 845 {
9e355bf1
WD
846 #ifdef HAVE_UTIMES
847 struct timeval t[2];
848- t[0].tv_sec = time(NULL);
849+ t[0].tv_sec = atime;
850 t[0].tv_usec = 0;
851 t[1].tv_sec = modtime;
852 t[1].tv_usec = 0;
f20eb450 853@@ -160,12 +164,12 @@ int set_modtime(char *fname, time_t modt
9e355bf1
WD
854 return utimes(fname, t);
855 #elif defined HAVE_UTIMBUF
43581f16
WD
856 struct utimbuf tbuf;
857- tbuf.actime = time(NULL);
858+ tbuf.actime = atime;
859 tbuf.modtime = modtime;
860 return utime(fname,&tbuf);
09fb8f03 861 #elif defined HAVE_UTIME
43581f16
WD
862 time_t t[2];
863- t[0] = time(NULL);
864+ t[0] = atime;
865 t[1] = modtime;
866 return utime(fname,t);
867 #else
93ca4d27 868@@ -1191,8 +1195,8 @@ int msleep(int t)
43581f16
WD
869
870
871 /**
872- * Determine if two file modification times are equivalent (either
873- * exact or in the modification timestamp window established by
874+ * Determine if two file times are equivalent (either
875+ * exact or in the timestamp window established by
876 * --modify-window).
877 *
878 * @retval 0 if the times should be treated as the same
93ca4d27 879@@ -1201,7 +1205,7 @@ int msleep(int t)
43581f16
WD
880 *
881 * @retval -1 if the 2nd is later
882 **/
883-int cmp_modtime(time_t file1, time_t file2)
884+int cmp_time(time_t file1, time_t file2)
885 {
7b675ff5
WD
886 if (file2 > file1) {
887 if (file2 - file1 <= modify_window)