#! /bin/sh
#set -xv
#=========================================================================
# Copyright (C) GemTalk Systems 1986-2024.  All Rights Reserved.
#
# Name - printlogs.sh
#
# Purpose - Script to print tranlog data.  
#           See "help" text for details.
#
#=========================================================================

usage() {
    cat <<EOF
====================================================================

Usage:
`basename $0` [-h]|[keyring <path>][privkey <file>][privkeypf <string>][privkeypffn <file>][<filters>][<keywords>][<tlogA>..<tlogZ>]

Purpose

  To print out contents of designated tranlogs in current directory.

  WARNING: This can produce vast amounts of output!!

  Make sure \$GEMSTONE is set.

Secure Tranlog Options (Required with tranlog*.sdbf files)

  keyring - Path to a directory containing private key files. May be specified
            more than once. Required for printing secure tranlogs.

  privkey - Name of the private key file. filename only, no path. If the 
            private key is protected by a passphrase, then ONE of privkeypf
            or privkeypffn must also be specified. Required for printing secure
            tranlogs.

  privkeypf - passphrase for privkey.

  privkeypffn - name of a file containing the passphrase for privkey.

Options

  -h (or no arguments): 

      print this usage message and exit.

  Filters: 

      Only print records that match any of the filtering criteria.
      One or more of the following pairs:

      user      username  - filter by GS UserProfilename 
      host      hostname  - filter by gem/topaz process host 
      client    X.X.X.X   - filter by client IP Address 
      euid      <integer> - filter by gem's effective UNIX user ID
      ruid      <integer> - filter by gem's real UNIX user ID
      luid      <integer> - filter by gem's login UNIX user ID
      euidstr   <string>  - filter by gem's effective UNIX user name
      ruidstr   <string>  - filter by gem's real UNIX user name
      luidstr   <string>  - filter by gem's login UNIX user name
      gempid    <integer> - filter by gem's process ID
      sessionid <integer> - filter by gem's session ID

  Keywords: 
      full - More detailed logs are produced (VERY LARGE!).

      all  - Print out contents of all tranlogs in this directory.
             You must list specific tranlogs on the command line or
             give the keyword 'all'.  Tranlogs are assumed to be named 
             'tranlogXXX.dbf'.  Secure tranlogs are assumed to be named 
             'tranlogXXX.sdbf'. Override by setting \$GS_TRANLOG_PREFIX 
             to the prefered value.

      nostrings  - Suppress the printing of String data in the output.
                   Useful for security when sharing tranlog output.

      nouserinfo - Suppress the printout of user information.

  WARNING: a maximum of 256 tranlogs can be analyzed in one set.

====================================================================
EOF
}

# check for -h or no args; print usage and exit
if [ "x$1" = "x" ] || [ "$1" = "-h" ]; then
    usage
    exit 0
fi 

# check that $GEMSTONE is set
if [ "x$GEMSTONE" = "x" ]; then
    echo "ERROR:  \$GEMSTONE not set" 1>&2
    exit 1
fi

# determine tranlog naming convention
if [ "x$GS_TRANLOG_PREFIX" = "x" ]; then
    GS_TRANLOG_PREFIX="tranlog"
fi

# debug
# echo "Using tranlog prefix $GS_TRANLOG_PREFIX"

# Check for $GEMSTONE/sys/pgsvrslow
if [ -f $GEMSTONE/sys/pgsvrslow ]; then
    pgsvrExe=$GEMSTONE/sys/pgsvrslow
else
    echo "ERROR:  \$GEMSTONE/sys/pgsvrslow not found" 1>&2
    exit 1;
fi

# debug
# echo "Using $pgsvrExe"

# initialize variables
printAll=0
haveFileArg=0
filters=""
pFilter=""
tranlogs=""
stranlogs=""
dumpCmd="dumplog"
tmpfile="/tmp/gsprintlog$$"
privkey=""
privkeypf=""
privkeypffn=""
keyring=""

# debug
# echo "tmpfile = $tmpfile"

# create temporary file to hold pgsvr commands
touch $tmpfile
echo "quiet " >>$tmpfile
echo "printusernames " >>$tmpfile

