]> git.proxmox.com Git - mirror_edk2.git/blobdiff - AppPkg/Applications/Python/Python-2.7.2/Lib/smtplib.py
edk2: Remove AppPkg, StdLib, StdLibPrivateInternalFiles
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Lib / smtplib.py
diff --git a/AppPkg/Applications/Python/Python-2.7.2/Lib/smtplib.py b/AppPkg/Applications/Python/Python-2.7.2/Lib/smtplib.py
deleted file mode 100644 (file)
index 8d11964..0000000
+++ /dev/null
@@ -1,848 +0,0 @@
-#! /usr/bin/env python\r
-\r
-'''SMTP/ESMTP client class.\r
-\r
-This should follow RFC 821 (SMTP), RFC 1869 (ESMTP), RFC 2554 (SMTP\r
-Authentication) and RFC 2487 (Secure SMTP over TLS).\r
-\r
-Notes:\r
-\r
-Please remember, when doing ESMTP, that the names of the SMTP service\r
-extensions are NOT the same thing as the option keywords for the RCPT\r
-and MAIL commands!\r
-\r
-Example:\r
-\r
-  >>> import smtplib\r
-  >>> s=smtplib.SMTP("localhost")\r
-  >>> print s.help()\r
-  This is Sendmail version 8.8.4\r
-  Topics:\r
-      HELO    EHLO    MAIL    RCPT    DATA\r
-      RSET    NOOP    QUIT    HELP    VRFY\r
-      EXPN    VERB    ETRN    DSN\r
-  For more info use "HELP <topic>".\r
-  To report bugs in the implementation send email to\r
-      sendmail-bugs@sendmail.org.\r
-  For local information send email to Postmaster at your site.\r
-  End of HELP info\r
-  >>> s.putcmd("vrfy","someone@here")\r
-  >>> s.getreply()\r
-  (250, "Somebody OverHere <somebody@here.my.org>")\r
-  >>> s.quit()\r
-'''\r
-\r
-# Author: The Dragon De Monsyne <dragondm@integral.org>\r
-# ESMTP support, test code and doc fixes added by\r
-#     Eric S. Raymond <esr@thyrsus.com>\r
-# Better RFC 821 compliance (MAIL and RCPT, and CRLF in data)\r
-#     by Carey Evans <c.evans@clear.net.nz>, for picky mail servers.\r
-# RFC 2554 (authentication) support by Gerhard Haering <gerhard@bigfoot.de>.\r
-#\r
-# This was modified from the Python 1.5 library HTTP lib.\r
-\r
-import socket\r
-import re\r
-import email.utils\r
-import base64\r
-import hmac\r
-from email.base64mime import encode as encode_base64\r
-from sys import stderr\r
-\r
-__all__ = ["SMTPException", "SMTPServerDisconnected", "SMTPResponseException",\r
-           "SMTPSenderRefused", "SMTPRecipientsRefused", "SMTPDataError",\r
-           "SMTPConnectError", "SMTPHeloError", "SMTPAuthenticationError",\r
-           "quoteaddr", "quotedata", "SMTP"]\r
-\r
-SMTP_PORT = 25\r
-SMTP_SSL_PORT = 465\r
-CRLF = "\r\n"\r
-\r
-OLDSTYLE_AUTH = re.compile(r"auth=(.*)", re.I)\r
-\r
-\r
-# Exception classes used by this module.\r
-class SMTPException(Exception):\r
-    """Base class for all exceptions raised by this module."""\r
-\r
-class SMTPServerDisconnected(SMTPException):\r
-    """Not connected to any SMTP server.\r
-\r
-    This exception is raised when the server unexpectedly disconnects,\r
-    or when an attempt is made to use the SMTP instance before\r
-    connecting it to a server.\r
-    """\r
-\r
-class SMTPResponseException(SMTPException):\r
-    """Base class for all exceptions that include an SMTP error code.\r
-\r
-    These exceptions are generated in some instances when the SMTP\r
-    server returns an error code.  The error code is stored in the\r
-    `smtp_code' attribute of the error, and the `smtp_error' attribute\r
-    is set to the error message.\r
-    """\r
-\r
-    def __init__(self, code, msg):\r
-        self.smtp_code = code\r
-        self.smtp_error = msg\r
-        self.args = (code, msg)\r
-\r
-class SMTPSenderRefused(SMTPResponseException):\r
-    """Sender address refused.\r
-\r
-    In addition to the attributes set by on all SMTPResponseException\r
-    exceptions, this sets `sender' to the string that the SMTP refused.\r
-    """\r
-\r
-    def __init__(self, code, msg, sender):\r
-        self.smtp_code = code\r
-        self.smtp_error = msg\r
-        self.sender = sender\r
-        self.args = (code, msg, sender)\r
-\r
-class SMTPRecipientsRefused(SMTPException):\r
-    """All recipient addresses refused.\r
-\r
-    The errors for each recipient are accessible through the attribute\r
-    'recipients', which is a dictionary of exactly the same sort as\r
-    SMTP.sendmail() returns.\r
-    """\r
-\r
-    def __init__(self, recipients):\r
-        self.recipients = recipients\r
-        self.args = (recipients,)\r
-\r
-\r
-class SMTPDataError(SMTPResponseException):\r
-    """The SMTP server didn't accept the data."""\r
-\r
-class SMTPConnectError(SMTPResponseException):\r
-    """Error during connection establishment."""\r
-\r
-class SMTPHeloError(SMTPResponseException):\r
-    """The server refused our HELO reply."""\r
-\r
-class SMTPAuthenticationError(SMTPResponseException):\r
-    """Authentication error.\r
-\r
-    Most probably the server didn't accept the username/password\r
-    combination provided.\r
-    """\r
-\r
-\r
-def quoteaddr(addr):\r
-    """Quote a subset of the email addresses defined by RFC 821.\r
-\r
-    Should be able to handle anything rfc822.parseaddr can handle.\r
-    """\r
-    m = (None, None)\r
-    try:\r
-        m = email.utils.parseaddr(addr)[1]\r
-    except AttributeError:\r
-        pass\r
-    if m == (None, None):  # Indicates parse failure or AttributeError\r
-        # something weird here.. punt -ddm\r
-        return "<%s>" % addr\r
-    elif m is None:\r
-        # the sender wants an empty return address\r
-        return "<>"\r
-    else:\r
-        return "<%s>" % m\r
-\r
-def quotedata(data):\r
-    """Quote data for email.\r
-\r
-    Double leading '.', and change Unix newline '\\n', or Mac '\\r' into\r
-    Internet CRLF end-of-line.\r
-    """\r
-    return re.sub(r'(?m)^\.', '..',\r
-        re.sub(r'(?:\r\n|\n|\r(?!\n))', CRLF, data))\r
-\r
-\r
-try:\r
-    import ssl\r
-except ImportError:\r
-    _have_ssl = False\r
-else:\r
-    class SSLFakeFile:\r
-        """A fake file like object that really wraps a SSLObject.\r
-\r
-        It only supports what is needed in smtplib.\r
-        """\r
-        def __init__(self, sslobj):\r
-            self.sslobj = sslobj\r
-\r
-        def readline(self):\r
-            str = ""\r
-            chr = None\r
-            while chr != "\n":\r
-                chr = self.sslobj.read(1)\r
-                if not chr:\r
-                    break\r
-                str += chr\r
-            return str\r
-\r
-        def close(self):\r
-            pass\r
-\r
-    _have_ssl = True\r
-\r
-class SMTP:\r
-    """This class manages a connection to an SMTP or ESMTP server.\r
-    SMTP Objects:\r
-        SMTP objects have the following attributes:\r
-            helo_resp\r
-                This is the message given by the server in response to the\r
-                most recent HELO command.\r
-\r
-            ehlo_resp\r
-                This is the message given by the server in response to the\r
-                most recent EHLO command. This is usually multiline.\r
-\r
-            does_esmtp\r
-                This is a True value _after you do an EHLO command_, if the\r
-                server supports ESMTP.\r
-\r
-            esmtp_features\r
-                This is a dictionary, which, if the server supports ESMTP,\r
-                will _after you do an EHLO command_, contain the names of the\r
-                SMTP service extensions this server supports, and their\r
-                parameters (if any).\r
-\r
-                Note, all extension names are mapped to lower case in the\r
-                dictionary.\r
-\r
-        See each method's docstrings for details.  In general, there is a\r
-        method of the same name to perform each SMTP command.  There is also a\r
-        method called 'sendmail' that will do an entire mail transaction.\r
-        """\r
-    debuglevel = 0\r
-    file = None\r
-    helo_resp = None\r
-    ehlo_msg = "ehlo"\r
-    ehlo_resp = None\r
-    does_esmtp = 0\r
-    default_port = SMTP_PORT\r
-\r
-    def __init__(self, host='', port=0, local_hostname=None,\r
-                 timeout=socket._GLOBAL_DEFAULT_TIMEOUT):\r
-        """Initialize a new instance.\r
-\r
-        If specified, `host' is the name of the remote host to which to\r
-        connect.  If specified, `port' specifies the port to which to connect.\r
-        By default, smtplib.SMTP_PORT is used.  An SMTPConnectError is raised\r
-        if the specified `host' doesn't respond correctly.  If specified,\r
-        `local_hostname` is used as the FQDN of the local host.  By default,\r
-        the local hostname is found using socket.getfqdn().\r
-\r
-        """\r
-        self.timeout = timeout\r
-        self.esmtp_features = {}\r
-        if host:\r
-            (code, msg) = self.connect(host, port)\r
-            if code != 220:\r
-                raise SMTPConnectError(code, msg)\r
-        if local_hostname is not None:\r
-            self.local_hostname = local_hostname\r
-        else:\r
-            # RFC 2821 says we should use the fqdn in the EHLO/HELO verb, and\r
-            # if that can't be calculated, that we should use a domain literal\r
-            # instead (essentially an encoded IP address like [A.B.C.D]).\r
-            fqdn = socket.getfqdn()\r
-            if '.' in fqdn:\r
-                self.local_hostname = fqdn\r
-            else:\r
-                # We can't find an fqdn hostname, so use a domain literal\r
-                addr = '127.0.0.1'\r
-                try:\r
-                    addr = socket.gethostbyname(socket.gethostname())\r
-                except socket.gaierror:\r
-                    pass\r
-                self.local_hostname = '[%s]' % addr\r
-\r
-    def set_debuglevel(self, debuglevel):\r
-        """Set the debug output level.\r
-\r
-        A non-false value results in debug messages for connection and for all\r
-        messages sent to and received from the server.\r
-\r
-        """\r
-        self.debuglevel = debuglevel\r
-\r
-    def _get_socket(self, port, host, timeout):\r
-        # This makes it simpler for SMTP_SSL to use the SMTP connect code\r
-        # and just alter the socket connection bit.\r
-        if self.debuglevel > 0:\r
-            print>>stderr, 'connect:', (host, port)\r
-        return socket.create_connection((port, host), timeout)\r
-\r
-    def connect(self, host='localhost', port=0):\r
-        """Connect to a host on a given port.\r
-\r
-        If the hostname ends with a colon (`:') followed by a number, and\r
-        there is no port specified, that suffix will be stripped off and the\r
-        number interpreted as the port number to use.\r
-\r
-        Note: This method is automatically invoked by __init__, if a host is\r
-        specified during instantiation.\r
-\r
-        """\r
-        if not port and (host.find(':') == host.rfind(':')):\r
-            i = host.rfind(':')\r
-            if i >= 0:\r
-                host, port = host[:i], host[i + 1:]\r
-                try:\r
-                    port = int(port)\r
-                except ValueError:\r
-                    raise socket.error, "nonnumeric port"\r
-        if not port:\r
-            port = self.default_port\r
-        if self.debuglevel > 0:\r
-            print>>stderr, 'connect:', (host, port)\r
-        self.sock = self._get_socket(host, port, self.timeout)\r
-        (code, msg) = self.getreply()\r
-        if self.debuglevel > 0:\r
-            print>>stderr, "connect:", msg\r
-        return (code, msg)\r
-\r
-    def send(self, str):\r
-        """Send `str' to the server."""\r
-        if self.debuglevel > 0:\r
-            print>>stderr, 'send:', repr(str)\r
-        if hasattr(self, 'sock') and self.sock:\r
-            try:\r
-                self.sock.sendall(str)\r
-            except socket.error:\r
-                self.close()\r
-                raise SMTPServerDisconnected('Server not connected')\r
-        else:\r
-            raise SMTPServerDisconnected('please run connect() first')\r
-\r
-    def putcmd(self, cmd, args=""):\r
-        """Send a command to the server."""\r
-        if args == "":\r
-            str = '%s%s' % (cmd, CRLF)\r
-        else:\r
-            str = '%s %s%s' % (cmd, args, CRLF)\r
-        self.send(str)\r
-\r
-    def getreply(self):\r
-        """Get a reply from the server.\r
-\r
-        Returns a tuple consisting of:\r
-\r
-          - server response code (e.g. '250', or such, if all goes well)\r
-            Note: returns -1 if it can't read response code.\r
-\r
-          - server response string corresponding to response code (multiline\r
-            responses are converted to a single, multiline string).\r
-\r
-        Raises SMTPServerDisconnected if end-of-file is reached.\r
-        """\r
-        resp = []\r
-        if self.file is None:\r
-            self.file = self.sock.makefile('rb')\r
-        while 1:\r
-            try:\r
-                line = self.file.readline()\r
-            except socket.error:\r
-                line = ''\r
-            if line == '':\r
-                self.close()\r
-                raise SMTPServerDisconnected("Connection unexpectedly closed")\r
-            if self.debuglevel > 0:\r
-                print>>stderr, 'reply:', repr(line)\r
-            resp.append(line[4:].strip())\r
-            code = line[:3]\r
-            # Check that the error code is syntactically correct.\r
-            # Don't attempt to read a continuation line if it is broken.\r
-            try:\r
-                errcode = int(code)\r
-            except ValueError:\r
-                errcode = -1\r
-                break\r
-            # Check if multiline response.\r
-            if line[3:4] != "-":\r
-                break\r
-\r
-        errmsg = "\n".join(resp)\r
-        if self.debuglevel > 0:\r
-            print>>stderr, 'reply: retcode (%s); Msg: %s' % (errcode, errmsg)\r
-        return errcode, errmsg\r
-\r
-    def docmd(self, cmd, args=""):\r
-        """Send a command, and return its response code."""\r
-        self.putcmd(cmd, args)\r
-        return self.getreply()\r
-\r
-    # std smtp commands\r
-    def helo(self, name=''):\r
-        """SMTP 'helo' command.\r
-        Hostname to send for this command defaults to the FQDN of the local\r
-        host.\r
-        """\r
-        self.putcmd("helo", name or self.local_hostname)\r
-        (code, msg) = self.getreply()\r
-        self.helo_resp = msg\r
-        return (code, msg)\r
-\r
-    def ehlo(self, name=''):\r
-        """ SMTP 'ehlo' command.\r
-        Hostname to send for this command defaults to the FQDN of the local\r
-        host.\r
-        """\r
-        self.esmtp_features = {}\r
-        self.putcmd(self.ehlo_msg, name or self.local_hostname)\r
-        (code, msg) = self.getreply()\r
-        # According to RFC1869 some (badly written)\r
-        # MTA's will disconnect on an ehlo. Toss an exception if\r
-        # that happens -ddm\r
-        if code == -1 and len(msg) == 0:\r
-            self.close()\r
-            raise SMTPServerDisconnected("Server not connected")\r
-        self.ehlo_resp = msg\r
-        if code != 250:\r
-            return (code, msg)\r
-        self.does_esmtp = 1\r
-        #parse the ehlo response -ddm\r
-        resp = self.ehlo_resp.split('\n')\r
-        del resp[0]\r
-        for each in resp:\r
-            # To be able to communicate with as many SMTP servers as possible,\r
-            # we have to take the old-style auth advertisement into account,\r
-            # because:\r
-            # 1) Else our SMTP feature parser gets confused.\r
-            # 2) There are some servers that only advertise the auth methods we\r
-            #    support using the old style.\r
-            auth_match = OLDSTYLE_AUTH.match(each)\r
-            if auth_match:\r
-                # This doesn't remove duplicates, but that's no problem\r
-                self.esmtp_features["auth"] = self.esmtp_features.get("auth", "") \\r
-                        + " " + auth_match.groups(0)[0]\r
-                continue\r
-\r
-            # RFC 1869 requires a space between ehlo keyword and parameters.\r
-            # It's actually stricter, in that only spaces are allowed between\r
-            # parameters, but were not going to check for that here.  Note\r
-            # that the space isn't present if there are no parameters.\r
-            m = re.match(r'(?P<feature>[A-Za-z0-9][A-Za-z0-9\-]*) ?', each)\r
-            if m:\r
-                feature = m.group("feature").lower()\r
-                params = m.string[m.end("feature"):].strip()\r
-                if feature == "auth":\r
-                    self.esmtp_features[feature] = self.esmtp_features.get(feature, "") \\r
-                            + " " + params\r
-                else:\r
-                    self.esmtp_features[feature] = params\r
-        return (code, msg)\r
-\r
-    def has_extn(self, opt):\r
-        """Does the server support a given SMTP service extension?"""\r
-        return opt.lower() in self.esmtp_features\r
-\r
-    def help(self, args=''):\r
-        """SMTP 'help' command.\r
-        Returns help text from server."""\r
-        self.putcmd("help", args)\r
-        return self.getreply()[1]\r
-\r
-    def rset(self):\r
-        """SMTP 'rset' command -- resets session."""\r
-        return self.docmd("rset")\r
-\r
-    def noop(self):\r
-        """SMTP 'noop' command -- doesn't do anything :>"""\r
-        return self.docmd("noop")\r
-\r
-    def mail(self, sender, options=[]):\r
-        """SMTP 'mail' command -- begins mail xfer session."""\r
-        optionlist = ''\r
-        if options and self.does_esmtp:\r
-            optionlist = ' ' + ' '.join(options)\r
-        self.putcmd("mail", "FROM:%s%s" % (quoteaddr(sender), optionlist))\r
-        return self.getreply()\r
-\r
-    def rcpt(self, recip, options=[]):\r
-        """SMTP 'rcpt' command -- indicates 1 recipient for this mail."""\r
-        optionlist = ''\r
-        if options and self.does_esmtp:\r
-            optionlist = ' ' + ' '.join(options)\r
-        self.putcmd("rcpt", "TO:%s%s" % (quoteaddr(recip), optionlist))\r
-        return self.getreply()\r
-\r
-    def data(self, msg):\r
-        """SMTP 'DATA' command -- sends message data to server.\r
-\r
-        Automatically quotes lines beginning with a period per rfc821.\r
-        Raises SMTPDataError if there is an unexpected reply to the\r
-        DATA command; the return value from this method is the final\r
-        response code received when the all data is sent.\r
-        """\r
-        self.putcmd("data")\r
-        (code, repl) = self.getreply()\r
-        if self.debuglevel > 0:\r
-            print>>stderr, "data:", (code, repl)\r
-        if code != 354:\r
-            raise SMTPDataError(code, repl)\r
-        else:\r
-            q = quotedata(msg)\r
-            if q[-2:] != CRLF:\r
-                q = q + CRLF\r
-            q = q + "." + CRLF\r
-            self.send(q)\r
-            (code, msg) = self.getreply()\r
-            if self.debuglevel > 0:\r
-                print>>stderr, "data:", (code, msg)\r
-            return (code, msg)\r
-\r
-    def verify(self, address):\r
-        """SMTP 'verify' command -- checks for address validity."""\r
-        self.putcmd("vrfy", quoteaddr(address))\r
-        return self.getreply()\r
-    # a.k.a.\r
-    vrfy = verify\r
-\r
-    def expn(self, address):\r
-        """SMTP 'expn' command -- expands a mailing list."""\r
-        self.putcmd("expn", quoteaddr(address))\r
-        return self.getreply()\r
-\r
-    # some useful methods\r
-\r
-    def ehlo_or_helo_if_needed(self):\r
-        """Call self.ehlo() and/or self.helo() if needed.\r
-\r
-        If there has been no previous EHLO or HELO command this session, this\r
-        method tries ESMTP EHLO first.\r
-\r
-        This method may raise the following exceptions:\r
-\r
-         SMTPHeloError            The server didn't reply properly to\r
-                                  the helo greeting.\r
-        """\r
-        if self.helo_resp is None and self.ehlo_resp is None:\r
-            if not (200 <= self.ehlo()[0] <= 299):\r
-                (code, resp) = self.helo()\r
-                if not (200 <= code <= 299):\r
-                    raise SMTPHeloError(code, resp)\r
-\r
-    def login(self, user, password):\r
-        """Log in on an SMTP server that requires authentication.\r
-\r
-        The arguments are:\r
-            - user:     The user name to authenticate with.\r
-            - password: The password for the authentication.\r
-\r
-        If there has been no previous EHLO or HELO command this session, this\r
-        method tries ESMTP EHLO first.\r
-\r
-        This method will return normally if the authentication was successful.\r
-\r
-        This method may raise the following exceptions:\r
-\r
-         SMTPHeloError            The server didn't reply properly to\r
-                                  the helo greeting.\r
-         SMTPAuthenticationError  The server didn't accept the username/\r
-                                  password combination.\r
-         SMTPException            No suitable authentication method was\r
-                                  found.\r
-        """\r
-\r
-        def encode_cram_md5(challenge, user, password):\r
-            challenge = base64.decodestring(challenge)\r
-            response = user + " " + hmac.HMAC(password, challenge).hexdigest()\r
-            return encode_base64(response, eol="")\r
-\r
-        def encode_plain(user, password):\r
-            return encode_base64("\0%s\0%s" % (user, password), eol="")\r
-\r
-\r
-        AUTH_PLAIN = "PLAIN"\r
-        AUTH_CRAM_MD5 = "CRAM-MD5"\r
-        AUTH_LOGIN = "LOGIN"\r
-\r
-        self.ehlo_or_helo_if_needed()\r
-\r
-        if not self.has_extn("auth"):\r
-            raise SMTPException("SMTP AUTH extension not supported by server.")\r
-\r
-        # Authentication methods the server supports:\r
-        authlist = self.esmtp_features["auth"].split()\r
-\r
-        # List of authentication methods we support: from preferred to\r
-        # less preferred methods. Except for the purpose of testing the weaker\r
-        # ones, we prefer stronger methods like CRAM-MD5:\r
-        preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]\r
-\r
-        # Determine the authentication method we'll use\r
-        authmethod = None\r
-        for method in preferred_auths:\r
-            if method in authlist:\r
-                authmethod = method\r
-                break\r
-\r
-        if authmethod == AUTH_CRAM_MD5:\r
-            (code, resp) = self.docmd("AUTH", AUTH_CRAM_MD5)\r
-            if code == 503:\r
-                # 503 == 'Error: already authenticated'\r
-                return (code, resp)\r
-            (code, resp) = self.docmd(encode_cram_md5(resp, user, password))\r
-        elif authmethod == AUTH_PLAIN:\r
-            (code, resp) = self.docmd("AUTH",\r
-                AUTH_PLAIN + " " + encode_plain(user, password))\r
-        elif authmethod == AUTH_LOGIN:\r
-            (code, resp) = self.docmd("AUTH",\r
-                "%s %s" % (AUTH_LOGIN, encode_base64(user, eol="")))\r
-            if code != 334:\r
-                raise SMTPAuthenticationError(code, resp)\r
-            (code, resp) = self.docmd(encode_base64(password, eol=""))\r
-        elif authmethod is None:\r
-            raise SMTPException("No suitable authentication method found.")\r
-        if code not in (235, 503):\r
-            # 235 == 'Authentication successful'\r
-            # 503 == 'Error: already authenticated'\r
-            raise SMTPAuthenticationError(code, resp)\r
-        return (code, resp)\r
-\r
-    def starttls(self, keyfile=None, certfile=None):\r
-        """Puts the connection to the SMTP server into TLS mode.\r
-\r
-        If there has been no previous EHLO or HELO command this session, this\r
-        method tries ESMTP EHLO first.\r
-\r
-        If the server supports TLS, this will encrypt the rest of the SMTP\r
-        session. If you provide the keyfile and certfile parameters,\r
-        the identity of the SMTP server and client can be checked. This,\r
-        however, depends on whether the socket module really checks the\r
-        certificates.\r
-\r
-        This method may raise the following exceptions:\r
-\r
-         SMTPHeloError            The server didn't reply properly to\r
-                                  the helo greeting.\r
-        """\r
-        self.ehlo_or_helo_if_needed()\r
-        if not self.has_extn("starttls"):\r
-            raise SMTPException("STARTTLS extension not supported by server.")\r
-        (resp, reply) = self.docmd("STARTTLS")\r
-        if resp == 220:\r
-            if not _have_ssl:\r
-                raise RuntimeError("No SSL support included in this Python")\r
-            self.sock = ssl.wrap_socket(self.sock, keyfile, certfile)\r
-            self.file = SSLFakeFile(self.sock)\r
-            # RFC 3207:\r
-            # The client MUST discard any knowledge obtained from\r
-            # the server, such as the list of SMTP service extensions,\r
-            # which was not obtained from the TLS negotiation itself.\r
-            self.helo_resp = None\r
-            self.ehlo_resp = None\r
-            self.esmtp_features = {}\r
-            self.does_esmtp = 0\r
-        return (resp, reply)\r
-\r
-    def sendmail(self, from_addr, to_addrs, msg, mail_options=[],\r
-                 rcpt_options=[]):\r
-        """This command performs an entire mail transaction.\r
-\r
-        The arguments are:\r
-            - from_addr    : The address sending this mail.\r
-            - to_addrs     : A list of addresses to send this mail to.  A bare\r
-                             string will be treated as a list with 1 address.\r
-            - msg          : The message to send.\r
-            - mail_options : List of ESMTP options (such as 8bitmime) for the\r
-                             mail command.\r
-            - rcpt_options : List of ESMTP options (such as DSN commands) for\r
-                             all the rcpt commands.\r
-\r
-        If there has been no previous EHLO or HELO command this session, this\r
-        method tries ESMTP EHLO first.  If the server does ESMTP, message size\r
-        and each of the specified options will be passed to it.  If EHLO\r
-        fails, HELO will be tried and ESMTP options suppressed.\r
-\r
-        This method will return normally if the mail is accepted for at least\r
-        one recipient.  It returns a dictionary, with one entry for each\r
-        recipient that was refused.  Each entry contains a tuple of the SMTP\r
-        error code and the accompanying error message sent by the server.\r
-\r
-        This method may raise the following exceptions:\r
-\r
-         SMTPHeloError          The server didn't reply properly to\r
-                                the helo greeting.\r
-         SMTPRecipientsRefused  The server rejected ALL recipients\r
-                                (no mail was sent).\r
-         SMTPSenderRefused      The server didn't accept the from_addr.\r
-         SMTPDataError          The server replied with an unexpected\r
-                                error code (other than a refusal of\r
-                                a recipient).\r
-\r
-        Note: the connection will be open even after an exception is raised.\r
-\r
-        Example:\r
-\r
-         >>> import smtplib\r
-         >>> s=smtplib.SMTP("localhost")\r
-         >>> tolist=["one@one.org","two@two.org","three@three.org","four@four.org"]\r
-         >>> msg = '''\\\r
-         ... From: Me@my.org\r
-         ... Subject: testin'...\r
-         ...\r
-         ... This is a test '''\r
-         >>> s.sendmail("me@my.org",tolist,msg)\r
-         { "three@three.org" : ( 550 ,"User unknown" ) }\r
-         >>> s.quit()\r
-\r
-        In the above example, the message was accepted for delivery to three\r
-        of the four addresses, and one was rejected, with the error code\r
-        550.  If all addresses are accepted, then the method will return an\r
-        empty dictionary.\r
-\r
-        """\r
-        self.ehlo_or_helo_if_needed()\r
-        esmtp_opts = []\r
-        if self.does_esmtp:\r
-            # Hmmm? what's this? -ddm\r
-            # self.esmtp_features['7bit']=""\r
-            if self.has_extn('size'):\r
-                esmtp_opts.append("size=%d" % len(msg))\r
-            for option in mail_options:\r
-                esmtp_opts.append(option)\r
-\r
-        (code, resp) = self.mail(from_addr, esmtp_opts)\r
-        if code != 250:\r
-            self.rset()\r
-            raise SMTPSenderRefused(code, resp, from_addr)\r
-        senderrs = {}\r
-        if isinstance(to_addrs, basestring):\r
-            to_addrs = [to_addrs]\r
-        for each in to_addrs:\r
-            (code, resp) = self.rcpt(each, rcpt_options)\r
-            if (code != 250) and (code != 251):\r
-                senderrs[each] = (code, resp)\r
-        if len(senderrs) == len(to_addrs):\r
-            # the server refused all our recipients\r
-            self.rset()\r
-            raise SMTPRecipientsRefused(senderrs)\r
-        (code, resp) = self.data(msg)\r
-        if code != 250:\r
-            self.rset()\r
-            raise SMTPDataError(code, resp)\r
-        #if we got here then somebody got our mail\r
-        return senderrs\r
-\r
-\r
-    def close(self):\r
-        """Close the connection to the SMTP server."""\r
-        if self.file:\r
-            self.file.close()\r
-        self.file = None\r
-        if self.sock:\r
-            self.sock.close()\r
-        self.sock = None\r
-\r
-\r
-    def quit(self):\r
-        """Terminate the SMTP session."""\r
-        res = self.docmd("quit")\r
-        self.close()\r
-        return res\r
-\r
-if _have_ssl:\r
-\r
-    class SMTP_SSL(SMTP):\r
-        """ This is a subclass derived from SMTP that connects over an SSL encrypted\r
-        socket (to use this class you need a socket module that was compiled with SSL\r
-        support). If host is not specified, '' (the local host) is used. If port is\r
-        omitted, the standard SMTP-over-SSL port (465) is used. keyfile and certfile\r
-        are also optional - they can contain a PEM formatted private key and\r
-        certificate chain file for the SSL connection.\r
-        """\r
-\r
-        default_port = SMTP_SSL_PORT\r
-\r
-        def __init__(self, host='', port=0, local_hostname=None,\r
-                     keyfile=None, certfile=None,\r
-                     timeout=socket._GLOBAL_DEFAULT_TIMEOUT):\r
-            self.keyfile = keyfile\r
-            self.certfile = certfile\r
-            SMTP.__init__(self, host, port, local_hostname, timeout)\r
-\r
-        def _get_socket(self, host, port, timeout):\r
-            if self.debuglevel > 0:\r
-                print>>stderr, 'connect:', (host, port)\r
-            new_socket = socket.create_connection((host, port), timeout)\r
-            new_socket = ssl.wrap_socket(new_socket, self.keyfile, self.certfile)\r
-            self.file = SSLFakeFile(new_socket)\r
-            return new_socket\r
-\r
-    __all__.append("SMTP_SSL")\r
-\r
-#\r
-# LMTP extension\r
-#\r
-LMTP_PORT = 2003\r
-\r
-class LMTP(SMTP):\r
-    """LMTP - Local Mail Transfer Protocol\r
-\r
-    The LMTP protocol, which is very similar to ESMTP, is heavily based\r
-    on the standard SMTP client. It's common to use Unix sockets for LMTP,\r
-    so our connect() method must support that as well as a regular\r
-    host:port server. To specify a Unix socket, you must use an absolute\r
-    path as the host, starting with a '/'.\r
-\r
-    Authentication is supported, using the regular SMTP mechanism. When\r
-    using a Unix socket, LMTP generally don't support or require any\r
-    authentication, but your mileage might vary."""\r
-\r
-    ehlo_msg = "lhlo"\r
-\r
-    def __init__(self, host='', port=LMTP_PORT, local_hostname=None):\r
-        """Initialize a new instance."""\r
-        SMTP.__init__(self, host, port, local_hostname)\r
-\r
-    def connect(self, host='localhost', port=0):\r
-        """Connect to the LMTP daemon, on either a Unix or a TCP socket."""\r
-        if host[0] != '/':\r
-            return SMTP.connect(self, host, port)\r
-\r
-        # Handle Unix-domain sockets.\r
-        try:\r
-            self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)\r
-            self.sock.connect(host)\r
-        except socket.error, msg:\r
-            if self.debuglevel > 0:\r
-                print>>stderr, 'connect fail:', host\r
-            if self.sock:\r
-                self.sock.close()\r
-            self.sock = None\r
-            raise socket.error, msg\r
-        (code, msg) = self.getreply()\r
-        if self.debuglevel > 0:\r
-            print>>stderr, "connect:", msg\r
-        return (code, msg)\r
-\r
-\r
-# Test the sendmail method, which tests most of the others.\r
-# Note: This always sends to localhost.\r
-if __name__ == '__main__':\r
-    import sys\r
-\r
-    def prompt(prompt):\r
-        sys.stdout.write(prompt + ": ")\r
-        return sys.stdin.readline().strip()\r
-\r
-    fromaddr = prompt("From")\r
-    toaddrs = prompt("To").split(',')\r
-    print "Enter message, end with ^D:"\r
-    msg = ''\r
-    while 1:\r
-        line = sys.stdin.readline()\r
-        if not line:\r
-            break\r
-        msg = msg + line\r
-    print "Message length is %d" % len(msg)\r
-\r
-    server = SMTP('localhost')\r
-    server.set_debuglevel(1)\r
-    server.sendmail(fromaddr, toaddrs, msg)\r
-    server.quit()\r