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