hi everyone

however they didn't work for me!
strangely they added every mail to the queue directory...

and i got this output all over my logfiles when sending through msmtpQ
(symlinked to sendmail):
--------------------
/usr/sbin/sendmail: 39: declare: not found
[: 170: Illegal number: ==
local: 184: -i: bad variable name
PING 64.233.183.147 (64.233.183.147) 56(84) bytes of data.

--- 64.233.183.147 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 35.872/35.872/35.872/0.000 ms
[: 184: ==: unexpected operator
[: 184: ==: unexpected operator
local: 184: -i: bad variable name
[: 184: ==: unexpected operator
[: 184: -e: unexpected operator
--------------------
this might be specific because i am using the script with the version
shipped with ubuntu 8.04 LTS...
thanks for writing the msmtpq scripts anyway :-)

since i have no clue of shell scripting i was unable to fix this
script and because i need one to work now with the msmtp version
shipped with ubuntu 8.04 i wrote a new one in python that works almost
in the same way as the shell scripts included in mstmp. mostly i
combined everything into one script and when unable to send a mail it
automatically forks of as a daemon, trying to flush the queue each
minute. when the queue is empty the daemon will quit (which is very
nice if you have network outages of a few minutes once a week). like
the included scripts it determines a live internet connection through
pinging google, although i've changed it to pinging smtp.google.com...
well anyway i just thought it might be useful to someone.

claude nobs
-------------------
#!/usr/bin/env python
# -*- coding: utf8 -*-

"""
msmtp-queue <http:/mq.blunet.cc/>

Copyright (C) 2008  Claude Nobs

Based on scripts from Martin Lambers & 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 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

For more details, see http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
"""

import sys, os, time, pwd, signal, re
        
def _usage() :
        print "Usage: %s [COMMAND]|[MSMTP-ARGS]" % sys.argv[0]
        print "\nCommands:"
        print "   --version   show version number"
        print "   --help      show this help message"
        print "   daemon      run the queue daemon"
        print "   display     display (list) queue state"
        print "   remove      remove a single mail from the queue"
        print "   purge       purge all mail from the queue"
        print "\nNote that only one command is allowed! msmtpq does not use
the -h option in\norder to be transparent to msmtp/sendmail."
        print "\nIf you want to send an email just work as you would with
msmtp (don't specify\nany of the above commands), but note that if
there is no internet connection\nany mstmp command gets enqueued (even
wrong ones)!"
        print "\nIf you want to do anything else than sending a mail, use
msmtp/sendmail directly!"
        print "\nNOTE: You should add 'msmtpq daemon' to /etc/rc.local (or by
other means\nconfigure your system to run the msmtpq daemon on
startup) in case there is mail\nin the queue and the system crashes/is
rebooted."

def log(string) :
        sys.stdout.write(time.strftime("%Y-%m-%d--%H-%M",time.localtime()) +
'  ' + string + '\n')
        sys.stdout.flush()

def enqueue_mail(mail) :
        queueitem = 
os.path.join(queuedir,time.strftime("%Y-%m-%d--%H-%M-%S",time.localtime()))
        if os.path.exists(queueitem) :
                f = open(logpath,"a+")
                f.write("ERROR : queue item %s already exists! appending mail
here:\n%s\n%s\n" % (queueitem,sys.argv,mail))
                f.close()
                sys.exit(os.EX_IOERR)
        else :
                try:
                        f = open(queueitem,'w')
                        f.write(" ".join(sys.argv)+"\n")
                        f.write(mail)
                        f.close()
                        print "SUCCESS : queued mail as %s" % queueitem
                        # get to be server if it isn't already running # FIXME
                        if not already_running(title) : # this is nearly save 
because
daemons last action is to evaluate listdir > 0
                                daemon()                                   # we 
might wait a second before looking if daemon
is there to make it really safe
                except (IOError,os.error), e :
                        f = open(logpath,"a+")
                        f.write("ERROR : failed to queue item %s! appending mail
here:\n%s\n%s\n" % (queueitem,sys.argv,mail))
                        f.close()
                        
#######################################################################
COMMON LIBRARY FUNCTIONS ###

def set_process_title(title):
        import ctypes
        libc = ctypes.CDLL('libc.so.6')
        libc.prctl(15,title,0,0,0)
        # FreeBSD : libc.setproctitle('rsyncbackup')

def already_running(title,uid=None,gid=None):
        """
        check if the process with the given title already exists.
        if it does, return a tuple of [[PID,UID,GID,CMD]...]
        else return []
        on error return False
        """
        import os, subprocess
        try :
                p = 
subprocess.Popen(['ps','-C',title,'--no-headers','-o',",".join(['pid','uid','gid','cmd'])],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
                output = [each.split(None,3) for each in 
p.stdout.read().strip().split("\n")]
                if p.wait() != 0:
                        if output != [[]]:
                                print "WARNING : ps execution returned 
unexpected result! : %s" %
str(output)
                                return False
                        return []
                else:
                        if uid != None :
                                return [each for each in output if int(each[1]) 
== uid]
                        elif gid != None :
                                return [each for each in output if int(each[2]) 
== uid]
                        else :
                                return output
        except OSError, e :
                print "ERROR : could not execute ps! ",e
                return False

def daemonize (stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
    '''
    This forks the current process into a daemon.
    The stdin, stdout, and stderr arguments are file names that
    will be opened and be used to replace the standard file descriptors
    in sys.stdin, sys.stdout, and sys.stderr.
    These arguments are optional and default to /dev/null.
    Note that stderr is opened unbuffered, so
    if it shares a file with stdout then interleaved output
    may not appear in the order that you expect.
    '''

    # Do first fork.
    try:
        pid = os.fork()
        if pid > 0:
            sys.exit(0)   # Exit first parent.
    except OSError, e:
        sys.stderr.write ("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror) )
        sys.exit(1)

    # Decouple from parent environment.
    os.chdir("/")
    os.umask(0)
    os.setsid()

    # Do second fork.
    try:
        pid = os.fork()
        if pid > 0:
            sys.exit(0)   # Exit second parent.
    except OSError, e:
        sys.stderr.write ("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror) )
        sys.exit(1)

    # Now I am a daemon!

    # Redirect standard file descriptors.
    si = open(stdin, 'r')
    so = open(stdout, 'a+')
    se = open(stderr, 'a+', 0)
    os.dup2(si.fileno(), sys.stdin.fileno())
    os.dup2(so.fileno(), sys.stdout.fileno())
    os.dup2(se.fileno(), sys.stderr.fileno())

#################################################################################
MODE FUNCTIONS ###

def version() :
        print "%s v.1.0 beta" % sys.argv[0]
        sys.exit(os.EX_OK)

def usage() :
        _usage()
        sys.exit(os.EX_OK)

def daemon() :
        set_process_title(title)
        daemonize('/dev/null',logpath,logpath)
        log('%s started as a Daemon with pid %d' % (__file__, os.getpid()))

        while len(os.listdir(queuedir)) > 0 :
                time.sleep(60)
                ping = os.popen('ping -qnc 1 209.85.135.111') #we use 
mx.google.com
but you could use just google.com : 64.233.183.147
                if ping.close() == None :
                        # notify sysadmin that there was an outage
                        try:
                                p = os.popen('msmtp %s' % sysemail,'w')
                                p.write("Subject: NOTE : there was an email 
outage!")
                                p.close()
                        except :
                                log("ERROR : could not inform sysadmin of 
outage!")
                        # process the queue
                        for each in os.listdir(queuedir) :
                                try :
                                        f = 
open(os.path.join(queuedir,each),'r')
                                        p = os.popen(f.readline().strip(),'w')
                                        p.write(f.read())
                                        f.close()
                                        if p.close() :
                                                log("ERROR : could not send %s 
from queue." % each)
                                        else :
                                                log("SUCCESS : sent %s from 
queue." % each)
                                        try :
                                                
os.remove(os.path.join(queuedir,each))
                                        except (IOError,os.error), e :
                                                        log("ERROR : could not 
remove %s from queue." % each)
                                except (IOError,os.error), e :
                                                log("ERROR : could not send %s 
from queue." % each)

def display() :
        if len(os.listdir(queuedir)) > 0 :
                for each in os.listdir(queuedir) :
                        try :
                                f = open (os.path.join(queuedir,each),'r')
                                info = 
re.findall('^(msmtp(\s+-[^\s])|To:|Cc:|Bcc:)([EMAIL 
PROTECTED])+\s*$|^Subject:(.+)$',f.read(),
re.I | re.M)
                                f.close()
                                print "%s   %s | %s" % (each," ".join([ 
i[2].strip() for i in info
if i[0] != '' ])," ".join([ i[3].strip() for i in info if i[0] == ''
]))
                        except (IOError,os.error), e :
                                        print "ERROR : could not open %s!" % 
each
                if not already_running(title) :
                        print "msmtpq daemon was not running! spawning daemon 
now..."
                        daemon()
        else :
                print "queue is empty"

def remove() :
        if len(sys.argv) < 3 :
                print "you must specify an item to remove! item id is of format 
:
%Y-%m-%d--%H-%M-%S"
                sys.exit(os.EX_USAGE)
        if len(os.listdir(queuedir)) > 0 :
                if os.path.isfile(os.path.join(queuedir,sys.argv[2])) :
                        try:
                                os.remove(os.path.join(queuedir,sys.argv[2]))
                                print "removed %s from queue." % sys.argv[2]
                        except (IOError,os.error), e :
                                        print "ERROR : could not remove %s!" % 
sys.argv[2]
                else :
                        print "ERROR : %s is not in queue!" % sys.argv[2]
        else :
                print "ERROR : queue is empty"

def purge() :
        if raw_input("Will delete all mails in queue! Type 'yes' to confirm:
") == 'yes' :
                if len(os.listdir(queuedir)) > 0 :
                        for each in os.listdir(queuedir) :
                                try:
                                        os.remove(os.path.join(queuedir,each))
                                        print "removed %s from queue." % each
                                except (IOError,os.error), e :
                                                print "ERROR : could not remove 
%s!" % each
                else :
                        print "ERROR : queue is empty"
        else :
                print "leaving queue untouched..."

def send_mail(mail='') :
        while True:
                s = sys.stdin.read(1)
                mail += s
                if not s:
                        break
        
        ping = os.popen('ping -qnc 1 209.85.135.111') #we use mx.google.com
but you could use just google.com : 64.233.183.147
        if ping.close() == None :
                try :
                        p = os.popen(" ".join(sys.argv),'w')
                except (IOError,os.error), e :
                        print "WARNING : error executing '%s'! trying to 
enqueue mail..." %
" ".join(sys.argv)
                        enqueue_mail(mail)
                        
                p.write(mail)
                if p.close() :
                        print "WARNING : sending email was unsuccessful! trying 
to enqueue mail..."
                        enqueue_mail(mail)
        else :
                print "WARNING : no route to the internet! trying to enqueue 
mail..."
                enqueue_mail(mail)

###########################################################################################
MAIN ###

if __name__ == "__main__":
        """
        set global variables
        parse commandline
        select mode function
        """
        # set global variables
        title = 'msmtpq'
        sys.argv[0] = 'msmtp' # so we can use sys.argv as if the user had
called msmtp directly
        logpath  = os.path.join(os.path.expanduser('/var/log/'),'msmtpq.log')
        queuedir = os.path.join(os.path.expanduser('/var/tmp/'),'msmtp.queue')
        sysemail = '[EMAIL PROTECTED]'
        
        # msmtp and we need at least one argument
        if len(sys.argv) < 2 :
                usage()
                sys.exit(os.EX_USAGE)
                
        # these commands must work even if the queue is missing
        if sys.argv[1] =='--version':
                version()
        if sys.argv[1] =='--help' :
                usage()
                
        # check if queue dir exists (or can be created)
        if not os.path.isdir(queuedir) :
                try :
                        os.makedirs(queuedir)
                except (IOError,os.error), e :
                        print "ERROR : can't create queue dir : %s" % queuedir
                        sys.exit(os.EX_IOERR)
        elif not os.access(queuedir,os.W_OK) :
                print "ERROR : can't write to queue dir : %s" % queuedir
                sys.exit(os.EX_IOERR)
                
        # ready to run !
        if sys.argv[1] in ('daemon','display','remove','purge') :
                eval(sys.argv[1]+'()')
        else :
                send_mail()
                
        sys.exit(os.EX_OK)

-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08
_______________________________________________
msmtp-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/msmtp-users

Reply via email to