summaryrefslogtreecommitdiff
path: root/bin/pax
diff options
context:
space:
mode:
Diffstat (limited to 'bin/pax')
-rw-r--r--bin/pax/extern.h3
-rw-r--r--bin/pax/file_subs.c4
-rw-r--r--bin/pax/tables.c60
3 files changed, 60 insertions, 7 deletions
diff --git a/bin/pax/extern.h b/bin/pax/extern.h
index 22912087c10..3b3400b26d1 100644
--- a/bin/pax/extern.h
+++ b/bin/pax/extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: extern.h,v 1.47 2015/02/12 23:44:57 guenther Exp $ */
+/* $OpenBSD: extern.h,v 1.48 2015/02/15 22:18:29 millert Exp $ */
/* $NetBSD: extern.h,v 1.5 1996/03/26 23:54:16 mrg Exp $ */
/*-
@@ -286,6 +286,7 @@ void add_atdir(char *, dev_t, ino_t, time_t, time_t);
int do_atdir(const char *, dev_t, ino_t);
int dir_start(void);
void add_dir(char *, struct stat *, int);
+void delete_dir(dev_t, ino_t);
void proc_dir(int _in_sig);
u_int st_hash(const char *, int, int);
diff --git a/bin/pax/file_subs.c b/bin/pax/file_subs.c
index 2c5475b963c..b71575bdfd6 100644
--- a/bin/pax/file_subs.c
+++ b/bin/pax/file_subs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: file_subs.c,v 1.42 2015/02/12 23:44:57 guenther Exp $ */
+/* $OpenBSD: file_subs.c,v 1.43 2015/02/15 22:18:29 millert Exp $ */
/* $NetBSD: file_subs.c,v 1.4 1995/03/21 09:07:18 cgd Exp $ */
/*-
@@ -299,6 +299,7 @@ mk_link(char *to, struct stat *to_sb, char *from, int ign)
syswarn(1, errno, "Unable to remove %s", from);
return(-1);
}
+ delete_dir(sb.st_dev, sb.st_ino);
} else if (unlink(from) < 0) {
if (!ign) {
syswarn(1, errno, "Unable to remove %s", from);
@@ -564,6 +565,7 @@ unlnk_exist(char *name, int type)
syswarn(1,errno,"Unable to remove directory %s", name);
return(-1);
}
+ delete_dir(sb.st_dev, sb.st_ino);
return(0);
}
diff --git a/bin/pax/tables.c b/bin/pax/tables.c
index b99dbbe4534..79db2a5e63f 100644
--- a/bin/pax/tables.c
+++ b/bin/pax/tables.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tables.c,v 1.42 2015/02/12 23:44:57 guenther Exp $ */
+/* $OpenBSD: tables.c,v 1.43 2015/02/15 22:18:29 millert Exp $ */
/* $NetBSD: tables.c,v 1.4 1995/03/21 09:07:45 cgd Exp $ */
/*-
@@ -556,7 +556,13 @@ sltab_add_sym(const char *path0, const char *value0, mode_t mode)
}
close(fd);
- if ((path = strdup(path0)) == NULL) {
+ if (havechd && *path0 != '/') {
+ if ((path = realpath(path0, NULL)) == NULL) {
+ syswarn(1, errno, "Cannot canonicalize %s", path0);
+ unlink(path0);
+ return (-1);
+ }
+ } else if ((path = strdup(path0)) == NULL) {
syswarn(1, errno, "defered symlink path");
unlink(path0);
return (-1);
@@ -640,7 +646,14 @@ sltab_add_link(const char *path, const struct stat *sb)
syswarn(1, errno, "deferred symlink hardlink");
return (-1);
}
- if ((p->sp_path = strdup(path)) == NULL) {
+ if (havechd && *path != '/') {
+ if ((p->sp_path = realpath(path, NULL)) == NULL) {
+ syswarn(1, errno, "Cannot canonicalize %s",
+ path);
+ free(p);
+ return (-1);
+ }
+ } else if ((p->sp_path = strdup(path)) == NULL) {
syswarn(1, errno, "defered symlink hardlink path");
free(p);
return (-1);
@@ -1372,7 +1385,8 @@ do_atdir(const char *name, dev_t dev, ino_t ino)
/*
* return if we did not find it.
*/
- if (pt == NULL || strcmp(name, pt->ft.ft_name) == 0)
+ if (pt == NULL || pt->ft.ft_name == NULL ||
+ strcmp(name, pt->ft.ft_name) == 0)
return(-1);
/*
@@ -1489,6 +1503,35 @@ add_dir(char *name, struct stat *psb, int frc_mode)
}
/*
+ * delete_dir()
+ * When we rmdir a directory, we may want to make sure we don't
+ * later warn about being unable to set its mode and times.
+ */
+
+void
+delete_dir(dev_t dev, ino_t ino)
+{
+ DIRDATA *dblk;
+ char *name;
+ size_t i;
+
+ if (dirp == NULL)
+ return;
+ for (i = 0; i < dircnt; i++) {
+ dblk = &dirp[i];
+
+ if (dblk->ft.ft_name == NULL)
+ continue;
+ if (dblk->ft.ft_dev == dev && dblk->ft.ft_ino == ino) {
+ name = dblk->ft.ft_name;
+ dblk->ft.ft_name = NULL;
+ free(name);
+ break;
+ }
+ }
+}
+
+/*
* proc_dir(int in_sig)
* process all file modes and times stored for directories CREATED
* by pax. If in_sig is set, we're in a signal handler and can't
@@ -1508,11 +1551,18 @@ proc_dir(int in_sig)
*/
cnt = dircnt;
while (cnt-- > 0) {
+ dblk = &dirp[cnt];
+ /*
+ * If we remove a directory we created, we replace the
+ * ft_name with NULL. Ignore those.
+ */
+ if (dblk->ft.ft_name == NULL)
+ continue;
+
/*
* frc_mode set, make sure we set the file modes even if
* the user didn't ask for it (see file_subs.c for more info)
*/
- dblk = &dirp[cnt];
set_attr(&dblk->ft, 0, dblk->mode, pmode || dblk->frc_mode,
in_sig);
if (!in_sig)