#!/bin/bash

###########################################################################
#
#	Shell program to Put Random Signatures of LOST,  OTHERS files,
#       pgp and reserved signatures (or NIL sigs) to outgoing mail
#
#	Copyright 2001-2002, USM Bish <bish@nde.vsnl.net.in>.
#
#	This program is free software; you can redistribute it and/ or
#	modify it under the terms of the GNU General Public License as
#	published by the Free Software Foundation; either version 2 of
#	the License, or (at your option) any later version. 
#
#	This program is distributed in the hope that it will be useful,
#	but WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or  FITNESS FOR A  PARTICULAR PURPOSE. See the
#	GNU General Public License for more details.
#
#	Description: The script is designed to  interface with various
#       mailers like mutt, pine and elm (where the editor can be chan-
#       ged to an external editor for composing/ reply)
#       
#	Usage: be used from within mailer by changing editor option
#
#	Revisions:
#
#	Sep/10/2001	File created            ..... ver 0.1
#       Sep/11/2001     Working model 		..... ver 0.2
#       Sep/13/2001     Simple menu             ..... ver 0.3
#       Sep/16/2001     Fix for second edit
#                       and re-run of rotator   ..... ver 0.4 
#       Sep/30/2001     pgp support added       ..... ver 0.5
#       Dec/27/2001     Q option added          ..... ver 0.6
#       Jan/07/2002     R option added and      ..... ver 0.7
#                       Reserved sig
#       Feb/24/2002     pgp sig modified for    ..... ver 0.8
#                       gnupgp for pine/ mutt
#                       for ascii-armor sigs
#       Apr/20/2002     PGP support for elm     ..... ver 0.9
#
###########################################################################

# EDIT THIS if needed !!! Can set this to view, less or more			
MY_PAGER="view"

# Where does your root dir for signature files lie ? The
# recommended places are /usr/local/share, /usr/share and
# /var for system wide installation, and $HOME for personal
# installation. EDIT this. IMPORTANT !!!
 
SIG_ROOT=/var                # System wide installation
#SIG_ROOT=/usr/local/share    #      -do-
#SIG_ROOT=/usr/local          #      -do-
#SIG_ROOT=$HOME               # For personal installation

# Location of the user's rotator sig and scratch dir (This
# normally does not need change)

PERSONAL_DIR=$HOME/.LOST

# Signature file. Most mailers use a file called .signature
# In case you want to leave that intact, use another name.
# This will be erased after every mail, and will not be
# available in your home directory 
MYSIG=$PERSONAL_DIR/$USER.$$

# Reserved sig. This is placed in a file $USER.res. Do not
# change unless mandatory. 
RESERVE=$PERSONAL_DIR/$USER.res

# Your preferred editor.  This is the editor which rotator
# will use for composing your mail.  This is automatically
# created the first time rotator is run. Normally, no need
# to edit
EDITOR_FILE=$PERSONAL_DIR/$USER.edit  

##########################################################
# DO NOT change below this ... WARNING : 440 volts ! 
##########################################################

# PGP binary. This is created the first time PGP option is
# fired under rotator ...  If you DO NOT have pgp or gnupg
# installed, this file should contain a single word "Nil".
# This is done automatically during the first run. No need 
# to change this usually ...
PGP_BIN=$PERSONAL_DIR/$USER.pgp.bin

# What are the directories under SIG_ROOT
# Prepend them to GROUP prefix as below:
GROUP1=/signature/LOST
GROUP2=/signature/OTHERS

# Name of lock file. Do NOT edit
LOCKFILE=$PERSONAL_DIR/rotator.lock

INFILE=$1
PROGNAME=`basename $0`
VERSION="0.8"

###############################################################

###############################################################
#   Functions/ program begins
###############################################################

function Do_pgp_pine
{
   # Added in ver 0.8 of rotator
   INFILE=$1
   TMPOUT="/tmp/gpgsig"
   cp $INFILE $TMPOUT
   echo -en "\n\n" >> $TMPOUT       
   # Use PGP or gnupg whichever is chosen
   PG=`basename $PGPPROG`
    
   case $PG in
    "pgp") $PGPPROG -sta $TMPOUT
           ;;
    "gpg") $PGPPROG --output $TMPOUT.asc --clearsign --armor --textmode $TMPOUT
           ;;
        *) Do_None
           return
   esac

   cat $TMPOUT.asc > $INFILE
   rm -f /tmp/gpgsig*
   return       
}

