summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOtto Moerbeek <otto@cvs.openbsd.org>2006-11-17 08:38:05 +0000
committerOtto Moerbeek <otto@cvs.openbsd.org>2006-11-17 08:38:05 +0000
commit2fd5da3e17a04d7b6973a11ec4552ac1e4e0d276 (patch)
tree844a008acb981ebbc99c149620bfcbb8f1ba6d79
parent81127282d1cf3a3b03192800afeb6705b3ba3cc4 (diff)
Fix extracting and setting permissions for tar archives when
(multiple) -C options are present and/or (multiple) file selections args are used. Based on a diff in NetBSD PR 22995. Tested by ckuethe@ and jaredy@; ok jaredy@
-rw-r--r--bin/pax/ar_subs.c9
-rw-r--r--bin/pax/extern.h3
-rw-r--r--bin/pax/options.c12
-rw-r--r--bin/pax/tables.c14
4 files changed, 28 insertions, 10 deletions
diff --git a/bin/pax/ar_subs.c b/bin/pax/ar_subs.c
index dcd2a99132a..3561dcd49c9 100644
--- a/bin/pax/ar_subs.c
+++ b/bin/pax/ar_subs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ar_subs.c,v 1.30 2006/07/21 22:56:58 ray Exp $ */
+/* $OpenBSD: ar_subs.c,v 1.31 2006/11/17 08:38:04 otto Exp $ */
/* $NetBSD: ar_subs.c,v 1.5 1995/03/21 09:07:06 cgd Exp $ */
/*-
@@ -38,7 +38,7 @@
#if 0
static const char sccsid[] = "@(#)ar_subs.c 8.2 (Berkeley) 4/18/94";
#else
-static const char rcsid[] = "$OpenBSD: ar_subs.c,v 1.30 2006/07/21 22:56:58 ray Exp $";
+static const char rcsid[] = "$OpenBSD: ar_subs.c,v 1.31 2006/11/17 08:38:04 otto Exp $";
#endif
#endif /* not lint */
@@ -327,7 +327,7 @@ extract(void)
(void)putc('\n', listf);
vfpart = 0;
}
- continue;
+ goto popd;
}
/*
* we have a file with data here. If we can not create it, skip
@@ -336,7 +336,7 @@ extract(void)
if ((fd = file_creat(arcn)) < 0) {
(void)rd_skip(arcn->skip + arcn->pad);
purg_lnk(arcn);
- continue;
+ goto popd;
}
/*
* extract the file from the archive and skip over padding and
@@ -351,6 +351,7 @@ extract(void)
if (!res)
(void)rd_skip(cnt + arcn->pad);
+popd:
/*
* if required, chdir around.
*/
diff --git a/bin/pax/extern.h b/bin/pax/extern.h
index 9ebdc74097f..77aad215203 100644
--- a/bin/pax/extern.h
+++ b/bin/pax/extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: extern.h,v 1.31 2005/04/28 06:58:07 otto Exp $ */
+/* $OpenBSD: extern.h,v 1.32 2006/11/17 08:38:04 otto Exp $ */
/* $NetBSD: extern.h,v 1.5 1996/03/26 23:54:16 mrg Exp $ */
/*-
@@ -243,6 +243,7 @@ extern char *argv0;
extern FILE *listf;
extern char *tempfile;
extern char *tempbase;
+extern int havechd;
int main(int, char **);
void sig_cleanup(int);
diff --git a/bin/pax/options.c b/bin/pax/options.c
index 5d8e96f79af..1d57c233631 100644
--- a/bin/pax/options.c
+++ b/bin/pax/options.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: options.c,v 1.64 2006/04/09 03:35:34 jaredy Exp $ */
+/* $OpenBSD: options.c,v 1.65 2006/11/17 08:38:04 otto Exp $ */
/* $NetBSD: options.c,v 1.6 1996/03/26 23:54:18 mrg Exp $ */
/*-
@@ -38,7 +38,7 @@
#if 0
static const char sccsid[] = "@(#)options.c 8.2 (Berkeley) 4/18/94";
#else
-static const char rcsid[] = "$OpenBSD: options.c,v 1.64 2006/04/09 03:35:34 jaredy Exp $";
+static const char rcsid[] = "$OpenBSD: options.c,v 1.65 2006/11/17 08:38:04 otto Exp $";
#endif
#endif /* not lint */
@@ -144,6 +144,11 @@ FSUB fsub[] = {
int ford[] = {5, 4, 3, 2, 1, 0, -1 };
/*
+ * Do we have -C anywhere?
+ */
+int havechd = 0;
+
+/*
* options()
* figure out if we are pax, tar or cpio. Call the appropriate options
* parser
@@ -740,6 +745,7 @@ tar_options(int argc, char **argv)
*/
break;
case 'C':
+ havechd++;
chdname = optarg;
break;
case 'H':
@@ -878,6 +884,7 @@ tar_options(int argc, char **argv)
if (*++argv == NULL)
break;
chdname = *argv++;
+ havechd++;
} else if (pat_add(*argv++, chdname) < 0)
tar_usage();
else
@@ -957,6 +964,7 @@ tar_options(int argc, char **argv)
break;
if (ftree_add(*argv++, 1) < 0)
tar_usage();
+ havechd++;
} else if (ftree_add(*argv++, 0) < 0)
tar_usage();
}
diff --git a/bin/pax/tables.c b/bin/pax/tables.c
index 425a8be05e8..2705b319c33 100644
--- a/bin/pax/tables.c
+++ b/bin/pax/tables.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tables.c,v 1.23 2005/04/21 21:47:18 beck Exp $ */
+/* $OpenBSD: tables.c,v 1.24 2006/11/17 08:38:04 otto Exp $ */
/* $NetBSD: tables.c,v 1.4 1995/03/21 09:07:45 cgd Exp $ */
/*-
@@ -38,7 +38,7 @@
#if 0
static const char sccsid[] = "@(#)tables.c 8.1 (Berkeley) 5/31/93";
#else
-static const char rcsid[] = "$OpenBSD: tables.c,v 1.23 2005/04/21 21:47:18 beck Exp $";
+static const char rcsid[] = "$OpenBSD: tables.c,v 1.24 2006/11/17 08:38:04 otto Exp $";
#endif
#endif /* not lint */
@@ -151,7 +151,7 @@ chk_lnk(ARCHD *arcn)
indx = ((unsigned)arcn->sb.st_ino) % L_TAB_SZ;
if ((pt = ltab[indx]) != NULL) {
/*
- * it's hash chain in not empty, walk down looking for it
+ * its hash chain in not empty, walk down looking for it
*/
ppt = &(ltab[indx]);
while (pt != NULL) {
@@ -1126,10 +1126,18 @@ void
add_dir(char *name, struct stat *psb, int frc_mode)
{
DIRDATA *dblk;
+ char realname[MAXPATHLEN], *rp;
if (dirp == NULL)
return;
+ if (havechd && *name != '/') {
+ if ((rp = realpath(name, realname)) == NULL) {
+ paxwarn(1, "Cannot canonicalize %s", name);
+ return;
+ }
+ name = rp;
+ }
if (dircnt == dirsize) {
dblk = realloc(dirp, 2 * dirsize * sizeof(DIRDATA));
if (dblk == NULL) {