1b528cefcSMark Murray#!/bin/sh 2b528cefcSMark Murray# install - install a program, script, or datafile 38d4ba808SJacques Vidrine 48d4ba808SJacques Vidrinescriptversion=2004-02-15.20 58d4ba808SJacques Vidrine 61c43270aSJacques Vidrine# This originates from X11R5 (mit/util/scripts/install.sh), which was 71c43270aSJacques Vidrine# later released in X11R6 (xc/config/util/install.sh) with the 81c43270aSJacques Vidrine# following copyright and license. 98373020dSJacques Vidrine# 101c43270aSJacques Vidrine# Copyright (C) 1994 X Consortium 111c43270aSJacques Vidrine# 121c43270aSJacques Vidrine# Permission is hereby granted, free of charge, to any person obtaining a copy 131c43270aSJacques Vidrine# of this software and associated documentation files (the "Software"), to 141c43270aSJacques Vidrine# deal in the Software without restriction, including without limitation the 151c43270aSJacques Vidrine# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 161c43270aSJacques Vidrine# sell copies of the Software, and to permit persons to whom the Software is 171c43270aSJacques Vidrine# furnished to do so, subject to the following conditions: 181c43270aSJacques Vidrine# 191c43270aSJacques Vidrine# The above copyright notice and this permission notice shall be included in 201c43270aSJacques Vidrine# all copies or substantial portions of the Software. 211c43270aSJacques Vidrine# 221c43270aSJacques Vidrine# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 231c43270aSJacques Vidrine# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 241c43270aSJacques Vidrine# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 251c43270aSJacques Vidrine# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 261c43270aSJacques Vidrine# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 271c43270aSJacques Vidrine# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 281c43270aSJacques Vidrine# 291c43270aSJacques Vidrine# Except as contained in this notice, the name of the X Consortium shall not 301c43270aSJacques Vidrine# be used in advertising or otherwise to promote the sale, use or other deal- 311c43270aSJacques Vidrine# ings in this Software without prior written authorization from the X Consor- 321c43270aSJacques Vidrine# tium. 331c43270aSJacques Vidrine# 341c43270aSJacques Vidrine# 351c43270aSJacques Vidrine# FSF changes to this file are in the public domain. 36b528cefcSMark Murray# 37b528cefcSMark Murray# Calling this script install-sh is preferred over install.sh, to prevent 38b528cefcSMark Murray# `make' implicit rules from creating a file called install from it 39b528cefcSMark Murray# when there is no Makefile. 40b528cefcSMark Murray# 41b528cefcSMark Murray# This script is compatible with the BSD install script, but was written 428373020dSJacques Vidrine# from scratch. It can only install one file at a time, a restriction 438373020dSJacques Vidrine# shared with many OS's install programs. 44b528cefcSMark Murray 45b528cefcSMark Murray# set DOITPROG to echo to test this script 46b528cefcSMark Murray 47b528cefcSMark Murray# Don't use :- since 4.3BSD and earlier shells don't like it. 48b528cefcSMark Murraydoit="${DOITPROG-}" 49b528cefcSMark Murray 50b528cefcSMark Murray# put in absolute paths if you don't have them in your path; or use env. vars. 51b528cefcSMark Murray 52b528cefcSMark Murraymvprog="${MVPROG-mv}" 53b528cefcSMark Murraycpprog="${CPPROG-cp}" 54b528cefcSMark Murraychmodprog="${CHMODPROG-chmod}" 55b528cefcSMark Murraychownprog="${CHOWNPROG-chown}" 56b528cefcSMark Murraychgrpprog="${CHGRPPROG-chgrp}" 57b528cefcSMark Murraystripprog="${STRIPPROG-strip}" 58b528cefcSMark Murrayrmprog="${RMPROG-rm}" 59b528cefcSMark Murraymkdirprog="${MKDIRPROG-mkdir}" 60b528cefcSMark Murray 618d4ba808SJacques Vidrinetransformbasename= 628d4ba808SJacques Vidrinetransform_arg= 63b528cefcSMark Murrayinstcmd="$mvprog" 64b528cefcSMark Murraychmodcmd="$chmodprog 0755" 658d4ba808SJacques Vidrinechowncmd= 668d4ba808SJacques Vidrinechgrpcmd= 678d4ba808SJacques Vidrinestripcmd= 68b528cefcSMark Murrayrmcmd="$rmprog -f" 69b528cefcSMark Murraymvcmd="$mvprog" 708d4ba808SJacques Vidrinesrc= 718d4ba808SJacques Vidrinedst= 728d4ba808SJacques Vidrinedir_arg= 73b528cefcSMark Murray 748d4ba808SJacques Vidrineusage="Usage: $0 [OPTION]... SRCFILE DSTFILE 758d4ba808SJacques Vidrine or: $0 [OPTION]... SRCFILES... DIRECTORY 768d4ba808SJacques Vidrine or: $0 -d DIRECTORIES... 778d4ba808SJacques Vidrine 788d4ba808SJacques VidrineIn the first form, install SRCFILE to DSTFILE, removing SRCFILE by default. 798d4ba808SJacques VidrineIn the second, create the directory path DIR. 808d4ba808SJacques Vidrine 818d4ba808SJacques VidrineOptions: 828d4ba808SJacques Vidrine-b=TRANSFORMBASENAME 838d4ba808SJacques Vidrine-c copy source (using $cpprog) instead of moving (using $mvprog). 848d4ba808SJacques Vidrine-d create directories instead of installing files. 858d4ba808SJacques Vidrine-g GROUP $chgrp installed files to GROUP. 868d4ba808SJacques Vidrine-m MODE $chmod installed files to MODE. 878d4ba808SJacques Vidrine-o USER $chown installed files to USER. 888d4ba808SJacques Vidrine-s strip installed files (using $stripprog). 898d4ba808SJacques Vidrine-t=TRANSFORM 908d4ba808SJacques Vidrine--help display this help and exit. 918d4ba808SJacques Vidrine--version display version info and exit. 928d4ba808SJacques Vidrine 938d4ba808SJacques VidrineEnvironment variables override the default commands: 948d4ba808SJacques Vidrine CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG 958d4ba808SJacques Vidrine" 968d4ba808SJacques Vidrine 978d4ba808SJacques Vidrinewhile test -n "$1"; do 98b528cefcSMark Murray case $1 in 998d4ba808SJacques Vidrine -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 1008d4ba808SJacques Vidrine shift 1018d4ba808SJacques Vidrine continue;; 1028d4ba808SJacques Vidrine 1031c43270aSJacques Vidrine -c) instcmd=$cpprog 104b528cefcSMark Murray shift 105b528cefcSMark Murray continue;; 106b528cefcSMark Murray 107b528cefcSMark Murray -d) dir_arg=true 108b528cefcSMark Murray shift 109b528cefcSMark Murray continue;; 110b528cefcSMark Murray 1118d4ba808SJacques Vidrine -g) chgrpcmd="$chgrpprog $2" 1128d4ba808SJacques Vidrine shift 1138d4ba808SJacques Vidrine shift 1148d4ba808SJacques Vidrine continue;; 1158d4ba808SJacques Vidrine 1168d4ba808SJacques Vidrine --help) echo "$usage"; exit 0;; 1178d4ba808SJacques Vidrine 118b528cefcSMark Murray -m) chmodcmd="$chmodprog $2" 119b528cefcSMark Murray shift 120b528cefcSMark Murray shift 121b528cefcSMark Murray continue;; 122b528cefcSMark Murray 123b528cefcSMark Murray -o) chowncmd="$chownprog $2" 124b528cefcSMark Murray shift 125b528cefcSMark Murray shift 126b528cefcSMark Murray continue;; 127b528cefcSMark Murray 1281c43270aSJacques Vidrine -s) stripcmd=$stripprog 129b528cefcSMark Murray shift 130b528cefcSMark Murray continue;; 131b528cefcSMark Murray 132b528cefcSMark Murray -t=*) transformarg=`echo $1 | sed 's/-t=//'` 133b528cefcSMark Murray shift 134b528cefcSMark Murray continue;; 135b528cefcSMark Murray 1368d4ba808SJacques Vidrine --version) echo "$0 $scriptversion"; exit 0;; 137b528cefcSMark Murray 1388d4ba808SJacques Vidrine *) # When -d is used, all remaining arguments are directories to create. 1398d4ba808SJacques Vidrine test -n "$dir_arg" && break 1408d4ba808SJacques Vidrine # Otherwise, the last argument is the destination. Remove it from $@. 1418d4ba808SJacques Vidrine for arg 1428d4ba808SJacques Vidrine do 1438d4ba808SJacques Vidrine if test -n "$dstarg"; then 1448d4ba808SJacques Vidrine # $@ is not empty: it contains at least $arg. 1458d4ba808SJacques Vidrine set fnord "$@" "$dstarg" 1468d4ba808SJacques Vidrine shift # fnord 147b528cefcSMark Murray fi 1488d4ba808SJacques Vidrine shift # arg 1498d4ba808SJacques Vidrine dstarg=$arg 1508d4ba808SJacques Vidrine done 1518d4ba808SJacques Vidrine break;; 152b528cefcSMark Murray esac 153b528cefcSMark Murraydone 154b528cefcSMark Murray 1558d4ba808SJacques Vidrineif test -z "$1"; then 1568d4ba808SJacques Vidrine if test -z "$dir_arg"; then 1578d4ba808SJacques Vidrine echo "$0: no input file specified." >&2 158b528cefcSMark Murray exit 1 1598d4ba808SJacques Vidrine fi 1608d4ba808SJacques Vidrine # It's OK to call `install-sh -d' without argument. 1618d4ba808SJacques Vidrine # This can happen when creating conditional directories. 1628d4ba808SJacques Vidrine exit 0 163b528cefcSMark Murrayfi 164b528cefcSMark Murray 1658d4ba808SJacques Vidrinefor src 1668d4ba808SJacques Vidrinedo 1678d4ba808SJacques Vidrine # Protect names starting with `-'. 1688d4ba808SJacques Vidrine case $src in 1698d4ba808SJacques Vidrine -*) src=./$src ;; 1708d4ba808SJacques Vidrine esac 171b528cefcSMark Murray 1728d4ba808SJacques Vidrine if test -n "$dir_arg"; then 1738d4ba808SJacques Vidrine dst=$src 1748d4ba808SJacques Vidrine src= 1758d4ba808SJacques Vidrine 1768d4ba808SJacques Vidrine if test -d "$dst"; then 177b528cefcSMark Murray instcmd=: 1788d4ba808SJacques Vidrine chmodcmd= 179b528cefcSMark Murray else 1808373020dSJacques Vidrine instcmd=$mkdirprog 181b528cefcSMark Murray fi 182b528cefcSMark Murray else 183b528cefcSMark Murray # Waiting for this to be detected by the "$instcmd $src $dsttmp" command 184b528cefcSMark Murray # might cause directories to be created, which would be especially bad 185b528cefcSMark Murray # if $src (and thus $dsttmp) contains '*'. 1868d4ba808SJacques Vidrine if test ! -f "$src" && test ! -d "$src"; then 1878d4ba808SJacques Vidrine echo "$0: $src does not exist." >&2 188b528cefcSMark Murray exit 1 189b528cefcSMark Murray fi 190b528cefcSMark Murray 1918d4ba808SJacques Vidrine if test -z "$dstarg"; then 1928d4ba808SJacques Vidrine echo "$0: no destination specified." >&2 193b528cefcSMark Murray exit 1 194b528cefcSMark Murray fi 195b528cefcSMark Murray 1968d4ba808SJacques Vidrine dst=$dstarg 1978d4ba808SJacques Vidrine # Protect names starting with `-'. 1988d4ba808SJacques Vidrine case $dst in 1998d4ba808SJacques Vidrine -*) dst=./$dst ;; 2008d4ba808SJacques Vidrine esac 201b528cefcSMark Murray 2028d4ba808SJacques Vidrine # If destination is a directory, append the input filename; won't work 2038d4ba808SJacques Vidrine # if double slashes aren't ignored. 2048d4ba808SJacques Vidrine if test -d "$dst"; then 2051c43270aSJacques Vidrine dst=$dst/`basename "$src"` 206b528cefcSMark Murray fi 207b528cefcSMark Murray fi 208b528cefcSMark Murray 2098d4ba808SJacques Vidrine # This sed command emulates the dirname command. 2101c43270aSJacques Vidrine dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 211b528cefcSMark Murray 212b528cefcSMark Murray # Make sure that the destination directory exists. 213b528cefcSMark Murray 214b528cefcSMark Murray # Skip lots of stat calls in the usual case. 2158d4ba808SJacques Vidrine if test ! -d "$dstdir"; then 216b528cefcSMark Murray defaultIFS=' 217b528cefcSMark Murray ' 2181c43270aSJacques Vidrine IFS="${IFS-$defaultIFS}" 219b528cefcSMark Murray 2201c43270aSJacques Vidrine oIFS=$IFS 221b528cefcSMark Murray # Some sh's can't handle IFS=/ for some reason. 222b528cefcSMark Murray IFS='%' 2231c43270aSJacques Vidrine set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 2241c43270aSJacques Vidrine IFS=$oIFS 225b528cefcSMark Murray 2268d4ba808SJacques Vidrine pathcomp= 227b528cefcSMark Murray 2288d4ba808SJacques Vidrine while test $# -ne 0 ; do 2291c43270aSJacques Vidrine pathcomp=$pathcomp$1 230b528cefcSMark Murray shift 2318d4ba808SJacques Vidrine if test ! -d "$pathcomp"; then 2328d4ba808SJacques Vidrine $mkdirprog "$pathcomp" || lasterr=$? 2338d4ba808SJacques Vidrine # mkdir can fail with a `File exist' error in case several 2348d4ba808SJacques Vidrine # install-sh are creating the directory concurrently. This 2358d4ba808SJacques Vidrine # is OK. 2368d4ba808SJacques Vidrine test ! -d "$pathcomp" && { (exit ${lasterr-1}); exit; } 237b528cefcSMark Murray fi 2381c43270aSJacques Vidrine pathcomp=$pathcomp/ 239b528cefcSMark Murray done 240b528cefcSMark Murray fi 241b528cefcSMark Murray 2428d4ba808SJacques Vidrine if test -n "$dir_arg"; then 2438d4ba808SJacques Vidrine $doit $instcmd "$dst" \ 2448d4ba808SJacques Vidrine && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ 2458d4ba808SJacques Vidrine && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ 2468d4ba808SJacques Vidrine && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ 2478d4ba808SJacques Vidrine && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } 248b528cefcSMark Murray 249b528cefcSMark Murray else 250b528cefcSMark Murray # If we're going to rename the final executable, determine the name now. 2518d4ba808SJacques Vidrine if test -z "$transformarg"; then 2521c43270aSJacques Vidrine dstfile=`basename "$dst"` 253b528cefcSMark Murray else 2548d4ba808SJacques Vidrine dstfile=`basename "$dst" $transformbasename \ 2558d4ba808SJacques Vidrine | sed $transformarg`$transformbasename 256b528cefcSMark Murray fi 257b528cefcSMark Murray 2588d4ba808SJacques Vidrine # don't allow the sed command to completely eliminate the filename. 2598d4ba808SJacques Vidrine test -z "$dstfile" && dstfile=`basename "$dst"` 260b528cefcSMark Murray 2611c43270aSJacques Vidrine # Make a couple of temp file names in the proper directory. 2621c43270aSJacques Vidrine dsttmp=$dstdir/_inst.$$_ 2631c43270aSJacques Vidrine rmtmp=$dstdir/_rm.$$_ 2641c43270aSJacques Vidrine 2658d4ba808SJacques Vidrine # Trap to clean up those temp files at exit. 2661c43270aSJacques Vidrine trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 2671c43270aSJacques Vidrine trap '(exit $?); exit' 1 2 13 15 268b528cefcSMark Murray 269b528cefcSMark Murray # Move or copy the file name to the temp name 2701c43270aSJacques Vidrine $doit $instcmd "$src" "$dsttmp" && 271b528cefcSMark Murray 2728d4ba808SJacques Vidrine # and set any options; do chmod last to preserve setuid bits. 2738d4ba808SJacques Vidrine # 274b528cefcSMark Murray # If any of these fail, we abort the whole thing. If we want to 275b528cefcSMark Murray # ignore errors from any of these, just make sure not to ignore 276b528cefcSMark Murray # errors from the above "$doit $instcmd $src $dsttmp" command. 2778d4ba808SJacques Vidrine # 2788d4ba808SJacques Vidrine { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ 2798d4ba808SJacques Vidrine && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ 2808d4ba808SJacques Vidrine && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ 2818d4ba808SJacques Vidrine && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && 282b528cefcSMark Murray 2838d4ba808SJacques Vidrine # Now remove or move aside any old file at destination location. We 2848d4ba808SJacques Vidrine # try this two ways since rm can't unlink itself on some systems and 2858d4ba808SJacques Vidrine # the destination file might be busy for other reasons. In this case, 2868d4ba808SJacques Vidrine # the final cleanup might fail but the new file should still install 2878d4ba808SJacques Vidrine # successfully. 2881c43270aSJacques Vidrine { 2898d4ba808SJacques Vidrine if test -f "$dstdir/$dstfile"; then 2908d4ba808SJacques Vidrine $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ 2918d4ba808SJacques Vidrine || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ 2928d4ba808SJacques Vidrine || { 2931c43270aSJacques Vidrine echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 2941c43270aSJacques Vidrine (exit 1); exit 2951c43270aSJacques Vidrine } 2961c43270aSJacques Vidrine else 2971c43270aSJacques Vidrine : 2981c43270aSJacques Vidrine fi 2991c43270aSJacques Vidrine } && 300b528cefcSMark Murray 301b528cefcSMark Murray # Now rename the file to the real destination. 3021c43270aSJacques Vidrine $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 3038d4ba808SJacques Vidrine fi || { (exit 1); exit; } 3048d4ba808SJacques Vidrinedone 305b528cefcSMark Murray 3061c43270aSJacques Vidrine# The final little trick to "correctly" pass the exit status to the exit trap. 3071c43270aSJacques Vidrine{ 3081c43270aSJacques Vidrine (exit 0); exit 3091c43270aSJacques Vidrine} 3108d4ba808SJacques Vidrine 3118d4ba808SJacques Vidrine# Local variables: 3128d4ba808SJacques Vidrine# eval: (add-hook 'write-file-hooks 'time-stamp) 3138d4ba808SJacques Vidrine# time-stamp-start: "scriptversion=" 3148d4ba808SJacques Vidrine# time-stamp-format: "%:y-%02m-%02d.%02H" 3158d4ba808SJacques Vidrine# time-stamp-end: "$" 3168d4ba808SJacques Vidrine# End: 317