Changeset View
Changeset View
Standalone View
Standalone View
usr.bin/xinstall/xinstall.c
Show First 20 Lines • Show All 527 Lines • ▼ Show 20 Lines | if (quiet_mktemp(tmpl) == NULL) | ||||
err(EX_OSERR, "%s: mktemp", tmpl); | err(EX_OSERR, "%s: mktemp", tmpl); | ||||
ret = link(from_name, tmpl); | ret = link(from_name, tmpl); | ||||
if (ret == 0) { | if (ret == 0) { | ||||
if (target_sb->st_mode & S_IFDIR && rmdir(to_name) == | if (target_sb->st_mode & S_IFDIR && rmdir(to_name) == | ||||
-1) { | -1) { | ||||
unlink(tmpl); | unlink(tmpl); | ||||
err(EX_OSERR, "%s", to_name); | err(EX_OSERR, "%s", to_name); | ||||
} | } | ||||
#if HAVE_STRUCT_STAT_ST_FLAGS | |||||
if (target_sb->st_flags & NOCHANGEBITS) | if (target_sb->st_flags & NOCHANGEBITS) | ||||
(void)chflags(to_name, target_sb->st_flags & | (void)chflags(to_name, target_sb->st_flags & | ||||
~NOCHANGEBITS); | ~NOCHANGEBITS); | ||||
#endif | |||||
if (verbose) | if (verbose) | ||||
printf("install: link %s -> %s\n", | printf("install: link %s -> %s\n", | ||||
from_name, to_name); | from_name, to_name); | ||||
ret = rename(tmpl, to_name); | ret = rename(tmpl, to_name); | ||||
/* | /* | ||||
* If rename has posix semantics, then the temporary | * If rename has posix semantics, then the temporary | ||||
* file may still exist when from_name and to_name point | * file may still exist when from_name and to_name point | ||||
* to the same file, so unlink it unconditionally. | * to the same file, so unlink it unconditionally. | ||||
Show All 27 Lines | if (safecopy && target_sb != NULL) { | ||||
if (symlink(from_name, tmpl) == -1) | if (symlink(from_name, tmpl) == -1) | ||||
err(EX_OSERR, "symlink %s -> %s", from_name, tmpl); | err(EX_OSERR, "symlink %s -> %s", from_name, tmpl); | ||||
if (target_sb->st_mode & S_IFDIR && rmdir(to_name) == -1) { | if (target_sb->st_mode & S_IFDIR && rmdir(to_name) == -1) { | ||||
(void)unlink(tmpl); | (void)unlink(tmpl); | ||||
err(EX_OSERR, "%s", to_name); | err(EX_OSERR, "%s", to_name); | ||||
} | } | ||||
#if HAVE_STRUCT_STAT_ST_FLAGS | |||||
if (target_sb->st_flags & NOCHANGEBITS) | if (target_sb->st_flags & NOCHANGEBITS) | ||||
(void)chflags(to_name, target_sb->st_flags & | (void)chflags(to_name, target_sb->st_flags & | ||||
~NOCHANGEBITS); | ~NOCHANGEBITS); | ||||
#endif | |||||
if (verbose) | if (verbose) | ||||
printf("install: symlink %s -> %s\n", | printf("install: symlink %s -> %s\n", | ||||
from_name, to_name); | from_name, to_name); | ||||
if (rename(tmpl, to_name) == -1) { | if (rename(tmpl, to_name) == -1) { | ||||
/* Remove temporary link before exiting. */ | /* Remove temporary link before exiting. */ | ||||
(void)unlink(tmpl); | (void)unlink(tmpl); | ||||
err(EX_OSERR, "%s: rename", to_name); | err(EX_OSERR, "%s: rename", to_name); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 181 Lines • ▼ Show 20 Lines | install(const char *from_name, const char *to_name, u_long fset, u_int flags) | ||||
} | } | ||||
target = (lstat(to_name, &to_sb) == 0); | target = (lstat(to_name, &to_sb) == 0); | ||||
if (dolink) { | if (dolink) { | ||||
if (target && !safecopy) { | if (target && !safecopy) { | ||||
if (to_sb.st_mode & S_IFDIR && rmdir(to_name) == -1) | if (to_sb.st_mode & S_IFDIR && rmdir(to_name) == -1) | ||||
err(EX_OSERR, "%s", to_name); | err(EX_OSERR, "%s", to_name); | ||||
#if HAVE_STRUCT_STAT_ST_FLAGS | |||||
if (to_sb.st_flags & NOCHANGEBITS) | if (to_sb.st_flags & NOCHANGEBITS) | ||||
(void)chflags(to_name, | (void)chflags(to_name, | ||||
to_sb.st_flags & ~NOCHANGEBITS); | to_sb.st_flags & ~NOCHANGEBITS); | ||||
#endif | |||||
unlink(to_name); | unlink(to_name); | ||||
} | } | ||||
makelink(from_name, to_name, target ? &to_sb : NULL); | makelink(from_name, to_name, target ? &to_sb : NULL); | ||||
return; | return; | ||||
} | } | ||||
if (target && !S_ISREG(to_sb.st_mode) && !S_ISLNK(to_sb.st_mode)) { | if (target && !S_ISREG(to_sb.st_mode) && !S_ISLNK(to_sb.st_mode)) { | ||||
errno = EFTYPE; | errno = EFTYPE; | ||||
▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | #endif | ||||
} else if (dostrip) | } else if (dostrip) | ||||
digestresult = digest_file(tempfile); | digestresult = digest_file(tempfile); | ||||
/* | /* | ||||
* Move the new file into place if doing a safe copy | * Move the new file into place if doing a safe copy | ||||
* and the files are different (or just not compared). | * and the files are different (or just not compared). | ||||
*/ | */ | ||||
if (tempcopy && !files_match) { | if (tempcopy && !files_match) { | ||||
#if HAVE_STRUCT_STAT_ST_FLAGS | |||||
/* Try to turn off the immutable bits. */ | /* Try to turn off the immutable bits. */ | ||||
if (to_sb.st_flags & NOCHANGEBITS) | if (to_sb.st_flags & NOCHANGEBITS) | ||||
(void)chflags(to_name, to_sb.st_flags & ~NOCHANGEBITS); | (void)chflags(to_name, to_sb.st_flags & ~NOCHANGEBITS); | ||||
#endif | |||||
if (dobackup) { | if (dobackup) { | ||||
if ((size_t)snprintf(backup, MAXPATHLEN, "%s%s", to_name, | if ((size_t)snprintf(backup, MAXPATHLEN, "%s%s", to_name, | ||||
suffix) != strlen(to_name) + strlen(suffix)) { | suffix) != strlen(to_name) + strlen(suffix)) { | ||||
unlink(tempfile); | unlink(tempfile); | ||||
errx(EX_OSERR, "%s: backup filename too long", | errx(EX_OSERR, "%s: backup filename too long", | ||||
to_name); | to_name); | ||||
} | } | ||||
if (verbose) | if (verbose) | ||||
(void)printf("install: %s -> %s\n", to_name, backup); | (void)printf("install: %s -> %s\n", to_name, backup); | ||||
if (unlink(backup) < 0 && errno != ENOENT) { | if (unlink(backup) < 0 && errno != ENOENT) { | ||||
serrno = errno; | serrno = errno; | ||||
#if HAVE_STRUCT_STAT_ST_FLAGS | |||||
if (to_sb.st_flags & NOCHANGEBITS) | if (to_sb.st_flags & NOCHANGEBITS) | ||||
(void)chflags(to_name, to_sb.st_flags); | (void)chflags(to_name, to_sb.st_flags); | ||||
#endif | |||||
unlink(tempfile); | unlink(tempfile); | ||||
errno = serrno; | errno = serrno; | ||||
err(EX_OSERR, "unlink: %s", backup); | err(EX_OSERR, "unlink: %s", backup); | ||||
} | } | ||||
if (link(to_name, backup) < 0) { | if (link(to_name, backup) < 0) { | ||||
serrno = errno; | serrno = errno; | ||||
unlink(tempfile); | unlink(tempfile); | ||||
#if HAVE_STRUCT_STAT_ST_FLAGS | |||||
if (to_sb.st_flags & NOCHANGEBITS) | if (to_sb.st_flags & NOCHANGEBITS) | ||||
(void)chflags(to_name, to_sb.st_flags); | (void)chflags(to_name, to_sb.st_flags); | ||||
#endif | |||||
errno = serrno; | errno = serrno; | ||||
err(EX_OSERR, "link: %s to %s", to_name, | err(EX_OSERR, "link: %s to %s", to_name, | ||||
backup); | backup); | ||||
} | } | ||||
} | } | ||||
if (verbose) | if (verbose) | ||||
(void)printf("install: %s -> %s\n", from_name, to_name); | (void)printf("install: %s -> %s\n", from_name, to_name); | ||||
if (rename(tempfile, to_name) < 0) { | if (rename(tempfile, to_name) < 0) { | ||||
Show All 28 Lines | #endif | ||||
/* | /* | ||||
* Set owner, group, mode for target; do the chown first, | * Set owner, group, mode for target; do the chown first, | ||||
* chown may lose the setuid bits. | * chown may lose the setuid bits. | ||||
*/ | */ | ||||
if (!dounpriv && ((gid != (gid_t)-1 && gid != to_sb.st_gid) || | if (!dounpriv && ((gid != (gid_t)-1 && gid != to_sb.st_gid) || | ||||
(uid != (uid_t)-1 && uid != to_sb.st_uid) || | (uid != (uid_t)-1 && uid != to_sb.st_uid) || | ||||
(mode != (to_sb.st_mode & ALLPERMS)))) { | (mode != (to_sb.st_mode & ALLPERMS)))) { | ||||
#if HAVE_STRUCT_STAT_ST_FLAGS | |||||
/* Try to turn off the immutable bits. */ | /* Try to turn off the immutable bits. */ | ||||
if (to_sb.st_flags & NOCHANGEBITS) | if (to_sb.st_flags & NOCHANGEBITS) | ||||
(void)fchflags(to_fd, to_sb.st_flags & ~NOCHANGEBITS); | (void)fchflags(to_fd, to_sb.st_flags & ~NOCHANGEBITS); | ||||
#endif | |||||
} | } | ||||
if (!dounpriv & | if (!dounpriv & | ||||
(gid != (gid_t)-1 && gid != to_sb.st_gid) || | (gid != (gid_t)-1 && gid != to_sb.st_gid) || | ||||
(uid != (uid_t)-1 && uid != to_sb.st_uid)) | (uid != (uid_t)-1 && uid != to_sb.st_uid)) | ||||
if (fchown(to_fd, uid, gid) == -1) { | if (fchown(to_fd, uid, gid) == -1) { | ||||
serrno = errno; | serrno = errno; | ||||
(void)unlink(to_name); | (void)unlink(to_name); | ||||
errno = serrno; | errno = serrno; | ||||
err(EX_OSERR,"%s: chown/chgrp", to_name); | err(EX_OSERR,"%s: chown/chgrp", to_name); | ||||
} | } | ||||
if (mode != (to_sb.st_mode & ALLPERMS)) { | if (mode != (to_sb.st_mode & ALLPERMS)) { | ||||
if (fchmod(to_fd, | if (fchmod(to_fd, | ||||
dounpriv ? mode & (S_IRWXU|S_IRWXG|S_IRWXO) : mode)) { | dounpriv ? mode & (S_IRWXU|S_IRWXG|S_IRWXO) : mode)) { | ||||
serrno = errno; | serrno = errno; | ||||
(void)unlink(to_name); | (void)unlink(to_name); | ||||
errno = serrno; | errno = serrno; | ||||
err(EX_OSERR, "%s: chmod", to_name); | err(EX_OSERR, "%s: chmod", to_name); | ||||
} | } | ||||
} | } | ||||
#if HAVE_STRUCT_STAT_ST_FLAGS | |||||
brooks: I'd preserve the blank line. | |||||
/* | /* | ||||
* If provided a set of flags, set them, otherwise, preserve the | * If provided a set of flags, set them, otherwise, preserve the | ||||
* flags, except for the dump flag. | * flags, except for the dump flag. | ||||
* NFS does not support flags. Ignore EOPNOTSUPP flags if we're just | * NFS does not support flags. Ignore EOPNOTSUPP flags if we're just | ||||
* trying to turn off UF_NODUMP. If we're trying to set real flags, | * trying to turn off UF_NODUMP. If we're trying to set real flags, | ||||
* then warn if the fs doesn't support it, otherwise fail. | * then warn if the fs doesn't support it, otherwise fail. | ||||
*/ | */ | ||||
if (!dounpriv & !devnull && (flags & SETFLAGS || | if (!dounpriv & !devnull && (flags & SETFLAGS || | ||||
(from_sb.st_flags & ~UF_NODUMP) != to_sb.st_flags) && | (from_sb.st_flags & ~UF_NODUMP) != to_sb.st_flags) && | ||||
fchflags(to_fd, | fchflags(to_fd, | ||||
flags & SETFLAGS ? fset : from_sb.st_flags & ~UF_NODUMP)) { | flags & SETFLAGS ? fset : from_sb.st_flags & ~UF_NODUMP)) { | ||||
if (flags & SETFLAGS) { | if (flags & SETFLAGS) { | ||||
if (errno == EOPNOTSUPP) | if (errno == EOPNOTSUPP) | ||||
warn("%s: chflags", to_name); | warn("%s: chflags", to_name); | ||||
else { | else { | ||||
serrno = errno; | serrno = errno; | ||||
(void)unlink(to_name); | (void)unlink(to_name); | ||||
errno = serrno; | errno = serrno; | ||||
err(EX_OSERR, "%s: chflags", to_name); | err(EX_OSERR, "%s: chflags", to_name); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
#endif | |||||
(void)close(to_fd); | (void)close(to_fd); | ||||
if (!devnull) | if (!devnull) | ||||
(void)close(from_fd); | (void)close(from_fd); | ||||
metadata_log(to_name, "file", tsb, NULL, digestresult, to_sb.st_size); | metadata_log(to_name, "file", tsb, NULL, digestresult, to_sb.st_size); | ||||
free(digestresult); | free(digestresult); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 110 Lines • ▼ Show 20 Lines | create_newfile(const char *path, int target, struct stat *sbp) | ||||
int newfd; | int newfd; | ||||
if (target) { | if (target) { | ||||
/* | /* | ||||
* Unlink now... avoid ETXTBSY errors later. Try to turn | * Unlink now... avoid ETXTBSY errors later. Try to turn | ||||
* off the append/immutable bits -- if we fail, go ahead, | * off the append/immutable bits -- if we fail, go ahead, | ||||
* it might work. | * it might work. | ||||
*/ | */ | ||||
#if HAVE_STRUCT_STAT_ST_FLAGS | |||||
if (sbp->st_flags & NOCHANGEBITS) | if (sbp->st_flags & NOCHANGEBITS) | ||||
(void)chflags(path, sbp->st_flags & ~NOCHANGEBITS); | (void)chflags(path, sbp->st_flags & ~NOCHANGEBITS); | ||||
#endif | |||||
if (dobackup) { | if (dobackup) { | ||||
if ((size_t)snprintf(backup, MAXPATHLEN, "%s%s", | if ((size_t)snprintf(backup, MAXPATHLEN, "%s%s", | ||||
path, suffix) != strlen(path) + strlen(suffix)) { | path, suffix) != strlen(path) + strlen(suffix)) { | ||||
saved_errno = errno; | saved_errno = errno; | ||||
#if HAVE_STRUCT_STAT_ST_FLAGS | |||||
if (sbp->st_flags & NOCHANGEBITS) | if (sbp->st_flags & NOCHANGEBITS) | ||||
(void)chflags(path, sbp->st_flags); | (void)chflags(path, sbp->st_flags); | ||||
#endif | |||||
errno = saved_errno; | errno = saved_errno; | ||||
errx(EX_OSERR, "%s: backup filename too long", | errx(EX_OSERR, "%s: backup filename too long", | ||||
path); | path); | ||||
} | } | ||||
(void)snprintf(backup, MAXPATHLEN, "%s%s", | (void)snprintf(backup, MAXPATHLEN, "%s%s", | ||||
path, suffix); | path, suffix); | ||||
if (verbose) | if (verbose) | ||||
(void)printf("install: %s -> %s\n", | (void)printf("install: %s -> %s\n", | ||||
path, backup); | path, backup); | ||||
if (rename(path, backup) < 0) { | if (rename(path, backup) < 0) { | ||||
saved_errno = errno; | saved_errno = errno; | ||||
#if HAVE_STRUCT_STAT_ST_FLAGS | |||||
if (sbp->st_flags & NOCHANGEBITS) | if (sbp->st_flags & NOCHANGEBITS) | ||||
(void)chflags(path, sbp->st_flags); | (void)chflags(path, sbp->st_flags); | ||||
#endif | |||||
errno = saved_errno; | errno = saved_errno; | ||||
err(EX_OSERR, "rename: %s to %s", path, backup); | err(EX_OSERR, "rename: %s to %s", path, backup); | ||||
} | } | ||||
} else | } else | ||||
if (unlink(path) < 0) | if (unlink(path) < 0) | ||||
saved_errno = errno; | saved_errno = errno; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 292 Lines • Show Last 20 Lines |
I'd preserve the blank line.