Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/bin/pax support ././@LongLink extraction, as created by GNU ...



details:   https://anonhg.NetBSD.org/src/rev/64fb089349b0
branches:  trunk
changeset: 477579:64fb089349b0
user:      mrg <mrg%NetBSD.org@localhost>
date:      Fri Oct 22 10:43:11 1999 +0000

description:
support ././@LongLink extraction, as created by GNU tar.

diffstat:

 bin/pax/ar_subs.c   |  47 +++++++++++++++++++++++++++++------------------
 bin/pax/buf_subs.c  |  10 ++++++----
 bin/pax/extern.h    |   3 ++-
 bin/pax/file_subs.c |  21 +++++++++++++++++----
 bin/pax/pax.h       |   4 +++-
 bin/pax/tar.c       |  32 ++++++++++++++++++++++++++++----
 bin/pax/tar.h       |   8 +++++++-
 7 files changed, 92 insertions(+), 33 deletions(-)

diffs (truncated from 331 to 300 lines):

diff -r 44277d983d2e -r 64fb089349b0 bin/pax/ar_subs.c
--- a/bin/pax/ar_subs.c Fri Oct 22 10:39:16 1999 +0000
+++ b/bin/pax/ar_subs.c Fri Oct 22 10:43:11 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ar_subs.c,v 1.12 1999/08/24 07:57:06 tron Exp $        */
+/*     $NetBSD: ar_subs.c,v 1.13 1999/10/22 10:43:11 mrg Exp $ */
 
 /*-
  * Copyright (c) 1992 Keith Muller.
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)ar_subs.c  8.2 (Berkeley) 4/18/94";
 #else
-__RCSID("$NetBSD: ar_subs.c,v 1.12 1999/08/24 07:57:06 tron Exp $");
+__RCSID("$NetBSD: ar_subs.c,v 1.13 1999/10/22 10:43:11 mrg Exp $");
 #endif
 #endif /* not lint */
 
