xref: /freebsd/contrib/bc/scripts/safe-install.sh (revision 44d4804d1945435745518cd09eb8ae6ab22ecef4)
1*44d4804dSStefan Eßer#!/bin/sh
2*44d4804dSStefan Eßer#
3*44d4804dSStefan Eßer# Written by Rich Felker, originally as part of musl libc.
4*44d4804dSStefan Eßer# Multi-licensed under MIT, 0BSD, and CC0.
5*44d4804dSStefan Eßer#
6*44d4804dSStefan Eßer# This is an actually-safe install command which installs the new
7*44d4804dSStefan Eßer# file atomically in the new location, rather than overwriting
8*44d4804dSStefan Eßer# existing files.
9*44d4804dSStefan Eßer#
10*44d4804dSStefan Eßer
11*44d4804dSStefan Eßerusage() {
12*44d4804dSStefan Eßerprintf "usage: %s [-D] [-l] [-m mode] src dest\n" "$0" 1>&2
13*44d4804dSStefan Eßerexit 1
14*44d4804dSStefan Eßer}
15*44d4804dSStefan Eßer
16*44d4804dSStefan Eßermkdirp=
17*44d4804dSStefan Eßersymlink=
18*44d4804dSStefan Eßermode=755
19*44d4804dSStefan Eßer
20*44d4804dSStefan Eßerwhile getopts Dlm: name ; do
21*44d4804dSStefan Eßercase "$name" in
22*44d4804dSStefan EßerD) mkdirp=yes ;;
23*44d4804dSStefan Eßerl) symlink=yes ;;
24*44d4804dSStefan Eßerm) mode=$OPTARG ;;
25*44d4804dSStefan Eßer?) usage ;;
26*44d4804dSStefan Eßeresac
27*44d4804dSStefan Eßerdone
28*44d4804dSStefan Eßershift $(($OPTIND - 1))
29*44d4804dSStefan Eßer
30*44d4804dSStefan Eßertest "$#" -eq 2 || usage
31*44d4804dSStefan Eßersrc=$1
32*44d4804dSStefan Eßerdst=$2
33*44d4804dSStefan Eßertmp="$dst.tmp.$$"
34*44d4804dSStefan Eßer
35*44d4804dSStefan Eßercase "$dst" in
36*44d4804dSStefan Eßer*/) printf "%s: %s ends in /\n", "$0" "$dst" 1>&2 ; exit 1 ;;
37*44d4804dSStefan Eßeresac
38*44d4804dSStefan Eßer
39*44d4804dSStefan Eßerset -C
40*44d4804dSStefan Eßerset -e
41*44d4804dSStefan Eßer
42*44d4804dSStefan Eßerif test "$mkdirp" ; then
43*44d4804dSStefan Eßerumask 022
44*44d4804dSStefan Eßercase "$2" in
45*44d4804dSStefan Eßer*/*) mkdir -p "${dst%/*}" ;;
46*44d4804dSStefan Eßeresac
47*44d4804dSStefan Eßerfi
48*44d4804dSStefan Eßer
49*44d4804dSStefan Eßertrap 'rm -f "$tmp"' EXIT INT QUIT TERM HUP
50*44d4804dSStefan Eßer
51*44d4804dSStefan Eßerumask 077
52*44d4804dSStefan Eßer
53*44d4804dSStefan Eßerif test "$symlink" ; then
54*44d4804dSStefan Eßerln -s "$1" "$tmp"
55*44d4804dSStefan Eßerelse
56*44d4804dSStefan Eßercat < "$1" > "$tmp"
57*44d4804dSStefan Eßerchmod "$mode" "$tmp"
58*44d4804dSStefan Eßerfi
59*44d4804dSStefan Eßer
60*44d4804dSStefan Eßermv -f "$tmp" "$2"
61*44d4804dSStefan Eßertest -d "$2" && {
62*44d4804dSStefan Eßerrm -f "$2/$tmp"
63*44d4804dSStefan Eßerprintf "%s: %s is a directory\n" "$0" "$dst" 1>&2
64*44d4804dSStefan Eßerexit 1
65*44d4804dSStefan Eßer}
66*44d4804dSStefan Eßer
67*44d4804dSStefan Eßerexit 0
68