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