#!/usr/bin/ksh

##############################################################################
#                                                                            #
#  DON'T CHANGE ANYTHING BELOW HERE                                          #
#                                                                            #
##############################################################################

PROGNAME=`basename $0`
VERSION="MARKER_PATCHLEVEL"
# $Header: /diskb/home/alexis/dev/support/bin/RCS/shinstall.shpp,v 1.3 1999/01/06 18:09:23 alexis Exp $'

usage()
{
    { 
        echo "Usage: $PROGNAME [ -n ] [ -m <mode> ] [ -o <owner> ] [ -g <group> ] <file> ... <directory>"
        echo "       $PROGNAME [ -n ] [ -m <mode> ] [ -o <owner> ] [ -g <group> ] -d <directory> ..."
        echo "       $PROGNAME -V"
    } >&2
    exit 2
}

main()
{
    VERBOSE_LEVEL=2
    GROUP=unset
    OWNER=unset
    MODE=unset
    FILE_MODE=644
    OPMODE=files
    DO=

    while [ "X$1" != X ]; do
        case "$1" in
            -V) if expr "$VERSION" : 'P.*R$' > /dev/null; then
                    warning "this is a development version; use 'ident' for version information"
                    exit 1 
                else                
                    echo "$PROGNAME version $VERSION"
                    exit 0
                fi ;;
            -debug) [ "X$2" = X ] && usage 
                VERBOSE_LEVEL=$2 
                shift ;;
            -v) VERBOSE_LEVEL=3 ;;
            -g) [ "X$2" = X ] && usage
                GROUP=$2 
                shift ;;
            -n) DO=echo ;;
            -o) [ "X$2" = X ] && usage
                OWNER=$2 
                shift ;;
            -d) OPMODE=directories ;;
            -m) [ "X$2" = X ] && usage
                MODE=$2
                shift ;;
            -*) usage ;;
            *)  break ;;
        esac
        shift
    done


    if [ OPMODE = directories -a $MODE != unset ]; then
        DIR_MODE = $MODE
    else
        [ $MODE != unset ] && FILE_MODE=$MODE
        for I in `echo $FILE_MODE | sed -e 's/^.\(...\)$/\1/' -e 's/\(.\)/\1 /g'`; do
            case $I in
                4) I=5 ;;
                6) I=7 ;;
                *) ;;
            esac
            DIR_MODE="$DIR_MODE$I"
        done
    fi

    [ "X$1" = X ] && usage
    if [ $OPMODE = directories ]; then
        DIR_MODE=$MODE
        process_objects $*
    else 
        for ARG in $*; do
            [ ! -f $ARG ] && break
            FILES="$FILES $ARG"
            shift
        done
        [ "X$1" = X -o "X$2" != X -o -f $1 -o "X$FILES" = X ] && usage
        process_objects $1
    fi
}

process_objects()
{
    for DIR in $*; do
        DIR_COMPONENTS=`echo $DIR | sed 's%/% %g'`
        expr "$DIR_COMPONENTS" : ' ' > /dev/null && DIR_COMPONENTS="/$DIR_COMPONENTS"
        debug 5 process_objects: calling: process_path $DIR_COMPONENTS
        process_path $DIR_COMPONENTS
    done
}

process_path()
{
    if [ -d $1 ]; then
        if [ "X$2" != X ]; then
            [ $1 = / ] && T=/$2 || T=$1/$2
            shift; shift
            set $T "$@"
            process_path "$@"
        elif [ $OPMODE = files ]; then
            for FILE in $FILES; do
                $DO cp $FILE $1 || error -f "can't cp $FILE $1"
                [ $1 = / ] && T=/$FILE || T=$1/$FILE
                fixperms $FILE_MODE $T
	    done
        fi
    else
        $DO mkdir $1 || error -f "$1: can't mkdir $1"
        if [ "X$2" != X ]; then
            [ $1 = / ] && T=/$2 || T=$1/$2
            shift; shift
            set $T "$@"
            process_path "$@"
            fixperms $DIR_MODE `dirname $1`
        else
            if [ $OPMODE = files ]; then
                for FILE in $FILES; do
                    $DO cp $FILE $1 || error -f "can't cp $FILE $1"
                    [ $1 = / ] && T=/$FILE || T=$1/$FILE
                    fixperms $FILE_MODE $T
	        done
	    fi
	    fixperms $DIR_MODE $1
        fi
    fi
}

