Hello Josiah,
Apologies for the late reply (I've been away for a while) ; I maintain
the msmtpq script and wonder what is going on here. I, as well, would
like to ensure that msmtpq works correctly with emacs mailers ;
hopefully we can work this out. You're correct ; what you are
describing is not the intended behaviour. It seems to me that you may
have an older or a corrupt version of the script ; the current version
does not have this problem (as far as I can tell). If the connect test
is failed then msmtp is *not* invoked - and, of course, then wouldn't
produce spurious messages. I've attached the latest version of msmtpq
; would you test it and see whether or not it produces the same
effect... Please let me know the results ; I'd like to see proper
functionality for emacs...
Thanks & best regards,
Chris
On Sun 1.Sep'13 at 19:47:00 -0700, Josiah Schwab wrote:
> Hi All,
>
> I am in the process of trying to switch from msmtp to msmtpq as my
> sendmail program in emacs. As has previously been discussed on this
> list, it appears that emacs expects silence upon success.
>
> http://sourceforge.net/mailarchive/message.php?msg_id=29729814[1]
>
> After reading the documentation, I have set the environment variable
> EMAIL_QUEUE_QUIET=t and that works great when sending while online.
>
> I do not have similar sucess offline. The messages queue correctly, but
> the subsequent failure of msmtp (because I'm offline), causes problems.
>
> My logs look like:
>
> 2013 01 Sep 19:06:28 : mail for [ -a XXXXXXXX jsch...@gmail.com ] :
> couldn't be sent - host not connected
> 2013 01 Sep 19:06:28 : enqueued mail as : [ 2013-09-01-19.06.28 ] ( -a
> XXXXXXXX jsch...@gmail.com ) : successful
> 2013 01 Sep 19:06:28 : mail for [ -a XXXXXXXX jsch...@gmail.com ] : send
> was unsuccessful ; msmtp exit code was 68
> 2013 01 Sep 19:06:28 : enqueued mail as : [ 2013-09-01-19.06.28 ] ( -a
> XXXXXXXX jsch...@gmail.com )
>
> and msmtp also complains on stderr:
>
> msmtp: cannot locate host smtp.gmail.com: Name or service not known
> msmtp: could not send mail (account XXXXXXXX from /home/jschwab/.msmtprc)
>
> Poking around in the code, the issue arises in during the send_mail
> (line 436) function. After failing the connection test (line 438) and
> enquing the message, msmtp is invovked (line 445) almost immediately
> thereafter. Naively, that seems surprising to me. Is this the intended
> behavior?
>
> This is relatively simple to workaround, either by wrapping the msmtp
> call in a connection test (so it doesn't run) or by sending stderr to
> /dev/null (so emacs doesn't hear the complaints.)
>
> I'd like to figure out how to set this up "correctly", so it can just
> be drop-in and work out-of-the-box for emacs users.
>
> Best,
> Josiah Schwab
>
>
> ------------------------------------------------------------------------------
> Learn the latest--Visual Studio 2012, SharePoint 2013, SQL 2012, more!
> Discover the easy way to master current and previous Microsoft technologies
> and advance your career. Get an incredible 1,500+ hours of step-by-step
> tutorial videos with LearnDevNow. Subscribe today and save!
> http://pubads.g.doubleclick.net/gampad/clk?id=58040911&iu=/4140/ostg.clktrk
> _______________________________________________
> msmtp-users mailing list
> msmtp-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/msmtp-users
>
#!/usr/bin/env bash
##--------------------------------------------------------------
##
## msmtpq : queue funtions to both use & manage the msmtp queue,
## as it was defined by Martin Lambers
## Copyright (C) 2008, 2009, 2010, 2011 Chris Gianniotis
##
## 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 3 of the License, or, at
## your option, any later version.
##
##--------------------------------------------------------------
##
## msmtpq is meant to be used by an email client - in 'sendmail' mode
## for this purpose, it is invoked directly as 'msmtpq'
## it is also meant to be used to maintain the msmtp queue
## evoked by the wrapper script 'msmtp-queue'
## (which calls this script as msmtpq --q-mgmt)
##
## there is a queue log file, distinct from the msmtp log,
## for all events & operations on the msmtp queue
## that is defined below
##
## (mutt users, using msmtpq in 'sendmail' mode,
## should make at least the following two settings in their .muttrc
## set sendmail = /path/to/msmtpq
## set sendmail_wait = -1
##
## please see the msmtp man page and docs for further mutt settings
## and optimisations
## )
##
## two essential patches by Philipp Hartwig
## 19 Oct 2011 & 27 Oct 2011
##
##--------------------------------------------------------------
## the msmtp queue contains unique filenames of the following form :
## two files for each mail in the queue
##
## creates new unique filenames of the form :
## MLF: ccyy-mm-dd-hh.mm.ss[-x].mail -- mail file
## MSF: ccyy-mm-dd-hh.mm.ss[-x].msmtp -- msmtp commands file
## where x is a consecutive number only appended for uniqueness
## if more than one mail per second is sent
##--------------------------------------------------------------
dsp() { local L ; for L ; do [ -n "$L" ] && echo " $L" || echo ; done ; }
err() { dsp '' "$@" '' ; exit 1 ; }
##
======================================================================================
## !!! please define or confirm the following three vars
!!!
## !!! before using the msmtpq or msmtp-queue scripts
!!!
##
======================================================================================
##
## only if necessary (in unusual circumstances - e.g. embedded systems),
## enter the location of the msmtp executable (no quotes !!)
## e.g. ( MSMTP=/path/to/msmtp )
## and uncomment the test for its existence
MSMTP=msmtp
#[ -x "$MSMTP" ] || \
# log -e 1 "msmtpq : can't find the msmtp executable [ $MSMTP ]" # if not
found - complain ; quit
##
## set the queue var to the location of the msmtp queue directory
## if the queue dir doesn't yet exist, create it (0700)
## before using this script
## e.g. ( mkdir msmtp.queue )
## ( chmod 0700 msmtp.queue )
##
## the queue dir - modify this to reflect where you'd like it to be (no quotes
!!)
Q=~/.msmtp.queue
[ -d "$Q" ] || \
err '' "msmtpq : can't find msmtp queue directory [ $Q ]" '' # if not
present - complain ; quit
##
## set the queue log file var to the location of the msmtp queue log file
## where it is or where you'd like it to be
## ( note that the LOG setting could be the same as the )
## ( 'logfile' setting in .msmtprc - but there may be )
## ( some advantage in keeping the two logs separate )
## if you don't want the log at all unset (comment out) this var
## LOG=~/log/msmtp.queue.log --> #LOG=~/log/msmtp.queue.log
## (doing so would be inadvisable under most conditions, however)
##
## the queue log file - modify (or comment out) to taste (but no quotes !!)
LOG=~/log/msmtp.queue.log
##
======================================================================================
## msmtpq can use the following environment variables :
## EMAIL_CONN_NOTEST if set will suppress any testing for a connection
## EMAIL_CONN_TEST if =p or unset will use a ping test (debian.org) for a
connection
## if =P will use a fast ping test (8.8.8.8) for a
connection
## if =n will use netcat (nc) to test for a connection
## if =s will use bash sockets to test for a connection
## EMAIL_QUEUE_QUIET if set will cause suppression of messages and 'chatter'
##
##
======================================================================================
## !!! define or confirm the following vars if you wish to set
!!!
## !!! these properties here in the script - the same properties
!!!
## !!! may be set externally, by means of environment variables
!!!
## !!! note the internal environment variables, if set, will take
!!!
## !!! precedence over properties set via environment variables
!!!
##
======================================================================================
##
#EMAIL_CONN_NOTEST=y
#EMAIL_CONN_TEST={ |p|P|n|s} # see settings above for EMAIL_CONN_TEST
EMAIL_CONN_TEST=n
#EMAIL__QUIET=t
##
======================================================================================
umask 077 # set secure permissions on created
directories and files
declare -i CNT # a count of mail(s) currently in the queue
declare -a Q_LST # queue list array ; used selecting a mail
(to send or remove)
## do ; test this !
#for sig in INT TERM EXIT; do
# trap "rm -f \"\$TMPFILE\"; [[ $sig == EXIT ]] || kill -$sig $$" $sig
#done
trap on_exit INT TERM EXIT # run 'on_exit' on exit
on_exit() {
[ -n "$LKD" ] && lock_queue -u 2>/dev/null # unlock the queue on exit if
the lock was set here
}
#
## ----------------------------------- functions common to both modes
## ----------------------------------- (msmtpq & msmtp-queue)
#
## make an entry to the queue log file, possibly an error
## (log queue changes only ; not interactive chatter)
## usage : log [ -e errcode ] msg [ msg ... ]
## opts : -e <exit code> an error ; log msg & terminate w/prejudice
## display msg to user, as well
##
log() {
local ARG RC PFX="$('date' +'%Y %d %b %H:%M:%S')"
# time stamp prefix - "2008 13 Mar
03:59:45 "
if [ "$1" = '-e' ] ; then # there's an error exit code
RC="$2" # take it
shift 2 # shift opt & its arg off
fi
#[ -z "$EMAIL_QUEUE_QUIET" ] && \
#[ -z "$__QUIET" ] && dsp "$@" # display msg to user, as well as logging
it
[ -z "$EMAIL_QUEUE_QUIET" ] && dsp "$@" # display msg to user, as well as
logging it
if [ -n "$LOG" ] ; then # log is defined and in use
for ARG ; do # each msg line out
[ -n "$ARG" ] && \
echo "$PFX : $ARG" >> "$LOG" # line has content ; send it to log
done
fi
if [ -n "$RC" ] ; then # an error ; leave w/error return
[ -n "$LKD" ] && lock_queue -u # unlock here (if locked)
[ -n "$LOG" ] && \
echo " exit code = $RC" >> "$LOG" # logging ok ; send exit code to log
exit $RC # exit w/return code
fi
}
## write/remove queue lockfile for a queue op
##
lock_queue() { # <-- '-u' to remove lockfile
local LOK="${Q}/.lock" # lock file name
local -i MAX=240 SEC=0 # max seconds to gain a lock ; seconds
waiting
if [ -z "$1" ] ; then # lock queue
## Philipp Hartwig patch #2
'mkdir' "$LOK" 2>/dev/null && LKD='t'
while [ -z "$LKD" ] && (( SEC < MAX )) ; do # lock file present
sleep 1 # wait a second
(( ++SEC )) # accumulate seconds
'mkdir' "$LOK" 2>/dev/null && LKD='t' # make lockdir ; lock
queue ; set flag
done # try again while locked
for MAX secs
[ -z "$LKD" ] && \
err '' "cannot use queue $Q : waited $MAX seconds for"\
" lockdir [ $LOK ] to vanish ; giving up"\
'if you are certain that no other instance of this script'\
" is running, then 'rmdir' the lock dir manually" '' # lock
file still there, give up
elif [ "$1" = '-u' ] ; then # unlock queue
'rmdir' "$LOK" # remove the lock
unset LKD # unset flag
fi
}
## test whether system is connected
## returns t/f (0/1)
##
connect_test() {
#if ( [ -z "$EMAIL_CONN_TEST" ] || \
# [ -z "$__TEST" ] ) || \
# ( [ "$EMAIL_CONN_TEST" = 'p' ] || \
# [ "$__TEST" = 'p' ] ) ; then # use ping test
(default)
if [ -z "$EMAIL_CONN_TEST" ] || \
[ "$EMAIL_CONN_TEST" = 'p' ] ; then # use ping test
(default)
# verify net connection - ping ip address of debian.org
# would ping -qnc2 -w4 be better ?
# would ping -qnc1 -w10 or -w20 be better ?
#ping -qnc1 -w4 debian.org >/dev/null 2>&1 || return 1
ping -qnc2 -w10 debian.org >/dev/null 2>&1 || return 1
#elif [ "$EMAIL_CONN_TEST" = 'P' ] || \
# [ "$__TEST" = 'P' ] ; then # use quicker
ping test
elif [ "$EMAIL_CONN_TEST" = 'P' ] ; then # use quicker
ping test
# I personally think that including a DNS lookup
# is a better connection test but some
# have found the above test too slow
ping -qnc1 -w4 8.8.8.8 >/dev/null 2>&1 || return 1
#elif [ "$EMAIL_CONN_TEST" = 'n' ] || \
# [ "$__TEST" = 'n' ] ; then # use netcat
(nc) test
elif [ "$EMAIL_CONN_TEST" = 'n' ] ; then # use netcat
(nc) test
# must, of course, have netcat (nc) installed
which nc >/dev/null 2>&1 || \
log -e 1 "msmtpq : can't find netcat executable [ nc ]" # if not found -
complain ; quit
'nc' -vz www.debian.org 80 >/dev/null 2>&1 || return 1
#elif [ "$EMAIL_CONN_TEST" = 's' ] || \
# [ "$__TEST" = 's' ] ; then # use sh
sockets test
elif [ "$EMAIL_CONN_TEST" = 's' ] ; then # use sh sockets
test
# note that this does not work on debian systems
# where bash opened sockets are suppressed for security reasons
# this should be ok for single user systems (including embedded systems)
# test whether this is supported on your system before using
# thank you to Brian Goose, on the list, for encouraging this
exec 3<>/dev/udp/debian.org/80 || return 1 # open socket on
site ; use dns
exec 3<&- ; exec 3>&- # close socket
fi
return 0
}
#
## ----------------------------------- functions for queue management
## ----------------------------------- queue maintenance mode - (msmtp-queue)
#
## show queue maintenance functions
##
usage() { # <-- error msg
dsp ''\
'usage : msmtp-queue functions' ''\
' msmtp-queue < op >'\
' ops : -r run (flush) mail queue - all mail in queue'\
' -R send selected individual mail(s) in queue'\
' -d display (list) queue contents (<-- default)'\
' -p purge individual mail(s) from queue'\
' -a purge all mail in queue'\
' -h this helpful blurt' ''\
' ( one op only ; any others ignored )' ''
[ -z "$1" ] && exit 0 || { dsp "$@" '' ; exit 1 ; }
}
## get user [y/n] acknowledgement
##
ok() {
local R YN='Y/n' # default to yes
[ "$1" = '-n' ] && \
{ YN='y/N' ; shift ; } # default to no ; change prompt ; shift
off spec
dsp "$@"
while true ; do
echo -n " ok [${YN}] ..: "
read R
case $R in
y|Y) return 0 ;;
n|N) return 1 ;;
'') [ "$YN" = 'Y/n' ] && return 0 || return 1 ;;
*) echo 'yYnN<cr> only please' ;;
esac
done
}
## send a queued mail out via msmtp
##
send_queued_mail() { # <-- mail id
local FQP="${Q}/${1}" # fully qualified path name
local -i RC=0 # for msmtp exit code
if [ -f "${FQP}.msmtp" ] ; then # corresponding .msmtp file found
#[ -z "$EMAIL_CONN_NOTEST" ] && \
#[ -z "$__NOTEST" ] && { # connection test
[ -z "$EMAIL_CONN_NOTEST" ] && { # connection test
connect_test || {
log "mail [ $2 ] [ $1 ] from queue ; couldn't be sent - host not
connected"
return
}
}
if $MSMTP $(< "${FQP}.msmtp") < "${FQP}.mail" ; then # this mail goes
out the door
log "mail [ $2 ] [ $1 ] from queue ; send was successful ; purged from
queue" # good news to user
'rm' -f ${FQP}.* # nuke both
queue mail files
ALT='t' # set queue changed flag
else # send was unsuccessful
RC=$? # take msmtp exit code
log "mail [ $2 ] [ $1 ] from queue ; send failed ; msmtp rc = $RC" # bad
news ...
fi
return $RC # func returns exit code
else # corresponding MSF file not found
log "preparing to send .mail file [ $1 ] [ ${FQP}.mail ] but"\
" corresponding .msmtp file [ ${FQP}.msmtp ] was not found in queue"\
' skipping this mail ; this is worth looking into' # give user the
bad news
fi # (but allow
continuation)
}
## run (flush) queue
##
run_queue() { # <- 'sm' mode # run queue
local M LST="$('ls' $Q/*.mail 2>/dev/null)" # list of mails in
queue
local -i NDX=0
if [ -n "$LST" ] ; then # something in queue
for M in $LST ; do # process all mails
((NDX++))
send_queued_mail "$(basename $M .mail)" "$NDX" # send mail - pass
{id} only
done
else # queue is empty
[ -z "$1" ] && \
dsp '' 'mail queue is empty (nothing to send)' ''
fi # inform user (if not running in sendmail
mode)
}
## display queue contents
##
display_queue() { # <-- { 'purge' | 'send' } (op label) ; { 'rec' }
(record array of mail ids)
local M ID LST="$('ls' ${Q}/*.mail 2>/dev/null)" # list of mail ids in
queue
CNT=0
if [ -n "$LST" ] ; then # list has contents (any mails in queue)
for M in $LST ; do # cycle through each
ID="$(basename $M .mail)" # take mail id from filename
((CNT++))
dsp '' "mail num=[ $CNT ] id=[ $ID ]" # show mail id
## patch in
'egrep' -s --colour -h '(^From:|^To:|^Subject:)' "$M" # show mail info
[ -n "$2" ] && Q_LST[$CNT]="$ID" # bang mail id into array (note 1-based
array indexing)
done
echo
else # no mails ; no contents
[ -z "$1" ] && \
dsp '' 'no mail in queue' '' || \
dsp '' "mail queue is empty (nothing to $1)" '' # inform user
exit 0
fi
}
## delete all mail in queue, after confirmation
##
purge_queue() {
display_queue 'purge' # show queue contents
if ok -n 'remove (purge) all mail from the queue' ; then
lock_queue # lock here
'rm' -f "$Q"/*.*
log 'msmtp queue purged (all mail)'
lock_queue -u # unlock here
else
dsp '' 'nothing done ; queue is untouched' ''
fi
}
## select a single mail from queue ; delete it or send it
## select by mail index (position in queue) or mail id
##
select_mail() { # <-- < 'purge' | 'send' >
local OK ID # mail id
local -i I NDX # mail index (position in
queue)
while true ; do # purge an individual mail
from queue
display_queue "$1" 'rec' # show queue contents ;
make mail ids array
## allow selection also by mail index
if [ $CNT -eq 1 ] ; then # only one mail in queue ;
take its id
NDX=1
ID="${Q_LST[1]}"
else # more than one mail ;
select its id
while true ; do # get mail id
OK='t' # optimistic to a fault
dsp "enter mail number or id to $1" # <-- num or file name
(only, no suff)
echo -n ' ( <cr> alone to exit ) ..: '
read ID
[ -n "$ID" ] || return # entry made - or say good
bye
if [ "${ID:4:1}" != '-' ] ; then # mail id *not* entered ;
test index num
for (( I=0 ; I<${#ID} ; I++ )) ; do # test index number
if [[ "${ID:${I}:1}" < '0' || \
"${ID:${I}:1}" > '9' ]] ; then
dsp '' "[ $ID ] is neither a valid mail id"\
'nor a valid mail number' ''
unset OK
fi
done
[ -z "$OK" ] && continue # format not ok (not all
nums)
NDX=$ID
if [ $NDX -lt 1 ] || [ $NDX -gt $CNT ] ; then # test number range (1
- $CNT)
dsp '' "[ $NDX ] is out of range as a mail number"\
"validity is from 1 to $CNT"
continue # try again
fi
ID="${Q_LST[$NDX]}" # format & range were ok ;
use it
break # valid mail selection
else # mail id entered
for (( NDX=1 ; NDX<=${#Q_LST[*]} ; NDX++ )) ; do # find entered id in
queue list
[ "$ID" = "${Q_LST[$NDX]}" ] && break
done
[ $NDX -le ${#Q_LST[*]} ] && \
break || \
dsp '' "mail [ $ID ] not found ; invalid id" # mail selection valid
(found) or
fi # fell through (not
found) complain
done # and ask again
fi
if ok '' "$1 :"\
" mail num=[ $NDX ]"\
" id=[ $ID ]" '' ; then # confirm mail op
if [ "$1" = 'purge' ] ; then # purging
lock_queue # lock here
'rm' -f "$Q"/"$ID".* # msmtp - nukes single
mail (both files) in queue
log "mail [ $ID ] purged from queue" # log op
lock_queue -u # unlock here
ALT='t' # mark that a queue
alteration has taken place
else # sending
lock_queue # lock here
send_queued_mail "$ID" "$NDX" # send out the mail
lock_queue -u # unlock here
fi
else # user opts out
dsp '' 'nothing done to this queued email' # soothe user
[ $CNT -eq 1 ] && break # single mail ; user opted
out
fi
dsp '' "--------------------------------------------------"
done
if [ -n "$ALT" ] ; then # queue was changed
dsp '' 'done' ''
else # queue is untouched
dsp '' 'nothing done ; queue is untouched' ''
fi
}
#
## ----------------------------------- functions for directly sending mail
## ----------------------------------- 'sendmail' mode - (msmtpq)
#
## ('sendmail' mode only)
## make base filename id for queue
##
make_id() {
local -i INC # increment counter for (possible) base
fqp name collision
ID="$(date +%Y-%m-%d-%H.%M.%S)" # make filename id for queue (global
FQP="${Q}/$ID" # make fully qualified pathname vars)
## Philipp Hartwig patch #1
if [ -f "${FQP}.mail" -o -f "${FQP}.msmtp" ] ; then # ensure fqp name is
unique
INC=1 # initial increment
while [ -f "${FQP}-${INC}.mail" -o -f "${FQP}-${INC}.msmtp" ] ; do #
fqp name w/incr exists
(( ++INC )) # bump increment
done
ID="${ID}-${INC}" # unique ; set id
FQP="${FQP}-${INC}" # unique ; set fqp name
fi
}
## ('sendmail' mode only)
## enqueue a mail
##
enqueue_mail() { # <-- all mail args ; mail text via TMP
if echo "$@" > "${FQP}.msmtp" ; then # write msmtp command line to queue
.msmtp file
log "enqueued mail as : [ $ID ] ( $* ) : successful" # (queue .mail file is
already there)
else # write failed ; bomb
log -e "$?" "queueing - writing msmtp cmd line { $* }"\
" to [ ${ID}.msmtp ] : failed"
fi
}
## ('sendmail' mode only)
## send a mail (if possible, otherwise enqueue it)
## if send is successful, msmtp will also log it (if enabled in ~/.msmtprc)
##
send_mail() { # <-- all mail args ; mail text via TMP
#[ -z "$EMAIL_CONN_NOTEST" ] && \
#[ -z "$__NOTEST" ] && { # connection test
[ -z "$EMAIL_CONN_NOTEST" ] && { # connection test
connect_test || {
log "mail for [ $* ] : couldn't be sent - host not connected"
enqueue_mail "$@" # enqueue the mail
return
}
}
if $MSMTP "$@" < "${FQP}.mail" > /dev/null ; then # send mail using
queue .mail fil
log "mail for [ $* ] : send was successful" # log it
'rm' -f ${FQP}.* # remove all queue mail files .mail &
.msmtp file
run_queue 'sm' # run/flush any other mails in queue
else # send failed - the mail stays in the queue
log "mail for [ $* ] : send was unsuccessful ; msmtp exit code was $?"\
"enqueued mail as : [ $ID ] ( $* )" # (queue .mail file is already
there)
fi
}
#
## -- entry point
#
if [ ! "$1" = '--q-mgmt' ] ; then # msmtpq - sendmail mode
lock_queue # lock here
make_id # make base queue filename id for this mail
# write mail body text to queue .mail file
cat > "${FQP}.mail" || \
log -e "$?" "creating mail body file [ ${FQP}.mail ] : failed" # test for
error
# write msmtp command line to queue .msmtp file
echo "$@" > "${FQP}.msmtp" || \
log -e "$?" "creating msmtp cmd line file { $* }"\
" to [ ${ID}.msmtp ] : failed" # test for error
send_mail "$@" # send the mail if possible, queue it if
not
lock_queue -u # unlock here
else # msmtp-queue - queue management mode
shift # trim off first (--q-mgmt) arg
OP=${1:1} # trim off first char of OP arg
case "$OP" in # sort ops ; run according to spec
r) lock_queue
run_queue
lock_queue -u ;; # run (flush) the queue
R) select_mail send ;; # send individual mail(s) in queue
d|'') display_queue ;; # display (list) all mail in queue
(default)
p) select_mail purge ;; # purge individual mail(s) from queue
a) purge_queue ;; # purge all mail in queue
h) usage ;; # show help
*) usage "[ -$OP ] is an unknown msmtp-queue option" ;;
esac
fi
exit 0
------------------------------------------------------------------------------
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from
the latest Intel processors and coprocessors. See abstracts and register >
http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk
_______________________________________________
msmtp-users mailing list
msmtp-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/msmtp-users