xref: /freebsd/contrib/bc/scripts/safe-install.sh (revision fe75646a0234a261c0013bf1840fdac4acaf0cec)
1#!/bin/sh
2#
3# Written by Rich Felker, originally as part of musl libc.
4# Multi-licensed under MIT, 0BSD, and CC0.
5#
6# This is an actually-safe install command which installs the new
7# file atomically in the new location, rather than overwriting
8# existing files.
9#
10
11usage() {
12printf "usage: %s [-D] [-l] [-m mode] src dest\n" "$0" 1>&2
13exit 1
14}
15
16mkdirp=
17symlink=
18mode=755
19
20while getopts Dlm: name ; do
21case "$name" in
22D) mkdirp=yes ;;
23l) symlink=yes ;;
24m) mode=$OPTARG ;;
25?) usage ;;
26esac
27done
28shift $(($OPTIND - 1))
29
30test "$#" -eq 2 || usage
31src=$1
32dst=$2
33tmp="$dst.tmp.$$"
34
35case "$dst" in
36*/) printf "%s: %s ends in /\n", "$0" "$dst" 1>&2 ; exit 1 ;;
37esac
38
39set -C
40set -e
41
42if test "$mkdirp" ; then
43umask 022
44case "$dst" in
45*/*) mkdir -p "${dst%/*}" ;;
46esac
47fi
48
49trap 'rm -f "$tmp"' EXIT INT QUIT TERM HUP
50
51umask 077
52
53if test "$symlink" ; then
54ln -s "$src" "$tmp"
55else
56cat < "$src" > "$tmp"
57chmod "$mode" "$tmp"
58fi
59
60mv -f "$tmp" "$dst"
61test -d "$dst" && {
62rm -f "$dst/$tmp"
63printf "%s: %s is a directory\n" "$0" "$dst" 1>&2
64exit 1
65}
66
67exit 0
68