58e7b586e41c6520c331703f42f3f16f41749e83
[xfstests-dev.git] / install-sh
1 #! /bin/bash
2 #
3 # Copyright (c) 2000-2001 Silicon Graphics, Inc.  All Rights Reserved.
4 #
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License as
7 # published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it would be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write the Free Software Foundation,
16 # Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17 #
18 #
19 # This script emulates bsd install and also recognises
20 # two environment variables, with the following semantics :-
21 #
22 # $DIST_MANIFEST - if set, the name of the file to append manifest
23 #                  information in the following format:
24 #                  File     :  f mode owner group src target
25 #                  Directory:  d mode owner group target
26 #                  Symlink  :  l linkval target
27 #
28 # $DIST_ROOT     - if set, prepend to target
29 #
30 # The sematics of all combinations of these two variables
31 # are as follows:
32 #
33 # $DIST_MANIFEST?  $DIST_ROOT? |   Copy?  Append Manifest?
34 # -----------------------------+--------------------------
35 #       not set       not set  |    yes        no
36 #       not set       set      |    yes        no
37 #       set           not set  |    no         yes
38 #       set           set      |    yes        yes
39 #
40 _usage() {
41     echo "Usage: $prog [-o owner] [-g group] [-m mode] -d directory"
42     echo "or     $prog [-D] [-o owner] [-g group] [-m mode] file directory/file"
43     echo "or     $prog [-o owner] [-g group] [-m mode] file [file ...] directory"
44     echo "or     $prog -S file target  (creates \"target\" symlink)"
45     echo ""
46     echo "The \$DIST_MANIFEST and \$DIST_ROOT environment variables affect the"
47     echo "behaviour of this command - see comments in the script."
48     echo "The -D flag is only available for the second usage, and causes"
49     echo "the target directory to be created before installing the file."
50     echo ""
51     exit 1
52 }
53
54 _chown ()
55 {
56     _st=255
57     if [ $# -eq 3 ] ; then
58         chown $1:$2 $3
59         _st=$?
60         if [ $_st -ne 0 ] ; then
61             if [ $REAL_UID != '0' ] ; then
62                 if [ ! -f $DIST_ROOT/.chown.quite ] ; then
63                     echo '==============================================='
64                     echo Ownership of files under ${DIST_ROOT:-/}
65                     echo cannot be changed
66                     echo '==============================================='
67                     if [ -n "$DIST_ROOT" ] ; then
68                         touch $DIST_ROOT/.chown.quite
69                     fi
70                 fi
71                _st=0
72             fi     
73         fi
74     fi
75
76     return $_st
77 }
78
79
80 _manifest ()
81
82     echo $* | sed -e 's/\/\//\//g' >>${DIST_MANIFEST:-/dev/null}
83 }
84
85 prog=`basename $0`
86 HERE=`pwd`
87 dflag=false
88 Dflag=false
89 Sflag=false
90 DIRMODE=755
91 FILEMODE=644
92 OWNER=`id -u`
93 GROUP=`id -g`
94 REAL_UID=$OWNER
95
96 # default is to install and don't append manifest
97 INSTALL=true
98 MANIFEST=:
99
100 : ${DIST_ROOT:=${DESTDIR}}
101
102 [ -n "$DIST_MANIFEST" -a -z "$DIST_ROOT" ] && INSTALL=false
103 [ -n "$DIST_MANIFEST" ] && MANIFEST="_manifest"
104
105 [ $# -eq 0 ] && _usage
106
107 if $INSTALL
108 then
109     CP=cp; LN=ln; MKDIR=mkdir; CHMOD=chmod; CHOWN=_chown
110 else
111     CP=true; LN=true; MKDIR=true; CHMOD=true; CHOWN=true
112 fi
113
114 [ -n "$DIST_ROOT" -a $REAL_UID -ne 0 ] && CHOWN=true
115
116 while getopts "Dcm:d:S:o:g:" c $*
117 do
118    case $c in
119    c)
120         ;;
121    g)
122         GROUP=$OPTARG
123         ;;
124    o)
125         OWNER=$OPTARG
126         ;;
127    m)
128         DIRMODE=`expr $OPTARG`
129         FILEMODE=$DIRMODE
130         ;;
131    D) 
132         Dflag=true
133         ;;
134    S) 
135         symlink=$OPTARG
136         Sflag=true
137         ;;
138    d) 
139         dir=$DIST_ROOT/$OPTARG
140         dflag=true
141         ;;
142    *)
143         _usage
144         ;;
145    esac
146 done
147
148 shift `expr $OPTIND - 1`
149
150 status=0
151 if $dflag
152 then
153     #
154     # first usage
155     #
156     $MKDIR -p $dir 
157     status=$?
158     if [ $status -eq 0 ]
159     then
160         $CHMOD $DIRMODE $dir
161         status=$?
162     fi
163     if [ $status -eq 0 ]
164     then
165         $CHOWN $OWNER $GROUP $dir
166         status=$?
167     fi
168     $MANIFEST d $DIRMODE $OWNER $GROUP ${dir#$DIST_ROOT}
169 elif $Sflag
170 then
171     #
172     # fourth usage (symlink)
173     #
174     if [ $# -ne 1 ]
175     then
176         _usage
177     else
178         target=$DIST_ROOT/$1
179     fi
180     $LN -s -f $symlink $target
181     status=$?
182     $MANIFEST l $symlink ${target#$DIST_ROOT} 
183 else
184     list=""
185     dir=""
186     if [ $# -eq 2 ]
187     then
188         #
189         # second usage
190         #
191         f=$1
192         dir=$DIST_ROOT/$2
193         if $Dflag
194         then
195             mkdir -p `dirname $dir`
196         fi
197         $CP $f $dir
198         status=$?
199         if [ $status -eq 0 ]
200         then 
201             if [ -f $dir/$f ]
202             then
203                 $CHMOD $FILEMODE $dir/$f
204                 status=$?
205                 if [ $status -eq 0 ]
206                 then
207                     $CHOWN $OWNER $GROUP $dir/$f
208                     status=$?
209                 fi
210                 $MANIFEST f $FILEMODE $OWNER $GROUP $HERE/$f ${dir#$DIST_ROOT}/$f
211             else
212                 $CHMOD $FILEMODE $dir
213                 status=$?
214                 if [ $status -eq 0 ]
215                 then
216                     $CHOWN $OWNER $GROUP $dir
217                     status=$?
218                 fi
219                 $MANIFEST f $FILEMODE $OWNER $GROUP $HERE/$dir ${dir#$DIST_ROOT}
220             fi
221         fi
222     else
223         #
224         # third usage
225         #
226         n=1
227         while [ $# -gt 0 ]
228         do
229             if [ $# -gt 1 ]
230             then
231                 list="$list $1"
232             else
233                 dir=$DIST_ROOT/$1
234             fi
235             shift
236         done
237
238         # echo DIR=$dir list=\"$list\"
239         for f in $list
240         do
241             $CP $f $dir
242             status=$?
243             if [ $status -eq 0 ]
244             then
245                 $CHMOD $FILEMODE $dir/$f
246                 status=$?
247                 if [ $status -eq 0 ]
248                 then
249                     $CHOWN $OWNER $GROUP $dir/$f
250                     status=$?
251                 fi
252                 $MANIFEST f $FILEMODE $OWNER $GROUP $HERE/$f ${dir#$DIST_ROOT}/$f
253             fi
254             [ $status -ne 0 ] && break
255         done
256     fi
257 fi
258
259 exit $status