install-sh revision 1.3 1 1.1 mrg #!/bin/sh
2 1.1 mrg #
3 1.3 mrg # $NetBSD: install-sh,v 1.3 2019/03/20 07:17:34 mrg Exp $
4 1.3 mrg # This script now also installs multiple files, but might choke on installing
5 1.3 mrg # multiple files with spaces in the file names.
6 1.1 mrg #
7 1.3 mrg # install - install a program, script, or datafile
8 1.3 mrg # This comes from X11R5 (mit/util/scripts/install.sh).
9 1.1 mrg #
10 1.3 mrg # Copyright 1991 by the Massachusetts Institute of Technology
11 1.1 mrg #
12 1.3 mrg # Permission to use, copy, modify, distribute, and sell this software and its
13 1.3 mrg # documentation for any purpose is hereby granted without fee, provided that
14 1.3 mrg # the above copyright notice appear in all copies and that both that
15 1.3 mrg # copyright notice and this permission notice appear in supporting
16 1.3 mrg # documentation, and that the name of M.I.T. not be used in advertising or
17 1.3 mrg # publicity pertaining to distribution of the software without specific,
18 1.3 mrg # written prior permission. M.I.T. makes no representations about the
19 1.3 mrg # suitability of this software for any purpose. It is provided "as is"
20 1.3 mrg # without express or implied warranty.
21 1.1 mrg #
22 1.1 mrg # Calling this script install-sh is preferred over install.sh, to prevent
23 1.1 mrg # `make' implicit rules from creating a file called install from it
24 1.1 mrg # when there is no Makefile.
25 1.1 mrg #
26 1.1 mrg # This script is compatible with the BSD install script, but was written
27 1.1 mrg # from scratch.
28 1.1 mrg
29 1.1 mrg # set DOITPROG to echo to test this script
30 1.1 mrg
31 1.1 mrg # Don't use :- since 4.3BSD and earlier shells don't like it.
32 1.3 mrg doit="${DOITPROG-}"
33 1.1 mrg
34 1.1 mrg
35 1.3 mrg # put in absolute paths if you don't have them in your path; or use env. vars.
36 1.1 mrg
37 1.3 mrg awkprog="${AWKPROG-awk}"
38 1.3 mrg mvprog="${MVPROG-mv}"
39 1.3 mrg cpprog="${CPPROG-cp}"
40 1.3 mrg chmodprog="${CHMODPROG-chmod}"
41 1.3 mrg chownprog="${CHOWNPROG-chown}"
42 1.3 mrg chgrpprog="${CHGRPPROG-chgrp}"
43 1.3 mrg stripprog="${STRIPPROG-strip}"
44 1.3 mrg rmprog="${RMPROG-rm}"
45 1.3 mrg mkdirprog="${MKDIRPROG-mkdir}"
46 1.3 mrg
47 1.3 mrg instcmd="$cpprog"
48 1.3 mrg instflags=""
49 1.3 mrg pathcompchmodcmd="$chmodprog 755"
50 1.3 mrg chmodcmd="$chmodprog 755"
51 1.3 mrg chowncmd=""
52 1.3 mrg chgrpcmd=""
53 1.3 mrg stripcmd=""
54 1.3 mrg stripflags=""
55 1.1 mrg rmcmd="$rmprog -f"
56 1.3 mrg mvcmd="$mvprog"
57 1.3 mrg src=""
58 1.3 mrg msrc=""
59 1.3 mrg dst=""
60 1.3 mrg dir_arg=""
61 1.3 mrg suffix=""
62 1.3 mrg suffixfmt=""
63 1.3 mrg
64 1.3 mrg while [ x"$1" != x ]; do
65 1.3 mrg case $1 in
66 1.3 mrg -b) suffix=".old"
67 1.3 mrg shift
68 1.3 mrg continue;;
69 1.3 mrg
70 1.3 mrg -B) suffixfmt="$2"
71 1.3 mrg shift
72 1.3 mrg shift
73 1.3 mrg continue;;
74 1.3 mrg
75 1.3 mrg -c) instcmd="$cpprog"
76 1.3 mrg shift
77 1.3 mrg continue;;
78 1.3 mrg
79 1.3 mrg -d) dir_arg=true
80 1.3 mrg shift
81 1.3 mrg continue;;
82 1.3 mrg
83 1.3 mrg -m) chmodcmd="$chmodprog $2"
84 1.3 mrg shift
85 1.3 mrg shift
86 1.3 mrg continue;;
87 1.3 mrg
88 1.3 mrg -m*)
89 1.3 mrg chmodcmd="$chmodprog ${1#-m}"
90 1.3 mrg shift
91 1.3 mrg continue;;
92 1.3 mrg
93 1.3 mrg -o) chowncmd="$chownprog $2"
94 1.3 mrg shift
95 1.3 mrg shift
96 1.3 mrg continue;;
97 1.3 mrg
98 1.3 mrg -g) chgrpcmd="$chgrpprog $2"
99 1.3 mrg shift
100 1.3 mrg shift
101 1.3 mrg continue;;
102 1.3 mrg
103 1.3 mrg -s) stripcmd="$stripprog"
104 1.3 mrg shift
105 1.3 mrg continue;;
106 1.3 mrg
107 1.3 mrg -S) stripcmd="$stripprog"
108 1.3 mrg stripflags="-S $2 $stripflags"
109 1.3 mrg shift
110 1.3 mrg shift
111 1.3 mrg continue;;
112 1.3 mrg
113 1.3 mrg -p) instflags="-p"
114 1.3 mrg shift
115 1.3 mrg continue;;
116 1.1 mrg
117 1.3 mrg *) if [ x"$msrc" = x ]
118 1.3 mrg then
119 1.3 mrg msrc="$dst"
120 1.3 mrg else
121 1.3 mrg msrc="$msrc $dst"
122 1.3 mrg fi
123 1.3 mrg src="$dst"
124 1.3 mrg dst="$1"
125 1.3 mrg shift
126 1.3 mrg continue;;
127 1.3 mrg esac
128 1.3 mrg done
129 1.1 mrg
130 1.3 mrg if [ x"$dir_arg" = x ]
131 1.3 mrg then
132 1.3 mrg dstisfile=""
133 1.3 mrg if [ ! -d "$dst" ]
134 1.3 mrg then
135 1.3 mrg if [ x"$msrc" = x"$src" ]
136 1.3 mrg then
137 1.3 mrg dstisfile=true
138 1.3 mrg else
139 1.3 mrg echo "install: destination is not a directory"
140 1.3 mrg exit 1
141 1.3 mrg fi
142 1.3 mrg fi
143 1.3 mrg else
144 1.3 mrg msrc="$msrc $dst"
145 1.3 mrg fi
146 1.1 mrg
147 1.3 mrg if [ x"$msrc" = x ]
148 1.3 mrg then
149 1.3 mrg echo "install: no destination specified"
150 1.3 mrg exit 1
151 1.3 mrg fi
152 1.1 mrg
153 1.3 mrg for srcarg in $msrc; do
154 1.1 mrg
155 1.3 mrg if [ x"$dir_arg" != x ]; then
156 1.1 mrg
157 1.3 mrg dstarg="$srcarg"
158 1.3 mrg else
159 1.3 mrg dstarg="$dst"
160 1.1 mrg
161 1.3 mrg # Waiting for this to be detected by the "$instcmd $srcarg $dsttmp" command
162 1.3 mrg # might cause directories to be created, which would be especially bad
163 1.3 mrg # if $src (and thus $dsttmp) contains '*'.
164 1.3 mrg
165 1.3 mrg if [ -f "$srcarg" ]
166 1.3 mrg then
167 1.3 mrg doinst="$instcmd $instflags"
168 1.3 mrg elif [ -d "$srcarg" ]
169 1.3 mrg then
170 1.3 mrg echo "install: $srcarg: not a regular file"
171 1.3 mrg exit 1
172 1.3 mrg elif [ "$srcarg" = "/dev/null" ]
173 1.3 mrg then
174 1.3 mrg doinst="$cpprog"
175 1.3 mrg else
176 1.3 mrg echo "install: $srcarg does not exist"
177 1.3 mrg exit 1
178 1.3 mrg fi
179 1.3 mrg
180 1.3 mrg # If destination is a directory, append the input filename; if your system
181 1.3 mrg # does not like double slashes in filenames, you may need to add some logic
182 1.3 mrg
183 1.3 mrg if [ -d "$dstarg" ]
184 1.3 mrg then
185 1.3 mrg dstarg="$dstarg"/`basename "$srcarg"`
186 1.3 mrg fi
187 1.3 mrg fi
188 1.1 mrg
189 1.3 mrg ## this sed command emulates the dirname command
190 1.3 mrg dstdir=`echo "$dstarg" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
191 1.1 mrg
192 1.3 mrg # Make sure that the destination directory exists.
193 1.3 mrg # this part is taken from Noah Friedman's mkinstalldirs script
194 1.1 mrg
195 1.3 mrg # Skip lots of stat calls in the usual case.
196 1.3 mrg if [ ! -d "$dstdir" ]; then
197 1.3 mrg defaultIFS='
198 1.3 mrg '
199 1.3 mrg IFS="${IFS-${defaultIFS}}"
200 1.1 mrg
201 1.3 mrg oIFS="${IFS}"
202 1.3 mrg # Some sh's can't handle IFS=/ for some reason.
203 1.3 mrg IFS='%'
204 1.3 mrg set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
205 1.3 mrg IFS="${oIFS}"
206 1.3 mrg
207 1.3 mrg pathcomp=''
208 1.3 mrg
209 1.3 mrg while [ $# -ne 0 ] ; do
210 1.3 mrg pathcomp="${pathcomp}${1}"
211 1.3 mrg shift
212 1.3 mrg
213 1.3 mrg if [ ! -d "${pathcomp}" ] ;
214 1.3 mrg then
215 1.3 mrg $doit $mkdirprog "${pathcomp}"
216 1.3 mrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "${pathcomp}"; else true ; fi &&
217 1.3 mrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "${pathcomp}"; else true ; fi &&
218 1.3 mrg if [ x"$pathcompchmodcmd" != x ]; then $doit $pathcompchmodcmd "${pathcomp}"; else true ; fi
219 1.1 mrg
220 1.3 mrg else
221 1.3 mrg true
222 1.3 mrg fi
223 1.1 mrg
224 1.3 mrg pathcomp="${pathcomp}/"
225 1.1 mrg done
226 1.1 mrg fi
227 1.1 mrg
228 1.3 mrg if [ x"$dir_arg" != x ]
229 1.3 mrg then
230 1.3 mrg if [ -d "$dstarg" ]; then
231 1.3 mrg true
232 1.3 mrg else
233 1.3 mrg $doit $mkdirprog "$dstarg" &&
234 1.3 mrg
235 1.3 mrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dstarg"; else true ; fi &&
236 1.3 mrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dstarg"; else true ; fi &&
237 1.3 mrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dstarg"; else true ; fi
238 1.3 mrg fi
239 1.1 mrg else
240 1.1 mrg
241 1.3 mrg if [ x"$dstisfile" = x ]
242 1.3 mrg then
243 1.3 mrg file=$srcarg
244 1.3 mrg else
245 1.3 mrg file=$dst
246 1.3 mrg fi
247 1.3 mrg
248 1.3 mrg dstfile=`basename "$file"`
249 1.3 mrg dstfinal="$dstdir/$dstfile"
250 1.3 mrg
251 1.3 mrg # Make a temp file name in the proper directory.
252 1.3 mrg
253 1.3 mrg dsttmp=$dstdir/#inst.$$#
254 1.3 mrg
255 1.3 mrg # Make a backup file name in the proper directory.
256 1.3 mrg case x$suffixfmt in
257 1.3 mrg *%*) suffix=`echo x |
258 1.3 mrg $awkprog -v bname="$dstfinal" -v fmt="$suffixfmt" '
259 1.3 mrg { cnt = 0;
260 1.3 mrg do {
261 1.3 mrg sfx = sprintf(fmt, cnt++);
262 1.3 mrg name = bname sfx;
263 1.3 mrg } while (system("test -f " name) == 0);
264 1.3 mrg print sfx; }' -`;;
265 1.3 mrg x) ;;
266 1.3 mrg *) suffix="$suffixfmt";;
267 1.3 mrg esac
268 1.3 mrg dstbackup="$dstfinal$suffix"
269 1.3 mrg
270 1.3 mrg # Move or copy the file name to the temp name
271 1.3 mrg
272 1.3 mrg $doit $doinst $srcarg "$dsttmp" &&
273 1.3 mrg
274 1.3 mrg trap "rm -f ${dsttmp}" 0 &&
275 1.3 mrg
276 1.3 mrg # and set any options; do chmod last to preserve setuid bits
277 1.3 mrg
278 1.3 mrg # If any of these fail, we abort the whole thing. If we want to
279 1.3 mrg # ignore errors from any of these, just make sure not to ignore
280 1.3 mrg # errors from the above "$doit $instcmd $src $dsttmp" command.
281 1.3 mrg
282 1.3 mrg if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else true;fi &&
283 1.3 mrg if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else true;fi &&
284 1.3 mrg if [ x"$stripcmd" != x ]; then $doit $stripcmd $stripflags "$dsttmp"; else true;fi &&
285 1.3 mrg if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else true;fi &&
286 1.3 mrg
287 1.3 mrg # Now rename the file to the real destination.
288 1.3 mrg
289 1.3 mrg if [ x"$suffix" != x ] && [ -f "$dstfinal" ]
290 1.3 mrg then
291 1.3 mrg $doit $mvcmd "$dstfinal" "$dstbackup"
292 1.3 mrg else
293 1.3 mrg $doit $rmcmd -f "$dstfinal"
294 1.3 mrg fi &&
295 1.3 mrg $doit $mvcmd "$dsttmp" "$dstfinal"
296 1.1 mrg fi
297 1.1 mrg
298 1.3 mrg done &&
299 1.1 mrg
300 1.1 mrg
301 1.3 mrg exit 0
302