#!/bin/ksh
##
## GNU install(1) emulator for Solaris install(1B) and AIX installbsd(1)
## Copyright (c) 2008-2009 SATOH Fumiyasu @ OSS Technology, Inc.
##               <http://www.osstech.co.jp/>
##
## License: GNU General Public License version 2 or later
## Date: 2009-03-28, since 2008-10-31
##

cmd_name="$0"
uname=`uname`

case "$uname" in
Linux)
  exec /usr/bin/install ${1+"$@"}
  exit 1
  ;;
SunOS)
  install_cmd="/usr/ucb/install"
  ;;
AIX)
  install_cmd="/usr/bin/installbsd -c"
  ;;
*)
  echo "$cmd_name: ERROR: Unsupported platform: $uname" 1>&2
  exit 1
  ;;
esac

function install_wrapper {
  local run=${INSTALL_WRAPPER_RUN:-}
  local mode= owner= group= preserve_time=
  local create_dirs= create_parent= dst_dir=
  local opts
  set -A opts

  ## In a function, /bin/ksh makes OPTIND and OPTARG as local automatically!
  #local OPTIND=1
  #local OPTARG
  local OPT
  while getopts bcdDm:o:g:pst: OPT; do
    case "$OPT" in
    [bc])
      : Ignore
      ;;
    d)
      create_dirs="yes"
      ;;
    D)
      create_parent="yes"
      ;;
    o)
      owner="$OPTARG"
      set -A opts -- "${opts[@]}" "-$OPT" "$OPTARG"
      ;;
    g)
      group="$OPTARG"
      set -A opts -- "${opts[@]}" "-$OPT" "$OPTARG"
      ;;
    p)
      preserve_time="yes"
      ;;
    t)
      dst_dir="$OPTARG"
      ;;
    m)
      mode="$OPTARG"
      set -A opts -- "${opts[@]}" "-$OPT" "$OPTARG"
      ;;
    *)
      set -A opts -- "${opts[@]}" "-$OPT"
      if [ -n "${OPTARG:+set}" ]; then
	set -A opts -- "${opts[@]}" "$OPTARG"
      fi
      ;;
    esac
  done
  shift $(($OPTIND - 1))

  if [ $# -eq 0 ]; then
    echo "Usage: $cmd_name [OPTIONS] FILES [...] DIR" 1>&2
    return 1
  fi

  if [ -n "$create_dirs" ]; then
    ## AIX: installbsd(1) does not have the -d option
    $run /bin/mkdir -p ${mode:+"-m$mode"} "$@" || return $?
    [ -n "$owner" ] && { $run /bin/chown -h "$owner" "$@" || return $?; } || :
    [ -n "$group" ] && { $run /bin/chgrp -h "$group" "$@" || return $?; } || :
    return 0
  fi

  local srcs dst
  set -A srcs --
  if [ -n "$dst_dir" ]; then
    set -A srcs -- ${1+"$@"}
    dst="$dst_dir"

    ## Inogre the -D option if the -t DIR (i.e. $dst_dir) specified.
  else
    while [ $# -gt 1 ]; do
      set -A srcs -- "${srcs[@]}" "$1"; shift
    done
    dst="$1"; shift

    ## The -D option is exclusive with the -t DIR option,
    ## and is valid only when the number of srcs is equal to 1.
    if [ -n "$create_parent" ] && [ "${#srcs[@]}" -eq 1 ]; then
      $run /bin/mkdir -p "${dst%/*}" || return $?
    fi
  fi

  $run $install_cmd "${opts[@]}" "${srcs[@]}" "$dst" || return $?

  ## Solaris: The chmod(2) clears setuid/gid bits if the caller has no
  ## {PRIV_FILE_SETID} privilege. See the chown(2) manpage for details.
  ## That is why the install(1B) command ignores setuid/gid bits
  ## from the specified mode because it do the chown(2) after
  ## the chmod(2). -- fumiyas, 2008-10-31
  case "$mode" in [2-7][0-7][0-7][0-7]) ;; *) mode="" ;; esac

  for src in "${srcs[@]}"; do
    [ -f "$dst" ] && dst_file="$dst" || dst_file="$dst/${src##*/}"
    [ -n "$mode" ] && { $run /bin/chmod "$mode" "$dst_file" || return $?; } || :
    [ -n "$preserve_time" ] && { $run /bin/touch -r "$src" "$dst_file" || return $?; } || :
  done
}

install_wrapper ${1+"$@"}
exit $?

