"Fossies" - the Fresh Open Source Software Archive

Member "msmtp-1.8.17/scripts/msmtpq/msmtpq" (30 Apr 2020, 23495 Bytes) of package /linux/privat/msmtp-1.8.17.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Bash source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 #!/usr/bin/env bash
    2 
    3 ##--------------------------------------------------------------
    4 ##
    5 ##  msmtpq : queue funtions to both use & manage the msmtp queue,
    6 ##             as it was defined by Martin Lambers
    7 ##  Copyright (C) 2008 - 2015 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 ## msmtpq is meant to be used by an email client - in 'sendmail' mode
   17 ##   for this purpose, it is invoked directly as 'msmtpq'
   18 ## it is also meant to be used to maintain the msmtp queue
   19 ##   when it is evoked by the wrapper script 'msmtp-queue'
   20 ##   (which calls this script as msmtpq --q-mgmt)
   21 ##
   22 ## there is a queue log file, distinct from the msmtp log,
   23 ##   for all events & operations on the msmtp queue
   24 ##   that is defined below
   25 ##
   26 ## (mutt users, using msmtpq in 'sendmail' mode,
   27 ##  should make at least the following two settings in their .muttrc
   28 ##    set sendmail = /path/to/msmtpq
   29 ##    set sendmail_wait = -1
   30 ##
   31 ##  please see the msmtp man page and docs for further mutt settings
   32 ##    and optimisations
   33 ## )
   34 ##
   35 ## two essential patches by Philipp Hartwig
   36 ## 19 Oct 2011 & 27 Oct 2011
   37 ##
   38 ##--------------------------------------------------------------
   39 ## the msmtp queue contains unique filenames of the following form :
   40 ##   two files for each mail in the queue
   41 ##
   42 ## creates new unique filenames of the form :
   43 ##   MLF: ccyy-mm-dd-hh.mm.ss[-x].mail   -- mail file
   44 ##   MSF: ccyy-mm-dd-hh.mm.ss[-x].msmtp  -- msmtp commands file
   45 ## where x is a consecutive number only appended for uniqueness
   46 ##   if more than one mail per second is sent
   47 ##--------------------------------------------------------------
   48 
   49 
   50 dsp() { local L ; for L ; do [ -n "$L" ] && echo "  $L" || echo ; done ; }
   51 err() { dsp '' "$@" '' ; exit 1 ; }
   52 
   53 ## ======================================================================================
   54 ##      !!!          please define or confirm the following three vars           !!!
   55 ##      !!!           before using the msmtpq or msmtp-queue scripts             !!!
   56 ## ======================================================================================
   57 ##
   58 ## only if necessary (in unusual circumstances - e.g. embedded systems),
   59 ##   enter the location of the msmtp executable  (no quotes !!)
   60 ##   e.g. ( MSMTP=/path/to/msmtp )
   61 ##   and uncomment the test for its existence
   62 MSMTP=msmtp
   63 #[ -x "$MSMTP" ] || \
   64 #  log -e 1 "msmtpq : can't find the msmtp executable [ $MSMTP ]"   # if not found - complain ; quit
   65 ##
   66 ## set the queue var to the location of the msmtp queue directory
   67 ##   if the queue dir doesn't yet exist, create it (0700)
   68 ##     before using this script
   69 ##       e.g. ( mkdir msmtp.queue      )
   70 ##            ( chmod 0700 msmtp.queue )
   71 ##
   72 ## the queue dir - modify this to reflect where you'd like it to be  (no quotes !!)
   73 Q=~/.msmtp.queue
   74 [ -d "$Q" ] || \
   75   err '' "msmtpq : can't find msmtp queue directory [ $Q ]" ''     # if not present - complain ; quit
   76 ##
   77 ## set the queue log file var to the location of the msmtp queue log file
   78 ##   where it is or where you'd like it to be
   79 ##     ( note that the LOG setting could be the same as the )
   80 ##     ( 'logfile' setting in .msmtprc - but there may be   )
   81 ##     ( some advantage in keeping the two logs separate    )
   82 ##   if you don't want the log at all unset (comment out) this var
   83 ##     LOG=~/log/msmtp.queue.log  -->  #LOG=~/log/msmtp.queue.log
   84 ##     (doing so would be inadvisable under most conditions, however)
   85 ##
   86 ## the queue log file - modify (or comment out) to taste  (but no quotes !!)
   87 LOG=~/log/msmtp.queue.log
   88 ## ======================================================================================
   89 
   90 ## msmtpq can use the following environment variables :
   91 ##   EMAIL_CONN_NOTEST   if set will suppress any testing for a connection
   92 ##                         (the above var is deprecated & will be removed ; use the var below)
   93 ##   EMAIL_CONN_TEST     if =x will suppress any testing for a connection
   94 ##                       if =p or unset will use a ping test (debian.org) for a connection
   95 ##                       if =P will use a fast ping test (8.8.8.8) for a connection
   96 ##                       if =n will use netcat (nc) to test for a connection
   97 ##                       if =s will use bash sockets to test for a connection
   98 ##   EMAIL_QUEUE_QUIET   if set will cause suppression of messages and 'chatter'
   99 ##                         (perhaps useful for some of the emacs mail clients)
  100 ##
  101 ## ======================================================================================
  102 ##      !!!      define or confirm the following vars if you wish to set         !!!
  103 ##      !!!      these properties here in the script - the same properties       !!!
  104 ##      !!!      may be set externally, by means of environment variables        !!!
  105 ##      !!!      note the internal variables, if set, will take precedence       !!!
  106 ##      !!!      over properties set via environment variables                   !!!
  107 ## ======================================================================================
  108 ##
  109 #EMAIL_CONN_NOTEST=y                 # deprecated ; use below var
  110 #EMAIL_CONN_TEST={x| |p|P|n|s}       # see settings above for EMAIL_CONN_TEST
  111 EMAIL_CONN_TEST=n
  112 #EMAIL_QUEUE_QUIET=t
  113 ## ======================================================================================
  114 
  115 umask 077                            # set secure permissions on created directories and files
  116 
  117 declare -i CNT                       # a count of mail(s) currently in the queue
  118 declare -a Q_LST                     # queue list array ; used selecting a mail (to send or remove)
  119 
  120 ## do ; test this !
  121 #for sig in INT TERM EXIT; do
  122 #  trap "rm -f \"\$TMPFILE\"; [[ $sig == EXIT ]] || kill -$sig $$" $sig
  123 #done
  124 trap on_exit INT TERM EXIT           # run 'on_exit' on exit
  125 on_exit() {                          # unlock the queue on exit if the lock was set here
  126   [ -n "$LKD" ] && lock_queue -u 2>/dev/null
  127 }
  128 
  129 #
  130 ## ----------------------------------- functions common to both modes
  131 ## ----------------------------------- (msmtpq & msmtp-queue)
  132 #
  133 
  134 ## make an entry to the queue log file, possibly an error
  135 ##   (log queue changes only ; not interactive chatter)
  136 ## usage : log [ -e errcode ] msg [ msg ... ]
  137 ##  opts : -e <exit code>  an error ; log msg & terminate w/prejudice
  138 ## display msg to user, as well
  139 ##
  140 log() {
  141   local ARG RC PFX
  142   PFX="$('date' +'%Y %d %b %H:%M:%S')"
  143                                      # time stamp prefix - "2008 13 Mar 03:59:45 "
  144   if [ "$1" = '-e' ] ; then          # there's an error exit code
  145     RC="$2"                          # take it
  146     shift 2                          # shift opt & its arg off
  147   fi
  148 
  149   [ -z "$EMAIL_QUEUE_QUIET" ] && dsp "$@"  # display msg to user, as well as logging it
  150 
  151   if [ -n "$LOG" ] ; then            # log is defined and in use
  152     for ARG ; do                     # each msg line out
  153       [ -n "$ARG" ] && \
  154         echo "$PFX : $ARG" >> "$LOG" # line has content ; send it to log
  155     done
  156   fi
  157 
  158   if [ -n "$RC" ] ; then             # an error ; leave w/error return
  159     [ -n "$LKD" ] && lock_queue -u   # unlock here (if locked)
  160     [ -n "$LOG" ] && \
  161       echo "    exit code = $RC" >> "$LOG" # logging ok ; send exit code to log
  162     exit "$RC"                       # exit w/return code
  163   fi
  164 }
  165 
  166 ## write/remove queue lockfile for a queue op
  167 ##
  168 lock_queue() {        # <-- '-u' to remove lockfile
  169   local LOK="${Q}/.lock"             # lock file name
  170   local -i MAX=240 SEC=0             # max seconds to gain a lock ; seconds waiting
  171 
  172   if [ -z "$1" ] ; then              # lock queue
  173     ## Philipp Hartwig patch #2
  174     'mkdir' "$LOK" 2>/dev/null && LKD='t'
  175     while [ -z "$LKD" ] && [ "$SEC" -lt "$MAX" ]; do # lock file present
  176       sleep 1                                        # wait a second
  177       SEC=$((SEC + 1))                               # accumulate seconds
  178       'mkdir' "$LOK" 2>/dev/null && LKD='t'          # make lockdir ; lock queue ; set flag
  179     done                                             # try again while locked for MAX secs
  180     [ -z "$LKD" ] && \
  181         err '' "cannot use queue $Q : waited $MAX seconds for"\
  182                "  lockdir [ $LOK ] to vanish ; giving up"\
  183                'if you are certain that no other instance of this script'\
  184                "  is running, then 'rmdir' the lock dir manually" '' # lock file still there, give up
  185 
  186   elif [ "$1" = '-u' ] ; then        # unlock queue
  187     'rmdir' "$LOK"                   # remove the lock
  188     unset LKD                        # unset flag
  189   fi
  190 }
  191 
  192 ## test whether system is connected
  193 ## returns t/f (0/1)
  194 ##
  195 connect_test() {
  196   if [ -z "$EMAIL_CONN_TEST" ] || \
  197      [ "$EMAIL_CONN_TEST" = 'p' ] ; then                       # use ping test (default)
  198     # verify net connection - ping ip address of debian.org
  199     # would ping -qnc2 -w4 be better ?
  200     # would ping -qnc1 -w10 or -w20 be better ?
  201     #ping -qnc1 -w4 debian.org >/dev/null 2>&1 || return 1
  202     ping -qnc2 -w10 debian.org >/dev/null 2>&1 || return 1
  203 
  204   elif [ "$EMAIL_CONN_TEST" = 'P' ] ; then                     # use quicker ping test
  205     # I personally think that including a DNS lookup
  206     # is a better connection test but some
  207     # have found the above test too slow
  208     ping -qnc1 -w4 8.8.8.8 >/dev/null 2>&1 || return 1
  209 
  210   elif [ "$EMAIL_CONN_TEST" = 'n' ] ; then                     # use netcat (nc) test
  211     # must, of course, have netcat (nc) installed
  212     which nc >/dev/null 2>&1 || \
  213       log -e 1 "msmtpq : can't find netcat executable [ nc ]"  # if not found - complain ; quit
  214     'nc' -vz www.debian.org 80 >/dev/null 2>&1 || return 1
  215 
  216   elif [ "$EMAIL_CONN_TEST" = 's' ] ; then                     # use sh sockets test
  217     # note that this does not work on debian systems
  218     #   where bash opened sockets are suppressed for security
  219     #   reasons on multiuser systems - however, this should be
  220     #   ok for single user systems (including embedded systems)
  221     # test whether this is supported on your system before using...
  222     # thank you to Brian Goose, on the list, for encouraging this
  223     exec 3<>/dev/udp/debian.org/80 || return 1                 # open socket on site ; use dns
  224     exec 3<&- ; exec 3>&-                                      # close socket
  225   fi
  226   return 0
  227 }
  228 
  229 #
  230 ## ----------------------------------- functions for queue management
  231 ## ----------------------------------- queue maintenance mode - (msmtp-queue)
  232 #
  233 
  234 ## show queue maintenance functions
  235 ##
  236 usage() {        # <-- error msg
  237   dsp ''\
  238       'usage : msmtp-queue functions' ''\
  239       '        msmtp-queue < op >'\
  240       '        ops : -r   run (flush) mail queue - all mail in queue'\
  241       '              -R   send selected individual mail(s) in queue'\
  242       '              -d   display (list) queue contents   (<-- default)'\
  243       '              -p   purge individual mail(s) from queue'\
  244       '              -a   purge all mail in queue'\
  245       '              -h   this helpful blurt' ''\
  246       '        ( one op only ; any others ignored )' ''
  247   if [ -z "$1" ]; then
  248     exit 0;
  249   else
  250     dsp "$@" '';
  251     exit 1;
  252   fi
  253 }
  254 
  255 ## get user [y/n] acknowledgement
  256 ##
  257 ok() {
  258   local R YN='Y/n'                   # default to yes
  259 
  260   [ "$1" = '-n' ] && \
  261     { YN='y/N' ; shift ; }           # default to no ; change prompt ; shift off spec
  262 
  263   dsp "$@"
  264   while true ; do
  265     echo -n "  ok [${YN}] ..: "
  266     read -r R
  267     case $R in
  268       y|Y) return 0 ;;
  269       n|N) return 1 ;;
  270       '')  [ "$YN" = 'Y/n' ] && return 0 || return 1 ;;
  271       *)   echo 'yYnN<cr> only please' ;;
  272     esac
  273   done
  274 }
  275 
  276 ## send a queued mail out via msmtp
  277 ##
  278 send_queued_mail() {   # <-- mail id
  279   local FQP="${Q}/${1}"              # fully qualified path name
  280   local -i RC=0                      # for msmtp exit code
  281 
  282   if [ -f "${FQP}.msmtp" ] ; then    # corresponding .msmtp file found
  283     [ "$EMAIL_CONN_TEST" != 'x' ] && \
  284     [ -z "$EMAIL_CONN_NOTEST" ] && { # do connection test
  285       connect_test || {
  286         log "mail [ $2 ] [ $1 ] from queue ; couldn't be sent - host not connected"
  287         return
  288       }
  289     }
  290 
  291     if "$MSMTP" $(< "${FQP}.msmtp") < "${FQP}.mail" ; then     # this mail goes out the door
  292       log "mail [ $2 ] [ $1 ] from queue ; send was successful ; purged from queue"  # good news to user
  293       'rm' -f "${FQP}".*                                       # nuke both queue mail files
  294       ALT='t'                        # set queue changed flag
  295     else                             # send was unsuccessful
  296       RC=$?                          # take msmtp exit code
  297       log "mail [ $2 ] [ $1 ] from queue ; send failed ; msmtp rc = $RC" # bad news ...
  298     fi
  299     return $RC                       # func returns exit code
  300   else                               # corresponding MSF file not found
  301     log "preparing to send .mail file [ $1 ] [ ${FQP}.mail ] but"\
  302         "  corresponding .msmtp file [ ${FQP}.msmtp ] was not found in queue"\
  303         '  skipping this mail ; this is worth looking into'    # give user the bad news
  304   fi                                                           # (but allow continuation)
  305 }
  306 
  307 ## run (flush) queue
  308 ##
  309 run_queue() {    # <- 'sm' mode      # run queue
  310   local M LST
  311   local -i NDX=0
  312 
  313   LST="$('ls' $Q/*.mail 2>/dev/null)"            # list of mails in queue
  314   if [ -n "$LST" ] ; then            # something in queue
  315     for M in $LST ; do               # process all mails
  316       NDX=$((NDX + 1))
  317       send_queued_mail "$(basename $M .mail)" "$NDX"     # send mail - pass {id} only
  318     done
  319   else                               # queue is empty
  320     [ -z "$1" ] && \
  321       dsp '' 'mail queue is empty (nothing to send)' ''
  322   fi                                 # inform user (if not running in sendmail mode)
  323 }
  324 
  325 ## display queue contents
  326 ##
  327 display_queue() {      # <-- { 'purge' | 'send' } (op label) ; { 'rec' } (record array of mail ids)
  328   local M ID LST
  329 
  330   LST="$('ls' ${Q}/*.mail 2>/dev/null)"       # list of mail ids in queue
  331   CNT=0
  332   if [ -n "$LST" ] ; then            # list has contents (any mails in queue)
  333     for M in $LST ; do               # cycle through each
  334       ID="$(basename $M .mail)"      # take mail id from filename
  335       CNT=$((CNT + 1))
  336       dsp '' "mail  num=[ $CNT ]  id=[ $ID ]"                  # show mail id ## patch in
  337       'grep' -E -s --colour -h -m 3 '(^From:|^To:|^Subject:)' "$M" # show mail info
  338       [ -n "$2" ] && Q_LST[$CNT]="$ID" # bang mail id into array (note 1-based array indexing)
  339     done
  340     echo
  341   else                               # no mails ; no contents
  342     if [ -z "$1" ]; then
  343       dsp '' 'no mail in queue' ''
  344     else
  345       dsp '' "mail queue is empty (nothing to $1)" ''    # inform user
  346     fi
  347     exit 0
  348   fi
  349 }
  350 
  351 ## delete all mail in queue, after confirmation
  352 ##
  353 purge_queue() {
  354   display_queue 'purge'              # show queue contents
  355   if ok -n 'remove (purge) all mail from the queue' ; then
  356     lock_queue                       # lock here
  357     'rm' -f "$Q"/*.*
  358     log 'msmtp queue purged (all mail)'
  359     lock_queue -u                    # unlock here
  360   else
  361     dsp '' 'nothing done ; queue is untouched' ''
  362   fi
  363 }
  364 
  365 ## select a single mail from queue ; delete it or send it
  366 ## select by mail index (position in queue) or mail id
  367 ##
  368 select_mail() {  # <-- < 'purge' | 'send' >
  369   local OK ID                                        # mail id
  370   local -i I NDX                                     # mail index (position in queue)
  371 
  372   while true ; do                                    # purge an individual mail from queue
  373     display_queue "$1" 'rec'                         # show queue contents ; make mail ids array
  374 
  375     ## allow selection also by mail index
  376     if [ $CNT -eq 1 ] ; then                         # only one mail in queue ; take its id
  377       NDX=1
  378       ID="${Q_LST[1]}"
  379     else                                             # more than one mail ; select its id
  380       while true ; do                                # get mail id
  381         OK='t'                                       # optimistic to a fault
  382         dsp "enter mail number or id to $1"          # <-- num or file name (only, no suff)
  383         echo -n '    ( <cr> alone to exit ) ..: '
  384         read -r ID
  385         [ -n "$ID" ] || return                       # entry made - or say good bye
  386 
  387         if [ "${ID:4:1}" != '-' ] ; then             # mail id *not* entered ; test index num
  388           I=0
  389           while [ "$I" -lt ${#ID} ]; do              # test index number
  390             if [ "${ID:${I}:1}" -lt '0' ] || \
  391                   [ "${ID:${I}:1}" -gt '9' ] ; then
  392               dsp '' "[ $ID ] is neither a valid mail id"\
  393                      'nor a valid mail number' ''
  394               unset OK
  395             fi
  396           I=$((I + 1))
  397           done
  398           [ -z "$OK" ] && continue                   # format not ok (not all nums)
  399 
  400           NDX=$ID
  401           if [ "$NDX" -lt 1 ] || [ "$NDX" -gt "$CNT" ] ; then  # test number range (1 - $CNT)
  402             dsp '' "[ $NDX ] is out of range as a mail number"\
  403                    "validity is from 1 to $CNT"
  404             continue                                 # try again
  405           fi
  406 
  407           ID="${Q_LST[$NDX]}"                        # format & range were ok ; use it
  408           break                                      # valid mail selection
  409         else                                         # mail id entered
  410           NDX=1
  411           while [ "$NDX" -le ${#Q_LST[*]} ]; do                 # find entered id in queue list
  412             [ "$ID" = "${Q_LST[$NDX]}" ] && break
  413             NDX=$((NDX + 1))
  414           done
  415           if [ "$NDX" -le ${#Q_LST[*]} ]; then
  416             break
  417           else
  418             dsp '' "mail [ $ID ] not found ; invalid id" # mail selection valid (found) or
  419           fi
  420         fi                                               # fell through (not found) complain
  421       done                                               # and ask again
  422     fi
  423 
  424     if ok '' "$1 :"\
  425           "  mail num=[ $NDX ]"\
  426           "        id=[ $ID ]" '' ; then             # confirm mail op
  427       if [ "$1" = 'purge' ] ; then                   # purging
  428         lock_queue                                   # lock here
  429         'rm' -f "$Q"/"$ID".*                         # msmtp - nukes single mail (both files) in queue
  430         log "mail [ $ID ] purged from queue"         # log op
  431         lock_queue -u                                # unlock here
  432         ALT='t'                                      # mark that a queue alteration has taken place
  433       else                                           # sending
  434         lock_queue                                   # lock here
  435         send_queued_mail "$ID" "$NDX"                # send out the mail
  436         lock_queue -u                                # unlock here
  437       fi
  438     else                                             # user opts out
  439       dsp '' 'nothing done to this queued email'     # soothe user
  440       [ $CNT -eq 1 ] && break                        # single mail ; user opted out
  441     fi
  442     dsp '' "--------------------------------------------------"
  443   done
  444 
  445   if [ -n "$ALT" ] ; then            # queue was changed
  446     dsp '' 'done' ''
  447   else                               # queue is untouched
  448     dsp '' 'nothing done ; queue is untouched' ''
  449   fi
  450 }
  451 
  452 #
  453 ## ----------------------------------- functions for directly sending mail
  454 ## ----------------------------------- 'sendmail' mode - (msmtpq)
  455 #
  456 
  457 ## ('sendmail' mode only)
  458 ## make base filename id for queue
  459 ##
  460 make_id() {
  461   local -i INC                       # increment counter for (possible) base fqp name collision
  462 
  463   ID="$(date +%Y-%m-%d-%H.%M.%S)"    # make filename id for queue    (global
  464   FQP="${Q}/$ID"                     # make fully qualified pathname  vars)
  465   ## Philipp Hartwig patch #1
  466   if [ -f "${FQP}.mail" ] || [ -f "${FQP}.msmtp" ] ; then    # ensure fqp name is unique
  467     INC=1                            # initial increment
  468       while [ -f "${FQP}-${INC}.mail" ] || [ -f "${FQP}-${INC}.msmtp" ] ; do # fqp name w/incr exists
  469         INC=$((INC + 1))             # bump increment
  470       done
  471       ID="${ID}-${INC}"              # unique ; set id
  472       FQP="${FQP}-${INC}"            # unique ; set fqp name
  473   fi
  474 }
  475 
  476 ## ('sendmail' mode only)
  477 ## enqueue a mail
  478 ##
  479 enqueue_mail() { # <-- all mail args ; mail text via TMP
  480   if echo "$@" > "${FQP}.msmtp" ; then     # write msmtp command line to queue .msmtp file
  481     log "enqueued mail as : [ $ID ] ( $* ) : successful" # (queue .mail file is already there)
  482   else                                     # write failed ; bomb
  483     log -e "$?" "queueing - writing msmtp cmd line { $* }"\
  484                 "           to [ ${ID}.msmtp ] : failed"
  485   fi
  486 }
  487 
  488 ## ('sendmail' mode only)
  489 ## send a mail (if possible, otherwise enqueue it)
  490 ## if send is successful, msmtp will also log it (if logging enabled in ~/.msmtprc)
  491 ##
  492 send_mail() {    # <-- all mail args ; mail text via TMP
  493   [ "$EMAIL_CONN_TEST" != 'x' ] && \
  494   [ -z "$EMAIL_CONN_NOTEST" ] && {   # do connection test
  495     connect_test || {
  496       log "mail for [ $* ] : couldn't be sent - host not connected"
  497       enqueue_mail "$@"              # enqueue the mail
  498       return
  499     }
  500   }
  501 
  502   if $MSMTP "$@" < "${FQP}.mail" > /dev/null ; then      # send mail using queue .mail fil
  503     log "mail for [ $* ] : send was successful"          # log it
  504     'rm' -f "${FQP}".*               # remove all queue mail files .mail & .msmtp file
  505     run_queue 'sm'                   # run/flush any other mails in queue
  506   else                               # send failed - the mail stays in the queue
  507     log "mail for [ $* ] : send was unsuccessful ; msmtp exit code was $?"\
  508         "enqueued mail as : [ $ID ] ( $* )"    # (queue .mail file is already there)
  509   fi
  510 }
  511 
  512 #
  513 ## -- entry point
  514 #
  515 
  516 if [ ! "$1" = '--q-mgmt' ] ; then    # msmtpq - sendmail mode
  517   lock_queue                         # lock here
  518   make_id                            # make base queue filename id for this mail
  519   # write mail body text to queue .mail file
  520   cat > "${FQP}.mail" || \
  521     log -e "$?" "creating mail body file [ ${FQP}.mail ] : failed" # test for error
  522   # write msmtp command line to queue .msmtp file
  523   echo "$@" > "${FQP}.msmtp" || \
  524     log -e "$?" "creating msmtp cmd line file { $* }"\
  525                 "           to [ ${ID}.msmtp ] : failed" # test for error
  526   send_mail "$@"                     # send the mail if possible, queue it if not
  527   lock_queue -u                      # unlock here
  528 else                                 # msmtp-queue - queue management mode
  529   shift                              # trim off first (--q-mgmt) arg
  530   OP=${1:1}                          # trim off first char of OP arg
  531   case "$OP" in                      # sort ops ; run according to spec
  532     r)    lock_queue
  533           run_queue
  534           lock_queue -u       ;;     # run (flush) the queue
  535     R)    select_mail send    ;;     # send individual mail(s) in queue
  536     d|'') display_queue       ;;     # display (list) all mail in queue (default)
  537     p)    select_mail purge   ;;     # purge individual mail(s) from queue
  538     a)    purge_queue         ;;     # purge all mail in queue
  539     h)    usage               ;;     # show help
  540     *)    usage "[ -$OP ] is an unknown msmtp-queue option" ;;
  541   esac
  542 fi
  543 
  544 exit 0