xref: /potrace-1.14/install-sh (revision b3fce824)
1189777a2SCristian Pallares#!/bin/sh
2189777a2SCristian Pallares# install - install a program, script, or datafile
3189777a2SCristian Pallares
4*b3fce824SCristian Pallarésscriptversion=2014-09-12.12; # UTC
5189777a2SCristian Pallares
6189777a2SCristian Pallares# This originates from X11R5 (mit/util/scripts/install.sh), which was
7189777a2SCristian Pallares# later released in X11R6 (xc/config/util/install.sh) with the
8189777a2SCristian Pallares# following copyright and license.
9189777a2SCristian Pallares#
10189777a2SCristian Pallares# Copyright (C) 1994 X Consortium
11189777a2SCristian Pallares#
12189777a2SCristian Pallares# Permission is hereby granted, free of charge, to any person obtaining a copy
13189777a2SCristian Pallares# of this software and associated documentation files (the "Software"), to
14189777a2SCristian Pallares# deal in the Software without restriction, including without limitation the
15189777a2SCristian Pallares# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16189777a2SCristian Pallares# sell copies of the Software, and to permit persons to whom the Software is
17189777a2SCristian Pallares# furnished to do so, subject to the following conditions:
18189777a2SCristian Pallares#
19189777a2SCristian Pallares# The above copyright notice and this permission notice shall be included in
20189777a2SCristian Pallares# all copies or substantial portions of the Software.
21189777a2SCristian Pallares#
22189777a2SCristian Pallares# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23189777a2SCristian Pallares# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24189777a2SCristian Pallares# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
25189777a2SCristian Pallares# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26189777a2SCristian Pallares# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
27189777a2SCristian Pallares# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28189777a2SCristian Pallares#
29189777a2SCristian Pallares# Except as contained in this notice, the name of the X Consortium shall not
30189777a2SCristian Pallares# be used in advertising or otherwise to promote the sale, use or other deal-
31189777a2SCristian Pallares# ings in this Software without prior written authorization from the X Consor-
32189777a2SCristian Pallares# tium.
33189777a2SCristian Pallares#
34189777a2SCristian Pallares#
35189777a2SCristian Pallares# FSF changes to this file are in the public domain.
36189777a2SCristian Pallares#
37189777a2SCristian Pallares# Calling this script install-sh is preferred over install.sh, to prevent
381f13f311SSkyrpex# 'make' implicit rules from creating a file called install from it
39189777a2SCristian Pallares# when there is no Makefile.
40189777a2SCristian Pallares#
41189777a2SCristian Pallares# This script is compatible with the BSD install script, but was written
42189777a2SCristian Pallares# from scratch.
43189777a2SCristian Pallares
44275def9cSCristian Pallaréstab='	'
45189777a2SCristian Pallaresnl='
46189777a2SCristian Pallares'
47275def9cSCristian PallarésIFS=" $tab$nl"
48189777a2SCristian Pallares
49275def9cSCristian Pallarés# Set DOITPROG to "echo" to test this script.
50189777a2SCristian Pallares
51189777a2SCristian Pallaresdoit=${DOITPROG-}
52275def9cSCristian Pallarésdoit_exec=${doit:-exec}
53189777a2SCristian Pallares
54189777a2SCristian Pallares# Put in absolute file names if you don't have them in your path;
55189777a2SCristian Pallares# or use environment vars.
56189777a2SCristian Pallares
57189777a2SCristian Pallareschgrpprog=${CHGRPPROG-chgrp}
58189777a2SCristian Pallareschmodprog=${CHMODPROG-chmod}
59189777a2SCristian Pallareschownprog=${CHOWNPROG-chown}
60189777a2SCristian Pallarescmpprog=${CMPPROG-cmp}
61189777a2SCristian Pallarescpprog=${CPPROG-cp}
62189777a2SCristian Pallaresmkdirprog=${MKDIRPROG-mkdir}
63189777a2SCristian Pallaresmvprog=${MVPROG-mv}
64189777a2SCristian Pallaresrmprog=${RMPROG-rm}
65189777a2SCristian Pallaresstripprog=${STRIPPROG-strip}
66189777a2SCristian Pallares
67189777a2SCristian Pallaresposix_mkdir=
68189777a2SCristian Pallares
69189777a2SCristian Pallares# Desired mode of installed file.
70189777a2SCristian Pallaresmode=0755
71189777a2SCristian Pallares
72189777a2SCristian Pallareschgrpcmd=
73189777a2SCristian Pallareschmodcmd=$chmodprog
74189777a2SCristian Pallareschowncmd=
75189777a2SCristian Pallaresmvcmd=$mvprog
76189777a2SCristian Pallaresrmcmd="$rmprog -f"
77189777a2SCristian Pallaresstripcmd=
78189777a2SCristian Pallares
79189777a2SCristian Pallaressrc=
80189777a2SCristian Pallaresdst=
81189777a2SCristian Pallaresdir_arg=
82189777a2SCristian Pallaresdst_arg=
83189777a2SCristian Pallares
84189777a2SCristian Pallarescopy_on_change=false
85275def9cSCristian Pallarésis_target_a_directory=possibly
86189777a2SCristian Pallares
87189777a2SCristian Pallaresusage="\
88189777a2SCristian PallaresUsage: $0 [OPTION]... [-T] SRCFILE DSTFILE
89189777a2SCristian Pallares   or: $0 [OPTION]... SRCFILES... DIRECTORY
90189777a2SCristian Pallares   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
91189777a2SCristian Pallares   or: $0 [OPTION]... -d DIRECTORIES...
92189777a2SCristian Pallares
93189777a2SCristian PallaresIn the 1st form, copy SRCFILE to DSTFILE.
94189777a2SCristian PallaresIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
95189777a2SCristian PallaresIn the 4th, create DIRECTORIES.
96189777a2SCristian Pallares
97189777a2SCristian PallaresOptions:
98189777a2SCristian Pallares     --help     display this help and exit.
99189777a2SCristian Pallares     --version  display version info and exit.
100189777a2SCristian Pallares
101189777a2SCristian Pallares  -c            (ignored)
102189777a2SCristian Pallares  -C            install only if different (preserve the last data modification time)
103189777a2SCristian Pallares  -d            create directories instead of installing files.
104189777a2SCristian Pallares  -g GROUP      $chgrpprog installed files to GROUP.
105189777a2SCristian Pallares  -m MODE       $chmodprog installed files to MODE.
106189777a2SCristian Pallares  -o USER       $chownprog installed files to USER.
107189777a2SCristian Pallares  -s            $stripprog installed files.
108189777a2SCristian Pallares  -t DIRECTORY  install into DIRECTORY.
109189777a2SCristian Pallares  -T            report an error if DSTFILE is a directory.
110189777a2SCristian Pallares
111189777a2SCristian PallaresEnvironment variables override the default commands:
112189777a2SCristian Pallares  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
113189777a2SCristian Pallares  RMPROG STRIPPROG
114189777a2SCristian Pallares"
115189777a2SCristian Pallares
116189777a2SCristian Pallareswhile test $# -ne 0; do
117189777a2SCristian Pallares  case $1 in
118189777a2SCristian Pallares    -c) ;;
119189777a2SCristian Pallares
120189777a2SCristian Pallares    -C) copy_on_change=true;;
121189777a2SCristian Pallares
122189777a2SCristian Pallares    -d) dir_arg=true;;
123189777a2SCristian Pallares
124189777a2SCristian Pallares    -g) chgrpcmd="$chgrpprog $2"
125189777a2SCristian Pallares        shift;;
126189777a2SCristian Pallares
127189777a2SCristian Pallares    --help) echo "$usage"; exit $?;;
128189777a2SCristian Pallares
129189777a2SCristian Pallares    -m) mode=$2
130189777a2SCristian Pallares        case $mode in
131275def9cSCristian Pallarés          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
132189777a2SCristian Pallares            echo "$0: invalid mode: $mode" >&2
133189777a2SCristian Pallares            exit 1;;
134189777a2SCristian Pallares        esac
135189777a2SCristian Pallares        shift;;
136189777a2SCristian Pallares
137189777a2SCristian Pallares    -o) chowncmd="$chownprog $2"
138189777a2SCristian Pallares        shift;;
139189777a2SCristian Pallares
140189777a2SCristian Pallares    -s) stripcmd=$stripprog;;
141189777a2SCristian Pallares
142275def9cSCristian Pallarés    -t)
143275def9cSCristian Pallarés        is_target_a_directory=always
144275def9cSCristian Pallarés        dst_arg=$2
1451f13f311SSkyrpex        # Protect names problematic for 'test' and other utilities.
1461f13f311SSkyrpex        case $dst_arg in
1471f13f311SSkyrpex          -* | [=\(\)!]) dst_arg=./$dst_arg;;
1481f13f311SSkyrpex        esac
149189777a2SCristian Pallares        shift;;
150189777a2SCristian Pallares
151275def9cSCristian Pallarés    -T) is_target_a_directory=never;;
152189777a2SCristian Pallares
153189777a2SCristian Pallares    --version) echo "$0 $scriptversion"; exit $?;;
154189777a2SCristian Pallares
155189777a2SCristian Pallares    --) shift
156189777a2SCristian Pallares        break;;
157189777a2SCristian Pallares
158189777a2SCristian Pallares    -*) echo "$0: invalid option: $1" >&2
159189777a2SCristian Pallares        exit 1;;
160189777a2SCristian Pallares
161189777a2SCristian Pallares    *)  break;;
162189777a2SCristian Pallares  esac
163189777a2SCristian Pallares  shift
164189777a2SCristian Pallaresdone
165189777a2SCristian Pallares
166275def9cSCristian Pallarés# We allow the use of options -d and -T together, by making -d
167275def9cSCristian Pallarés# take the precedence; this is for compatibility with GNU install.
168275def9cSCristian Pallarés
169275def9cSCristian Pallarésif test -n "$dir_arg"; then
170275def9cSCristian Pallarés  if test -n "$dst_arg"; then
171275def9cSCristian Pallarés    echo "$0: target directory not allowed when installing a directory." >&2
172275def9cSCristian Pallarés    exit 1
173275def9cSCristian Pallarés  fi
174275def9cSCristian Pallarésfi
175275def9cSCristian Pallarés
176189777a2SCristian Pallaresif test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
177189777a2SCristian Pallares  # When -d is used, all remaining arguments are directories to create.
178189777a2SCristian Pallares  # When -t is used, the destination is already specified.
179189777a2SCristian Pallares  # Otherwise, the last argument is the destination.  Remove it from $@.
180189777a2SCristian Pallares  for arg
181189777a2SCristian Pallares  do
182189777a2SCristian Pallares    if test -n "$dst_arg"; then
183189777a2SCristian Pallares      # $@ is not empty: it contains at least $arg.
184189777a2SCristian Pallares      set fnord "$@" "$dst_arg"
185189777a2SCristian Pallares      shift # fnord
186189777a2SCristian Pallares    fi
187189777a2SCristian Pallares    shift # arg
188189777a2SCristian Pallares    dst_arg=$arg
1891f13f311SSkyrpex    # Protect names problematic for 'test' and other utilities.
1901f13f311SSkyrpex    case $dst_arg in
1911f13f311SSkyrpex      -* | [=\(\)!]) dst_arg=./$dst_arg;;
1921f13f311SSkyrpex    esac
193189777a2SCristian Pallares  done
194189777a2SCristian Pallaresfi
195189777a2SCristian Pallares
196189777a2SCristian Pallaresif test $# -eq 0; then
197189777a2SCristian Pallares  if test -z "$dir_arg"; then
198189777a2SCristian Pallares    echo "$0: no input file specified." >&2
199189777a2SCristian Pallares    exit 1
200189777a2SCristian Pallares  fi
2011f13f311SSkyrpex  # It's OK to call 'install-sh -d' without argument.
202189777a2SCristian Pallares  # This can happen when creating conditional directories.
203189777a2SCristian Pallares  exit 0
204189777a2SCristian Pallaresfi
205189777a2SCristian Pallares
206189777a2SCristian Pallaresif test -z "$dir_arg"; then
207275def9cSCristian Pallarés  if test $# -gt 1 || test "$is_target_a_directory" = always; then
208275def9cSCristian Pallarés    if test ! -d "$dst_arg"; then
209275def9cSCristian Pallarés      echo "$0: $dst_arg: Is not a directory." >&2
210275def9cSCristian Pallarés      exit 1
211275def9cSCristian Pallarés    fi
212275def9cSCristian Pallarés  fi
213275def9cSCristian Pallarésfi
214275def9cSCristian Pallarés
215275def9cSCristian Pallarésif test -z "$dir_arg"; then
2161f13f311SSkyrpex  do_exit='(exit $ret); exit $ret'
2171f13f311SSkyrpex  trap "ret=129; $do_exit" 1
2181f13f311SSkyrpex  trap "ret=130; $do_exit" 2
2191f13f311SSkyrpex  trap "ret=141; $do_exit" 13
2201f13f311SSkyrpex  trap "ret=143; $do_exit" 15
221189777a2SCristian Pallares
222189777a2SCristian Pallares  # Set umask so as not to create temps with too-generous modes.
223189777a2SCristian Pallares  # However, 'strip' requires both read and write access to temps.
224189777a2SCristian Pallares  case $mode in
225189777a2SCristian Pallares    # Optimize common cases.
226189777a2SCristian Pallares    *644) cp_umask=133;;
227189777a2SCristian Pallares    *755) cp_umask=22;;
228189777a2SCristian Pallares
229189777a2SCristian Pallares    *[0-7])
230189777a2SCristian Pallares      if test -z "$stripcmd"; then
231189777a2SCristian Pallares        u_plus_rw=
232189777a2SCristian Pallares      else
233189777a2SCristian Pallares        u_plus_rw='% 200'
234189777a2SCristian Pallares      fi
235189777a2SCristian Pallares      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
236189777a2SCristian Pallares    *)
237189777a2SCristian Pallares      if test -z "$stripcmd"; then
238189777a2SCristian Pallares        u_plus_rw=
239189777a2SCristian Pallares      else
240189777a2SCristian Pallares        u_plus_rw=,u+rw
241189777a2SCristian Pallares      fi
242189777a2SCristian Pallares      cp_umask=$mode$u_plus_rw;;
243189777a2SCristian Pallares  esac
244189777a2SCristian Pallaresfi
245189777a2SCristian Pallares
246189777a2SCristian Pallaresfor src
247189777a2SCristian Pallaresdo
2481f13f311SSkyrpex  # Protect names problematic for 'test' and other utilities.
249189777a2SCristian Pallares  case $src in
2501f13f311SSkyrpex    -* | [=\(\)!]) src=./$src;;
251189777a2SCristian Pallares  esac
252189777a2SCristian Pallares
253189777a2SCristian Pallares  if test -n "$dir_arg"; then
254189777a2SCristian Pallares    dst=$src
255189777a2SCristian Pallares    dstdir=$dst
256189777a2SCristian Pallares    test -d "$dstdir"
257189777a2SCristian Pallares    dstdir_status=$?
258189777a2SCristian Pallares  else
259189777a2SCristian Pallares
260189777a2SCristian Pallares    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
261189777a2SCristian Pallares    # might cause directories to be created, which would be especially bad
262189777a2SCristian Pallares    # if $src (and thus $dsttmp) contains '*'.
263189777a2SCristian Pallares    if test ! -f "$src" && test ! -d "$src"; then
264189777a2SCristian Pallares      echo "$0: $src does not exist." >&2
265189777a2SCristian Pallares      exit 1
266189777a2SCristian Pallares    fi
267189777a2SCristian Pallares
268189777a2SCristian Pallares    if test -z "$dst_arg"; then
269189777a2SCristian Pallares      echo "$0: no destination specified." >&2
270189777a2SCristian Pallares      exit 1
271189777a2SCristian Pallares    fi
272189777a2SCristian Pallares    dst=$dst_arg
273189777a2SCristian Pallares
274189777a2SCristian Pallares    # If destination is a directory, append the input filename; won't work
275189777a2SCristian Pallares    # if double slashes aren't ignored.
276189777a2SCristian Pallares    if test -d "$dst"; then
277275def9cSCristian Pallarés      if test "$is_target_a_directory" = never; then
278189777a2SCristian Pallares        echo "$0: $dst_arg: Is a directory" >&2
279189777a2SCristian Pallares        exit 1
280189777a2SCristian Pallares      fi
281189777a2SCristian Pallares      dstdir=$dst
282189777a2SCristian Pallares      dst=$dstdir/`basename "$src"`
283189777a2SCristian Pallares      dstdir_status=0
284189777a2SCristian Pallares    else
285275def9cSCristian Pallarés      dstdir=`dirname "$dst"`
286189777a2SCristian Pallares      test -d "$dstdir"
287189777a2SCristian Pallares      dstdir_status=$?
288189777a2SCristian Pallares    fi
289189777a2SCristian Pallares  fi
290189777a2SCristian Pallares
291189777a2SCristian Pallares  obsolete_mkdir_used=false
292189777a2SCristian Pallares
293189777a2SCristian Pallares  if test $dstdir_status != 0; then
294189777a2SCristian Pallares    case $posix_mkdir in
295189777a2SCristian Pallares      '')
296189777a2SCristian Pallares        # Create intermediate dirs using mode 755 as modified by the umask.
297189777a2SCristian Pallares        # This is like FreeBSD 'install' as of 1997-10-28.
298189777a2SCristian Pallares        umask=`umask`
299189777a2SCristian Pallares        case $stripcmd.$umask in
300189777a2SCristian Pallares          # Optimize common cases.
301189777a2SCristian Pallares          *[2367][2367]) mkdir_umask=$umask;;
302189777a2SCristian Pallares          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
303189777a2SCristian Pallares
304189777a2SCristian Pallares          *[0-7])
305189777a2SCristian Pallares            mkdir_umask=`expr $umask + 22 \
306189777a2SCristian Pallares              - $umask % 100 % 40 + $umask % 20 \
307189777a2SCristian Pallares              - $umask % 10 % 4 + $umask % 2
308189777a2SCristian Pallares            `;;
309189777a2SCristian Pallares          *) mkdir_umask=$umask,go-w;;
310189777a2SCristian Pallares        esac
311189777a2SCristian Pallares
312189777a2SCristian Pallares        # With -d, create the new directory with the user-specified mode.
313189777a2SCristian Pallares        # Otherwise, rely on $mkdir_umask.
314189777a2SCristian Pallares        if test -n "$dir_arg"; then
315189777a2SCristian Pallares          mkdir_mode=-m$mode
316189777a2SCristian Pallares        else
317189777a2SCristian Pallares          mkdir_mode=
318189777a2SCristian Pallares        fi
319189777a2SCristian Pallares
320189777a2SCristian Pallares        posix_mkdir=false
321189777a2SCristian Pallares        case $umask in
322189777a2SCristian Pallares          *[123567][0-7][0-7])
323189777a2SCristian Pallares            # POSIX mkdir -p sets u+wx bits regardless of umask, which
324189777a2SCristian Pallares            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
325189777a2SCristian Pallares            ;;
326189777a2SCristian Pallares          *)
327*b3fce824SCristian Pallarés            # $RANDOM is not portable (e.g. dash);  use it when possible to
328*b3fce824SCristian Pallarés            # lower collision chance
329189777a2SCristian Pallares            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
330*b3fce824SCristian Pallarés            trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
331189777a2SCristian Pallares
332*b3fce824SCristian Pallarés            # As "mkdir -p" follows symlinks and we work in /tmp possibly;  so
333*b3fce824SCristian Pallarés            # create the $tmpdir first (and fail if unsuccessful) to make sure
334*b3fce824SCristian Pallarés            # that nobody tries to guess the $tmpdir name.
335189777a2SCristian Pallares            if (umask $mkdir_umask &&
336*b3fce824SCristian Pallarés                $mkdirprog $mkdir_mode "$tmpdir" &&
337*b3fce824SCristian Pallarés                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
338189777a2SCristian Pallares            then
339189777a2SCristian Pallares              if test -z "$dir_arg" || {
340189777a2SCristian Pallares                   # Check for POSIX incompatibilities with -m.
341189777a2SCristian Pallares                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
3421f13f311SSkyrpex                   # other-writable bit of parent directory when it shouldn't.
343189777a2SCristian Pallares                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
344*b3fce824SCristian Pallarés                   test_tmpdir="$tmpdir/a"
345*b3fce824SCristian Pallarés                   ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
346189777a2SCristian Pallares                   case $ls_ld_tmpdir in
347189777a2SCristian Pallares                     d????-?r-*) different_mode=700;;
348189777a2SCristian Pallares                     d????-?--*) different_mode=755;;
349189777a2SCristian Pallares                     *) false;;
350189777a2SCristian Pallares                   esac &&
351*b3fce824SCristian Pallarés                   $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
352*b3fce824SCristian Pallarés                     ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
353189777a2SCristian Pallares                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
354189777a2SCristian Pallares                   }
355189777a2SCristian Pallares                 }
356189777a2SCristian Pallares              then posix_mkdir=:
357189777a2SCristian Pallares              fi
358*b3fce824SCristian Pallarés              rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
359189777a2SCristian Pallares            else
360189777a2SCristian Pallares              # Remove any dirs left behind by ancient mkdir implementations.
361*b3fce824SCristian Pallarés              rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
362189777a2SCristian Pallares            fi
363189777a2SCristian Pallares            trap '' 0;;
364189777a2SCristian Pallares        esac;;
365189777a2SCristian Pallares    esac
366189777a2SCristian Pallares
367189777a2SCristian Pallares    if
368189777a2SCristian Pallares      $posix_mkdir && (
369189777a2SCristian Pallares        umask $mkdir_umask &&
370189777a2SCristian Pallares        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
371189777a2SCristian Pallares      )
372189777a2SCristian Pallares    then :
373189777a2SCristian Pallares    else
374189777a2SCristian Pallares
375189777a2SCristian Pallares      # The umask is ridiculous, or mkdir does not conform to POSIX,
376189777a2SCristian Pallares      # or it failed possibly due to a race condition.  Create the
377189777a2SCristian Pallares      # directory the slow way, step by step, checking for races as we go.
378189777a2SCristian Pallares
379189777a2SCristian Pallares      case $dstdir in
380189777a2SCristian Pallares        /*) prefix='/';;
3811f13f311SSkyrpex        [-=\(\)!]*) prefix='./';;
382189777a2SCristian Pallares        *)  prefix='';;
383189777a2SCristian Pallares      esac
384189777a2SCristian Pallares
385189777a2SCristian Pallares      oIFS=$IFS
386189777a2SCristian Pallares      IFS=/
387275def9cSCristian Pallarés      set -f
388189777a2SCristian Pallares      set fnord $dstdir
389189777a2SCristian Pallares      shift
390275def9cSCristian Pallarés      set +f
391189777a2SCristian Pallares      IFS=$oIFS
392189777a2SCristian Pallares
393189777a2SCristian Pallares      prefixes=
394189777a2SCristian Pallares
395189777a2SCristian Pallares      for d
396189777a2SCristian Pallares      do
3971f13f311SSkyrpex        test X"$d" = X && continue
398189777a2SCristian Pallares
399189777a2SCristian Pallares        prefix=$prefix$d
400189777a2SCristian Pallares        if test -d "$prefix"; then
401189777a2SCristian Pallares          prefixes=
402189777a2SCristian Pallares        else
403189777a2SCristian Pallares          if $posix_mkdir; then
404189777a2SCristian Pallares            (umask=$mkdir_umask &&
405189777a2SCristian Pallares             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
406189777a2SCristian Pallares            # Don't fail if two instances are running concurrently.
407189777a2SCristian Pallares            test -d "$prefix" || exit 1
408189777a2SCristian Pallares          else
409189777a2SCristian Pallares            case $prefix in
410189777a2SCristian Pallares              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
411189777a2SCristian Pallares              *) qprefix=$prefix;;
412189777a2SCristian Pallares            esac
413189777a2SCristian Pallares            prefixes="$prefixes '$qprefix'"
414189777a2SCristian Pallares          fi
415189777a2SCristian Pallares        fi
416189777a2SCristian Pallares        prefix=$prefix/
417189777a2SCristian Pallares      done
418189777a2SCristian Pallares
419189777a2SCristian Pallares      if test -n "$prefixes"; then
420189777a2SCristian Pallares        # Don't fail if two instances are running concurrently.
421189777a2SCristian Pallares        (umask $mkdir_umask &&
422189777a2SCristian Pallares         eval "\$doit_exec \$mkdirprog $prefixes") ||
423189777a2SCristian Pallares          test -d "$dstdir" || exit 1
424189777a2SCristian Pallares        obsolete_mkdir_used=true
425189777a2SCristian Pallares      fi
426189777a2SCristian Pallares    fi
427189777a2SCristian Pallares  fi
428189777a2SCristian Pallares
429189777a2SCristian Pallares  if test -n "$dir_arg"; then
430189777a2SCristian Pallares    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
431189777a2SCristian Pallares    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
432189777a2SCristian Pallares    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
433189777a2SCristian Pallares      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
434189777a2SCristian Pallares  else
435189777a2SCristian Pallares
436189777a2SCristian Pallares    # Make a couple of temp file names in the proper directory.
437189777a2SCristian Pallares    dsttmp=$dstdir/_inst.$$_
438189777a2SCristian Pallares    rmtmp=$dstdir/_rm.$$_
439189777a2SCristian Pallares
440189777a2SCristian Pallares    # Trap to clean up those temp files at exit.
441189777a2SCristian Pallares    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
442189777a2SCristian Pallares
443189777a2SCristian Pallares    # Copy the file name to the temp name.
444189777a2SCristian Pallares    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
445189777a2SCristian Pallares
446189777a2SCristian Pallares    # and set any options; do chmod last to preserve setuid bits.
447189777a2SCristian Pallares    #
448189777a2SCristian Pallares    # If any of these fail, we abort the whole thing.  If we want to
449189777a2SCristian Pallares    # ignore errors from any of these, just make sure not to ignore
450189777a2SCristian Pallares    # errors from the above "$doit $cpprog $src $dsttmp" command.
451189777a2SCristian Pallares    #
452189777a2SCristian Pallares    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
453189777a2SCristian Pallares    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
454189777a2SCristian Pallares    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
455189777a2SCristian Pallares    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
456189777a2SCristian Pallares
457189777a2SCristian Pallares    # If -C, don't bother to copy if it wouldn't change the file.
458189777a2SCristian Pallares    if $copy_on_change &&
459189777a2SCristian Pallares       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
460189777a2SCristian Pallares       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
461275def9cSCristian Pallarés       set -f &&
462189777a2SCristian Pallares       set X $old && old=:$2:$4:$5:$6 &&
463189777a2SCristian Pallares       set X $new && new=:$2:$4:$5:$6 &&
464275def9cSCristian Pallarés       set +f &&
465189777a2SCristian Pallares       test "$old" = "$new" &&
466189777a2SCristian Pallares       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
467189777a2SCristian Pallares    then
468189777a2SCristian Pallares      rm -f "$dsttmp"
469189777a2SCristian Pallares    else
470189777a2SCristian Pallares      # Rename the file to the real destination.
471189777a2SCristian Pallares      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
472189777a2SCristian Pallares
473189777a2SCristian Pallares      # The rename failed, perhaps because mv can't rename something else
474189777a2SCristian Pallares      # to itself, or perhaps because mv is so ancient that it does not
475189777a2SCristian Pallares      # support -f.
476189777a2SCristian Pallares      {
477189777a2SCristian Pallares        # Now remove or move aside any old file at destination location.
478189777a2SCristian Pallares        # We try this two ways since rm can't unlink itself on some
479189777a2SCristian Pallares        # systems and the destination file might be busy for other
480189777a2SCristian Pallares        # reasons.  In this case, the final cleanup might fail but the new
481189777a2SCristian Pallares        # file should still install successfully.
482189777a2SCristian Pallares        {
483189777a2SCristian Pallares          test ! -f "$dst" ||
484189777a2SCristian Pallares          $doit $rmcmd -f "$dst" 2>/dev/null ||
485189777a2SCristian Pallares          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
486189777a2SCristian Pallares            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
487189777a2SCristian Pallares          } ||
488189777a2SCristian Pallares          { echo "$0: cannot unlink or rename $dst" >&2
489189777a2SCristian Pallares            (exit 1); exit 1
490189777a2SCristian Pallares          }
491189777a2SCristian Pallares        } &&
492189777a2SCristian Pallares
493189777a2SCristian Pallares        # Now rename the file to the real destination.
494189777a2SCristian Pallares        $doit $mvcmd "$dsttmp" "$dst"
495189777a2SCristian Pallares      }
496189777a2SCristian Pallares    fi || exit 1
497189777a2SCristian Pallares
498189777a2SCristian Pallares    trap '' 0
499189777a2SCristian Pallares  fi
500189777a2SCristian Pallaresdone
501189777a2SCristian Pallares
502189777a2SCristian Pallares# Local variables:
503189777a2SCristian Pallares# eval: (add-hook 'write-file-hooks 'time-stamp)
504189777a2SCristian Pallares# time-stamp-start: "scriptversion="
505189777a2SCristian Pallares# time-stamp-format: "%:y-%02m-%02d.%02H"
506189777a2SCristian Pallares# time-stamp-time-zone: "UTC"
507189777a2SCristian Pallares# time-stamp-end: "; # UTC"
508189777a2SCristian Pallares# End:
509