159243Sobrien#!/bin/sh 259243Sobrien# install - install a program, script, or datafile 3145479Smp 4231990Smpscriptversion=2009-04-28.21; # UTC 5145479Smp 6145479Smp# This originates from X11R5 (mit/util/scripts/install.sh), which was 7145479Smp# later released in X11R6 (xc/config/util/install.sh) with the 8145479Smp# following copyright and license. 959243Sobrien# 10145479Smp# Copyright (C) 1994 X Consortium 1159243Sobrien# 12145479Smp# Permission is hereby granted, free of charge, to any person obtaining a copy 13145479Smp# of this software and associated documentation files (the "Software"), to 14145479Smp# deal in the Software without restriction, including without limitation the 15145479Smp# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16145479Smp# sell copies of the Software, and to permit persons to whom the Software is 17145479Smp# furnished to do so, subject to the following conditions: 1859243Sobrien# 19145479Smp# The above copyright notice and this permission notice shall be included in 20145479Smp# all copies or substantial portions of the Software. 21145479Smp# 22145479Smp# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23145479Smp# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24145479Smp# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25145479Smp# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26145479Smp# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27145479Smp# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28145479Smp# 29145479Smp# Except as contained in this notice, the name of the X Consortium shall not 30145479Smp# be used in advertising or otherwise to promote the sale, use or other deal- 31145479Smp# ings in this Software without prior written authorization from the X Consor- 32145479Smp# tium. 33145479Smp# 34145479Smp# 35145479Smp# FSF changes to this file are in the public domain. 36145479Smp# 3759243Sobrien# Calling this script install-sh is preferred over install.sh, to prevent 3859243Sobrien# `make' implicit rules from creating a file called install from it 3959243Sobrien# when there is no Makefile. 4059243Sobrien# 4159243Sobrien# This script is compatible with the BSD install script, but was written 42231990Smp# from scratch. 4359243Sobrien 44231990Smpnl=' 45231990Smp' 46231990SmpIFS=" "" $nl" 47231990Smp 4859243Sobrien# set DOITPROG to echo to test this script 4959243Sobrien 5059243Sobrien# Don't use :- since 4.3BSD and earlier shells don't like it. 51231990Smpdoit=${DOITPROG-} 52231990Smpif test -z "$doit"; then 53231990Smp doit_exec=exec 54231990Smpelse 55231990Smp doit_exec=$doit 56231990Smpfi 5759243Sobrien 58231990Smp# Put in absolute file names if you don't have them in your path; 59231990Smp# or use environment vars. 6059243Sobrien 61231990Smpchgrpprog=${CHGRPPROG-chgrp} 62231990Smpchmodprog=${CHMODPROG-chmod} 63231990Smpchownprog=${CHOWNPROG-chown} 64231990Smpcmpprog=${CMPPROG-cmp} 65231990Smpcpprog=${CPPROG-cp} 66231990Smpmkdirprog=${MKDIRPROG-mkdir} 67231990Smpmvprog=${MVPROG-mv} 68231990Smprmprog=${RMPROG-rm} 69231990Smpstripprog=${STRIPPROG-strip} 7059243Sobrien 71231990Smpposix_glob='?' 72231990Smpinitialize_posix_glob=' 73231990Smp test "$posix_glob" != "?" || { 74231990Smp if (set -f) 2>/dev/null; then 75231990Smp posix_glob= 76231990Smp else 77231990Smp posix_glob=: 78231990Smp fi 79231990Smp } 80231990Smp' 81231990Smp 82231990Smpposix_mkdir= 83231990Smp 84231990Smp# Desired mode of installed file. 85231990Smpmode=0755 86231990Smp 87231990Smpchgrpcmd= 88231990Smpchmodcmd=$chmodprog 89145479Smpchowncmd= 90231990Smpmvcmd=$mvprog 91231990Smprmcmd="$rmprog -f" 92145479Smpstripcmd= 93231990Smp 94145479Smpsrc= 95145479Smpdst= 96145479Smpdir_arg= 97231990Smpdst_arg= 98231990Smp 99231990Smpcopy_on_change=false 100145479Smpno_target_directory= 10159243Sobrien 102231990Smpusage="\ 103231990SmpUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 104145479Smp or: $0 [OPTION]... SRCFILES... DIRECTORY 105145479Smp or: $0 [OPTION]... -t DIRECTORY SRCFILES... 106145479Smp or: $0 [OPTION]... -d DIRECTORIES... 10759243Sobrien 108145479SmpIn the 1st form, copy SRCFILE to DSTFILE. 109145479SmpIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 110145479SmpIn the 4th, create DIRECTORIES. 11159243Sobrien 112145479SmpOptions: 113231990Smp --help display this help and exit. 114231990Smp --version display version info and exit. 11559243Sobrien 116231990Smp -c (ignored) 117231990Smp -C install only if different (preserve the last data modification time) 118231990Smp -d create directories instead of installing files. 119231990Smp -g GROUP $chgrpprog installed files to GROUP. 120231990Smp -m MODE $chmodprog installed files to MODE. 121231990Smp -o USER $chownprog installed files to USER. 122231990Smp -s $stripprog installed files. 123231990Smp -t DIRECTORY install into DIRECTORY. 124231990Smp -T report an error if DSTFILE is a directory. 125231990Smp 126145479SmpEnvironment variables override the default commands: 127231990Smp CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 128231990Smp RMPROG STRIPPROG 129145479Smp" 13059243Sobrien 131231990Smpwhile test $# -ne 0; do 132145479Smp case $1 in 133231990Smp -c) ;; 13459243Sobrien 135231990Smp -C) copy_on_change=true;; 13659243Sobrien 137231990Smp -d) dir_arg=true;; 138231990Smp 139145479Smp -g) chgrpcmd="$chgrpprog $2" 140231990Smp shift;; 14159243Sobrien 142231990Smp --help) echo "$usage"; exit $?;; 14359243Sobrien 144231990Smp -m) mode=$2 145231990Smp case $mode in 146231990Smp *' '* | *' '* | *' 147231990Smp'* | *'*'* | *'?'* | *'['*) 148231990Smp echo "$0: invalid mode: $mode" >&2 149231990Smp exit 1;; 150231990Smp esac 151231990Smp shift;; 15259243Sobrien 153145479Smp -o) chowncmd="$chownprog $2" 154231990Smp shift;; 15559243Sobrien 156231990Smp -s) stripcmd=$stripprog;; 15759243Sobrien 158231990Smp -t) dst_arg=$2 159231990Smp shift;; 16059243Sobrien 161231990Smp -T) no_target_directory=true;; 16259243Sobrien 163231990Smp --version) echo "$0 $scriptversion"; exit $?;; 16459243Sobrien 165231990Smp --) shift 166145479Smp break;; 167231990Smp 168231990Smp -*) echo "$0: invalid option: $1" >&2 169231990Smp exit 1;; 170231990Smp 171231990Smp *) break;; 172145479Smp esac 173231990Smp shift 174145479Smpdone 175145479Smp 176231990Smpif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 177231990Smp # When -d is used, all remaining arguments are directories to create. 178231990Smp # When -t is used, the destination is already specified. 179231990Smp # Otherwise, the last argument is the destination. Remove it from $@. 180231990Smp for arg 181231990Smp do 182231990Smp if test -n "$dst_arg"; then 183231990Smp # $@ is not empty: it contains at least $arg. 184231990Smp set fnord "$@" "$dst_arg" 185231990Smp shift # fnord 186231990Smp fi 187231990Smp shift # arg 188231990Smp dst_arg=$arg 189231990Smp done 190231990Smpfi 191231990Smp 192231990Smpif test $# -eq 0; then 193145479Smp if test -z "$dir_arg"; then 194145479Smp echo "$0: no input file specified." >&2 195145479Smp exit 1 196145479Smp fi 197145479Smp # It's OK to call `install-sh -d' without argument. 198145479Smp # This can happen when creating conditional directories. 199145479Smp exit 0 20059243Sobrienfi 20159243Sobrien 202231990Smpif test -z "$dir_arg"; then 203231990Smp trap '(exit $?); exit' 1 2 13 15 204231990Smp 205231990Smp # Set umask so as not to create temps with too-generous modes. 206231990Smp # However, 'strip' requires both read and write access to temps. 207231990Smp case $mode in 208231990Smp # Optimize common cases. 209231990Smp *644) cp_umask=133;; 210231990Smp *755) cp_umask=22;; 211231990Smp 212231990Smp *[0-7]) 213231990Smp if test -z "$stripcmd"; then 214231990Smp u_plus_rw= 215231990Smp else 216231990Smp u_plus_rw='% 200' 217231990Smp fi 218231990Smp cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 219231990Smp *) 220231990Smp if test -z "$stripcmd"; then 221231990Smp u_plus_rw= 222231990Smp else 223231990Smp u_plus_rw=,u+rw 224231990Smp fi 225231990Smp cp_umask=$mode$u_plus_rw;; 226231990Smp esac 227231990Smpfi 228231990Smp 229145479Smpfor src 230145479Smpdo 231145479Smp # Protect names starting with `-'. 232145479Smp case $src in 233231990Smp -*) src=./$src;; 234145479Smp esac 23559243Sobrien 236145479Smp if test -n "$dir_arg"; then 237145479Smp dst=$src 238231990Smp dstdir=$dst 239231990Smp test -d "$dstdir" 240231990Smp dstdir_status=$? 241231990Smp else 24259243Sobrien 243145479Smp # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 244145479Smp # might cause directories to be created, which would be especially bad 245145479Smp # if $src (and thus $dsttmp) contains '*'. 246145479Smp if test ! -f "$src" && test ! -d "$src"; then 247145479Smp echo "$0: $src does not exist." >&2 248145479Smp exit 1 249145479Smp fi 25059243Sobrien 251231990Smp if test -z "$dst_arg"; then 252145479Smp echo "$0: no destination specified." >&2 253145479Smp exit 1 254145479Smp fi 25559243Sobrien 256231990Smp dst=$dst_arg 257145479Smp # Protect names starting with `-'. 258145479Smp case $dst in 259231990Smp -*) dst=./$dst;; 260145479Smp esac 26159243Sobrien 262145479Smp # If destination is a directory, append the input filename; won't work 263145479Smp # if double slashes aren't ignored. 264145479Smp if test -d "$dst"; then 265145479Smp if test -n "$no_target_directory"; then 266231990Smp echo "$0: $dst_arg: Is a directory" >&2 267145479Smp exit 1 268145479Smp fi 269231990Smp dstdir=$dst 270231990Smp dst=$dstdir/`basename "$src"` 271231990Smp dstdir_status=0 272231990Smp else 273231990Smp # Prefer dirname, but fall back on a substitute if dirname fails. 274231990Smp dstdir=` 275231990Smp (dirname "$dst") 2>/dev/null || 276231990Smp expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ 277231990Smp X"$dst" : 'X\(//\)[^/]' \| \ 278231990Smp X"$dst" : 'X\(//\)$' \| \ 279231990Smp X"$dst" : 'X\(/\)' \| . 2>/dev/null || 280231990Smp echo X"$dst" | 281231990Smp sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ 282231990Smp s//\1/ 283231990Smp q 284231990Smp } 285231990Smp /^X\(\/\/\)[^/].*/{ 286231990Smp s//\1/ 287231990Smp q 288231990Smp } 289231990Smp /^X\(\/\/\)$/{ 290231990Smp s//\1/ 291231990Smp q 292231990Smp } 293231990Smp /^X\(\/\).*/{ 294231990Smp s//\1/ 295231990Smp q 296231990Smp } 297231990Smp s/.*/./; q' 298231990Smp ` 299231990Smp 300231990Smp test -d "$dstdir" 301231990Smp dstdir_status=$? 302145479Smp fi 303145479Smp fi 30459243Sobrien 305231990Smp obsolete_mkdir_used=false 30659243Sobrien 307231990Smp if test $dstdir_status != 0; then 308231990Smp case $posix_mkdir in 309231990Smp '') 310231990Smp # Create intermediate dirs using mode 755 as modified by the umask. 311231990Smp # This is like FreeBSD 'install' as of 1997-10-28. 312231990Smp umask=`umask` 313231990Smp case $stripcmd.$umask in 314231990Smp # Optimize common cases. 315231990Smp *[2367][2367]) mkdir_umask=$umask;; 316231990Smp .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 31759243Sobrien 318231990Smp *[0-7]) 319231990Smp mkdir_umask=`expr $umask + 22 \ 320231990Smp - $umask % 100 % 40 + $umask % 20 \ 321231990Smp - $umask % 10 % 4 + $umask % 2 322231990Smp `;; 323231990Smp *) mkdir_umask=$umask,go-w;; 324231990Smp esac 32559243Sobrien 326231990Smp # With -d, create the new directory with the user-specified mode. 327231990Smp # Otherwise, rely on $mkdir_umask. 328231990Smp if test -n "$dir_arg"; then 329231990Smp mkdir_mode=-m$mode 330231990Smp else 331231990Smp mkdir_mode= 332231990Smp fi 33359243Sobrien 334231990Smp posix_mkdir=false 335231990Smp case $umask in 336231990Smp *[123567][0-7][0-7]) 337231990Smp # POSIX mkdir -p sets u+wx bits regardless of umask, which 338231990Smp # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 339231990Smp ;; 340231990Smp *) 341231990Smp tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 342231990Smp trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 34359243Sobrien 344231990Smp if (umask $mkdir_umask && 345231990Smp exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 346231990Smp then 347231990Smp if test -z "$dir_arg" || { 348231990Smp # Check for POSIX incompatibilities with -m. 349231990Smp # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 350231990Smp # other-writeable bit of parent directory when it shouldn't. 351231990Smp # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 352231990Smp ls_ld_tmpdir=`ls -ld "$tmpdir"` 353231990Smp case $ls_ld_tmpdir in 354231990Smp d????-?r-*) different_mode=700;; 355231990Smp d????-?--*) different_mode=755;; 356231990Smp *) false;; 357231990Smp esac && 358231990Smp $mkdirprog -m$different_mode -p -- "$tmpdir" && { 359231990Smp ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 360231990Smp test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 361231990Smp } 362231990Smp } 363231990Smp then posix_mkdir=: 364231990Smp fi 365231990Smp rmdir "$tmpdir/d" "$tmpdir" 366231990Smp else 367231990Smp # Remove any dirs left behind by ancient mkdir implementations. 368231990Smp rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 369231990Smp fi 370231990Smp trap '' 0;; 371231990Smp esac;; 372231990Smp esac 373231990Smp 374231990Smp if 375231990Smp $posix_mkdir && ( 376231990Smp umask $mkdir_umask && 377231990Smp $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 378231990Smp ) 379231990Smp then : 380231990Smp else 381231990Smp 382231990Smp # The umask is ridiculous, or mkdir does not conform to POSIX, 383231990Smp # or it failed possibly due to a race condition. Create the 384231990Smp # directory the slow way, step by step, checking for races as we go. 385231990Smp 386231990Smp case $dstdir in 387231990Smp /*) prefix='/';; 388231990Smp -*) prefix='./';; 389231990Smp *) prefix='';; 390231990Smp esac 391231990Smp 392231990Smp eval "$initialize_posix_glob" 393231990Smp 394231990Smp oIFS=$IFS 395231990Smp IFS=/ 396231990Smp $posix_glob set -f 397231990Smp set fnord $dstdir 398145479Smp shift 399231990Smp $posix_glob set +f 400231990Smp IFS=$oIFS 401231990Smp 402231990Smp prefixes= 403231990Smp 404231990Smp for d 405231990Smp do 406231990Smp test -z "$d" && continue 407231990Smp 408231990Smp prefix=$prefix$d 409231990Smp if test -d "$prefix"; then 410231990Smp prefixes= 411231990Smp else 412231990Smp if $posix_mkdir; then 413231990Smp (umask=$mkdir_umask && 414231990Smp $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 415231990Smp # Don't fail if two instances are running concurrently. 416231990Smp test -d "$prefix" || exit 1 417231990Smp else 418231990Smp case $prefix in 419231990Smp *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 420231990Smp *) qprefix=$prefix;; 421231990Smp esac 422231990Smp prefixes="$prefixes '$qprefix'" 423231990Smp fi 424231990Smp fi 425231990Smp prefix=$prefix/ 426231990Smp done 427231990Smp 428231990Smp if test -n "$prefixes"; then 429231990Smp # Don't fail if two instances are running concurrently. 430231990Smp (umask $mkdir_umask && 431231990Smp eval "\$doit_exec \$mkdirprog $prefixes") || 432231990Smp test -d "$dstdir" || exit 1 433231990Smp obsolete_mkdir_used=true 434145479Smp fi 435231990Smp fi 436145479Smp fi 43759243Sobrien 438145479Smp if test -n "$dir_arg"; then 439231990Smp { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 440231990Smp { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 441231990Smp { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 442231990Smp test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 443145479Smp else 44459243Sobrien 445145479Smp # Make a couple of temp file names in the proper directory. 446145479Smp dsttmp=$dstdir/_inst.$$_ 447145479Smp rmtmp=$dstdir/_rm.$$_ 44859243Sobrien 449145479Smp # Trap to clean up those temp files at exit. 450145479Smp trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 45159243Sobrien 452145479Smp # Copy the file name to the temp name. 453231990Smp (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 45459243Sobrien 455145479Smp # and set any options; do chmod last to preserve setuid bits. 456145479Smp # 457145479Smp # If any of these fail, we abort the whole thing. If we want to 458145479Smp # ignore errors from any of these, just make sure not to ignore 459145479Smp # errors from the above "$doit $cpprog $src $dsttmp" command. 460145479Smp # 461231990Smp { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 462231990Smp { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 463231990Smp { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 464231990Smp { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 46559243Sobrien 466231990Smp # If -C, don't bother to copy if it wouldn't change the file. 467231990Smp if $copy_on_change && 468231990Smp old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 469231990Smp new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 47059243Sobrien 471231990Smp eval "$initialize_posix_glob" && 472231990Smp $posix_glob set -f && 473231990Smp set X $old && old=:$2:$4:$5:$6 && 474231990Smp set X $new && new=:$2:$4:$5:$6 && 475231990Smp $posix_glob set +f && 47659243Sobrien 477231990Smp test "$old" = "$new" && 478231990Smp $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 479231990Smp then 480231990Smp rm -f "$dsttmp" 481231990Smp else 482231990Smp # Rename the file to the real destination. 483231990Smp $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 484231990Smp 485231990Smp # The rename failed, perhaps because mv can't rename something else 486231990Smp # to itself, or perhaps because mv is so ancient that it does not 487231990Smp # support -f. 488231990Smp { 489231990Smp # Now remove or move aside any old file at destination location. 490231990Smp # We try this two ways since rm can't unlink itself on some 491231990Smp # systems and the destination file might be busy for other 492231990Smp # reasons. In this case, the final cleanup might fail but the new 493231990Smp # file should still install successfully. 494231990Smp { 495231990Smp test ! -f "$dst" || 496231990Smp $doit $rmcmd -f "$dst" 2>/dev/null || 497231990Smp { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 498231990Smp { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 499231990Smp } || 500231990Smp { echo "$0: cannot unlink or rename $dst" >&2 501231990Smp (exit 1); exit 1 502231990Smp } 503231990Smp } && 504231990Smp 505231990Smp # Now rename the file to the real destination. 506231990Smp $doit $mvcmd "$dsttmp" "$dst" 507231990Smp } 508231990Smp fi || exit 1 509231990Smp 510231990Smp trap '' 0 511231990Smp fi 512145479Smpdone 51359243Sobrien 514145479Smp# Local variables: 515145479Smp# eval: (add-hook 'write-file-hooks 'time-stamp) 516145479Smp# time-stamp-start: "scriptversion=" 517145479Smp# time-stamp-format: "%:y-%02m-%02d.%02H" 518231990Smp# time-stamp-time-zone: "UTC" 519231990Smp# time-stamp-end: "; # UTC" 520145479Smp# End: 521