#!/bin/bash
#
# GPG4PINE main program
#

GLOBALRC="/etc" # Change it to directory containing gpg4pine.defaults
			  # and/or gpg4pine.override

# Some command definitions. When one does not work for you try the another :)

 # Standard echo, but it must have -n option!
export P4P_ECHO="echo"
#export P4P_ECHO="/bin/echo"

 # I want to receive number of seconds since 1970-01-01 00:00:00 UTC
export P4P_TIME1="date +%s"; export P4P_TIME2="cat"
#export P4P_TIME1="echo print time"; export P4P_TIME2="perl"

# GO!

# Daddy...

PINEID=$PPID

# Useful later

CH13=`echo -e '\r'`

# For security reasons first :>

wipetmp () # function
{
    while [ ! -z "$1" ]
    do
	if [ -f "$1" ]
	then
	    s=`cat "$1" | wc -c`
	    dd if=/dev/urandom of="$1" bs="$[$s]" count=1 2>/dev/null
	fi
	rm -f "$1"
	shift 1
    done
}

# Are we expected to serve as passphrase server?...

if [ "$1" = "-s" ]
then

# ...Damn it! :)

# When pine exits we do not want to leave any our processes

    rem_cleaner() # function
    {
	t=`$P4P_TIME1 | $P4P_TIME2`
	read x y z
	while [ $? -eq 0 ]
	do
	    if [ ! -z "$z" ]
	    then
		if [ "$t" -gt "$[$y + 60 * $GPG4PINE_STORE_TIME ]" ]
		then
		    wipetmp "$z"
		fi
	    fi
	    read x y z
	done
    }

    rem_killer() # function
    {
        while [ -e "$1" -a -e "/proc/$3" ]
        do
	    sleep 10
	done
# Kill the passphrase server main process
	if [ -e "$2" ]
	then
	    $P4P_ECHO QUIT > "$2"
	fi
# Clean up decoded files
	head -1 -q "$GPG4PINE_SPOOL"/* 2>/dev/null | rem_cleaner
    }

# Do the hard work

    rem_server() # function
    {
	q=0
	c=-1
	p=""
	while [ "$q" -eq "0" ]
	do
	    e=`cat "$3"`
	    e1=`$P4P_ECHO "$e" | cut -d' ' -f1`
	    e2=`$P4P_ECHO "$e" | cut -d' ' -f2`
	    if [ "$e1" = QUIT ]
	    then
		q=1
	    else
	        if [ "$e1" = PASS ]
		then
		    c="$e2"
		    $P4P_ECHO OK > "$2"
		    p=`cat "$3"`
		    $P4P_ECHO OK > "$2"
		else
		    if [ "$e1" = STAT ]
		    then
			if [ "$c" -lt 0 ]
			then
			    $P4P_ECHO NO > "$2"
			else
			    $P4P_ECHO OK > "$2"
			fi
		    else
			if [ "$e2" = "$c" ]
			then
			    if [ "$e1" = RE ]
			    then
				$P4P_ECHO "$p" > "$2"
			    else
				if [ "$e1" = CLEAN ]
				then
				    c=-1
				    p=""
				    $P4P_ECHO OK > "$2"
				fi
			    fi
			else
			    q=1
			fi
		    fi
		fi
	    fi
	done
	wipetmp "$2" "$3"
	if [ -e "$1" ]
	then
	    > "$1"
	fi
    }

# Prepare and go

    mkfifo -m 600 "$3"
    mkfifo -m 600 "$4"
    rem_killer "$2" "$4" "$5" &
    rem_server "$2" "$3" "$4" &

else

# ...Thank god we have to work in standard mode :)

# That's it! :)

	VER="4.2"
	REL="(20000827)"
	SPLASH="GPG4PINE $VER $REL by Marcin Marszalek <azzie@staszic.waw.pl>"
# Internationalization!

	msg_echo() # function
	{
	    if [ ! -z "$2" ]
	    then
		$P4P_ECHO "$1""$2"
	    else
		$P4P_ECHO "$1""$3"
	    fi
	}

# If something goes wrong...

	err_crit() # function
	{
	    $P4P_ECHO
	    $P4P_ECHO "$SPLASH"
	    msg_echo "" "$MSG_01" "Press enter to continue..."
	    read dummy
	    exit 1
	}

# Load the defaults

	if [ -f "$GLOBALRC/gpg4pine.defaults" ]
	then
	    . "$GLOBALRC/gpg4pine.defaults"
	fi

# Let's check for config file

	if [ "$1" = "-f" ]
	then
	    shift
	    if [ -z "$1" ]
	    then
		$P4P_ECHO "$0: Value after option missed" >&2
		err_crit
	    else
		GPG4PINE_CONFIG="$1"
		shift
	    fi
	else
	    GPG4PINE_CONFIG="$HOME/.gpg4pine/gpg4pinerc"
	fi
	if [ -f "$GPG4PINE_CONFIG" ]
	then
	    . "$GPG4PINE_CONFIG"
	else
	    $P4P_ECHO "$0: Configuration file \"$GPG4PINE_CONFIG\" is missing"
	    err_crit
	fi

# Load the language

	if [ -f "$GPG4PINE_LANGUAGE/messages.$GPG4PINE_LANG" ]
	then
	    . $GPG4PINE_LANGUAGE/messages.$GPG4PINE_LANG
	else
	    $P4P_ECHO "*** Language file was not found, using builtin"
	    MSG_Y_UP="Y"
	    MSG_Y_LOW="y"
	    MSG_N_UP="N"
	    MSG_N_LOW="n"
	fi

# Let's define two cool functions

	maketmp () # function
	{
	    mtp="$GPG4PINE_TMP"/p4p.$1.$RANDOM.tmp
	    while [ -e "$mtp" ]
	    do
		mtp="$GPG4PINE_TMP"/p4p.$1.$RANDOM.tmp
	    done
	    touch "$mtp"
	    chmod 600 $mtp
	    $P4P_ECHO "$mtp"
	}

	makespool () # function
	{
	    mtp="$GPG4PINE_SPOOL"/p4p.$RANDOM.tmp
	    while [ -e "$mtp" ]
	    do
		mtp="$GPG4PINE_SPOOL"/p4p.$RANDOM.tmp
	    done
	    touch "$mtp"
	    chmod 600 $mtp
	    $P4P_ECHO "$mtp"
	}

# And even a cooler one :>

	decide () # function
	{
	    if [ "$1" = "Y" ]
	    then
		x=y
	    else
		if [ "$1" = "N" ]
		then
		    x=n
		else
		    x="?"
		    while [ "$x" = "?" ]
		    do
			$P4P_ECHO -n "$2 "
			if [ "$1" = "y" ]
			then
			    $P4P_ECHO -n "[$MSG_Y_UP/$MSG_N_LOW] "
			else
			    if [ "$1" = "n" ]
			    then
				$P4P_ECHO -n "[$MSG_Y_LOW/$MSG_N_UP] "
			    else
				$P4P_ECHO -n "[$MSG_Y_LOW/$MSG_N_LOW] "
			    fi
			fi
			read tz
			if [ "$tz" = "" ]
			then
			    if [ "$1" = "y" ]
			    then
				x=y
			    else
				x=n
			    fi
			fi
			if [ "$tz" = "$MSG_Y_UP" -o "$tz" = "$MSG_Y_LOW" ]
			then
			    x=y
			fi
			if [ "$tz" = "$MSG_N_UP" -o "$tz" = "$MSG_N_LOW" ]
			then
			    x=n
			fi
		    done
		fi
	    fi
	}

# Now let's parse config options

	PINECODE=0
	while [ ! -z "$1" ]
	do
	    case "$1" in
	    -e)
		m=e
		nwt="$GPG4PINE_NOWAIT_ENCRYPT"
		;;
	    -d)
		m=d
		nwt="$GPG4PINE_NOWAIT_DECRYPT"
		;;
	    -i)
		shift
		f="$1"
		;;
	    -r)
		shift
		while [ ! -z "$1" ]
		do
		    r="$r $1"
		    shift
		done
		;;
	    -p)
		shift
		PINESESS="$1"
		;;
	    -n)
		PINECODE=""
		;;
	    -ks)
		shift
		GPG4PINE_SIGKEY="$1"
		;;
	    -ke)
		shift
	    	GPG4PINE_ENCKEY="$1"
		;;
	    -ae)
		shift
		GPG4PINE_ENCRYPT="$1"
		;;
	    -aes)
		shift
		GPG4PINE_ENCSELF="$1"
		;;
	    -as)
		shift
		GPG4PINE_SIGN="$1"
		;;
	    -asr)
		shift
		GPG4PINE_SIGREAD="$1"
		;;
	    -bv)
		shift
		GPG4PINE_BIN_VERSION="$1"
		;;
	    -bt)
		shift
		GPG4PINE_BROKENTERM="$1"
		;;
	    -c)
		shift
		GPG4PINE_COMMENT="$1"
		;;
	    esac
	    if [ ! -z "$1" ]
	    then
		shift
	    else
		if [ -z "$r" ]
		then
		    msg_echo "$0: " "$MSG_02" "Value after option missed" >&2
		    err_crit
		fi
	    fi
	done
	if [ -z "$m" -o -z "$f" ]
	then
	    msg_echo "$0: " "$MSG_04" "-d or -e, and -i options are obligatory" >&2
	    $P4P_ECHO '
Usage: gpg4pine [-f config] -e|-d -i file [options] [-r recp recp ...]

Options:
-e                      Set encrypt mode (one mode must be set)
-d                      Set decrypt mode
-i file                 Define input file (required)
-r recipient ...        Define recipients (if used, must be the last option)
-p file                 Define the session file that is removed after pine exits
-n                      Define the session code in the first line of input file
-f file                 Define configuration file (use only as first option)
-c file                 Define comment file
-ks key                 Use this key for signing
-ke key                 Use this key for encrypting to self
-ae x                   Set x for question "Encrypt?"
-aes x                  Set x for question "Encrypt to self?"
-as x                   Set x for question "Sign?"
-asr x                  Set x for question "Sign leaving readable?"
-bv x                   Use y version of PGP (use 2 for 2.6.3, 5 for 5.0,
                        6 for 6.5.1 and G for GNUPG 1.0)
-bt x                   Do we have to set the terminal settings before
                        printing data to the screen? (have to use with old
                        versions of pine)
' >&2
	    err_crit
	fi

# But the global overrides :>

	if [ -f "$GLOBALRC/gpg4pine.override" ]
	then
	    . "$GLOBALRC/gpg4pine.override"
	fi

# Load the stuff

	if [ ! -z "$PINESESS" ]
	then
	    PASSFI=`cat "$PINESESS" | head -1`
	    PASSFO=`cat "$PINESESS" | tail -1`
	fi

# Set the terminal

	if [ "$GPG4PINE_BROKENTERM" = "Y" -o "$GPG4PINE_BROKENTERM" = "y" ]
	then
	    stty onlcr echo -ctlecho icrnl
	fi

# Need thoes exports

	export GPG4PINE_TMP GPG4PINE_SPOOL GPG4PINE_STORE_TIME

# Stale temporary files?

	if [ "$GPG4PINE_RM_STALETMP" = "Y" -o "$GPG4PINE_RM_STALETMP" = "y" ]
	then

	    tem_remove () # function
	    {
		i=0
		read x
		while [ $? -eq 0 ]
		do
		    if [ ! -e "/proc/`basename "$x" | cut -f 2 -d.`" ]
		    then
			i="$[ $i + 1 ]"
			wipetmp "$x"
		    fi
		    read x
		done
		$P4P_ECHO $i
	    }

	    i=`ls "$GPG4PINE_TMP"/p4p*.tmp 2>/dev/null | tem_remove $PINEID`
	    if [ "$i" -gt 0 ]
	    then
		msg_echo "*** " "$MSG_05" 'Removing $1 stale temporary files' | sed '\^$1^s^^'"$[$i]"'^g'
		$P4P_ECHO
	    fi
	fi
	
# News?
	
	if [ "$GPG4PINE_NEWS" != "N" -a "$GPG4PINE_NEWS" != "n" ]
	then

 # Current?

	    if [ -f "$HOME/.gpg4pine/oneliner" ]
	    then
		msg_echo "*** " "$MSG_06" 'GPG4PINE news ($1)' | \
		    sed '\^$1^s^^'"`head -2 "$HOME/.gpg4pine/oneliner" | tail -1`"'^g'
		tail +3 "$HOME/.gpg4pine/oneliner"
	    fi

 # Check for new news :>

  # So let's define some functions first

	    fun_reader () # function
	    {
		read fx
		fy=$?
		while [ $fy -eq 0 -a -z "`$P4P_ECHO "$fx" | grep "Escape character"`" ]
		do
		    read fx
		    fy=$?
		done
		while [ $fy -eq 0 ]
		do
		    read fx
		    fy=$?
		    if [ ! -z "$fx" ]
		    then
			$P4P_ECHO "$fx" >>"$2"
		    fi
		done
		if [ -s "$2" ]
		then
		    $P4P_ECHO "$[ $1 + 86400 ]" >"$HOME/.gpg4pine/oneliner"
		    date >>"$HOME/.gpg4pine/oneliner"
		    cat "$2" >>"$HOME/.gpg4pine/oneliner"
		fi
		rm -f "$2" # Wiping not needed
	    }

	    fun_server () # function
	    {
		HOST=boss.staszic.waw.pl
		PORT=4004
	
		sleep 600 | telnet $HOST $PORT 2>/dev/null | fun_reader "$2" "$3" &
		sfun=$!
		while [ -e "/proc/$sfun" -a -e "/proc/$1" ]
		do
		    sleep 10
		done
		if [ -e "/proc/$sfun" ]
		then
		    kill -9 $sfun
		fi
		while [ -e "/proc/$4" ]
		do
		    sleep 10
		done
	    }

 # Connect?

	    rkti=`$P4P_TIME1 | $P4P_TIME2`
	    rkex=`head -1 "$HOME/.gpg4pine/oneliner" 2>/dev/null`
	    if [ -z "$rkex" ]
	    then
		rkex=0
	    fi
	    if [ "$rkti" -gt "$rkex" ]
	    then
		msg_echo "*** " "$MSG_07" "Checking for news in the background"
		rect=`maketmp $PINEID`
		fun_server $PINEID "$rkti" "$rect" $$ &
	    else
		msg_echo "*** " "$MSG_08" "End of news"
	    fi
	    $P4P_ECHO
	fi

# Anything is missing?

	if [ ! -z "$GPG4PINE_COMMENT" -a ! -f "$GPG4PINE_COMMENT" ]
	then
	    msg_echo "$0: " "$MSG_09" 'Comment file "$1" is missing' | \
		sed '\^$1^s^^'"$GPG4PINE_COMMENT"'^g' >&2
	    err_crit
	fi
	if [ ! -z "$PINESESS" -a ! -f "$PINESESS" ]
	then
	    msg_echo "$0: " "$MSG_10" 'Session file "$1" is missing' | sed '\^$1^s^^'"$PINESESS"'^g' >&2
	    err_crit
	fi

# We are prepared for a moment when session key can be used...

	if [ -z "$PINECODE" ]
	then
	    PINECODE=`head -1 "$f"`
	    tail +2 "$f" > "$r1"
	    cat "$r1" > "$f"
	fi

# Ufff... We got it all... Now its time to decide what we have to do

	cm=""
	enc=""
	sig=""
	dec=""
	vis=""
	r1=`maketmp $PINEID`
	r2=`maketmp $PINEID`
	r3=`maketmp $PINEID`
	if [ "$m" = "e" ]
	then

# Cool function of course to do the dirty work with headers :)

	    headers_parse () # Function
	    {
		read x
		eh=$?
		while [ $eh -eq 0 -a ! -z "$x" -a "$x" != "$CH13" ]
		do
		    read x y
		    eh=$?
		    if [ "$x" = "From:" ]
		    then
			z=`echo "$y" | cut -d'<' -f2 | cut -d'>' -f1`
		    fi
		done
		if [ $eh -eq 0 ]
		then
	    	    echo "$z"
		fi
		cat > "$1"
	    }

# Parse the headers

	    fl=`cat "$f" | headers_parse "$r1"`
	    if [ ! -z "$fl" ]
	    then
		cat "$r1" > "$f"
		if [ -z "$GPG4PINE_SIGKEY" -o -z "$GPG4PINE_ENCKEY" ]
		then
		    msg_echo "*** " "$MSG_35" 'Using "$1" as your auto-detected key' | \
		    sed '\^$1^s^^'"$fl"'^g'
		    if [ -z "$GPG4PINE_SIGKEY" ]
		    then
			GPG4PINE_SIGKEY="$fl"
		    fi
		    if [ -z "$GPG4PINE_ENCKEY" ]
		    then
		    	GPG4PINE_ENCKEY="$fl"
		    fi
		fi
	    fi

# Oh boy, oh boy...

	    cutkeys () # function
	    {
		read zz
		while [ $? -eq 0 ]
		do
		    s=`$P4P_ECHO "$zz" | cut -c 1-3 | egrep '^(RSA|DSS|pub|sec)'`
		    if [ ! -z "$s" ]
		    then
			$P4P_ECHO
			$P4P_ECHO -n "`$P4P_ECHO "$zz" | cut -c $1`"
		    else
			$P4P_ECHO -n " `$P4P_ECHO "$zz" | cut -c $2`"
		    fi
		    read zz
		done
		$P4P_ECHO
	    }

# Know how to check keys...

	    cmnd1="$GPG4PINE_BIN_OPTIONS"
	
	    if [ "$GPG4PINE_BIN_VERSION" = "6" ]
	    then
		cmnd1="$GPG4PINE_BIN_6 $cmnd1 -kv"
		cmnd2="egrep ^(RSA|DSS|[[:space:]])"
		cmnd3="cutkeys 16-25,37- 1-"
	    else
		if [ "$GPG4PINE_BIN_VERSION" = "G" ]
		then

# for use with GNUPG 1.0, check AUTHORS to know who helped :)

		    cmnd1="$GPG4PINE_BIN_G $cmnd1 -k"
		    cmnd2="egrep ^(pub|uid|sec)"
# if it STILL does not work for you, see developement/
		    cmnd3="cutkeys 12-20,32- 32-"
	        else
		    if [ "$GPG4PINE_BIN_VERSION" = "5" ]
		    then
			cmnd1="$GPG4PINE_BIN_5_K $cmnd1 -l"
			cmnd2="egrep ^(pub|uid|sec)"
			cmnd3="cutkeys 11-20 6-"
		    else
			cmnd1="$GPG4PINE_BIN_2 $cmnd1 -kv"
			cmnd2="egrep ^(pub|[[:space:]])"
			cmnd3="cutkeys 11-18,30- 1-"
		    fi
		fi
	    fi
	    
# Use tmpfile to put there the stuff

	    kt=`maketmp $PINEID`
	    $cmnd1 2>/dev/null | $cmnd2 | $cmnd3 >"$kt"

# Small ;) function first to widely support aliasing

	    alias_use () # function
	    {
		nm=0
		ne=0
		if [ -f "$HOME/.gpg4pine/aliases" ]
		then
		    ni=`cat "$HOME/.gpg4pine/aliases" | sed '/	/s// /g
/  */s// /g' | grep -i "^$i " | cut -d' ' -f2- | tail -1`
		else
		    ni=""
		fi

 # Anything to do?

		if [ ! -z "$ni" ]
		then
		    nj=`echo "$ni " | cut -d' ' -f2`
		    if [ ! -z "$nj" ]
		    then

 # It is a multialias, isn't it?

			if [ -z "$1" ]
			then
			    msg_echo "" "$MSG_32" 'Using alias file: expanding "$1" to "$2"' | \
				sed '\^$1^s^^'"$i"'^g
\^$2^s^^'"$ni"'^g'
			fi
			i="$ni"
			for j in $i
			do
			    nn=` cat "$kt" | grep -i "$j" | wc -l`
			    if [ ! "$[$nn]" -eq 1 ]
			    then
				ne=1
			    fi
			    nm="$[$nm + $nn]"
			done
		    else

 # Standard alias

			if [ -z "$1" ]
			then
			    msg_echo "" "$MSG_15" 'Using alias file: translating "$1" to "$2"' | \
				sed '\^$1^s^^'"$i"'^g
\^$2^s^^'"$ni"'^g'
			fi
			i="$ni"
			nn=`cat "$kt" | grep -i "$i" | wc -l`
			if [ ! "$[$nn]" -eq 1 ]
			then
			    ne=1
			fi
			nm="$[$nn]"
		    fi
		else

 # No aliases

		    nn=`cat "$kt" | grep -i "$i" | wc -l`
		    if [ ! "$[$nn]" -eq 1 ]
		    then
			ne=1
		    fi
		    nm="$[$nn]"
		fi
	    }

