18cf6c252SPaul Traina#! /bin/sh 28cf6c252SPaul Traina# 38cf6c252SPaul Traina# install - install a program, script, or datafile 43052b236SBill Fenner# This comes from X11R5 (mit/util/scripts/install.sh). 53052b236SBill Fenner# 63052b236SBill Fenner# Copyright 1991 by the Massachusetts Institute of Technology 73052b236SBill Fenner# 83052b236SBill Fenner# Permission to use, copy, modify, distribute, and sell this software and its 93052b236SBill Fenner# documentation for any purpose is hereby granted without fee, provided that 103052b236SBill Fenner# the above copyright notice appear in all copies and that both that 113052b236SBill Fenner# copyright notice and this permission notice appear in supporting 123052b236SBill Fenner# documentation, and that the name of M.I.T. not be used in advertising or 133052b236SBill Fenner# publicity pertaining to distribution of the software without specific, 143052b236SBill Fenner# written prior permission. M.I.T. makes no representations about the 153052b236SBill Fenner# suitability of this software for any purpose. It is provided "as is" 163052b236SBill Fenner# without express or implied warranty. 178cf6c252SPaul Traina# 188cf6c252SPaul Traina# Calling this script install-sh is preferred over install.sh, to prevent 198cf6c252SPaul Traina# `make' implicit rules from creating a file called install from it 208cf6c252SPaul Traina# when there is no Makefile. 218cf6c252SPaul Traina# 228cf6c252SPaul Traina# This script is compatible with the BSD install script, but was written 233052b236SBill Fenner# from scratch. It can only install one file at a time, a restriction 243052b236SBill Fenner# shared with many OS's install programs. 258cf6c252SPaul Traina 268cf6c252SPaul Traina 278cf6c252SPaul Traina# set DOITPROG to echo to test this script 288cf6c252SPaul Traina 298cf6c252SPaul Traina# Don't use :- since 4.3BSD and earlier shells don't like it. 308cf6c252SPaul Trainadoit="${DOITPROG-}" 318cf6c252SPaul Traina 328cf6c252SPaul Traina 338cf6c252SPaul Traina# put in absolute paths if you don't have them in your path; or use env. vars. 348cf6c252SPaul Traina 358cf6c252SPaul Trainamvprog="${MVPROG-mv}" 368cf6c252SPaul Trainacpprog="${CPPROG-cp}" 378cf6c252SPaul Trainachmodprog="${CHMODPROG-chmod}" 388cf6c252SPaul Trainachownprog="${CHOWNPROG-chown}" 398cf6c252SPaul Trainachgrpprog="${CHGRPPROG-chgrp}" 408cf6c252SPaul Trainastripprog="${STRIPPROG-strip}" 418cf6c252SPaul Trainarmprog="${RMPROG-rm}" 428cf6c252SPaul Trainamkdirprog="${MKDIRPROG-mkdir}" 438cf6c252SPaul Traina 448cf6c252SPaul Trainatransformbasename="" 458cf6c252SPaul Trainatransform_arg="" 468cf6c252SPaul Trainainstcmd="$mvprog" 478cf6c252SPaul Trainachmodcmd="$chmodprog 0755" 488cf6c252SPaul Trainachowncmd="" 498cf6c252SPaul Trainachgrpcmd="" 508cf6c252SPaul Trainastripcmd="" 518cf6c252SPaul Trainarmcmd="$rmprog -f" 528cf6c252SPaul Trainamvcmd="$mvprog" 538cf6c252SPaul Trainasrc="" 548cf6c252SPaul Trainadst="" 558cf6c252SPaul Trainadir_arg="" 568cf6c252SPaul Traina 578cf6c252SPaul Trainawhile [ x"$1" != x ]; do 588cf6c252SPaul Traina case $1 in 598cf6c252SPaul Traina -c) instcmd="$cpprog" 608cf6c252SPaul Traina shift 618cf6c252SPaul Traina continue;; 628cf6c252SPaul Traina 638cf6c252SPaul Traina -d) dir_arg=true 648cf6c252SPaul Traina shift 658cf6c252SPaul Traina continue;; 668cf6c252SPaul Traina 678cf6c252SPaul Traina -m) chmodcmd="$chmodprog $2" 688cf6c252SPaul Traina shift 698cf6c252SPaul Traina shift 708cf6c252SPaul Traina continue;; 718cf6c252SPaul Traina 728cf6c252SPaul Traina -o) chowncmd="$chownprog $2" 738cf6c252SPaul Traina shift 748cf6c252SPaul Traina shift 758cf6c252SPaul Traina continue;; 768cf6c252SPaul Traina 778cf6c252SPaul Traina -g) chgrpcmd="$chgrpprog $2" 788cf6c252SPaul Traina shift 798cf6c252SPaul Traina shift 808cf6c252SPaul Traina continue;; 818cf6c252SPaul Traina 828cf6c252SPaul Traina -s) stripcmd="$stripprog" 838cf6c252SPaul Traina shift 848cf6c252SPaul Traina continue;; 858cf6c252SPaul Traina 868cf6c252SPaul Traina -t=*) transformarg=`echo $1 | sed 's/-t=//'` 878cf6c252SPaul Traina shift 888cf6c252SPaul Traina continue;; 898cf6c252SPaul Traina 908cf6c252SPaul Traina -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 918cf6c252SPaul Traina shift 928cf6c252SPaul Traina continue;; 938cf6c252SPaul Traina 948cf6c252SPaul Traina *) if [ x"$src" = x ] 958cf6c252SPaul Traina then 968cf6c252SPaul Traina src=$1 978cf6c252SPaul Traina else 988cf6c252SPaul Traina # this colon is to work around a 386BSD /bin/sh bug 998cf6c252SPaul Traina : 1008cf6c252SPaul Traina dst=$1 1018cf6c252SPaul Traina fi 1028cf6c252SPaul Traina shift 1038cf6c252SPaul Traina continue;; 1048cf6c252SPaul Traina esac 1058cf6c252SPaul Trainadone 1068cf6c252SPaul Traina 1078cf6c252SPaul Trainaif [ x"$src" = x ] 1088cf6c252SPaul Trainathen 1098cf6c252SPaul Traina echo "install: no input file specified" 1108cf6c252SPaul Traina exit 1 1118cf6c252SPaul Trainaelse 1128cf6c252SPaul Traina true 1138cf6c252SPaul Trainafi 1148cf6c252SPaul Traina 1158cf6c252SPaul Trainaif [ x"$dir_arg" != x ]; then 1168cf6c252SPaul Traina dst=$src 1178cf6c252SPaul Traina src="" 1188cf6c252SPaul Traina 1198cf6c252SPaul Traina if [ -d $dst ]; then 1208cf6c252SPaul Traina instcmd=: 1218cf6c252SPaul Traina else 1228cf6c252SPaul Traina instcmd=mkdir 1238cf6c252SPaul Traina fi 1248cf6c252SPaul Trainaelse 1258cf6c252SPaul Traina 1268cf6c252SPaul Traina# Waiting for this to be detected by the "$instcmd $src $dsttmp" command 1278cf6c252SPaul Traina# might cause directories to be created, which would be especially bad 1288cf6c252SPaul Traina# if $src (and thus $dsttmp) contains '*'. 1298cf6c252SPaul Traina 1308cf6c252SPaul Traina if [ -f $src -o -d $src ] 1318cf6c252SPaul Traina then 1328cf6c252SPaul Traina true 1338cf6c252SPaul Traina else 1348cf6c252SPaul Traina echo "install: $src does not exist" 1358cf6c252SPaul Traina exit 1 1368cf6c252SPaul Traina fi 1378cf6c252SPaul Traina 1388cf6c252SPaul Traina if [ x"$dst" = x ] 1398cf6c252SPaul Traina then 1408cf6c252SPaul Traina echo "install: no destination specified" 1418cf6c252SPaul Traina exit 1 1428cf6c252SPaul Traina else 1438cf6c252SPaul Traina true 1448cf6c252SPaul Traina fi 1458cf6c252SPaul Traina 1468cf6c252SPaul Traina# If destination is a directory, append the input filename; if your system 1478cf6c252SPaul Traina# does not like double slashes in filenames, you may need to add some logic 1488cf6c252SPaul Traina 1498cf6c252SPaul Traina if [ -d $dst ] 1508cf6c252SPaul Traina then 1518cf6c252SPaul Traina dst="$dst"/`basename $src` 1528cf6c252SPaul Traina else 1538cf6c252SPaul Traina true 1548cf6c252SPaul Traina fi 1558cf6c252SPaul Trainafi 1568cf6c252SPaul Traina 1578cf6c252SPaul Traina## this sed command emulates the dirname command 1588cf6c252SPaul Trainadstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 1598cf6c252SPaul Traina 1608cf6c252SPaul Traina# Make sure that the destination directory exists. 1618cf6c252SPaul Traina# this part is taken from Noah Friedman's mkinstalldirs script 1628cf6c252SPaul Traina 1638cf6c252SPaul Traina# Skip lots of stat calls in the usual case. 1648cf6c252SPaul Trainaif [ ! -d "$dstdir" ]; then 1658cf6c252SPaul TrainadefaultIFS=' 1668cf6c252SPaul Traina' 1678cf6c252SPaul TrainaIFS="${IFS-${defaultIFS}}" 1688cf6c252SPaul Traina 1698cf6c252SPaul TrainaoIFS="${IFS}" 1708cf6c252SPaul Traina# Some sh's can't handle IFS=/ for some reason. 1718cf6c252SPaul TrainaIFS='%' 1728cf6c252SPaul Trainaset - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` 1738cf6c252SPaul TrainaIFS="${oIFS}" 1748cf6c252SPaul Traina 1758cf6c252SPaul Trainapathcomp='' 1768cf6c252SPaul Traina 1778cf6c252SPaul Trainawhile [ $# -ne 0 ] ; do 1788cf6c252SPaul Traina pathcomp="${pathcomp}${1}" 1798cf6c252SPaul Traina shift 1808cf6c252SPaul Traina 1818cf6c252SPaul Traina if [ ! -d "${pathcomp}" ] ; 1828cf6c252SPaul Traina then 1838cf6c252SPaul Traina $mkdirprog "${pathcomp}" 1848cf6c252SPaul Traina else 1858cf6c252SPaul Traina true 1868cf6c252SPaul Traina fi 1878cf6c252SPaul Traina 1888cf6c252SPaul Traina pathcomp="${pathcomp}/" 1898cf6c252SPaul Trainadone 1908cf6c252SPaul Trainafi 1918cf6c252SPaul Traina 1928cf6c252SPaul Trainaif [ x"$dir_arg" != x ] 1938cf6c252SPaul Trainathen 1948cf6c252SPaul Traina $doit $instcmd $dst && 1958cf6c252SPaul Traina 1968cf6c252SPaul Traina if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && 1978cf6c252SPaul Traina if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && 1988cf6c252SPaul Traina if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && 1998cf6c252SPaul Traina if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi 2008cf6c252SPaul Trainaelse 2018cf6c252SPaul Traina 2028cf6c252SPaul Traina# If we're going to rename the final executable, determine the name now. 2038cf6c252SPaul Traina 2048cf6c252SPaul Traina if [ x"$transformarg" = x ] 2058cf6c252SPaul Traina then 2068cf6c252SPaul Traina dstfile=`basename $dst` 2078cf6c252SPaul Traina else 2088cf6c252SPaul Traina dstfile=`basename $dst $transformbasename | 2098cf6c252SPaul Traina sed $transformarg`$transformbasename 2108cf6c252SPaul Traina fi 2118cf6c252SPaul Traina 2128cf6c252SPaul Traina# don't allow the sed command to completely eliminate the filename 2138cf6c252SPaul Traina 2148cf6c252SPaul Traina if [ x"$dstfile" = x ] 2158cf6c252SPaul Traina then 2168cf6c252SPaul Traina dstfile=`basename $dst` 2178cf6c252SPaul Traina else 2188cf6c252SPaul Traina true 2198cf6c252SPaul Traina fi 2208cf6c252SPaul Traina 2218cf6c252SPaul Traina# Make a temp file name in the proper directory. 2228cf6c252SPaul Traina 2238cf6c252SPaul Traina dsttmp=$dstdir/#inst.$$# 2248cf6c252SPaul Traina 2258cf6c252SPaul Traina# Move or copy the file name to the temp name 2268cf6c252SPaul Traina 2278cf6c252SPaul Traina $doit $instcmd $src $dsttmp && 2288cf6c252SPaul Traina 2298cf6c252SPaul Traina trap "rm -f ${dsttmp}" 0 && 2308cf6c252SPaul Traina 2318cf6c252SPaul Traina# and set any options; do chmod last to preserve setuid bits 2328cf6c252SPaul Traina 2338cf6c252SPaul Traina# If any of these fail, we abort the whole thing. If we want to 2348cf6c252SPaul Traina# ignore errors from any of these, just make sure not to ignore 2358cf6c252SPaul Traina# errors from the above "$doit $instcmd $src $dsttmp" command. 2368cf6c252SPaul Traina 2378cf6c252SPaul Traina if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && 2388cf6c252SPaul Traina if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && 2398cf6c252SPaul Traina if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && 2408cf6c252SPaul Traina if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && 2418cf6c252SPaul Traina 2428cf6c252SPaul Traina# Now rename the file to the real destination. 2438cf6c252SPaul Traina 2448cf6c252SPaul Traina $doit $rmcmd -f $dstdir/$dstfile && 2458cf6c252SPaul Traina $doit $mvcmd $dsttmp $dstdir/$dstfile 2468cf6c252SPaul Traina 2478cf6c252SPaul Trainafi && 2488cf6c252SPaul Traina 2498cf6c252SPaul Traina 2508cf6c252SPaul Trainaexit 0 251