mybin

my ~/bin
git clone https://a3nm.net/git/mybin/
Log | Files | Refs | README

msmtpq (10791B)


      1 #!/bin/bash
      2 
      3 #--------------------------------------------------------------
      4 #
      5 #  msmtpq : queue funtions to manage the msmtp queue,
      6 #           as it was defined by Martin Lambers
      7 #  Copyright (C) 2008 Chris Gianniotis
      8 #
      9 #  This program is free software: you can redistribute it and/or modify
     10 #  it under the terms of the GNU General Public License as published by
     11 #  the Free Software Foundation, either version 3 of the License, or (at
     12 #  your option) any later version.
     13 #
     14 #--------------------------------------------------------------
     15 
     16 #--------------------------------------------------------------
     17 # 
     18 # This version has tiny modifications by Marianne Promberger to the original 
     19 # found here: 
     20 # http://www.mail-archive.com/msmtp-users@lists.sourceforge.net/msg00005.html 
     21 #
     22 # -- cleaned up accidental linebreaks in comments
     23 # -- changed shell from /bin/sh to /bin/bash
     24 # -- changed logfile location
     25 #
     26 # marianne@promberger.info
     27 #--------------------------------------------------------------
     28 
     29 #--------------------------------------------------------------
     30 # the msmtp queue contains unique filenames of the following form :
     31 #   two for each mail in the queue
     32 #
     33 # create new unique filenames of the form :
     34 #   MLF: ccyy-mm-dd-hh.mm.ss[-x].mail   -- mail file
     35 #   MSF: ccyy-mm-dd-hh.mm.ss[-x].msmtp  -- msmtp command line file
     36 # where x is a consecutive number only appended for uniqueness
     37 #   if you send more than one mail per second
     38 #--------------------------------------------------------------
     39 
     40 
     41 # msmtpq is meant to be used to maintain the msmtp queue
     42 # there is a separate log file for all events & operations on the msmtp
     43 #   queue that is defined below
     44 
     45 
     46 ## !! please define the following two vars before using the msmtpq & msmtpQ
     47 ## !! routines
     48 
     49 # msmtpQ is meant to be used directly by an email client - in 'sendmail' mode
     50 
     51 # set the queue var to the location of the msmtp queue directory
     52 #   if the queue dir doesn't yet exist, better to create it (0700)
     53 #     before using this routine (it will only complain ...)
     54 #
     55 Q=~/msmtp.queue                     # the queue - modify this to reflect where
     56 				     # you'd like it to be
     57 
     58 # set the queue log var to the location of the msmtp queue log file
     59 #   where it is or where you'd like it to be
     60 #     ( note that the LOG setting could be the same as the )
     61 #     ( 'logfile' setting in .msmtprc - but there may be   )
     62 #     ( some advantage in keeping the two logs separate    )
     63 #   if you don't want the log please unset (comment out) this var
     64 #
     65 LOG=~/logs/msmtp-queue            # the log   - modify to taste ...
     66 
     67 umask 077                            # set secure permissions on created
     68 				     # directories and files
     69 
     70 declare -i CNT                       # a count of mail(s) currently in the queue
     71 
     72 usage() {
     73   echo
     74   [ -n "$1" ] && { dsp '' "$@" '' ; echo ; }
     75   echo '  usage : msmtpq functions'
     76   echo
     77   echo '          msmtpq <op>'
     78   echo '          ops : -r   run (flush) mail queue'
     79   echo '                -d   display (list) queue contents'
     80   echo '                -p   purge a single mail from queue'
     81   echo '                -a   purge all mail in queue'
     82   echo '                -h   this helpful blurt'
     83   echo
     84   echo '       - note that only one op per invocation is allowed'
     85   echo '       - if more than one op is specified, the first one'
     86   echo '           only is executed'
     87   echo
     88   [ -n "$1" ] && exit 1
     89   exit 0
     90 }
     91 
     92 # display a message, possibly an error
     93 # usage : dsp [ -e ] [ -l ] msg [ msg ] ...
     94 #  opts : -e  an error ; display msg & terminate w/prejudice
     95 #  opts : -L  don't log this ; display msg only
     96 dsp() {
     97   local ARG ERR NOL PFX
     98 
     99   [ "$1" == '-e' ] && \
    100     { ERR='t' ; shift ; }            # set error flag ; shift opt off
    101   [ "$1" == '-L' ] && \
    102     { NOL='t' ; shift ; }            # set don't log flag ; shift opt off
    103 
    104   for ARG ; do                       # each msg line out ; no content - send blank
    105     if [ -n "$ARG" ] ; then          # line has content
    106       echo "  $ARG"                  # send it out
    107     else
    108       echo                           # send out blank
    109     fi
    110   done
    111 
    112   if [ -n "$LOG" ] && [ -z "$NOL" ] ; then   # logging allowed (not suppressed)
    113     PFX="$(/bin/date +'%Y %b %d %H:%M:%S')"  # time stamp prefix - "2008 Mar 13
    114 					     # 03:59:45 "
    115     for ARG ; do                     # each msg line out
    116       [ -n "$ARG" ] && \
    117         echo "$PFX : $ARG" >> "$LOG" # line has content ; send it to log
    118     done
    119   fi
    120 
    121   [ -n "$ERR" ] && exit 1            # error ; leave w/error return
    122 }
    123 
    124 # verify that the msmtp queue is present
    125 #   the first version can be used if you'd like to create the queue dir
    126 #   if it's not found ; I'd rather just be warned if it's not there
    127 check_queue() {                      # make certain queue dir is present
    128   #if [ ! -d "$Q" ] ; then            # queue dir not present ; create it
    129         #  /bin/mkdir -p "$Q" || dsp -e 'could not create queue dir'
    130         #  dsp "created msmtp queue dir [ $Q ]"
    131   #fi
    132   [ -d "$Q" ] || \
    133     dsp -e "can't find msmtp queue [ $Q ]"  # queue dir not present - complain
    134 }
    135 
    136 # run (flush) queue
    137 run_queue() {                        # run queue
    138   local LOK="${Q}/.lock" MLF MSF     # lock file name ; queued mail filename pairs
    139   local -i MAX=120 SEC=0 RC          # max seconds to gain a lock ; seconds waiting
    140 
    141   if (( $(/bin/ls -1 ${Q}/*.mail 2> /dev/null | \
    142           /usr/bin/wc -l) > 0 )) ; then              # if any mail in Q
    143                                                      # attempt to lock queue
    144     while [ -e "$LOK" ] && (( SEC < MAX )) ; do      # if a lock file there
    145             /bin/sleep 1                                   # wait a second
    146             (( ++SEC ))                                    # accumulate seconds
    147     done                                             # try again while locked
    148 						     # for MAX secs
    149     if [ -e "$LOK" ] ; then                          # lock file still there, give up
    150             dsp -e '' "cannot use $Q : waited $MAX seconds for"\
    151                    "  lockfile [ $LOK ] to vanish ; giving up"\
    152                    'if you are sure that no other instance of this script'\
    153                    '  is running, then delete the lock file manually' ''
    154     fi
    155 
    156     /bin/touch "$LOK" || \
    157       dsp -e "couldn't create lock file [ $LOK ]" # lock queue
    158 
    159     for MLF in ${Q}/*.mail ; do      # process all mails
    160             dsp "sending mail file [ $MLF ] ..." # scratch user's itch
    161             MSF="${MLF%.*}.msmtp"
    162             if [ ! -f "$MSF" ] ; then      # no corresponding MSF file found
    163                     dsp "corresponding mail file [ $MSF ] not found in queue"\
    164                         '  worth an investigation ...' # give user the bad news
    165                     continue                     # crank on
    166             fi
    167             /usr/bin/msmtp $(/bin/cat "$MSF") < "$MLF"  # this mail goes out the door
    168       RC=$?
    169             if [ $RC == 0 ] ; then         # send was successful
    170                     /bin/rm -f "$MLF" "$MSF"     # nuke the mail files
    171                     dsp "sent mail [ $MLF ] from queue : send successful ; purged from queue" # good news to user
    172             else                           # send was unsuccessful
    173                     dsp "sent mail [ $MLF ] from queue ; send failed ; msmtp rc = $RC" # bad news ...
    174             fi
    175     done
    176   else                               # no mails in queue
    177     dsp -L '' 'mail queue is empty'\
    178            'nothing to run/flush' '' # inform user
    179   fi
    180 
    181   /bin/rm -f "$LOK"                  # remove the lock
    182   nohup notmuch new &
    183 }
    184 
    185 # display queue contents
    186 display_queue() {
    187   local M LST="$(/bin/ls $Q/*.mail 2>/dev/null)"   # list of mails in queue
    188 
    189   (( CNT = 0 ))
    190   if [ -n "$LST" ] ; then            # list has contents (any mails in queue)
    191     for M in $LST ; do               # cycle through each
    192       dsp -L '' "mail id = [ $(/usr/bin/basename $M .mail) ]"  # show mail id
    193       /bin/egrep -s --colour -h '(^From:|^To:|^Subject:)' "$M" # show mail info
    194       (( CNT++ ))                    # bump counter
    195     done
    196     echo
    197   else                               # no mails ; no contents
    198     dsp -L '' 'no mail in queue' ''  # inform user
    199   fi
    200 }
    201 
    202 # delete all mail in queue
    203 purge_all_mail() { # <-- 'one mail' opt (-1)
    204   local YN I C                       # confirmation response ; question text ; ack text
    205 
    206   if [ "$1" == '-1' ] ; then         # queue contains single mail
    207     I="remove the only mail from the queue"
    208     C="single mail purged from queue"
    209   else                               # queue contains multiple mails
    210     I="remove (purge) all mail from the queue"
    211     C="msmtp queue purged (all mail)"
    212     display_queue
    213   fi
    214 
    215   echo -n "  $I [y/N] ? ...: " ; read YN
    216   case $YN in                        # nuke all mail in queue (dir)
    217     y|Y) /bin/rm -f "$Q"/*.* ; dsp '' "$C ..." ''             ;;
    218     *)   dsp -L '' 'nothing done ; queue is untouched ...' '' ;;
    219   esac
    220 }
    221 
    222 # purge a single mail from queue
    223 purge_one_mail() {
    224   local ID                           # id of mail being deleted
    225 
    226   while true ; do                    # purge an individual mail from queue
    227     display_queue                    # show queue contents, if any
    228     if (( CNT > 0 )) ; then          # something there
    229       if (( CNT == 1 )) ; then       # only one mail
    230         purge_all_mail -1            # purge it
    231         break
    232       else                           # more than one mail
    233         echo '  remove (purge) a mail from the queue ; enter its id'
    234         echo -n '    ( <cr> only to exit ) ...: ' ; read ID
    235         if [ -n "$ID" ] ; then       # <-- file name (only, no suff)
    236           if [ -n "$(/bin/ls "$Q"/"$ID".* 2>/dev/null)" ] ; then
    237             /bin/rm -f "$Q"/"$ID".*  # msmtp - nukes a single mail in queue (dir)
    238             dsp '' "mail [ $ID ] purged from queue ..."
    239           else                       # invalid id entered
    240             dsp -L '' "mail [ $ID ] not found ; bad id ..."
    241           fi
    242         else                         # nothing entered
    243           dsp -L '' 'nothing done ; queue is untouched ...' ''
    244           break
    245         fi
    246       fi
    247     else
    248       break
    249     fi
    250   done
    251 }
    252 
    253 #
    254 ## -- entry point
    255 #
    256 
    257 [ -z "$1" ] && usage 'msmtpq requires an instruction'
    258 
    259 check_queue                          # check that queue directory is present ...
    260 OP=${1:1}                            # trim off first char of OP
    261 case "$OP" in                        # sort ops ; run according to spec
    262   r) run_queue      ;;               # run (flush) the queue
    263   d) display_queue  ;;               # display (list) all mail in queue
    264   p) purge_one_mail ;;               # purge an individual mail from queue
    265   a) purge_all_mail ;;               # purge all mail in queue
    266   h) usage          ;;               # show help
    267   *) usage "[ $A ] is an unknown msmtpq option" ;;
    268 esac
    269 
    270 exit 0