diff options
Diffstat (limited to 'bin/pax')
-rw-r--r-- | bin/pax/extern.h | 3 | ||||
-rw-r--r-- | bin/pax/file_subs.c | 4 | ||||
-rw-r--r-- | bin/pax/tables.c | 60 |
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) |