fixperms()
{
    [ $OWNER = unset ] || $DO chown $OWNER $2 || error -f "$1: can't chown $OWNER $2"
    [ $GROUP = unset ] || $DO chgrp $GROUP $2 || error -f "$1: can't chgrp $GROUP $2"
    [ $1     = unset ] || $DO chmod $1     $2 || error -f "$1: can't chmod $1 $2"
}

###############################################################################
#
#  SHELL LIBRARY OF HANDY FUNCTIONS
#
###############################################################################

###############################################################################
#
#  IMPORTANT NOTES
#
#  1.	Any calls to 'error' made *inside* this file, *must* be supplied with
#       -e or -ne options. This is because we have no way of knowing the
#       value of ERRORS_CAUSE_EXITS.
#
###############################################################################

# $Header: /diskb/home/alexis/dev/support/lib/RCS/utils.sh.shpp,v 1.8 1999/01/06 18:20:27 alexis Exp $

###############################################################################
#
#  RESILIANT MESSAGING FUNCTIONS 
#
###############################################################################

internal()
{
    #  Safest to put these *in* all functions - if they're outside then
    #  there is a chance a function can get called by *other* extra-function
    #  code with the vars still unset.
    VERBOSE_LEVEL=${VERBOSE_LEVEL:-2}
    FACILITY=${FACILITY:-local0}

    MSG="INTERNAL ERROR: $*"

    #  echo it so that the user can see it or cron can trap it (split line
    #  to avoid confusing 'ident')
    echo "$PROGNAME: \
$MSG" >&2

    #  try to write it into $LOG_FILE if that's defined - other message types
    #  treat unwritable but defined LOG_FILE as an error
    ( echo "`date`: \
$MSG" >> ${LOG_FILE:-/dev/null} ) 2>/dev/null

    #  try to syslog it - other message types are only syslog'ed if there is
    #  no controlling terminal (as when run from 'at' or 'cron')
    logger -i -p $FACILITY.alert -t $PROGNAME "$MSG"

    #  try to log it on the console
    [ -w /dev/console ] && { echo "`date`: \
$PROGNAME: \
$MSG" > /dev/console; }

    exit 2
}

error()
{
    typeset FILE MODE MAX_MSG_LINES USE_LOG_FILE_IF_DEFINED

    ERRORS_CAUSE_EXITS=${ERRORS_CAUSE_EXITS:-true}
    VERBOSE_LEVEL=${VERBOSE_LEVEL:-2}
    FACILITY=${FACILITY:-local0}
    #  This variable may be set in the main script, but can also be
    #  inherited from programs which call this one.
    I_AM_A_DAEMON=${I_AM_A_DAEMON:-false}

    DO_EXIT=$ERRORS_CAUSE_EXITS
    USE_LOG_FILE_IF_DEFINED=true
    MODE=line
    while :; do
        case "$1" in
            -)  internal "change '-' to '-f file' in message calls" ;;
            -m) MAX_MSG_LINES=$2
                shift ;;
            -f) MODE=file 
                FILE=$2
                shift ;;
            -e) DO_EXIT=true ;;
            -ne) DO_EXIT=false ;;
            -nl) USE_LOG_FILE_IF_DEFINED=false ;;
            -*) internal "invalid option to error() '$1' (pars: $*)" ;;
            *)  break ;;
        esac
        shift
    done

    if [ ${VERBOSE_LEVEL:-2} -ge 1 ]; then
        if [ "X$I_AM_A_DAEMON" = Xtrue ]; then
            { { [ $MODE = line ] && echo "$@"; } || sed "${MAX_MSG_LINES:-10}{
a\\
long output suppressed!
q
}" $FILE; } | while read LINE; do
                logger -i -p $FACILITY.err -t $PROGNAME "$LINE"
            done

        else
            { { [ $MODE = line ] && echo "$@"; } || sed "${MAX_MSG_LINES:-10}{
a\\
long output suppressed!
q
}" $FILE; } | sed "s/^/$PROGNAME: ERROR: /" >&2
        fi

        if [ $USE_LOG_FILE_IF_DEFINED = true -a "X$LOG_FILE" != X ]; then
            { { [ $MODE = line ] && echo "$@"; } || cat $FILE; } | ( sed "s/^/`date`: ERROR: /" >> $LOG_FILE ) 2>/dev/null || error -e -nl "log file $LOG_FILE not writable!"
        fi
    fi

    [ $DO_EXIT = false ] && return 1
    exitdel
    exit 1
}

