#!/usr/pkg/bin/ksh93
# $XConsortium: dtappintegrate.src /main/4 1996/04/21 19:27:37 drk $
# ###################################################################
#                                                                   #
#  dtappintegrate                                                   #
#                                                                   #
# (c) Copyright 1996 Digital Equipment Corporation.                 #
# (c) Copyright 1993,1994,1996 Hewlett-Packard Company.             #
# (c) Copyright 1993,1994,1996 International Business Machines Corp.#
# (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.               #
# (c) Copyright 1996 Novell, Inc.                                   #
# (c) Copyright 1996 FUJITSU LIMITED.                               #
# (c) Copyright 1996 Hitachi.                                       #
# (c) Copyright 1993, 1994 Unix System Labs, Inc., a subsidiary of  #
#     Novell, Inc.                                                  #
#                                                                   #
#  This is the dt  application integration script to assist         #
#  in integrating applications into COSE Desktop Environment.       #
#                                                                   #
#  syntax: dtappintegrate -s <source> [-t <target>] [-l <lang>] [-u]#
#  where                                                            #
#        -s           indicates application's root location.        #
#        source       the path name of the application's root.      #
#        -t           indicates a new location for the              #
#                       application's group files.                  #
#        target       the path name of the target location.         #
#        -l           indicates the language for this application.  #
#        language     the language name as used by $LANG            #
#                       environment variable.                       #
#        -u           indicates to unintegrate the application.     #
#                                                                   #
#                                                                   #
# ###################################################################
# ------------------------------------------------------------------#
#  ShowSyntax                                                       #
#                                                                   #
#       This routine is used to echo the command line syntax.       #
#                                                                   #
#       input:                                                      #
#         none                                                      #
#                                                                   #
#       return codes:                                               #
#         0   - success                                             #
#                                                                   #
# ------------------------------------------------------------------#
function ShowSyntax
{
  echo "Usage: $SCRIPT_NAME -s <source> [-t <target>] [-l <language>] [-u]" | tee -a "$LOGFILE"
  return 0
}
# ------------------------------------------------------------------#
#  GetAbsolutePath                                                  #
#                                                                   #
#       This routine is to resolve a path to its actual path,       #
#       following links, etc.                                       #
#                                                                   #
#       input:                                                      #
#         $1 = path                                                 #
#                                                                   #
#       output:                                                     #
#         absolute path                                             #
#                                                                   #
# ------------------------------------------------------------------#
function GetAbsolutePath
{
  if [ "/" = "$1" ]; then
     echo "$2"
  elif [ -L "$1" ]; then
     GetAbsolutePath "$(find . -name "$1" | awk '{print $NF}')" "$2"
  else
  {
     if [ "." = "$1" ] || [ ".." = "$1" ]; then
        GetAbsolutePath / /"$(basename "$1")""$2"
     else
        GetAbsolutePath "$(dirname "$1")" /"$(basename "$1")""$2"
     fi
  }
  fi
}
# ------------------------------------------------------------------#
#  GetRelativePath                                                  #
#                                                                   #
#       This routine is used to determine the relative path of      #
#       of the source path from the target path.                    #
#                                                                   #
#       input:                                                      #
#         $1 = absolute source path                                 #
#         $2 = absolute target path                                 #
#                                                                   #
#       return codes:                                               #
#         0   - success                                             #
#         1   - error                                               #
#                                                                   #
# ------------------------------------------------------------------#
function GetRelativePath
{
  $AWK 'BEGIN {
          src = ARGV[1]
          dest = ARGV[2]
          a = split(src, A, "/");
          b = split(dest, B, "/");
          s = 0;
           for (i = 2; i < a && i < b; i++) {
             if (match(A[i],B[i])) {
                ++s;
             } else {
                break;
             }
           }
          for (i = 0 ; i <= (a - s - 2); i++) {
             printf("../")
          }
          for (i = 2 + s; i <= b; i++) {
             printf("%s%s", B[i], (i < b) ? "/":"\n");
          }
  }' "$2" "$1"
}
# ------------------------------------------------------------------#
#  LinkCfgs                                                         #
#                                                                   #
#       This routine creates the actual links from the application's#
#       root config files to the target location.                   #
#                                                                   #
#       input:                                                      #
#                                                                   #
#       return codes:                                               #
#         n   - number of files integrated or unintegrated          #
#                                                                   #
# ------------------------------------------------------------------#
function LinkCfgs
{
  typeset source=$1 target=$2 torf=$3 spath="" tpath="" cfgfile="" rpath=""
  typeset pattern="" files=""
  shift;shift;shift
  if [[ -L $source || -L $(dirname "$source") ]]
    then
    spath=$(GetAbsolutePath "$source")
  else
    spath=$source
  fi
  if [[ -L $target || -L $(dirname "$target") ]]
    then
    tpath=$(GetAbsolutePath "$target")
  else
    tpath=$target
  fi
  rpath=""
  for pattern in "$@"
  do
    if [[ $pattern = "(*)" ]]
      then
      files=$(ls -d "$source/"* 2>/dev/null)
    else
      files=$(ls -d "$source/$pattern" 2>/dev/null)
    fi
    if $files
      then
      count=$(echo "$files" | wc -w)
      for cfgfile in $files
      do
        basecfg=$(basename "$cfgfile")
        if [[ $torf = TRUE ]]
          then
          if [[ $rpath = "" ]]
            then
            rpath=$(GetRelativePath "$spath" "$tpath")
          fi
          rm -f "$tpath"/"$basecfg"
          echo "ln -sf $rpath/$basecfg $tpath/$basecfg" >> "$LOGFILE"
          ln -sf "$rpath/$basecfg" "$tpath/$basecfg" >> "$LOGFILE" 2>&1
        else
          if rm "$tpath"/"$basecfg" >/dev/null 2>&1
            then
            echo "rm $tpath/$basecfg" >> "$LOGFILE"
          fi
        fi
      done
    fi
  done
  return "$count"
}
# ------------------------------------------------------------------#
#  IntegrateUnintegrate                                             #
#                                                                   #
#       This routine integrates the files into the cose desktop     #
#       environment or unintegrates them depending on the boolean   #
#       input parameter.                                            #
#                                                                   #
#       input:                                                      #
#         $1 = Integrate or not. TRUE=integrate. FALSE=unintegrate. #
#                                                                   #
#       return codes:                                               #
#         0   - work was done                                       #
#         1   - no work done                                        #
#                                                                   #
# ------------------------------------------------------------------#
function IntegrateUnintegrate
{
  typeset torf=$1 srcs="" trgs="" fpats="" tpath="" spath="" rpath="" languages="" lang=""
  typeset srcabs="" trgabs=""
  integer i=0 icons=0 types=1 help=2 appmgr=3
  srcabs=$(GetAbsolutePath "$APP_ROOT")
  trgabs=$(GetAbsolutePath "$APP_TARGET")
  srcs[0]=$srcabs$ICONS$APP_LANG
  srcs[1]=$srcabs$TYPES$APP_LANG
  srcs[2]=$srcabs$HELP$APP_LANG
  srcs[3]=$srcabs$APPMANAGER$APP_LANG
  trgs[0]=$trgabs$ICONS$APP_LANG
  trgs[1]=$trgabs$TYPES$APP_LANG
  trgs[2]=$trgabs$HELP$APP_LANG
  trgs[3]=$trgabs$APPMANAGER$APP_LANG
  fpats[0]="$PIXMAP_FILES $BITMAP_FILES"
  fpats[1]="$ACTIONDB_FILES"
  fpats[2]="$HELPVOLUME_FILES_OLD $HELPVOLUME_FILES_NEW $HELPFAMILY_FILES"
  fpats[3]="$APPMAN_FILES"
  rc=1
  while (( i < 4 ))
  do
    if [[ $APP_LANG = "" ]]
      then
      if languages=$(ls -d "${srcs[i]}"/COMMENT_STAR 2>/dev/null)
        then
        for lang in $languages
        do
          baselang=$(basename "$lang")
          if [[ -d $lang ]]
            then
            if [[ $torf = TRUE ]]
              then
              if [[ ! -d ${trgs[i]}/$baselang ]]
                then
                mkdir -p "${trgs[i]}"/"$baselang"
              fi
            fi
            if ! LinkCfgs "${srcs[i]}/$baselang" "${trgs[i]}/$baselang" "$torf" "${fpats[i]}"
              then
              rc=0
            fi
          fi
        done
      fi
    else
      if ! LinkCfgs "${srcs[i]}" "${trgs[i]}" "$torf" "${fpats[i]}"
        then
        rc=0
      fi
    fi
    i=$((i+1))
  done
  return $rc
}
# ------------------------------------------------------------------#
#  ExitOut                                                          #
#                                                                   #
#       Exit the program.                                           #
#                                                                   #
#       input:                                                      #
#         $1 = return code                                          #
#                                                                   #
# ------------------------------------------------------------------#
function ExitOut
{
  typeset retcode=$1
  echo "<<<<<<< END  OF  APPLICATION INTEGRATION >>>>>>>" >> "$LOGFILE"
  echo "See $LOGFILE file for more information"
  exit "$retcode"
}
#  ----<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>-----
#  ----<<<<<<<<<<<.-------------------------.>>>>>>>>>>>-----
#  ----<<<<<<<<<<<|                         |>>>>>>>>>>>-----
#  ----<<<<<<<<<<<|  START OF MAIN ROUTINE  |>>>>>>>>>>>>-----
#  ----<<<<<<<<<<<|_________________________|>>>>>>>>>>>-----
#  ----<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>-----
# -------------------------------------------------------------------
#  Initialize variables
# -------------------------------------------------------------------
sFLAG=0
tFLAG=0
uFLAG=0
TYPES=/types
APPMANAGER=/appmanager
ICONS=/icons
HELP=/help
APPCONFIG=/dt/appconfig
CONFIG_TOP=/usr/pkg/usr/pkg/etc/dt
DT=$(basename $CONFIG_TOP)
APP_TARGET=${CONFIG_TOP%/$DT}$APPCONFIG
PIXMAP_FILES="*.pm"
BITMAP_FILES="*.bm"
HELPVOLUME_FILES_OLD="*.hv"
HELPVOLUME_FILES_NEW="*.sdl"
HELPFAMILY_FILES="*.hf"
ACTIONDB_FILES="*.dt"
APPMAN_FILES="(*)"
ID=$(id)
LOGFILE=$(mktemp /tmp/dtappint.logXXXXXXXXXXXXXXXX)
PATH=/usr/pkg/dt/bin:/usr/bin:/bin
# -------------------------------------------------------------------
#  Save application's name in variable.
# -------------------------------------------------------------------
SCRIPT_NAME=$0
# -------------------------------------------------------------------
#  Check if root user.  Exit if not.
# -------------------------------------------------------------------
ID=${ID##*uid=}
ID=${ID#*\(}
ID=${ID%%\)*}
if [[ $ID != root ]]
   then
   echo "Error: Must be root user to run $0!" >&2
   exit 3
fi
# -------------------------------------------------------------------
#  Put prolog into log file.
# -------------------------------------------------------------------
echo "<<<<<<< START OF APPLICATION INTEGRATION >>>>>>>" > "$LOGFILE"
# -------------------------------------------------------------------
#  Put the date of application integration into the log file.
# -------------------------------------------------------------------
date >> "$LOGFILE"
# -------------------------------------------------------------------
#  Put the command line into the log file.
# -------------------------------------------------------------------
echo "$SCRIPT_NAME $*" >> "$LOGFILE"
# -------------------------------------------------------------------
#  Check if there are no command line arguments.
#  If none, then display the command syntax.
# -------------------------------------------------------------------
if [[ $# = 0 ]]
  then
  ShowSyntax
  ExitOut 0
fi
# -------------------------------------------------------------------
#  Parse the command line into flags and variables.
# -------------------------------------------------------------------
while getopts s:t:l:u  flag
do
  case $flag in
     s)   sFLAG=1
          APP_ROOT="$OPTARG";;
     t)   tFLAG=1
          APP_TARGET="$OPTARG";;
     l)   APP_LANG="$OPTARG";;
     u)   uFLAG=1;;
     ?)   echo " "
          ShowSyntax
          ExitOut 2;;
  esac