# One more function for aliasing

	    alias_use_while () # function
	    {
		alias_use
		while [ ! $ne -eq 0 -a ! -z "$i" ]
		do
		    if [ -z "`echo "$i " | cut -d' ' -f2`" ]
		    then
		        msg_echo "" "$MSG_16" 'I cannot choose a key for user "$1" ($2 elements)' | \
			    sed '\^$1^s^^'"$i"'^g
\^$2^s^^'"$nm"'^g'
		    else
			msg_echo "" "$MSG_33" 'I cannot choose keys for group "$1" ($2 elements)' | \
			    sed '\^$1^s^^'"$i"'^g
\^$2^s^^'"$nm"'^g'
		    fi
		    $P4P_ECHO -n `msg_echo "" "$MSG_17" "Please define it again [cancel this recipient]"`" "
		    read i xx
		    alias_use
		done
	    }

# OK, encryption. If we need it, let's ask some questions

	    if [ "$GPG4PINE_ENCRYPT" = "i" -o "$GPG4PINE_ENCRYPT" = "I" ]
	    then

 # Artifical inteligence :)

		msg_echo "*** " "$MSG_03" 'Looking for keys...'
		a="y"
		re=""
		for i in $r
		do
		    alias_use -
		    if [ $ne -eq 0 ]
		    then
			re="$re $i"
		    else
			a="n"
		    fi
		done
		if [ "$GPG4PINE_ENCRYPT" = "I" ]
		then
		    x="$a"
		    $P4P_ECHO -n "*** "`msg_echo "" "$MSG_11" "Encrypt?"`" "
		    if [ "$x" = "y" ]
		    then
			$P4P_ECHO "$MSG_Y_UP"
		    else
			$P4P_ECHO "$MSG_N_UP"
		    fi
		else
		    decide "$a" `msg_echo "" "$MSG_11" "Encrypt?"`
		fi
	    else
		a="n"
		decide "$GPG4PINE_ENCRYPT" `msg_echo "" "$MSG_11" "Encrypt?"`
	    fi
	    if [ "$x" = "n" ]
	    then
		a="y"
		re=""
	    else
		enc="+"
		decide "$GPG4PINE_ENCSELF" `msg_echo "" "$MSG_12" "Encrypt to self too?"`
		if [ "$x" = "y" ]
		then
		    i="$GPG4PINE_ENCKEY"
		    alias_use_while
		    r="$i $r"
		    re="$i $re"
		fi
	    fi
	    decide "$GPG4PINE_SIGN" `msg_echo "" "$MSG_13" "Sign?"`
	    if [ "$x" = "y" ]
	    then
		sig="+"
		if [ -z "$enc" ]
		then
		    decide "$GPG4PINE_SIGREAD" `msg_echo "" "$MSG_14" "Sign leaving text readable?"`
		    if [ ! "$x" = "n" ]
		    then
			vis="+"
			cm="$GPG4PINE_COMMENT"
		    fi
		fi
	    fi
	else