warning()
{
    typeset FILE MODE MAX_MSG_LINES USE_LOG_FILE_IF_DEFINED

    ERRORS_CAUSE_EXITS=${ERRORS_CAUSE_EXITS:-true}
    VERBOSE_LEVEL=${VERBOSE_LEVEL:-2}
    FACILITY=${FACILITY:-local0}
    #  This variable may be set in the main script, but can also be
    #  inherited from programs which call this one.
    I_AM_A_DAEMON=${I_AM_A_DAEMON:-false}

    MODE=line
    USE_LOG_FILE_IF_DEFINED=true
    while :; do
        case "$1" in
            -)  internal "change '-' to '-f file' in message calls" ;;
            -m) MAX_MSG_LINES=$2
                shift ;;
            -f) MODE=file 
                FILE=$2
                shift ;;
            -nl) USE_LOG_FILE_IF_DEFINED=false ;;
            -*) internal "invalid option to error() '$1'" ;;
            *)  break ;;
        esac
        shift
    done

    if [ ${VERBOSE_LEVEL:-2} -ge 2 ]; then
        if [ "X$I_AM_A_DAEMON" = Xtrue ]; then
            { { [ $MODE = line ] && echo "$@"; } || sed "${MAX_MSG_LINES:-10}{
a\\
long output suppressed!
q
}" $FILE; } | while read LINE; do
                logger -i -p $FACILITY.warning -t $PROGNAME "$LINE"
            done

        else
            { { [ $MODE = line ] && echo "$@"; } || sed "${MAX_MSG_LINES:-10}{
a\\
long output suppressed!
q
}" $FILE; } | sed "s/^/$PROGNAME: WARNING: /" >&2
        fi

        if [ $USE_LOG_FILE_IF_DEFINED = true -a "X$LOG_FILE" != X ]; then
            { { [ $MODE = line ] && echo "$@"; } || cat $FILE; } | ( sed "s/^/`date`: WARNING: /" >> $LOG_FILE ) 2>/dev/null || error -e -nl "log file $LOG_FILE not writable!"
        fi
    fi

    return 0
}

debug()
{
    typeset FILE MODE MAX_MSG_LINES USE_LOG_FILE_IF_DEFINED

    ERRORS_CAUSE_EXITS=${ERRORS_CAUSE_EXITS:-true}
    VERBOSE_LEVEL=${VERBOSE_LEVEL:-2}
    FACILITY=${FACILITY:-local0}
    #  This variable may be set in the main script, but can also be
    #  inherited from programs which call this one.
    I_AM_A_DAEMON=${I_AM_A_DAEMON:-false}

    MODE=line
    USE_LOG_FILE_IF_DEFINED=true
    while :; do
        case "$1" in
            -)  internal "change '-' to '-f file' in message calls" ;;
            -m) MAX_MSG_LINES=$2
                shift ;;
            -f) MODE=file 
                FILE=$2
                shift ;;
            -nl) USE_LOG_FILE_IF_DEFINED=false ;;
            -*) internal "invalid option to debug() '$1'" ;;
            *)  break ;;
        esac
        shift
    done

    LEVEL=$1
    shift

    if [ ${VERBOSE_LEVEL:-2} -ge $LEVEL ]; then
        if [ "X$I_AM_A_DAEMON" = Xtrue ]; then
            { { [ $MODE = line ] && echo "$@"; } || sed "${MAX_MSG_LINES:-10}{
a\\
long output suppressed!
q
}" $FILE; } | while read LINE; do
                logger -i -p $FACILITY.debug -t $PROGNAME "$LINE"
            done

        else
            { { [ $MODE = line ] && echo "$@"; } || sed "${MAX_MSG_LINES:-10}{
a\\
long output suppressed!
q
}" $FILE; } | sed "s/^/$PROGNAME: DEBUG[$LEVEL]: /" >&2
        fi

        if [ $USE_LOG_FILE_IF_DEFINED = true -a "X$LOG_FILE" != X ]; then
            { { [ $MODE = line ] && echo "$@"; } || cat $FILE; } | ( sed "s/^/`date`: DEBUG[$LEVEL]: /" >> $LOG_FILE ) 2>/dev/null || error -e -nl "log file $LOG_FILE not writable!"
        fi
    fi

    return 0
}