@@ -199,6 +199,8 @@
         * says it is done
         */
        while (next_head(arcn) == 0) {
+               int gnu_longlink_hack =
+                   (arcn->type == PAX_GLL || arcn->type == PAX_GLF);
 
                if (arcn->name[0] == '/' && !check_Aflag()) {
                        memmove(arcn->name, arcn->name + 1, strlen(arcn->name));
@@ -207,16 +209,19 @@
                 * check for pattern, and user specified options match. When
                 * all the patterns are matched we are done
                 */
-               if ((res = pat_match(arcn)) < 0)
-                       break;
+               if (!gnu_longlink_hack) {
+                       if ((res = pat_match(arcn)) < 0)
+                               break;
 
-               if ((res > 0) || (sel_chk(arcn) != 0)) {
-                       /*
-                        * file is not selected. skip past any file data and
-                        * padding and go back for the next archive member
-                        */
-                       (void)rd_skip(arcn->skip + arcn->pad);
-                       continue;
+                       if ((res > 0) || (sel_chk(arcn) != 0)) {
+                               /*
+                                * file is not selected. skip past any file
+                                * data and padding and go back for the next
+                                * archive member
+                                */
+                               (void)rd_skip(arcn->skip + arcn->pad);
+                               continue;
+                       }
                }
 
                /*
@@ -227,9 +232,10 @@
                 * specified by pax. this operation can be confusing to the
                 * user who might expect the test to be done on an existing
                 * file AFTER the name mod. In honesty the pax spec is probably
-                * flawed in this respect.
+                * flawed in this respect.  ignore this for GNU long links.
                 */
-               if ((uflag || Dflag) && ((lstat(arcn->name, &sb) == 0))) {
+               if ((uflag || Dflag) && ((lstat(arcn->name, &sb) == 0)) &&
+                   !gnu_longlink_hack) {
                        if (uflag && Dflag) {
                                if ((arcn->sb.st_mtime <= sb.st_mtime) &&
                                    (arcn->sb.st_ctime <= sb.st_ctime)) {
@@ -263,9 +269,10 @@
 
                /*
                 * Non standard -Y and -Z flag. When the exisiting file is
-                * same age or newer skip
+                * same age or newer skip; ignore this for GNU long links.
                 */
-               if ((Yflag || Zflag) && ((lstat(arcn->name, &sb) == 0))) {
+               if ((Yflag || Zflag) && ((lstat(arcn->name, &sb) == 0)) &&
+                   !gnu_longlink_hack) {
                        if (Yflag && Zflag) {
                                if ((arcn->sb.st_mtime <= sb.st_mtime) &&
                                    (arcn->sb.st_ctime <= sb.st_ctime)) {
@@ -291,7 +298,8 @@
                /*
                 * all ok, extract this member based on type
                 */
-               if ((arcn->type != PAX_REG) && (arcn->type != PAX_CTG)) {
+               if ((arcn->type != PAX_REG) && (arcn->type != PAX_CTG) &&
+                   !gnu_longlink_hack) {
                        /*
                         * process archive members that are not regular files.
                         * throw out padding and any data that might follow the
@@ -316,7 +324,9 @@
                 * we have a file with data here. If we can not create it, skip
                 * over the data and purge the name from hard link table
                 */
-               if ((fd = file_creat(arcn)) < 0) {
+               if (gnu_longlink_hack)
+                       fd = -1;  /* this tells the pax internals to DTRT */
+               else if ((fd = file_creat(arcn)) < 0) {
                        (void)rd_skip(arcn->skip + arcn->pad);
                        purg_lnk(arcn);
                        continue;
@@ -326,7 +336,8 @@
                 * any unprocessed data
                 */
                res = (*frmt->rd_data)(arcn, fd, &cnt);
-               file_close(arcn, fd);
+               if (!gnu_longlink_hack)
+                       file_close(arcn, fd);
                if (vflag && vfpart) {
                        (void)putc('\n', stderr);
                        vfpart = 0;
diff -r 44277d983d2e -r 64fb089349b0 bin/pax/buf_subs.c
--- a/bin/pax/buf_subs.c        Fri Oct 22 10:39:16 1999 +0000
+++ b/bin/pax/buf_subs.c        Fri Oct 22 10:43:11 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: buf_subs.c,v 1.10 1999/10/22 10:38:40 mrg Exp $        */
+/*     $NetBSD: buf_subs.c,v 1.11 1999/10/22 10:43:11 mrg Exp $        */
 
 /*-
  * Copyright (c) 1992 Keith Muller.
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)buf_subs.c 8.2 (Berkeley) 4/18/94";
 #else
-__RCSID("$NetBSD: buf_subs.c,v 1.10 1999/10/22 10:38:40 mrg Exp $");
+__RCSID("$NetBSD: buf_subs.c,v 1.11 1999/10/22 10:43:11 mrg Exp $");
 #endif
 #endif /* not lint */
 
@@ -767,7 +767,9 @@
         * pass the blocksize of the file being written to the write routine,
         * if the size is zero, use the default MINFBSZ
         */
-        if (fstat(ofd, &sb) == 0) {
+       if (ofd == -1)
+               sz = PAXPATHLEN+1;
+        else if (fstat(ofd, &sb) == 0) {
                if (sb.st_blksize > 0)
                        sz = (int)sb.st_blksize;
         } else
@@ -813,7 +815,7 @@
         * written. just closing with the file offset moved foward may not put
         * a hole at the end of the file.
         */
-       if (isem && (arcn->sb.st_size > 0L))
+       if (ofd != -1 && isem && (arcn->sb.st_size > 0L))
                file_flush(ofd, fnm, isem);
 
        /*
diff -r 44277d983d2e -r 64fb089349b0 bin/pax/extern.h
--- a/bin/pax/extern.h  Fri Oct 22 10:39:16 1999 +0000
+++ b/bin/pax/extern.h  Fri Oct 22 10:43:11 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: extern.h,v 1.17 1999/08/24 07:57:06 tron Exp $ */
+/*     $NetBSD: extern.h,v 1.18 1999/10/22 10:43:11 mrg Exp $  */
 
 /*-
  * Copyright (c) 1992 Keith Muller.
@@ -129,6 +129,7 @@
 /*
  * file_subs.c
  */
+extern char *gnu_hack_string;
 int file_creat __P((ARCHD *));
 void file_close __P((ARCHD *, int));
 int lnk_creat __P((ARCHD *));
diff -r 44277d983d2e -r 64fb089349b0 bin/pax/file_subs.c
--- a/bin/pax/file_subs.c       Fri Oct 22 10:39:16 1999 +0000
+++ b/bin/pax/file_subs.c       Fri Oct 22 10:43:11 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: file_subs.c,v 1.11 1999/10/22 10:38:41 mrg Exp $       */
+/*     $NetBSD: file_subs.c,v 1.12 1999/10/22 10:43:11 mrg Exp $       */
 
 /*-
  * Copyright (c) 1992 Keith Muller.
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)file_subs.c        8.1 (Berkeley) 5/31/93";
 #else
-__RCSID("$NetBSD: file_subs.c,v 1.11 1999/10/22 10:38:41 mrg Exp $");
+__RCSID("$NetBSD: file_subs.c,v 1.12 1999/10/22 10:43:11 mrg Exp $");
 #endif
 #endif /* not lint */
 
@@ -51,6 +51,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <sys/param.h>
+#include <err.h>
 #include <fcntl.h>
 #include <string.h>
 #include <stdio.h>
@@ -893,7 +894,8 @@
                                /*
                                 * skip, buf is empty so far
                                 */
-                               if (lseek(fd, (off_t)wcnt, SEEK_CUR) < 0) {
+                               if (fd > -1 &&
+                                   lseek(fd, (off_t)wcnt, SEEK_CUR) < 0) {
                                        syswarn(1,errno,"File seek on %s",
                                            name);
                                        return(-1);
@@ -910,7 +912,18 @@
                /*
                 * have non-zero data in this file system block, have to write
                 */
-               if (write(fd, st, wcnt) != wcnt) {
+               if (fd == -1) {
+                       /* GNU hack */
+                       if (gnu_hack_string)
+                               err(1, "WARNING! Major Internal Error! GNU hack Failing!");
+                       gnu_hack_string = malloc(wcnt + 1);
+                       if (gnu_hack_string == NULL) {
+                               tty_warn(1, "Out of memory");
+                               return(-1);
+                       }
+                       strncpy(gnu_hack_string, st, wcnt);
+                       gnu_hack_string[wcnt] = 0;
+               } else if (write(fd, st, wcnt) != wcnt) {
                        syswarn(1, errno, "Failed write to file %s", name);
                        return(-1);
                }
diff -r 44277d983d2e -r 64fb089349b0 bin/pax/pax.h
--- a/bin/pax/pax.h     Fri Oct 22 10:39:16 1999 +0000
+++ b/bin/pax/pax.h     Fri Oct 22 10:43:11 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pax.h,v 1.6 1999/07/03 14:42:39 kleink Exp $   */
+/*     $NetBSD: pax.h,v 1.7 1999/10/22 10:43:12 mrg Exp $      */
 
 /*-
  * Copyright (c) 1992 Keith Muller.
@@ -125,6 +125,8 @@
 #define PAX_HLK                8               /* hard link */
 #define PAX_HRG                9               /* hard link to a regular file */
 #define PAX_CTG                10              /* high performance file */ 
+#define PAX_GLL                11              /* GNU long symlink */ 
+#define PAX_GLF                12              /* GNU long file */ 
 } ARCHD;
 
 /*
diff -r 44277d983d2e -r 64fb089349b0 bin/pax/tar.c
--- a/bin/pax/tar.c     Fri Oct 22 10:39:16 1999 +0000
+++ b/bin/pax/tar.c     Fri Oct 22 10:43:11 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tar.c,v 1.15 1999/08/18 17:46:28 kleink Exp $  */
+/*     $NetBSD: tar.c,v 1.16 1999/10/22 10:43:12 mrg Exp $     */
 
 /*-
  * Copyright (c) 1992 Keith Muller.
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)tar.c      8.2 (Berkeley) 4/18/94";
 #else
-__RCSID("$NetBSD: tar.c,v 1.15 1999/08/18 17:46:28 kleink Exp $");
+__RCSID("$NetBSD: tar.c,v 1.16 1999/10/22 10:43:12 mrg Exp $");
 #endif
 #endif /* not lint */
 
@@ -81,6 +81,7 @@
 
 static int tar_nodir;                  /* do not write dirs under old tar */
 int is_oldgnutar;                      /* skip end-ofvolume checks */
+char *gnu_hack_string;                 /* ././@LongLink hackery */
 
 /*
  * tar_endwr()
@@ -466,8 +467,16 @@
         * copy out the name and values in the stat buffer
         */
        hd = (HD_TAR *)buf;
-       arcn->nlen = l_strncpy(arcn->name, hd->name, sizeof(hd->name));
-       arcn->name[arcn->nlen] = '\0';
+       if (gnu_hack_string) {
+               int len = MAX(strlen(gnu_hack_string), PAXPATHLEN);
+               arcn->nlen = l_strncpy(arcn->name, gnu_hack_string, len);
+               arcn->name[len] = '\0';
+               free(gnu_hack_string);
+               gnu_hack_string = NULL;
+       } else {
+               arcn->nlen = l_strncpy(arcn->name, hd->name, sizeof(hd->name));
+               arcn->name[arcn->nlen] = '\0';
+       }
        arcn->sb.st_mode = (mode_t)(asc_ul(hd->mode,sizeof(hd->mode),OCT) &
            0xfff);
        arcn->sb.st_uid = (uid_t)asc_ul(hd->uid, sizeof(hd->uid), OCT);
@@ -512,6 +521,21 @@
                 */
                arcn->sb.st_mode |= S_IFREG;
                break;
+       case LONGLINKTYPE:
+               arcn->type = PAX_GLL;
+               /* FALLTHROUGH */
+       case LONGNAMETYPE:
+               /*
+                * GNU long link/file; we tag these here and let the
+                * pax internals deal with it -- too ugly otherwise.
+                */
+               if (hd->linkflag != LONGLINKTYPE)



Home | Main Index | Thread Index | Old Index