xref: /freebsd/contrib/bc/scripts/safe-install.sh (revision 103d7cdfb7435591049413e1bc39482cb316efb7)
144d4804dSStefan Eßer#!/bin/sh
244d4804dSStefan Eßer#
344d4804dSStefan Eßer# Written by Rich Felker, originally as part of musl libc.
444d4804dSStefan Eßer# Multi-licensed under MIT, 0BSD, and CC0.
544d4804dSStefan Eßer#
644d4804dSStefan Eßer# This is an actually-safe install command which installs the new
744d4804dSStefan Eßer# file atomically in the new location, rather than overwriting
844d4804dSStefan Eßer# existing files.
944d4804dSStefan Eßer#
1044d4804dSStefan Eßer
1144d4804dSStefan Eßerusage() {
1244d4804dSStefan Eßerprintf "usage: %s [-D] [-l] [-m mode] src dest\n" "$0" 1>&2
1344d4804dSStefan Eßerexit 1
1444d4804dSStefan Eßer}
1544d4804dSStefan Eßer
1644d4804dSStefan Eßermkdirp=
1744d4804dSStefan Eßersymlink=
1844d4804dSStefan Eßermode=755
1944d4804dSStefan Eßer
2044d4804dSStefan Eßerwhile getopts Dlm: name ; do
2144d4804dSStefan Eßercase "$name" in
2244d4804dSStefan EßerD) mkdirp=yes ;;
2344d4804dSStefan Eßerl) symlink=yes ;;
2444d4804dSStefan Eßerm) mode=$OPTARG ;;
2544d4804dSStefan Eßer?) usage ;;
2644d4804dSStefan Eßeresac
2744d4804dSStefan Eßerdone
2844d4804dSStefan Eßershift $(($OPTIND - 1))
2944d4804dSStefan Eßer
3044d4804dSStefan Eßertest "$#" -eq 2 || usage
3144d4804dSStefan Eßersrc=$1
3244d4804dSStefan Eßerdst=$2
3344d4804dSStefan Eßertmp="$dst.tmp.$$"
3444d4804dSStefan Eßer
3544d4804dSStefan Eßercase "$dst" in
3644d4804dSStefan Eßer*/) printf "%s: %s ends in /\n", "$0" "$dst" 1>&2 ; exit 1 ;;
3744d4804dSStefan Eßeresac
3844d4804dSStefan Eßer
3944d4804dSStefan Eßerset -C
4044d4804dSStefan Eßerset -e
4144d4804dSStefan Eßer
4244d4804dSStefan Eßerif test "$mkdirp" ; then
4344d4804dSStefan Eßerumask 022
44*103d7cdfSStefan Eßercase "$dst" in
4544d4804dSStefan Eßer*/*) mkdir -p "${dst%/*}" ;;
4644d4804dSStefan Eßeresac
4744d4804dSStefan Eßerfi
4844d4804dSStefan Eßer
4944d4804dSStefan Eßertrap 'rm -f "$tmp"' EXIT INT QUIT TERM HUP
5044d4804dSStefan Eßer
5144d4804dSStefan Eßerumask 077
5244d4804dSStefan Eßer
5344d4804dSStefan Eßerif test "$symlink" ; then
54*103d7cdfSStefan Eßerln -s "$src" "$tmp"
5544d4804dSStefan Eßerelse
56*103d7cdfSStefan Eßercat < "$src" > "$tmp"
5744d4804dSStefan Eßerchmod "$mode" "$tmp"
5844d4804dSStefan Eßerfi
5944d4804dSStefan Eßer
60*103d7cdfSStefan Eßermv -f "$tmp" "$dst"
61*103d7cdfSStefan Eßertest -d "$dst" && {
62*103d7cdfSStefan Eßerrm -f "$dst/$tmp"
6344d4804dSStefan Eßerprintf "%s: %s is a directory\n" "$0" "$dst" 1>&2
6444d4804dSStefan Eßerexit 1
6544d4804dSStefan Eßer}
6644d4804dSStefan Eßer
6744d4804dSStefan Eßerexit 0
68