Fixed the patch (it had bit-rotted over time). Also changed it
[rsync/rsync-patches.git] / atimes.diff
... / ...
CommitLineData
1After applying this patch and running configure, you MUST run this
2command before "make":
3
4 make proto
5
6
7--- orig/batch.c 2005-10-26 16:49:08
8+++ batch.c 2004-07-03 20:15:41
9@@ -225,6 +225,8 @@ void show_flist(int index, struct file_s
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);
18--- orig/flist.c 2005-11-07 04:29:01
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;
26 extern int implied_dirs;
27 extern int copy_links;
28@@ -138,16 +139,18 @@ static void list_file_entry(struct file_
29
30 #ifdef SUPPORT_LINKS
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,
35 (double)f->length, timestring(f->modtime),
36+ timestring(f->atime),
37 safe_fname(f_name(f)), safe_fname(f->u.link));
38 } else
39 #endif
40 {
41- rprintf(FINFO, "%s %11.0f %s %s\n",
42+ rprintf(FINFO, "%s %11.0f %s %s %s\n",
43 perms,
44 (double)f->length, timestring(f->modtime),
45+ timestring(f->atime),
46 safe_fname(f_name(f)));
47 }
48 }
49@@ -309,6 +312,7 @@ void send_file_entry(struct file_struct
50 {
51 unsigned short flags;
52 static time_t modtime;
53+ static time_t atime;
54 static mode_t mode;
55 static int64 dev;
56 static dev_t rdev;
57@@ -324,7 +328,7 @@ void send_file_entry(struct file_struct
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;
66@@ -373,6 +377,12 @@ void send_file_entry(struct file_struct
67 flags |= XMIT_SAME_TIME;
68 else
69 modtime = file->modtime;
70+ if (preserve_atimes && !S_ISDIR(mode)) {
71+ if (file->atime == atime)
72+ flags |= XMIT_SAME_ATIME;
73+ else
74+ atime = file->atime;
75+ }
76
77 #ifdef SUPPORT_HARD_LINKS
78 if (file->link_u.idev) {
79@@ -426,6 +436,8 @@ void send_file_entry(struct file_struct
80 write_int(f, modtime);
81 if (!(flags & XMIT_SAME_MODE))
82 write_int(f, to_wire_mode(mode));
83+ if (preserve_atimes && !S_ISDIR(mode) && !(flags & XMIT_SAME_ATIME))
84+ write_int(f, atime);
85 if (preserve_uid && !(flags & XMIT_SAME_UID)) {
86 if (!numeric_ids)
87 add_uid(uid);
88@@ -494,6 +506,7 @@ static struct file_struct *receive_file_
89 unsigned short flags, int f)
90 {
91 static time_t modtime;
92+ static time_t atime;
93 static mode_t mode;
94 static int64 dev;
95 static dev_t rdev;
96@@ -512,7 +525,7 @@ static struct file_struct *receive_file_
97 struct file_struct *file;
98
99 if (!flist) {
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;
105@@ -568,6 +581,8 @@ static struct file_struct *receive_file_
106 modtime = (time_t)read_int(f);
107 if (!(flags & XMIT_SAME_MODE))
108 mode = from_wire_mode(read_int(f));
109+ if (preserve_atimes && !S_ISDIR(mode) && !(flags & XMIT_SAME_ATIME))
110+ atime = (time_t)read_int(f);
111
112 if (preserve_uid && !(flags & XMIT_SAME_UID))
113 uid = (uid_t)read_int(f);
114@@ -618,6 +633,7 @@ static struct file_struct *receive_file_
115
116 file->flags = 0;
117 file->modtime = modtime;
118+ file->atime = atime;
119 file->length = file_length;
120 file->mode = mode;
121 file->uid = uid;
122@@ -866,6 +882,7 @@ skip_filters:
123
124 file->flags = flags;
125 file->modtime = st.st_mtime;
126+ file->atime = st.st_atime;
127 file->length = st.st_size;
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
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;
140@@ -325,9 +326,21 @@ void itemize(struct file_struct *file, i
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))
163@@ -379,7 +392,7 @@ static int unchanged_file(char *fn, stru
164 if (ignore_times)
165 return 0;
166
167- return cmp_modtime(st->st_mtime, file->modtime) == 0;
168+ return cmp_time(st->st_mtime, file->modtime) == 0;
169 }
170
171
172@@ -539,7 +552,7 @@ static int find_fuzzy(struct file_struct
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",
181@@ -891,7 +904,7 @@ static void recv_generator(char *fname,
182 }
183
184 if (update_only && statret == 0
185- && cmp_modtime(st.st_mtime, file->modtime) > 0) {
186+ && cmp_time(st.st_mtime, file->modtime) > 0) {
187 if (verbose > 1)
188 rprintf(FINFO, "%s is newer\n", safe_fname(fname));
189 return;
190--- orig/log.c 2005-10-26 16:49:08
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;
200@@ -503,11 +504,14 @@ static void log_formatted(enum logcode c
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 ? '+' : '?';
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;
223 int preserve_gid = 0;
224 int preserve_times = 0;
225 int omit_dir_times = 0;
226+int preserve_atimes = 0;
227 int update_only = 0;
228 int cvs_exclude = 0;
229 int dry_run = 0;
230@@ -292,8 +293,9 @@ void usage(enum logcode F)
231 rprintf(F," -o, --owner preserve owner (root only)\n");
232 rprintf(F," -g, --group preserve group\n");
233 rprintf(F," -D, --devices preserve devices (root only)\n");
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");
239 rprintf(F," --chmod=CHMOD change destination permissions\n");
240 rprintf(F," -S, --sparse handle sparse files efficiently\n");
241 rprintf(F," -n, --dry-run show what would have been transferred\n");
242@@ -397,6 +399,9 @@ static struct poptOption long_options[]
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 },
249 {"omit-dir-times", 'O', POPT_ARG_VAL, &omit_dir_times, 2, 0, 0 },
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 },
252@@ -1429,6 +1434,8 @@ void server_options(char **args,int *arg
253 argstr[x++] = 'D';
254 if (preserve_times)
255 argstr[x++] = 't';
256+ if (preserve_atimes)
257+ argstr[x++] = 'A';
258 if (omit_dir_times == 2 && am_sender)
259 argstr[x++] = 'O';
260 if (preserve_perms)
261--- orig/rsync.c 2005-07-27 23:31:12
262+++ rsync.c 2005-07-28 00:17:37
263@@ -27,6 +27,7 @@ extern int dry_run;
264 extern int daemon_log_format_has_i;
265 extern int preserve_times;
266 extern int omit_dir_times;
267+extern int preserve_atimes;
268 extern int am_root;
269 extern int am_server;
270 extern int am_sender;
271@@ -56,6 +57,7 @@ int set_perms(char *fname,struct file_st
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)
279@@ -70,16 +72,29 @@ int set_perms(char *fname,struct file_st
280
281 if (!preserve_times || (S_ISDIR(st->st_mode) && omit_dir_times))
282 flags |= PERMS_SKIP_MTIME;
283+ if (!preserve_atimes || S_ISDIR(st->st_mode))
284+ flags |= PERMS_SKIP_ATIME;
285 if (!(flags & PERMS_SKIP_MTIME)
286- && cmp_modtime(st->st_mtime, file->modtime) != 0) {
287- int ret = set_modtime(fname, file->modtime, st->st_mode);
288+ && cmp_time(st->st_mtime, file->modtime) != 0) {
289+ mtime = file->modtime;
290+ updated = 1;
291+ } else
292+ mtime = st->st_mtime;
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;
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;
310 }
311
312 change_uid = am_root && preserve_uid && st->st_uid != file->uid;
313--- orig/rsync.h 2005-10-14 18:45:50
314+++ rsync.h 2005-07-28 00:04:51
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
323@@ -119,6 +120,7 @@
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
331@@ -140,6 +142,7 @@
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)
339@@ -522,6 +525,7 @@ struct file_struct {
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;
347--- orig/rsync.yo 2005-11-07 04:29:02
348+++ rsync.yo 2005-11-07 04:34:55
349@@ -319,8 +319,9 @@ to the detailed description below for a
350 -o, --owner preserve owner (root only)
351 -g, --group preserve group
352 -D, --devices preserve devices (root only)
353- -t, --times preserve times
354- -O, --omit-dir-times omit directories when preserving times
355+ -t, --times preserve modify times
356+ -O, --omit-dir-times omit directories when preserving mod-times
357+ -A, --atimes preserve access times
358 --chmod=CHMOD change destination permissions
359 -S, --sparse handle sparse files efficiently
360 -n, --dry-run show what would have been transferred
361@@ -698,6 +699,12 @@ it is preserving modification times (see
362 the directories on the receiving side, it is a good idea to use bf(-O).
363 This option is inferred if you use bf(--backup) without bf(--backup-dir).
364
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.
370+
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
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.
383@@ -1178,17 +1185,22 @@ quote(itemize(
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
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
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
568--- orig/testsuite/rsync.fns 2005-06-10 21:33:28
569+++ testsuite/rsync.fns 2005-07-28 00:41:20
570@@ -50,7 +50,7 @@ printmsg() {
571
572
573 rsync_ls_lR() {
574- find "$@" -print | sort | sed 's/ /\\ /g' | xargs "$TOOLDIR/tls"
575+ find "$@" -print | sort | sed 's/ /\\ /g' | xargs "$TOOLDIR/tls" $TLS_ARGS
576 }
577
578 rsync_getgroups() {
579@@ -158,6 +158,10 @@ checkit() {
580 # We can just write everything to stdout/stderr, because the
581 # wrapper hides it unless there is a problem.
582
583+ if test x$TLS_ARGS = x--atime; then
584+ ( cd "$2" && rsync_ls_lR . ) > "$tmpdir/ls-from"
585+ fi
586+
587 echo "Running: \"$1\""
588 eval "$1"
589 status=$?
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+
598 echo "-------------"
599 echo "check how the directory listings compare with diff:"
600 echo ""
601- ( cd "$2" && rsync_ls_lR . ) > "$tmpdir/ls-from"
602 ( cd "$3" && rsync_ls_lR . ) > "$tmpdir/ls-to"
603 diff $diffopt "$tmpdir/ls-from" "$tmpdir/ls-to" || failed=YES
604
605--- orig/tls.c 2005-09-24 17:40:31
606+++ tls.c 2005-03-23 17:49:48
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
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);
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 ",
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);
639+ } else {
640+ strcpy(dest, " ");
641+ }
642+}
643
644 static void list_file(const char *fname)
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
654 if (do_lstat(fname, &buf) < 0)
655@@ -96,19 +113,8 @@ static void list_file(const char *fname)
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",
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);
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
677@@ -119,24 +125,55 @@ static void list_file(const char *fname)
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);
685+ mtimebuf, display_atime && !S_ISDIR(buf.st_mode) ? atimebuf : "",
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) {
707- fprintf(stderr, "usage: " PROGRAM " DIR ...\n"
708- "Trivial file listing program for portably checking rsync\n");
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++) {
730- list_file(*argv);
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 }
742--- orig/util.c 2005-10-16 22:38:40
743+++ util.c 2005-07-27 23:37:27
744@@ -129,7 +129,7 @@ void overflow_exit(char *str)
745
746
747
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)
750 {
751 #if !defined HAVE_LUTIMES || !defined HAVE_UTIMES
752 if (S_ISLNK(mode))
753@@ -137,9 +137,13 @@ int set_modtime(char *fname, time_t modt
754 #endif
755
756 if (verbose > 2) {
757- rprintf(FINFO, "set modtime of %s to (%ld) %s",
758+ char mtimebuf[200];
759+
760+ strlcpy(mtimebuf, timestring(modtime), sizeof mtimebuf);
761+ rprintf(FINFO,
762+ "set modtime, atime of %s to (%ld) %s, (%ld) %s\n",
763 safe_fname(fname), (long)modtime,
764- asctime(localtime(&modtime)));
765+ mtimebuf, (long)atime, timestring(atime));
766 }
767
768 if (dry_run)
769@@ -148,7 +152,7 @@ int set_modtime(char *fname, time_t modt
770 {
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;
778@@ -159,12 +163,12 @@ int set_modtime(char *fname, time_t modt
779 return utimes(fname, t);
780 #elif defined HAVE_UTIMBUF
781 struct utimbuf tbuf;
782- tbuf.actime = time(NULL);
783+ tbuf.actime = atime;
784 tbuf.modtime = modtime;
785 return utime(fname,&tbuf);
786 #elif defined HAVE_UTIME
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
793@@ -1171,8 +1175,8 @@ int msleep(int t)
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
804@@ -1181,7 +1185,7 @@ int msleep(int t)
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 {
811 if (file2 > file1) {
812 if (file2 - file1 <= modify_window)