Fixed failing hunk.
[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-02-16 17:08:13
8 +++ batch.c     2004-07-03 20:15:41
9 @@ -205,6 +205,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-02-20 00:16:35
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 deletion_count;
28 @@ -143,16 +144,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 @@ -316,6 +319,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 @@ -331,7 +335,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 @@ -380,6 +384,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 @@ -435,6 +445,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 @@ -508,6 +520,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 @@ -526,7 +539,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 @@ -582,6 +595,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 @@ -632,6 +647,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 @@ -881,6 +897,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-02-20 22:13:19
131 +++ generator.c 2004-11-03 23:02:12
132 @@ -150,7 +150,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 @@ -725,7 +725,7 @@ static void recv_generator(char *fname, 
142         }
143  
144         if (update_only && fnamecmp_type == FNAMECMP_FNAME
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-02-21 07:28:59
151 +++ options.c   2005-01-24 01:51:48
152 @@ -50,6 +50,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 @@ -284,6 +285,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 @@ -408,6 +410,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_NONE,   &omit_dir_times, 0, 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 @@ -1272,6 +1275,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 && am_sender)
183                 argstr[x++] = 'O';
184         if (preserve_perms)
185 --- orig/rsync.c        2005-02-20 00:02:23
186 +++ rsync.c     2005-01-24 01:59:12
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 @@ -173,6 +174,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 @@ -185,18 +187,28 @@ int set_perms(char *fname,struct file_st
204                 st = &st2;
205         }
206  
207 +       if (!copy_atimes || S_ISLNK(st->st_mode) || S_ISDIR(st->st_mode))
208 +               flags |= PERMS_SKIP_ATIME;
209         if (!preserve_times || S_ISLNK(st->st_mode)
210          || (S_ISDIR(st->st_mode)
211           && (omit_dir_times || (make_backups && !backup_dir))))
212                 flags |= PERMS_SKIP_MTIME;
213 +       if (!(flags & PERMS_SKIP_ATIME)
214 +           && cmp_time(st->st_atime, file->atime) != 0) {
215 +               atime = file->atime;
216 +               updated = 1;
217 +       } else
218 +               atime = st->st_atime;
219         if (!(flags & PERMS_SKIP_MTIME)
220 -           && cmp_modtime(st->st_mtime, file->modtime) != 0) {
221 -               if (set_modtime(fname,file->modtime) != 0) {
222 -                       rsyserr(FERROR, errno, "failed to set times on %s",
223 -                               full_fname(fname));
224 -                       return 0;
225 -               }
226 +           && cmp_time(st->st_mtime, file->modtime) != 0) {
227 +               mtime = file->modtime;
228                 updated = 1;
229 +       } else
230 +               mtime = st->st_mtime;
231 +       if (updated && set_times(fname, mtime, atime) != 0) {
232 +               rsyserr(FERROR, errno, "failed to set times on %s",
233 +                       full_fname(fname));
234 +               return 0;
235         }
236  
237         change_uid = am_root && preserve_uid && st->st_uid != file->uid;
238 --- orig/rsync.h        2005-02-20 00:02:23
239 +++ rsync.h     2004-07-03 20:15:41
240 @@ -54,6 +54,7 @@
241  #define XMIT_HAS_IDEV_DATA (1<<9)
242  #define XMIT_SAME_DEV (1<<10)
243  #define XMIT_RDEV_MINOR_IS_SMALL (1<<11)
244 +#define XMIT_SAME_ATIME (1<<12)
245  
246  /* These flags are used in the live flist data. */
247  
248 @@ -116,6 +117,7 @@
249  
250  #define PERMS_REPORT           (1<<0)
251  #define PERMS_SKIP_MTIME       (1<<1)
252 +#define PERMS_SKIP_ATIME       (1<<2)
253  
254  #define FULL_FLUSH     1
255  #define NORMAL_FLUSH   0
256 @@ -498,6 +500,7 @@ struct file_struct {
257                 struct hlink *links;
258         } link_u;
259         time_t modtime;
260 +       time_t atime;
261         uid_t uid;
262         gid_t gid;
263         mode_t mode;
264 --- orig/rsync.yo       2005-02-20 01:12:43
265 +++ rsync.yo    2005-01-24 01:57:18
266 @@ -322,6 +322,7 @@ to the detailed description below for a 
267   -D, --devices               preserve devices (root only)
268   -t, --times                 preserve times
269   -O, --omit-dir-times        omit directories when preserving times
270 + -A, --copy-atimes           copy access times
271   -S, --sparse                handle sparse files efficiently
272   -n, --dry-run               show what would have been transferred
273   -W, --whole-file            copy files whole (without rsync algorithm)
274 @@ -654,6 +655,11 @@ dit(bf(-O, --omit-dir-times)) This tells
275  it is preserving modification times (see bf(--times)).  If NFS is sharing
276  the directories on the receiving side, it is a good idea to use bf(-O).
277  
278 +dit(bf(-A, --copy-atimes)) This tells rsync to transfer access times
279 +along with the files and update them on the remote system.  Note that
280 +reading the source file may update the atime and hence repeated rsync
281 +copies with --copy-atimes may copy files unnecessarily.
282 +
283  dit(bf(-n, --dry-run)) This tells rsync to not do any file transfers,
284  instead it will just report the actions it would have taken.
285  
286 --- orig/testsuite/copy-atimes.test     2004-06-30 00:06:23
287 +++ testsuite/copy-atimes.test  2004-06-30 00:06:23
288 @@ -0,0 +1,19 @@
289 +#! /bin/sh
290 +
291 +# Test rsync copying atimes
292 +
293 +. "$suitedir/rsync.fns"
294 +
295 +set -x
296 +
297 +mkdir "$fromdir"
298 +
299 +touch "$fromdir/foo"
300 +touch -a -t 200102031717.42 "$fromdir/foo"
301 +
302 +TLS_ARGS=--atime
303 +
304 +checkit "$RSYNC -rtAgvvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
305 +
306 +# The script would have aborted on error, so getting here means we've won.
307 +exit 0
308 --- orig/testsuite/rsync.fns    2005-02-21 07:29:00
309 +++ testsuite/rsync.fns 2005-02-21 07:30:11
310 @@ -50,7 +50,7 @@ printmsg() {
311  
312  
313  rsync_ls_lR() {
314 -    find "$@" -print | sort | sed 's/ /\\ /g' | xargs "$TOOLDIR/tls"
315 +    find "$@" -print | sort | sed 's/ /\\ /g' | xargs "$TOOLDIR/tls" $TLS_ARGS
316  }
317  
318  rsync_getgroups() { 
319 @@ -158,6 +158,8 @@ checkit() {
320      # We can just write everything to stdout/stderr, because the
321      # wrapper hides it unless there is a problem.
322  
323 +    ( cd "$2" && rsync_ls_lR . ) > "$tmpdir/ls-from"
324 +
325      echo "Running: \"$1\""  
326      eval "$1" 
327      status=$?
328 @@ -168,7 +170,6 @@ checkit() {
329      echo "-------------"
330      echo "check how the directory listings compare with diff:"
331      echo ""
332 -    ( cd "$2" && rsync_ls_lR . ) > "$tmpdir/ls-from"
333      ( cd "$3" && rsync_ls_lR . ) > "$tmpdir/ls-to"
334      diff $diffopt "$tmpdir/ls-from" "$tmpdir/ls-to" || failed=YES
335  
336 --- orig/tls.c  2005-01-19 20:11:10
337 +++ tls.c       2004-07-03 20:15:41
338 @@ -39,6 +39,7 @@
339  
340  
341  #include "rsync.h"
342 +#include "popt.h"
343  
344  #define PROGRAM "tls"
345  
346 @@ -48,6 +49,7 @@ int read_only = 1;
347  int list_only = 0;
348  int preserve_perms = 0;
349  
350 +static int display_atime = 0;
351  
352  static void failed(char const *what, char const *where)
353  {
354 @@ -56,14 +58,29 @@ static void failed(char const *what, cha
355         exit(1);
356  }
357  
358 +static void storetime(char *dest, time_t t)
359 +{
360 +       if (t) {
361 +               struct tm *mt = gmtime(&t);
362  
363 +               sprintf(dest, "%04d-%02d-%02d %02d:%02d:%02d ",
364 +                       mt->tm_year + 1900,
365 +                       mt->tm_mon + 1,
366 +                       mt->tm_mday,
367 +                       mt->tm_hour,
368 +                       mt->tm_min,
369 +                       mt->tm_sec);
370 +       } else {
371 +               strcpy(dest, "                    ");
372 +       }
373 +}      
374  
375  static void list_file(const char *fname)
376  {
377         STRUCT_STAT buf;
378         char permbuf[PERMSTRING_SIZE];
379 -       struct tm *mt;
380 -       char datebuf[50];
381 +       char mtimebuf[50];
382 +       char atimebuf[50];
383         char linkbuf[4096];
384  
385         if (do_lstat(fname, &buf) < 0)
386 @@ -96,19 +113,8 @@ static void list_file(const char *fname)
387  
388         permstring(permbuf, buf.st_mode);
389  
390 -       if (buf.st_mtime) {
391 -               mt = gmtime(&buf.st_mtime);
392 -
393 -               sprintf(datebuf, "%04d-%02d-%02d %02d:%02d:%02d",
394 -                       mt->tm_year + 1900,
395 -                       mt->tm_mon + 1,
396 -                       mt->tm_mday,
397 -                       mt->tm_hour,
398 -                       mt->tm_min,
399 -                       mt->tm_sec);
400 -       } else {
401 -               strcpy(datebuf, "                   ");
402 -       }
403 +       storetime(mtimebuf, buf.st_mtime);
404 +       storetime(atimebuf, buf.st_atime);
405  
406         /* TODO: Perhaps escape special characters in fname? */
407  
408 @@ -119,24 +125,55 @@ static void list_file(const char *fname)
409                     (long)minor(buf.st_rdev));
410         } else /* NB: use double for size since it might not fit in a long. */
411                 printf("%12.0f", (double)buf.st_size);
412 -       printf(" %6ld.%-6ld %6ld %s %s%s\n",
413 +       printf(" %6ld.%-6ld %6ld %s%s%s%s\n",
414                (long)buf.st_uid, (long)buf.st_gid, (long)buf.st_nlink,
415 -              datebuf, fname, linkbuf);
416 +              mtimebuf, display_atime ? atimebuf : "",
417 +              fname, linkbuf);
418  }
419  
420 +static struct poptOption long_options[] = {
421 +  /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
422 +  {"atime",           'u', POPT_ARG_NONE,   &display_atime, 0,   0, 0},
423 +  {"help",            'h', POPT_ARG_NONE,   0,              'h', 0, 0},
424 +  {0,0,0,0,0,0,0}
425 +};
426 +
427 +static void tls_usage(int ret)
428 +{
429 +       fprintf(stderr, "usage: " PROGRAM " [--atime | -u] DIR ...\n"
430 +           "Trivial file listing program for portably checking rsync\n");
431 +       exit(ret);
432 +}
433  
434  int
435  main(int argc, char *argv[])
436  {
437 -       if (argc < 2) {
438 -               fprintf(stderr, "usage: " PROGRAM " DIR ...\n"
439 -                       "Trivial file listing program for portably checking rsync\n");
440 -               return 1;
441 +       poptContext pc;
442 +       const char **extra_args;
443 +       int opt;
444 +
445 +       pc = poptGetContext(PROGRAM, argc, (const char **)argv,
446 +                           long_options, 0);
447 +       while ((opt = poptGetNextOpt(pc)) != -1) {
448 +               switch (opt) {
449 +               case 'h':
450 +                       tls_usage(0);
451 +               default:
452 +                       fprintf(stderr,
453 +                               "%s: %s\n",
454 +                               poptBadOption(pc, POPT_BADOPTION_NOALIAS),
455 +                               poptStrerror(opt));
456 +                       tls_usage(1);
457 +               }
458         }
459  
460 -       for (argv++; *argv; argv++) {
461 -               list_file(*argv);
462 -       }
463 +       extra_args = poptGetArgs(pc);
464 +       if (*extra_args == NULL)
465 +               tls_usage(1);
466 +
467 +       for (; *extra_args; extra_args++)
468 +               list_file(*extra_args);
469 +       poptFreeContext(pc);
470  
471         return 0;
472  }
473 --- orig/util.c 2005-02-20 19:17:49
474 +++ util.c      2005-02-07 21:09:12
475 @@ -128,12 +128,17 @@ void overflow(char *str)
476  
477  
478  
479 -int set_modtime(char *fname, time_t modtime)
480 +int set_times(char *fname, time_t modtime, time_t atime)
481  {
482         if (verbose > 2) {
483 -               rprintf(FINFO, "set modtime of %s to (%ld) %s",
484 +               char mtimebuf[200];
485 +
486 +               strlcpy(mtimebuf, timestring(modtime), sizeof mtimebuf);
487 +               rprintf(FINFO,
488 +                       "set modtime, atime of %s to (%ld) %s, (%ld) %s\n",
489                         safe_fname(fname), (long)modtime,
490 -                       asctime(localtime(&modtime)));
491 +                       mtimebuf,
492 +                       (long)atime, timestring(atime));
493         }
494  
495         if (dry_run)
496 @@ -142,17 +147,17 @@ int set_modtime(char *fname, time_t modt
497         {
498  #ifdef HAVE_UTIMBUF
499                 struct utimbuf tbuf;
500 -               tbuf.actime = time(NULL);
501 +               tbuf.actime = atime;
502                 tbuf.modtime = modtime;
503                 return utime(fname,&tbuf);
504  #elif defined HAVE_UTIME
505                 time_t t[2];
506 -               t[0] = time(NULL);
507 +               t[0] = atime;
508                 t[1] = modtime;
509                 return utime(fname,t);
510  #else
511                 struct timeval t[2];
512 -               t[0].tv_sec = time(NULL);
513 +               t[0].tv_sec = atime;
514                 t[0].tv_usec = 0;
515                 t[1].tv_sec = modtime;
516                 t[1].tv_usec = 0;
517 @@ -1149,8 +1154,8 @@ int msleep(int t)
518  
519  
520  /**
521 - * Determine if two file modification times are equivalent (either
522 - * exact or in the modification timestamp window established by
523 + * Determine if two file  times are equivalent (either
524 + * exact or in the timestamp window established by
525   * --modify-window).
526   *
527   * @retval 0 if the times should be treated as the same
528 @@ -1159,7 +1164,7 @@ int msleep(int t)
529   *
530   * @retval -1 if the 2nd is later
531   **/
532 -int cmp_modtime(time_t file1, time_t file2)
533 +int cmp_time(time_t file1, time_t file2)
534  {
535         if (file2 > file1) {
536                 if (file2 - file1 <= modify_window)