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