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