info()
{
    typeset FILE MODE MAX_MSG_LINES USE_LOG_FILE_IF_DEFINED

    ERRORS_CAUSE_EXITS=${ERRORS_CAUSE_EXITS:-true}
    VERBOSE_LEVEL=${VERBOSE_LEVEL:-2}
    FACILITY=${FACILITY:-local0}
    #  This variable may be set in the main script, but can also be
    #  inherited from programs which call this one.
    I_AM_A_DAEMON=${I_AM_A_DAEMON:-false}

    MODE=line
    USE_LOG_FILE_IF_DEFINED=true
    while :; do
        case "$1" in
            -)  internal "change '-' to '-f file' in message calls" ;;
            -m) MAX_MSG_LINES=$2
                shift ;;
            -f) MODE=file 
                FILE=$2
                shift ;;
            -nl) USE_LOG_FILE_IF_DEFINED=false ;;
            -*) internal "invalid option to error() '$1'" ;;
            *)  break ;;
        esac
        shift
    done

    if [ ${VERBOSE_LEVEL:-2} -ge 3 ]; then
        if [ "X$I_AM_A_DAEMON" = Xtrue ]; then
            { { [ $MODE = line ] && echo "$@"; } || sed "${MAX_MSG_LINES:-10}{
a\\
long output suppressed!
q
}" $FILE; } | while read LINE; do
                logger -i -p $FACILITY.info -t $PROGNAME "$LINE"
            done

        else
            { { [ $MODE = line ] && echo "$@"; } || sed "${MAX_MSG_LINES:-10}{
a\\
long output suppressed!
q
}" $FILE; } | sed "s/^/$PROGNAME: INFO: /" >&2
        fi

        if [ $USE_LOG_FILE_IF_DEFINED = true -a "X$LOG_FILE" != X ]; then
            { { [ $MODE = line ] && echo "$@"; } || cat $FILE; } | ( sed "s/^/`date`: INFO: /" >> $LOG_FILE ) 2>/dev/null || error -e -nl "log file $LOG_FILE not writable!"
        fi
    fi

    return 0
}

###############################################################################
#
#  INTERACTIVE MESSAGING FUNCTIONS
#
###############################################################################

### echo loading interactive messaging functions

pause()
{
    necho "Press ENTER to continue "
    read RESPONSE
    return 0
}

proceed()
{
    typeset PROMPT DEFAULT RESPONSE

    PROMPT="do you wish to proceed"

    while [ "X$1" != X ]; do
        case "$1" in
            -d) DEFAULT="$2"
                shift ;;
            -p) PROMPT="$2"
                shift ;;
            -*) internal "proceed: invalid option '$1'" ;;
            *)  break ;;
        esac
        shift
    done

    while :; do
        question "${PROMPT:-proceed}? [${DEFAULT:-n}]" > /dev/tty
        read RESPONSE < /dev/tty
        [ "X$RESPONSE" = X ] && RESPONSE=${DEFAULT:-n}
        case "$RESPONSE" in
            [Yy]*) return 0 ;;
            [Nn]*) return 1 ;;
            *)     echo "Eh? Try again" > /dev/tty ;;
        esac
    done
}

question()
{
    necho "$PROGNAME: \
QUESTION: $*: "
    return 0
}

###############################################################################
#
#  MISCELLANEOUS INTERACTIVE FUNCTIONS
#
###############################################################################

### echo loading miscellaneous interactive functions

do_a_shell()
{
    OLD_PS1="$PS1"
    export PS1

    while :; do
        case "$1" in
            -p) PS1="$2"
                shift ;;
            -*) internal "invalid option '$1' to do_a_shell() (001)" ;;
            *)  break ;;
        esac
        shift
    done
    
    COMMAND="$*"
    debug 10 "command to run is $COMMAND, SHELL is $SHELL"
    case "$COMMAND" in
        "") info "starting sub-shell, type 'exit' to resume"
            ${SHELL:-/bin/sh} ;;
        *)  ${SHELL:-/bin/sh} -c "$COMMAND" ;;
    esac

    PS1="$OLD_PS1"

    return 0
}

###############################################################################
#
#  GENERIC SUPPORT FUNCTIONS
#
###############################################################################

### echo loading generic support functions

choosecmd()
{
    for POSSCMD in $*; do
        [ X`locatecmd $POSSCMD` != X ] && { echo $POSSCMD; return 0; }
    done
    return 1
}

