xref: /minix3/external/bsd/file/dist/install-sh (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1ef01931fSBen Gras#!/bin/sh
2835f6802SDirk Vogt#
3*0a6a1f1dSLionel Sambuc# $NetBSD: install-sh,v 1.10 2014/10/20 22:04:31 christos Exp $
4835f6802SDirk Vogt# This script now also installs multiple files, but might choke on installing
5835f6802SDirk Vogt# multiple files with spaces in the file names.
6835f6802SDirk Vogt#
7ef01931fSBen Gras# install - install a program, script, or datafile
8835f6802SDirk Vogt# This comes from X11R5 (mit/util/scripts/install.sh).
9ef01931fSBen Gras#
10835f6802SDirk Vogt# Copyright 1991 by the Massachusetts Institute of Technology
11ef01931fSBen Gras#
12835f6802SDirk Vogt# Permission to use, copy, modify, distribute, and sell this software and its
13835f6802SDirk Vogt# documentation for any purpose is hereby granted without fee, provided that
14835f6802SDirk Vogt# the above copyright notice appear in all copies and that both that
15835f6802SDirk Vogt# copyright notice and this permission notice appear in supporting
16835f6802SDirk Vogt# documentation, and that the name of M.I.T. not be used in advertising or
17835f6802SDirk Vogt# publicity pertaining to distribution of the software without specific,
18835f6802SDirk Vogt# written prior permission.  M.I.T. makes no representations about the
19835f6802SDirk Vogt# suitability of this software for any purpose.  It is provided "as is"
20835f6802SDirk Vogt# without express or implied warranty.
21ef01931fSBen Gras#
22ef01931fSBen Gras# Calling this script install-sh is preferred over install.sh, to prevent
23ef01931fSBen Gras# `make' implicit rules from creating a file called install from it
24ef01931fSBen Gras# when there is no Makefile.
25ef01931fSBen Gras#
26ef01931fSBen Gras# This script is compatible with the BSD install script, but was written
27ef01931fSBen Gras# from scratch.
28ef01931fSBen Gras
29ef01931fSBen Gras# set DOITPROG to echo to test this script
30ef01931fSBen Gras
31ef01931fSBen Gras# Don't use :- since 4.3BSD and earlier shells don't like it.
32ef01931fSBen Grasdoit="${DOITPROG-}"
33ef01931fSBen Gras
34ef01931fSBen Gras
35835f6802SDirk Vogt# put in absolute paths if you don't have them in your path; or use env. vars.
36835f6802SDirk Vogt
37835f6802SDirk Vogtawkprog="${AWKPROG-awk}"
38ef01931fSBen Grasmvprog="${MVPROG-mv}"
39ef01931fSBen Grascpprog="${CPPROG-cp}"
40ef01931fSBen Graschmodprog="${CHMODPROG-chmod}"
41ef01931fSBen Graschownprog="${CHOWNPROG-chown}"
42ef01931fSBen Graschgrpprog="${CHGRPPROG-chgrp}"
43ef01931fSBen Grasstripprog="${STRIPPROG-strip}"
44ef01931fSBen Grasrmprog="${RMPROG-rm}"
45ef01931fSBen Grasmkdirprog="${MKDIRPROG-mkdir}"
46ef01931fSBen Gras
4784d9c625SLionel Sambucinstcmd="$cpprog"
4884d9c625SLionel Sambucinstflags=""
49835f6802SDirk Vogtpathcompchmodcmd="$chmodprog 755"
50835f6802SDirk Vogtchmodcmd="$chmodprog 755"
51835f6802SDirk Vogtchowncmd=""
52835f6802SDirk Vogtchgrpcmd=""
53835f6802SDirk Vogtstripcmd=""
54835f6802SDirk Vogtstripflags=""
55ef01931fSBen Grasrmcmd="$rmprog -f"
56ef01931fSBen Grasmvcmd="$mvprog"
57835f6802SDirk Vogtsrc=""
58835f6802SDirk Vogtmsrc=""
59835f6802SDirk Vogtdst=""
60835f6802SDirk Vogtdir_arg=""
61835f6802SDirk Vogtsuffix=""
62835f6802SDirk Vogtsuffixfmt=""
63ef01931fSBen Gras
64835f6802SDirk Vogtwhile [ x"$1" != x ]; do
65ef01931fSBen Gras    case $1 in
66835f6802SDirk Vogt	-b) suffix=".old"
67835f6802SDirk Vogt	    shift
68835f6802SDirk Vogt	    continue;;
69835f6802SDirk Vogt
70835f6802SDirk Vogt	-B) suffixfmt="$2"
71835f6802SDirk Vogt	    shift
72835f6802SDirk Vogt	    shift
73835f6802SDirk Vogt	    continue;;
74835f6802SDirk Vogt
75835f6802SDirk Vogt	-c) instcmd="$cpprog"
76835f6802SDirk Vogt	    shift
77ef01931fSBen Gras	    continue;;
78ef01931fSBen Gras
79ef01931fSBen Gras	-d) dir_arg=true
80ef01931fSBen Gras	    shift
81ef01931fSBen Gras	    continue;;
82ef01931fSBen Gras
83835f6802SDirk Vogt	-m) chmodcmd="$chmodprog $2"
84835f6802SDirk Vogt	    shift
85835f6802SDirk Vogt	    shift
86835f6802SDirk Vogt	    continue;;
87835f6802SDirk Vogt
8884d9c625SLionel Sambuc	-m*)
8984d9c625SLionel Sambuc	    chmodcmd="$chmodprog ${1#-m}"
9084d9c625SLionel Sambuc	    shift
9184d9c625SLionel Sambuc	    continue;;
9284d9c625SLionel Sambuc
93835f6802SDirk Vogt	-o) chowncmd="$chownprog $2"
94835f6802SDirk Vogt	    shift
95835f6802SDirk Vogt	    shift
96835f6802SDirk Vogt	    continue;;
97835f6802SDirk Vogt
98ef01931fSBen Gras	-g) chgrpcmd="$chgrpprog $2"
99ef01931fSBen Gras	    shift
100ef01931fSBen Gras	    shift
101ef01931fSBen Gras	    continue;;
102ef01931fSBen Gras
103835f6802SDirk Vogt	-s) stripcmd="$stripprog"
104ef01931fSBen Gras	    shift
105ef01931fSBen Gras	    continue;;
106ef01931fSBen Gras
107835f6802SDirk Vogt	-S) stripcmd="$stripprog"
108835f6802SDirk Vogt	    stripflags="-S $2 $stripflags"
109ef01931fSBen Gras	    shift
110ef01931fSBen Gras	    shift
111ef01931fSBen Gras	    continue;;
112ef01931fSBen Gras
11384d9c625SLionel Sambuc	-p) instflags="-p"
11484d9c625SLionel Sambuc	    shift
11584d9c625SLionel Sambuc	    continue;;
11684d9c625SLionel Sambuc
117835f6802SDirk Vogt	*)  if [ x"$msrc" = x ]
118835f6802SDirk Vogt	    then
119835f6802SDirk Vogt		msrc="$dst"
120835f6802SDirk Vogt	    else
121835f6802SDirk Vogt		msrc="$msrc $dst"
122835f6802SDirk Vogt	    fi
123835f6802SDirk Vogt	    src="$dst"
124835f6802SDirk Vogt	    dst="$1"
125ef01931fSBen Gras	    shift
126ef01931fSBen Gras	    continue;;
127ef01931fSBen Gras    esac
128ef01931fSBen Grasdone
129ef01931fSBen Gras
130835f6802SDirk Vogtif [ x"$dir_arg" = x ]
131835f6802SDirk Vogtthen
132835f6802SDirk Vogt	dstisfile=""
133835f6802SDirk Vogt	if [ ! -d "$dst" ]
134835f6802SDirk Vogt	then
135835f6802SDirk Vogt		if [ x"$msrc" = x"$src" ]
136835f6802SDirk Vogt		then
137835f6802SDirk Vogt			dstisfile=true
138835f6802SDirk Vogt		else
139835f6802SDirk Vogt			echo "install: destination is not a directory"
140ef01931fSBen Gras			exit 1
141ef01931fSBen Gras		fi
142ef01931fSBen Gras	fi
143ef01931fSBen Graselse
144835f6802SDirk Vogt	msrc="$msrc $dst"
145ef01931fSBen Grasfi
146835f6802SDirk Vogt
147835f6802SDirk Vogtif [ x"$msrc" = x ]
148835f6802SDirk Vogtthen
149835f6802SDirk Vogt	echo "install: no destination specified"
150835f6802SDirk Vogt	exit 1
151835f6802SDirk Vogtfi
152835f6802SDirk Vogt
153835f6802SDirk Vogtfor srcarg in $msrc; do
154835f6802SDirk Vogt
155835f6802SDirk Vogtif [ x"$dir_arg" != x ]; then
156835f6802SDirk Vogt
157835f6802SDirk Vogt	dstarg="$srcarg"
158ef01931fSBen Graselse
159835f6802SDirk Vogt	dstarg="$dst"
160ef01931fSBen Gras
161835f6802SDirk Vogt# Waiting for this to be detected by the "$instcmd $srcarg $dsttmp" command
162ef01931fSBen Gras# might cause directories to be created, which would be especially bad
163ef01931fSBen Gras# if $src (and thus $dsttmp) contains '*'.
164ef01931fSBen Gras
165835f6802SDirk Vogt	if [ -f "$srcarg" ]
166ef01931fSBen Gras	then
16784d9c625SLionel Sambuc		doinst="$instcmd $instflags"
168835f6802SDirk Vogt	elif [ -d "$srcarg" ]
169835f6802SDirk Vogt	then
170835f6802SDirk Vogt		echo "install: $srcarg: not a regular file"
171835f6802SDirk Vogt		exit 1
172835f6802SDirk Vogt	elif [ "$srcarg" = "/dev/null" ]
173835f6802SDirk Vogt	then
174835f6802SDirk Vogt		doinst="$cpprog"
175835f6802SDirk Vogt	else
176835f6802SDirk Vogt		echo "install:  $srcarg does not exist"
177835f6802SDirk Vogt		exit 1
178ef01931fSBen Gras	fi
179835f6802SDirk Vogt
180835f6802SDirk Vogt# If destination is a directory, append the input filename; if your system
181835f6802SDirk Vogt# does not like double slashes in filenames, you may need to add some logic
182835f6802SDirk Vogt
183835f6802SDirk Vogt	if [ -d "$dstarg" ]
184835f6802SDirk Vogt	then
185835f6802SDirk Vogt		dstarg="$dstarg"/`basename "$srcarg"`
186ef01931fSBen Gras	fi
187835f6802SDirk Vogtfi
188ef01931fSBen Gras
189835f6802SDirk Vogt## this sed command emulates the dirname command
190835f6802SDirk Vogtdstdir=`echo "$dstarg" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
191ef01931fSBen Gras
192835f6802SDirk Vogt# Make sure that the destination directory exists.
193835f6802SDirk Vogt#  this part is taken from Noah Friedman's mkinstalldirs script
194ef01931fSBen Gras
195835f6802SDirk Vogt# Skip lots of stat calls in the usual case.
196835f6802SDirk Vogtif [ ! -d "$dstdir" ]; then
197835f6802SDirk VogtdefaultIFS='
198835f6802SDirk Vogt'
199835f6802SDirk VogtIFS="${IFS-${defaultIFS}}"
200ef01931fSBen Gras
201835f6802SDirk VogtoIFS="${IFS}"
202835f6802SDirk Vogt# Some sh's can't handle IFS=/ for some reason.
203835f6802SDirk VogtIFS='%'
204835f6802SDirk Vogtset - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
205835f6802SDirk VogtIFS="${oIFS}"
206ef01931fSBen Gras
207835f6802SDirk Vogtpathcomp=''
208835f6802SDirk Vogt
209835f6802SDirk Vogtwhile [ $# -ne 0 ] ; do
210835f6802SDirk Vogt	pathcomp="${pathcomp}${1}"
211ef01931fSBen Gras	shift
212ef01931fSBen Gras
213835f6802SDirk Vogt	if [ ! -d "${pathcomp}" ] ;
214835f6802SDirk Vogt        then
215835f6802SDirk Vogt		$doit $mkdirprog "${pathcomp}"
216835f6802SDirk Vogt        	if [ x"$chowncmd" != x ]; then $doit $chowncmd "${pathcomp}"; else true ; fi &&
217835f6802SDirk Vogt        	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "${pathcomp}"; else true ; fi &&
218835f6802SDirk Vogt        	if [ x"$pathcompchmodcmd" != x ]; then $doit $pathcompchmodcmd "${pathcomp}"; else true ; fi
219ef01931fSBen Gras
220ef01931fSBen Gras	else
221835f6802SDirk Vogt		true
222ef01931fSBen Gras	fi
223835f6802SDirk Vogt
224835f6802SDirk Vogt	pathcomp="${pathcomp}/"
225ef01931fSBen Grasdone
226ef01931fSBen Grasfi
227ef01931fSBen Gras
228835f6802SDirk Vogt	if [ x"$dir_arg" != x ]
229835f6802SDirk Vogt	then
230835f6802SDirk Vogt		if [ -d "$dstarg" ]; then
231835f6802SDirk Vogt			true
232835f6802SDirk Vogt		else
233835f6802SDirk Vogt			$doit $mkdirprog "$dstarg" &&
234835f6802SDirk Vogt
235835f6802SDirk Vogt			if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dstarg"; else true ; fi &&
236835f6802SDirk Vogt			if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dstarg"; else true ; fi &&
237835f6802SDirk Vogt			if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dstarg"; else true ; fi
238835f6802SDirk Vogt		fi
239ef01931fSBen Gras	else
240ef01931fSBen Gras
241835f6802SDirk Vogt		if [ x"$dstisfile" = x ]
242835f6802SDirk Vogt		then
243835f6802SDirk Vogt			file=$srcarg
244835f6802SDirk Vogt		else
245835f6802SDirk Vogt			file=$dst
246835f6802SDirk Vogt		fi
247ef01931fSBen Gras
248835f6802SDirk Vogt		dstfile=`basename "$file"`
249835f6802SDirk Vogt		dstfinal="$dstdir/$dstfile"
250ef01931fSBen Gras
251835f6802SDirk Vogt# Make a temp file name in the proper directory.
252ef01931fSBen Gras
253835f6802SDirk Vogt		dsttmp=$dstdir/#inst.$$#
254835f6802SDirk Vogt
255835f6802SDirk Vogt# Make a backup file name in the proper directory.
256835f6802SDirk Vogt		case x$suffixfmt in
257835f6802SDirk Vogt		*%*)	suffix=`echo x |
258835f6802SDirk Vogt			$awkprog -v bname="$dstfinal" -v fmt="$suffixfmt" '
259835f6802SDirk Vogt			{ cnt = 0;
260835f6802SDirk Vogt			  do {
261835f6802SDirk Vogt				sfx = sprintf(fmt, cnt++);
262835f6802SDirk Vogt				name = bname sfx;
263835f6802SDirk Vogt			  } while (system("test -f " name) == 0);
264835f6802SDirk Vogt			  print sfx; }' -`;;
265835f6802SDirk Vogt		x)	;;
266835f6802SDirk Vogt		*)	suffix="$suffixfmt";;
267835f6802SDirk Vogt		esac
268835f6802SDirk Vogt		dstbackup="$dstfinal$suffix"
269835f6802SDirk Vogt
270835f6802SDirk Vogt# Move or copy the file name to the temp name
271835f6802SDirk Vogt
272835f6802SDirk Vogt		$doit $doinst $srcarg "$dsttmp" &&
273835f6802SDirk Vogt
274835f6802SDirk Vogt		trap "rm -f ${dsttmp}" 0 &&
275835f6802SDirk Vogt
276835f6802SDirk Vogt# and set any options; do chmod last to preserve setuid bits
277835f6802SDirk Vogt
278ef01931fSBen Gras# If any of these fail, we abort the whole thing.  If we want to
279ef01931fSBen Gras# ignore errors from any of these, just make sure not to ignore
280835f6802SDirk Vogt# errors from the above "$doit $instcmd $src $dsttmp" command.
281835f6802SDirk Vogt
282835f6802SDirk Vogt		if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else true;fi &&
283835f6802SDirk Vogt		if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else true;fi &&
284835f6802SDirk Vogt		if [ x"$stripcmd" != x ]; then $doit $stripcmd $stripflags "$dsttmp"; else true;fi &&
285835f6802SDirk Vogt		if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else true;fi &&
286ef01931fSBen Gras
287ef01931fSBen Gras# Now rename the file to the real destination.
288ef01931fSBen Gras
289835f6802SDirk Vogt		if [ x"$suffix" != x ] && [ -f "$dstfinal" ]
290835f6802SDirk Vogt		then
291835f6802SDirk Vogt			$doit $mvcmd "$dstfinal" "$dstbackup"
292ef01931fSBen Gras		else
293835f6802SDirk Vogt			$doit $rmcmd -f "$dstfinal"
294835f6802SDirk Vogt		fi &&
295835f6802SDirk Vogt		$doit $mvcmd "$dsttmp" "$dstfinal"
296ef01931fSBen Gras	fi
297ef01931fSBen Gras
298835f6802SDirk Vogtdone &&
299ef01931fSBen Gras
300ef01931fSBen Gras
301835f6802SDirk Vogtexit 0
302