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# SPDX-License-Identifier: BSD-2-Clause 57# 58# RCSid: 59# $Id: install-sh,v 1.26 2024/02/17 17:26:57 sjg Exp $ 60# 61# @(#) Copyright (c) 1993-2023 Simon J. Gerraty 62# 63# This file is provided in the hope that it will 64# be of use. There is absolutely NO WARRANTY. 65# Permission to copy, redistribute or otherwise 66# use this file is hereby granted provided that 67# the above copyright notice and this notice are 68# left intact. 69# 70# Please send copies of changes and bug-fixes to: 71# sjg@crufty.net 72# 73 74set -- `getopt B:bpxCNcsdo:g:m:i:f: $*` 75 76Mydir=`dirname $0` 77[ -s $Mydir/.installrc ] && . $Mydir/.installrc 78 79OLD_EXT=.old 80owner=: 81group=: 82mode=: 83MODE=0 84strip=: 85mkdirs= 86compare=: 87newer=: 88chflags=: 89LS_1= 90CP_p= 91 92while : 93do 94 case "$1" in 95 --) shift; break;; 96 -[bc]) ;; # ignore 97 -p) CP_p=-p;; 98 -x) set -x;; 99 -B) OLD_EXT=$2; shift;; 100 -C) compare=Different;; 101 -N) newer=Newer; 102 # check if /bin/ls supports -1 103 'ls' -1 $0 > /dev/null 2>&1 && LS_1=1 104 ;; 105 -o) owner="${CHOWN:-chown} $2 "; shift;; 106 -g) group="${CHGRP:-chgrp} $2 "; shift;; 107 -m) MODE=$2 mode="${CHMOD:-chmod} $2 "; shift;; 108 -s) strip=${STRIP:-strip};; 109 -d) mkdirs="mkdir -p";; 110 -i) ignore_err="$ignore_err$2"; shift;; 111 -f) chflags="${CHFLAGS:-chflags} $2 "; shift;; 112 *) break;; 113 esac 114 shift 115done 116 117Newer() { 118 n=`'ls' -t$LS_1 $* 2> /dev/null | head -1` 119 [ $1 = $n ] 120} 121 122Different() { 123 cmp -s $* 124 [ $? != 0 ] 125} 126 127Err() { 128 case "$ignore_err" in 129 *$1*) ;; 130 *) exit 1;; 131 esac 132} 133 134Setem() { 135 # the order is important 136 if [ ! -d $1 ]; then 137 $strip $1 || Err s 138 fi 139 $group $1 || Err g 140 $owner $1 || Err o 141 $mode $1 || Err m 142 $chflags $1 || Err f 143 return 0 144} 145 146# a bug in HP-UX's /bin/sh, means we need to re-set $* 147# after any calls to add_path() 148args="$*" 149 150add_path () { 151 test -d $1 || return 152 case ":$PATH:" in 153 *:$1:*) return;; 154 esac 155 PATH=$PATH:$1 156} 157 158add_path /sbin 159add_path /usr/sbin 160 161case "$owner" in 162:) ;; 163*) # some systems put chown in odd places 164 add_path /etc 165 add_path /usr/etc 166 ;; 167esac 168 169# restore saved $* 170set -- $args 171 172# make directories if needed 173# and ensure mode etc are as desired 174if [ "$mkdirs" ]; then 175 case "$MODE" in 176 [1-7]*) 177 # make sure umask is compatible 178 case "$MODE" in 179 ????*) MODE=`echo $MODE | sed 's,.*\(...\)$,\1,'`;; 180 esac 181 umask `expr 0777 - 0$MODE | 182 sed 's,^,000,;s,^.*\(...\)$,\1,'`;; 183 esac 184 for d in $* 185 do 186 [ ! -d $d ] && $mkdirs $d 187 Setem $d 188 done 189 exit 0 # that's all we do 190fi 191 192# install files 193if [ $# -eq 1 ]; then 194 echo "what should I do with $*?" >&2 195 exit 1 196fi 197 198# get list of files 199files= 200while [ $# -gt 1 ] 201do 202 test "x$files" = x || dest_dir=yes 203 files="$files $1" 204 shift 205done 206# last one is dest 207dest=$1 208shift 209 210if [ "$dest_dir" = yes -a ! -d $dest ]; then 211 echo "no directory $dest" >&2 212 exit 1 213fi 214 215for f in $files 216do 217 b=`basename $f` 218 if [ -d $dest ]; then 219 t=$dest/$b 220 else 221 t=$dest 222 fi 223 $newer $f $t || continue 224 $compare $f $t || continue 225 [ -f $t ] && { mv -f $t $t$OLD_EXT || exit 1; } 226 { cp $CP_p $f $t && Setem $t; } || exit 1 227done 228exit 0 229