#!/bin/sh

# phone - phone list program
#
#
#   This software is Public Domain. Please maintain version history.
#   Report all bugs to Greg Ercolano (erco@3dsite.com).
#
#       VERS    DATE            AUTHOR          COMMENTS
#       1.00    05/??/96        erco@3dsite.com Initial version
#       1.10    10/31/97        ""              Added locks, etc
#
# Installation:
#     To install a new database, use 'phone -newdbase'.
#

umask 022		# 000=public, 002=group only, 022=one owner only

##################
### VARIABLES
##################
  PROGNAME=phone
  DBASEDIR=/server/local/data/phone	# path to global phonelist dir
     DBASE=${DBASEDIR}/phonelist
 DBASELOCK=${DBASE}.lock
       TMP=/usr/tmp/$PROGNAME.$$

##################
### FUNCTIONS
##################

# LOCK THE FILE
#       $1 - original filename
#
Lock()
{
    if mv $1 $1.lock; then return 0; fi
    echo $PROGNAME: ${DBASE}: 2>&1 
    echo $PROGNAME: someone has the file locked 2>&1
    exit 1
}

# UNLOCK THE FILE
#   Of course these locks are not infallible, but it's better than nothing.
#       $1 - original filename
#
Unlock()
{
    if mv $1.lock $1; then return 0; fi
    echo "$PROGNAME: HELP: your changes are stuck in $1.lock!"
    echo "$PROGNAME: HELP: You must 'mv $1.lock $1' by hand"
    exit 1
}

# TEMP COPY OF LOCKED OR UNLOCKED VERSION
#       $1 - original filename
#       $2 - temp copy filename
#
TempCopy()
{
    # IF NEITHER ORIGINAL NOR LOCKED EXISTS, FAIL
    if [ ! -e $1 -a ! -e $1.lock ]; then
        # CHECK AGAIN INCASE OF RACE CONDITION
        sleep 1;
        if [ ! -e $1 -a ! -e $1.lock ]; then
            echo "$PROGNAME: FAIL: Can't find $1 or $1.lock"
            exit 1
        fi
    fi

    while [ 1 ]; do
        # FIRST, TRY UNLOCKED FILE
        if cp $1 $2 2> /dev/null; then return 0; fi

        # SECOND, TRY LOCKED FILE
        if cp $1.lock $2 2> /dev/null; then return 0; fi

        # RACE CONDITION? TRY AGAIN
        sleep 1
    done
}

# JUST EDIT THE FILE (ASSUME LOCKING HANDLED)
#       $1 - locked filename to edit
#
Edit()
{
    ${EDITOR:-vi} $1
}

# BOOT STRAP A NEW DATABASE
#    no args
#
NewDbase()
{
    if [ -r $DBASE ]; then
        echo "--- Database already exists. Remove it first:"
	echo "--- $DBASE"
	exit 1
    else
        # CREATE THE DIRECTORY AND A TEST FILE
	mkdir -p      $DBASEDIR
	touch         $DBASE
	chown -R 0.0  $DBASEDIR
	chmod -R a+rw $DBASEDIR

	cat << EOF > $DBASE
Op Amp Books (OPAMP)    1033 N. Sycamore Ave                  T:(213)-464-4322
Op Amp Books (OPAMP)    LA CA                                 F: ?
Op Amp Books (OPAMP)    90038
> Directions:
>    10 Fwy, LaBrea North, Santa Monica West, Sycamore south.
>

777-FILM                777-FILM                              W:777-3456
777-FILM                http://www.movielink.com/             F:-

EOF
	echo "--- Created new phone database:";
	ls -la $DBASEDIR
	echo "--- Try 'phone opamp' or 'phone' to see sample entries."
	echo "--- Use 'phone -n' to add new entries, 'phone -e' to edit."
    fi
}

# HELP SCREEN
#    no args
#
HelpAndExit()
{
    cat << EOF 1>&2
    usage:
    	phone             	# print entire list
    	phone <searchname>	# search for entries (regex patterns work too)
	phone -new		# add a new entry
	phone -edit		# edit phone list
	phone -newdbase		# create phonelist from scratch
	phone -paths   		# print phonelist filename to stdout
				# (for other tools to use)

    Note: Whenever you edit the phonelist, backups are saved. 
          If you screw up an edit, you can recover a copy from:

	      $DBASEDIR
EOF
    exit 1
}

# SEARCH FOR ENTRIES IN THE PHONE LIST
#    all args - search strings
#
Search()
{
    # ARGS? SEARCH THE LIST FOR EACH ONE
    for i in "$@"; do
	nawk '
	    # CASE INSENSITIVE
	    BEGIN {
	        dots = "--------------------";
		dots = dots dots dots "-------------------";
		find = tolower("'$i'");
	    }

	    # PRINT THE ENTRY
	    function Print()
		{ for (i=0; i<tot; i++) print arr[i]; print dots; }

	    # SEARCH THE LIST
	    {
		if ($1=="")
		{
		    if (flag) Print();
		    tot = 0; flag=0;
		}
		else
		{
		    arr[tot++] = $0;
		    if (match(tolower($0), find)) flag=1;
		}
	    }
	    END {
		if (flag) Print();
	    }' $DBASE | more
    done
}

# APPEND A SAMPLE ENTRY TO THE SPECIFIED FILE
#     $1 - the locked phonelist file
#
Sample()
{
    date=`date`
    cat << EOF >> $1

Name                    Address                               T:(xxx)-xxx-xxxx
Name                    City, State, Zip                      F:(xxx)-xxx-xxxx
Name                    Email
Name			Entry Created: $date
> notes
EOF
}

# MAKE A FOUR LEVEL BACKUP OF THE FILE (..just incase..)
#       $1 - filename to backup
#       $2 - actual name for backup copy
#
Backup()
{
    if [ -e $2.3 ]; then mv $2.3 $2.4; fi
    if [ -e $2.2 ]; then mv $2.2 $2.3; fi
    if [ -e $2.1 ]; then mv $2.1 $2.2; fi
    cp $1 $2.1
}

##################
### MAIN
##################

trap "echo ${PROGNAME}': killed (removing crap)'; rm -f ${TMP} 2>/dev/null" 3 15
case "$1" in

    "")
	# NO ARGS? JUST PRINT ENTIRE LIST
        Search .	# prints everything
	;;

    -newdbase)
	NewDbase
	;;

    -|-h|-help)
        HelpAndExit
	;;

    -n|-new)
        Lock      ${DBASE}
        Backup    ${DBASELOCK} ${DBASE}
	Sample    ${DBASELOCK}
	echo ''; echo '--- Edit new entry at END OF FILE.'; sleep 2
        Edit      ${DBASELOCK}
        Unlock    ${DBASE}
        exit 0
        ;;

    -e|-edit)
        Lock      ${DBASE}
        Backup    ${DBASELOCK} ${DBASE}
        Edit      ${DBASELOCK}
        Unlock    ${DBASE}
	exit 0
	;;

    -p|-paths)
	echo "PHONELIST=$DBASE"
	exit 0
	;;

    *)
        Search "$@"
	exit 0
	;;
esac
