#
#  mail      (5/31/88)
#-----------------------------------------------------------------------------
#  mail will allow you to read mail from other users, to send mail to
#  one or more other users, or to transfer whole files to other users as
#  mail messages.
#
#  usage: mail                                   read your own mail
#         mail sendto-address [...]              send mail to other user(s)
#         mail sendto-address [...] < mail-text  send mail-text to user(s)
#
#             (sendto-address may be a user login or an alias defined
#              in the file ${MAIL}\malias)
#
#  Once you have found mail addressed to youself, options are:
#
#      help        print the help messages kept in the file ${MAIL}\help
#      ! (or sh)   enter a subshell
#      ! command   execute a command in a subshell (also "sh command")
#      q           quit
#      =           show the current message number
#      a           show the current alias list (in ${MAIL}\malias)
#      m user(s)   send mail to user(s)
#      0-99        go to message number 0 through 99
#      <RETURN>    go to the next message and display it
#      +0-99       go forward 0 to 99 messages and display it
#      -0-99       go backwards 0 to 99 messages and display it
#      p [list]    show current message [or list of messages]
#      t [list]    show top 5 lines of current message [or list of messages]
#      d [list]    delete current message [or list of messages]
#      f list      forward current message to list of users
#      l [list]    print current message [or list of messages] on printer
#      h [list]    show header for all messages [or list of messages]
#      r [list]    reply to message [or list of messages]
#      s string    search for string in all mail files
#      w filename  save current message in filename
#-----------------------------------------------------------------------------
#  Notice that the use of constructed file names in lines such as:
#          eval FNAME${PTR}="$FILE"
#          eval FILE=\$FNAME${CMD}
#  provides a way to handle array-like variable values in shell scripts.
#-----------------------------------------------------------------------------
#  First, create a sed control file to extract the sender, subject, and date
#  from the standard mail message header information.  Then set a trap to
#  remove temporary files upon termination.
#-----------------------------------------------------------------------------
cat > ${TEMPDIR}sedctl <<\!end!
        1s/From:    \(.*\)/SENDER="\1"/p
        3s/Subject: \(.*\)/SUBJECT="\1"/p
        4s/Date:    \(.*\)/DATE="\1"/p
!end!
trap 'rm -sf ${TEMPDIR}sedctl ${TEMPDIR}tempmail' 0 1
set +\/                                          # turn off the -/ flag
HEADING="^n#^tSender^tDate^t^t^tSize^tSubject"   # set up heading title line
#-----------------------------------------------------------------------------
#  Now look for command line arguments.  If any are found, send mail to those
#  user names using the mailout script.  Otherwise, look for mail for ouw own
#  user login name.
#-----------------------------------------------------------------------------
case $1 in                                       # if arguments found then
   ?*) if [ ! -t 0 ]                             # if running in a pipeline
         then                                    # set -s flag and put pipe-
         set -s                                  # line data into std file
         cat > ${TEMPDIR}tempmail                # send mail using mailout
         sh mailout -s "transferred-file" -f "${TEMPDIR}tempmail" $*
       else                                      # else send mail from user
         sh mailout $*                           # using mailout
       fi
       exit 0;;                                  # end when done
esac
if [ ! -f ${MAIL}\\${LOGNAME}\\* ]               # no arguments, look for our
   then                                          # own mail.  If not found,
   echo "You have no mail"                       # print an error message
   exit 0                                        # and end
fi
#-----------------------------------------------------------------------------
#  Found mail, now look through each file and extract the data needed for the
#  heading lines and for other functions used below.
#-----------------------------------------------------------------------------
PTR=0                                            # initial message pointer
FLIST=                                           # and message list
echo "looking for mail "
for FILE in `ls -1et ${MAIL}\\${LOGNAME}`        # for each mail message in
   do                                            # our mail directory (listed
   echo "$FILE"                                  # in reverse cron. order)
   PTR=`expr $PTR + 1`                           # show and count the file
   eval `sed -n -f ${TEMPDIR}sedctl $FILE`       # get sender/subject/date
   SIZE="`wc -cs $FILE`"                         # get size and set up datar
   SIZE=`expr $SIZE`                             # for a header line
   eval HDR${PTR}="$PTR^t$SENDER^t$DATE^t$SIZE^t$SUBJECT"
   FLIST="$FLIST $PTR"                           # add to message list
   eval FNAME${PTR}="$FILE"                      # save file name and sender
   eval SENDR${PTR}="$SENDER"                    # NOTE array-like logic here
done
MAXFILE=$PTR                                     # set high message number
MSGCOUNT=$PTR                                    # set number of messages left
#-----------------------------------------------------------------------------
#  All data gathered, now print an initial display of heading lines.
#-----------------------------------------------------------------------------
echo "^nNOTE: type   help   as a command if you need help"
echo "$HEADING"                                  # display title line
for X in $FLIST                                  # and each header line.
   do                                            # again, notice the array-
   eval echo "\$HDR${X}"                         # like logic here
