summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bin/pax/file_subs.c70
-rw-r--r--bin/pax/tar.110
2 files changed, 56 insertions, 24 deletions
diff --git a/bin/pax/file_subs.c b/bin/pax/file_subs.c
index 670a2fdb309..5288e390c2a 100644
--- a/bin/pax/file_subs.c
+++ b/bin/pax/file_subs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: file_subs.c,v 1.14 2001/05/16 03:04:56 mickey Exp $ */
+/* $OpenBSD: file_subs.c,v 1.15 2001/10/25 16:59:03 niklas Exp $ */
/* $NetBSD: file_subs.c,v 1.4 1995/03/21 09:07:18 cgd Exp $ */
/*-
@@ -42,7 +42,7 @@
#if 0
static char sccsid[] = "@(#)file_subs.c 8.1 (Berkeley) 5/31/93";
#else
-static char rcsid[] = "$OpenBSD: file_subs.c,v 1.14 2001/05/16 03:04:56 mickey Exp $";
+static char rcsid[] = "$OpenBSD: file_subs.c,v 1.15 2001/10/25 16:59:03 niklas Exp $";
#endif
#endif /* not lint */
@@ -400,6 +400,9 @@ node_creat(arcn)
register int pass = 0;
mode_t file_mode;
struct stat sb;
+ char target[MAXPATHLEN];
+ char *nm = arcn->name;
+ int len;
/*
* create node based on type, if that fails try to unlink the node and
@@ -412,20 +415,43 @@ node_creat(arcn)
for (;;) {
switch(arcn->type) {
case PAX_DIR:
- res = mkdir(arcn->name, file_mode);
+ /*
+ * If -h (or -L) was given in tar-mode, follow the
+ * potential symlink chain before trying to create the
+ * directory.
+ */
+ if (strcmp(NM_TAR, argv0) == 0 && Lflag) {
+ while (lstat(nm, &sb) == 0 &&
+ S_ISLNK(sb.st_mode)) {
+ len = readlink(nm, target,
+ sizeof target - 1);
+ if (len == -1) {
+ syswarn(0, errno,
+ "cannot follow symlink %s in chain for %s",
+ nm, arcn->name);
+ res = -1;
+ goto badlink;
+ }
+ target[len] = '\0';
+ nm = target;
+ }
+ }
+ res = mkdir(nm, file_mode);
+
+badlink:
if (ign)
res = 0;
break;
case PAX_CHR:
file_mode |= S_IFCHR;
- res = mknod(arcn->name, file_mode, arcn->sb.st_rdev);
+ res = mknod(nm, file_mode, arcn->sb.st_rdev);
break;
case PAX_BLK:
file_mode |= S_IFBLK;
- res = mknod(arcn->name, file_mode, arcn->sb.st_rdev);
+ res = mknod(nm, file_mode, arcn->sb.st_rdev);
break;
case PAX_FIF:
- res = mkfifo(arcn->name, file_mode);
+ res = mkfifo(nm, file_mode);
break;
case PAX_SCK:
/*
@@ -433,10 +459,10 @@ node_creat(arcn)
*/
paxwarn(0,
"%s skipped. Sockets cannot be copied or extracted",
- arcn->name);
+ nm);
return(-1);
case PAX_SLK:
- res = symlink(arcn->ln_name, arcn->name);
+ res = symlink(arcn->ln_name, nm);
break;
case PAX_CTG:
case PAX_HLK:
@@ -447,7 +473,7 @@ node_creat(arcn)
* we should never get here
*/
paxwarn(0, "%s has an unknown file type, skipping",
- arcn->name);
+ nm);
return(-1);
}
@@ -463,14 +489,14 @@ node_creat(arcn)
* we failed to make the node
*/
oerrno = errno;
- if ((ign = unlnk_exist(arcn->name, arcn->type)) < 0)
+ if ((ign = unlnk_exist(nm, arcn->type)) < 0)
return(-1);
if (++pass <= 1)
continue;
- if (nodirs || chk_path(arcn->name,arcn->sb.st_uid,arcn->sb.st_gid) < 0) {
- syswarn(1, oerrno, "Could not create: %s", arcn->name);
+ if (nodirs || chk_path(nm,arcn->sb.st_uid,arcn->sb.st_gid) < 0) {
+ syswarn(1, oerrno, "Could not create: %s", nm);
return(-1);
}
}
@@ -480,8 +506,8 @@ node_creat(arcn)
*/
if (pids)
res = ((arcn->type == PAX_SLK) ?
- set_lids(arcn->name, arcn->sb.st_uid, arcn->sb.st_gid) :
- set_ids(arcn->name, arcn->sb.st_uid, arcn->sb.st_gid));
+ set_lids(nm, arcn->sb.st_uid, arcn->sb.st_gid) :
+ set_ids(nm, arcn->sb.st_uid, arcn->sb.st_gid));
else
res = 0;
@@ -499,7 +525,7 @@ node_creat(arcn)
if (!pmode || res)
arcn->sb.st_mode &= ~(SETBITS);
if (pmode)
- set_pmode(arcn->name, arcn->sb.st_mode);
+ set_pmode(nm, arcn->sb.st_mode);
if (arcn->type == PAX_DIR && strcmp(NM_CPIO, argv0) != 0) {
/*
@@ -511,11 +537,11 @@ node_creat(arcn)
* and modes will be fixed after the entire archive is read and
* before pax exits.
*/
- if (access(arcn->name, R_OK | W_OK | X_OK) < 0) {
- if (lstat(arcn->name, &sb) < 0) {
+ if (access(nm, R_OK | W_OK | X_OK) < 0) {
+ if (lstat(nm, &sb) < 0) {
syswarn(0, errno,"Could not access %s (stat)",
arcn->name);
- set_pmode(arcn->name,file_mode | S_IRWXU);
+ set_pmode(nm,file_mode | S_IRWXU);
} else {
/*
* We have to add rights to the dir, so we make
@@ -523,7 +549,7 @@ node_creat(arcn)
* restored AS CREATED and not as stored if
* pmode is not set.
*/
- set_pmode(arcn->name,
+ set_pmode(nm,
((sb.st_mode & FILEBITS) | S_IRWXU));
if (!pmode)
arcn->sb.st_mode = sb.st_mode;
@@ -533,13 +559,13 @@ node_creat(arcn)
* we have to force the mode to what was set here,
* since we changed it from the default as created.
*/
- add_dir(arcn->name, arcn->nlen, &(arcn->sb), 1);
+ add_dir(nm, strlen(nm), &(arcn->sb), 1);
} else if (pmode || patime || pmtime)
- add_dir(arcn->name, arcn->nlen, &(arcn->sb), 0);
+ add_dir(nm, strlen(nm), &(arcn->sb), 0);
}
if (patime || pmtime)
- set_ftime(arcn->name, arcn->sb.st_mtime, arcn->sb.st_atime, 0);
+ set_ftime(nm, arcn->sb.st_mtime, arcn->sb.st_atime, 0);
return(0);
}
diff --git a/bin/pax/tar.1 b/bin/pax/tar.1
index e5c45997cbc..f81b49e4ce7 100644
--- a/bin/pax/tar.1
+++ b/bin/pax/tar.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tar.1,v 1.34 2001/05/11 20:02:16 mickey Exp $
+.\" $OpenBSD: tar.1,v 1.35 2001/10/25 16:59:03 niklas Exp $
.\"
.\" Copyright (c) 1996 SigmaSoft, Th. Lockert
.\" All rights reserved.
@@ -28,7 +28,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $OpenBSD: tar.1,v 1.34 2001/05/11 20:02:16 mickey Exp $
+.\" $OpenBSD: tar.1,v 1.35 2001/10/25 16:59:03 niklas Exp $
.\"
.Dd February 7, 2001
.Dt TAR 1
@@ -108,6 +108,9 @@ Defaults to
.It Fl h
Follow symbolic links as if they were normal files
or directories.
+In extract mode this means that a directory entry in the archive
+will not overwrite an existing symbolic link, but rather what the
+link ultimately points to.
.It Fl m
Do not preserve modification time.
.It Fl O
@@ -202,6 +205,9 @@ from the directory.
Follow symlinks given on command line only.
.It Fl L
Follow all symlinks.
+In extract mode this means that a directory entry in the archive
+will not overwrite an existing symbolic link, but rather what the
+link ultimately points to.
.It Fl P
Do not strip leading slashes
.Pq Sq /