1: 2# NAME: 3# install.sh - portable version of install(1) 4# 5# SYNOPSIS: 6# install [-CNcs] [-f flags] [-i errs] [-o owner] [-g group] [-m mode] file1 file2 ... 7# install -d [-i errs] [-o owner] [-g group] [-m mode] directory ... 8# 9# DESCRIPTION: 10# Compatible with BSD install(1). Except that '-c' is always 11# true and we always move an already installed target aside as 12# this is important on many systems. Recent BSD install(1) 13# versions have a '-b' option for this. 14# 15# 16# OPTIONS: 17# -b move previous target file aside (always true). 18# 19# -B "suffix" 20# use "suffix" instead of .old for saving existing target. 21# 22# -c copy rather than move the file into place (always true). 23# 24# -C compare. Only install if target is missing or 25# different. 26# 27# -N newer. Only install if target is missing or older. 28# 29# -s strip target 30# 31# -o "owner" 32# make target owned by "owner" 33# 34# -g "group" 35# make target group owned by "group" 36# 37# -m "mode" 38# set permissions to "mode" 39# 40# -f "flags" 41# Pass "flags" onto chflags(1) 42# 43# -i "errs" 44# Ignore errors from steps indicated by "errs" (``s,o,g,m''). 45# 46# BUGS: 47# The '-i' option is to save your sanity when 'bsd.prog.mk' 48# insists on haveing a '-o' "owner" option which is doomed to 49# fail on many systems. We ignore '-b', '-B' and '-c' options. 50# 51# AUTHOR: 52# Simon J. Gerraty <sjg@crufty.net> 53# 54 55# RCSid: 56# $Id: install-sh,v 1.22 2023/01/28 16:21:19 sjg Exp $ 57# 58# @(#) Copyright (c) 1993-2023 Simon J. Gerraty 59# 60# This file is provided in the hope that it will 61# be of use. There is absolutely NO WARRANTY. 62# Permission to copy, redistribute or otherwise 63# use this file is hereby granted provided that 64# the above copyright notice and this notice are 65# left intact. 66# 67# Please send copies of changes and bug-fixes to: 68# sjg@crufty.net 69# 70 71set -- `getopt B:bpxCNcsdo:g:m:i:f: $*` 72 73Mydir=`dirname $0` 74[ -s $Mydir/.installrc ] && . $Mydir/.installrc 75 76owner=: 77group=: 78mode=: 79MODE=0 80strip=: 81mkdirs= 82compare=: 83newer=: 84chflags=: 85LS_1= 86CP_p= 87 88while : 89do 90 case "$1" in 91 --) shift; break;; 92 -p) CP_p=-p;; 93 -x) set -x;; 94 -B) OLD_EXT=$2; shift;; 95 -C) compare=Different;; 96 -N) newer=Newer; 97 # check if /bin/ls supports -1 98 'ls' -1 $0 > /dev/null 2>&1 && LS_1=1 99 ;; 100 -o) owner="${CHOWN:-chown} $2 "; shift;; 101 -g) group="${CHGRP:-chgrp} $2 "; shift;; 102 -m) MODE=$2 mode="${CHMOD:-chmod} $2 "; shift;; 103 -s) strip=${STRIP:-strip};; 104 -d) mkdirs="mkdir -p";; 105 -i) ignore_err="$ignore_err$2"; shift;; 106 -f) chflags="${CHFLAGS:-chflags} $2 "; shift;; 107 *) break;; 108 esac 109 shift 110done 111 112Newer() { 113 n=`'ls' -t$LS_1 $* 2> /dev/null | head -1` 114 [ $1 = $n ] 115} 116 117Different() { 118 cmp -s $* 119 [ $? != 0 ] 120} 121 122Err() { 123 case "$ignore_err" in 124 *$1*) ;; 125 *) exit 1;; 126 esac 127} 128 129Setem() { 130 # the order is important 131 if [ ! -d $1 ]; then 132 $strip $1 || Err s 133 fi 134 $group $1 || Err g 135 $owner $1 || Err o 136 $mode $1 || Err m 137 $chflags $1 || Err f 138 return 0 139} 140 141# a bug in HP-UX's /bin/sh, means we need to re-set $* 142# after any calls to add_path() 143args="$*" 144 145add_path () { 146 test -d $1 || return 147 case ":$PATH:" in 148 *:$1:*) return;; 149 esac 150 PATH=$PATH:$1 151} 152 153add_path /sbin 154add_path /usr/sbin 155 156case "$owner" in 157:) ;; 158*) 159 add_path /etc 160 add_path /usr/etc 161 ;; 162esac 163 164# restore saved $* 165set -- $args 166 167# make directories if needed 168# and ensure mode etc are as desired 169if [ "$mkdirs" ]; then 170 case "$MODE" in 171 [1-7]*) 172 # make sure umask is compatible 173 case "$MODE" in 174 ????*) MODE=`echo $MODE | sed 's,.*\(...\)$,\1,'`;; 175 esac 176 umask `expr 0777 - 0$MODE | 177 sed 's,^,000,;s,^.*\(...\)$,\1,'`;; 178 esac 179 for d in $* 180 do 181 [ ! -d $d ] && $mkdirs $d 182 Setem $d 183 done 184 exit 0 # that's all we do 185fi 186 187# install files 188if [ $# -gt 2 ]; then 189 dest_dir=yes 190elif [ $# -eq 1 ]; then 191 echo "what should I do with $*?" >&2 192 exit 1 193fi 194 195# get list of files 196while [ $# -gt 1 ] 197do 198 files="$files $1" 199 shift 200done 201# last one is dest 202dest=$1 203shift 204 205 206if [ "$dest_dir" = yes -a ! -d $dest ]; then 207 echo "no directory $dest" >&2 208 exit 1 209fi 210 211for f in $files 212do 213 b=`basename $f` 214 if [ -d $dest ]; then 215 t=$dest/$b 216 else 217 t=$dest 218 fi 219 $newer $f $t || continue 220 $compare $f $t || continue 221 [ -f $t ] && { mv -f $t $t.old || exit 1; } 222 { cp $CP_p $f $t && Setem $t; } || exit 1 223done 224exit 0 225