Source-Changes-HG archive

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

[src/trunk]: src/bin/pax Implement positional -C argument to tar.



details:   https://anonhg.NetBSD.org/src/rev/91b763b377f0
branches:  trunk
changeset: 477583:91b763b377f0
user:      is <is%NetBSD.org@localhost>
date:      Fri Oct 22 20:59:08 1999 +0000

description:
Implement positional -C argument to tar.

diffstat:

 bin/pax/ar_io.c   |  94 ++++++++++++++++++++++++++++++++++++++++--------------
 bin/pax/extern.h  |  10 +++--
 bin/pax/ftree.c   |  23 +++++++++---
 bin/pax/options.c |  90 +++++++++++++++++++++++++++++++++++++++++++++-------
 bin/pax/pat_rep.c |  21 ++++++++---
 bin/pax/pax.h     |   3 +-
 6 files changed, 187 insertions(+), 54 deletions(-)

diffs (truncated from 535 to 300 lines):

diff -r c536e6c7d2dd -r 91b763b377f0 bin/pax/ar_io.c
--- a/bin/pax/ar_io.c   Fri Oct 22 17:06:12 1999 +0000
+++ b/bin/pax/ar_io.c   Fri Oct 22 20:59:08 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ar_io.c,v 1.13 1999/03/03 18:06:52 christos Exp $      */
+/*     $NetBSD: ar_io.c,v 1.14 1999/10/22 20:59:08 is Exp $    */
 
 /*-
  * Copyright (c) 1992 Keith Muller.
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)ar_io.c    8.2 (Berkeley) 4/18/94";
 #else
-__RCSID("$NetBSD: ar_io.c,v 1.13 1999/03/03 18:06:52 christos Exp $");
+__RCSID("$NetBSD: ar_io.c,v 1.14 1999/10/22 20:59:08 is Exp $");
 #endif
 #endif /* not lint */
 
@@ -88,6 +88,8 @@
 const char *arcname;                   /* printable name of archive */
 const char *gzip_program;              /* name of gzip program */
 time_t starttime;                      /* time the run started */
+int minusCfd = -1;                     /* active -C directory */
+int curdirfd = -1;                     /* original current directory */
 
 static int get_phys __P((void));
 extern sigset_t s_mask;
@@ -114,7 +116,6 @@
 #endif
 {
         struct mtget mb;
-       static int minusCfd = -1, curdirfd = -1;
 
        /*
         * change back to the current directory (for now).
@@ -209,6 +210,13 @@
         */
        if (artyp != ISREG)
                can_unlnk = 0;
+
+       /*
+        * change directory if necessary
+        */
+       if (minusCfd != -1)
+               fchdir(minusCfd);
+
        /*
         * if we are writing, we are done
         */
@@ -219,27 +227,6 @@
        }
 
        /*
-        * change directory if necessary
-        */
-       if (chdir_dir) {
-               if (curdirfd == -1)
-                       curdirfd = open(".", O_RDONLY);
-               if (curdirfd < 1) {
-                       syswarn(0, errno, "failed to open directory .");
-                       return (-1);
-               }
-
-               if (minusCfd == -1)
-                       minusCfd = open(chdir_dir, O_RDONLY);
-               if (minusCfd < 1) {
-                       syswarn(0, errno, "failed to open directory %s",
-                           chdir_dir);
-                       return (-1);
-               }
-               fchdir(minusCfd);
-       }
-
-       /*
         * set default blksz on read. APPNDs writes rdblksz on the last volume
         * On all new archive volumes, we shift to wrblksz (if the user
         * specified one, otherwize we will continue to use rdblksz). We
@@ -1477,3 +1464,62 @@
        else
                (void)write(STDERR_FILENO, buf, strlen(buf));
 }
+
+/*
+ * ar_dochdir(name)
+ *     change directory to name, and remember where we came from and
+ *     where we change to (for ar_open).
+ *
+ *     Maybe we could try to be smart and only do the actual chdir
+ *     when necessary to write a file read from the archive, but this
+ *     is not easy to get right given the pax code structure.
+ *
+ *     Be sure to not leak descriptors!
+ *
+ *     We are called N * M times when extracting, and N times when
+ *     writing archives, where
+ *     N:      number of -C options
+ *     M:      number of files in archive
+ *    
+ * Returns 0 if all went well, else -1.
+ */
+
+#ifdef __STDC__
+int
+ar_dochdir(char *name)
+#else
+int
+ar_dochdir(name)
+       char *name;
+#endif
+{
+       if (curdirfd == -1) {
+               /* first time. remember where we came from */
+               curdirfd = open(".", O_RDONLY);
+               if (curdirfd < 0) {
+                       syswarn(0, errno, "failed to open directory .");
+                       return (-1);
+               }
+       } else /* XXX if (*name != '/') XXX */ {
+               /*
+                * relative chdir. Make sure to get the same directory
+                * each time by fchdir-ing back first.
+                */
+               fchdir(curdirfd);
+       }
+
+       if (minusCfd != -1) {
+               /* don't leak descriptors */
+               close(minusCfd);
+               minusCfd = -1;
+       }
+
+       minusCfd = open(name, O_RDONLY);
+       if (minusCfd < 0) {
+               syswarn(0, errno, "failed to open directory %s", name);
+               return (-1);
+       }
+
+       fchdir(minusCfd);
+       return (0);
+}
diff -r c536e6c7d2dd -r 91b763b377f0 bin/pax/extern.h
--- a/bin/pax/extern.h  Fri Oct 22 17:06:12 1999 +0000
+++ b/bin/pax/extern.h  Fri Oct 22 20:59:08 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: extern.h,v 1.18 1999/10/22 10:43:11 mrg Exp $  */
+/*     $NetBSD: extern.h,v 1.19 1999/10/22 20:59:08 is Exp $   */
 
 /*-
  * Copyright (c) 1992 Keith Muller.
@@ -49,6 +49,7 @@
  * ar_io.c
  */
 extern const char *arcname;