# OK, decryption... So do nothing :)

	    dec="+"
	    re=""
	    a="y"
	    kt=`maketmp $PINEID`
	fi

# What about doing nothing?

	if [ "$dec" = "+" -o "$enc" = "+" -o "$sig" = "+" ]
	then

# It is good to check recipients. Nice thing :)

	    if [ "$a" != "y" ]
	    then
		re=""
		for i in $r
		do
		    alias_use_while
		    re="$re $i"
		done
	    fi

# Let's prepare for work

	    if [ ! -z "$cm" ]
	    then
		cat "$cm" >> "$f"
	    fi

# Check if passphrase/cleanup server is running

	    pser=-
	    if [ ! -z "$PINESESS" -a ! -z "$PASSFI" ]
	    then
		pser=+
	    fi

# Start the passphrase/cleanup server if needed

	    if [ "$pser" != "+" ]
	    then
		if [ "$GPG4PINE_STORE_PASS" = "Y" -o "$GPG4PINE_STORE_PASS" = "y" -o \
		    "$GPG4PINE_STORE_DECODED" = "Y" -o "$GPG4PINE_STORE_DECODED" = "y" ]
		then
		    pser=+
		    PASSFI=`maketmp $PINEID`
		    PASSFO=`maketmp $PINEID`
		    rm -f "$PASSFI" "$PASSFO" # Empty yet
		    $0 -s "$PINESESS" "$PASSFI" "$PASSFO" $PINEID
		    $P4P_ECHO "$PASSFI" >"$PINESESS"
		    $P4P_ECHO "$PASSFO" >>"$PINESESS"
		fi
	    fi