locatecmd()
{
    typeset PATH_DIR
    #  if it's fully qualified then just test if it exists
    #  note that we may be passed command line parameters which we
    #  ignore
    L_QUIET=false
    while [ "X$1" != X ]; do
        case "$1" in
            -q) L_QUIET=true ;;
            -*) internal "locatecmd: called with invalid option: $1" ;;
            *)  break ;;
        esac
        shift
    done

    if expr $1 : '.*/.*$' > /dev/null; then
        [ -x $1 ] && { [ $L_QUIET = false ] && echo $1; return 0; }
        return 1
    else
        for PATH_DIR in `echo $PATH | sed 's/:/ /g'`; do
            [ -x $PATH_DIR/$1 ] && { [ $L_QUIET = false ] && echo $PATH_DIR/$1; return 0; }
        done
        return 1
    fi
}

necho()
{
    if [ "X$ECHO_MODE" = X ]; then
        if [ `echo -n | wc -c` -eq 0 ]; then
            ECHO_MODE=mn
        elif [ `echo "\\c" | wc -c` -eq 0 ]; then
            ECHO_MODE=bsc
        else
            internal "don't know how to suppress newlines in echos"
        fi
    fi
 
    if [ $ECHO_MODE = mn ]; then
        echo -n "$@"
    elif [ $ECHO_MODE = bsc ]; then
        echo "$@""\\c"
    fi

    return 0
}

#  This function is concerned with setting *standard* *OS*
#  command options for common requirements. It is not for
#  things like 'sendmail' which may vary from site to 
#  site. So notice that there are no markers in this section.
#  Many scripts will not want to call this function as it
#  is pretty half-hearted.

os_config()
{
    UNAME_SR=`uname -sr`
    [ -f /etc/debian_version ] && { LINUX_DISTRIBUTION=debian; LINUX_DISTRIBUTION_VERSION=`cat /etc/debian_version`; }
    
    if expr "$UNAME_SR" : 'HP-UX B\.10\.[12]0$' > /dev/null; then
        DF_CMD="/usr/bin/bdf -t hfs"
        MAILX_CMD=/usr/bin/mailx
        JOIN_CMD="/usr/bin/join"
        LOGGER_CMD=/usr/bin/logger
        PS_CMD="ps -ef"
    elif expr "$UNAME_SR" : 'SunOS 5\.[45].*$' > /dev/null; then
        DF_CMD="/usr/ucb/df -k -F ufs" 
        MAILX_CMD=/bin/mailx
        JOIN_CMD="/usr/bin/join"
        LOGGER_CMD=/usr/ucb/logger
        PS_CMD="ps aux"
    elif expr "$UNAME_SR" : 'Linux .*' > /dev/null && [ "X$LINUX_DISTRIBUTION" = Xdebian ]; then
        DF_CMD="/bin/df --type=msdos --type=ext2 --type vfat"
        MAILX_CMD=/usr/bin/mailx
        JOIN_CMD="/usr/bin/join"
        LOGGER_CMD=/usr/bin/logger
        PS_CMD="ps ax"
    else
        internal "os_config: unrecognised OS: $UNAME_SR/$LINUX_DISTRIBUTION/$LINUX_DISTRIBUTION_VERSION/"
    fi

    locatecmd -q $DF_CMD     || error -e "can't find: $DF_CMD"
    locatecmd -q $MAILX_CMD  || error -e "can't find: $MAILX_CMD"
    locatecmd -q $LOGGER_CMD || error -e "can't find: $LOGGER_CMD"
    locatecmd -q $JOIN_CMD   || error -e "can't find: $JOIN_CMD"
    locatecmd -q $PS_CMD     || error -e "can't find: $PS_CMD"
}

am_i_root()
{
    [ ! -w / -o "X$LOGNAME" != Xroot ] && return 1

    return 0
}

who_am_i()
{
    echo ${USER:-${LOGNAME:-`id | sed -n 's/^[^(][^(]*(\([^)][^)]*\)).*$/\1/p'`}}
}

###############################################################################
#
#  TEMPORARY FILE MANAGEMENT FUNCTIONS
#
###############################################################################

### echo loading temportary file management functions 

delonexit()
{
    DELONEXIT="$DELONEXIT $*"
}
 
dontdelonexit()
{
    for FILE in $*; do
        DELONEXIT=`echo $DELONEXIT | sed "s@$FILE@@g"`
    done
}
 
exitdel()
{
    #  this function cannot do any message function - if it does, then 
    #  possibly removed log files are recreated.
    rm -f $DELONEXIT
}

genericsighandler()
{
    sighandler
}

sighandler()
{
    warning "signal recieved, clearing up and exiting"
    exitdel
    exit 3
}

