diff options
| author | orivej <[email protected]> | 2022-02-10 16:45:01 +0300 |
|---|---|---|
| committer | Daniil Cherednik <[email protected]> | 2022-02-10 16:45:01 +0300 |
| commit | 2d37894b1b037cf24231090eda8589bbb44fb6fc (patch) | |
| tree | be835aa92c6248212e705f25388ebafcf84bc7a1 /contrib/tools/python3/src/Lib/poplib.py | |
| parent | 718c552901d703c502ccbefdfc3c9028d608b947 (diff) | |
Restoring authorship annotation for <[email protected]>. Commit 2 of 2.
Diffstat (limited to 'contrib/tools/python3/src/Lib/poplib.py')
| -rw-r--r-- | contrib/tools/python3/src/Lib/poplib.py | 954 |
1 files changed, 477 insertions, 477 deletions
diff --git a/contrib/tools/python3/src/Lib/poplib.py b/contrib/tools/python3/src/Lib/poplib.py index 5c8f5a58655..0f8587317c2 100644 --- a/contrib/tools/python3/src/Lib/poplib.py +++ b/contrib/tools/python3/src/Lib/poplib.py @@ -1,483 +1,483 @@ -"""A POP3 client class. - -Based on the J. Myers POP3 draft, Jan. 96 -""" - -# Author: David Ascher <[email protected]> -# [heavily stealing from nntplib.py] -# Updated: Piers Lauder <[email protected]> [Jul '97] -# String method conversion and test jig improvements by ESR, February 2001. -# Added the POP3_SSL class. Methods loosely based on IMAP_SSL. Hector Urtubia <[email protected]> Aug 2003 - -# Example (see the test function at the end of this file) - -# Imports - -import errno -import re -import socket +"""A POP3 client class. + +Based on the J. Myers POP3 draft, Jan. 96 +""" + +# Author: David Ascher <[email protected]> +# [heavily stealing from nntplib.py] +# Updated: Piers Lauder <[email protected]> [Jul '97] +# String method conversion and test jig improvements by ESR, February 2001. +# Added the POP3_SSL class. Methods loosely based on IMAP_SSL. Hector Urtubia <[email protected]> Aug 2003 + +# Example (see the test function at the end of this file) + +# Imports + +import errno +import re +import socket import sys - -try: - import ssl - HAVE_SSL = True -except ImportError: - HAVE_SSL = False - -__all__ = ["POP3","error_proto"] - -# Exception raised when an error or invalid response is received: - -class error_proto(Exception): pass - -# Standard Port -POP3_PORT = 110 - -# POP SSL PORT -POP3_SSL_PORT = 995 - -# Line terminators (we always output CRLF, but accept any of CRLF, LFCR, LF) -CR = b'\r' -LF = b'\n' -CRLF = CR+LF - -# maximal line length when calling readline(). This is to prevent -# reading arbitrary length lines. RFC 1939 limits POP3 line length to -# 512 characters, including CRLF. We have selected 2048 just to be on -# the safe side. -_MAXLINE = 2048 - - -class POP3: - - """This class supports both the minimal and optional command sets. - Arguments can be strings or integers (where appropriate) - (e.g.: retr(1) and retr('1') both work equally well. - - Minimal Command Set: - USER name user(name) - PASS string pass_(string) - STAT stat() - LIST [msg] list(msg = None) - RETR msg retr(msg) - DELE msg dele(msg) - NOOP noop() - RSET rset() - QUIT quit() - - Optional Commands (some servers support these): - RPOP name rpop(name) - APOP name digest apop(name, digest) - TOP msg n top(msg, n) - UIDL [msg] uidl(msg = None) - CAPA capa() - STLS stls() - UTF8 utf8() - - Raises one exception: 'error_proto'. - - Instantiate with: - POP3(hostname, port=110) - - NB: the POP protocol locks the mailbox from user - authorization until QUIT, so be sure to get in, suck - the messages, and quit, each time you access the - mailbox. - - POP is a line-based protocol, which means large mail - messages consume lots of python cycles reading them - line-by-line. - - If it's available on your mail server, use IMAP4 - instead, it doesn't suffer from the two problems - above. - """ - - encoding = 'UTF-8' - - def __init__(self, host, port=POP3_PORT, - timeout=socket._GLOBAL_DEFAULT_TIMEOUT): - self.host = host - self.port = port - self._tls_established = False + +try: + import ssl + HAVE_SSL = True +except ImportError: + HAVE_SSL = False + +__all__ = ["POP3","error_proto"] + +# Exception raised when an error or invalid response is received: + +class error_proto(Exception): pass + +# Standard Port +POP3_PORT = 110 + +# POP SSL PORT +POP3_SSL_PORT = 995 + +# Line terminators (we always output CRLF, but accept any of CRLF, LFCR, LF) +CR = b'\r' +LF = b'\n' +CRLF = CR+LF + +# maximal line length when calling readline(). This is to prevent +# reading arbitrary length lines. RFC 1939 limits POP3 line length to +# 512 characters, including CRLF. We have selected 2048 just to be on +# the safe side. +_MAXLINE = 2048 + + +class POP3: + + """This class supports both the minimal and optional command sets. + Arguments can be strings or integers (where appropriate) + (e.g.: retr(1) and retr('1') both work equally well. + + Minimal Command Set: + USER name user(name) + PASS string pass_(string) + STAT stat() + LIST [msg] list(msg = None) + RETR msg retr(msg) + DELE msg dele(msg) + NOOP noop() + RSET rset() + QUIT quit() + + Optional Commands (some servers support these): + RPOP name rpop(name) + APOP name digest apop(name, digest) + TOP msg n top(msg, n) + UIDL [msg] uidl(msg = None) + CAPA capa() + STLS stls() + UTF8 utf8() + + Raises one exception: 'error_proto'. + + Instantiate with: + POP3(hostname, port=110) + + NB: the POP protocol locks the mailbox from user + authorization until QUIT, so be sure to get in, suck + the messages, and quit, each time you access the + mailbox. + + POP is a line-based protocol, which means large mail + messages consume lots of python cycles reading them + line-by-line. + + If it's available on your mail server, use IMAP4 + instead, it doesn't suffer from the two problems + above. + """ + + encoding = 'UTF-8' + + def __init__(self, host, port=POP3_PORT, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT): + self.host = host + self.port = port + self._tls_established = False sys.audit("poplib.connect", self, host, port) - self.sock = self._create_socket(timeout) - self.file = self.sock.makefile('rb') - self._debugging = 0 - self.welcome = self._getresp() - - def _create_socket(self, timeout): + self.sock = self._create_socket(timeout) + self.file = self.sock.makefile('rb') + self._debugging = 0 + self.welcome = self._getresp() + + def _create_socket(self, timeout): if timeout is not None and not timeout: raise ValueError('Non-blocking socket (timeout=0) is not supported') - return socket.create_connection((self.host, self.port), timeout) - - def _putline(self, line): - if self._debugging > 1: print('*put*', repr(line)) + return socket.create_connection((self.host, self.port), timeout) + + def _putline(self, line): + if self._debugging > 1: print('*put*', repr(line)) sys.audit("poplib.putline", self, line) - self.sock.sendall(line + CRLF) - - - # Internal: send one command to the server (through _putline()) - - def _putcmd(self, line): - if self._debugging: print('*cmd*', repr(line)) - line = bytes(line, self.encoding) - self._putline(line) - - - # Internal: return one line from the server, stripping CRLF. - # This is where all the CPU time of this module is consumed. - # Raise error_proto('-ERR EOF') if the connection is closed. - - def _getline(self): - line = self.file.readline(_MAXLINE + 1) - if len(line) > _MAXLINE: - raise error_proto('line too long') - - if self._debugging > 1: print('*get*', repr(line)) - if not line: raise error_proto('-ERR EOF') - octets = len(line) - # server can send any combination of CR & LF - # however, 'readline()' returns lines ending in LF - # so only possibilities are ...LF, ...CRLF, CR...LF - if line[-2:] == CRLF: - return line[:-2], octets - if line[:1] == CR: - return line[1:-1], octets - return line[:-1], octets - - - # Internal: get a response from the server. - # Raise 'error_proto' if the response doesn't start with '+'. - - def _getresp(self): - resp, o = self._getline() - if self._debugging > 1: print('*resp*', repr(resp)) - if not resp.startswith(b'+'): - raise error_proto(resp) - return resp - - - # Internal: get a response plus following text from the server. - - def _getlongresp(self): - resp = self._getresp() - list = []; octets = 0 - line, o = self._getline() - while line != b'.': - if line.startswith(b'..'): - o = o-1 - line = line[1:] - octets = octets + o - list.append(line) - line, o = self._getline() - return resp, list, octets - - - # Internal: send a command and get the response - - def _shortcmd(self, line): - self._putcmd(line) - return self._getresp() - - - # Internal: send a command and get the response plus following text - - def _longcmd(self, line): - self._putcmd(line) - return self._getlongresp() - - - # These can be useful: - - def getwelcome(self): - return self.welcome - - - def set_debuglevel(self, level): - self._debugging = level - - - # Here are all the POP commands: - - def user(self, user): - """Send user name, return response - - (should indicate password required). - """ - return self._shortcmd('USER %s' % user) - - - def pass_(self, pswd): - """Send password, return response - - (response includes message count, mailbox size). - - NB: mailbox is locked by server from here to 'quit()' - """ - return self._shortcmd('PASS %s' % pswd) - - - def stat(self): - """Get mailbox status. - - Result is tuple of 2 ints (message count, mailbox size) - """ - retval = self._shortcmd('STAT') - rets = retval.split() - if self._debugging: print('*stat*', repr(rets)) - numMessages = int(rets[1]) - sizeMessages = int(rets[2]) - return (numMessages, sizeMessages) - - - def list(self, which=None): - """Request listing, return result. - - Result without a message number argument is in form - ['response', ['mesg_num octets', ...], octets]. - - Result when a message number argument is given is a - single response: the "scan listing" for that message. - """ - if which is not None: - return self._shortcmd('LIST %s' % which) - return self._longcmd('LIST') - - - def retr(self, which): - """Retrieve whole message number 'which'. - - Result is in form ['response', ['line', ...], octets]. - """ - return self._longcmd('RETR %s' % which) - - - def dele(self, which): - """Delete message number 'which'. - - Result is 'response'. - """ - return self._shortcmd('DELE %s' % which) - - - def noop(self): - """Does nothing. - - One supposes the response indicates the server is alive. - """ - return self._shortcmd('NOOP') - - - def rset(self): - """Unmark all messages marked for deletion.""" - return self._shortcmd('RSET') - - - def quit(self): - """Signoff: commit changes on server, unlock mailbox, close connection.""" - resp = self._shortcmd('QUIT') - self.close() - return resp - - def close(self): - """Close the connection without assuming anything about it.""" - try: - file = self.file - self.file = None - if file is not None: - file.close() - finally: - sock = self.sock - self.sock = None - if sock is not None: - try: - sock.shutdown(socket.SHUT_RDWR) - except OSError as exc: - # The server might already have closed the connection. - # On Windows, this may result in WSAEINVAL (error 10022): - # An invalid operation was attempted. - if (exc.errno != errno.ENOTCONN - and getattr(exc, 'winerror', 0) != 10022): - raise - finally: - sock.close() - - #__del__ = quit - - - # optional commands: - - def rpop(self, user): - """Not sure what this does.""" - return self._shortcmd('RPOP %s' % user) - - - timestamp = re.compile(br'\+OK.[^<]*(<.*>)') - - def apop(self, user, password): - """Authorisation - - - only possible if server has supplied a timestamp in initial greeting. - - Args: - user - mailbox user; - password - mailbox password. - - NB: mailbox is locked by server from here to 'quit()' - """ - secret = bytes(password, self.encoding) - m = self.timestamp.match(self.welcome) - if not m: - raise error_proto('-ERR APOP not supported by server') - import hashlib - digest = m.group(1)+secret - digest = hashlib.md5(digest).hexdigest() - return self._shortcmd('APOP %s %s' % (user, digest)) - - - def top(self, which, howmuch): - """Retrieve message header of message number 'which' - and first 'howmuch' lines of message body. - - Result is in form ['response', ['line', ...], octets]. - """ - return self._longcmd('TOP %s %s' % (which, howmuch)) - - - def uidl(self, which=None): - """Return message digest (unique id) list. - - If 'which', result contains unique id for that message - in the form 'response mesgnum uid', otherwise result is - the list ['response', ['mesgnum uid', ...], octets] - """ - if which is not None: - return self._shortcmd('UIDL %s' % which) - return self._longcmd('UIDL') - - - def utf8(self): - """Try to enter UTF-8 mode (see RFC 6856). Returns server response. - """ - return self._shortcmd('UTF8') - - - def capa(self): - """Return server capabilities (RFC 2449) as a dictionary - >>> c=poplib.POP3('localhost') - >>> c.capa() - {'IMPLEMENTATION': ['Cyrus', 'POP3', 'server', 'v2.2.12'], - 'TOP': [], 'LOGIN-DELAY': ['0'], 'AUTH-RESP-CODE': [], - 'EXPIRE': ['NEVER'], 'USER': [], 'STLS': [], 'PIPELINING': [], - 'UIDL': [], 'RESP-CODES': []} - >>> - - Really, according to RFC 2449, the cyrus folks should avoid - having the implementation split into multiple arguments... - """ - def _parsecap(line): - lst = line.decode('ascii').split() - return lst[0], lst[1:] - - caps = {} - try: - resp = self._longcmd('CAPA') - rawcaps = resp[1] - for capline in rawcaps: - capnm, capargs = _parsecap(capline) - caps[capnm] = capargs + self.sock.sendall(line + CRLF) + + + # Internal: send one command to the server (through _putline()) + + def _putcmd(self, line): + if self._debugging: print('*cmd*', repr(line)) + line = bytes(line, self.encoding) + self._putline(line) + + + # Internal: return one line from the server, stripping CRLF. + # This is where all the CPU time of this module is consumed. + # Raise error_proto('-ERR EOF') if the connection is closed. + + def _getline(self): + line = self.file.readline(_MAXLINE + 1) + if len(line) > _MAXLINE: + raise error_proto('line too long') + + if self._debugging > 1: print('*get*', repr(line)) + if not line: raise error_proto('-ERR EOF') + octets = len(line) + # server can send any combination of CR & LF + # however, 'readline()' returns lines ending in LF + # so only possibilities are ...LF, ...CRLF, CR...LF + if line[-2:] == CRLF: + return line[:-2], octets + if line[:1] == CR: + return line[1:-1], octets + return line[:-1], octets + + + # Internal: get a response from the server. + # Raise 'error_proto' if the response doesn't start with '+'. + + def _getresp(self): + resp, o = self._getline() + if self._debugging > 1: print('*resp*', repr(resp)) + if not resp.startswith(b'+'): + raise error_proto(resp) + return resp + + + # Internal: get a response plus following text from the server. + + def _getlongresp(self): + resp = self._getresp() + list = []; octets = 0 + line, o = self._getline() + while line != b'.': + if line.startswith(b'..'): + o = o-1 + line = line[1:] + octets = octets + o + list.append(line) + line, o = self._getline() + return resp, list, octets + + + # Internal: send a command and get the response + + def _shortcmd(self, line): + self._putcmd(line) + return self._getresp() + + + # Internal: send a command and get the response plus following text + + def _longcmd(self, line): + self._putcmd(line) + return self._getlongresp() + + + # These can be useful: + + def getwelcome(self): + return self.welcome + + + def set_debuglevel(self, level): + self._debugging = level + + + # Here are all the POP commands: + + def user(self, user): + """Send user name, return response + + (should indicate password required). + """ + return self._shortcmd('USER %s' % user) + + + def pass_(self, pswd): + """Send password, return response + + (response includes message count, mailbox size). + + NB: mailbox is locked by server from here to 'quit()' + """ + return self._shortcmd('PASS %s' % pswd) + + + def stat(self): + """Get mailbox status. + + Result is tuple of 2 ints (message count, mailbox size) + """ + retval = self._shortcmd('STAT') + rets = retval.split() + if self._debugging: print('*stat*', repr(rets)) + numMessages = int(rets[1]) + sizeMessages = int(rets[2]) + return (numMessages, sizeMessages) + + + def list(self, which=None): + """Request listing, return result. + + Result without a message number argument is in form + ['response', ['mesg_num octets', ...], octets]. + + Result when a message number argument is given is a + single response: the "scan listing" for that message. + """ + if which is not None: + return self._shortcmd('LIST %s' % which) + return self._longcmd('LIST') + + + def retr(self, which): + """Retrieve whole message number 'which'. + + Result is in form ['response', ['line', ...], octets]. + """ + return self._longcmd('RETR %s' % which) + + + def dele(self, which): + """Delete message number 'which'. + + Result is 'response'. + """ + return self._shortcmd('DELE %s' % which) + + + def noop(self): + """Does nothing. + + One supposes the response indicates the server is alive. + """ + return self._shortcmd('NOOP') + + + def rset(self): + """Unmark all messages marked for deletion.""" + return self._shortcmd('RSET') + + + def quit(self): + """Signoff: commit changes on server, unlock mailbox, close connection.""" + resp = self._shortcmd('QUIT') + self.close() + return resp + + def close(self): + """Close the connection without assuming anything about it.""" + try: + file = self.file + self.file = None + if file is not None: + file.close() + finally: + sock = self.sock + self.sock = None + if sock is not None: + try: + sock.shutdown(socket.SHUT_RDWR) + except OSError as exc: + # The server might already have closed the connection. + # On Windows, this may result in WSAEINVAL (error 10022): + # An invalid operation was attempted. + if (exc.errno != errno.ENOTCONN + and getattr(exc, 'winerror', 0) != 10022): + raise + finally: + sock.close() + + #__del__ = quit + + + # optional commands: + + def rpop(self, user): + """Not sure what this does.""" + return self._shortcmd('RPOP %s' % user) + + + timestamp = re.compile(br'\+OK.[^<]*(<.*>)') + + def apop(self, user, password): + """Authorisation + + - only possible if server has supplied a timestamp in initial greeting. + + Args: + user - mailbox user; + password - mailbox password. + + NB: mailbox is locked by server from here to 'quit()' + """ + secret = bytes(password, self.encoding) + m = self.timestamp.match(self.welcome) + if not m: + raise error_proto('-ERR APOP not supported by server') + import hashlib + digest = m.group(1)+secret + digest = hashlib.md5(digest).hexdigest() + return self._shortcmd('APOP %s %s' % (user, digest)) + + + def top(self, which, howmuch): + """Retrieve message header of message number 'which' + and first 'howmuch' lines of message body. + + Result is in form ['response', ['line', ...], octets]. + """ + return self._longcmd('TOP %s %s' % (which, howmuch)) + + + def uidl(self, which=None): + """Return message digest (unique id) list. + + If 'which', result contains unique id for that message + in the form 'response mesgnum uid', otherwise result is + the list ['response', ['mesgnum uid', ...], octets] + """ + if which is not None: + return self._shortcmd('UIDL %s' % which) + return self._longcmd('UIDL') + + + def utf8(self): + """Try to enter UTF-8 mode (see RFC 6856). Returns server response. + """ + return self._shortcmd('UTF8') + + + def capa(self): + """Return server capabilities (RFC 2449) as a dictionary + >>> c=poplib.POP3('localhost') + >>> c.capa() + {'IMPLEMENTATION': ['Cyrus', 'POP3', 'server', 'v2.2.12'], + 'TOP': [], 'LOGIN-DELAY': ['0'], 'AUTH-RESP-CODE': [], + 'EXPIRE': ['NEVER'], 'USER': [], 'STLS': [], 'PIPELINING': [], + 'UIDL': [], 'RESP-CODES': []} + >>> + + Really, according to RFC 2449, the cyrus folks should avoid + having the implementation split into multiple arguments... + """ + def _parsecap(line): + lst = line.decode('ascii').split() + return lst[0], lst[1:] + + caps = {} + try: + resp = self._longcmd('CAPA') + rawcaps = resp[1] + for capline in rawcaps: + capnm, capargs = _parsecap(capline) + caps[capnm] = capargs except error_proto: - raise error_proto('-ERR CAPA not supported by server') - return caps - - - def stls(self, context=None): - """Start a TLS session on the active connection as specified in RFC 2595. - - context - a ssl.SSLContext - """ - if not HAVE_SSL: - raise error_proto('-ERR TLS support missing') - if self._tls_established: - raise error_proto('-ERR TLS session already established') - caps = self.capa() - if not 'STLS' in caps: - raise error_proto('-ERR STLS not supported by server') - if context is None: - context = ssl._create_stdlib_context() - resp = self._shortcmd('STLS') - self.sock = context.wrap_socket(self.sock, - server_hostname=self.host) - self.file = self.sock.makefile('rb') - self._tls_established = True - return resp - - -if HAVE_SSL: - - class POP3_SSL(POP3): - """POP3 client class over SSL connection - - Instantiate with: POP3_SSL(hostname, port=995, keyfile=None, certfile=None, - context=None) - - hostname - the hostname of the pop3 over ssl server - port - port number - keyfile - PEM formatted file that contains your private key - certfile - PEM formatted certificate chain file - context - a ssl.SSLContext - - See the methods of the parent class POP3 for more documentation. - """ - - def __init__(self, host, port=POP3_SSL_PORT, keyfile=None, certfile=None, - timeout=socket._GLOBAL_DEFAULT_TIMEOUT, context=None): - if context is not None and keyfile is not None: - raise ValueError("context and keyfile arguments are mutually " - "exclusive") - if context is not None and certfile is not None: - raise ValueError("context and certfile arguments are mutually " - "exclusive") - if keyfile is not None or certfile is not None: - import warnings - warnings.warn("keyfile and certfile are deprecated, use a " - "custom context instead", DeprecationWarning, 2) - self.keyfile = keyfile - self.certfile = certfile - if context is None: - context = ssl._create_stdlib_context(certfile=certfile, - keyfile=keyfile) - self.context = context - POP3.__init__(self, host, port, timeout) - - def _create_socket(self, timeout): - sock = POP3._create_socket(self, timeout) - sock = self.context.wrap_socket(sock, - server_hostname=self.host) - return sock - - def stls(self, keyfile=None, certfile=None, context=None): - """The method unconditionally raises an exception since the - STLS command doesn't make any sense on an already established - SSL/TLS session. - """ - raise error_proto('-ERR TLS session already established') - - __all__.append("POP3_SSL") - -if __name__ == "__main__": - import sys - a = POP3(sys.argv[1]) - print(a.getwelcome()) - a.user(sys.argv[2]) - a.pass_(sys.argv[3]) - a.list() - (numMsgs, totalSize) = a.stat() - for i in range(1, numMsgs + 1): - (header, msg, octets) = a.retr(i) - print("Message %d:" % i) - for line in msg: - print(' ' + line) - print('-----------------------') - a.quit() + raise error_proto('-ERR CAPA not supported by server') + return caps + + + def stls(self, context=None): + """Start a TLS session on the active connection as specified in RFC 2595. + + context - a ssl.SSLContext + """ + if not HAVE_SSL: + raise error_proto('-ERR TLS support missing') + if self._tls_established: + raise error_proto('-ERR TLS session already established') + caps = self.capa() + if not 'STLS' in caps: + raise error_proto('-ERR STLS not supported by server') + if context is None: + context = ssl._create_stdlib_context() + resp = self._shortcmd('STLS') + self.sock = context.wrap_socket(self.sock, + server_hostname=self.host) + self.file = self.sock.makefile('rb') + self._tls_established = True + return resp + + +if HAVE_SSL: + + class POP3_SSL(POP3): + """POP3 client class over SSL connection + + Instantiate with: POP3_SSL(hostname, port=995, keyfile=None, certfile=None, + context=None) + + hostname - the hostname of the pop3 over ssl server + port - port number + keyfile - PEM formatted file that contains your private key + certfile - PEM formatted certificate chain file + context - a ssl.SSLContext + + See the methods of the parent class POP3 for more documentation. + """ + + def __init__(self, host, port=POP3_SSL_PORT, keyfile=None, certfile=None, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT, context=None): + if context is not None and keyfile is not None: + raise ValueError("context and keyfile arguments are mutually " + "exclusive") + if context is not None and certfile is not None: + raise ValueError("context and certfile arguments are mutually " + "exclusive") + if keyfile is not None or certfile is not None: + import warnings + warnings.warn("keyfile and certfile are deprecated, use a " + "custom context instead", DeprecationWarning, 2) + self.keyfile = keyfile + self.certfile = certfile + if context is None: + context = ssl._create_stdlib_context(certfile=certfile, + keyfile=keyfile) + self.context = context + POP3.__init__(self, host, port, timeout) + + def _create_socket(self, timeout): + sock = POP3._create_socket(self, timeout) + sock = self.context.wrap_socket(sock, + server_hostname=self.host) + return sock + + def stls(self, keyfile=None, certfile=None, context=None): + """The method unconditionally raises an exception since the + STLS command doesn't make any sense on an already established + SSL/TLS session. + """ + raise error_proto('-ERR TLS session already established') + + __all__.append("POP3_SSL") + +if __name__ == "__main__": + import sys + a = POP3(sys.argv[1]) + print(a.getwelcome()) + a.user(sys.argv[2]) + a.pass_(sys.argv[3]) + a.list() + (numMsgs, totalSize) = a.stat() + for i in range(1, numMsgs + 1): + (header, msg, octets) = a.retr(i) + print("Message %d:" % i) + for line in msg: + print(' ' + line) + print('-----------------------') + a.quit() |