# Check message ID

	    id=`cat "$f" | grep '^MessageID:' | cut -d' ' -f2`
	    if [ -z "$id" ]
	    then
		id=`cat "$f" | md5sum | cut -d' ' -f1`
	    fi



# Look in the spool

	    spl=-
	    sn=`head -1 -q "$GPG4PINE_SPOOL"/* 2>/dev/null | grep "^$id" | cut -d' ' -f3- | head -1`
	    if [ ! -z "$sn" -a "$dec" = "+" ]
	    then
	        wipetmp "$kt"
		msg_echo "*** " "$MSG_18" 'Message found in spool'
		spl=+
		tail +2 "$sn" >"$r1"
		$P4P_ECHO 0 >"$r3"
	    else

# Check signing key

		if [ ! -z "$sig" ]
		then
		    i="$GPG4PINE_SIGKEY"
		    alias_use_while
		    while [ -z "$i" -o ! -z "`echo "$i " | cut -d' ' -f2`" ]
		    do
			msg_echo "" "$MSG_34" 'I need exactly one signing key'
			echo "a $i a"
			i="$GPG4PINE_SIGKEY"
			alias_use_while
		    done
		fi
		wipetmp "$kt"

# Let's create command line

		cmnd="$GPG4PINE_BIN_OPTIONS"

		if [ "$GPG4PINE_BIN_VERSION" = "6" ]
		then
	
		    cmnd="$GPG4PINE_BIN_6 $cmnd -f"
		    if [ -z "$dec" ]
		    then
			cmnd="$cmnd -a"
			if [ ! -z "$enc" ]
			then
			    cmnd=$cmnd"e"
			fi
			if [ ! -z "$vis" ]
			then
			    cmnd=$cmnd"t"
			fi
			if [ ! -z "$sig" ]
			then
			    cmnd=$cmnd"s -u $i"
			fi
		    fi
		    cmnd="$cmnd $re"
	
		else
		    if [ "$GPG4PINE_BIN_VERSION" = "G" ]
		    then

