Deleted Added
full compact
install-sh (127808) install-sh (142403)
1#!/bin/sh
1#!/bin/sh
2#
3# install - install a program, script, or datafile
2# install - install a program, script, or datafile
4#
3
4scriptversion=2004-02-15.20
5
5# This originates from X11R5 (mit/util/scripts/install.sh), which was
6# later released in X11R6 (xc/config/util/install.sh) with the
7# following copyright and license.
8#
9# Copyright (C) 1994 X Consortium
10#
11# Permission is hereby granted, free of charge, to any person obtaining a copy
12# of this software and associated documentation files (the "Software"), to

--- 23 unchanged lines hidden (view full) ---

36# Calling this script install-sh is preferred over install.sh, to prevent
37# `make' implicit rules from creating a file called install from it
38# when there is no Makefile.
39#
40# This script is compatible with the BSD install script, but was written
41# from scratch. It can only install one file at a time, a restriction
42# shared with many OS's install programs.
43
6# This originates from X11R5 (mit/util/scripts/install.sh), which was
7# later released in X11R6 (xc/config/util/install.sh) with the
8# following copyright and license.
9#
10# Copyright (C) 1994 X Consortium
11#
12# Permission is hereby granted, free of charge, to any person obtaining a copy
13# of this software and associated documentation files (the "Software"), to

--- 23 unchanged lines hidden (view full) ---

