Fixed failing hunks.
[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/batch.c        2005-04-09 18:00:28
8 +++ batch.c     2004-07-03 20:15:41
9 @@ -208,6 +208,8 @@ void show_flist(int index, struct file_s
10                 rprintf(FINFO, "flist->flags=%#x\n", fptr[i]->flags);
11                 rprintf(FINFO, "flist->modtime=%#lx\n",
12                         (long unsigned) fptr[i]->modtime);
13 +               rprintf(FINFO, "flist->atime=%#lx\n",
14 +                       (long unsigned) fptr[i]->atime);
15                 rprintf(FINFO, "flist->length=%.0f\n",
16                         (double) fptr[i]->length);
17                 rprintf(FINFO, "flist->mode=%#o\n", (int) fptr[i]->mode);
18 --- orig/flist.c        2005-07-27 23:31:12
19 +++ flist.c     2005-02-07 21:06:04
20 @@ -54,6 +54,7 @@ extern int relative_paths;
21  extern int implied_dirs;
22  extern int copy_links;
23  extern int copy_unsafe_links;
24 +extern int copy_atimes;
25  extern int protocol_version;
26  extern int sanitize_paths;
27  extern int orig_umask;
28 @@ -141,16 +142,18 @@ static void list_file_entry(struct file_
29  
30  #ifdef SUPPORT_LINKS
31         if (preserve_links && S_ISLNK(f->mode)) {
32 -               rprintf(FINFO, "%s %11.0f %s %s -> %s\n",
33 +               rprintf(FINFO, "%s %11.0f %s %s %s -> %s\n",
34                         perms,
35                         (double)f->length, timestring(f->modtime),
36 +                       timestring(f->atime),
37                         safe_fname(f_name(f)), safe_fname(f->u.link));
38         } else
39  #endif
40         {
41 -               rprintf(FINFO, "%s %11.0f %s %s\n",
42 +               rprintf(FINFO, "%s %11.0f %s %s %s\n",
43                         perms,
44                         (double)f->length, timestring(f->modtime),
45 +                       timestring(f->atime),
46                         safe_fname(f_name(f)));
47         }
48  }
49 @@ -314,6 +317,7 @@ void send_file_entry(struct file_struct 
50  {
51         unsigned short flags;
52         static time_t modtime;
53 +       static time_t atime;
54         static mode_t mode;
55         static int64 dev;
56         static dev_t rdev;
57 @@ -329,7 +333,7 @@ void send_file_entry(struct file_struct 
58  
59         if (!file) {
60                 write_byte(f, 0);
61 -               modtime = 0, mode = 0;
62 +               modtime = 0, atime = 0, mode = 0;
63                 dev = 0, rdev = makedev(0, 0);
64                 rdev_major = 0;
65                 uid = 0, gid = 0;
66 @@ -378,6 +382,12 @@ void send_file_entry(struct file_struct 
67                 flags |= XMIT_SAME_TIME;
68         else
69                 modtime = file->modtime;
70 +       if (copy_atimes && !S_ISDIR(mode)) {
71 +               if (file->atime == atime)
72 +                       flags |= XMIT_SAME_ATIME;
73 +               else
74 +                       atime = file->atime;
75 +       }
76  
77  #ifdef SUPPORT_HARD_LINKS
78         if (file->link_u.idev) {
79 @@ -433,6 +443,8 @@ void send_file_entry(struct file_struct 
80                 write_int(f, modtime);
81         if (!(flags & XMIT_SAME_MODE))
82                 write_int(f, to_wire_mode(mode));
83 +       if (copy_atimes && !S_ISDIR(mode) && !(flags & XMIT_SAME_ATIME))
84 +               write_int(f, atime);
85         if (preserve_uid && !(flags & XMIT_SAME_UID)) {
86                 if (!numeric_ids)
87                         add_uid(uid);
88 @@ -506,6 +518,7 @@ static struct file_struct *receive_file_
89                                               unsigned short flags, int f)
90  {
91         static time_t modtime;
92 +       static time_t atime;
93         static mode_t mode;
94         static int64 dev;
95         static dev_t rdev;
96 @@ -524,7 +537,7 @@ static struct file_struct *receive_file_
97         struct file_struct *file;
98  
99         if (!flist) {
100 -               modtime = 0, mode = 0;
101 +               modtime = 0, atime = 0, mode = 0;
102                 dev = 0, rdev = makedev(0, 0);
103                 rdev_major = 0;
104                 uid = 0, gid = 0;
105 @@ -580,6 +593,8 @@ static struct file_struct *receive_file_
106                 modtime = (time_t)read_int(f);
107         if (!(flags & XMIT_SAME_MODE))
108                 mode = from_wire_mode(read_int(f));
109 +       if (copy_atimes && !S_ISDIR(mode) && !(flags & XMIT_SAME_ATIME))
110 +               atime = (time_t)read_int(f);
111  
112         if (preserve_uid && !(flags & XMIT_SAME_UID))
113                 uid = (uid_t)read_int(f);
114 @@ -630,6 +645,7 @@ static struct file_struct *receive_file_
115  
116         file->flags = 0;
117         file->modtime = modtime;
118 +       file->atime = atime;
119         file->length = file_length;
120         file->mode = mode;
121         file->uid = uid;
122 @@ -882,6 +898,7 @@ skip_filters:
123  
124         file->flags = flags;
125         file->modtime = st.st_mtime;
126 +       file->atime = st.st_atime;
127         file->length = st.st_size;
128         file->mode = st.st_mode;
129         file->uid = st.st_uid;
130 --- orig/generator.c    2005-07-27 23:31:12
131 +++ generator.c 2004-11-03 23:02:12
132 @@ -377,7 +377,7 @@ static int unchanged_file(char *fn, stru
133         if (ignore_times)
134                 return 0;
135  
136 -       return cmp_modtime(st->st_mtime, file->modtime) == 0;
137 +       return cmp_time(st->st_mtime, file->modtime) == 0;
138  }
139  
140  
141 @@ -851,7 +851,7 @@ static void recv_generator(char *fname, 
142         }
143  
144         if (update_only && statret == 0
145 -           && cmp_modtime(st.st_mtime, file->modtime) > 0) {
146 +           && cmp_time(st.st_mtime, file->modtime) > 0) {
147                 if (verbose > 1)
148                         rprintf(FINFO, "%s is newer\n", safe_fname(fname));
149                 return;
150 --- orig/options.c      2005-07-27 23:31:12
151 +++ options.c   2005-02-21 10:53:28
152 @@ -49,6 +49,7 @@ int preserve_uid = 0;
153  int preserve_gid = 0;
154  int preserve_times = 0;
155  int omit_dir_times = 0;
156 +int copy_atimes = 0;
157  int update_only = 0;
158  int cvs_exclude = 0;
159  int dry_run = 0;
160 @@ -286,6 +287,7 @@ void usage(enum logcode F)
161    rprintf(F," -g, --group                 preserve group\n");
162    rprintf(F," -D, --devices               preserve devices (root only)\n");
163    rprintf(F," -t, --times                 preserve times\n");
164 +  rprintf(F," -A, --copy-atimes           copy access times\n");
165    rprintf(F," -O, --omit-dir-times        omit directories when preserving times\n");
166    rprintf(F," -S, --sparse                handle sparse files efficiently\n");
167    rprintf(F," -n, --dry-run               show what would have been transferred\n");
168 @@ -413,6 +415,7 @@ static struct poptOption long_options[] 
169    {"devices",         'D', POPT_ARG_NONE,   &preserve_devices, 0, 0, 0 },
170    {"times",           't', POPT_ARG_NONE,   &preserve_times, 0, 0, 0 },
171    {"omit-dir-times",  'O', POPT_ARG_VAL,    &omit_dir_times, 2, 0, 0 },
172 +  {"copy-atimes",     'A', POPT_ARG_NONE,   &copy_atimes, 0, 0, 0 },
173    {"checksum",        'c', POPT_ARG_NONE,   &always_checksum, 0, 0, 0 },
174    {"verbose",         'v', POPT_ARG_NONE,   0, 'v', 0, 0 },
175    {"quiet",           'q', POPT_ARG_NONE,   0, 'q', 0, 0 },
176 @@ -1292,6 +1295,8 @@ void server_options(char **args,int *arg
177                 argstr[x++] = 'D';
178         if (preserve_times)
179                 argstr[x++] = 't';
180 +       if (copy_atimes)
181 +               argstr[x++] = 'A';
182         if (omit_dir_times == 2 && am_sender)
183                 argstr[x++] = 'O';
184         if (preserve_perms)
185 --- orig/rsync.c        2005-07-27 23:31:12
186 +++ rsync.c     2005-07-27 23:35:49
187 @@ -27,6 +27,7 @@ extern int dry_run;
188  extern int daemon_log_format_has_i;
189  extern int preserve_times;
190  extern int omit_dir_times;
191 +extern int copy_atimes;
192  extern int am_root;
193  extern int am_server;
194  extern int am_sender;
195 @@ -56,6 +57,7 @@ int set_perms(char *fname,struct file_st
196         int updated = 0;
197         STRUCT_STAT st2;
198         int change_uid, change_gid;
199 +       time_t atime, mtime;
200  
201         if (!st) {
202                 if (dry_run)
203 @@ -68,18 +70,31 @@ int set_perms(char *fname,struct file_st
204                 st = &st2;
205         }
206  
207 +       if (!copy_atimes || S_ISDIR(st->st_mode))
208 +               flags |= PERMS_SKIP_ATIME;
209         if (!preserve_times || (S_ISDIR(st->st_mode) && omit_dir_times))
210                 flags |= PERMS_SKIP_MTIME;
211 +       if (!(flags & PERMS_SKIP_ATIME)
212 +           && cmp_time(st->st_atime, file->atime) != 0) {
213 +               atime = file->atime;
214 +               updated = 1;
215 +       } else
216 +               atime = st->st_atime;
217         if (!(flags & PERMS_SKIP_MTIME)
218 -           && cmp_modtime(st->st_mtime, file->modtime) != 0) {
219 -               int ret = set_modtime(fname, file->modtime, st->st_mode);
220 +           && cmp_time(st->st_mtime, file->modtime) != 0) {
221 +               mtime = file->modtime;
222 +               updated = 1;
223 +       } else
224 +               mtime = st->st_mtime;
225 +       if (updated) {
226 +               int ret = set_times(fname, mtime, atime, st->st_mode);
227                 if (ret < 0) {
228                         rsyserr(FERROR, errno, "failed to set times on %s",
229                                 full_fname(fname));
230                         return 0;
231                 }
232 -               if (ret == 0) /* ret == 1 if symlink could not be set */
233 -                       updated = 1;
234 +               if (ret > 0) /* ret == 1 if symlink could not be set */
235 +                       updated = 0;
236         }
237  
238         change_uid = am_root && preserve_uid && st->st_uid != file->uid;
239 --- orig/rsync.h        2005-05-03 17:11:01
240 +++ rsync.h     2004-07-03 20:15:41
241 @@ -54,6 +54,7 @@
242  #define XMIT_HAS_IDEV_DATA (1<<9)
243  #define XMIT_SAME_DEV (1<<10)
244  #define XMIT_RDEV_MINOR_IS_SMALL (1<<11)
245 +#define XMIT_SAME_ATIME (1<<12)
246  
247  /* These flags are used in the live flist data. */
248  
249 @@ -118,6 +119,7 @@
250  
251  #define PERMS_REPORT           (1<<0)
252  #define PERMS_SKIP_MTIME       (1<<1)
253 +#define PERMS_SKIP_ATIME       (1<<2)
254  
255  #define FULL_FLUSH     1
256  #define NORMAL_FLUSH   0
257 @@ -509,6 +511,7 @@ struct file_struct {
258                 struct hlink *links;
259         } link_u;
260         time_t modtime;
261 +       time_t atime;
262         uid_t uid;
263         gid_t gid;
264         mode_t mode;
265 --- orig/rsync.yo       2005-07-07 23:11:09
266 +++ rsync.yo    2005-01-24 01:57:18
267 @@ -311,6 +311,7 @@ to the detailed description below for a 
268   -D, --devices               preserve devices (root only)
269   -t, --times                 preserve times
270   -O, --omit-dir-times        omit directories when preserving times
271 + -A, --copy-atimes           copy access times
272   -S, --sparse                handle sparse files efficiently
273   -n, --dry-run               show what would have been transferred
274   -W, --whole-file            copy files whole (without rsync algorithm)
275 @@ -648,6 +649,12 @@ it is preserving modification times (see
276  the directories on the receiving side, it is a good idea to use bf(-O).
277  This option is inferred if you use bf(--backup) without bf(--backup-dir).
278  
279 +dit(bf(-A, --copy-atimes)) This tells rsync to transfer access times
280 +along with the files and update them on the remote system.  Note that
281 +reading the source file may update the atime, so repeated rsync runs
282 +with --copy-atimes may be needed if you want the atime values to be
283 +100% identical.
284 +
285  dit(bf(-n, --dry-run)) This tells rsync to not do any file transfers,
286  instead it will just report the actions it would have taken.
287  
288 --- orig/testsuite/copy-atimes.test     2004-06-30 00:06:23
289 +++ testsuite/copy-atimes.test  2004-06-30 00:06:23
290 @@ -0,0 +1,19 @@
291 +#! /bin/sh
292 +
293 +# Test rsync copying atimes
294 +
295 +. "$suitedir/rsync.fns"
296 +
297 +set -x
298 +
299 +mkdir "$fromdir"
300 +
301 +touch "$fromdir/foo"
302 +touch -a -t 200102031717.42 "$fromdir/foo"
303 +
304 +TLS_ARGS=--atime
305 +
306 +checkit "$RSYNC -rtAgvvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
307 +
308 +# The script would have aborted on error, so getting here means we've won.
309 +exit 0
310 --- orig/testsuite/rsync.fns    2005-06-10 21:33:28
311 +++ testsuite/rsync.fns 2005-02-21 07:30:11
312 @@ -50,7 +50,7 @@ printmsg() {
313  
314  
315  rsync_ls_lR() {
316 -    find "$@" -print | sort | sed 's/ /\\ /g' | xargs "$TOOLDIR/tls"
317 +    find "$@" -print | sort | sed 's/ /\\ /g' | xargs "$TOOLDIR/tls" $TLS_ARGS
318  }
319  
320  rsync_getgroups() { 
321 @@ -158,6 +158,8 @@ checkit() {
322      # We can just write everything to stdout/stderr, because the
323      # wrapper hides it unless there is a problem.
324  
325 +    ( cd "$2" && rsync_ls_lR . ) > "$tmpdir/ls-from"
326 +
327      echo "Running: \"$1\""  
328      eval "$1" 
329      status=$?
330 @@ -168,7 +170,6 @@ checkit() {
331      echo "-------------"
332      echo "check how the directory listings compare with diff:"
333      echo ""
334 -    ( cd "$2" && rsync_ls_lR . ) > "$tmpdir/ls-from"
335      ( cd "$3" && rsync_ls_lR . ) > "$tmpdir/ls-to"
336      diff $diffopt "$tmpdir/ls-from" "$tmpdir/ls-to" || failed=YES
337  
338 --- orig/tls.c  2005-01-19 19:30:29
339 +++ tls.c       2005-03-23 17:49:48
340 @@ -39,6 +39,7 @@
341  
342  
343  #include "rsync.h"
344 +#include "popt.h"
345  
346  #define PROGRAM "tls"
347  
348 @@ -48,6 +49,7 @@ int read_only = 1;
349  int list_only = 0;
350  int preserve_perms = 0;
351  
352 +static int display_atime = 0;
353  
354  static void failed(char const *what, char const *where)
355  {
356 @@ -56,14 +58,29 @@ static void failed(char const *what, cha
357         exit(1);
358  }
359  
360 +static void storetime(char *dest, time_t t)
361 +{
362 +       if (t) {
363 +               struct tm *mt = gmtime(&t);
364  
365 +               sprintf(dest, "%04d-%02d-%02d %02d:%02d:%02d ",
366 +                       mt->tm_year + 1900,
367 +                       mt->tm_mon + 1,
368 +                       mt->tm_mday,
369 +                       mt->tm_hour,
370 +                       mt->tm_min,
371 +                       mt->tm_sec);
372 +       } else {
373 +               strcpy(dest, "                    ");
374 +       }
375 +}      
376  
377  static void list_file(const char *fname)
378  {
379         STRUCT_STAT buf;
380         char permbuf[PERMSTRING_SIZE];
381 -       struct tm *mt;
382 -       char datebuf[50];
383 +       char mtimebuf[50];
384 +       char atimebuf[50];
385         char linkbuf[4096];
386  
387         if (do_lstat(fname, &buf) < 0)
388 @@ -96,19 +113,8 @@ static void list_file(const char *fname)
389  
390         permstring(permbuf, buf.st_mode);
391  
392 -       if (buf.st_mtime) {
393 -               mt = gmtime(&buf.st_mtime);
394 -
395 -               sprintf(datebuf, "%04d-%02d-%02d %02d:%02d:%02d",
396 -                       mt->tm_year + 1900,
397 -                       mt->tm_mon + 1,
398 -                       mt->tm_mday,
399 -                       mt->tm_hour,
400 -                       mt->tm_min,
401 -                       mt->tm_sec);
402 -       } else {
403 -               strcpy(datebuf, "                   ");
404 -       }
405 +       storetime(mtimebuf, buf.st_mtime);
406 +       storetime(atimebuf, buf.st_atime);
407  
408         /* TODO: Perhaps escape special characters in fname? */
409  
410 @@ -119,24 +125,55 @@ static void list_file(const char *fname)
411                     (long)minor(buf.st_rdev));
412         } else /* NB: use double for size since it might not fit in a long. */
413                 printf("%12.0f", (double)buf.st_size);
414 -       printf(" %6ld.%-6ld %6ld %s %s%s\n",
415 +       printf(" %6ld.%-6ld %6ld %s%s%s%s\n",
416                (long)buf.st_uid, (long)buf.st_gid, (long)buf.st_nlink,
417 -              datebuf, fname, linkbuf);
418 +              mtimebuf, display_atime && !S_ISDIR(buf.st_mode) ? atimebuf : "",
419 +              fname, linkbuf);
420  }
421  
422 +static struct poptOption long_options[] = {
423 +  /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
424 +  {"atime",           'u', POPT_ARG_NONE,   &display_atime, 0,   0, 0},
425 +  {"help",            'h', POPT_ARG_NONE,   0,              'h', 0, 0},
426 +  {0,0,0,0,0,0,0}
427 +};
428 +
429 +static void tls_usage(int ret)
430 +{
431 +       fprintf(stderr, "usage: " PROGRAM " [--atime | -u] DIR ...\n"
432 +           "Trivial file listing program for portably checking rsync\n");
433 +       exit(ret);
434 +}
435  
436  int
437  main(int argc, char *argv[])
438  {
439 -       if (argc < 2) {
440 -               fprintf(stderr, "usage: " PROGRAM " DIR ...\n"
441 -                       "Trivial file listing program for portably checking rsync\n");
442 -               return 1;
443 +       poptContext pc;
444 +       const char **extra_args;
445 +       int opt;
446 +
447 +       pc = poptGetContext(PROGRAM, argc, (const char **)argv,
448 +                           long_options, 0);
449 +       while ((opt = poptGetNextOpt(pc)) != -1) {
450 +               switch (opt) {
451 +               case 'h':
452 +                       tls_usage(0);
453 +               default:
454 +                       fprintf(stderr,
455 +                               "%s: %s\n",
456 +                               poptBadOption(pc, POPT_BADOPTION_NOALIAS),
457 +                               poptStrerror(opt));
458 +                       tls_usage(1);
459 +               }
460         }
461  
462 -       for (argv++; *argv; argv++) {
463 -               list_file(*argv);
464 -       }
465 +       extra_args = poptGetArgs(pc);
466 +       if (*extra_args == NULL)
467 +               tls_usage(1);
468 +
469 +       for (; *extra_args; extra_args++)
470 +               list_file(*extra_args);
471 +       poptFreeContext(pc);
472  
473         return 0;
474  }
475 --- orig/util.c 2005-07-27 23:31:12
476 +++ util.c      2005-07-27 23:37:27
477 @@ -128,7 +128,7 @@ void overflow_exit(char *str)
478  
479  
480  
481 -int set_modtime(char *fname, time_t modtime, mode_t mode)
482 +int set_times(char *fname, time_t modtime, time_t atime, mode_t mode)
483  {
484  #if !defined HAVE_LUTIMES || !defined HAVE_UTIMES
485         if (S_ISLNK(mode))
486 @@ -136,9 +136,13 @@ int set_modtime(char *fname, time_t modt
487  #endif
488  
489         if (verbose > 2) {
490 -               rprintf(FINFO, "set modtime of %s to (%ld) %s",
491 +               char mtimebuf[200];
492 +
493 +               strlcpy(mtimebuf, timestring(modtime), sizeof mtimebuf);
494 +               rprintf(FINFO,
495 +                       "set modtime, atime of %s to (%ld) %s, (%ld) %s\n",
496                         safe_fname(fname), (long)modtime,
497 -                       asctime(localtime(&modtime)));
498 +                       mtimebuf, (long)atime, timestring(atime));
499         }
500  
501         if (dry_run)
502 @@ -147,7 +151,7 @@ int set_modtime(char *fname, time_t modt
503         {
504  #ifdef HAVE_UTIMES
505                 struct timeval t[2];
506 -               t[0].tv_sec = time(NULL);
507 +               t[0].tv_sec = atime;
508                 t[0].tv_usec = 0;
509                 t[1].tv_sec = modtime;
510                 t[1].tv_usec = 0;
511 @@ -158,12 +162,12 @@ int set_modtime(char *fname, time_t modt
512                 return utimes(fname, t);
513  #elif defined HAVE_UTIMBUF
514                 struct utimbuf tbuf;
515 -               tbuf.actime = time(NULL);
516 +               tbuf.actime = atime;
517                 tbuf.modtime = modtime;
518                 return utime(fname,&tbuf);
519  #elif defined HAVE_UTIME
520                 time_t t[2];
521 -               t[0] = time(NULL);
522 +               t[0] = atime;
523                 t[1] = modtime;
524                 return utime(fname,t);
525  #else
526 @@ -1167,8 +1171,8 @@ int msleep(int t)
527  
528  
529  /**
530 - * Determine if two file modification times are equivalent (either
531 - * exact or in the modification timestamp window established by
532 + * Determine if two file  times are equivalent (either
533 + * exact or in the timestamp window established by
534   * --modify-window).
535   *
536   * @retval 0 if the times should be treated as the same
537 @@ -1177,7 +1181,7 @@ int msleep(int t)
538   *
539   * @retval -1 if the 2nd is later
540   **/
541 -int cmp_modtime(time_t file1, time_t file2)
542 +int cmp_time(time_t file1, time_t file2)
543  {
544         if (file2 > file1) {
545                 if (file2 - file1 <= modify_window)