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