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