#!/bin/sh
# grabmail: fetch all mail accounts specified in a config file and format it into a local mailbox format. Program dependencies: fetchmail, rxvt or similar when in X.
# Config file has the following syntax: local_mailbox mail_addr account protocol encr_password delete_after_fetch=0..keep|1..delete after|2..delete all read msgs first [mail_limit]
# When mail limit is not specified to a account, the common MAIL_LIMIT or command-line parameter is used.
#--------------------------------------------------------------------

CFG_FILE="$HOME/.grabmail"
ADR_FUNCT="rot13|rev"  #the pipeline to decode the passw - it should be a special prog invoked by sudo etc. for proper security
MAIL_INIT_COMM='echo {0 > `dirname \$LINBOX`/.`basename \$LINBOX|sed 's/^.*[/]//'`.idx'
JOB_COLOR=LightBlue
JOB_XWRAPPER="xterm -geometry 60x10+400 -fg black -bg $JOB_COLOR -sl 1500 -e"  #invoke color xterm when fetching in X
#JOB_XWRAPPER=eval  #run in a current terminal
#MAIL_LIMIT=750  #limit to short messages
MAIL_LIMIT=360000  #360K max mail
GRAB_LOG=/tmp/grabmail-${USER}.log
CNT_TOT=0
BOX_LST=

#fetchmail default setting: if you don't specify `-k' (--keep), then fetchmail will automati cally delete messages after successful delivery.
#-K, --nokeep  (Keyword: nokeep) Delete retrieved messages from the remote mailserver (after delivery).
#-F, --flush   POP3/IMAP  only.  Delete old (previously retrieved) messages from the mailserver before retrieving new messages.

#--------------------------------------------------------------------
# GrabMailBox local_mailbox  mail_addr    user_account protocol encr_password delete_after_fetch   mail_limit
#               ~/mybox     pop3.isp.com     john_doe    POP3...     string          [0/1/2]       [0=unlimited..]
GrabMailBox() {
  #variables including password
  LINBOX="$1"
  LADRESS="$2"
  LACCOUNT="$3"
  LPROTO="$4"
  LPASSW=`echo "$5"|eval "$ADR_FUNCT"`  #passw decrypting
  LINIT_INBOX=0
  LIDS="$HOME/.fetchids.`basename $LINBOX|sed 's/^.*[/]//'`"  #get proper mailbox filename from rc fetchids
  ! [ -r "$LIDS" ] && > "$LIDS"   #create new mailbox file if it doesn't exist
  chmod u=rw,g=,o= "$LIDS"  #security for mailbox file
  LDELETE="--keep"  #our default is to keep
  [ "$6" == "1" ] && LDELETE=  #fetchmail default means delete after fetch (so no parameter needed)
  [ "$6" == "2" ] && LDELETE="--flush"  #this means delete all old messages before fetching new
  [ "$7" -a "`echo "x$7"|grep "x[0-9]"`" ] && LMAIL_LIMIT=$7 || LMAIL_LIMIT=$MAIL_LIMIT

  echo "`date +%y%m%d.%H:%M:%S` fetching account $LACCOUNT from $LADRESS, mail length limit $LMAIL_LIMIT"
  #debuging echo "box:$LINBOX adr:$LADRESS acc:$LACCOUNT pr:$LPROTO pass:$LPASSW limit:$LMAIL_LIMIT ids: $LIDS del: $LDELETE"
  #read

  #fetch the mail         ************************* fetchmail ***************************
  #and prepare mailboxes  ***************************************************************
  echo "$LPASSW"|fetchmail $LDELETE -U -u "$LACCOUNT" --bsmtp "$LINBOX".raw "$LADRESS" --limit $LMAIL_LIMIT --protocol "$LPROTO" -i "$LIDS"|tee "$GRAB_LOG"
  MDAT=`date`
  ! [ -r "$LINBOX" ] && LINIT_INBOX=1
  [ -r "$LINBOX".raw ] && cat "$LINBOX".raw \
     |sed '/^MAIL FROM\|^RCPT TO/d;s/^DATA/From - '"$MDAT"'/;/20[0-9][0-9] PDT/s/PDT/12:00:00 PDT/;/20[0-9][0-9] PST/s/PST/12:00:00 PST/;/Date/s/ 101 / 2001 /;' \
     |sed '/[ /.,:;-][a-zA-Z0-9]\+.*[ /.,:;-][a-zA-Z0-9]\+/{ /?=$\|?=.$/!{ s/=.$/'ÿÿÿ"`echo -e "\r"`"'/; s/=$/ÿÿÿ/; }; }'|tr "\n" "ð"|sed 's/ÿÿÿð//g;s/ÿÿÿ.ð//g;'|tr "ð" "\n" \
     > "$LINBOX"  #the command to prepare standard mailbox from smtp format. 1.remove smtp tags 2.[ /.,:;-] to remove = on line ends (chars must be in this order) 3.add file name= to Content-Type
  [ -r "$LINBOX" ] && [ "$LINIT_INBOX" == "1" ] && eval "$MAIL_INIT_COMM"
  [ "$DELETE" == "1" ]
  CNT=`cat "$GRAB_LOG"|grep -c -i "^.tu \|^read"`
  [ $CNT -gt 0 ] && BOX_LST="$BOX_LST `basename "$LINBOX"`"
  #rm "$GRAB_LOG"
  CNT_TOT=$[ $CNT_TOT + $CNT ]
  echo "`date +%y%m%d.%H:%M` *** grabbed $CNT messages for account $LACCOUNT from $LADRESS"; echo
}

#--------------------------------------------------------------------
# main
! [ "$DISPLAY" ] && JOB_XWRAPPER=
! [ -r "${CFG_FILE}" ] && { echo "grabmail: cannot read config file " 1>&2; exit 1; }
[ "$1" == "--go" -o "$1" == "-novt" ] || exec $JOB_XWRAPPER "$0" --go "$@"  #launch the script again in the wrapper
while [ "$1" ]; do
  case "$1" in
  --help|-h) echo "Usage: grabmail [options]"; sleep 5; exit 1;;
  -limit|-quota) [ "$2" ] && [ `echo "x$2"|grep "x[0-9]"` ] && MAIL_LIMIT=$2 && shift;;
  esac; shift
done
chmod u=rw,g=,o= "${CFG_FILE}"  #security
for i in $( cat "${CFG_FILE}"|grep -v "^#\|^$"|sed "s/ /\\\/g" ); do PARAMS=$( echo "${i}"|sed "s/\\\/ /g" ); GrabMailBox ${PARAMS}; done
echo -e "done grabbing the mail at `date`,\n$CNT_TOT messages total (updated mailboxes:$BOX_LST)"
[ "${JOB_XWRAPPER}" ] && echo "press <Enter> to exit..." && read || echo

syntax highlighted by Code2HTML, v. 0.9.1