#!/bin/sh
#
#	extman, Extension Manager
#
#	(c) 1993, Harald Schlangmann
#
#	The code is copyright 1993 by Harald Schlangmann.
#	Permission is granted for noncommercial redistribution/use
#	of this program.

#	Some defaults

ASKUSER=yes
APP=
ACTION=

#	Build help file

USAGE=/tmp/extman$$help
EXTMAN=`basename $0`

cat <<EOH > ${USAGE}

                          Extension Manager v1.0

     (c) 1993 Harald Schlangmann <schlangm@informatik.uni-muenchen.de>
  Permission is granted for noncommercial redistribution/use of this program.

Usage: $EXTMAN <application> [<options>] (-add <new_ext> <old_ext>|
          -remove <old_ext>|-list|-default)

  where <application> is the name of a application wrapper <application>.app
  either in the current directory or in Workspace's default database entry 
  ApplicationPaths and <options> is out of

    -force	don't ask user for patch confirmation,
    -help	display this message.

  $EXTMAN adds/removes/lists extensions supported by the named <application>.
  The \`\`default'' action reverts all previous changes using a file
  <application>.origheader inside of the application wrapper <application>.app.

  Examples:
    # Show extensions provided by Edit
    sh> extman Edit -list
  
    # Add .latex as a synonym for .ltx
    sh> extman TeXmenu -add latex ltx
    
    # Don't let TeXview advertise it's .tex extension
    sh> extman TeXview -remove tex

  Limitations:
    o  The patched <application> must support the new extension. When
       designing your application to be used with this script, you may
       read the section __ICON __header to get the currently available
       extensions.
    o  No new extension tiffs can be added - instead the add action uses
       the tiff provided by the <old_ext>.
    o  This script requires NeXTSTEP 3.1 DEVELOPER to be installed.

EOH

#	Check if NS Developer is installed...

if [ ! -f /bin/segedit ]
  then
    echo $EXTMAN requires NS DEVELOPER to be installed! Sorry...
    exit 1
  fi

#	Parse command line

while [ $# -ge 1 ]
  do
    case $1 in
      -f*)
      	ASKUSER=no ;;
      -a*)
        ACTION=add
	ARG1=$2
	ARG2=$3
	shift
	shift ;;
      -l*)
        ACTION=list ;;
      -r*)
        ACTION=remove
	ARG1=$2
	shift ;;
      -d*)
        ACTION=default ;;
      -*)
        /usr/ucb/more ${USAGE}
        /bin/rm ${USAGE}
        exit 1 ;;
      *)
        if [ ${APP}x = x ]
	   then
	     APP=$1
	   else
             /usr/ucb/more ${USAGE}
             /bin/rm ${USAGE}
             exit 1
	   fi
    esac
    shift
  done

#	One action must be specified

if [ ${ACTION}x = x ]
  then
    more ${USAGE}
    /bin/rm ${USAGE}
    exit 1
  fi

#	Find application binary

APPLICATIONPATHS=`dread Workspace ApplicationPaths 2> /dev/null`

if [ ${APPLICATIONPATHS}x = x ]
  then
    APPLICATIONPATHS=${HOME}/Apps:/LocalApps:/NextApps:/NextDeveloper/Apps
    APPLICATIONPATHS=${APPLICATIONPATHS}:/NextAdmin:/NextDeveloper/Demos
  fi

#	First, we search in current folder, then in APPLICATIONPATHS

if [ ! -f ${APP}.app/${APP} ]
  then
    APPFULL=
    for PATH in `echo ${APPLICATIONPATHS} | tr ':' ' '`
      do
        APPFULL=`/usr/bin/find ${PATH} -name ${APP}.app -print \
	  -o -name '*.app' -prune | /usr/ucb/head -1`
        if [ ! ${APPFULL}x = x -a -f ${APPFULL}/${APP} ]
          then
	    APPFULL=${APPFULL}/${APP}
            break
          else
            APPFULL=
          fi
      done
  else
    APPFULL=${APP}.app/${APP}
  fi

if [ ${APPFULL}x = x ]
  then
    echo ${EXTMAN}: Cannot find application \"${APP}\"...
    /bin/rm ${USAGE}
    exit 1
  fi

#	Check whether binary is MAB...

set `lipo /NextApps/Edit.app/Edit -info`
if [ $1x != Non-fatx ]
  then
    echo ${EXTMAN} is currently not able to handle MABs! Sorry...
    exit 1
  fi 

#	Check whether binary is read(-write)

if [ ! -r ${APPFULL} -o \( ! ${ACTION} = list -a ! -w ${APPFULL} \) ]
  then
    echo ${EXTMAN}: We are not allowed to read/patch \"${APPFULL}\"
    /bin/rm ${USAGE}; exit 1
  fi

#	Extract header-information

HEADER=/tmp/extman$$header
NEWHEADER=/tmp/extman$$header.new
if /bin/segedit ${APPFULL} -extract __ICON __header ${HEADER}
  then
    :
  else
    echo ${EXTMAN}: Cannot extract extension information from \"${APPFULL}\"...
    /bin/rm ${USAGE}
    exit 1
  fi

#	Perform action

case ${ACTION} in
  list)
    echo -n "${APP}.app recognizes extensions "
    /bin/cat ${HEADER} | /bin/awk 'BEGIN { first = 1 }
      $1 == "S" {
        if( first ) {
	  first = 0
	  printf "%s",$2
	} else
          printf ", %s", $2
      }
      END { 
        printf ".\n"
      }' ;;
  remove)
      if /bin/awk 'BEGIN { notpatched = 1 }
        {
          if( $1=="S" && $2=="'${ARG1}'" ) {
	    notpatched = 0
	  } else
	    print
	}
	END {
	  if( notpatched )
	    exit 1
	}' ${HEADER} > ${NEWHEADER}
	then
	  :
	else
	  echo ${EXTMAN}: Sorry, cannot find extension \"${ARG1}\"...
	  /bin/rm ${HEADER} ${NEWHEADER} ${USAGE}
	  exit 1
	fi ;;
  add)
      if /bin/awk 'BEGIN { notpatched = 1 }
        {
	  if( $1=="S" && $2=="'${ARG2}'" ) {
	    app=$3
	    tiff=$4
	    notpatched = 0
	    print
	  } else if( $1=="S" && $2=="'${ARG1}'" ) {
	    exit 1
	  } else if( $0!="" )
	    print
	}
	END {
	  if( notpatched )
	     exit 1
	  else
	     printf "S\t%s\t%s\t%s\n","'${ARG1}'",app,tiff
	}' ${HEADER} > ${NEWHEADER}
	then
	  :
	else
	  echo ${EXTMAN}: Sorry, either cannot find extension \"${ARG2}\" or
	  echo ${EXTMAN}: extension \"${ARG1}\" already exists...
	  /bin/rm ${HEADER} ${NEWHEADER} ${USAGE}
	  exit 1
	fi ;;
  default)
    if [ -f ${APPFULL}.origheader ]
      then
        /bin/cp ${APPFULL}.origheader ${NEWHEADER}
      else
        echo ${EXTMAN}: ${APP}.app seems to be in default state...
	/bin/rm ${HEADER} ${USAGE}
	exit 1
      fi
    ;;
esac

#	Ask user for patch-confirmation

if [ ${ASKUSER} = yes -a ! ${ACTION} = list ]
  then
    echo -n Ok patching \"${APPFULL}\"? [y/n]" "
    read PERFORMPATCH
    case ${PERFORMPATCH} in
      [Yy]*)
      	;;
      *)
        echo ${EXTMAN}: Nothing patched...
        /bin/rm ${USAGE} ${HEADER} ${NEWHEADER}
	exit 1
    esac
  fi

#	Manage .origheader

if [ ! ${ACTION} = list ]
  then
    if [ ! -f ${APPFULL}.origheader ]
      then
        /bin/cp ${HEADER} ${APPFULL}.origheader
      fi
  fi

#	Patch the binary

if [ ! ${ACTION} = list ]
  then
    /bin/cp ${APPFULL} ${APPFULL}.orig
    if /bin/segedit ${APPFULL}.orig -replace __ICON __header ${NEWHEADER} \
      -output ${APPFULL}
      then
        echo ${EXTMAN}: Application \"${APP}.app\" successfully patched...
	/bin/rm ${APPFULL}.orig
      else
        echo ${EXTMAN}: Error occured during patching...
	/bin/mv ${APPFULL}.orig ${APPFULL}
	/bin/rm ${NEWHEADER} ${USAGE} ${HEADER}
	exit 1
      fi	
  fi

#	Remove .origheader when ACTION==default

if [ ${ACTION} = default ]
  then
    /bin/rm ${APPFULL}.origheader
  fi

#	Finished, clean up

/bin/rm ${USAGE} ${HEADER}