# loop over arguments..
while [ "x$1" != "x" ] 
do
    # check for filtering keywords

    if [ $1 = "user" ]; then
	echo "'$2' username" >>$tmpfile
	filters="$filters user $2"
	pFilter="$pFilter user $2"
	shift 2

    elif [ $1 = "host" ]; then
	echo "'$2' gemhost" >>$tmpfile
	filters="$filters host $2"
	pFilter="$pFilter host $2"
	shift
	shift

    elif [ $1 = "client" ]; then
	echo "'$2' clientip" >>$tmpfile
	filters="$filters client $2"
	pFilter="$pFilter client $2"
	shift 2

    elif [ $1 = "euid" ]; then
	echo "$2 findeuid" >>$tmpfile
	filters="$filters findeuid $2"
	pFilter="$pFilter euid $2"
	shift 2

    elif [ $1 = "ruid" ]; then
	echo "$2 findruid" >>$tmpfile
	filters="$filters findruid $2"
	pFilter="$pFilter ruid $2"
	shift 2

    elif [ $1 = "luid" ]; then
	echo "$2 findluid" >>$tmpfile
	filters="$filters findluid $2"
	pFilter="$pFilter luid $2"
	shift 2

    elif [ $1 = "euidstr" ]; then
	echo "'$2' findeuidstr" >>$tmpfile
	filters="$filters findeuidstr $2"
	pFilter="$pFilter euidstr $2"
	shift 2

    elif [ $1 = "ruidstr" ]; then
	echo "'$2' findruidstr" >>$tmpfile
	filters="$filters findruidstr $2"
	pFilter="$pFilter ruidstr $2"
	shift 2

    elif [ $1 = "luidstr" ]; then
	echo "'$2' findluidstr" >>$tmpfile
	filters="$filters findluidstr $2"
	pFilter="$pFilter luidstr $2"
	shift 2

    elif [ $1 = "gempid" ]; then
	echo "$2 findgempid" >>$tmpfile
	filters="$filters findgempid $2"
	pFilter="$pFilter gempid $2"
	shift 2

    elif [ $1 = "sessionid" ]; then
	echo "$2 findsessionid" >>$tmpfile
	filters="$filters findsessionid $2"
	pFilter="$pFilter sessionid $2"
	shift 2

	# check for keyword full
    elif [ $1 = "full" ]; then
	dumpCmd=dumplogfull
	shift

	# check for keyword all
    elif [ $1 = "all" ]; then
	tranlogs=`ls -1rt *$GS_TRANLOG_PREFIX*.dbf` 2>/dev/null
	stranlogs=`ls -1rt *$GS_TRANLOG_PREFIX*.sdbf` 2>/dev/null
	if [ "X${tranlogs}" = "X" -a "X${stranlogs}" = "X" ]; then
	    echo "No tranlog or secure tranlog files found"
	    exit 1
	fi
	printAll=1
	shift

	# check for keyword nostrings
    elif [ $1 = "nostrings" ]; then
	echo "nostrings" >>$tmpfile
	filters="$filters nostrings"
	shift

	# check for keyword nouserinfo
    elif [ $1 = "nouserinfo" ]; then
	echo "noprintusername " >>$tmpfile
	shift

    elif [ $1 = "keyring" ]; then
	if [ ! -d "$2" ]; then
	    echo "[Error]: $2 is not a directory"
	    exit 1
	fi    
	keyring="$keyring $2"
	echo "'$2' setkeyring " >>$tmpfile
	shift 2

    elif [ $1 = "privkey" ]; then
	privkey="$2"
	echo "'$2' setprivatekey " >>$tmpfile
	shift 2

    elif [ $1 = "privkeypf" ]; then
	privkeypf="$2"
	echo "'$2' setprivatekeypf " >>$tmpfile
	shift 2

    elif [ $1 = "privkeypffn" ]; then
	if [ ! -r "$2" ]; then
	    echo "[Error]: Cannot read private key passphrase file $2"
	    exit 1
	fi      
	privkeypffn="$2"
	echo "'$2' setprivatekeypffn " >>$tmpfile
	shift 2           
	
	# check if it's a tranlog or secure tranlog name
    elif [ -r $1 ]; then
	haveFileArg=1
	case "$1" in
	    ${GS_TRANLOG_PREFIX}*.sdbf)
		stranlogs="$stranlogs $1"  ;;
	    
	    ${GS_TRANLOG_PREFIX}*.dbf)
		tranlogs="$tranlogs $1"	;;
	    
            *)
		echo "Unknown tranlog file kind $1"
		exit 1
		;;
	esac
	shift 
    # otherwise we don't know what it is
    else
	echo "Unrecognized keyword or file not found: $1"
	shift
    fi
    # done with argument processing loop..
done

if [ $haveFileArg -eq 0 -a $printAll -eq 0 ]; then
    echo "[Error]: Either the 'all' option or at least one tranlog filename is required."
    exit 1
fi

if [ $haveFileArg -eq 1 -a $printAll -eq 1 ]; then
    echo "[Error]: Please specify either 'all' option or one or more tranlog filenames, not both."
    exit 1
fi

if [ "X${stranlogs}" != "X" ]; then
    if [ "X${privkey}" = "X" -o "X${keyring}" = "X" ]; then
	echo "[Error]: privkey and keyring must be specified when printing secure tranlogs"
	exit 1
    fi
fi

# construct pgsvr commands
for each in $tranlogs
do
    echo "'$each' openlog 0 100000000 $dumpCmd closedbf" >>$tmpfile
done

for each in $stranlogs
do
    echo "'$each' openlog 0 100000000 $dumpCmd closedbf" >>$tmpfile
done

# debug: print out contents of temporary file
# echo "PGSVRSLOW command file contents:"
# cat $tmpfile
# exit

# print summary info
echo "Tranlog Analysis Print Log:"
echo
if [ "X${tranlogs}" != "X" ]; then
    echo "Printing the following tranlogs:"
    for each in $tranlogs
    do
	echo "  $each"
    done
fi

if [ "X${stranlogs}" != "X" ]; then
    echo "Printing the following secure tranlogs:"
    for each in $stranlogs
    do
	echo "  $each"
    done
fi
echo ""

if [ "$filters" != "" ]; then
    echo "Filtering on: $pFilter"
else
    echo "No filters have been specified."
fi

# now execute..
$pgsvrExe < $tmpfile
pStatus=$?
if [ $pStatus -ne 0 ]; then
    echo "pgsvr returned $pStatus";
    exit $pStatus
fi

# delete temporary file
rm -f $tmpfile

#
# end of script


