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