function Do_pgp_mutt
{
   INFILE=$1
   # Added in ver 0.8 of rotator
   cp $INFILE /tmp/gpgsig.1
   COPY=/tmp/gpgsig.1
   TOTLINES=$(wc $COPY | awk '{print $1}')
   sed -e '1,/^$/d' $COPY > /tmp/gpgsig.body
   BODYSIZE=$(wc /tmp/gpgsig.body | awk '{print $1}')
   HEADSIZE=$((TOTLINES-BODYSIZE))
   head -$HEADSIZE $COPY > /tmp/gpgsig.head

   echo -en "\n\n" >> /tmp/gpgsig.body       
   
   # Use PGP or gnupg whichever is chosen

   PG=`basename $PGPPROG`
   case $PG in
   "pgp") $PGPPROG -sta /tmp/gpgsig.body
          ;;
   "gpg") $PGPPROG --output /tmp/gpgsig.body.asc --clearsign --armor --textmode /tmp/gpgsig.body
          ;;
       *) Do_None
          return 
   esac
   
   cat /tmp/gpgsig.head > $INFILE
   echo "" >> $INFILE
   cat /tmp/gpgsig.body.asc >> $INFILE
   rm -f /tmp/gpgsig*       
}

function query
 {
    # This function has been adapted from the lgrep v1.1 script
    # Binand Raj S. <binand@cysphere.com>. The  lgrep script in
    # original is also included in the LOST scripts tarball. 
    
    lostdir=$SIG_ROOT/$GROUP1
    pattern="$TAIL"
    
    filelist=$(echo $lostdir/*.lost | xargs grep -l -e "$pattern")
    if [ -z "$filelist" ]; then
        echo -en 'Pattern NOT found : '"'$pattern'"'  ... Press [Return] '
        read
    else     
        cnt=0
        >$HOME/lost.tmp
        for file in $filelist; do
            cnt=$((cnt+1))
            cat $file >> $HOME/lost.tmp
        done
        echo -en "\n\nTotal matches = $cnt\n\n" >> $HOME/lost.tmp
        $MY_PAGER $HOME/lost.tmp
        rm -f $HOME/lost.tmp
    fi
}

function get_editor
{
    # Introduced in ver 0.7
    echo -en "Choice of editor ? : "
    read ED
    MY_ED=`which $ED`
    if [ -x "$MY_ED" ]; then
       echo $MY_ED > $EDITOR_FILE
       return 
    else
       echo "$ED not found ... "
       get_editor
    fi
}

function get_pgp
{
    # Introduced in ver 0.8
    echo
    echo "$PROGNAME ($VERSION) is capable of placing ascii-armor"
    echo "PGP/gnupg sigs on mails with [P] option with  mutt and"
    echo "pine. There is no need for any changes to rc files for"
    echo "these mailers. If no PGP software is installed on your"
    echo 'system choose "0"' 
    echo -en "\nPGP software choice\n\n"
    echo "[0] No PGP/gnupgp installed"
    echo "[1] PGP ver 6.x.x "
    echo "[2] gnupgp ver 1.0.x"
    echo -en "\nChoice of pgp [0-2] ? : "
    read PGP_CHOICE
    case $PGP_CHOICE in
    "0") echo "Nil" > $PGP_BIN;;
    "1") TMP=`which pgp`
         echo $TMP > $PGP_BIN;;
    "2") TMP=`which gpg`
         echo $TMP > $PGP_BIN;;
      *) echo "Nil" > $PGP_BIN
         echo "Invalid Option. No PGP option being intialised."
         echo "Press [Return] to continue"
         read
    esac     
}

function Chk_editor
{
    # Introduced in ver 0.7
    if ! [ -s "$EDITOR_FILE" ]; then
       get_editor
    else
       MY_EDITOR=`cat $EDITOR_FILE | grep -v "#"`
    fi   
}

function Check_personal_dir
{
    # Introduced in ver 0.7
    if ! [ -d $PERSONAL_DIR ]; then
        mkdir $PERSONAL_DIR
        echo "Please enter Reserved signature in $RESERVE" > $RESERVE
        echo $PROGNAME" v-"$VERSION" First time run ... "
        get_editor
        get_pgp
        echo
        echo "$PERSONAL_DIR created. Edit the following files:"
        echo "o Place Reserved sig in ... $RESERVE"  
        echo -en "o Preferred Editor is  .... "
        cat $EDITOR_FILE
        echo -en "o Selected PGP binary is .. "
        cat $PGP_BIN
        echo
        echo "Initialisation complete. Press [Return] to continue ..."
        read 
    fi
}

function Do_reserve
{
    # This option for Reserved sig added in ver 0.7
    NUMBER=$RESERVE
    if [ -s "$NUMBER" ]; then
       echo -en "\n\n\n" >> $INFILE
       cat $NUMBER >> $INFILE
       $MY_EDITOR $INFILE
       return
    else  # No Reserved file found; make one and re-do
       > $RESERVE
       Do_reserve
    fi
}

function Chk_pgp
{
    # Introduced in ver 0.8
    if ! [ -s "$PGP_BIN" ]; then
       get_pgp
    fi
}

function Do_pgp
{
    # Added ascii-armor sigs in ver 0.8

    if [ "$PGPPROG" = "Nil" ]; then
       $MY_EDITOR $INFILE

    else    
       
       MY_MAILER="Unknown"
    
       if [ $(echo $INFILE | grep "pico") ]; then
          MY_MAILER="pine"
       fi  
     
       if [ $(echo $INFILE | grep "mutt") ]; then
          MY_MAILER="mutt"
       fi
    
       # Added in v-0.9 for elm support.  Elm mails have    
       # header and body seperate like pine. The tmp dir
       # under /tmp done through ~/.elm/elmrc
       if [ $(echo $INFILE | grep "snd") ]; then
          MY_MAILER="pine"
       fi
            
       case $MY_MAILER in
    
       "mutt") # mutt uses this rtn
               $MY_EDITOR $INFILE
               Do_pgp_mutt $INFILE
               return
               ;;
          
       "pine") #both pine and elm use this rtn
               $MY_EDITOR $INFILE
               Do_pgp_pine $INFILE
               return
               ;;
          
            *) $MY_EDITOR $INFILE
               return        
       esac
                    
    fi
}

function Pad_zero
{    
    # The variable NUMBER is padded with zeros if needed
    # Pad with single zero for 2 digit numbers and
    # with two zeros in front for 1 digit numbers.
 
    if [ "$NUMBER" -lt 100 ]; then
       if [ "$NUMBER" -lt 10 ]; then
          NEW_NUM="00"$NUMBER
       else
          NEW_NUM="0"$NUMBER
       fi
    else
       NEW_NUM=$NUMBER  
    fi
    NUMBER=$NEW_NUM

    # Trim number to three digits if extra
     
    echo $NUMBER > $HOME/rot.$$
    NREV=`rev $HOME/rot.$$`
    echo $NREV | cut -b 1-3 > $HOME/rot.$$
    NUMBER=`rev $HOME/rot.$$`
    rm -f $HOME/rot.$$
}

          
function Do_LOST_menu
{
    LOST_PATH=$SIG_ROOT/$GROUP1
    MENU=/tmp/lost.menu
    
    echo 'List LOST Tips available. Press "q" to exit menu' > $MENU
    echo "then type the LOST Tip No." >> $MENU
    echo "" >> $MENU
    echo "-----------------------------------------------" >> $MENU
    echo "" >> $MENU    
          
    cat $LOST_PATH/*.lost | grep "Sub :" >> $MENU
    
    less $MENU 
    echo ""
    echo -en "Enter LOST No : "
    read SEARCH

    NUMBER=$SEARCH
    Pad_zero
    SEARCH=$NUMBER
    echo -en "\n\n\n" >> $INFILE
    cat $LOST_PATH/$SEARCH.lost >> $INFILE
    $MY_EDITOR $INFILE
    return
        
}

function write_sig
{
    cp $SIG_FILE $MYSIG
}

function get_file_name
{
    SIG_FILE=`ls $SIG_DIR/*.$SUFFIX | grep "$RND_NUMBER"`
}

function check_how_many
{
    PD=`pwd`
    cd $SIG_DIR
    CNT=0
    for i in `ls *.$SUFFIX`; do
        CNT=$((CNT+1))
    done
    TOTAL_SIGS=$CNT
    CNT=0
    cd $PD
}

    
function generate_random
{
    check_how_many
    RANGE=$TOTAL_SIGS
    RND_NUMBER=$RANDOM
    let "RND_NUMBER %= $RANGE"
    NUMBER=0
    while [ $NUMBER -le 1 ]
    do
       NUMBER=$RND_NUMBER
    done   
    Pad_zero
    RND_NUMBER=$NUMBER
}    

function random_sig
{
    generate_random
    get_file_name
    write_sig
}

function Get_options
{
    echo -en "["$PROGNAME" v-"$VERSION" Signature [L|M|N|O|P|Q|R] : "
    read SIG
    FIRST=`echo $SIG | awk '{print $1}'`
    SECOND=`echo $SIG | awk '{print $2}'`
        
    case $FIRST in
    
         L|l|LOST|lost|Lost)
            if ! [ "$SECOND" = "" ]; then
                NUMBER=$SECOND
                Pad_zero
                SECOND=$NUMBER                
                NUMBER=$SIG_ROOT/$GROUP1/$SECOND.lost
                    if [ -s "$NUMBER" ]; then
                        echo -en "\n\n\n" >> $INFILE
                        cat $NUMBER >> $INFILE
                        $MY_EDITOR $INFILE
                        return
                    else

                        echo "ERROR 1: Sig File Not found"
                        Menu1                         
                    fi
             else
                SIG_DIR=$SIG_ROOT/$GROUP1
                SUFFIX=lost
                Do_LOST_random
             fi          
             ;;
             
         O|o|OTHERS|others|Others)
            if ! [ "$SECOND" = "" ]; then
                NUMBER=$SIG_ROOT/$GROUP2/$SECOND.others
                    if [ -s "$NUMBER" ]; then
                        echo -en "\n\n\n" >> $INFILE
                        cat $NUMBER >> $INFILE
                        $MY_EDITOR $INFILE
                        return
                    else
                        echo "ERROR 1: Sig File Not found"
                        Menu1                         
                    fi
             else
                SIG_DIR=$SIG_ROOT/$GROUP2
                SUFFIX=others
                Do_OTHERS_random
             fi          
             ;;
 
          M|m|MENU|menu|Menu)
             Do_LOST_menu
             ;;           

          N|n|Nil|NIL|nil)
             Do_None
             ;;

          P|p|PGP|Pgp|pgp)
             Do_pgp       
             ;;

          Q|q|QUERY|query|Query)
             echo -en "Search pattern ? "
             read TAIL
             query
             Get_options
             ;;            
          
          R|r|RESERVE|reserve|Reserve)
             Do_reserve
             ;;

          *) echo "Error 2: No such sig option : "$FIRST
             Menu1            
    esac 
}
    
function Do_OTHERS_specific
{
    SIG_DIR=$SIG_ROOT/$GROUP2
    SUFFIX=others
    check_how_many
    echo -en "OTHERS Number : "
    read SECOND
    NUMBER=$SECOND
    Pad_zero
    SECOND=$NUMBER
    NUMBER=$SIG_ROOT/$GROUP2/$SECOND.others
    if [ -s "$NUMBER" ]; then
       echo -en "\n\n\n" >> $INFILE
       cat $NUMBER >> $INFILE
       $MY_EDITOR $INFILE
       return
    else
       echo "ERROR 1: Not found : "`basename $NUMBER`" (Max : ["$TOTAL_SIGS"])"
       Menu1                         
    fi
    echo -en "\n\n\n" >> $INFILE
    cat $HOME/signature/OTHERS/$NUMBER >> $INFILE
    $MY_EDITOR $INFILE
    return
}
    
function Do_OTHERS_random
{
    SIG_DIR=$SIG_ROOT/$GROUP2
    SUFFIX=others
    check_how_many
    random_sig
    echo -en "\n\n\n" >> $INFILE
    cat $MYSIG >> $INFILE
    $MY_EDITOR $INFILE
    return
}


function Do_LOST_specific
{
    SIG_DIR=$SIG_ROOT/$GROUP1
    SUFFIX=lost
    check_how_many
    echo -en "LOST Number : "
    read SECOND
    NUMBER=$SECOND
    Pad_zero
    SECOND=$NUMBER

    NUMBER=$SIG_ROOT/$GROUP1/$SECOND.lost
    if [ -s "$NUMBER" ]; then
       echo -en "\n\n\n" >> $INFILE
       cat $NUMBER >> $INFILE
       $MY_EDITOR $INFILE
       return
    else
       echo "ERROR 1: Not found : "`basename $NUMBER`" (Max : ["$TOTAL_SIGS"])"
       Menu1                         
    fi
    echo -en "\n\n\n" >> $INFILE
    cat $HOME/signature/LOST/$NUMBER >> $INFILE
    $MY_EDITOR $INFILE
    return
}
    
function Do_LOST_random
{
    SIG_DIR=$SIG_ROOT/$GROUP1
    SUFFIX=lost
    check_how_many
    random_sig
    echo -en "\n\n\n" >> $INFILE
    cat $MYSIG >> $INFILE
    $MY_EDITOR $INFILE
    return
}

function Do_OTHERS
{
    echo -en "OTHERS Options --> [1] Random [2] Specific : "
    read OTHERS_ANS
    case $OTHERS_ANS in
        1|R|r|Random|RANDOM|random) Do_OTHERS_random;;
        2|S|s|Specific|SPECIFIC|specific) Do_OTHERS_specific;;
        *) Do_Others;;
    esac
}

function Do_LOST
{
    echo -en "LOST Options --> [1] Random [2] Specific [3] Menu : "
    read LOST_ANS
    case $LOST_ANS in
        1|R|r|Random|RANDOM|random) Do_LOST_random;;
        2|S|s|Specific|SPECIFIC|specific) Do_LOST_specific;;
        3|M|m|Menu|MENU|menu) Do_LOST_menu ;;
        *) Do_Lost;;
    esac
}
    
function Do_None
{
    $MY_EDITOR $INFILE
    return
}

function graceful_exit
{
    rm -f $MYSIG
    exit 0
}
    
function Menu1
{     
    echo -en "Signature Option --> [1]None  [2]LOST  [3]Others : "
    read ANSWER
    case $ANSWER in
        1|N|n|None|NONE|none) Do_None;;
        2|L|l|Lost|LOST|lost) Do_LOST;;
        3|O|o|Others|OTHERS|others) Do_OTHERS;;
        *) Menu1;;
    esac
}

########################################
# Main Program
########################################

# Exit if not run from within mailer

if ! [ $1 ]; then
   echo $PROGNAME"                       Version : "$VERSION
   echo "This must be run from a mailer ... Quitting"
   exit 1
fi
   
# Added in 0.7 : Check if first run, if yes make the
# personal rotator directory 

Check_personal_dir
Chk_editor
Chk_pgp

MY_EDITOR=`cat $EDITOR_FILE | grep -v "#"`
PGPPROG=`cat $PGP_BIN | grep -v "#"`

# Amendments made in ver 0.4 to correct the problem
# of second pass, wherein the menu was coming again

LOCK_SIZE=`ls -al $INFILE | awk '{print $5}'`
OLD_LOCK_SIZE=`cat $LOCKFILE 2> /dev/null`
echo $LOCK_SIZE > $LOCKFILE

if [ "$OLD_LOCK_SIZE" = "$LOCK_SIZE" ]; then
   # Re-edit. Do not pass through menu
   $MY_EDITOR $INFILE
   graceful_exit
else
   # New file. Pass through menu
   Get_options
   LOCK_SIZE=`ls -al $INFILE | awk '{print $5}'`   
   echo $LOCK_SIZE > $LOCKFILE
   graceful_exit   
fi

graceful_exit
      
##############################################################
