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