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