- Some improvements in the itemized output, including using 'u' and 'U'
[rsync/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/flist.c        2006-01-24 19:03:06
8 +++ flist.c     2006-01-24 22:40:04
9 @@ -50,6 +50,7 @@ extern int preserve_perms;
10  extern int preserve_devices;
11  extern int preserve_uid;
12  extern int preserve_gid;
13 +extern int preserve_atimes;
14  extern int relative_paths;
15  extern int implied_dirs;
16  extern int copy_links;
17 @@ -83,7 +84,13 @@ void init_flist(void)
18         struct file_struct f;
19  
20         /* Figure out how big the file_struct is without trailing padding */
21 -       file_struct_len = offsetof(struct file_struct, flags) + sizeof f.flags;
22 +       if (preserve_atimes)
23 +               file_struct_len = offsetof(struct file_struct, fl4g5);
24 +       else
25 +               file_struct_len = offsetof(struct file_struct, atime);
26 +       /* The "flags" uchar is no longer accessed directly, so I
27 +        * mangled the name to fl4g5 as a reminder. */
28 +       file_struct_len += sizeof f.fl4g5;
29         checksum_len = protocol_version < 21 ? 2 : MD4_SUM_LENGTH;
30  }
31  
32 @@ -139,16 +146,18 @@ static void list_file_entry(struct file_
33  
34  #ifdef SUPPORT_LINKS
35         if (preserve_links && S_ISLNK(f->mode)) {
36 -               rprintf(FINFO, "%s %11.0f %s %s -> %s\n",
37 +               rprintf(FINFO, "%s %11.0f %s %s %s -> %s\n",
38                         perms,
39                         (double)f->length, timestring(f->modtime),
40 +                       preserve_atimes ? timestring(f->atime) : "",
41                         f_name(f, NULL), f->u.link);
42         } else
43  #endif
44         {
45 -               rprintf(FINFO, "%s %11.0f %s %s\n",
46 +               rprintf(FINFO, "%s %11.0f %s %s %s\n",
47                         perms,
48                         (double)f->length, timestring(f->modtime),
49 +                       preserve_atimes ? timestring(f->atime) : "",
50                         f_name(f, NULL));
51         }
52  }
53 @@ -310,6 +319,7 @@ static void send_file_entry(struct file_
54  {
55         unsigned short flags;
56         static time_t modtime;
57 +       static time_t atime;
58         static mode_t mode;
59         static int64 dev;
60         static dev_t rdev;
61 @@ -325,7 +335,7 @@ static void send_file_entry(struct file_
62  
63         if (!file) {
64                 write_byte(f, 0);
65 -               modtime = 0, mode = 0;
66 +               modtime = 0, atime = 0, mode = 0;
67                 dev = 0, rdev = makedev(0, 0);
68                 rdev_major = 0;
69                 uid = 0, gid = 0;
70 @@ -337,7 +347,7 @@ static void send_file_entry(struct file_
71  
72         f_name(file, fname);
73  
74 -       flags = file->flags & XMIT_TOP_DIR;
75 +       flags = FFLAGS(file) & XMIT_TOP_DIR;
76  
77         if (file->mode == mode)
78                 flags |= XMIT_SAME_MODE;
79 @@ -374,6 +384,12 @@ static void send_file_entry(struct file_
80                 flags |= XMIT_SAME_TIME;
81         else
82                 modtime = file->modtime;
83 +       if (preserve_atimes && !S_ISDIR(mode)) {
84 +               if (file->atime == atime)
85 +                       flags |= XMIT_SAME_ATIME;
86 +               else
87 +                       atime = file->atime;
88 +       }
89  
90  #ifdef SUPPORT_HARD_LINKS
91         if (file->link_u.idev) {
92 @@ -427,6 +443,8 @@ static void send_file_entry(struct file_
93                 write_int(f, modtime);
94         if (!(flags & XMIT_SAME_MODE))
95                 write_int(f, to_wire_mode(mode));
96 +       if (preserve_atimes && !S_ISDIR(mode) && !(flags & XMIT_SAME_ATIME))
97 +               write_int(f, atime);
98         if (preserve_uid && !(flags & XMIT_SAME_UID)) {
99                 if (!numeric_ids)
100                         add_uid(uid);
101 @@ -494,6 +512,7 @@ static struct file_struct *receive_file_
102                                               unsigned short flags, int f)
103  {
104         static time_t modtime;
105 +       static time_t atime;
106         static mode_t mode;
107         static int64 dev;
108         static dev_t rdev;
109 @@ -512,7 +531,7 @@ static struct file_struct *receive_file_
110         struct file_struct *file;
111  
112         if (!flist) {
113 -               modtime = 0, mode = 0;
114 +               modtime = 0, atime = 0, mode = 0;
115                 dev = 0, rdev = makedev(0, 0);
116                 rdev_major = 0;
117                 uid = 0, gid = 0;
118 @@ -568,6 +587,8 @@ static struct file_struct *receive_file_
119                 modtime = (time_t)read_int(f);
120         if (!(flags & XMIT_SAME_MODE))
121                 mode = from_wire_mode(read_int(f));
122 +       if (preserve_atimes && !S_ISDIR(mode) && !(flags & XMIT_SAME_ATIME))
123 +               atime = (time_t)read_int(f);
124  
125         if (chmod_modes && !S_ISLNK(mode))
126                 mode = tweak_mode(mode, chmod_modes);
127 @@ -623,6 +644,8 @@ static struct file_struct *receive_file_
128         file->length = file_length;
129         file->mode = mode;
130         file->ids = id_pair(uid, gid);
131 +       if (preserve_atimes)
132 +               file->atime = atime;
133  
134         if (dirname_len) {
135                 file->dirname = lastdir = bp;
136 @@ -648,12 +671,12 @@ static struct file_struct *receive_file_
137                             && lastname[del_hier_name_len-1] == '.'
138                             && lastname[del_hier_name_len-2] == '/')
139                                 del_hier_name_len -= 2;
140 -                       file->flags |= FLAG_TOP_DIR | FLAG_DEL_HERE;
141 +                       FFLAGS(file) |= FLAG_TOP_DIR | FLAG_DEL_HERE;
142                 } else if (in_del_hier) {
143                         if (!relative_paths || !del_hier_name_len
144                          || (l1 >= del_hier_name_len
145                           && lastname[del_hier_name_len] == '/'))
146 -                               file->flags |= FLAG_DEL_HERE;
147 +                               FFLAGS(file) |= FLAG_DEL_HERE;
148                         else
149                                 in_del_hier = 0;
150                 }
151 @@ -874,11 +897,13 @@ struct file_struct *make_file(char *fnam
152         memset(bp, 0, file_struct_len);
153         bp += file_struct_len;
154  
155 -       file->flags = flags;
156 +       FFLAGS(file) = flags;
157         file->modtime = st.st_mtime;
158         file->length = st.st_size;
159         file->mode = st.st_mode;
160         file->ids = id_pair(st.st_uid, st.st_gid);
161 +       if (preserve_atimes)
162 +               file->atime = st.st_atime;
163  
164  #ifdef SUPPORT_HARD_LINKS
165         if (flist && flist->hlink_pool) {
166 @@ -989,7 +1014,7 @@ static void send_if_directory(int f, str
167         char is_dot_dir = fbuf[ol-1] == '.' && (ol == 1 || fbuf[ol-2] == '/');
168  
169         if (S_ISDIR(file->mode)
170 -           && !(file->flags & FLAG_MOUNT_POINT) && f_name(file, fbuf)) {
171 +           && !(FFLAGS(file) & FLAG_MOUNT_POINT) && f_name(file, fbuf)) {
172                 void *save_filters;
173                 unsigned int len = strlen(fbuf);
174                 if (len > 1 && fbuf[len-1] == '/')
175 @@ -1567,8 +1592,9 @@ static void clean_flist(struct file_list
176                         }
177                         /* Make sure that if we unduplicate '.', that we don't
178                          * lose track of a user-specified top directory. */
179 -                       flist->files[keep]->flags |= flist->files[drop]->flags
180 -                                                  & (FLAG_TOP_DIR|FLAG_DEL_HERE);
181 +                       FFLAGS(flist->files[keep])
182 +                           |= FFLAGS(flist->files[drop])
183 +                            & (FLAG_TOP_DIR|FLAG_DEL_HERE);
184  
185                         clear_file(drop, flist);
186  
187 @@ -1630,7 +1656,7 @@ static void output_flist(struct file_lis
188                         file->dirname ? file->dirname : "",
189                         file->dirname ? "/" : "", NS(file->basename),
190                         S_ISDIR(file->mode) ? "/" : "", (int)file->mode,
191 -                       (double)file->length, uidbuf, gidbuf, file->flags);
192 +                       (double)file->length, uidbuf, gidbuf, FFLAGS(file));
193         }
194  }
195  
196 --- orig/generator.c    2006-01-24 19:03:07
197 +++ generator.c 2006-01-24 22:29:56
198 @@ -43,6 +43,7 @@ extern int preserve_perms;
199  extern int preserve_uid;
200  extern int preserve_gid;
201  extern int preserve_times;
202 +extern int preserve_atimes;
203  extern int omit_dir_times;
204  extern int delete_before;
205  extern int delete_during;
206 @@ -89,6 +90,7 @@ extern dev_t filesystem_dev;
207  extern char *backup_dir;
208  extern char *backup_suffix;
209  extern int backup_suffix_len;
210 +extern unsigned int file_struct_len;
211  extern struct file_list *the_file_list;
212  extern struct filter_list_struct server_filter_list;
213  
214 @@ -183,7 +185,7 @@ static int delete_item(char *fname, int 
215         for (j = dirlist->count; j--; ) {
216                 struct file_struct *fp = dirlist->files[j];
217  
218 -               if (fp->flags & FLAG_MOUNT_POINT)
219 +               if (FFLAGS(fp) & FLAG_MOUNT_POINT)
220                         continue;
221  
222                 strlcpy(p, fp->basename, remainder);
223 @@ -261,7 +263,7 @@ static void delete_in_dir(struct file_li
224         filt_array[cur_depth] = push_local_filters(fbuf, dlen);
225  
226         if (one_file_system) {
227 -               if (file->flags & FLAG_TOP_DIR)
228 +               if (FFLAGS(file) & FLAG_TOP_DIR)
229                         filesystem_dev = stp->st_dev;
230                 else if (filesystem_dev != stp->st_dev)
231                         return;
232 @@ -273,7 +275,7 @@ static void delete_in_dir(struct file_li
233          * from the filesystem. */
234         for (i = dirlist->count; i--; ) {
235                 struct file_struct *fp = dirlist->files[i];
236 -               if (!fp->basename || fp->flags & FLAG_MOUNT_POINT)
237 +               if (!fp->basename || FFLAGS(fp) & FLAG_MOUNT_POINT)
238                         continue;
239                 if (flist_find(flist, fp) < 0) {
240                         int mode = fp->mode;
241 @@ -300,11 +302,11 @@ static void do_delete_pass(struct file_l
242         for (j = 0; j < flist->count; j++) {
243                 struct file_struct *file = flist->files[j];
244  
245 -               if (!(file->flags & FLAG_DEL_HERE))
246 +               if (!(FFLAGS(file) & FLAG_DEL_HERE))
247                         continue;
248  
249                 f_name(file, fbuf);
250 -               if (verbose > 1 && file->flags & FLAG_TOP_DIR)
251 +               if (verbose > 1 && FFLAGS(file) & FLAG_TOP_DIR)
252                         rprintf(FINFO, "deleting in %s\n", fbuf);
253  
254                 if (link_stat(fbuf, &st, keep_dirlinks) < 0
255 @@ -346,8 +348,11 @@ void itemize(struct file_struct *file, i
256                         iflags |= ITEM_REPORT_SIZE;
257                 if ((iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !keep_time
258                      && (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
259 -                   || (keep_time && cmp_modtime(file->modtime, st->st_mtime) != 0))
260 +                   || (keep_time && cmp_time(file->modtime, st->st_mtime) != 0))
261                         iflags |= ITEM_REPORT_TIME;
262 +               if (preserve_atimes && !S_ISDIR(file->mode) && !S_ISLNK(file->mode)
263 +                && cmp_time(file->atime, st->st_atime) != 0)
264 +                       iflags |= ITEM_REPORT_ATIME;
265                 if (preserve_perms
266                  && (file->mode & CHMOD_BITS) != (st->st_mode & CHMOD_BITS))
267                         iflags |= ITEM_REPORT_PERMS;
268 @@ -396,7 +401,7 @@ int unchanged_file(char *fn, struct file
269         if (ignore_times)
270                 return 0;
271  
272 -       return cmp_modtime(st->st_mtime, file->modtime) == 0;
273 +       return cmp_time(st->st_mtime, file->modtime) == 0;
274  }
275  
276  
277 @@ -550,13 +555,13 @@ static int find_fuzzy(struct file_struct
278                 uint32 dist;
279  
280                 if (!S_ISREG(fp->mode) || !fp->length
281 -                   || fp->flags & FLAG_NO_FUZZY)
282 +                   || FFLAGS(fp) & FLAG_NO_FUZZY)
283                         continue;
284  
285                 name = fp->basename;
286  
287                 if (fp->length == file->length
288 -                   && cmp_modtime(fp->modtime, file->modtime) == 0) {
289 +                   && cmp_time(fp->modtime, file->modtime) == 0) {
290                         if (verbose > 4) {
291                                 rprintf(FINFO,
292                                         "fuzzy size/modtime match for %s\n",
293 @@ -632,7 +637,7 @@ static int try_dests_reg(struct file_str
294                         if (!unchanged_attrs(file, stp))
295                                 continue;
296                         if ((always_checksum || ignore_times)
297 -                        && cmp_modtime(stp->st_mtime, file->modtime))
298 +                        && cmp_time(stp->st_mtime, file->modtime))
299                                 continue;
300                         best_match = j;
301                         match_level = 3;
302 @@ -894,7 +899,7 @@ static void recv_generator(char *fname, 
303                     && verbose && code && f_out != -1)
304                         rprintf(code, "%s/\n", fname);
305                 if (delete_during && f_out != -1 && !phase && dry_run < 2
306 -                   && (file->flags & FLAG_DEL_HERE))
307 +                   && (FFLAGS(file) & FLAG_DEL_HERE))
308                         delete_in_dir(the_file_list, fname, file, &st);
309                 return;
310         }
311 @@ -1071,7 +1076,7 @@ static void recv_generator(char *fname, 
312         }
313  
314         if (update_only && statret == 0
315 -           && cmp_modtime(st.st_mtime, file->modtime) > 0) {
316 +           && cmp_time(st.st_mtime, file->modtime) > 0) {
317                 if (verbose > 1)
318                         rprintf(FINFO, "%s is newer\n", fname);
319                 return;
320 @@ -1174,7 +1179,7 @@ static void recv_generator(char *fname, 
321         if (fuzzy_basis) {
322                 int j = flist_find(fuzzy_dirlist, file);
323                 if (j >= 0) /* don't use changing file as future fuzzy basis */
324 -                       fuzzy_dirlist->files[j]->flags |= FLAG_NO_FUZZY;
325 +                       FFLAGS(fuzzy_dirlist->files[j]) |= FLAG_NO_FUZZY;
326         }
327  
328         /* open the file */
329 --- orig/hlink.c        2006-01-14 20:27:09
330 +++ hlink.c     2006-01-24 19:17:58
331 @@ -26,6 +26,7 @@ extern int link_dest;
332  extern int make_backups;
333  extern int log_format_has_i;
334  extern char *basis_dir[];
335 +extern unsigned int file_struct_len;
336  extern struct file_list *the_file_list;
337  
338  #ifdef SUPPORT_HARD_LINKS
339 @@ -86,10 +87,10 @@ static void link_idev_data(void)
340                         FPTR(cur)->link_u.links = pool_talloc(hlink_pool,
341                             struct hlink, 1, "hlink_list");
342  
343 -                       FPTR(head)->flags |= FLAG_HLINK_TOL;
344 +                       FFLAGS(FPTR(head)) |= FLAG_HLINK_TOL;
345                         FPTR(cur)->F_HLINDEX = to;
346                         FPTR(cur)->F_NEXT = head;
347 -                       FPTR(cur)->flags |= FLAG_HLINK_EOL;
348 +                       FFLAGS(FPTR(cur)) |= FLAG_HLINK_EOL;
349                         hlink_list[to++] = head;
350                 } else
351                         FPTR(cur)->link_u.links = NULL;
352 @@ -175,7 +176,7 @@ int hard_link_check(struct file_struct *
353  {
354  #ifdef SUPPORT_HARD_LINKS
355         int head;
356 -       if (skip && !(file->flags & FLAG_HLINK_EOL))
357 +       if (skip && !(FFLAGS(file) & FLAG_HLINK_EOL))
358                 head = hlink_list[file->F_HLINDEX] = file->F_NEXT;
359         else
360                 head = hlink_list[file->F_HLINDEX];
361 @@ -270,8 +271,8 @@ void hard_link_cluster(struct file_struc
362         file->F_HLINDEX = FINISHED_LINK;
363         if (link_stat(f_name(file, hlink1), &st1, 0) < 0)
364                 return;
365 -       if (!(file->flags & FLAG_HLINK_TOL)) {
366 -               while (!(file->flags & FLAG_HLINK_EOL)) {
367 +       if (!(FFLAGS(file) & FLAG_HLINK_TOL)) {
368 +               while (!(FFLAGS(file) & FLAG_HLINK_EOL)) {
369                         ndx = file->F_NEXT;
370                         file = FPTR(ndx);
371                 }
372 @@ -286,6 +287,6 @@ void hard_link_cluster(struct file_struc
373                 maybe_hard_link(file, ndx, hlink2, statret, &st2,
374                                 hlink1, &st1, itemizing, code);
375                 file->F_HLINDEX = FINISHED_LINK;
376 -       } while (!(file->flags & FLAG_HLINK_EOL));
377 +       } while (!(FFLAGS(file) & FLAG_HLINK_EOL));
378  #endif
379  }
380 --- orig/log.c  2006-01-24 22:24:32
381 +++ log.c       2006-01-24 22:50:01
382 @@ -38,6 +38,7 @@ extern int module_id;
383  extern int msg_fd_out;
384  extern int protocol_version;
385  extern int preserve_times;
386 +extern int preserve_atimes;
387  extern int log_format_has_i;
388  extern int log_format_has_o_or_i;
389  extern int daemon_log_format_has_o_or_i;
390 @@ -542,10 +543,12 @@ static void log_formatted(enum logcode c
391                         n[3] = !(iflags & ITEM_REPORT_SIZE) ? '.' : 's';
392                         n[4] = !(iflags & ITEM_REPORT_TIME) ? '.'
393                              : !preserve_times || S_ISLNK(file->mode) ? 'T' : 't';
394 -                       n[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p';
395 -                       n[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o';
396 -                       n[7] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g';
397 -                       n[8] = '\0';
398 +                       n[5] = !(iflags & ITEM_REPORT_ATIME) ? '.'
399 +                            : S_ISLNK(file->mode) ? 'U' : 'u';
400 +                       n[6] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p';
401 +                       n[7] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o';
402 +                       n[8] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g';
403 +                       n[9] = '\0';
404  
405                         if (iflags & (ITEM_IS_NEW|ITEM_MISSING_DATA)) {
406                                 char ch = iflags & ITEM_IS_NEW ? '+' : '?';
407 --- orig/options.c      2006-01-23 18:48:23
408 +++ options.c   2006-01-24 22:53:18
409 @@ -50,6 +50,7 @@ int preserve_uid = 0;
410  int preserve_gid = 0;
411  int preserve_times = 0;
412  int omit_dir_times = 0;
413 +int preserve_atimes = 0;
414  int update_only = 0;
415  int cvs_exclude = 0;
416  int dry_run = 0;
417 @@ -291,8 +292,9 @@ void usage(enum logcode F)
418    rprintf(F," -o, --owner                 preserve owner (root only)\n");
419    rprintf(F," -g, --group                 preserve group\n");
420    rprintf(F," -D, --devices               preserve devices (root only)\n");
421 -  rprintf(F," -t, --times                 preserve times\n");
422 -  rprintf(F," -O, --omit-dir-times        omit directories when preserving times\n");
423 +  rprintf(F," -t, --times                 preserve modify times\n");
424 +  rprintf(F," -O, --omit-dir-times        omit directories when preserving modify times\n");
425 +  rprintf(F," -U, --atimes                preserve access (use) times\n");
426    rprintf(F,"     --chmod=CHMOD           change destination permissions\n");
427    rprintf(F," -S, --sparse                handle sparse files efficiently\n");
428    rprintf(F," -n, --dry-run               show what would have been transferred\n");
429 @@ -400,6 +402,9 @@ static struct poptOption long_options[] 
430    {"times",           't', POPT_ARG_VAL,    &preserve_times, 1, 0, 0 },
431    {"no-times",         0,  POPT_ARG_VAL,    &preserve_times, 0, 0, 0 },
432    {"no-t",             0,  POPT_ARG_VAL,    &preserve_times, 0, 0, 0 },
433 +  {"atimes",          'U', POPT_ARG_VAL,    &preserve_atimes, 1, 0, 0 },
434 +  {"no-atimes",        0,  POPT_ARG_VAL,    &preserve_atimes, 0, 0, 0 },
435 +  {"no-k",             0,  POPT_ARG_VAL,    &preserve_atimes, 0, 0, 0 },
436    {"omit-dir-times",  'O', POPT_ARG_VAL,    &omit_dir_times, 2, 0, 0 },
437    {"modify-window",    0,  POPT_ARG_INT,    &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
438    {"owner",           'o', POPT_ARG_VAL,    &preserve_uid, 1, 0, 0 },
439 @@ -1468,6 +1473,8 @@ void server_options(char **args,int *arg
440                 argstr[x++] = 'D';
441         if (preserve_times)
442                 argstr[x++] = 't';
443 +       if (preserve_atimes)
444 +               argstr[x++] = 'U';
445         if (omit_dir_times == 2 && am_sender)
446                 argstr[x++] = 'O';
447         if (preserve_perms)
448 --- orig/rsync.c        2006-01-24 19:03:07
449 +++ rsync.c     2005-07-28 00:17:37
450 @@ -27,6 +27,7 @@ extern int dry_run;
451  extern int daemon_log_format_has_i;
452  extern int preserve_times;
453  extern int omit_dir_times;
454 +extern int preserve_atimes;
455  extern int am_root;
456  extern int am_server;
457  extern int am_sender;
458 @@ -56,6 +57,7 @@ int set_perms(char *fname,struct file_st
459         int updated = 0;
460         STRUCT_STAT st2;
461         int change_uid, change_gid;
462 +       time_t atime, mtime;
463  
464         if (!st) {
465                 if (dry_run)
466 @@ -70,16 +72,29 @@ int set_perms(char *fname,struct file_st
467  
468         if (!preserve_times || (S_ISDIR(st->st_mode) && omit_dir_times))
469                 flags |= PERMS_SKIP_MTIME;
470 +       if (!preserve_atimes || S_ISDIR(st->st_mode))
471 +               flags |= PERMS_SKIP_ATIME;
472         if (!(flags & PERMS_SKIP_MTIME)
473 -           && cmp_modtime(st->st_mtime, file->modtime) != 0) {
474 -               int ret = set_modtime(fname, file->modtime, st->st_mode);
475 +           && cmp_time(st->st_mtime, file->modtime) != 0) {
476 +               mtime = file->modtime;
477 +               updated = 1;
478 +       } else
479 +               mtime = st->st_mtime;
480 +       if (!(flags & PERMS_SKIP_ATIME)
481 +           && cmp_time(st->st_atime, file->atime) != 0) {
482 +               atime = file->atime;
483 +               updated = 1;
484 +       } else
485 +               atime = st->st_atime;
486 +       if (updated) {
487 +               int ret = set_times(fname, mtime, atime, st->st_mode);
488                 if (ret < 0) {
489                         rsyserr(FERROR, errno, "failed to set times on %s",
490                                 full_fname(fname));
491                         return 0;
492                 }
493 -               if (ret == 0) /* ret == 1 if symlink could not be set */
494 -                       updated = 1;
495 +               if (ret > 0) /* ret == 1 if symlink could not be set */
496 +                       updated = 0;
497         }
498  
499         change_uid = am_root && preserve_uid && st->st_uid != file->ids->uid;
500 --- orig/rsync.h        2006-01-24 19:03:07
501 +++ rsync.h     2006-01-24 22:38:08
502 @@ -54,6 +54,7 @@
503  #define XMIT_HAS_IDEV_DATA (1<<9)
504  #define XMIT_SAME_DEV (1<<10)
505  #define XMIT_RDEV_MINOR_IS_SMALL (1<<11)
506 +#define XMIT_SAME_ATIME (1<<12)
507  
508  /* These flags are used in the live flist data. */
509  
510 @@ -119,6 +120,7 @@
511  
512  #define PERMS_REPORT           (1<<0)
513  #define PERMS_SKIP_MTIME       (1<<1)
514 +#define PERMS_SKIP_ATIME       (1<<2)
515  
516  #define FULL_FLUSH     1
517  #define NORMAL_FLUSH   0
518 @@ -135,6 +137,7 @@
519  #define FNAMECMP_FUZZY         0x83
520  
521  /* For use by the itemize_changes code */
522 +#define ITEM_REPORT_ATIME (1<<0)
523  #define ITEM_REPORT_CHECKSUM (1<<1)
524  #define ITEM_REPORT_SIZE (1<<2)
525  #define ITEM_REPORT_TIME (1<<3)
526 @@ -524,9 +527,12 @@ struct file_struct {
527         struct id_pair *ids;
528         time_t modtime;
529         mode_t mode;
530 -       uchar flags;    /* this item MUST remain last */
531 +       time_t atime;   /* this MUST be second to last */
532 +       uchar fl4g5;    /* this item MUST remain last */
533  };
534  
535 +#define FFLAGS(f) ((uchar*)(f))[file_struct_len-1]
536 +
537  /*
538   * Start the flist array at FLIST_START entries and grow it
539   * by doubling until FLIST_LINEAR then grow by FLIST_LINEAR
540 --- orig/rsync.yo       2006-01-24 22:19:58
541 +++ rsync.yo    2006-01-24 22:54:23
542 @@ -319,8 +319,9 @@ to the detailed description below for a 
543   -o, --owner                 preserve owner (root only)
544   -g, --group                 preserve group
545   -D, --devices               preserve devices (root only)
546 - -t, --times                 preserve times
547 - -O, --omit-dir-times        omit directories when preserving times
548 + -t, --times                 preserve modify times
549 + -O, --omit-dir-times        omit directories when preserving mod-times
550 + -U, --atimes                preserve access (use) times
551       --chmod=CHMOD           change destination permissions
552   -S, --sparse                handle sparse files efficiently
553   -n, --dry-run               show what would have been transferred
554 @@ -711,6 +712,12 @@ it is preserving modification times (see
555  the directories on the receiving side, it is a good idea to use bf(-O).
556  This option is inferred if you use bf(--backup) without bf(--backup-dir).
557  
558 +dit(bf(-U, --atimes)) This tells rsync to set the access (use) times of the
559 +destination files to the same value as the source files.  Note that the
560 +reading of the source file may update the atime of the source files, so
561 +repeated rsync runs with --atimes may be needed if you want to force the
562 +access-time values to be 100% identical on the two systems.
563 +
564  dit(bf(--chmod)) This options tells rsync to apply the listed "chmod" pattern
565  to the permission of the files on the destination.  In addition to the normal
566  parsing rules specified in the chmod manpage, you can specify an item that
567 @@ -1219,9 +1226,13 @@ quote(itemize(
568    by the file transfer.
569    it() A bf(t) means the modification time is different and is being updated
570    to the sender's value (requires bf(--times)).  An alternate value of bf(T)
571 -  means that the time will be set to the transfer time, which happens
572 +  means that the modify time will be set to the transfer time, which happens
573    anytime a symlink is transferred, or when a file or device is transferred
574    without bf(--times).
575 +  it() A bf(u) means the access (use) time is different and is being updated to
576 +  the sender's value (requires bf(--atimes)).  An alternate value of bf(U)
577 +  means that the access time will be set to the transfer time, which happens
578 +  anytime a symlink is transferred.
579    it() A bf(p) means the permissions are different and are being updated to
580    the sender's value (requires bf(--perms)).
581    it() An bf(o) means the owner is different and is being updated to the
582 --- orig/sender.c       2006-01-14 20:27:10
583 +++ sender.c    2006-01-24 18:10:23
584 @@ -38,6 +38,7 @@ extern int do_progress;
585  extern int inplace;
586  extern int batch_fd;
587  extern int write_batch;
588 +extern unsigned int file_struct_len;
589  extern struct stats stats;
590  extern struct file_list *the_file_list;
591  extern char *log_format;
592 @@ -126,7 +127,7 @@ void successful_send(int ndx)
593  
594         file = the_file_list->files[ndx];
595         /* The generator might tell us about symlinks we didn't send. */
596 -       if (!(file->flags & FLAG_SENT) && !S_ISLNK(file->mode))
597 +       if (!(FFLAGS(file) & FLAG_SENT) && !S_ISLNK(file->mode))
598                 return;
599         if (file->dir.root) {
600                 offset = stringjoin(fname, sizeof fname,
601 @@ -370,7 +371,7 @@ void send_files(struct file_list *flist,
602                         rprintf(FINFO, "sender finished %s\n", fname);
603  
604                 /* Flag that we actually sent this entry. */
605 -               file->flags |= FLAG_SENT;
606 +               FFLAGS(file) |= FLAG_SENT;
607         }
608         make_backups = save_make_backups;
609  
610 --- orig/testsuite/atimes.test  2006-01-24 22:54:53
611 +++ testsuite/atimes.test       2006-01-24 22:54:53
612 @@ -0,0 +1,19 @@
613 +#! /bin/sh
614 +
615 +# Test rsync copying atimes
616 +
617 +. "$suitedir/rsync.fns"
618 +
619 +set -x
620 +
621 +mkdir "$fromdir"
622 +
623 +touch "$fromdir/foo"
624 +touch -a -t 200102031717.42 "$fromdir/foo"
625 +
626 +TLS_ARGS=--atime
627 +
628 +checkit "$RSYNC -rtUgvvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
629 +
630 +# The script would have aborted on error, so getting here means we've won.
631 +exit 0
632 --- orig/testsuite/devices.test 2006-01-24 22:24:32
633 +++ testsuite/devices.test      2006-01-24 22:32:30
634 @@ -55,14 +55,14 @@ touch -r "$fromdir/block" "$fromdir/bloc
635  $RSYNC -ai "$fromdir/block" "$todir/block2" \
636      | tee "$outfile"
637  cat <<EOT >"$chkfile"
638 -cD++++++ block
639 +cD+++++++ block
640  EOT
641  diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed"
642  
643  $RSYNC -ai "$fromdir/block2" "$todir/block" \
644      | tee "$outfile"
645  cat <<EOT >"$chkfile"
646 -cD++++++ block2
647 +cD+++++++ block2
648  EOT
649  diff $diffopt "$chkfile" "$outfile" || test_fail "test 2 failed"
650  
651 @@ -71,7 +71,7 @@ sleep 1
652  $RSYNC -Di "$fromdir/block3" "$todir/block" \
653      | tee "$outfile"
654  cat <<EOT >"$chkfile"
655 -cD..T... block3
656 +cD..T.... block3
657  EOT
658  diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed"
659  
660 @@ -79,15 +79,15 @@ $RSYNC -aiHvv "$fromdir/" "$todir/" \
661      | tee "$outfile"
662  filter_outfile
663  cat <<EOT >"$chkfile"
664 -.d..t... ./
665 -cD..t... block
666 -cD...... block2
667 -cD++++++ block3
668 -hD++++++ block2.5 => block3
669 -cD++++++ char
670 -cD++++++ char2
671 -cD++++++ char3
672 -cD++++++ fifo
673 +.d..t.... ./
674 +cD..t.... block
675 +cD....... block2
676 +cD+++++++ block3
677 +hD+++++++ block2.5 => block3
678 +cD+++++++ char
679 +cD+++++++ char2
680 +cD+++++++ char3
681 +cD+++++++ fifo
682  EOT
683  if test ! -b "$fromdir/block2.5"; then
684      sed -e '/block2\.5/d' \
685 --- orig/testsuite/itemize.test 2006-01-24 22:24:32
686 +++ testsuite/itemize.test      2006-01-24 22:32:03
687 @@ -44,14 +44,14 @@ ln "$fromdir/foo/config1" "$fromdir/foo/
688  $RSYNC -iplr "$fromdir/" "$todir/" \
689      | tee "$outfile"
690  cat <<EOT >"$chkfile"
691 -cd++++++ bar/
692 -cd++++++ bar/baz/
693 ->f++++++ bar/baz/rsync
694 -cd++++++ foo/
695 ->f++++++ foo/config1
696 ->f++++++ foo/config2
697 ->f++++++ foo/extra
698 -cL++++++ foo/sym -> ../bar/baz/rsync
699 +cd+++++++ bar/
700 +cd+++++++ bar/baz/
701 +>f+++++++ bar/baz/rsync
702 +cd+++++++ foo/
703 +>f+++++++ foo/config1
704 +>f+++++++ foo/config2
705 +>f+++++++ foo/extra
706 +cL+++++++ foo/sym -> ../bar/baz/rsync
707  EOT
708  diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed"
709  
710 @@ -63,10 +63,10 @@ chmod 601 "$fromdir/foo/config2"
711  $RSYNC -iplrH "$fromdir/" "$todir/" \
712      | tee "$outfile"
713  cat <<EOT >"$chkfile"
714 ->f..T... bar/baz/rsync
715 ->f..T... foo/config1
716 ->f.sTp.. foo/config2
717 -hf..T... foo/extra => foo/config1
718 +>f..T.... bar/baz/rsync
719 +>f..T.... foo/config1
720 +>f.sT.p.. foo/config2
721 +hf..T.... foo/extra => foo/config1
722  EOT
723  diff $diffopt "$chkfile" "$outfile" || test_fail "test 2 failed"
724  
725 @@ -83,11 +83,11 @@ chmod 777 "$todir/bar/baz/rsync"
726  $RSYNC -iplrtc "$fromdir/" "$todir/" \
727      | tee "$outfile"
728  cat <<EOT >"$chkfile"
729 -.f..tp.. bar/baz/rsync
730 -.d..t... foo/
731 -.f..t... foo/config1
732 ->fcstp.. foo/config2
733 -cL..T... foo/sym -> ../bar/baz/rsync
734 +.f..t.p.. bar/baz/rsync
735 +.d..t.... foo/
736 +.f..t.... foo/config1
737 +>fcst.p.. foo/config2
738 +cL..T.... foo/sym -> ../bar/baz/rsync
739  EOT
740  diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed"
741  
742 @@ -112,15 +112,15 @@ $RSYNC -ivvplrtH "$fromdir/" "$todir/" \
743      | tee "$outfile"
744  filter_outfile
745  cat <<EOT >"$chkfile"
746 -.d       ./
747 -.d       bar/
748 -.d       bar/baz/
749 -.f...p.. bar/baz/rsync
750 -.d       foo/
751 -.f       foo/config1
752 ->f..t... foo/config2
753 -hf       foo/extra
754 -.L       foo/sym -> ../bar/baz/rsync
755 +.d        ./
756 +.d        bar/
757 +.d        bar/baz/
758 +.f....p.. bar/baz/rsync
759 +.d        foo/
760 +.f        foo/config1
761 +>f..t.... foo/config2
762 +hf        foo/extra
763 +.L        foo/sym -> ../bar/baz/rsync
764  EOT
765  diff $diffopt "$chkfile" "$outfile" || test_fail "test 5 failed"
766  
767 @@ -139,8 +139,8 @@ touch "$todir/foo/config2"
768  $RSYNC -iplrtH "$fromdir/" "$todir/" \
769      | tee "$outfile"
770  cat <<EOT >"$chkfile"
771 -.f...p.. foo/config1
772 ->f..t... foo/config2
773 +.f....p.. foo/config1
774 +>f..t.... foo/config2
775  EOT
776  diff $diffopt "$chkfile" "$outfile" || test_fail "test 7 failed"
777  
778 @@ -149,15 +149,15 @@ $RSYNC -ivvplrtH --copy-dest="$lddir" "$
779      | tee "$outfile"
780  filter_outfile
781  cat <<EOT >"$chkfile"
782 -.d..t... ./
783 -cd++++++ bar/
784 -cd++++++ bar/baz/
785 -cf       bar/baz/rsync
786 -cd++++++ foo/
787 -cf       foo/config1
788 -cf       foo/config2
789 -hf       foo/extra => foo/config1
790 -cL..T... foo/sym -> ../bar/baz/rsync
791 +.d..t.... ./
792 +cd+++++++ bar/
793 +cd+++++++ bar/baz/
794 +cf        bar/baz/rsync
795 +cd+++++++ foo/
796 +cf        foo/config1
797 +cf        foo/config2
798 +hf        foo/extra => foo/config1
799 +cL..T.... foo/sym -> ../bar/baz/rsync
800  EOT
801  diff $diffopt "$chkfile" "$outfile" || test_fail "test 8 failed"
802  
803 @@ -165,11 +165,11 @@ rm -rf "$todir"
804  $RSYNC -iplrtH --copy-dest="$lddir" "$fromdir/" "$todir/" \
805      | tee "$outfile"
806  cat <<EOT >"$chkfile"
807 -.d..t... ./
808 -cd++++++ bar/
809 -cd++++++ bar/baz/
810 -cd++++++ foo/
811 -hf       foo/extra => foo/config1
812 +.d..t.... ./
813 +cd+++++++ bar/
814 +cd+++++++ bar/baz/
815 +cd+++++++ foo/
816 +hf        foo/extra => foo/config1
817  EOT
818  diff $diffopt "$chkfile" "$outfile" || test_fail "test 9 failed"
819  
820 @@ -196,15 +196,15 @@ $RSYNC -ivvplrtH --link-dest="$lddir" "$
821      | tee "$outfile"
822  filter_outfile
823  cat <<EOT >"$chkfile"
824 -.d..t... ./
825 -cd++++++ bar/
826 -cd++++++ bar/baz/
827 -hf       bar/baz/rsync
828 -cd++++++ foo/
829 -hf       foo/config1
830 -hf       foo/config2
831 -hf       foo/extra => foo/config1
832 -hL       foo/sym -> ../bar/baz/rsync
833 +.d..t.... ./
834 +cd+++++++ bar/
835 +cd+++++++ bar/baz/
836 +hf        bar/baz/rsync
837 +cd+++++++ foo/
838 +hf        foo/config1
839 +hf        foo/config2
840 +hf        foo/extra => foo/config1
841 +hL        foo/sym -> ../bar/baz/rsync
842  EOT
843  diff $diffopt "$chkfile" "$outfile" || test_fail "test 11 failed"
844  
845 @@ -212,10 +212,10 @@ rm -rf "$todir"
846  $RSYNC -iplrtH --link-dest="$lddir" "$fromdir/" "$todir/" \
847      | tee "$outfile"
848  cat <<EOT >"$chkfile"
849 -.d..t... ./
850 -cd++++++ bar/
851 -cd++++++ bar/baz/
852 -cd++++++ foo/
853 +.d..t.... ./
854 +cd+++++++ bar/
855 +cd+++++++ bar/baz/
856 +cd+++++++ foo/
857  EOT
858  diff $diffopt "$chkfile" "$outfile" || test_fail "test 12 failed"
859  
860 @@ -243,14 +243,14 @@ filter_outfile
861  # TODO fix really-old problem when combining -H with --compare-dest:
862  # missing output for foo/extra hard-link (and it might not be updated)!
863  cat <<EOT >"$chkfile"
864 -.d..t... ./
865 -cd++++++ bar/
866 -cd++++++ bar/baz/
867 -.f       bar/baz/rsync
868 -cd++++++ foo/
869 -.f       foo/config1
870 -.f       foo/config2
871 -.L       foo/sym -> ../bar/baz/rsync
872 +.d..t.... ./
873 +cd+++++++ bar/
874 +cd+++++++ bar/baz/
875 +.f        bar/baz/rsync
876 +cd+++++++ foo/
877 +.f        foo/config1
878 +.f        foo/config2
879 +.L        foo/sym -> ../bar/baz/rsync
880  EOT
881  diff $diffopt "$chkfile" "$outfile" || test_fail "test 14 failed"
882  
883 @@ -258,10 +258,10 @@ rm -rf "$todir"
884  $RSYNC -iplrtH --compare-dest="$lddir" "$fromdir/" "$todir/" \
885      | tee "$outfile"
886  cat <<EOT >"$chkfile"
887 -.d..t... ./
888 -cd++++++ bar/
889 -cd++++++ bar/baz/
890 -cd++++++ foo/
891 +.d..t.... ./
892 +cd+++++++ bar/
893 +cd+++++++ bar/baz/
894 +cd+++++++ foo/
895  EOT
896  diff $diffopt "$chkfile" "$outfile" || test_fail "test 15 failed"
897  
898 --- orig/testsuite/rsync.fns    2005-06-10 21:33:28
899 +++ testsuite/rsync.fns 2005-07-28 00:41:20
900 @@ -50,7 +50,7 @@ printmsg() {
901  
902  
903  rsync_ls_lR() {
904 -    find "$@" -print | sort | sed 's/ /\\ /g' | xargs "$TOOLDIR/tls"
905 +    find "$@" -print | sort | sed 's/ /\\ /g' | xargs "$TOOLDIR/tls" $TLS_ARGS
906  }
907  
908  rsync_getgroups() { 
909 @@ -158,6 +158,10 @@ checkit() {
910      # We can just write everything to stdout/stderr, because the
911      # wrapper hides it unless there is a problem.
912  
913 +    if test x$TLS_ARGS = x--atime; then
914 +       ( cd "$2" && rsync_ls_lR . ) > "$tmpdir/ls-from"
915 +    fi
916 +
917      echo "Running: \"$1\""  
918      eval "$1" 
919      status=$?
920 @@ -165,10 +169,13 @@ checkit() {
921         failed="YES";
922      fi
923  
924 +    if test x$TLS_ARGS != x--atime; then
925 +       ( cd "$2" && rsync_ls_lR . ) > "$tmpdir/ls-from"
926 +    fi
927 +
928      echo "-------------"
929      echo "check how the directory listings compare with diff:"
930      echo ""
931 -    ( cd "$2" && rsync_ls_lR . ) > "$tmpdir/ls-from"
932      ( cd "$3" && rsync_ls_lR . ) > "$tmpdir/ls-to"
933      diff $diffopt "$tmpdir/ls-from" "$tmpdir/ls-to" || failed=YES
934  
935 --- orig/tls.c  2005-09-24 17:40:31
936 +++ tls.c       2005-03-23 17:49:48
937 @@ -39,6 +39,7 @@
938  
939  
940  #include "rsync.h"
941 +#include "popt.h"
942  
943  #define PROGRAM "tls"
944  
945 @@ -48,6 +49,7 @@ int read_only = 1;
946  int list_only = 0;
947  int preserve_perms = 0;
948  
949 +static int display_atime = 0;
950  
951  static void failed(char const *what, char const *where)
952  {
953 @@ -56,14 +58,29 @@ static void failed(char const *what, cha
954         exit(1);
955  }
956  
957 +static void storetime(char *dest, time_t t)
958 +{
959 +       if (t) {
960 +               struct tm *mt = gmtime(&t);
961  
962 +               sprintf(dest, "%04d-%02d-%02d %02d:%02d:%02d ",
963 +                       (int)mt->tm_year + 1900,
964 +                       (int)mt->tm_mon + 1,
965 +                       (int)mt->tm_mday,
966 +                       (int)mt->tm_hour,
967 +                       (int)mt->tm_min,
968 +                       (int)mt->tm_sec);
969 +       } else {
970 +               strcpy(dest, "                    ");
971 +       }
972 +}      
973  
974  static void list_file(const char *fname)
975  {
976         STRUCT_STAT buf;
977         char permbuf[PERMSTRING_SIZE];
978 -       struct tm *mt;
979 -       char datebuf[50];
980 +       char mtimebuf[50];
981 +       char atimebuf[50];
982         char linkbuf[4096];
983  
984         if (do_lstat(fname, &buf) < 0)
985 @@ -96,19 +113,8 @@ static void list_file(const char *fname)
986  
987         permstring(permbuf, buf.st_mode);
988  
989 -       if (buf.st_mtime) {
990 -               mt = gmtime(&buf.st_mtime);
991 -
992 -               sprintf(datebuf, "%04d-%02d-%02d %02d:%02d:%02d",
993 -                       (int)mt->tm_year + 1900,
994 -                       (int)mt->tm_mon + 1,
995 -                       (int)mt->tm_mday,
996 -                       (int)mt->tm_hour,
997 -                       (int)mt->tm_min,
998 -                       (int)mt->tm_sec);
999 -       } else {
1000 -               strcpy(datebuf, "                   ");
1001 -       }
1002 +       storetime(mtimebuf, buf.st_mtime);
1003 +       storetime(atimebuf, buf.st_atime);
1004  
1005         /* TODO: Perhaps escape special characters in fname? */
1006  
1007 @@ -119,24 +125,55 @@ static void list_file(const char *fname)
1008                     (long)minor(buf.st_rdev));
1009         } else /* NB: use double for size since it might not fit in a long. */
1010                 printf("%12.0f", (double)buf.st_size);
1011 -       printf(" %6ld.%-6ld %6ld %s %s%s\n",
1012 +       printf(" %6ld.%-6ld %6ld %s%s%s%s\n",
1013                (long)buf.st_uid, (long)buf.st_gid, (long)buf.st_nlink,
1014 -              datebuf, fname, linkbuf);
1015 +              mtimebuf, display_atime && !S_ISDIR(buf.st_mode) ? atimebuf : "",
1016 +              fname, linkbuf);
1017  }
1018  
1019 +static struct poptOption long_options[] = {
1020 +  /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
1021 +  {"atime",           'u', POPT_ARG_NONE,   &display_atime, 0,   0, 0},
1022 +  {"help",            'h', POPT_ARG_NONE,   0,              'h', 0, 0},
1023 +  {0,0,0,0,0,0,0}
1024 +};
1025 +
1026 +static void tls_usage(int ret)
1027 +{
1028 +       fprintf(stderr, "usage: " PROGRAM " [--atime | -u] DIR ...\n"
1029 +           "Trivial file listing program for portably checking rsync\n");
1030 +       exit(ret);
1031 +}
1032  
1033  int
1034  main(int argc, char *argv[])
1035  {
1036 -       if (argc < 2) {
1037 -               fprintf(stderr, "usage: " PROGRAM " DIR ...\n"
1038 -                       "Trivial file listing program for portably checking rsync\n");
1039 -               return 1;
1040 +       poptContext pc;
1041 +       const char **extra_args;
1042 +       int opt;
1043 +
1044 +       pc = poptGetContext(PROGRAM, argc, (const char **)argv,
1045 +                           long_options, 0);
1046 +       while ((opt = poptGetNextOpt(pc)) != -1) {
1047 +               switch (opt) {
1048 +               case 'h':
1049 +                       tls_usage(0);
1050 +               default:
1051 +                       fprintf(stderr,
1052 +                               "%s: %s\n",
1053 +                               poptBadOption(pc, POPT_BADOPTION_NOALIAS),
1054 +                               poptStrerror(opt));
1055 +                       tls_usage(1);
1056 +               }
1057         }
1058  
1059 -       for (argv++; *argv; argv++) {
1060 -               list_file(*argv);
1061 -       }
1062 +       extra_args = poptGetArgs(pc);
1063 +       if (*extra_args == NULL)
1064 +               tls_usage(1);
1065 +
1066 +       for (; *extra_args; extra_args++)
1067 +               list_file(*extra_args);
1068 +       poptFreeContext(pc);
1069  
1070         return 0;
1071  }
1072 --- orig/util.c 2006-01-20 00:12:48
1073 +++ util.c      2006-01-14 08:20:29
1074 @@ -130,7 +130,7 @@ void overflow_exit(char *str)
1075  
1076  
1077  
1078 -int set_modtime(char *fname, time_t modtime, mode_t mode)
1079 +int set_times(char *fname, time_t modtime, time_t atime, mode_t mode)
1080  {
1081  #if !defined HAVE_LUTIMES || !defined HAVE_UTIMES
1082         if (S_ISLNK(mode))
1083 @@ -138,9 +138,13 @@ int set_modtime(char *fname, time_t modt
1084  #endif
1085  
1086         if (verbose > 2) {
1087 -               rprintf(FINFO, "set modtime of %s to (%ld) %s",
1088 +               char mtimebuf[200];
1089 +
1090 +               strlcpy(mtimebuf, timestring(modtime), sizeof mtimebuf);
1091 +               rprintf(FINFO,
1092 +                       "set modtime, atime of %s to (%ld) %s, (%ld) %s\n",
1093                         fname, (long)modtime,
1094 -                       asctime(localtime(&modtime)));
1095 +                       mtimebuf, (long)atime, timestring(atime));
1096         }
1097  
1098         if (dry_run)
1099 @@ -149,7 +153,7 @@ int set_modtime(char *fname, time_t modt
1100         {
1101  #ifdef HAVE_UTIMES
1102                 struct timeval t[2];
1103 -               t[0].tv_sec = time(NULL);
1104 +               t[0].tv_sec = atime;
1105                 t[0].tv_usec = 0;
1106                 t[1].tv_sec = modtime;
1107                 t[1].tv_usec = 0;
1108 @@ -160,12 +164,12 @@ int set_modtime(char *fname, time_t modt
1109                 return utimes(fname, t);
1110  #elif defined HAVE_UTIMBUF
1111                 struct utimbuf tbuf;
1112 -               tbuf.actime = time(NULL);
1113 +               tbuf.actime = atime;
1114                 tbuf.modtime = modtime;
1115                 return utime(fname,&tbuf);
1116  #elif defined HAVE_UTIME
1117                 time_t t[2];
1118 -               t[0] = time(NULL);
1119 +               t[0] = atime;
1120                 t[1] = modtime;
1121                 return utime(fname,t);
1122  #else
1123 @@ -1175,8 +1179,8 @@ int msleep(int t)
1124  
1125  
1126  /**
1127 - * Determine if two file modification times are equivalent (either
1128 - * exact or in the modification timestamp window established by
1129 + * Determine if two file  times are equivalent (either
1130 + * exact or in the timestamp window established by
1131   * --modify-window).
1132   *
1133   * @retval 0 if the times should be treated as the same
1134 @@ -1185,7 +1189,7 @@ int msleep(int t)
1135   *
1136   * @retval -1 if the 2nd is later
1137   **/
1138 -int cmp_modtime(time_t file1, time_t file2)
1139 +int cmp_time(time_t file1, time_t file2)
1140  {
1141         if (file2 > file1) {
1142                 if (file2 - file1 <= modify_window)