# for use with GNUPG 1.0, check AUTHORS to know who helped :)

			cmnd="$GPG4PINE_BIN_G $cmnd"
			if [ -z "$dec" ]
			then
			    if [ -z "$enc" ]
			    then
				cmnd="$cmnd -sa"
				if [ ! -z "$vis" ]
				then
				    cmnd="$cmnd --clearsign"
				fi
				cmnd=$cmnd" -u $i"
			    else
				cmnd="$cmnd -ea"
				if [ ! -z "$sig" ]
				then
				    cmnd=$cmnd"s"
				    cmnd=$cmnd" -u $i"
				fi
			    fi
			fi
			for i in $re
			do
			    cmnd="$cmnd -r $i"
			done
	
		    else
	
			if [ "$GPG4PINE_BIN_VERSION" = "5" ]
			then
			    if [ -z "$dec" ]
			    then
				if [ -z "$enc" ]
				then
				    cmnd="$GPG4PINE_BIN_5_S $cmnd -a"
				    if [ ! -z "$vis" ]
				    then
					cmnd=$cmnd"t -u $i"
				    fi
				else
				    cmnd="$GPG4PINE_BIN_5_E $cmnd -a"
				    if [ ! -z "$sig" ]
				    then
					cmnd=$cmnd"s -u $i"
				    fi
				fi
			    else
				cmnd="$GPG4PINE_BIN_5_V $cmnd"
			    fi
			    for i in $re
			    do
				cmnd="$cmnd -r $i"
			    done
	
			else
	
			    cmnd="$GPG4PINE_BIN_2 $cmnd -f"
			    if [ -z "$dec" ]
			    then
				cmnd="$cmnd -a"
				if [ ! -z "$enc" ]
				then
				    cmnd=$cmnd" -e"
				fi
				if [ ! -z "$sig" ]
				then
				    cmnd=$cmnd" -s -u $i"
				fi
				if [ ! -z "$vis" ]
				then
				    cmnd=$cmnd" -t"
				fi
			    fi
			    cmnd="$cmnd $re"
	
			fi
		    fi
		fi