+extern int curdirfd;
 extern const char *gzip_program;
 extern time_t starttime;
 int ar_open __P((const char *));
@@ -63,6 +64,7 @@
 int ar_rev __P((off_t ));
 int ar_next __P((void));
 void ar_summary __P((int));
+int ar_dochdir __P((char *));
 
 /*
  * ar_subs.c
@@ -150,7 +152,7 @@
  * ftree.c
  */
 int ftree_start __P((void));
-int ftree_add __P((char *));
+int ftree_add __P((char *, int));
 void ftree_sel __P((ARCHD *));
 void ftree_chk __P((void));
 int next_file __P((ARCHD *));
@@ -181,17 +183,17 @@
 extern FSUB fsub[];
 extern int ford[];
 extern int cpio_mode;
-extern char *chdir_dir;
 void options __P((int, char **));
 OPLIST * opt_next __P((void));
 int opt_add __P((const char *));
+int opt_chdir __P((char *));
 int bad_opt __P((void));
 
 /*
  * pat_rep.c
  */
 int rep_add __P((char *));
-int pat_add __P((char *));
+int pat_add __P((char *, int));
 void pat_chk __P((void));
 int pat_sel __P((ARCHD *));
 int pat_match __P((ARCHD *));
diff -r c536e6c7d2dd -r 91b763b377f0 bin/pax/ftree.c
--- a/bin/pax/ftree.c   Fri Oct 22 17:06:12 1999 +0000
+++ b/bin/pax/ftree.c   Fri Oct 22 20:59:08 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ftree.c,v 1.8 1998/07/28 17:44:24 mycroft Exp $        */
+/*     $NetBSD: ftree.c,v 1.9 1999/10/22 20:59:08 is Exp $     */
 
 /*-
  * Copyright (c) 1992 Keith Muller.
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)ftree.c    8.2 (Berkeley) 4/18/94";
 #else
-__RCSID("$NetBSD: ftree.c,v 1.8 1998/07/28 17:44:24 mycroft Exp $");
+__RCSID("$NetBSD: ftree.c,v 1.9 1999/10/22 20:59:08 is Exp $");
 #endif
 #endif /* not lint */
 
@@ -157,11 +157,12 @@
 
 #if __STDC__
 int
-ftree_add(char *str)
+ftree_add(char *str, int isdir)
 #else
 int
-ftree_add(str)
+ftree_add(str, isdir)
        char *str;
+       int isdir;
 #endif
 {
        FTREE *ft;
@@ -188,7 +189,7 @@
        if (((len = strlen(str) - 1) > 0) && (str[len] == '/'))
                str[len] = '\0';
        ft->fname = str;
-       ft->refcnt = 0;
+       ft->refcnt = -isdir;
        ft->fow = NULL;
        if (fthead == NULL) {
                fttail = fthead = ft;
@@ -266,7 +267,7 @@
         * that never had a match
         */
        for (ft = fthead; ft != NULL; ft = ft->fow) {
-               if (ft->refcnt > 0)
+               if (ft->refcnt != 0)
                        continue;
                if (wban == 0) {
                        tty_warn(1,
@@ -327,6 +328,16 @@
                                ftcur = fthead;
                        else if ((ftcur = ftcur->fow) == NULL)
                                return(-1);
+
+                       if (ftcur->refcnt < 0) {
+                               /*
+                                * chdir entry.
+                                * Change directory and retry loop.
+                                */
+                               if (ar_dochdir(ftcur->fname))
+                                       return (-1);
+                               continue;
+                       }
                        farray[0] = ftcur->fname;
                }
 
diff -r c536e6c7d2dd -r 91b763b377f0 bin/pax/options.c
--- a/bin/pax/options.c Fri Oct 22 17:06:12 1999 +0000
+++ b/bin/pax/options.c Fri Oct 22 20:59:08 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: options.c,v 1.22 1999/08/24 08:02:27 tron Exp $        */
+/*     $NetBSD: options.c,v 1.23 1999/10/22 20:59:08 is Exp $  */
 
 /*-
  * Copyright (c) 1992 Keith Muller.
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)options.c  8.2 (Berkeley) 4/18/94";
 #else
-__RCSID("$NetBSD: options.c,v 1.22 1999/08/24 08:02:27 tron Exp $");
+__RCSID("$NetBSD: options.c,v 1.23 1999/10/22 20:59:08 is Exp $");
 #endif
 #endif /* not lint */
 
@@ -68,12 +68,12 @@
  */
 
 int cpio_mode;                 /* set if we are in cpio mode */
-char *chdir_dir;               /* directory to chdir to before operating */
 
 static int nopids;             /* tar mode: suppress "pids" for -p option */
 static char *flgch = FLGCH;    /* list of all possible flags (pax) */
 static OPLIST *ophead = NULL;  /* head for format specific options -x */
 static OPLIST *optail = NULL;  /* option tail */
+static char *firstminusC;      /* first -C argument encountered. */
 
 static int no_op __P((void));
 static void printflg __P((unsigned int));
@@ -86,6 +86,8 @@
 static void cpio_options __P((int, char **));
 static void cpio_usage __P((void));
 
+static void checkpositionalminusC __P((char ***, int (*)(char *, int)));
+



Home | Main Index | Thread Index | Old Index