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