# Passphrase remembering routine is really cool :)

		pok=-
		if [ "$GPG4PINE_STORE_PASS" = "Y" -o "$GPG4PINE_STORE_PASS" = "y" ]
		then

 # Do we have the passphrase remembered?
		    $P4P_ECHO STAT > "$PASSFO"
		    p=`cat "$PASSFI"`
		    if [ "$p" = "NO" ]
		    then
			p=+
		    else
			p=-
		    fi
		    while [ "$pok" != "+" -a ! -z "$p" ]
		    do
			if [ "$p" != "-" ]
			then
 # Ask for it
			    msg_echo "*** " "$MSG_19" 'No passphrase found (type nothing to skip)'
			    if [ ! -f "$GPG4PINE_BIN_GETPASS" ]
			    then
				stty -echo 2>/dev/null
				if [ $? != 0 ]
				then
				    msg_echo "*** " "$MSG_20" 'WARNING: THE PASSPHRASE WILL SHOW UP'
				fi
			    fi
 # Input
			    if [ -f "$GPG4PINE_BIN_GETPASS" ]
			    then
				msg_echo "*** " "$MSG_21" 'Using external program to receive passphrase'
				export MSG_GETPASS="$MSG_22"
				p=`$GPG4PINE_BIN_GETPASS`
			    else
				$P4P_ECHO -n `msg_echo "" "$MSG_22" 'Enter passphrase (to remember):'`" "
				read p
				$P4P_ECHO
			    fi
 # Save
			    if [ ! -z "$p" ]
			    then
				$P4P_ECHO PASS "$PINECODE" >"$PASSFO"
				cat "$PASSFI" >/dev/null
				$P4P_ECHO "$p" >"$PASSFO"
				cat "$PASSFI" >/dev/null
			    fi
			fi

 # Check it 
			if [ ! -z "$p" ]
			then
			    if [ "$GPG4PINE_CHECKPASS" = "N" -o "$GPG4PINE_CHECKPASS" = "n" ]
			    then
				pok=+
			    else
				p=+
				msg_echo "*** " "$MSG_23" 'Checking the passphrase'
				if [ "$GPG4PINE_BIN_VERSION" = "6" ]
				then
				    cmnd2="$GPG4PINE_BIN_6 -saf +batch"
				else
				    if [ "$GPG4PINE_BIN_VERSION" = "G" ]
				    then
					cmnd2="$GPG4PINE_BIN_G -sa --passphrase-fd 4"
				    else
					if [ "$GPG4PINE_BIN_VERSION" = "5" ]
					then
					    cmnd2="$GPG4PINE_BIN_5_S -fa +batch"
					else
					    cmnd2="$GPG4PINE_BIN_2 -saf +batch"
					fi
				    fi
				fi
				$P4P_ECHO RE "$PINECODE" > "$PASSFO"
				PGPPASSFD=4
				export PGPPASSFD
				$P4P_ECHO | $cmnd2 4<"$PASSFI" >/dev/null 2>/dev/null
				if [ $? -eq 0 ]
				then
				    msg_echo "*** " "$MSG_24" 'The passphrase is good'
				    pok=+
				else
				    msg_echo "*** " "$MSG_25" 'The passphrase was incorrect'
				fi
				export -n PGPPASSFD
			    fi
			fi
		    done
		    $P4P_ECHO
		    if [ ! -f "$GPG4PINE_BIN_GETPASS" ]
		    then
			stty echo 2>/dev/null
		    fi
		fi
		if [ "$pok" != + ]
		then
		    PASSFI=/dev/null
		else
		    $P4P_ECHO RE "$PINECODE" >"$PASSFO"
		    PGPPASSFD=4
		    export PGPPASSFD
		    if [ "$GPG4PINE_BIN_VERSION" = "G" ]
		    then
			cmnd="$cmnd --passphrase-fd 4"
		    fi
		fi

