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

Reply via email to