Den 06/10/2010 kl. 08.00 skrev Tim Kientzle: >> >> % diff mod.strings orig.strings >> 2c2 >> < / 1286312209 0 0 0 958 ` >> --- >>> / 1269146263 0 0 0 958 ` > > That's the timestamp on the pseudo-entry used to store the archive > symbol table. (GNU/SysV ar files use a pseudo-entry named "/" to > store the symbol table. Since '/' is added to end of names in this > format, this is essentially an entry with an empty name.) > > The current ar code generates this entry and sets the timestamp > around line 624 of usr.bin/ar/write.c. > > As far as I can tell, ar itself doesn't care about the timestamp here; > it's possible that ranlib or ld do care. If they don't, we could set > this timestamp to zero always.
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. erik% svn diff 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 +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 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,22 @@ if (mtime != 0 && bsdar->options & AR_U && sb.st_mtime <= mtime) goto giveup; - obj->uid = sb.st_uid; - obj->gid = sb.st_gid; + /* + * When modifier -D is specified, mtime and UID / GID from the file + * will be replaced with 0. 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; + } 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 +632,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)); Thanks, Erik