Den 06/10/2010 kl. 14.35 skrev Erik Cederstrand: > Den 06/10/2010 kl. 13.07 skrev Erik Cederstrand: > >> Is something like the following acceptable? Without risking changes to >> buildworld/distribution just now, this would allow me to dump contents of an >> archive and re-insert them with '0' for mtime, uid and gid before checking >> checksums, without affecting normal ar behaviour. > > Great, I didn't even see the discussion on this list recently: > http://lists.freebsd.org/pipermail/freebsd-hackers/2010-September/033005.html > > Anyway, I added file mode to the patch. Apparently recent binutils also added > this feature. I haven't looked at their patch, but chance has it I used the > same option '-D'. > > I'm sure the file mode I'm setting in line 175 of write.c is wrong (obj->md = > 100644), but I couldn't quite figure out how to set the value to rw-r--r--. > Here's the new patch: > > Index: ar.1 > =================================================================== > --- ar.1 (revision 213478) > +++ ar.1 (working copy) > @@ -62,6 +62,7 @@ > .Op Fl a Ar position-after > .Op Fl b Ar position-before > .Op Fl c > +.Op Fl D > .Op Fl i Ar position-before > .Op Fl j > .Op Fl s > @@ -179,6 +180,14 @@ > .Ar archive . > The archive's symbol table, if present, is updated to reflect > the new contents of the archive. > +.It Fl D > +When used in combination with the > +.Fl r > +option, insterts 0's instead of the real mtime, uid and gid values > +and 644 instead of file mode from the members named by arguments > +.Ar files ... . > +This ensures that checksums on the resulting archives are reproducible > +when member contents are identical. > .It Fl f > Synonymous with option > .Fl T . > Index: ar.c > =================================================================== > --- ar.c (revision 213478) > +++ ar.c (working copy) > @@ -154,7 +154,7 @@ > } > } > > - while ((opt = getopt_long(argc, argv, "abCcdfijlMmopqrSsTtuVvxz", > + while ((opt = getopt_long(argc, argv, "abCcdDfijlMmopqrSsTtuVvxz", > longopts, NULL)) != -1) { > switch(opt) { > case 'a': > @@ -173,6 +173,9 @@ > case 'd': > set_mode(bsdar, opt); > break; > + case 'D': > + bsdar->options |= AR_D; > + break; > case 'f': > case 'T': > bsdar->options |= AR_TR; > @@ -357,8 +360,8 @@ > (void)fprintf(stderr, "\tar -m [-Tabijsvz] position archive file > ...\n"); > (void)fprintf(stderr, "\tar -p [-Tv] archive [file ...]\n"); > (void)fprintf(stderr, "\tar -q [-Tcjsvz] archive file ...\n"); > - (void)fprintf(stderr, "\tar -r [-Tcjsuvz] archive file ...\n"); > - (void)fprintf(stderr, "\tar -r [-Tabcijsuvz] position archive file > ...\n"); > + (void)fprintf(stderr, "\tar -r [-TcDjsuvz] archive file ...\n"); > + (void)fprintf(stderr, "\tar -r [-TabcDijsuvz] position archive file > ...\n"); > (void)fprintf(stderr, "\tar -s [-jz] archive\n"); > (void)fprintf(stderr, "\tar -t [-Tv] archive [file ...]\n"); > (void)fprintf(stderr, "\tar -x [-CTouv] archive [file ...]\n"); > Index: ar.h > =================================================================== > --- ar.h (revision 213478) > +++ ar.h (working copy) > @@ -43,6 +43,7 @@ > #define AR_U 0x0200 /* only extract or update newer members.*/ > #define AR_V 0x0400 /* verbose mode */ > #define AR_Z 0x0800 /* gzip compression */ > +#define AR_D 0x1000 /* insert members with dummy mode, mtime, uid > and gid */ > > #define DEF_BLKSZ 10240 /* default block size */ > > Index: write.c > =================================================================== > --- write.c (revision 213478) > +++ write.c (working copy) > @@ -163,11 +163,23 @@ > if (mtime != 0 && bsdar->options & AR_U && sb.st_mtime <= mtime) > goto giveup; > > - obj->uid = sb.st_uid; > - obj->gid = sb.st_gid; > - obj->md = sb.st_mode; > + /* > + * When option '-D' is specified, mtime and UID / GID from the file > + * will be replaced with 0, and file mode with 644. This ensures that > + * checksums will match for two archives containing the exact same > files. > + */ > + if (bsdar->options & AR_D) { > + obj->uid = 0; > + obj->gid = 0; > + obj->mtime = 0; > + obj->md = 100644; > + } else { > + obj->uid = sb.st_uid; > + obj->gid = sb.st_gid; > + obj->mtime = sb.st_mtime; > + obj->md = sb.st_mode; > + } > obj->size = sb.st_size; > - obj->mtime = sb.st_mtime; > obj->dev = sb.st_dev; > obj->ino = sb.st_ino; > > @@ -621,7 +633,10 @@ > bsdar->options & AR_S) { > entry = archive_entry_new(); > archive_entry_copy_pathname(entry, "/"); > - archive_entry_set_mtime(entry, time(NULL), 0); > + if (bsdar->options & AR_O) > + archive_entry_set_mtime(entry, 0, 0); > + else > + archive_entry_set_mtime(entry, time(NULL), 0); > archive_entry_set_size(entry, (bsdar->s_cnt + 1) * > sizeof(uint32_t) + bsdar->s_sn_sz); > AC(archive_write_header(a, entry));
For the record, a correct version of this patch was applied in r213643. Erik