install-sh revision 130561
154359Sroberto#!/bin/sh 254359Sroberto# 354359Sroberto# install - install a program, script, or datafile 454359Sroberto# 554359Sroberto# This originates from X11R5 (mit/util/scripts/install.sh), which was 654359Sroberto# later released in X11R6 (xc/config/util/install.sh) with the 754359Sroberto# following copyright and license. 854359Sroberto# 954359Sroberto# Copyright (C) 1994 X Consortium 10132451Sroberto# 11132451Sroberto# Permission is hereby granted, free of charge, to any person obtaining a copy 12132451Sroberto# of this software and associated documentation files (the "Software"), to 13132451Sroberto# deal in the Software without restriction, including without limitation the 14132451Sroberto# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 1554359Sroberto# sell copies of the Software, and to permit persons to whom the Software is 1654359Sroberto# furnished to do so, subject to the following conditions: 17182007Sroberto# 18182007Sroberto# The above copyright notice and this permission notice shall be included in 19182007Sroberto# all copies or substantial portions of the Software. 2054359Sroberto# 2154359Sroberto# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2282498Sroberto# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2354359Sroberto# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 2454359Sroberto# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2554359Sroberto# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 2682498Sroberto# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27182007Sroberto# 2882498Sroberto# Except as contained in this notice, the name of the X Consortium shall not 2982498Sroberto# be used in advertising or otherwise to promote the sale, use or other deal- 3054359Sroberto# ings in this Software without prior written authorization from the X Consor- 3154359Sroberto# tium. 3254359Sroberto# 3354359Sroberto# 3454359Sroberto# FSF changes to this file are in the public domain. 3554359Sroberto# 3654359Sroberto# Calling this script install-sh is preferred over install.sh, to prevent 3754359Sroberto# `make' implicit rules from creating a file called install from it 3882498Sroberto# when there is no Makefile. 3982498Sroberto# 4082498Sroberto# This script is compatible with the BSD install script, but was written 4182498Sroberto# from scratch. It can only install one file at a time, a restriction 4282498Sroberto# shared with many OS's install programs. 4382498Sroberto 4482498Sroberto 4582498Sroberto# set DOITPROG to echo to test this script 4682498Sroberto 4782498Sroberto# Don't use :- since 4.3BSD and earlier shells don't like it. 4882498Srobertodoit="${DOITPROG-}" 4982498Sroberto 5082498Sroberto 5182498Sroberto# put in absolute paths if you don't have them in your path; or use env. vars. 5282498Sroberto 5382498Srobertomvprog="${MVPROG-mv}" 5482498Srobertocpprog="${CPPROG-cp}" 5554359Srobertochmodprog="${CHMODPROG-chmod}" 5654359Srobertochownprog="${CHOWNPROG-chown}" 5754359Srobertochgrpprog="${CHGRPPROG-chgrp}" 5854359Srobertostripprog="${STRIPPROG-strip}" 5954359Srobertormprog="${RMPROG-rm}" 6056746Srobertomkdirprog="${MKDIRPROG-mkdir}" 6156746Sroberto 6256746Srobertotransformbasename="" 6356746Srobertotransform_arg="" 6456746Srobertoinstcmd="$mvprog" 6554359Srobertochmodcmd="$chmodprog 0755" 6654359Srobertochowncmd="" 6782498Srobertochgrpcmd="" 6854359Srobertostripcmd="" 6954359Srobertormcmd="$rmprog -f" 7082498Srobertomvcmd="$mvprog" 7182498Srobertosrc="" 7254359Srobertodst="" 7354359Srobertodir_arg="" 7454359Sroberto 7554359Srobertowhile [ x"$1" != x ]; do 7654359Sroberto case $1 in 7754359Sroberto -c) instcmd=$cpprog 7854359Sroberto shift 7954359Sroberto continue;; 8054359Sroberto 8154359Sroberto -d) dir_arg=true 8254359Sroberto shift 8354359Sroberto continue;; 8454359Sroberto 8554359Sroberto -m) chmodcmd="$chmodprog $2" 8654359Sroberto shift 8754359Sroberto shift 8854359Sroberto continue;; 8982498Sroberto 9082498Sroberto -o) chowncmd="$chownprog $2" 9182498Sroberto shift 9282498Sroberto shift 9382498Sroberto continue;; 9482498Sroberto 9554359Sroberto -g) chgrpcmd="$chgrpprog $2" 9654359Sroberto shift 9754359Sroberto shift 9854359Sroberto continue;; 9954359Sroberto 10054359Sroberto -s) stripcmd=$stripprog 10154359Sroberto shift 10282498Sroberto continue;; 10382498Sroberto 10482498Sroberto -t=*) transformarg=`echo $1 | sed 's/-t=//'` 10582498Sroberto shift 10682498Sroberto continue;; 10782498Sroberto 10854359Sroberto -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 10954359Sroberto shift 11054359Sroberto continue;; 11154359Sroberto 11254359Sroberto *) if [ x"$src" = x ] 11354359Sroberto then 11454359Sroberto src=$1 11554359Sroberto else 11654359Sroberto # this colon is to work around a 386BSD /bin/sh bug 11754359Sroberto : 11854359Sroberto dst=$1 11954359Sroberto fi 12082498Sroberto shift 12182498Sroberto continue;; 12282498Sroberto esac 12382498Srobertodone 12482498Sroberto 12554359Srobertoif [ x"$src" = x ] 12654359Srobertothen 12754359Sroberto echo "$0: no input file specified" >&2 12854359Sroberto exit 1 12954359Srobertoelse 13054359Sroberto : 13154359Srobertofi 13254359Sroberto 13354359Srobertoif [ x"$dir_arg" != x ]; then 13454359Sroberto dst=$src 13554359Sroberto src="" 13654359Sroberto 13754359Sroberto if [ -d "$dst" ]; then 13854359Sroberto instcmd=: 13954359Sroberto chmodcmd="" 14054359Sroberto else 14154359Sroberto instcmd=$mkdirprog 14254359Sroberto fi 14354359Srobertoelse 14454359Sroberto 14554359Sroberto# Waiting for this to be detected by the "$instcmd $src $dsttmp" command 14654359Sroberto# might cause directories to be created, which would be especially bad 14754359Sroberto# if $src (and thus $dsttmp) contains '*'. 14856746Sroberto 149132451Sroberto if [ -f "$src" ] || [ -d "$src" ] 150182007Sroberto then 151182007Sroberto : 152182007Sroberto else 153182007Sroberto echo "$0: $src does not exist" >&2 154182007Sroberto exit 1 155182007Sroberto fi 156182007Sroberto 157182007Sroberto if [ x"$dst" = x ] 158182007Sroberto then 159182007Sroberto echo "$0: no destination specified" >&2 160182007Sroberto exit 1 161182007Sroberto else 162182007Sroberto : 163182007Sroberto fi 164182007Sroberto 165182007Sroberto# If destination is a directory, append the input filename; if your system 166182007Sroberto# does not like double slashes in filenames, you may need to add some logic 167182007Sroberto 168182007Sroberto if [ -d "$dst" ] 16954359Sroberto then 170182007Sroberto dst=$dst/`basename "$src"` 171182007Sroberto else 172182007Sroberto : 173182007Sroberto fi 174182007Srobertofi 175182007Sroberto 176182007Sroberto## this sed command emulates the dirname command 177182007Srobertodstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 178182007Sroberto 179182007Sroberto# Make sure that the destination directory exists. 180182007Sroberto# this part is taken from Noah Friedman's mkinstalldirs script 181182007Sroberto 182182007Sroberto# Skip lots of stat calls in the usual case. 183182007Srobertoif [ ! -d "$dstdir" ]; then 184182007SrobertodefaultIFS=' 185182007Sroberto ' 186182007SrobertoIFS="${IFS-$defaultIFS}" 187182007Sroberto 188182007SrobertooIFS=$IFS 189182007Sroberto# Some sh's can't handle IFS=/ for some reason. 190182007SrobertoIFS='%' 191182007Srobertoset - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 192182007SrobertoIFS=$oIFS 193182007Sroberto 194182007Srobertopathcomp='' 195182007Sroberto 196182007Srobertowhile [ $# -ne 0 ] ; do 197182007Sroberto pathcomp=$pathcomp$1 19854359Sroberto shift 19954359Sroberto 20054359Sroberto if [ ! -d "$pathcomp" ] ; 201132451Sroberto then 202132451Sroberto $mkdirprog "$pathcomp" 20354359Sroberto else 20454359Sroberto : 20554359Sroberto fi 20654359Sroberto 20754359Sroberto pathcomp=$pathcomp/ 20854359Srobertodone 20954359Srobertofi 21054359Sroberto 21154359Srobertoif [ x"$dir_arg" != x ] 21254359Srobertothen 21354359Sroberto $doit $instcmd "$dst" && 21454359Sroberto 21554359Sroberto if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && 21654359Sroberto if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && 21754359Sroberto if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && 21854359Sroberto if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi 21954359Srobertoelse 22054359Sroberto 22154359Sroberto# If we're going to rename the final executable, determine the name now. 22282498Sroberto 22354359Sroberto if [ x"$transformarg" = x ] 22454359Sroberto then 22554359Sroberto dstfile=`basename "$dst"` 22654359Sroberto else 22754359Sroberto dstfile=`basename "$dst" $transformbasename | 22882498Sroberto sed $transformarg`$transformbasename 22982498Sroberto fi 23082498Sroberto 23182498Sroberto# don't allow the sed command to completely eliminate the filename 23282498Sroberto 23382498Sroberto if [ x"$dstfile" = x ] 23482498Sroberto then 23582498Sroberto dstfile=`basename "$dst"` 23682498Sroberto else 23782498Sroberto : 23882498Sroberto fi 23982498Sroberto 24082498Sroberto# Make a couple of temp file names in the proper directory. 24154359Sroberto 24282498Sroberto dsttmp=$dstdir/#inst.$$# 24354359Sroberto rmtmp=$dstdir/#rm.$$# 24454359Sroberto 24554359Sroberto# Trap to clean up temp files at exit. 24654359Sroberto 24754359Sroberto trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 24854359Sroberto trap '(exit $?); exit' 1 2 13 15 24954359Sroberto 25054359Sroberto# Move or copy the file name to the temp name 25154359Sroberto 25254359Sroberto $doit $instcmd "$src" "$dsttmp" && 25354359Sroberto 25454359Sroberto# and set any options; do chmod last to preserve setuid bits 25554359Sroberto 25654359Sroberto# If any of these fail, we abort the whole thing. If we want to 25754359Sroberto# ignore errors from any of these, just make sure not to ignore 25854359Sroberto# errors from the above "$doit $instcmd $src $dsttmp" command. 25982498Sroberto 26082498Sroberto if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && 26182498Sroberto if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && 26282498Sroberto if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && 26354359Sroberto if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && 26454359Sroberto 26554359Sroberto# Now remove or move aside any old file at destination location. We try this 26654359Sroberto# two ways since rm can't unlink itself on some systems and the destination 26782498Sroberto# file might be busy for other reasons. In this case, the final cleanup 26854359Sroberto# might fail but the new file should still install successfully. 26982498Sroberto 27082498Sroberto{ 27182498Sroberto if [ -f "$dstdir/$dstfile" ] 27282498Sroberto then 27382498Sroberto $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || 27482498Sroberto $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || 27582498Sroberto { 27682498Sroberto echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 27782498Sroberto (exit 1); exit 27882498Sroberto } 27982498Sroberto else 28082498Sroberto : 28182498Sroberto fi 28282498Sroberto} && 28382498Sroberto 28482498Sroberto# Now rename the file to the real destination. 28582498Sroberto 28682498Sroberto $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 28782498Sroberto 28882498Srobertofi && 28982498Sroberto 29082498Sroberto# The final little trick to "correctly" pass the exit status to the exit trap. 29182498Sroberto 29282498Sroberto{ 29382498Sroberto (exit 0); exit 29482498Sroberto} 29582498Sroberto