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