1238104Sdes#!/bin/sh 2238104Sdes# install - install a program, script, or datafile 3238104Sdes 4238104Sdesscriptversion=2009-04-28.21; # UTC 5238104Sdes 6238104Sdes# This originates from X11R5 (mit/util/scripts/install.sh), which was 7238104Sdes# later released in X11R6 (xc/config/util/install.sh) with the 8238104Sdes# following copyright and license. 9238104Sdes# 10238104Sdes# Copyright (C) 1994 X Consortium 11238104Sdes# 12238104Sdes# Permission is hereby granted, free of charge, to any person obtaining a copy 13238104Sdes# of this software and associated documentation files (the "Software"), to 14238104Sdes# deal in the Software without restriction, including without limitation the 15238104Sdes# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16238104Sdes# sell copies of the Software, and to permit persons to whom the Software is 17238104Sdes# furnished to do so, subject to the following conditions: 18238104Sdes# 19238104Sdes# The above copyright notice and this permission notice shall be included in 20238104Sdes# all copies or substantial portions of the Software. 21238104Sdes# 22238104Sdes# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23238104Sdes# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24238104Sdes# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25238104Sdes# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26238104Sdes# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27238104Sdes# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28238104Sdes# 29238104Sdes# Except as contained in this notice, the name of the X Consortium shall not 30238104Sdes# be used in advertising or otherwise to promote the sale, use or other deal- 31238104Sdes# ings in this Software without prior written authorization from the X Consor- 32238104Sdes# tium. 33238104Sdes# 34238104Sdes# 35238104Sdes# FSF changes to this file are in the public domain. 36238104Sdes# 37238104Sdes# Calling this script install-sh is preferred over install.sh, to prevent 38238104Sdes# `make' implicit rules from creating a file called install from it 39238104Sdes# when there is no Makefile. 40238104Sdes# 41238104Sdes# This script is compatible with the BSD install script, but was written 42238104Sdes# from scratch. 43238104Sdes 44238104Sdesnl=' 45238104Sdes' 46238104SdesIFS=" "" $nl" 47238104Sdes 48238104Sdes# set DOITPROG to echo to test this script 49238104Sdes 50238104Sdes# Don't use :- since 4.3BSD and earlier shells don't like it. 51238104Sdesdoit=${DOITPROG-} 52238104Sdesif test -z "$doit"; then 53238104Sdes doit_exec=exec 54238104Sdeselse 55238104Sdes doit_exec=$doit 56238104Sdesfi 57238104Sdes 58238104Sdes# Put in absolute file names if you don't have them in your path; 59238104Sdes# or use environment vars. 60238104Sdes 61238104Sdeschgrpprog=${CHGRPPROG-chgrp} 62238104Sdeschmodprog=${CHMODPROG-chmod} 63238104Sdeschownprog=${CHOWNPROG-chown} 64238104Sdescmpprog=${CMPPROG-cmp} 65238104Sdescpprog=${CPPROG-cp} 66238104Sdesmkdirprog=${MKDIRPROG-mkdir} 67238104Sdesmvprog=${MVPROG-mv} 68238104Sdesrmprog=${RMPROG-rm} 69238104Sdesstripprog=${STRIPPROG-strip} 70238104Sdes 71238104Sdesposix_glob='?' 72238104Sdesinitialize_posix_glob=' 73238104Sdes test "$posix_glob" != "?" || { 74238104Sdes if (set -f) 2>/dev/null; then 75238104Sdes posix_glob= 76238104Sdes else 77238104Sdes posix_glob=: 78238104Sdes fi 79238104Sdes } 80238104Sdes' 81238104Sdes 82238104Sdesposix_mkdir= 83238104Sdes 84238104Sdes# Desired mode of installed file. 85238104Sdesmode=0755 86238104Sdes 87238104Sdeschgrpcmd= 88238104Sdeschmodcmd=$chmodprog 89238104Sdeschowncmd= 90238104Sdesmvcmd=$mvprog 91238104Sdesrmcmd="$rmprog -f" 92238104Sdesstripcmd= 93238104Sdes 94238104Sdessrc= 95238104Sdesdst= 96238104Sdesdir_arg= 97238104Sdesdst_arg= 98238104Sdes 99238104Sdescopy_on_change=false 100238104Sdesno_target_directory= 101238104Sdes 102238104Sdesusage="\ 103238104SdesUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE 104238104Sdes or: $0 [OPTION]... SRCFILES... DIRECTORY 105238104Sdes or: $0 [OPTION]... -t DIRECTORY SRCFILES... 106238104Sdes or: $0 [OPTION]... -d DIRECTORIES... 107238104Sdes 108238104SdesIn the 1st form, copy SRCFILE to DSTFILE. 109238104SdesIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 110238104SdesIn the 4th, create DIRECTORIES. 111238104Sdes 112238104SdesOptions: 113238104Sdes --help display this help and exit. 114238104Sdes --version display version info and exit. 115238104Sdes 116238104Sdes -c (ignored) 117238104Sdes -C install only if different (preserve the last data modification time) 118238104Sdes -d create directories instead of installing files. 119238104Sdes -g GROUP $chgrpprog installed files to GROUP. 120238104Sdes -m MODE $chmodprog installed files to MODE. 121238104Sdes -o USER $chownprog installed files to USER. 122238104Sdes -s $stripprog installed files. 123238104Sdes -t DIRECTORY install into DIRECTORY. 124238104Sdes -T report an error if DSTFILE is a directory. 125238104Sdes 126238104SdesEnvironment variables override the default commands: 127238104Sdes CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 128238104Sdes RMPROG STRIPPROG 129238104Sdes" 130238104Sdes 131238104Sdeswhile test $# -ne 0; do 132238104Sdes case $1 in 133238104Sdes -c) ;; 134238104Sdes 135238104Sdes -C) copy_on_change=true;; 136238104Sdes 137238104Sdes -d) dir_arg=true;; 138238104Sdes 139238104Sdes -g) chgrpcmd="$chgrpprog $2" 140238104Sdes shift;; 141238104Sdes 142238104Sdes --help) echo "$usage"; exit $?;; 143238104Sdes 144238104Sdes -m) mode=$2 145238104Sdes case $mode in 146238104Sdes *' '* | *' '* | *' 147238104Sdes'* | *'*'* | *'?'* | *'['*) 148238104Sdes echo "$0: invalid mode: $mode" >&2 149238104Sdes exit 1;; 150238104Sdes esac 151238104Sdes shift;; 152238104Sdes 153238104Sdes -o) chowncmd="$chownprog $2" 154238104Sdes shift;; 155238104Sdes 156238104Sdes -s) stripcmd=$stripprog;; 157238104Sdes 158238104Sdes -t) dst_arg=$2 159238104Sdes shift;; 160238104Sdes 161238104Sdes -T) no_target_directory=true;; 162238104Sdes 163238104Sdes --version) echo "$0 $scriptversion"; exit $?;; 164238104Sdes 165238104Sdes --) shift 166238104Sdes break;; 167238104Sdes 168238104Sdes -*) echo "$0: invalid option: $1" >&2 169238104Sdes exit 1;; 170238104Sdes 171238104Sdes *) break;; 172238104Sdes esac 173238104Sdes shift 174238104Sdesdone 175238104Sdes 176238104Sdesif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 177238104Sdes # When -d is used, all remaining arguments are directories to create. 178238104Sdes # When -t is used, the destination is already specified. 179238104Sdes # Otherwise, the last argument is the destination. Remove it from $@. 180238104Sdes for arg 181238104Sdes do 182238104Sdes if test -n "$dst_arg"; then 183238104Sdes # $@ is not empty: it contains at least $arg. 184238104Sdes set fnord "$@" "$dst_arg" 185238104Sdes shift # fnord 186238104Sdes fi 187238104Sdes shift # arg 188238104Sdes dst_arg=$arg 189238104Sdes done 190238104Sdesfi 191238104Sdes 192238104Sdesif test $# -eq 0; then 193238104Sdes if test -z "$dir_arg"; then 194238104Sdes echo "$0: no input file specified." >&2 195238104Sdes exit 1 196238104Sdes fi 197238104Sdes # It's OK to call `install-sh -d' without argument. 198238104Sdes # This can happen when creating conditional directories. 199238104Sdes exit 0 200238104Sdesfi 201238104Sdes 202238104Sdesif test -z "$dir_arg"; then 203238104Sdes trap '(exit $?); exit' 1 2 13 15 204238104Sdes 205238104Sdes # Set umask so as not to create temps with too-generous modes. 206238104Sdes # However, 'strip' requires both read and write access to temps. 207238104Sdes case $mode in 208238104Sdes # Optimize common cases. 209238104Sdes *644) cp_umask=133;; 210238104Sdes *755) cp_umask=22;; 211238104Sdes 212238104Sdes *[0-7]) 213238104Sdes if test -z "$stripcmd"; then 214238104Sdes u_plus_rw= 215238104Sdes else 216238104Sdes u_plus_rw='% 200' 217238104Sdes fi 218238104Sdes cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 219238104Sdes *) 220238104Sdes if test -z "$stripcmd"; then 221238104Sdes u_plus_rw= 222238104Sdes else 223238104Sdes u_plus_rw=,u+rw 224238104Sdes fi 225238104Sdes cp_umask=$mode$u_plus_rw;; 226238104Sdes esac 227238104Sdesfi 228238104Sdes 229238104Sdesfor src 230238104Sdesdo 231238104Sdes # Protect names starting with `-'. 232238104Sdes case $src in 233238104Sdes -*) src=./$src;; 234238104Sdes esac 235238104Sdes 236238104Sdes if test -n "$dir_arg"; then 237238104Sdes dst=$src 238238104Sdes dstdir=$dst 239238104Sdes test -d "$dstdir" 240238104Sdes dstdir_status=$? 241238104Sdes else 242238104Sdes 243238104Sdes # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 244238104Sdes # might cause directories to be created, which would be especially bad 245238104Sdes # if $src (and thus $dsttmp) contains '*'. 246238104Sdes if test ! -f "$src" && test ! -d "$src"; then 247238104Sdes echo "$0: $src does not exist." >&2 248238104Sdes exit 1 249238104Sdes fi 250238104Sdes 251238104Sdes if test -z "$dst_arg"; then 252238104Sdes echo "$0: no destination specified." >&2 253238104Sdes exit 1 254238104Sdes fi 255238104Sdes 256238104Sdes dst=$dst_arg 257238104Sdes # Protect names starting with `-'. 258238104Sdes case $dst in 259238104Sdes -*) dst=./$dst;; 260238104Sdes esac 261238104Sdes 262238104Sdes # If destination is a directory, append the input filename; won't work 263238104Sdes # if double slashes aren't ignored. 264238104Sdes if test -d "$dst"; then 265238104Sdes if test -n "$no_target_directory"; then 266238104Sdes echo "$0: $dst_arg: Is a directory" >&2 267238104Sdes exit 1 268238104Sdes fi 269238104Sdes dstdir=$dst 270238104Sdes dst=$dstdir/`basename "$src"` 271238104Sdes dstdir_status=0 272238104Sdes else 273238104Sdes # Prefer dirname, but fall back on a substitute if dirname fails. 274238104Sdes dstdir=` 275238104Sdes (dirname "$dst") 2>/dev/null || 276238104Sdes expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ 277238104Sdes X"$dst" : 'X\(//\)[^/]' \| \ 278238104Sdes X"$dst" : 'X\(//\)$' \| \ 279238104Sdes X"$dst" : 'X\(/\)' \| . 2>/dev/null || 280238104Sdes echo X"$dst" | 281238104Sdes sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ 282238104Sdes s//\1/ 283238104Sdes q 284238104Sdes } 285238104Sdes /^X\(\/\/\)[^/].*/{ 286238104Sdes s//\1/ 287238104Sdes q 288238104Sdes } 289238104Sdes /^X\(\/\/\)$/{ 290238104Sdes s//\1/ 291238104Sdes q 292238104Sdes } 293238104Sdes /^X\(\/\).*/{ 294238104Sdes s//\1/ 295238104Sdes q 296238104Sdes } 297238104Sdes s/.*/./; q' 298238104Sdes ` 299238104Sdes 300238104Sdes test -d "$dstdir" 301238104Sdes dstdir_status=$? 302238104Sdes fi 303238104Sdes fi 304238104Sdes 305238104Sdes obsolete_mkdir_used=false 306238104Sdes 307238104Sdes if test $dstdir_status != 0; then 308238104Sdes case $posix_mkdir in 309238104Sdes '') 310238104Sdes # Create intermediate dirs using mode 755 as modified by the umask. 311238104Sdes # This is like FreeBSD 'install' as of 1997-10-28. 312238104Sdes umask=`umask` 313238104Sdes case $stripcmd.$umask in 314238104Sdes # Optimize common cases. 315238104Sdes *[2367][2367]) mkdir_umask=$umask;; 316238104Sdes .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 317238104Sdes 318238104Sdes *[0-7]) 319238104Sdes mkdir_umask=`expr $umask + 22 \ 320238104Sdes - $umask % 100 % 40 + $umask % 20 \ 321238104Sdes - $umask % 10 % 4 + $umask % 2 322238104Sdes `;; 323238104Sdes *) mkdir_umask=$umask,go-w;; 324238104Sdes esac 325238104Sdes 326238104Sdes # With -d, create the new directory with the user-specified mode. 327238104Sdes # Otherwise, rely on $mkdir_umask. 328238104Sdes if test -n "$dir_arg"; then 329238104Sdes mkdir_mode=-m$mode 330238104Sdes else 331238104Sdes mkdir_mode= 332238104Sdes fi 333238104Sdes 334238104Sdes posix_mkdir=false 335238104Sdes case $umask in 336238104Sdes *[123567][0-7][0-7]) 337238104Sdes # POSIX mkdir -p sets u+wx bits regardless of umask, which 338238104Sdes # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 339238104Sdes ;; 340238104Sdes *) 341238104Sdes tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 342238104Sdes trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 343238104Sdes 344238104Sdes if (umask $mkdir_umask && 345238104Sdes exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 346238104Sdes then 347238104Sdes if test -z "$dir_arg" || { 348238104Sdes # Check for POSIX incompatibilities with -m. 349238104Sdes # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 350238104Sdes # other-writeable bit of parent directory when it shouldn't. 351238104Sdes # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 352238104Sdes ls_ld_tmpdir=`ls -ld "$tmpdir"` 353238104Sdes case $ls_ld_tmpdir in 354238104Sdes d????-?r-*) different_mode=700;; 355238104Sdes d????-?--*) different_mode=755;; 356238104Sdes *) false;; 357238104Sdes esac && 358238104Sdes $mkdirprog -m$different_mode -p -- "$tmpdir" && { 359238104Sdes ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 360238104Sdes test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 361238104Sdes } 362238104Sdes } 363238104Sdes then posix_mkdir=: 364238104Sdes fi 365238104Sdes rmdir "$tmpdir/d" "$tmpdir" 366238104Sdes else 367238104Sdes # Remove any dirs left behind by ancient mkdir implementations. 368238104Sdes rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 369238104Sdes fi 370238104Sdes trap '' 0;; 371238104Sdes esac;; 372238104Sdes esac 373238104Sdes 374238104Sdes if 375238104Sdes $posix_mkdir && ( 376238104Sdes umask $mkdir_umask && 377238104Sdes $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 378238104Sdes ) 379238104Sdes then : 380238104Sdes else 381238104Sdes 382238104Sdes # The umask is ridiculous, or mkdir does not conform to POSIX, 383238104Sdes # or it failed possibly due to a race condition. Create the 384238104Sdes # directory the slow way, step by step, checking for races as we go. 385238104Sdes 386238104Sdes case $dstdir in 387238104Sdes /*) prefix='/';; 388238104Sdes -*) prefix='./';; 389238104Sdes *) prefix='';; 390238104Sdes esac 391238104Sdes 392238104Sdes eval "$initialize_posix_glob" 393238104Sdes 394238104Sdes oIFS=$IFS 395238104Sdes IFS=/ 396238104Sdes $posix_glob set -f 397238104Sdes set fnord $dstdir 398238104Sdes shift 399238104Sdes $posix_glob set +f 400238104Sdes IFS=$oIFS 401238104Sdes 402238104Sdes prefixes= 403238104Sdes 404238104Sdes for d 405238104Sdes do 406238104Sdes test -z "$d" && continue 407238104Sdes 408238104Sdes prefix=$prefix$d 409238104Sdes if test -d "$prefix"; then 410238104Sdes prefixes= 411238104Sdes else 412238104Sdes if $posix_mkdir; then 413238104Sdes (umask=$mkdir_umask && 414238104Sdes $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 415238104Sdes # Don't fail if two instances are running concurrently. 416238104Sdes test -d "$prefix" || exit 1 417238104Sdes else 418238104Sdes case $prefix in 419238104Sdes *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 420238104Sdes *) qprefix=$prefix;; 421238104Sdes esac 422238104Sdes prefixes="$prefixes '$qprefix'" 423238104Sdes fi 424238104Sdes fi 425238104Sdes prefix=$prefix/ 426238104Sdes done 427238104Sdes 428238104Sdes if test -n "$prefixes"; then 429238104Sdes # Don't fail if two instances are running concurrently. 430238104Sdes (umask $mkdir_umask && 431238104Sdes eval "\$doit_exec \$mkdirprog $prefixes") || 432238104Sdes test -d "$dstdir" || exit 1 433238104Sdes obsolete_mkdir_used=true 434238104Sdes fi 435238104Sdes fi 436238104Sdes fi 437238104Sdes 438238104Sdes if test -n "$dir_arg"; then 439238104Sdes { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 440238104Sdes { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 441238104Sdes { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 442238104Sdes test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 443238104Sdes else 444238104Sdes 445238104Sdes # Make a couple of temp file names in the proper directory. 446238104Sdes dsttmp=$dstdir/_inst.$$_ 447238104Sdes rmtmp=$dstdir/_rm.$$_ 448238104Sdes 449238104Sdes # Trap to clean up those temp files at exit. 450238104Sdes trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 451238104Sdes 452238104Sdes # Copy the file name to the temp name. 453238104Sdes (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 454238104Sdes 455238104Sdes # and set any options; do chmod last to preserve setuid bits. 456238104Sdes # 457238104Sdes # If any of these fail, we abort the whole thing. If we want to 458238104Sdes # ignore errors from any of these, just make sure not to ignore 459238104Sdes # errors from the above "$doit $cpprog $src $dsttmp" command. 460238104Sdes # 461238104Sdes { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 462238104Sdes { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 463238104Sdes { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 464238104Sdes { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 465238104Sdes 466238104Sdes # If -C, don't bother to copy if it wouldn't change the file. 467238104Sdes if $copy_on_change && 468238104Sdes old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 469238104Sdes new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 470238104Sdes 471238104Sdes eval "$initialize_posix_glob" && 472238104Sdes $posix_glob set -f && 473238104Sdes set X $old && old=:$2:$4:$5:$6 && 474238104Sdes set X $new && new=:$2:$4:$5:$6 && 475238104Sdes $posix_glob set +f && 476238104Sdes 477238104Sdes test "$old" = "$new" && 478238104Sdes $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 479238104Sdes then 480238104Sdes rm -f "$dsttmp" 481238104Sdes else 482238104Sdes # Rename the file to the real destination. 483238104Sdes $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 484238104Sdes 485238104Sdes # The rename failed, perhaps because mv can't rename something else 486238104Sdes # to itself, or perhaps because mv is so ancient that it does not 487238104Sdes # support -f. 488238104Sdes { 489238104Sdes # Now remove or move aside any old file at destination location. 490238104Sdes # We try this two ways since rm can't unlink itself on some 491238104Sdes # systems and the destination file might be busy for other 492238104Sdes # reasons. In this case, the final cleanup might fail but the new 493238104Sdes # file should still install successfully. 494238104Sdes { 495238104Sdes test ! -f "$dst" || 496238104Sdes $doit $rmcmd -f "$dst" 2>/dev/null || 497238104Sdes { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 498238104Sdes { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 499238104Sdes } || 500238104Sdes { echo "$0: cannot unlink or rename $dst" >&2 501238104Sdes (exit 1); exit 1 502238104Sdes } 503238104Sdes } && 504238104Sdes 505238104Sdes # Now rename the file to the real destination. 506238104Sdes $doit $mvcmd "$dsttmp" "$dst" 507238104Sdes } 508238104Sdes fi || exit 1 509238104Sdes 510238104Sdes trap '' 0 511238104Sdes fi 512238104Sdesdone 513238104Sdes 514238104Sdes# Local variables: 515238104Sdes# eval: (add-hook 'write-file-hooks 'time-stamp) 516238104Sdes# time-stamp-start: "scriptversion=" 517238104Sdes# time-stamp-format: "%:y-%02m-%02d.%02H" 518238104Sdes# time-stamp-time-zone: "UTC" 519238104Sdes# time-stamp-end: "; # UTC" 520238104Sdes# End: 521