done
# -------------------------------------------------------------------
#  Check if application's root was specified and is valid.
# -------------------------------------------------------------------
if [[ $sFLAG = 0 ]]
  then
  echo "Error: Did not specify -s option!" >&2
  ExitOut 4
else
  if [[ ! -d $APP_ROOT ]]
    then
    APP_PATH=$APP_ROOT
    echo "Error: $APP_PATH is not a directory!" >&2
    ExitOut 4
  fi
  if [[ ! -r $APP_ROOT ]] || [[ ! -x $APP_ROOT ]]
    then
    APP_PATH=$APP_ROOT
    echo "Error: Can not read $APP_PATH directory!" >&2
    ExitOut 4
  fi
fi
if [[ ${APP_ROOT%%/COMMENT_STAR} != "" ]]
  then
  APP_ROOT=$(pwd)/$APP_ROOT
fi
# -------------------------------------------------------------------
#  If target is specified, do some sanity checks on this path.
# -------------------------------------------------------------------
if [[ $tFLAG = 1 ]]
  then
  if [[ ! -d $APP_TARGET ]]
    then
    APP_PATH=$APP_TARGET
    echo "Error: $APP_PATH is not a directory!" >&2
    ExitOut 4
  fi
  if [[ ! -r $APP_TARGET ]] || [[ ! -x $APP_TARGET ]]
    then
    APP_PATH=$APP_TARGET
    echo "Error: Can not read $APP_PATH directory!" >&2
    ExitOut 4
  fi
  if [[ ${APP_TARGET%%/COMMENT_STAR} != "" ]]
    then
    APP_TARGET=$(pwd)/$APP_TARGET
  fi
