aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/xinstall
diff options
context:
space:
mode:
authorBaptiste Daroussin <bapt@FreeBSD.org>2015-11-20 08:45:59 +0000
committerBaptiste Daroussin <bapt@FreeBSD.org>2015-11-20 08:45:59 +0000
commitd0b9260683aacb7b8d772273bfb03a1bdfc30e2f (patch)
treec7b54c9f68c1485b9dce758b07031059c9f9a2db /usr.bin/xinstall
parent0e51ea9106f14e6dbefe3ab4ca36e31e3b124038 (diff)
install: do not follow symlinks
In case the target of install is a dead symlink, install(1) used to not consider it as "existing" because of the usage of stat(2) instead of lstat(2). meaning the old file (the symlink) is not removed before the new file is created. The symlink is being followed and the new file becoming the target of the symlink instead of the target of install(1) Reviewed by: jhb, brooks MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D4191
Notes
Notes: svn path=/head/; revision=291091
Diffstat (limited to 'usr.bin/xinstall')
-rw-r--r--usr.bin/xinstall/xinstall.c16
1 files changed, 5 insertions, 11 deletions
diff --git a/usr.bin/xinstall/xinstall.c b/usr.bin/xinstall/xinstall.c
index 30cc6c7a7768..1121cffe78ac 100644
--- a/usr.bin/xinstall/xinstall.c
+++ b/usr.bin/xinstall/xinstall.c
@@ -754,10 +754,7 @@ install(const char *from_name, const char *to_name, u_long fset, u_int flags)
devnull = 1;
}
- if (!dolink)
- target = (stat(to_name, &to_sb) == 0);
- else
- target = (lstat(to_name, &to_sb) == 0);
+ target = (lstat(to_name, &to_sb) == 0);
if (dolink) {
if (target && !safecopy) {
@@ -772,8 +769,7 @@ install(const char *from_name, const char *to_name, u_long fset, u_int flags)
return;
}
- /* Only install to regular files. */
- if (target && !S_ISREG(to_sb.st_mode)) {
+ if (target && !S_ISREG(to_sb.st_mode) && !S_ISLNK(to_sb.st_mode)) {
errno = EFTYPE;
warn("%s", to_name);
return;
@@ -786,7 +782,7 @@ install(const char *from_name, const char *to_name, u_long fset, u_int flags)
err(EX_OSERR, "%s", from_name);
/* If we don't strip, we can compare first. */
- if (docompare && !dostrip && target) {
+ if (docompare && !dostrip && target && S_ISREG(to_sb.st_mode)) {
if ((to_fd = open(to_name, O_RDONLY, 0)) < 0)
err(EX_OSERR, "%s", to_name);
if (devnull)
@@ -838,7 +834,7 @@ install(const char *from_name, const char *to_name, u_long fset, u_int flags)
/*
* Compare the stripped temp file with the target.
*/
- if (docompare && dostrip && target) {
+ if (docompare && dostrip && target && S_ISREG(to_sb.st_mode)) {
temp_fd = to_fd;
/* Re-open to_fd using the real target name. */
@@ -872,9 +868,7 @@ install(const char *from_name, const char *to_name, u_long fset, u_int flags)
}
(void) close(temp_fd);
}
- }
-
- if (dostrip && (!docompare || !target))
+ } else if (dostrip)
digestresult = digest_file(tempfile);
/*