# Yes... Engine! Beautiful, isn't it?

		{ $cmnd <"$f" 4<"$PASSFI" 3<&1 1>"$r1" 2>&3; $P4P_ECHO "$?" >"$r3"; } | tee "$r2"

# No paths :)

		export -n PGPPASSFD

	    fi

	else

# Do really nothing!

	    $P4P_ECHO 0 >"$r3"
	    nwt=Y
	    GPG4PINE_SPLASH=N
	    GPG4PINE_SIGDASHES=N
	fi

# What do we get? What about some splash?

	err=`cat "$r3"`
	wipetmp "$r3"

# Maybe it is only a signature error at GNUPG 1.0 :)

        if [ "$GPG4PINE_BIN_VERSION" = "G" -a "$err" -lt 3 -a "$m" = "d" ]
        then
		err=0
	fi

	if [ "$nwt" = "N" -o "$nwt" = "n" -o ! "$err" -eq 0 ]
	then
	    $P4P_ECHO
	    $P4P_ECHO
	    $P4P_ECHO "*** $SPLASH"
	    if [ "$err" -eq 0 ]
	    then
		msg_echo "*** " "$MSG_26" 'Press ENTER to leave GPG4PINE and return to PINE'
	    else
	        msg_echo "*** " "$MSG_27" 'An ERROR (code $1) has occured, press ENTER to return to PINE' | \
		sed '/$1/s//'"$err"'/g'
	    fi
	    read dummy
	fi