done
unset SIZE SENDER DATE SUBJECT                   # remove obsolete variables
#-----------------------------------------------------------------------------
#  Now loop through the command interpretation loop until the user enters a
#  quit (or exit) command.
#-----------------------------------------------------------------------------
PTR=0                                            # start before message 1
while true                                       # loop until told to stop
   do
   echo -n "^n --------^nmail: "                 # print mail prompt
   read CMD OPTIONS                              # get user's command
   case $CMD in                                  # process each command
     help)                                       # print the help file
         more -v ${MAIL}\\help;;
     ! | sh)                                     # handle sub-shell options
       case $OPTIONS in
         "") sh;;                                # run a sub-shell
         *)  sh -c "$OPTIONS";;                  # run cmd in a sub-shell
       esac;;
     q | x)                                      # quit (or exit)
         echo "$MSGCOUNT message(s) left in mail"; exit 0;;
                                                 # show current message number
     =)  echo "--current message is # ${PTR}--";;
     a)  echo "^nalias^twill send messages to..."
         echo "-----^t------------------------"  # show heading for aliases
         more ${MAIL}\\malias;;                  # show current alias file
     m)  echo "--entering edit function--"       # send mail using the
         sh mailout $OPTIONS;;                   # mailout script
     [0-9] | [0-9][0-9])                         # display a specific message
         if [ $CMD -lt 1 -o $CMD -gt $MAXFILE ]  # check for bad message number
           then                                  # and handle errors
           echo "$CMD: invalid message number"
         else
           PTR=$CMD                              # set current message number
           eval FILE=\$FNAME${CMD}               # get proper file name
           echo "^n --- $CMD ---"                # show message number
           more $FILE                            # show the message text
         fi;;
     "" | +* | -*)                               # display relative message
         case $CMD in                            # if no command given,
           "") CMD=+;;                           # default to +
         esac
         case $CMD in                            # if all one command (eg. +1)
                                                 # get command pat (+)
           ??*) OPTIONS=`expr "$CMD" : '.\(.*\)'`
                CMD=`expr "$CMD" : '\(.\).*'`;;  # get number part
         esac
         case $OPTIONS in                        # if no number given,
           "") OPTIONS=1;;                       # default to 1
         esac
         X=`expr "$PTR" "$CMD" "$OPTIONS"`       # calc proper message number
         if [ $X -lt 1 -o $X -gt $MAXFILE ]      # check for bad message number
           then                                  # and handle errors for number
           case $X in                            # too low or too high
             -* | 0) echo "can't go beyond first message";;
             *)      echo "can't go beyond last message";;
           esac
         else
           PTR=$X                                # set current message number
           eval FILE=\$FNAME${PTR}               # get proper file name
           echo "^n --- $PTR ---"                # show message number
           more $FILE                            # show message text
         fi;;
#-----------------------------------------------------------------------------
#  Process more complex commands that may have one or more arguments to
#  process.  Analyze those arguments and set any needed defaults
#-----------------------------------------------------------------------------
     p | t | d | f | l | h | r | s | w)          # handle complex commands
         case $OPTIONS in
           "") case $CMD in                      # if or options entered,
                 h)  echo "$HEADING"             # show titles for "h" cmd
                     OPTIONS="$FLIST";;          # and default full msg list
                 *)  OPTIONS=$PTR;;              # else default current message
               esac;;
         esac
         case $CMD in                            # special conditions, for cmd
           f)  WORK="$OPTIONS"                   # f: save users to forward to
               OPTIONS=$PTR;;                    #  and forward current message
           s)  echo "--searching for: $OPTIONS"  # s: show search message
               SEARCH="$OPTIONS"                 #  save text to search for
               OPTIONS="$FLIST";;                #  and use full msg list
           w)  OUTFILE="$OPTIONS"                # w: save output file name
               OPTIONS=$PTR;;                    #  and use current message
         esac
#-----------------------------------------------------------------------------
#  Arguments done, now process each argument for the current command.
#-----------------------------------------------------------------------------
         for X in $OPTIONS                       # for each message selected
           do
           if [ $X -lt 1 -o $X -gt $MAXFILE ]    # check for bad message number
             then                                # and handle errors for number
             case $X in                          # too low or too high
               -* | 0) echo "can't go beyond first message";;
               *)      echo "can't go beyond last message";;
             esac
           else
             eval FILE=\$FNAME${X}               # get proper file name
             case $CMD in                        # and process command
               p)  echo "^n --- $X ---"          # show current message number
                   more $FILE                    # show message text
                   PTR=$X;;                      # set current message number
               t)  echo "^n --- $X ---"          # show current message number
                   head -5 $FILE                 # show message heading
                   PTR=$X;;                      # set current message number
               d)  rm -f $FILE                   # remove this message file
                                                 # change heading text
                   eval HDR${X}="$X^t--deleted--"
                   MSGCOUNT=`expr $MSGCOUNT - 1` # decrement message count
                   echo "--message $X deleted--" # show deletion message
                   PTR=`expr $X + 1`;;           # advance current message num
                                                 # put tabs into forwarded file
               f)  sed -e "s/^/ /" $FILE > ${TEMPDIR}tempmail
                                                 # mail it with mailout
                   sh mailout -s forwarded-file -f "${TEMPDIR}tempmail" $WORK
                                                 # show forwarding message
                   echo "--message $PTR forwarded to $WORK--";;
               l)  print $FILE                   # print the message text
                   echo "--message $X printed--" # show printed message
                   PTR=$X;;                      # set current message number
               h)  eval echo "\$HDR${X}";;       # show current header text
               r)  eval SENDER=\$SENDR${X}       # get user to reply to
                   echo "--replying to $SENDER--"
                   sh mailout $SENDER            # reply using mailout
                   PTR=$X;;                      # set current message number
               s)  echo "--looking in $FILE--"   # show search message
                   grep "$SEARCH" $FILE;;        # look for text with grep
                                                 # show write-to-file message
               w)  echo "--saving $FILE in $OUTFILE--"
                   cat $FILE >> $OUTFILE;;       # append message to file
             esac                                # end of complex command
           fi                                    # done with good message
         done;;                                  # done with this message
   esac                                          # done with command
done                                             # end of master loop
