Changed f_name() to new syntax.
[rsync-patches.git] / atimes.diff
1 After applying this patch and running configure, you MUST run this
2 command before "make":
3
4     make proto
5
6
7 --- orig/batch.c        2006-01-14 08:14:29
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        2006-01-17 02:15:59
19 +++ flist.c     2006-01-17 02:42:04
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 @@ -139,16 +140,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                         f_name(f, NULL), 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                         f_name(f, NULL));
47         }
48  }
49 @@ -310,6 +313,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 @@ -325,7 +329,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 @@ -374,6 +378,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 @@ -427,6 +437,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 @@ -864,6 +880,7 @@ struct file_struct *make_file(char *fnam
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    2006-01-14 20:27:09
131 +++ generator.c 2005-12-15 23:05:32
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 @@ -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)
154 +                               iflags |= ITEM_REPORT_TIME;
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
163         if (ignore_times)
164                 return 0;
165  
166 -       return cmp_modtime(st->st_mtime, file->modtime) == 0;
167 +       return cmp_time(st->st_mtime, file->modtime) == 0;
168  }
169  
170  
171 @@ -555,7 +564,7 @@ static int find_fuzzy(struct file_struct
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",
180 @@ -1068,7 +1077,7 @@ static void recv_generator(char *fname, 
181         }
182  
183         if (update_only && statret == 0
184 -           && cmp_modtime(st.st_mtime, file->modtime) > 0) {
185 +           && cmp_time(st.st_mtime, file->modtime) > 0) {
186                 if (verbose > 1)
187                         rprintf(FINFO, "%s is newer\n", fname);
188                 return;
189 --- orig/log.c  2006-01-17 02:16:40
190 +++ log.c       2005-12-15 23:05:44
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;
196  extern int log_format_has_i;
197  extern int log_format_has_o_or_i;
198  extern int daemon_log_format_has_o_or_i;
199 @@ -542,11 +543,14 @@ static void log_formatted(enum logcode c
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 ? '+' : '?';
219 --- orig/options.c      2006-01-14 08:14:30
220 +++ options.c   2005-11-07 04:32:19
221 @@ -50,6 +50,7 @@ int preserve_uid = 0;
222  int preserve_gid = 0;
223  int preserve_times = 0;
224  int omit_dir_times = 0;
225 +int preserve_atimes = 0;
226  int update_only = 0;
227  int cvs_exclude = 0;
228  int dry_run = 0;
229 @@ -293,8 +294,9 @@ void usage(enum logcode F)
230    rprintf(F," -o, --owner                 preserve owner (root only)\n");
231    rprintf(F," -g, --group                 preserve group\n");
232    rprintf(F," -D, --devices               preserve devices (root only)\n");
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");
237 +  rprintf(F," -A, --atimes                preserve access times\n");
238    rprintf(F,"     --chmod=CHMOD           change destination permissions\n");
239    rprintf(F," -S, --sparse                handle sparse files efficiently\n");
240    rprintf(F," -n, --dry-run               show what would have been transferred\n");
241 @@ -402,6 +404,9 @@ static struct poptOption long_options[] 
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 },
245 +  {"atimes",          'A', POPT_ARG_VAL,    &preserve_atimes, 1, 0, 0 },
246 +  {"no-atimes",        0,  POPT_ARG_VAL,    &preserve_atimes, 0, 0, 0 },
247 +  {"no-A",             0,  POPT_ARG_VAL,    &preserve_atimes, 0, 0, 0 },
248    {"omit-dir-times",  'O', POPT_ARG_VAL,    &omit_dir_times, 2, 0, 0 },
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 },
251 @@ -1442,6 +1447,8 @@ void server_options(char **args,int *arg
252                 argstr[x++] = 'D';
253         if (preserve_times)
254                 argstr[x++] = 't';
255 +       if (preserve_atimes)
256 +               argstr[x++] = 'A';
257         if (omit_dir_times == 2 && am_sender)
258                 argstr[x++] = 'O';
259         if (preserve_perms)
260 --- orig/rsync.c        2006-01-14 08:14:31
261 +++ rsync.c     2005-07-28 00:17:37
262 @@ -27,6 +27,7 @@ extern int dry_run;
263  extern int daemon_log_format_has_i;
264  extern int preserve_times;
265  extern int omit_dir_times;
266 +extern int preserve_atimes;
267  extern int am_root;
268  extern int am_server;
269  extern int am_sender;
270 @@ -56,6 +57,7 @@ int set_perms(char *fname,struct file_st
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)
278 @@ -70,16 +72,29 @@ int set_perms(char *fname,struct file_st
279  
280         if (!preserve_times || (S_ISDIR(st->st_mode) && omit_dir_times))
281                 flags |= PERMS_SKIP_MTIME;
282 +       if (!preserve_atimes || S_ISDIR(st->st_mode))
283 +               flags |= PERMS_SKIP_ATIME;
284         if (!(flags & PERMS_SKIP_MTIME)
285 -           && cmp_modtime(st->st_mtime, file->modtime) != 0) {
286 -               int ret = set_modtime(fname, file->modtime, st->st_mode);
287 +           && cmp_time(st->st_mtime, file->modtime) != 0) {
288 +               mtime = file->modtime;
289 +               updated = 1;
290 +       } else
291 +               mtime = st->st_mtime;
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;
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;
309         }
310  
311         change_uid = am_root && preserve_uid && st->st_uid != file->uid;
312 --- orig/rsync.h        2006-01-14 20:27:10
313 +++ rsync.h     2005-07-28 00:04:51
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  
322 @@ -119,6 +120,7 @@
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
330 @@ -135,6 +137,7 @@
331  #define FNAMECMP_FUZZY         0x83
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)
338 @@ -517,6 +520,7 @@ struct file_struct {
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;
346 --- orig/rsync.yo       2006-01-14 08:14:31
347 +++ rsync.yo    2005-11-07 04:34:55
348 @@ -319,8 +319,9 @@ to the detailed description below for a 
349   -o, --owner                 preserve owner (root only)
350   -g, --group                 preserve group
351   -D, --devices               preserve devices (root only)
352 - -t, --times                 preserve times
353 - -O, --omit-dir-times        omit directories when preserving times
354 + -t, --times                 preserve modify times
355 + -O, --omit-dir-times        omit directories when preserving mod-times
356 + -A, --atimes                preserve access times
357       --chmod=CHMOD           change destination permissions
358   -S, --sparse                handle sparse files efficiently
359   -n, --dry-run               show what would have been transferred
360 @@ -711,6 +712,12 @@ it is preserving modification times (see
361  the directories on the receiving side, it is a good idea to use bf(-O).
362  This option is inferred if you use bf(--backup) without bf(--backup-dir).
363  
364 +dit(bf(-A, --atimes)) This tells rsync to set the access times of the
365 +destination files to the same value as the source files.  Note that the
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.
369 +
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
373 @@ -1160,7 +1167,7 @@ changes that are being made to each file
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.
382 @@ -1199,17 +1206,22 @@ quote(itemize(
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
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
430 --- orig/testsuite/itemize.test 2005-12-15 23:00:49
431 +++ testsuite/itemize.test      2005-12-15 23:11:34
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/
530 -cf        bar/baz/rsync
531 -cd+++++++ foo/
532 -cf        foo/config1
533 -cf        foo/config2
534 -hf        foo/extra => foo/config1
535 -cL..T.... foo/sym -> ../bar/baz/rsync
536 +.d..t..... ./
537 +cd++++++++ bar/
538 +cd++++++++ bar/baz/
539 +cf         bar/baz/rsync
540 +cd++++++++ foo/
541 +cf         foo/config1
542 +cf         foo/config2
543 +hf         foo/extra => foo/config1
544 +cL..T..... foo/sym -> ../bar/baz/rsync
545  EOT
546  diff $diffopt "$chkfile" "$outfile" || test_fail "test 8 failed"
547  
548 @@ -165,11 +165,11 @@ rm -rf "$todir"
549  $RSYNC -iplrtH --copy-dest="$lddir" "$fromdir/" "$todir/" \
550      | tee "$outfile"
551  cat <<EOT >"$chkfile"
552 -.d..t.... ./
553 -cd+++++++ bar/
554 -cd+++++++ bar/baz/
555 -cd+++++++ foo/
556 -hf        foo/extra => foo/config1
557 +.d..t..... ./
558 +cd++++++++ bar/
559 +cd++++++++ bar/baz/
560 +cd++++++++ foo/
561 +hf         foo/extra => foo/config1
562  EOT
563  diff $diffopt "$chkfile" "$outfile" || test_fail "test 9 failed"
564  
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  
643 --- orig/testsuite/rsync.fns    2005-06-10 21:33:28
644 +++ testsuite/rsync.fns 2005-07-28 00:41:20
645 @@ -50,7 +50,7 @@ printmsg() {
646  
647  
648  rsync_ls_lR() {
649 -    find "$@" -print | sort | sed 's/ /\\ /g' | xargs "$TOOLDIR/tls"
650 +    find "$@" -print | sort | sed 's/ /\\ /g' | xargs "$TOOLDIR/tls" $TLS_ARGS
651  }
652  
653  rsync_getgroups() { 
654 @@ -158,6 +158,10 @@ checkit() {
655      # We can just write everything to stdout/stderr, because the
656      # wrapper hides it unless there is a problem.
657  
658 +    if test x$TLS_ARGS = x--atime; then
659 +       ( cd "$2" && rsync_ls_lR . ) > "$tmpdir/ls-from"
660 +    fi
661 +
662      echo "Running: \"$1\""  
663      eval "$1" 
664      status=$?
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 +
673      echo "-------------"
674      echo "check how the directory listings compare with diff:"
675      echo ""
676 -    ( cd "$2" && rsync_ls_lR . ) > "$tmpdir/ls-from"
677      ( cd "$3" && rsync_ls_lR . ) > "$tmpdir/ls-to"
678      diff $diffopt "$tmpdir/ls-from" "$tmpdir/ls-to" || failed=YES
679  
680 --- orig/tls.c  2005-09-24 17:40:31
681 +++ tls.c       2005-03-23 17:49:48
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  
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);
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 ",
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);
714 +       } else {
715 +               strcpy(dest, "                    ");
716 +       }
717 +}      
718  
719  static void list_file(const char *fname)
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  
729         if (do_lstat(fname, &buf) < 0)
730 @@ -96,19 +113,8 @@ static void list_file(const char *fname)
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",
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);
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  
752 @@ -119,24 +125,55 @@ static void list_file(const char *fname)
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);
760 +              mtimebuf, display_atime && !S_ISDIR(buf.st_mode) ? atimebuf : "",
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) {
782 -               fprintf(stderr, "usage: " PROGRAM " DIR ...\n"
783 -                       "Trivial file listing program for portably checking rsync\n");
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++) {
805 -               list_file(*argv);
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  }
817 --- orig/util.c 2006-01-14 08:14:31
818 +++ util.c      2006-01-14 08:20:29
819 @@ -130,7 +130,7 @@ void overflow_exit(char *str)
820  
821  
822  
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)
825  {
826  #if !defined HAVE_LUTIMES || !defined HAVE_UTIMES
827         if (S_ISLNK(mode))
828 @@ -138,9 +138,13 @@ int set_modtime(char *fname, time_t modt
829  #endif
830  
831         if (verbose > 2) {
832 -               rprintf(FINFO, "set modtime of %s to (%ld) %s",
833 +               char mtimebuf[200];
834 +
835 +               strlcpy(mtimebuf, timestring(modtime), sizeof mtimebuf);
836 +               rprintf(FINFO,
837 +                       "set modtime, atime of %s to (%ld) %s, (%ld) %s\n",
838                         fname, (long)modtime,
839 -                       asctime(localtime(&modtime)));
840 +                       mtimebuf, (long)atime, timestring(atime));
841         }
842  
843         if (dry_run)
844 @@ -149,7 +153,7 @@ int set_modtime(char *fname, time_t modt
845         {
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;
853 @@ -160,12 +164,12 @@ int set_modtime(char *fname, time_t modt
854                 return utimes(fname, t);
855  #elif defined HAVE_UTIMBUF
856                 struct utimbuf tbuf;
857 -               tbuf.actime = time(NULL);
858 +               tbuf.actime = atime;
859                 tbuf.modtime = modtime;
860                 return utime(fname,&tbuf);
861  #elif defined HAVE_UTIME
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
868 @@ -1191,8 +1195,8 @@ int msleep(int t)
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
879 @@ -1201,7 +1205,7 @@ int msleep(int t)
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  {
886         if (file2 > file1) {
887                 if (file2 - file1 <= modify_window)