fi
# -------------------------------------------------------------------
#  Set up variables.
# -------------------------------------------------------------------
APP_ROOT=$APP_ROOT$APPCONFIG
if [[ $APP_LANG != "" ]]
  then
  APP_LANG=/$APP_LANG
fi
# -------------------------------------------------------------------
#  Unintegrate the application by un-doing the integration steps.
# -------------------------------------------------------------------
if [[ $uFLAG = 1 ]]
  then
  if IntegrateUnintegrate FALSE
    then
    echo "Unintegration Complete"
  else
    echo "No files to unintegrate"
  fi
  ExitOut 0
fi
# -------------------------------------------------------------------
#  See if these directories exist.  If they don't, then create them.
# -------------------------------------------------------------------
for i in $APP_TARGET$ICONS$APP_LANG $APP_TARGET$TYPES$APP_LANG $APP_TARGET$APPMANAGER$APP_LANG $APP_TARGET$HELP$APP_LANG
 do
  if [[ ! -d $i ]]
    then
    mkdir -p "$i"
  fi
 done
# -------------------------------------------------------------------
#  Determine which awk to use.
# -------------------------------------------------------------------
if ! type nawk > /dev/null 2>&1
  then
  AWK="awk"
else
  AWK="nawk"
fi
# -------------------------------------------------------------------
#  Integrate the application.
# -------------------------------------------------------------------
if IntegrateUnintegrate TRUE
  then
  echo "Integration Complete"
else
  echo "No files to integrate"
fi
# -------------------------------------------------------------------
#  Exit
# -------------------------------------------------------------------
ExitOut 0
