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