###############################################################################
#
#  LOCKING ROUTINES
#
###############################################################################

### echo loading locking routines

#  It would be nice to return minus numbers on errors, positive ones on
#  discovering locks held be another process (the return value being the
#  holding pid). But 'return' won't accept minus numbers (even in variables).
#  So we use 1 to represent an error (since no locking process should use
#  this pid).

lock()
{
    typeset LOCK_FILE MODE LOCK_TEXT

    MODE=pid

    while [ "X$1" != X ]; do
        case "$1" in
            -ph) MODE=pidandhost ;;
            -*) internal "lock: called with bad option: $1" ;;
            *)  break ;;
        esac
        shift
    done

    LOCK_FILE=`gen_lock_file_name "$1"`

    case $MODE in
        pid)        LOCK_TEXT="$$" ;;
        pidandhost) LOCK_TEXT="$$ `uname -n`" ;;
    esac

    #  create temporary lock
    delonexit $LOCK_FILE.$$
    { echo $LOCK_TEXT > $LOCK_FILE.$$; } 2>/dev/null || { 
        error -ne "can't create temporary lock"
        return 1
    }

    #  Slide the temporary lockfile into place
    delonexit $LOCK_FILE
    ln $LOCK_FILE.$$ $LOCK_FILE 2>/dev/null && { 
        rm -f $LOCK_FILE.$$
        dontdelonexit $LOCK_FILE.$$
        return 0
    }
    dontdelonexit $LOCK_FILE

    #  It failed. Check who is locking us out.
    HOLDING_LOCK_TEXT=`cat $LOCK_FILE`
    HOLDING_PID=`echo $HOLDING_LOCK_TEXT | cut -f1 -d' '`
    case $MODE in
        pid)        HOLDING_HOST=`uname -n` ;;
        pidandhost) HOLDING_HOST=`echo $HOLDING_LOCK_TEXT | cut -f2 -d' '` ;;
    esac

    #  validate lock
    [ "X$HOLDING_PID" = X -o "X$HOLDING_HOST" = X ] && { 
        rm -f $LOCK_FILE.$$
        dontdelonexit $LOCK_FILE.$$
        error -ne "corrupt lockfile: $LOCK_FILE"
        return 1
    }

    #  if locking host is remote then there's not much we can do to verify it
    #  though we should really return a positive (made up) pid or something
    [ $HOLDING_HOST != `uname -n` ] && {
        error -ne "locking host is remote, cannot verify if lock is stale"
        return 1
    }

    #  if the locking host is local (it must be if we get here) if running
    #  abandon lock attempt and return locking pid
    pid_running $HOLDING_PID && { 
        rm -f $LOCK_FILE.$$
        dontdelonexit $LOCK_FILE.$$
        return $HOLDING_PID
    }

    #  if the lock is local and stale (it must be if we get here) remove lock
    info "removing stale lock (pid=$HOLDING_PID)"
    rm -f $LOCK_FILE

    #  try locking again
    delonexit $LOCK_FILE
    ln $LOCK_FILE.$$ $LOCK_FILE 2>/dev/null && { 
        rm -f $LOCK_FILE.$$
        dontdelonexit $LOCK_FILE.$$
        return 0
    }

    #  if we still haven't successfully locked by now then there is something
    #  seriously wrong
    rm -f $LOCK_FILE.$$
    dontdelonexit $LOCK_FILE.$$
    internal "couldn't lock even after removing stale lockfile"
}

pid_running()
{
    typeset UNAMES

    if [ -d /proc ]; then
        [ -d /proc/$1 ]
	return $?
    fi

    UNAMES=`uname -s`

    if [ $UNAMES = Linux ]; then
        [ X`ps ax | sed -n 's/^[ 	]*\([0-9][0-9]*\)[ 	].*$/\1/p'` != X ]
        return $?
    
    elif [ $UNAMES = SunOS ]; then
        [ X`ps -ae | sed -n 's/^[ 	]*\([0-9][0-9]*\)[ 	].*$/\1/p'` != X ]
        return $?

    fi

    internal "cannot determine if pid $1 is running (recode pid_running())"
}

unlock()
{
    typeset LOCK_FILE MODE LOCK_TEXT

    LOCK_FILE=`gen_lock_file_name "$1"`

    rm -f $LOCK_FILE
}

###############################################################################
#
#  GENERIC ENTRY POINT
#
###############################################################################

### echo reached generic entry point

[ "X$UMASK" != X ] && umask $UMASK
main "$@"
exit $?
