xref: /aosp_15_r20/external/bc/scripts/safe-install.sh (revision 5a6e848804d15c18a0125914844ee4eb0bda4fcf)
1*5a6e8488SAndroid Build Coastguard Worker#!/bin/sh
2*5a6e8488SAndroid Build Coastguard Worker#
3*5a6e8488SAndroid Build Coastguard Worker# Written by Rich Felker, originally as part of musl libc.
4*5a6e8488SAndroid Build Coastguard Worker# Multi-licensed under MIT, 0BSD, and CC0.
5*5a6e8488SAndroid Build Coastguard Worker#
6*5a6e8488SAndroid Build Coastguard Worker# This is an actually-safe install command which installs the new
7*5a6e8488SAndroid Build Coastguard Worker# file atomically in the new location, rather than overwriting
8*5a6e8488SAndroid Build Coastguard Worker# existing files.
9*5a6e8488SAndroid Build Coastguard Worker#
10*5a6e8488SAndroid Build Coastguard Worker
11*5a6e8488SAndroid Build Coastguard Workerusage() {
12*5a6e8488SAndroid Build Coastguard Workerprintf "usage: %s [-D] [-l] [-m mode] src dest\n" "$0" 1>&2
13*5a6e8488SAndroid Build Coastguard Workerexit 1
14*5a6e8488SAndroid Build Coastguard Worker}
15*5a6e8488SAndroid Build Coastguard Worker
16*5a6e8488SAndroid Build Coastguard Workermkdirp=
17*5a6e8488SAndroid Build Coastguard Workersymlink=
18*5a6e8488SAndroid Build Coastguard Workermode=755
19*5a6e8488SAndroid Build Coastguard Worker
20*5a6e8488SAndroid Build Coastguard Workerwhile getopts Dlm: name ; do
21*5a6e8488SAndroid Build Coastguard Workercase "$name" in
22*5a6e8488SAndroid Build Coastguard WorkerD) mkdirp=yes ;;
23*5a6e8488SAndroid Build Coastguard Workerl) symlink=yes ;;
24*5a6e8488SAndroid Build Coastguard Workerm) mode=$OPTARG ;;
25*5a6e8488SAndroid Build Coastguard Worker?) usage ;;
26*5a6e8488SAndroid Build Coastguard Workeresac
27*5a6e8488SAndroid Build Coastguard Workerdone
28*5a6e8488SAndroid Build Coastguard Workershift $(($OPTIND - 1))
29*5a6e8488SAndroid Build Coastguard Worker
30*5a6e8488SAndroid Build Coastguard Workertest "$#" -eq 2 || usage
31*5a6e8488SAndroid Build Coastguard Workersrc=$1
32*5a6e8488SAndroid Build Coastguard Workerdst=$2
33*5a6e8488SAndroid Build Coastguard Workertmp="$dst.tmp.$$"
34*5a6e8488SAndroid Build Coastguard Worker
35*5a6e8488SAndroid Build Coastguard Workercase "$dst" in
36*5a6e8488SAndroid Build Coastguard Worker*/) printf "%s: %s ends in /\n", "$0" "$dst" 1>&2 ; exit 1 ;;
37*5a6e8488SAndroid Build Coastguard Workeresac
38*5a6e8488SAndroid Build Coastguard Worker
39*5a6e8488SAndroid Build Coastguard Workerset -C
40*5a6e8488SAndroid Build Coastguard Workerset -e
41*5a6e8488SAndroid Build Coastguard Worker
42*5a6e8488SAndroid Build Coastguard Workerif test "$mkdirp" ; then
43*5a6e8488SAndroid Build Coastguard Workerumask 022
44*5a6e8488SAndroid Build Coastguard Workercase "$dst" in
45*5a6e8488SAndroid Build Coastguard Worker*/*) mkdir -p "${dst%/*}" ;;
46*5a6e8488SAndroid Build Coastguard Workeresac
47*5a6e8488SAndroid Build Coastguard Workerfi
48*5a6e8488SAndroid Build Coastguard Worker
49*5a6e8488SAndroid Build Coastguard Workertrap 'rm -f "$tmp"' EXIT INT QUIT TERM HUP
50*5a6e8488SAndroid Build Coastguard Worker
51*5a6e8488SAndroid Build Coastguard Workerumask 077
52*5a6e8488SAndroid Build Coastguard Worker
53*5a6e8488SAndroid Build Coastguard Workerif test "$symlink" ; then
54*5a6e8488SAndroid Build Coastguard Workerln -s "$src" "$tmp"
55*5a6e8488SAndroid Build Coastguard Workerelse
56*5a6e8488SAndroid Build Coastguard Workercat < "$src" > "$tmp"
57*5a6e8488SAndroid Build Coastguard Workerchmod "$mode" "$tmp"
58*5a6e8488SAndroid Build Coastguard Workerfi
59*5a6e8488SAndroid Build Coastguard Worker
60*5a6e8488SAndroid Build Coastguard Workermv -f "$tmp" "$dst"
61*5a6e8488SAndroid Build Coastguard Workertest -d "$dst" && {
62*5a6e8488SAndroid Build Coastguard Workerrm -f "$dst/$tmp"
63*5a6e8488SAndroid Build Coastguard Workerprintf "%s: %s is a directory\n" "$0" "$dst" 1>&2
64*5a6e8488SAndroid Build Coastguard Workerexit 1
65*5a6e8488SAndroid Build Coastguard Worker}
66*5a6e8488SAndroid Build Coastguard Worker
67*5a6e8488SAndroid Build Coastguard Workerexit 0
68