198875883SSimon J. Gerraty#!/bin/sh 298875883SSimon J. Gerraty 33955d011SMarcel Moolenaar# NAME: 43955d011SMarcel Moolenaar# install.sh - portable version of install(1) 53955d011SMarcel Moolenaar# 63955d011SMarcel Moolenaar# SYNOPSIS: 73955d011SMarcel Moolenaar# install [-CNcs] [-f flags] [-i errs] [-o owner] [-g group] [-m mode] file1 file2 ... 83955d011SMarcel Moolenaar# install -d [-i errs] [-o owner] [-g group] [-m mode] directory ... 93955d011SMarcel Moolenaar# 103955d011SMarcel Moolenaar# DESCRIPTION: 113955d011SMarcel Moolenaar# Compatible with BSD install(1). Except that '-c' is always 123955d011SMarcel Moolenaar# true and we always move an already installed target aside as 133955d011SMarcel Moolenaar# this is important on many systems. Recent BSD install(1) 143955d011SMarcel Moolenaar# versions have a '-b' option for this. 153955d011SMarcel Moolenaar# 163955d011SMarcel Moolenaar# 173955d011SMarcel Moolenaar# OPTIONS: 183955d011SMarcel Moolenaar# -b move previous target file aside (always true). 193955d011SMarcel Moolenaar# 203955d011SMarcel Moolenaar# -B "suffix" 213955d011SMarcel Moolenaar# use "suffix" instead of .old for saving existing target. 223955d011SMarcel Moolenaar# 233955d011SMarcel Moolenaar# -c copy rather than move the file into place (always true). 243955d011SMarcel Moolenaar# 253955d011SMarcel Moolenaar# -C compare. Only install if target is missing or 263955d011SMarcel Moolenaar# different. 273955d011SMarcel Moolenaar# 283955d011SMarcel Moolenaar# -N newer. Only install if target is missing or older. 293955d011SMarcel Moolenaar# 303955d011SMarcel Moolenaar# -s strip target 313955d011SMarcel Moolenaar# 323955d011SMarcel Moolenaar# -o "owner" 333955d011SMarcel Moolenaar# make target owned by "owner" 343955d011SMarcel Moolenaar# 353955d011SMarcel Moolenaar# -g "group" 363955d011SMarcel Moolenaar# make target group owned by "group" 373955d011SMarcel Moolenaar# 383955d011SMarcel Moolenaar# -m "mode" 393955d011SMarcel Moolenaar# set permissions to "mode" 403955d011SMarcel Moolenaar# 413955d011SMarcel Moolenaar# -f "flags" 423955d011SMarcel Moolenaar# Pass "flags" onto chflags(1) 433955d011SMarcel Moolenaar# 443955d011SMarcel Moolenaar# -i "errs" 453955d011SMarcel Moolenaar# Ignore errors from steps indicated by "errs" (``s,o,g,m''). 463955d011SMarcel Moolenaar# 473955d011SMarcel Moolenaar# BUGS: 483955d011SMarcel Moolenaar# The '-i' option is to save your sanity when 'bsd.prog.mk' 493955d011SMarcel Moolenaar# insists on haveing a '-o' "owner" option which is doomed to 5098875883SSimon J. Gerraty# fail on many systems. We ignore '-b' and '-c' options. 513955d011SMarcel Moolenaar# 523955d011SMarcel Moolenaar# AUTHOR: 53dc1b8c9aSSimon J. Gerraty# Simon J. Gerraty <sjg@crufty.net> 543955d011SMarcel Moolenaar# 553955d011SMarcel Moolenaar 563955d011SMarcel Moolenaar# RCSid: 57*c60f6422SSimon J. Gerraty# $Id: install-sh,v 1.27 2025/08/09 22:42:24 sjg Exp $ 583955d011SMarcel Moolenaar# 59dc1b8c9aSSimon J. Gerraty# @(#) Copyright (c) 1993-2023 Simon J. Gerraty 603955d011SMarcel Moolenaar# 61*c60f6422SSimon J. Gerraty# SPDX-License-Identifier: BSD-2-Clause 623955d011SMarcel Moolenaar# 633955d011SMarcel Moolenaar# Please send copies of changes and bug-fixes to: 64dc1b8c9aSSimon J. Gerraty# sjg@crufty.net 653955d011SMarcel Moolenaar# 663955d011SMarcel Moolenaar 673955d011SMarcel Moolenaarset -- `getopt B:bpxCNcsdo:g:m:i:f: $*` 683955d011SMarcel Moolenaar 693955d011SMarcel MoolenaarMydir=`dirname $0` 703955d011SMarcel Moolenaar[ -s $Mydir/.installrc ] && . $Mydir/.installrc 713955d011SMarcel Moolenaar 7298875883SSimon J. GerratyOLD_EXT=.old 733955d011SMarcel Moolenaarowner=: 743955d011SMarcel Moolenaargroup=: 753955d011SMarcel Moolenaarmode=: 76dc1b8c9aSSimon J. GerratyMODE=0 773955d011SMarcel Moolenaarstrip=: 783955d011SMarcel Moolenaarmkdirs= 793955d011SMarcel Moolenaarcompare=: 803955d011SMarcel Moolenaarnewer=: 813955d011SMarcel Moolenaarchflags=: 82dc1b8c9aSSimon J. GerratyLS_1= 83dc1b8c9aSSimon J. GerratyCP_p= 843955d011SMarcel Moolenaar 85dc1b8c9aSSimon J. Gerratywhile : 863955d011SMarcel Moolenaardo 87dc1b8c9aSSimon J. Gerraty case "$1" in 883955d011SMarcel Moolenaar --) shift; break;; 8998875883SSimon J. Gerraty -[bc]) ;; # ignore 90dc1b8c9aSSimon J. Gerraty -p) CP_p=-p;; 913955d011SMarcel Moolenaar -x) set -x;; 923955d011SMarcel Moolenaar -B) OLD_EXT=$2; shift;; 933955d011SMarcel Moolenaar -C) compare=Different;; 943955d011SMarcel Moolenaar -N) newer=Newer; 953955d011SMarcel Moolenaar # check if /bin/ls supports -1 96dc1b8c9aSSimon J. Gerraty 'ls' -1 $0 > /dev/null 2>&1 && LS_1=1 973955d011SMarcel Moolenaar ;; 983955d011SMarcel Moolenaar -o) owner="${CHOWN:-chown} $2 "; shift;; 993955d011SMarcel Moolenaar -g) group="${CHGRP:-chgrp} $2 "; shift;; 100dc1b8c9aSSimon J. Gerraty -m) MODE=$2 mode="${CHMOD:-chmod} $2 "; shift;; 1013955d011SMarcel Moolenaar -s) strip=${STRIP:-strip};; 1023955d011SMarcel Moolenaar -d) mkdirs="mkdir -p";; 1033955d011SMarcel Moolenaar -i) ignore_err="$ignore_err$2"; shift;; 1043955d011SMarcel Moolenaar -f) chflags="${CHFLAGS:-chflags} $2 "; shift;; 105dc1b8c9aSSimon J. Gerraty *) break;; 1063955d011SMarcel Moolenaar esac 1073955d011SMarcel Moolenaar shift 1083955d011SMarcel Moolenaardone 1093955d011SMarcel Moolenaar 1103955d011SMarcel MoolenaarNewer() { 111dc1b8c9aSSimon J. Gerraty n=`'ls' -t$LS_1 $* 2> /dev/null | head -1` 1123955d011SMarcel Moolenaar [ $1 = $n ] 1133955d011SMarcel Moolenaar} 1143955d011SMarcel Moolenaar 1153955d011SMarcel MoolenaarDifferent() { 1163955d011SMarcel Moolenaar cmp -s $* 1173955d011SMarcel Moolenaar [ $? != 0 ] 1183955d011SMarcel Moolenaar} 1193955d011SMarcel Moolenaar 1203955d011SMarcel MoolenaarErr() { 1213955d011SMarcel Moolenaar case "$ignore_err" in 1223955d011SMarcel Moolenaar *$1*) ;; 1233955d011SMarcel Moolenaar *) exit 1;; 1243955d011SMarcel Moolenaar esac 1253955d011SMarcel Moolenaar} 1263955d011SMarcel Moolenaar 1273955d011SMarcel MoolenaarSetem() { 1283955d011SMarcel Moolenaar # the order is important 1293955d011SMarcel Moolenaar if [ ! -d $1 ]; then 1303955d011SMarcel Moolenaar $strip $1 || Err s 1313955d011SMarcel Moolenaar fi 1323955d011SMarcel Moolenaar $group $1 || Err g 1333955d011SMarcel Moolenaar $owner $1 || Err o 1343955d011SMarcel Moolenaar $mode $1 || Err m 1353955d011SMarcel Moolenaar $chflags $1 || Err f 1363955d011SMarcel Moolenaar return 0 1373955d011SMarcel Moolenaar} 1383955d011SMarcel Moolenaar 1393955d011SMarcel Moolenaar# a bug in HP-UX's /bin/sh, means we need to re-set $* 1403955d011SMarcel Moolenaar# after any calls to add_path() 1413955d011SMarcel Moolenaarargs="$*" 1423955d011SMarcel Moolenaar 143dc1b8c9aSSimon J. Gerratyadd_path () { 144dc1b8c9aSSimon J. Gerraty test -d $1 || return 145dc1b8c9aSSimon J. Gerraty case ":$PATH:" in 146dc1b8c9aSSimon J. Gerraty *:$1:*) return;; 147dc1b8c9aSSimon J. Gerraty esac 148dc1b8c9aSSimon J. Gerraty PATH=$PATH:$1 149dc1b8c9aSSimon J. Gerraty} 150dc1b8c9aSSimon J. Gerraty 1513955d011SMarcel Moolenaaradd_path /sbin 1523955d011SMarcel Moolenaaradd_path /usr/sbin 1533955d011SMarcel Moolenaar 154dc1b8c9aSSimon J. Gerratycase "$owner" in 155dc1b8c9aSSimon J. Gerraty:) ;; 15698875883SSimon J. Gerraty*) # some systems put chown in odd places 157dc1b8c9aSSimon J. Gerraty add_path /etc 158dc1b8c9aSSimon J. Gerraty add_path /usr/etc 159dc1b8c9aSSimon J. Gerraty ;; 160dc1b8c9aSSimon J. Gerratyesac 161dc1b8c9aSSimon J. Gerraty 1623955d011SMarcel Moolenaar# restore saved $* 1633955d011SMarcel Moolenaarset -- $args 1643955d011SMarcel Moolenaar 1653955d011SMarcel Moolenaar# make directories if needed 1663955d011SMarcel Moolenaar# and ensure mode etc are as desired 1673955d011SMarcel Moolenaarif [ "$mkdirs" ]; then 168dc1b8c9aSSimon J. Gerraty case "$MODE" in 169dc1b8c9aSSimon J. Gerraty [1-7]*) 170dc1b8c9aSSimon J. Gerraty # make sure umask is compatible 171dc1b8c9aSSimon J. Gerraty case "$MODE" in 172dc1b8c9aSSimon J. Gerraty ????*) MODE=`echo $MODE | sed 's,.*\(...\)$,\1,'`;; 173dc1b8c9aSSimon J. Gerraty esac 174dc1b8c9aSSimon J. Gerraty umask `expr 0777 - 0$MODE | 175dc1b8c9aSSimon J. Gerraty sed 's,^,000,;s,^.*\(...\)$,\1,'`;; 176dc1b8c9aSSimon J. Gerraty esac 1773955d011SMarcel Moolenaar for d in $* 1783955d011SMarcel Moolenaar do 1793955d011SMarcel Moolenaar [ ! -d $d ] && $mkdirs $d 1803955d011SMarcel Moolenaar Setem $d 1813955d011SMarcel Moolenaar done 1823955d011SMarcel Moolenaar exit 0 # that's all we do 1833955d011SMarcel Moolenaarfi 1843955d011SMarcel Moolenaar 1853955d011SMarcel Moolenaar# install files 18698875883SSimon J. Gerratyif [ $# -eq 1 ]; then 1873955d011SMarcel Moolenaar echo "what should I do with $*?" >&2 1883955d011SMarcel Moolenaar exit 1 1893955d011SMarcel Moolenaarfi 1903955d011SMarcel Moolenaar 1913955d011SMarcel Moolenaar# get list of files 19298875883SSimon J. Gerratyfiles= 1933955d011SMarcel Moolenaarwhile [ $# -gt 1 ] 1943955d011SMarcel Moolenaardo 19598875883SSimon J. Gerraty test "x$files" = x || dest_dir=yes 1963955d011SMarcel Moolenaar files="$files $1" 1973955d011SMarcel Moolenaar shift 1983955d011SMarcel Moolenaardone 1993955d011SMarcel Moolenaar# last one is dest 2003955d011SMarcel Moolenaardest=$1 2013955d011SMarcel Moolenaarshift 2023955d011SMarcel Moolenaar 2033955d011SMarcel Moolenaarif [ "$dest_dir" = yes -a ! -d $dest ]; then 2043955d011SMarcel Moolenaar echo "no directory $dest" >&2 2053955d011SMarcel Moolenaar exit 1 2063955d011SMarcel Moolenaarfi 2073955d011SMarcel Moolenaar 2083955d011SMarcel Moolenaarfor f in $files 2093955d011SMarcel Moolenaardo 2103955d011SMarcel Moolenaar b=`basename $f` 2113955d011SMarcel Moolenaar if [ -d $dest ]; then 2123955d011SMarcel Moolenaar t=$dest/$b 2133955d011SMarcel Moolenaar else 2143955d011SMarcel Moolenaar t=$dest 2153955d011SMarcel Moolenaar fi 2163955d011SMarcel Moolenaar $newer $f $t || continue 2173955d011SMarcel Moolenaar $compare $f $t || continue 21898875883SSimon J. Gerraty [ -f $t ] && { mv -f $t $t$OLD_EXT || exit 1; } 219dc1b8c9aSSimon J. Gerraty { cp $CP_p $f $t && Setem $t; } || exit 1 2203955d011SMarcel Moolenaardone 2213955d011SMarcel Moolenaarexit 0 222