37# Calling this script install-sh is preferred over install.sh, to prevent
38# `make' implicit rules from creating a file called install from it
39# when there is no Makefile.
40#
41# This script is compatible with the BSD install script, but was written
42# from scratch. It can only install one file at a time, a restriction
43# shared with many OS's install programs.
44
44
45# set DOITPROG to echo to test this script
46
47# Don't use :- since 4.3BSD and earlier shells don't like it.
48doit="${DOITPROG-}"
49
45# set DOITPROG to echo to test this script
46
47# Don't use :- since 4.3BSD and earlier shells don't like it.
48doit="${DOITPROG-}"
49
50
51# put in absolute paths if you don't have them in your path; or use env. vars.
52
53mvprog="${MVPROG-mv}"
54cpprog="${CPPROG-cp}"
55chmodprog="${CHMODPROG-chmod}"
56chownprog="${CHOWNPROG-chown}"
57chgrpprog="${CHGRPPROG-chgrp}"
58stripprog="${STRIPPROG-strip}"
59rmprog="${RMPROG-rm}"
60mkdirprog="${MKDIRPROG-mkdir}"
61
50# put in absolute paths if you don't have them in your path; or use env. vars.
51
52mvprog="${MVPROG-mv}"
53cpprog="${CPPROG-cp}"
54chmodprog="${CHMODPROG-chmod}"
55chownprog="${CHOWNPROG-chown}"
56chgrpprog="${CHGRPPROG-chgrp}"
57stripprog="${STRIPPROG-strip}"
58rmprog="${RMPROG-rm}"
59mkdirprog="${MKDIRPROG-mkdir}"
60
62transformbasename=""
63transform_arg=""
61transformbasename=
62transform_arg=
64instcmd="$mvprog"
65chmodcmd="$chmodprog 0755"
63instcmd="$mvprog"
64chmodcmd="$chmodprog 0755"
66chowncmd=""
67chgrpcmd=""
68stripcmd=""
65chowncmd=
66chgrpcmd=
67stripcmd=
69rmcmd="$rmprog -f"
70mvcmd="$mvprog"
68rmcmd="$rmprog -f"
69mvcmd="$mvprog"
71src=""
72dst=""
73dir_arg=""
70src=
71dst=
72dir_arg=
74
73
75while [ x"$1" != x ]; do
76 case $1 in
77 -c) instcmd=$cpprog
78 shift
79 continue;;
74usage="Usage: $0 [OPTION]... SRCFILE DSTFILE
75 or: $0 [OPTION]... SRCFILES... DIRECTORY
76 or: $0 -d DIRECTORIES...
80
77
81 -d) dir_arg=true
82 shift
83 continue;;
78In the first form, install SRCFILE to DSTFILE, removing SRCFILE by default.
79In the second, create the directory path DIR.
84
80
85 -m) chmodcmd="$chmodprog $2"
86 shift
87 shift
88 continue;;
81Options:
82-b=TRANSFORMBASENAME
83-c copy source (using $cpprog) instead of moving (using $mvprog).
84-d create directories instead of installing files.
85-g GROUP $chgrp installed files to GROUP.
86-m MODE $chmod installed files to MODE.
87-o USER $chown installed files to USER.
88-s strip installed files (using $stripprog).
89-t=TRANSFORM
90--help display this help and exit.
91--version display version info and exit.
89
92
90 -o) chowncmd="$chownprog $2"
91 shift
92 shift
93 continue;;
93Environment variables override the default commands:
94 CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
95"
94
96
95 -g) chgrpcmd="$chgrpprog $2"
96 shift
97 shift
98 continue;;
97while test -n "$1"; do
98 case $1 in
99 -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
100 shift
101 continue;;
99
102
100 -s) stripcmd=$stripprog
101 shift
102 continue;;
103 -c) instcmd=$cpprog
104 shift
105 continue;;
103
106
104 -t=*) transformarg=`echo $1 | sed 's/-t=//'`
105 shift
106 continue;;
107 -d) dir_arg=true
108 shift
109 continue;;
107
110
108 -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
109 shift
110 continue;;
111 -g) chgrpcmd="$chgrpprog $2"
112 shift
113 shift
114 continue;;
111
115
112 *) if [ x"$src" = x ]
113 then
114 src=$1
115 else
116 # this colon is to work around a 386BSD /bin/sh bug
117 :
118 dst=$1
119 fi
120 shift
121 continue;;
122 esac
123done
116 --help) echo "$usage"; exit 0;;
124
117
125if [ x"$src" = x ]
126then
127 echo "$0: no input file specified" >&2
128 exit 1
129else
130 :
131fi
118 -m) chmodcmd="$chmodprog $2"
119 shift
120 shift
121 continue;;
132
122
133if [ x"$dir_arg" != x ]; then
134 dst=$src
135 src=""
123 -o) chowncmd="$chownprog $2"
124 shift
125 shift
126 continue;;
136
127
137 if [ -d "$dst" ]; then
138 instcmd=:
139 chmodcmd=""
140 else
141 instcmd=$mkdirprog
142 fi
143else
128 -s) stripcmd=$stripprog
129 shift
130 continue;;
144
131
145# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
146# might cause directories to be created, which would be especially bad
147# if $src (and thus $dsttmp) contains '*'.
132 -t=*) transformarg=`echo $1 | sed 's/-t=//'`
133 shift
134 continue;;
148
135
149 if [ -f "$src" ] || [ -d "$src" ]
150 then
151 :
152 else
153 echo "$0: $src does not exist" >&2
154 exit 1
155 fi
136 --version) echo "$0 $scriptversion"; exit 0;;
156
137
157 if [ x"$dst" = x ]
158 then
159 echo "$0: no destination specified" >&2
160 exit 1
161 else
162 :
163 fi
138 *) # When -d is used, all remaining arguments are directories to create.
139 test -n "$dir_arg" && break
140 # Otherwise, the last argument is the destination. Remove it from $@.
141 for arg
142 do
143 if test -n "$dstarg"; then
144 # $@ is not empty: it contains at least $arg.
145 set fnord "$@" "$dstarg"
146 shift # fnord
147 fi
148 shift # arg
149 dstarg=$arg
150 done
151 break;;
152 esac
153done
164
154
165# If destination is a directory, append the input filename; if your system
166# does not like double slashes in filenames, you may need to add some logic
167
168 if [ -d "$dst" ]
169 then
170 dst=$dst/`basename "$src"`
171 else
172 :
173 fi
155if test -z "$1"; then
156 if test -z "$dir_arg"; then
157 echo "$0: no input file specified." >&2
158 exit 1
159 fi
160 # It's OK to call `install-sh -d' without argument.
161 # This can happen when creating conditional directories.
162 exit 0
174fi
175
163fi
164
176## this sed command emulates the dirname command
177dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
165for src
166do
167 # Protect names starting with `-'.
168 case $src in
169 -*) src=./$src ;;
170 esac
178
171
179# Make sure that the destination directory exists.
180# this part is taken from Noah Friedman's mkinstalldirs script
172 if test -n "$dir_arg"; then
173 dst=$src
174 src=
181
175
182# Skip lots of stat calls in the usual case.
183if [ ! -d "$dstdir" ]; then
184defaultIFS='
185 '
186IFS="${IFS-$defaultIFS}"
176 if test -d "$dst"; then
177 instcmd=:
178 chmodcmd=
179 else
180 instcmd=$mkdirprog
181 fi
182 else
183 # Waiting for this to be detected by the "$instcmd $src $dsttmp" command
184 # might cause directories to be created, which would be especially bad
185 # if $src (and thus $dsttmp) contains '*'.
186 if test ! -f "$src" && test ! -d "$src"; then
187 echo "$0: $src does not exist." >&2
188 exit 1
189 fi
187
190
188oIFS=$IFS
189# Some sh's can't handle IFS=/ for some reason.
190IFS='%'
191set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
192IFS=$oIFS
191 if test -z "$dstarg"; then
192 echo "$0: no destination specified." >&2
193 exit 1
194 fi
193
195
194pathcomp=''
196 dst=$dstarg
197 # Protect names starting with `-'.
198 case $dst in
199 -*) dst=./$dst ;;
200 esac
195
201
196while [ $# -ne 0 ] ; do
197 pathcomp=$pathcomp$1
198 shift
202 # If destination is a directory, append the input filename; won't work
203 # if double slashes aren't ignored.
204 if test -d "$dst"; then
205 dst=$dst/`basename "$src"`
206 fi
207 fi
199
208
200 if [ ! -d "$pathcomp" ] ;
201 then
202 $mkdirprog "$pathcomp"
203 else
204 :
205 fi
209 # This sed command emulates the dirname command.
210 dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
206
211
207 pathcomp=$pathcomp/
208done
209fi
212 # Make sure that the destination directory exists.
210
213
211if [ x"$dir_arg" != x ]
212then
213 $doit $instcmd "$dst" &&
214 # Skip lots of stat calls in the usual case.
215 if test ! -d "$dstdir"; then
216 defaultIFS='
217 '
218 IFS="${IFS-$defaultIFS}"
214
219
215 if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
216 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
217 if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
218 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
219else
220 oIFS=$IFS
221 # Some sh's can't handle IFS=/ for some reason.
222 IFS='%'
223 set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
224 IFS=$oIFS
220
225
221# If we're going to rename the final executable, determine the name now.
226 pathcomp=
222
227
223 if [ x"$transformarg" = x ]
224 then
225 dstfile=`basename "$dst"`
226 else
227 dstfile=`basename "$dst" $transformbasename |
228 sed $transformarg`$transformbasename
229 fi
228 while test $# -ne 0 ; do
229 pathcomp=$pathcomp$1
230 shift
231 if test ! -d "$pathcomp"; then
232 $mkdirprog "$pathcomp" || lasterr=$?
233 # mkdir can fail with a `File exist' error in case several
234 # install-sh are creating the directory concurrently. This
235 # is OK.
236 test ! -d "$pathcomp" && { (exit ${lasterr-1}); exit; }
237 fi
238 pathcomp=$pathcomp/
239 done
240 fi
230
241
231# don't allow the sed command to completely eliminate the filename
242 if test -n "$dir_arg"; then
243 $doit $instcmd "$dst" \
244 && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
245 && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
246 && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
247 && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
232
248
233 if [ x"$dstfile" = x ]
234 then
235 dstfile=`basename "$dst"`
236 else
237 :
238 fi
249 else
250 # If we're going to rename the final executable, determine the name now.
251 if test -z "$transformarg"; then
252 dstfile=`basename "$dst"`
253 else
254 dstfile=`basename "$dst" $transformbasename \
255 | sed $transformarg`$transformbasename
256 fi
239
257
240# Make a couple of temp file names in the proper directory.
258 # don't allow the sed command to completely eliminate the filename.
259 test -z "$dstfile" && dstfile=`basename "$dst"`
241
260
242 dsttmp=$dstdir/_inst.$$_
243 rmtmp=$dstdir/_rm.$$_
261 # Make a couple of temp file names in the proper directory.
262 dsttmp=$dstdir/_inst.$$_
263 rmtmp=$dstdir/_rm.$$_
244
264
245# Trap to clean up temp files at exit.
265 # Trap to clean up those temp files at exit.
266 trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
267 trap '(exit $?); exit' 1 2 13 15
246
268
247 trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
248 trap '(exit $?); exit' 1 2 13 15
269 # Move or copy the file name to the temp name
270 $doit $instcmd "$src" "$dsttmp" &&
249
271
250# Move or copy the file name to the temp name
272 # and set any options; do chmod last to preserve setuid bits.
273 #
274 # If any of these fail, we abort the whole thing. If we want to
275 # ignore errors from any of these, just make sure not to ignore
276 # errors from the above "$doit $instcmd $src $dsttmp" command.
277 #
278 { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
279 && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
280 && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
281 && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
251
282
252 $doit $instcmd "$src" "$dsttmp" &&
283 # Now remove or move aside any old file at destination location. We
284 # try this two ways since rm can't unlink itself on some systems and
285 # the destination file might be busy for other reasons. In this case,
286 # the final cleanup might fail but the new file should still install
287 # successfully.
288 {
289 if test -f "$dstdir/$dstfile"; then
290 $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
291 || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
292 || {
293 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
294 (exit 1); exit
295 }
296 else
297 :
298 fi
299 } &&
253
300
254# and set any options; do chmod last to preserve setuid bits
301 # Now rename the file to the real destination.
302 $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
303 fi || { (exit 1); exit; }
304done
255
305
256# If any of these fail, we abort the whole thing. If we want to
257# ignore errors from any of these, just make sure not to ignore
258# errors from the above "$doit $instcmd $src $dsttmp" command.
259
260 if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
261 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
262 if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
263 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
264
265# Now remove or move aside any old file at destination location. We try this
266# two ways since rm can't unlink itself on some systems and the destination
267# file might be busy for other reasons. In this case, the final cleanup
268# might fail but the new file should still install successfully.
269
270{
271 if [ -f "$dstdir/$dstfile" ]
272 then
273 $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
274 $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
275 {
276 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
277 (exit 1); exit
278 }
279 else
280 :
281 fi
282} &&
283
284# Now rename the file to the real destination.
285
286 $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
287
288fi &&
289
290# The final little trick to "correctly" pass the exit status to the exit trap.
306# The final little trick to "correctly" pass the exit status to the exit trap.
291
292{
307{
293 (exit 0); exit
308 (exit 0); exit
294}
309}
310
311# Local variables:
312# eval: (add-hook 'write-file-hooks 'time-stamp)
313# time-stamp-start: "scriptversion="
314# time-stamp-format: "%:y-%02m-%02d.%02H"
315# time-stamp-end: "$"
316# End: