#!/usr/bin/python
"""SMTP/ESMTP client class.

Author: The Dragon De Monsyne <dragondm@integral.org>
ESMTP support, test code and doc fixes added by
    Eric S. Raymond <esr@thyrsus.com>
Better RFC 821 compliance (MAIL and RCPT, and CRLF in data)
    by Carey Evans <c.evans@clear.net.nz>, for picky mail servers.
   
(This was modified from the Python 1.5 library HTTP lib.)

This should follow RFC 821 (SMTP) and RFC 1869 (ESMTP).

Notes:

Please remember, when doing ESMTP, that the names of the SMTP service
extensions are NOT the same thing as the option keyords for the RCPT
and MAIL commands!

Example:

>>> import smtplib
>>> s=smtplib.SMTP("localhost")
>>> print s.help()
This is Sendmail version 8.8.4
Topics:
    HELO    EHLO    MAIL    RCPT    DATA
    RSET    NOOP    QUIT    HELP    VRFY
    EXPN    VERB    ETRN    DSN
For more info use "HELP <topic>".
To report bugs in the implementation send email to
    sendmail-bugs@sendmail.org.
For local information send email to Postmaster at your site.
End of HELP info
>>> s.putcmd("vrfy","someone@here")
>>> s.getreply()
(250, "Somebody OverHere <somebody@here.my.org>")
>>> s.quit()

"""

import socket
import string, re
import rfc822

SMTP_PORT = 25
CRLF="\r\n"

# used for exceptions 
SMTPServerDisconnected="Server not connected"
SMTPSenderRefused="Sender address refused"
SMTPRecipientsRefused="All Recipients refused"
SMTPDataError="Error transmitting message data"

def quoteaddr(addr):
    """Quote a subset of the email addresses defined by RFC 821.

    Should be able to handle anything rfc822.parseaddr can handle."""

    m=None
    try:
        m=rfc822.parseaddr(addr)[1]
    except AttributeError:
        pass
    if not m:
        #something weird here.. punt -ddm
        return addr
    else:
        return "<%s>" % m

def quotedata(data):
    """Quote data for email.

    Double leading '.', and change Unix newline '\n', or Mac '\r' into
    Internet CRLF end-of-line."""
    return re.sub(r'(?m)^\.', '..',
        re.sub(r'(?:\r\n|\n|\r(?!\n))', CRLF, data))

class SMTP:
    """This class manages a connection to an SMTP or ESMTP server.
    SMTP Objects:
        SMTP objects have the following attributes:    
            helo_resp 
                This is the message given by the server in responce to the 
                most recent HELO command.
                
            ehlo_resp
                This is the message given by the server in responce to the 
                most recent EHLO command. This is usually multiline.

            does_esmtp 
                This is a True value _after you do an EHLO command_, if the
                server supports ESMTP.

            esmtp_features 
                This is a dictionary, which, if the server supports ESMTP,
                will  _after you do an EHLO command_, contain the names of the
                SMTP service  extentions this server supports, and their 
                parameters (if any).
                Note, all extention names are mapped to lower case in the 
                dictionary. 

        For method docs, see each method's docstrings. In general, there is 
            a method of the same name to preform each SMTP comand, and there 
            is a method called 'sendmail' that will do an entiere mail 
            transaction."""

    debuglevel = 0
    file = None
    helo_resp = None
    ehlo_resp = None
    does_esmtp = 0

    def __init__(self, host = '', port = 0):
        """Initialize a new instance.

        If specified, `host' is the name of the remote host to which
        to connect.  If specified, `port' specifies the port to which
        to connect.  By default, smtplib.SMTP_PORT is used.

        """
        self.esmtp_features = {}
        if host: self.connect(host, port)
    
    def set_debuglevel(self, debuglevel):
        """Set the debug output level.

        A non-false value results in debug messages for connection and
        for all messages sent to and received from the server.

        """
        self.debuglevel = debuglevel

    def connect(self, host='localhost', port = 0):
        """Connect to a host on a given port.

        If the hostname ends with a colon (`:') followed by a number,
        and there is no port specified,  that suffix will be stripped 
        off and the number interpreted as the port number to use.

        Note:  This method is automatically invoked by __init__,
        if a host is specified during instantiation.

        """
        if not port:
            i = string.find(host, ':')
            if i >= 0:
                host, port = host[:i], host[i+1:]
                try: port = string.atoi(port)
                except string.atoi_error:
                    raise socket.error, "nonnumeric port"
        if not port: port = SMTP_PORT
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        if self.debuglevel > 0: print 'connect:', (host, port)
        self.sock.connect(host, port)
        (code,msg)=self.getreply()
        if self.debuglevel >0 : print "connect:", msg
        return msg
    
    def send(self, str):
        """Send `str' to the server."""
        if self.debuglevel > 0: print 'send:', `str`
        if self.sock:
            try:
                self.sock.send(str)
            except socket.error:
                raise SMTPServerDisconnected
        else:
            raise SMTPServerDisconnected
 
    def putcmd(self, cmd, args=""):
        """Send a command to the server.
        """
        str = '%s %s%s' % (cmd, args, CRLF)
        self.send(str)
    
    def getreply(self):
        """Get a reply from the server.
        
        Returns a tuple consisting of:
        - server response code (e.g. '250', or such, if all goes well)
          Note: returns -1 if it can't read response code.
        - server response string corresponding to response code
                (note : multiline responses converted to a single, 
                 multiline string)
        """
        resp=[]
        self.file = self.sock.makefile('rb')
        while 1:
            line = self.file.readline()
            if self.debuglevel > 0: print 'reply:', `line`
            resp.append(string.strip(line[4:]))
            code=line[:3]
            #check if multiline resp
            if line[3:4]!="-":
                break
        try:
            errcode = string.atoi(code)
        except(ValueError):
            errcode = -1

        errmsg = string.join(resp,"\n")
        if self.debuglevel > 0: 
            print 'reply: retcode (%s); Msg: %s' % (errcode,errmsg)
        return errcode, errmsg
    
    def docmd(self, cmd, args=""):
        """ Send a command, and return its response code """
        
        self.putcmd(cmd,args)
        (code,msg)=self.getreply()
        return code
# std smtp commands

    def helo(self, name=''):
        """ SMTP 'helo' command. Hostname to send for this command  
        defaults to the FQDN of the local host """
        name=string.strip(name)
        if len(name)==0:
                name=socket.gethostbyaddr(socket.gethostname())[0]
        self.putcmd("helo",name)
        (code,msg)=self.getreply()
        self.helo_resp=msg
        return code

    def ehlo(self, name=''):
        """ SMTP 'ehlo' command. Hostname to send for this command  
        defaults to the FQDN of the local host.  """
        name=string.strip(name)
        if len(name)==0:
                name=socket.gethostbyaddr(socket.gethostname())[0]
        self.putcmd("ehlo",name)
        (code,msg)=self.getreply()
        # According to RFC1869 some (badly written) 
        # MTA's will disconnect on an ehlo. Toss an exception if 
        # that happens -ddm
        if code == -1 and len(msg) == 0:
            raise SMTPServerDisconnected
        self.ehlo_resp=msg
        if code<>250:
            return code
        self.does_esmtp=1
        #parse the ehlo responce -ddm
        resp=string.split(self.ehlo_resp,'\n')
        del resp[0]
        for each in resp:
            m=re.match(r'(?P<feature>[A-Za-z0-9][A-Za-z0-9\-]*)',each)
            if m:
                feature=string.lower(m.group("feature"))
                params=string.strip(m.string[m.end("feature"):])
                self.esmtp_features[feature]=params
        return code

    def has_extn(self, opt):
        """Does the server support a given SMTP service extension?"""
        return self.esmtp_features.has_key(string.lower(opt))

    def help(self, args=''):
        """ SMTP 'help' command. Returns help text from server """
        self.putcmd("help", args)
        (code,msg)=self.getreply()
        return msg

    def rset(self):
        """ SMTP 'rset' command. Resets session. """
        code=self.docmd("rset")
        return code

    def noop(self):
        """ SMTP 'noop' command. Doesn't do anything :> """
        code=self.docmd("noop")
        return code

    def mail(self,sender,options=[]):
        """ SMTP 'mail' command. Begins mail xfer session. """
        optionlist = ''
        if options and self.does_esmtp:
            optionlist = string.join(options, ' ')
        self.putcmd("mail", "FROM:%s %s" % (quoteaddr(sender) ,optionlist))
        return self.getreply()

    def rcpt(self,recip,options=[]):
        """ SMTP 'rcpt' command. Indicates 1 recipient for this mail. """
        optionlist = ''
        if options and self.does_esmtp:
            optionlist = string.join(options, ' ')
        self.putcmd("rcpt","TO:%s %s" % (quoteaddr(recip),optionlist))
        return self.getreply()

    def data(self,msg):
        """ SMTP 'DATA' command. Sends message data to server. 
            Automatically quotes lines beginning with a period per rfc821. """
        self.putcmd("data")
        (code,repl)=self.getreply()
        if self.debuglevel >0 : print "data:", (code,repl)
        if code <> 354:
            return -1
        else:
            self.send(quotedata(msg))
            self.send("%s.%s" % (CRLF, CRLF))
            (code,msg)=self.getreply()
            if self.debuglevel >0 : print "data:", (code,msg)
            return code

    def vrfy(self, address):
        return self.verify(address)

    def verify(self, address):
        """ SMTP 'verify' command. Checks for address validity. """
        self.putcmd("vrfy", quoteaddr(address))
        return self.getreply()

    def expn(self, address):
        """ SMTP 'verify' command. Checks for address validity. """
        self.putcmd("expn", quoteaddr(address))
        return self.getreply()


#some useful methods
    def sendmail(self,from_addr,to_addrs,msg,mail_options=[],rcpt_options=[]):
        """ This command performs an entire mail transaction. 
            The arguments are: 
               - from_addr : The address sending this mail.
               - to_addrs :  a list of addresses to send this mail to
               - msg : the message to send. 
               - mail_options : list of ESMTP options (such as 8bitmime)
                                for the mail command
               - rcpt_options : List of ESMTP options (such as DSN commands)
                               for all the rcpt commands
        If there has been no previous EHLO or HELO command this session,
        this method tries ESMTP EHLO first. If the server does ESMTP, message
        size and each of the specified options will be passed to it.  
        If EHLO fails, HELO will be tried and ESMTP options suppressed.

        This method will return normally if the mail is accepted for at least 
        one recipient. Otherwise it will throw an exception (either
        SMTPSenderRefused, SMTPRecipientsRefused, or SMTPDataError)
        That is, if this method does not throw an exception, then someone 
        should get your mail.  If this method does not throw an exception,
        it returns a dictionary, with one entry for each recipient that was 
        refused. 

        Example:
      
         >>> import smtplib
         >>> s=smtplib.SMTP("localhost")
         >>> tolist=["one@one.org","two@two.org","three@three.org","four@four.org"]
         >>> msg = '''
         ... From: Me@my.org
         ... Subject: testin'...
         ...
         ... This is a test '''
         >>> s.sendmail("me@my.org",tolist,msg)
         { "three@three.org" : ( 550 ,"User unknown" ) }
         >>> s.quit()
        
         In the above example, the message was accepted for delivery to 
         three of the four addresses, and one was rejected, with the error
         code 550. If all addresses are accepted, then the method
         will return an empty dictionary.  
         """
        if not self.helo_resp and not self.ehlo_resp:
            if self.ehlo() >= 400:
                self.helo()
        esmtp_opts = []
        if self.does_esmtp:
            # Hmmm? what's this? -ddm
            # self.esmtp_features['7bit']=""
            if self.has_extn('size'):
                esmtp_opts.append("size=" + `len(msg)`)
            for option in mail_options:
                esmtp_opts.append(option)

        (code,resp) = self.mail(from_addr, esmtp_opts)
        if code <> 250:
            self.rset()
            raise SMTPSenderRefused
        senderrs={}
        for each in to_addrs:
            (code,resp)=self.rcpt(each, rcpt_options)
            if (code <> 250) and (code <> 251):
                senderrs[each]=(code,resp)
        if len(senderrs)==len(to_addrs):
            # the server refused all our recipients
            self.rset()
            raise SMTPRecipientsRefused
        code=self.data(msg)
        if code <>250 :
            self.rset()
            raise SMTPDataError
        #if we got here then somebody got our mail
        return senderrs         


    def close(self):
        """Close the connection to the SMTP server."""
        if self.file:
            self.file.close()
        self.file = None
        if self.sock:
            self.sock.close()
        self.sock = None


    def quit(self):
        """Terminate the SMTP session."""
        self.docmd("quit")
        self.close()

# Test the sendmail method, which tests most of the others.
# Note: This always sends to localhost.
if __name__ == '__main__':
    import sys, rfc822

    def prompt(prompt):
        sys.stdout.write(prompt + ": ")
        return string.strip(sys.stdin.readline())

    fromaddr = prompt("From")
    toaddrs  = string.splitfields(prompt("To"), ',')
    print "Enter message, end with ^D:"
    msg = ''
    while 1:
        line = sys.stdin.readline()
        if not line:
            break
        msg = msg + line
    print "Message length is " + `len(msg)`

    server = SMTP('localhost')
    server.set_debuglevel(1)
    server.sendmail(fromaddr, toaddrs, msg)
    server.quit()
