blob: bd82841ef19ec297654688efc28112bddc3c043b [file] [log] [blame]
Guido van Rossum03774bb1998-04-09 13:50:55 +00001"""A POP3 client class.
Guido van Rossum484772d1998-04-06 18:27:27 +00002
Guido van Rossum03774bb1998-04-09 13:50:55 +00003Based on the J. Myers POP3 draft, Jan. 96
Guido van Rossum484772d1998-04-06 18:27:27 +00004"""
5
Guido van Rossum98d9fd32000-02-28 15:12:25 +00006# Author: David Ascher <david_ascher@brown.edu>
7# [heavily stealing from nntplib.py]
8# Updated: Piers Lauder <piers@cs.su.oz.au> [Jul '97]
Eric S. Raymond341f9292001-02-09 06:56:56 +00009# String method conversion and test jig improvements by ESR, February 2001.
Martin v. Löwis48440b72003-10-31 12:52:35 +000010# Added the POP3_SSL class. Methods loosely based on IMAP_SSL. Hector Urtubia <urtubia@mrbook.org> Aug 2003
Guido van Rossum98d9fd32000-02-28 15:12:25 +000011
Guido van Rossum484772d1998-04-06 18:27:27 +000012# Example (see the test function at the end of this file)
13
Guido van Rossum484772d1998-04-06 18:27:27 +000014# Imports
15
Eric S. Raymond341f9292001-02-09 06:56:56 +000016import re, socket
Guido van Rossum484772d1998-04-06 18:27:27 +000017
Thomas Wouters47b49bf2007-08-30 22:15:33 +000018__all__ = ["POP3","error_proto"]
Skip Montanaroc62c81e2001-02-12 02:00:42 +000019
Guido van Rossum484772d1998-04-06 18:27:27 +000020# Exception raised when an error or invalid response is received:
Guido van Rossum03774bb1998-04-09 13:50:55 +000021
22class error_proto(Exception): pass
Guido van Rossum484772d1998-04-06 18:27:27 +000023
24# Standard Port
25POP3_PORT = 110
26
Martin v. Löwis48440b72003-10-31 12:52:35 +000027# POP SSL PORT
28POP3_SSL_PORT = 995
29
Guido van Rossum03774bb1998-04-09 13:50:55 +000030# Line terminators (we always output CRLF, but accept any of CRLF, LFCR, LF)
Jeremy Hylton88d06a72007-08-29 19:08:30 +000031CR = b'\r'
32LF = b'\n'
Guido van Rossum03774bb1998-04-09 13:50:55 +000033CRLF = CR+LF
Guido van Rossum484772d1998-04-06 18:27:27 +000034
35
36class POP3:
Guido van Rossum03774bb1998-04-09 13:50:55 +000037
Tim Peters2344fae2001-01-15 00:50:52 +000038 """This class supports both the minimal and optional command sets.
39 Arguments can be strings or integers (where appropriate)
40 (e.g.: retr(1) and retr('1') both work equally well.
Guido van Rossum03774bb1998-04-09 13:50:55 +000041
Tim Peters2344fae2001-01-15 00:50:52 +000042 Minimal Command Set:
43 USER name user(name)
44 PASS string pass_(string)
45 STAT stat()
46 LIST [msg] list(msg = None)
47 RETR msg retr(msg)
48 DELE msg dele(msg)
49 NOOP noop()
50 RSET rset()
51 QUIT quit()
Guido van Rossum03774bb1998-04-09 13:50:55 +000052
Tim Peters2344fae2001-01-15 00:50:52 +000053 Optional Commands (some servers support these):
54 RPOP name rpop(name)
55 APOP name digest apop(name, digest)
56 TOP msg n top(msg, n)
57 UIDL [msg] uidl(msg = None)
Guido van Rossum03774bb1998-04-09 13:50:55 +000058
Tim Peters2344fae2001-01-15 00:50:52 +000059 Raises one exception: 'error_proto'.
Guido van Rossum03774bb1998-04-09 13:50:55 +000060
Tim Peters2344fae2001-01-15 00:50:52 +000061 Instantiate with:
62 POP3(hostname, port=110)
Guido van Rossum03774bb1998-04-09 13:50:55 +000063
Tim Peters2344fae2001-01-15 00:50:52 +000064 NB: the POP protocol locks the mailbox from user
65 authorization until QUIT, so be sure to get in, suck
66 the messages, and quit, each time you access the
67 mailbox.
Guido van Rossum03774bb1998-04-09 13:50:55 +000068
Tim Peters2344fae2001-01-15 00:50:52 +000069 POP is a line-based protocol, which means large mail
70 messages consume lots of python cycles reading them
71 line-by-line.
Guido van Rossum03774bb1998-04-09 13:50:55 +000072
Tim Peters2344fae2001-01-15 00:50:52 +000073 If it's available on your mail server, use IMAP4
74 instead, it doesn't suffer from the two problems
75 above.
76 """
Guido van Rossum03774bb1998-04-09 13:50:55 +000077
78
Georg Brandlf78e02b2008-06-10 17:40:04 +000079 def __init__(self, host, port=POP3_PORT,
80 timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
Martin v. Löwis4eb59402001-07-26 13:37:33 +000081 self.host = host
82 self.port = port
Guido van Rossumd8faa362007-04-27 19:54:29 +000083 self.sock = socket.create_connection((host, port), timeout)
Martin v. Löwis4eb59402001-07-26 13:37:33 +000084 self.file = self.sock.makefile('rb')
85 self._debugging = 0
86 self.welcome = self._getresp()
Guido van Rossum484772d1998-04-06 18:27:27 +000087
Guido van Rossum03774bb1998-04-09 13:50:55 +000088
Tim Peters2344fae2001-01-15 00:50:52 +000089 def _putline(self, line):
Guido van Rossumbe19ed72007-02-09 05:37:30 +000090 if self._debugging > 1: print('*put*', repr(line))
Martin v. Löwise12454f2002-02-16 23:06:19 +000091 self.sock.sendall('%s%s' % (line, CRLF))
Guido van Rossum03774bb1998-04-09 13:50:55 +000092
Guido van Rossum484772d1998-04-06 18:27:27 +000093
Tim Peters2344fae2001-01-15 00:50:52 +000094 # Internal: send one command to the server (through _putline())
Guido van Rossum03774bb1998-04-09 13:50:55 +000095
Tim Peters2344fae2001-01-15 00:50:52 +000096 def _putcmd(self, line):
Guido van Rossumbe19ed72007-02-09 05:37:30 +000097 if self._debugging: print('*cmd*', repr(line))
Tim Peters2344fae2001-01-15 00:50:52 +000098 self._putline(line)
Guido van Rossum484772d1998-04-06 18:27:27 +000099
Guido van Rossum03774bb1998-04-09 13:50:55 +0000100
Tim Peters2344fae2001-01-15 00:50:52 +0000101 # Internal: return one line from the server, stripping CRLF.
102 # This is where all the CPU time of this module is consumed.
103 # Raise error_proto('-ERR EOF') if the connection is closed.
Guido van Rossum03774bb1998-04-09 13:50:55 +0000104
Tim Peters2344fae2001-01-15 00:50:52 +0000105 def _getline(self):
106 line = self.file.readline()
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000107 if self._debugging > 1: print('*get*', repr(line))
Tim Peters2344fae2001-01-15 00:50:52 +0000108 if not line: raise error_proto('-ERR EOF')
109 octets = len(line)
110 # server can send any combination of CR & LF
111 # however, 'readline()' returns lines ending in LF
112 # so only possibilities are ...LF, ...CRLF, CR...LF
113 if line[-2:] == CRLF:
114 return line[:-2], octets
115 if line[0] == CR:
116 return line[1:-1], octets
117 return line[:-1], octets
Guido van Rossum03774bb1998-04-09 13:50:55 +0000118
Guido van Rossum484772d1998-04-06 18:27:27 +0000119
Tim Peters2344fae2001-01-15 00:50:52 +0000120 # Internal: get a response from the server.
121 # Raise 'error_proto' if the response doesn't start with '+'.
Guido van Rossum03774bb1998-04-09 13:50:55 +0000122
Tim Peters2344fae2001-01-15 00:50:52 +0000123 def _getresp(self):
124 resp, o = self._getline()
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000125 if self._debugging > 1: print('*resp*', repr(resp))
Tim Peters2344fae2001-01-15 00:50:52 +0000126 c = resp[:1]
Collin Winterf86f2852007-07-23 00:24:10 +0000127 if c != b'+':
Tim Peters2344fae2001-01-15 00:50:52 +0000128 raise error_proto(resp)
129 return resp
Guido van Rossum484772d1998-04-06 18:27:27 +0000130
Guido van Rossum03774bb1998-04-09 13:50:55 +0000131
Tim Peters2344fae2001-01-15 00:50:52 +0000132 # Internal: get a response plus following text from the server.
Guido van Rossum03774bb1998-04-09 13:50:55 +0000133
Tim Peters2344fae2001-01-15 00:50:52 +0000134 def _getlongresp(self):
135 resp = self._getresp()
136 list = []; octets = 0
137 line, o = self._getline()
Guido van Rossum0ec34772007-09-10 00:27:13 +0000138 while line != b'.':
139 if line[:2] == b'..':
Tim Peters2344fae2001-01-15 00:50:52 +0000140 o = o-1
141 line = line[1:]
142 octets = octets + o
143 list.append(line)
144 line, o = self._getline()
145 return resp, list, octets
Guido van Rossum03774bb1998-04-09 13:50:55 +0000146
Guido van Rossum484772d1998-04-06 18:27:27 +0000147
Tim Peters2344fae2001-01-15 00:50:52 +0000148 # Internal: send a command and get the response
Guido van Rossum03774bb1998-04-09 13:50:55 +0000149
Tim Peters2344fae2001-01-15 00:50:52 +0000150 def _shortcmd(self, line):
151 self._putcmd(line)
152 return self._getresp()
Guido van Rossum484772d1998-04-06 18:27:27 +0000153
Guido van Rossum03774bb1998-04-09 13:50:55 +0000154
Tim Peters2344fae2001-01-15 00:50:52 +0000155 # Internal: send a command and get the response plus following text
Guido van Rossum03774bb1998-04-09 13:50:55 +0000156
Tim Peters2344fae2001-01-15 00:50:52 +0000157 def _longcmd(self, line):
158 self._putcmd(line)
159 return self._getlongresp()
Guido van Rossum484772d1998-04-06 18:27:27 +0000160
Guido van Rossum03774bb1998-04-09 13:50:55 +0000161
Tim Peters2344fae2001-01-15 00:50:52 +0000162 # These can be useful:
163
164 def getwelcome(self):
165 return self.welcome
166
167
168 def set_debuglevel(self, level):
169 self._debugging = level
170
171
172 # Here are all the POP commands:
173
174 def user(self, user):
175 """Send user name, return response
Guido van Rossum484772d1998-04-06 18:27:27 +0000176
Tim Peters2344fae2001-01-15 00:50:52 +0000177 (should indicate password required).
178 """
179 return self._shortcmd('USER %s' % user)
Guido van Rossum484772d1998-04-06 18:27:27 +0000180
Guido van Rossum03774bb1998-04-09 13:50:55 +0000181
Tim Peters2344fae2001-01-15 00:50:52 +0000182 def pass_(self, pswd):
183 """Send password, return response
Guido van Rossum484772d1998-04-06 18:27:27 +0000184
Tim Peters2344fae2001-01-15 00:50:52 +0000185 (response includes message count, mailbox size).
Guido van Rossum03774bb1998-04-09 13:50:55 +0000186
Tim Peters2344fae2001-01-15 00:50:52 +0000187 NB: mailbox is locked by server from here to 'quit()'
188 """
189 return self._shortcmd('PASS %s' % pswd)
Guido van Rossum484772d1998-04-06 18:27:27 +0000190
Guido van Rossum03774bb1998-04-09 13:50:55 +0000191
Tim Peters2344fae2001-01-15 00:50:52 +0000192 def stat(self):
193 """Get mailbox status.
Guido van Rossum484772d1998-04-06 18:27:27 +0000194
Tim Peters2344fae2001-01-15 00:50:52 +0000195 Result is tuple of 2 ints (message count, mailbox size)
196 """
197 retval = self._shortcmd('STAT')
Eric S. Raymond341f9292001-02-09 06:56:56 +0000198 rets = retval.split()
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000199 if self._debugging: print('*stat*', repr(rets))
Eric S. Raymond341f9292001-02-09 06:56:56 +0000200 numMessages = int(rets[1])
201 sizeMessages = int(rets[2])
Tim Peters2344fae2001-01-15 00:50:52 +0000202 return (numMessages, sizeMessages)
Guido van Rossum03774bb1998-04-09 13:50:55 +0000203
Guido van Rossum03774bb1998-04-09 13:50:55 +0000204
Tim Peters2344fae2001-01-15 00:50:52 +0000205 def list(self, which=None):
206 """Request listing, return result.
Guido van Rossum484772d1998-04-06 18:27:27 +0000207
Tim Peters2344fae2001-01-15 00:50:52 +0000208 Result without a message number argument is in form
Georg Brandl2772c672005-08-05 21:01:58 +0000209 ['response', ['mesg_num octets', ...], octets].
Guido van Rossum484772d1998-04-06 18:27:27 +0000210
Tim Peters2344fae2001-01-15 00:50:52 +0000211 Result when a message number argument is given is a
212 single response: the "scan listing" for that message.
213 """
Raymond Hettinger16e3c422002-06-01 16:07:16 +0000214 if which is not None:
Tim Peters2344fae2001-01-15 00:50:52 +0000215 return self._shortcmd('LIST %s' % which)
216 return self._longcmd('LIST')
Guido van Rossum03774bb1998-04-09 13:50:55 +0000217
Guido van Rossum03774bb1998-04-09 13:50:55 +0000218
Tim Peters2344fae2001-01-15 00:50:52 +0000219 def retr(self, which):
220 """Retrieve whole message number 'which'.
Guido van Rossumf6ae7431998-09-02 14:42:02 +0000221
Tim Peters2344fae2001-01-15 00:50:52 +0000222 Result is in form ['response', ['line', ...], octets].
223 """
224 return self._longcmd('RETR %s' % which)
Guido van Rossum03774bb1998-04-09 13:50:55 +0000225
Guido van Rossum484772d1998-04-06 18:27:27 +0000226
Tim Peters2344fae2001-01-15 00:50:52 +0000227 def dele(self, which):
228 """Delete message number 'which'.
Guido van Rossum03774bb1998-04-09 13:50:55 +0000229
Tim Peters2344fae2001-01-15 00:50:52 +0000230 Result is 'response'.
231 """
232 return self._shortcmd('DELE %s' % which)
Guido van Rossum03774bb1998-04-09 13:50:55 +0000233
Guido van Rossum484772d1998-04-06 18:27:27 +0000234
Tim Peters2344fae2001-01-15 00:50:52 +0000235 def noop(self):
236 """Does nothing.
Guido van Rossum03774bb1998-04-09 13:50:55 +0000237
Tim Peters2344fae2001-01-15 00:50:52 +0000238 One supposes the response indicates the server is alive.
239 """
240 return self._shortcmd('NOOP')
Guido van Rossum03774bb1998-04-09 13:50:55 +0000241
Guido van Rossum484772d1998-04-06 18:27:27 +0000242
Tim Peters2344fae2001-01-15 00:50:52 +0000243 def rset(self):
Benjamin Petersona37cfc62008-05-26 13:48:34 +0000244 """Unmark all messages marked for deletion."""
Tim Peters2344fae2001-01-15 00:50:52 +0000245 return self._shortcmd('RSET')
Guido van Rossum484772d1998-04-06 18:27:27 +0000246
Guido van Rossum03774bb1998-04-09 13:50:55 +0000247
Tim Peters2344fae2001-01-15 00:50:52 +0000248 def quit(self):
249 """Signoff: commit changes on server, unlock mailbox, close connection."""
250 try:
251 resp = self._shortcmd('QUIT')
Guido van Rossumb940e112007-01-10 16:19:56 +0000252 except error_proto as val:
Tim Peters2344fae2001-01-15 00:50:52 +0000253 resp = val
254 self.file.close()
255 self.sock.close()
256 del self.file, self.sock
257 return resp
Guido van Rossum484772d1998-04-06 18:27:27 +0000258
Tim Peters2344fae2001-01-15 00:50:52 +0000259 #__del__ = quit
Guido van Rossum484772d1998-04-06 18:27:27 +0000260
Guido van Rossum484772d1998-04-06 18:27:27 +0000261
Tim Peters2344fae2001-01-15 00:50:52 +0000262 # optional commands:
Guido van Rossum03774bb1998-04-09 13:50:55 +0000263
Tim Peters2344fae2001-01-15 00:50:52 +0000264 def rpop(self, user):
265 """Not sure what this does."""
266 return self._shortcmd('RPOP %s' % user)
Guido van Rossum03774bb1998-04-09 13:50:55 +0000267
Guido van Rossum03774bb1998-04-09 13:50:55 +0000268
Moshe Zadkaccc2e3d2001-01-19 19:56:27 +0000269 timestamp = re.compile(r'\+OK.*(<[^>]+>)')
Guido van Rossum03774bb1998-04-09 13:50:55 +0000270
Tim Peters2344fae2001-01-15 00:50:52 +0000271 def apop(self, user, secret):
272 """Authorisation
Guido van Rossum03774bb1998-04-09 13:50:55 +0000273
Tim Peters2344fae2001-01-15 00:50:52 +0000274 - only possible if server has supplied a timestamp in initial greeting.
Guido van Rossum03774bb1998-04-09 13:50:55 +0000275
Tim Peters2344fae2001-01-15 00:50:52 +0000276 Args:
277 user - mailbox user;
278 secret - secret shared between client and server.
Guido van Rossum03774bb1998-04-09 13:50:55 +0000279
Tim Peters2344fae2001-01-15 00:50:52 +0000280 NB: mailbox is locked by server from here to 'quit()'
281 """
Moshe Zadkaccc2e3d2001-01-19 19:56:27 +0000282 m = self.timestamp.match(self.welcome)
283 if not m:
Tim Peters2344fae2001-01-15 00:50:52 +0000284 raise error_proto('-ERR APOP not supported by server')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000285 import hashlib
286 digest = hashlib.md5(m.group(1)+secret).digest()
Eric S. Raymond341f9292001-02-09 06:56:56 +0000287 digest = ''.join(map(lambda x:'%02x'%ord(x), digest))
Tim Peters2344fae2001-01-15 00:50:52 +0000288 return self._shortcmd('APOP %s %s' % (user, digest))
Guido van Rossum03774bb1998-04-09 13:50:55 +0000289
Guido van Rossum03774bb1998-04-09 13:50:55 +0000290
Tim Peters2344fae2001-01-15 00:50:52 +0000291 def top(self, which, howmuch):
292 """Retrieve message header of message number 'which'
293 and first 'howmuch' lines of message body.
Guido van Rossum03774bb1998-04-09 13:50:55 +0000294
Tim Peters2344fae2001-01-15 00:50:52 +0000295 Result is in form ['response', ['line', ...], octets].
296 """
297 return self._longcmd('TOP %s %s' % (which, howmuch))
Guido van Rossum03774bb1998-04-09 13:50:55 +0000298
Guido van Rossum03774bb1998-04-09 13:50:55 +0000299
Tim Peters2344fae2001-01-15 00:50:52 +0000300 def uidl(self, which=None):
301 """Return message digest (unique id) list.
Guido van Rossum03774bb1998-04-09 13:50:55 +0000302
Tim Peters2344fae2001-01-15 00:50:52 +0000303 If 'which', result contains unique id for that message
304 in the form 'response mesgnum uid', otherwise result is
305 the list ['response', ['mesgnum uid', ...], octets]
306 """
Raymond Hettinger16e3c422002-06-01 16:07:16 +0000307 if which is not None:
Tim Peters2344fae2001-01-15 00:50:52 +0000308 return self._shortcmd('UIDL %s' % which)
309 return self._longcmd('UIDL')
Guido van Rossum03774bb1998-04-09 13:50:55 +0000310
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000311try:
312 import ssl
313except ImportError:
314 pass
315else:
Martin v. Löwis48440b72003-10-31 12:52:35 +0000316
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000317 class POP3_SSL(POP3):
318 """POP3 client class over SSL connection
Martin v. Löwis48440b72003-10-31 12:52:35 +0000319
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000320 Instantiate with: POP3_SSL(hostname, port=995, keyfile=None, certfile=None)
Martin v. Löwis48440b72003-10-31 12:52:35 +0000321
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000322 hostname - the hostname of the pop3 over ssl server
323 port - port number
324 keyfile - PEM formatted file that countains your private key
325 certfile - PEM formatted certificate chain file
Martin v. Löwis48440b72003-10-31 12:52:35 +0000326
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000327 See the methods of the parent class POP3 for more documentation.
328 """
Martin v. Löwis48440b72003-10-31 12:52:35 +0000329
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000330 def __init__(self, host, port = POP3_SSL_PORT, keyfile = None, certfile = None):
331 self.host = host
332 self.port = port
333 self.keyfile = keyfile
334 self.certfile = certfile
335 self.buffer = ""
336 msg = "getaddrinfo returns an empty list"
337 self.sock = None
338 for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM):
339 af, socktype, proto, canonname, sa = res
340 try:
341 self.sock = socket.socket(af, socktype, proto)
342 self.sock.connect(sa)
343 except socket.error as msg:
344 if self.sock:
345 self.sock.close()
346 self.sock = None
347 continue
348 break
349 if not self.sock:
350 raise socket.error(msg)
351 self.file = self.sock.makefile('rb')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000352 self.sslobj = ssl.wrap_socket(self.sock, self.keyfile, self.certfile)
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000353 self._debugging = 0
354 self.welcome = self._getresp()
Martin v. Löwis48440b72003-10-31 12:52:35 +0000355
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000356 def _fillBuffer(self):
357 localbuf = self.sslobj.read()
358 if len(localbuf) == 0:
359 raise error_proto('-ERR EOF')
360 self.buffer += localbuf
361
362 def _getline(self):
363 line = ""
364 renewline = re.compile(r'.*?\n')
Martin v. Löwis48440b72003-10-31 12:52:35 +0000365 match = renewline.match(self.buffer)
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000366 while not match:
367 self._fillBuffer()
368 match = renewline.match(self.buffer)
369 line = match.group(0)
370 self.buffer = renewline.sub('' ,self.buffer, 1)
371 if self._debugging > 1: print('*get*', repr(line))
Martin v. Löwis48440b72003-10-31 12:52:35 +0000372
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000373 octets = len(line)
374 if line[-2:] == CRLF:
375 return line[:-2], octets
376 if line[0] == CR:
377 return line[1:-1], octets
378 return line[:-1], octets
Martin v. Löwis48440b72003-10-31 12:52:35 +0000379
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000380 def _putline(self, line):
381 if self._debugging > 1: print('*put*', repr(line))
382 line += CRLF
383 bytes = len(line)
384 while bytes > 0:
385 sent = self.sslobj.write(line)
386 if sent == bytes:
387 break # avoid copy
388 line = line[sent:]
389 bytes = bytes - sent
Martin v. Löwis48440b72003-10-31 12:52:35 +0000390
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000391 def quit(self):
392 """Signoff: commit changes on server, unlock mailbox, close connection."""
393 try:
394 resp = self._shortcmd('QUIT')
395 except error_proto as val:
396 resp = val
397 self.sock.close()
398 del self.sslobj, self.sock
399 return resp
Martin v. Löwis48440b72003-10-31 12:52:35 +0000400
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000401 __all__.append("POP3_SSL")
Guido van Rossum03774bb1998-04-09 13:50:55 +0000402
Guido van Rossum484772d1998-04-06 18:27:27 +0000403if __name__ == "__main__":
Eric S. Raymond341f9292001-02-09 06:56:56 +0000404 import sys
405 a = POP3(sys.argv[1])
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000406 print(a.getwelcome())
Eric S. Raymond341f9292001-02-09 06:56:56 +0000407 a.user(sys.argv[2])
408 a.pass_(sys.argv[3])
Tim Peters2344fae2001-01-15 00:50:52 +0000409 a.list()
410 (numMsgs, totalSize) = a.stat()
411 for i in range(1, numMsgs + 1):
412 (header, msg, octets) = a.retr(i)
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000413 print("Message %d:" % i)
Tim Peters2344fae2001-01-15 00:50:52 +0000414 for line in msg:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000415 print(' ' + line)
416 print('-----------------------')
Tim Peters2344fae2001-01-15 00:50:52 +0000417 a.quit()