#!/bin/ksh
##
## GNU install(1) emulator for Solaris install(1B) and AIX installbsd(1)
## Copyright (c) 2008-2011 SATOH Fumiyasu @ OSS Technology, Inc.
##               <http://www.osstech.co.jp/>
##
## License: GNU General Public License version 2 or later
## Date: 2011-07-14, 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"
  group=$(/usr/bin/id |/bin/sed -n 's/^[^=]*=[^=]*=[0-9]*(\([^)]*\)).*$/\1/p')
  ## Default group for the installbsd -g option is "staff"!
  ## Override it by the user's primary group...
  if [ -z "$group" ];then
    echo "$cmd_name: ERROR: Your primary group not detected" 1>&2
    exit 1
  fi
  set -- -g "$group" ${1+"$@"}
  ;;
*)
  echo "$cmd_name: ERROR: Unsupported platform: $uname" 1>&2
  exit 1
  ;;
esac

function install_wrapper {
  typeset run=${INSTALL_WRAPPER_RUN:-}
  typeset backup= backup_suffix="~"
  typeset mode= owner= group= preserve_time=
  typeset create_dirs= create_parent= dst_dir=
  typeset opts
  set -A opts

  ## In a function, /bin/ksh makes OPTIND and OPTARG as local automatically.
  #typeset OPTIND=1
  #typeset OPTARG
  typeset OPT
  while getopts cbS:dDm:o:g:pst: OPT; do
    case "$OPT" in
    c)
      : Ignore
      ;;
    b)
      backup="set"
      ;;
    S)
      backup_suffix="$OPTARG"
      ;;
    d)
      create_dirs="set"
      ;;
    D)
      create_parent="set"
      ;;
    o)
      owner="$OPTARG"
      set -A opts -- "${opts[@]}" "-$OPT" "$OPTARG"
      ;;
    g)
      group="$OPTARG"
      set -A opts -- "${opts[@]}" "-$OPT" "$OPTARG"
      ;;
    p)
      preserve_time="set"
      ;;
    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

  typeset 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

  if [ -n "$backup" ]; then
    for src in "${srcs[@]}"; do
      [ -d "$dst" ] && dst_file="$dst/${src##*/}" || dst_file="$dst"
      if [ -f "$dst_file" ]; then
	$run cp -p "$dst_file" "$dst_file$backup_suffix" || return $?
      fi
    done
  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
    [ -d "$dst" ] && dst_file="$dst/${src##*/}" || dst_file="$dst"
    [ -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 $?