# Unset the terminal

	if [ "$GPG4PINE_BROKENTERM" = "Y" -o "$GPG4PINE_BROKENTERM" = "y" ]
	then
	    stty ctlecho
	fi

# Log?

	if [ "$err" -eq 0 ]
	then
	    if [ "$GPG4PINE_DECINFO" != "N" -a "$GPG4PINE_DECINFO" != "n" -a "$m" = "d" -a "$spl" != "+" ]
	    then
		$P4P_ECHO >>"$r1"
		$P4P_ECHO "*** $SPLASH" >>"$r1"
		msg_echo "*** " "$MSG_28" 'Decryption log - $1' | sed '\^$1^s^^'"`date`"'^g' >>"$r1"
		$P4P_ECHO >>"$r1"
		cat "$r2" >>"$r1"
		$P4P_ECHO >>"$r1"
		msg_echo "*** " "$MSG_29" 'End of decryption log' >>"$r1"
	    fi

# Anything left?

	    if [ "$m" = "d" ]
	    then

 # Our cleaning function

	        shownopgp() # function
	        {
	    	    pf=0
		    read
		    while [ $? -eq 0 ]
		    do
			if [ ! "${REPLY#-----BEGIN PGP}" = "$REPLY" ]
			then
			    pf=1
			fi
			if [ $pf -eq 0 ]
			then
			    $P4P_ECHO "$REPLY"
			fi
			if [ ! "${REPLY#-----END PGP}" = "$REPLY" ]
			then
			    pf=0
			fi
			read
		    done
		}

 # Use it!

	        cat "$f" | sed '/\\/s//\\\\/g' | shownopgp > "$r2"

 # So?
 
	        if [ ! -z "`cat "$r2" | grep -v "^$" | head -1`" ]
	        then
		    $P4P_ECHO >>"$r1"
		    msg_echo "*** " "$MSG_30" 'Not encrypted nor signed data is left' >>"$r1"
		    $P4P_ECHO >>"$r1"
		    cat "$r2" >>"$r1"
		    $P4P_ECHO >>"$r1"
		    msg_echo "*** " "$MSG_31" 'End of not encrypted nor signed data' >>"$r1"
		    $P4P_ECHO >>"$r1"
		fi
	    fi

# Do we have to run any signature rotating prog?

	    if [ ! -z "$GPG4PINE_SIG_ROTATE" -a "$m" != "d" ]
	    then
		$GPG4PINE_SIG_ROTATE
	    fi

# Hey... Let's store it!

	    if [ "$spl" != "+" -a "$dec" = "+" ]
	    then
	        if [ "$GPG4PINE_STORE_DECODED" = "Y" -o "$GPG4PINE_STORE_DECODED" = "y" ]
	        then
		    sp1=`makespool`
		    echo "$id" `$P4P_TIME1 | $P4P_TIME2` "$sp1" >"$sp1"
		    cat "$r1" >>"$sp1"
		fi
	    fi

# Final filtering

	    if [ "$dec" = "+" ]
	    then

 # Use filter to not get double carriage returns

		cat "$r1" | sed "\^$CH13^s^^^g" > "$f"
	    else

 # Splash rulez again!
 
		showoutsplash() # function
		{
		    pf=0
		    read
		    while [ $? -eq 0 ]
		    do
			if [ ! "${REPLY#-----BEGIN PGP}" = "$REPLY" ]
			then
			    if [ "${REPLY#-----BEGIN PGP SIGNED}" = "$REPLY" ]
			    then
				pf=1
			    fi
			fi
			if [ $pf -eq 1 -a -z "$REPLY" ]
			then
			    $P4P_ECHO "Filter: gpg4pine $VER (http://azzie.robotics.net)"
			fi
			if [ ! "${REPLY#-----END PGP}" = "$REPLY" ]
			then
			    pf=0
			fi
			$P4P_ECHO "$REPLY"
		        read
		    done
	        }

		if [ "$GPG4PINE_SPLASH" = "N" -o "$GPG4PINE_SPLASH" = "n" ]
		then
		    

 # No splash :(

	    	    cat "$r1" > "$r2"
	        else

 # Yeah! That's it!

		    cat "$r1" | sed '/\\/s//\\\\/g' | showoutsplash > "$r2"
		fi

 # Filter to unescape sigdashes
 
		if [ "$GPG4PINE_SIGDASHES" = "N" -o "$GPG4PINE_SIGDASHES" = "n" ]
		then
		    cat "$r2" > "$f"
		else
		    cat "$r2" | sed '\x^- -- $xsxx-- x' > "$f"
		fi
	    fi

# Let's clean

	    wipetmp "$r1" "$r2"
	    exit 0
	else
	    wipetmp "$r1" "$r2"
	    exit $err
	fi

fi

#
# GPG4PINE by Marcin Marszalek <azzie@staszic.waw.pl>
# 27/08/00  version 4.2
#
