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