annotate Lib/smtpd.py @ 54294:dba767bc3155 legacy-trunk

remove mention of old ctypes version
author Benjamin Peterson <benjamin@python.org>
date Sat, 23 May 2009 20:59:09 +0000
parents 74c0a78114ae
children 76bc255d29fd
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
1 #! /usr/bin/env python
19235
c6129428e053 found_terminator(): Add a debug print showing the data.
Barry Warsaw <barry@python.org>
parents: 19213
diff changeset
2 """An RFC 2821 smtp proxy.
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
3
20251
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
4 Usage: %(program)s [options] [localhost:localport [remotehost:remoteport]]
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
5
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
6 Options:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
7
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
8 --nosetuid
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
9 -n
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
10 This program generally tries to setuid `nobody', unless this flag is
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
11 set. The setuid call will fail if this program is not run as root (in
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
12 which case, use this flag).
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
13
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
14 --version
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
15 -V
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
16 Print the version number and exit.
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
17
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
18 --class classname
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
19 -c classname
33704
295bd8c55a78 Fix for SF bug # 1010102. The default is PureProxy not SMTPProxy.
Barry Warsaw <barry@python.org>
parents: 32640
diff changeset
20 Use `classname' as the concrete SMTP proxy class. Uses `PureProxy' by
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
21 default.
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
22
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
23 --debug
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
24 -d
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
25 Turn on debugging prints.
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
26
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
27 --help
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
28 -h
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
29 Print this message and exit.
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
30
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
31 Version: %(__version__)s
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
32
20251
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
33 If localhost is not given then `localhost' is used, and if localport is not
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
34 given then 8025 is used. If remotehost is not given then `localhost' is used,
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
35 and if remoteport is not given, then 25 is used.
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
36 """
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
37
20251
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
38
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
39 # Overview:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
40 #
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
41 # This file implements the minimal SMTP protocol as defined in RFC 821. It
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
42 # has a hierarchy of classes which implement the backend functionality for the
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
43 # smtpd. A number of classes are provided:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
44 #
17527
01be08333308 Fix typo in exception name (UnimplementedError should be
Guido van Rossum <guido@python.org>
parents: 16948
diff changeset
45 # SMTPServer - the base class for the backend. Raises NotImplementedError
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
46 # if you try to use it.
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
47 #
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
48 # DebuggingServer - simply prints each message it receives on stdout.
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
49 #
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
50 # PureProxy - Proxies all messages to a real smtpd which does final
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
51 # delivery. One known problem with this class is that it doesn't handle
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
52 # SMTP errors from the backend server at all. This should be fixed
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
53 # (contributions are welcome!).
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
54 #
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
55 # MailmanProxy - An experimental hack to work with GNU Mailman
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
56 # <www.list.org>. Using this server as your real incoming smtpd, your
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
57 # mailhost will automatically recognize and accept mail destined to Mailman
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
58 # lists when those lists are created. Every message not destined for a list
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
59 # gets forwarded to a real backend smtpd, as with PureProxy. Again, errors
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
60 # are not handled correctly yet.
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
61 #
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
62 # Please note that this script requires Python 2.0
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
63 #
32640
da18210e311c Updated my email address to something that works <wink>.
Barry Warsaw <barry@python.org>
parents: 32415
diff changeset
64 # Author: Barry Warsaw <barry@python.org>
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
65 #
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
66 # TODO:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
67 #
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
68 # - support mailbox delivery
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
69 # - alias files
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
70 # - ESMTP
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
71 # - handle error codes from the backend smtpd
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
72
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
73 import sys
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
74 import os
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
75 import errno
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
76 import getopt
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
77 import time
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
78 import socket
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
79 import asyncore
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
80 import asynchat
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
81
16613
f68dbffff927 bunch more __all__ lists
Skip Montanaro <skip@pobox.com>
parents: 16535
diff changeset
82 __all__ = ["SMTPServer","DebuggingServer","PureProxy","MailmanProxy"]
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
83
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
84 program = sys.argv[0]
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
85 __version__ = 'Python SMTP proxy version 0.2'
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
86
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
87
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
88 class Devnull:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
89 def write(self, msg): pass
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
90 def flush(self): pass
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
91
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
92
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
93 DEBUGSTREAM = Devnull()
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
94 NEWLINE = '\n'
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
95 EMPTYSTRING = ''
20251
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
96 COMMASPACE = ', '
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
97
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
98
20251
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
99
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
100 def usage(code, msg=''):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
101 print >> sys.stderr, __doc__ % globals()
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
102 if msg:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
103 print >> sys.stderr, msg
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
104 sys.exit(code)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
105
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
106
20251
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
107
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
108 class SMTPChannel(asynchat.async_chat):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
109 COMMAND = 0
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
110 DATA = 1
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
111
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
112 def __init__(self, server, conn, addr):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
113 asynchat.async_chat.__init__(self, conn)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
114 self.__server = server
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
115 self.__conn = conn
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
116 self.__addr = addr
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
117 self.__line = []
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
118 self.__state = self.COMMAND
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
119 self.__greeting = 0
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
120 self.__mailfrom = None
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
121 self.__rcpttos = []
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
122 self.__data = ''
20251
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
123 self.__fqdn = socket.getfqdn()
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
124 self.__peer = conn.getpeername()
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
125 print >> DEBUGSTREAM, 'Peer:', repr(self.__peer)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
126 self.push('220 %s %s' % (self.__fqdn, __version__))
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
127 self.set_terminator('\r\n')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
128
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
129 # Overrides base class for convenience
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
130 def push(self, msg):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
131 asynchat.async_chat.push(self, msg + '\r\n')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
132
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
133 # Implementation of base class abstract method
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
134 def collect_incoming_data(self, data):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
135 self.__line.append(data)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
136
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
137 # Implementation of base class abstract method
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
138 def found_terminator(self):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
139 line = EMPTYSTRING.join(self.__line)
19235
c6129428e053 found_terminator(): Add a debug print showing the data.
Barry Warsaw <barry@python.org>
parents: 19213
diff changeset
140 print >> DEBUGSTREAM, 'Data:', repr(line)
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
141 self.__line = []
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
142 if self.__state == self.COMMAND:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
143 if not line:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
144 self.push('500 Error: bad syntax')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
145 return
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
146 method = None
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
147 i = line.find(' ')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
148 if i < 0:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
149 command = line.upper()
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
150 arg = None
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
151 else:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
152 command = line[:i].upper()
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
153 arg = line[i+1:].strip()
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
154 method = getattr(self, 'smtp_' + command, None)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
155 if not method:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
156 self.push('502 Error: command "%s" not implemented' % command)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
157 return
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
158 method(arg)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
159 return
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
160 else:
16948
faa52f384af6 Use != instead of <>. Sorry, Barry.
Guido van Rossum <guido@python.org>
parents: 16613
diff changeset
161 if self.__state != self.DATA:
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
162 self.push('451 Internal confusion')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
163 return
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
164 # Remove extraneous carriage returns and de-transparency according
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
165 # to RFC 821, Section 4.5.2.
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
166 data = []
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
167 for text in line.split('\r\n'):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
168 if text and text[0] == '.':
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
169 data.append(text[1:])
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
170 else:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
171 data.append(text)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
172 self.__data = NEWLINE.join(data)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
173 status = self.__server.process_message(self.__peer,
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
174 self.__mailfrom,
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
175 self.__rcpttos,
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
176 self.__data)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
177 self.__rcpttos = []
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
178 self.__mailfrom = None
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
179 self.__state = self.COMMAND
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
180 self.set_terminator('\r\n')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
181 if not status:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
182 self.push('250 Ok')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
183 else:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
184 self.push(status)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
185
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
186 # SMTP and ESMTP commands
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
187 def smtp_HELO(self, arg):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
188 if not arg:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
189 self.push('501 Syntax: HELO hostname')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
190 return
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
191 if self.__greeting:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
192 self.push('503 Duplicate HELO/EHLO')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
193 else:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
194 self.__greeting = arg
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
195 self.push('250 %s' % self.__fqdn)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
196
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
197 def smtp_NOOP(self, arg):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
198 if arg:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
199 self.push('501 Syntax: NOOP')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
200 else:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
201 self.push('250 Ok')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
202
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
203 def smtp_QUIT(self, arg):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
204 # args is ignored
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
205 self.push('221 Bye')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
206 self.close_when_done()
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
207
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
208 # factored
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
209 def __getaddr(self, keyword, arg):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
210 address = None
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
211 keylen = len(keyword)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
212 if arg[:keylen].upper() == keyword:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
213 address = arg[keylen:].strip()
20862
d9b9b5b4815b Two bug fixes for problems reported by Sverre:
Barry Warsaw <barry@python.org>
parents: 20332
diff changeset
214 if not address:
d9b9b5b4815b Two bug fixes for problems reported by Sverre:
Barry Warsaw <barry@python.org>
parents: 20332
diff changeset
215 pass
d9b9b5b4815b Two bug fixes for problems reported by Sverre:
Barry Warsaw <barry@python.org>
parents: 20332
diff changeset
216 elif address[0] == '<' and address[-1] == '>' and address != '<>':
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
217 # Addresses can be in the form <person@dom.com> but watch out
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
218 # for null address, e.g. <>
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
219 address = address[1:-1]
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
220 return address
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
221
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
222 def smtp_MAIL(self, arg):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
223 print >> DEBUGSTREAM, '===> MAIL', arg
43641
53ee8943d165 Backport 58594:
Neal Norwitz <nnorwitz@gmail.com>
parents: 33704
diff changeset
224 address = self.__getaddr('FROM:', arg) if arg else None
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
225 if not address:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
226 self.push('501 Syntax: MAIL FROM:<address>')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
227 return
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
228 if self.__mailfrom:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
229 self.push('503 Error: nested MAIL command')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
230 return
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
231 self.__mailfrom = address
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
232 print >> DEBUGSTREAM, 'sender:', self.__mailfrom
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
233 self.push('250 Ok')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
234
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
235 def smtp_RCPT(self, arg):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
236 print >> DEBUGSTREAM, '===> RCPT', arg
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
237 if not self.__mailfrom:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
238 self.push('503 Error: need MAIL command')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
239 return
43659
974e64cc083d Backport 58618:
Neal Norwitz <nnorwitz@gmail.com>
parents: 43641
diff changeset
240 address = self.__getaddr('TO:', arg) if arg else None
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
241 if not address:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
242 self.push('501 Syntax: RCPT TO: <address>')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
243 return
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
244 self.__rcpttos.append(address)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
245 print >> DEBUGSTREAM, 'recips:', self.__rcpttos
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
246 self.push('250 Ok')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
247
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
248 def smtp_RSET(self, arg):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
249 if arg:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
250 self.push('501 Syntax: RSET')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
251 return
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
252 # Resets the sender, recipients, and data, but not the greeting
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
253 self.__mailfrom = None
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
254 self.__rcpttos = []
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
255 self.__data = ''
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
256 self.__state = self.COMMAND
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
257 self.push('250 Ok')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
258
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
259 def smtp_DATA(self, arg):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
260 if not self.__rcpttos:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
261 self.push('503 Error: need RCPT command')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
262 return
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
263 if arg:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
264 self.push('501 Syntax: DATA')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
265 return
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
266 self.__state = self.DATA
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
267 self.set_terminator('\r\n.\r\n')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
268 self.push('354 End data with <CR><LF>.<CR><LF>')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
269
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
270
20251
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
271
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
272 class SMTPServer(asyncore.dispatcher):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
273 def __init__(self, localaddr, remoteaddr):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
274 self._localaddr = localaddr
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
275 self._remoteaddr = remoteaddr
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
276 asyncore.dispatcher.__init__(self)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
277 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
278 # try to re-use a server port if possible
20332
04fee70fed8f SMTPServer.__init__(): The asyncore.dispatcher base class has a method
Barry Warsaw <barry@python.org>
parents: 20271
diff changeset
279 self.set_reuse_addr()
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
280 self.bind(localaddr)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
281 self.listen(5)
20271
612e86a4cd9f SMTPServer.__init__(): Print the start information on the DEBUGSTREAM
Barry Warsaw <barry@python.org>
parents: 20251
diff changeset
282 print >> DEBUGSTREAM, \
612e86a4cd9f SMTPServer.__init__(): Print the start information on the DEBUGSTREAM
Barry Warsaw <barry@python.org>
parents: 20251
diff changeset
283 '%s started at %s\n\tLocal addr: %s\n\tRemote addr:%s' % (
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
284 self.__class__.__name__, time.ctime(time.time()),
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
285 localaddr, remoteaddr)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
286
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
287 def handle_accept(self):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
288 conn, addr = self.accept()
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
289 print >> DEBUGSTREAM, 'Incoming connection from %s' % repr(addr)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
290 channel = SMTPChannel(self, conn, addr)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
291
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
292 # API for "doing something useful with the message"
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
293 def process_message(self, peer, mailfrom, rcpttos, data):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
294 """Override this abstract method to handle messages from the client.
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
295
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
296 peer is a tuple containing (ipaddr, port) of the client that made the
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
297 socket connection to our smtp port.
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
298
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
299 mailfrom is the raw address the client claims the message is coming
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
300 from.
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
301
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
302 rcpttos is a list of raw addresses the client wishes to deliver the
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
303 message to.
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
304
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
305 data is a string containing the entire full text of the message,
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
306 headers (if supplied) and all. It has been `de-transparencied'
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
307 according to RFC 821, Section 4.5.2. In other words, a line
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
308 containing a `.' followed by other text has had the leading dot
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
309 removed.
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
310
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
311 This function should return None, for a normal `250 Ok' response;
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
312 otherwise it returns the desired response string in RFC 821 format.
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
313
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
314 """
17527
01be08333308 Fix typo in exception name (UnimplementedError should be
Guido van Rossum <guido@python.org>
parents: 16948
diff changeset
315 raise NotImplementedError
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
316
16535
084b3dc9b6ff Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 16377
diff changeset
317
20251
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
318
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
319 class DebuggingServer(SMTPServer):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
320 # Do something with the gathered message
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
321 def process_message(self, peer, mailfrom, rcpttos, data):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
322 inheaders = 1
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
323 lines = data.split('\n')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
324 print '---------- MESSAGE FOLLOWS ----------'
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
325 for line in lines:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
326 # headers first
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
327 if inheaders and not line:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
328 print 'X-Peer:', peer[0]
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
329 inheaders = 0
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
330 print line
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
331 print '------------ END MESSAGE ------------'
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
332
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
333
20251
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
334
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
335 class PureProxy(SMTPServer):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
336 def process_message(self, peer, mailfrom, rcpttos, data):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
337 lines = data.split('\n')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
338 # Look for the last header
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
339 i = 0
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
340 for line in lines:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
341 if not line:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
342 break
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
343 i += 1
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
344 lines.insert(i, 'X-Peer: %s' % peer[0])
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
345 data = NEWLINE.join(lines)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
346 refused = self._deliver(mailfrom, rcpttos, data)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
347 # TBD: what to do with refused addresses?
21920
59bb43b6eb11 SF #515021, print the refused list to the DEBUGSTREAM, so the parameter is used
Neal Norwitz <nnorwitz@gmail.com>
parents: 20862
diff changeset
348 print >> DEBUGSTREAM, 'we got some refusals:', refused
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
349
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
350 def _deliver(self, mailfrom, rcpttos, data):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
351 import smtplib
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
352 refused = {}
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
353 try:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
354 s = smtplib.SMTP()
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
355 s.connect(self._remoteaddr[0], self._remoteaddr[1])
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
356 try:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
357 refused = s.sendmail(mailfrom, rcpttos, data)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
358 finally:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
359 s.quit()
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
360 except smtplib.SMTPRecipientsRefused, e:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
361 print >> DEBUGSTREAM, 'got SMTPRecipientsRefused'
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
362 refused = e.recipients
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
363 except (socket.error, smtplib.SMTPException), e:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
364 print >> DEBUGSTREAM, 'got', e.__class__
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
365 # All recipients were refused. If the exception had an associated
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
366 # error code, use it. Otherwise,fake it with a non-triggering
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
367 # exception code.
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
368 errcode = getattr(e, 'smtp_code', -1)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
369 errmsg = getattr(e, 'smtp_error', 'ignore')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
370 for r in rcpttos:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
371 refused[r] = (errcode, errmsg)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
372 return refused
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
373
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
374
20251
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
375
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
376 class MailmanProxy(PureProxy):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
377 def process_message(self, peer, mailfrom, rcpttos, data):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
378 from cStringIO import StringIO
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
379 from Mailman import Utils
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
380 from Mailman import Message
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
381 from Mailman import MailList
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
382 # If the message is to a Mailman mailing list, then we'll invoke the
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
383 # Mailman script directly, without going through the real smtpd.
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
384 # Otherwise we'll forward it to the local proxy for disposition.
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
385 listnames = []
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
386 for rcpt in rcpttos:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
387 local = rcpt.lower().split('@')[0]
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
388 # We allow the following variations on the theme
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
389 # listname
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
390 # listname-admin
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
391 # listname-owner
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
392 # listname-request
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
393 # listname-join
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
394 # listname-leave
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
395 parts = local.split('-')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
396 if len(parts) > 2:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
397 continue
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
398 listname = parts[0]
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
399 if len(parts) == 2:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
400 command = parts[1]
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
401 else:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
402 command = ''
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
403 if not Utils.list_exists(listname) or command not in (
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
404 '', 'admin', 'owner', 'request', 'join', 'leave'):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
405 continue
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
406 listnames.append((rcpt, listname, command))
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
407 # Remove all list recipients from rcpttos and forward what we're not
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
408 # going to take care of ourselves. Linear removal should be fine
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
409 # since we don't expect a large number of recipients.
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
410 for rcpt, listname, command in listnames:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
411 rcpttos.remove(rcpt)
16535
084b3dc9b6ff Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 16377
diff changeset
412 # If there's any non-list destined recipients left,
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
413 print >> DEBUGSTREAM, 'forwarding recips:', ' '.join(rcpttos)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
414 if rcpttos:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
415 refused = self._deliver(mailfrom, rcpttos, data)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
416 # TBD: what to do with refused addresses?
21920
59bb43b6eb11 SF #515021, print the refused list to the DEBUGSTREAM, so the parameter is used
Neal Norwitz <nnorwitz@gmail.com>
parents: 20862
diff changeset
417 print >> DEBUGSTREAM, 'we got refusals:', refused
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
418 # Now deliver directly to the list commands
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
419 mlists = {}
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
420 s = StringIO(data)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
421 msg = Message.Message(s)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
422 # These headers are required for the proper execution of Mailman. All
55049
74c0a78114ae Merged revisions 69846 via svnmerge from
Jesus Cea <jcea@jcea.es>
parents: 43659
diff changeset
423 # MTAs in existence seem to add these if the original message doesn't
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
424 # have them.
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
425 if not msg.getheader('from'):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
426 msg['From'] = mailfrom
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
427 if not msg.getheader('date'):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
428 msg['Date'] = time.ctime(time.time())
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
429 for rcpt, listname, command in listnames:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
430 print >> DEBUGSTREAM, 'sending message to', rcpt
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
431 mlist = mlists.get(listname)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
432 if not mlist:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
433 mlist = MailList.MailList(listname, lock=0)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
434 mlists[listname] = mlist
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
435 # dispatch on the type of command
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
436 if command == '':
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
437 # post
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
438 msg.Enqueue(mlist, tolist=1)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
439 elif command == 'admin':
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
440 msg.Enqueue(mlist, toadmin=1)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
441 elif command == 'owner':
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
442 msg.Enqueue(mlist, toowner=1)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
443 elif command == 'request':
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
444 msg.Enqueue(mlist, torequest=1)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
445 elif command in ('join', 'leave'):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
446 # TBD: this is a hack!
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
447 if command == 'join':
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
448 msg['Subject'] = 'subscribe'
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
449 else:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
450 msg['Subject'] = 'unsubscribe'
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
451 msg.Enqueue(mlist, torequest=1)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
452
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
453
20251
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
454
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
455 class Options:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
456 setuid = 1
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
457 classname = 'PureProxy'
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
458
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
459
20251
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
460
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
461 def parseargs():
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
462 global DEBUGSTREAM
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
463 try:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
464 opts, args = getopt.getopt(
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
465 sys.argv[1:], 'nVhc:d',
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
466 ['class=', 'nosetuid', 'version', 'help', 'debug'])
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
467 except getopt.error, e:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
468 usage(1, e)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
469
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
470 options = Options()
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
471 for opt, arg in opts:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
472 if opt in ('-h', '--help'):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
473 usage(0)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
474 elif opt in ('-V', '--version'):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
475 print >> sys.stderr, __version__
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
476 sys.exit(0)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
477 elif opt in ('-n', '--nosetuid'):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
478 options.setuid = 0
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
479 elif opt in ('-c', '--class'):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
480 options.classname = arg
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
481 elif opt in ('-d', '--debug'):
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
482 DEBUGSTREAM = sys.stderr
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
483
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
484 # parse the rest of the arguments
20251
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
485 if len(args) < 1:
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
486 localspec = 'localhost:8025'
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
487 remotespec = 'localhost:25'
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
488 elif len(args) < 2:
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
489 localspec = args[0]
20251
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
490 remotespec = 'localhost:25'
20862
d9b9b5b4815b Two bug fixes for problems reported by Sverre:
Barry Warsaw <barry@python.org>
parents: 20332
diff changeset
491 elif len(args) < 3:
d9b9b5b4815b Two bug fixes for problems reported by Sverre:
Barry Warsaw <barry@python.org>
parents: 20332
diff changeset
492 localspec = args[0]
d9b9b5b4815b Two bug fixes for problems reported by Sverre:
Barry Warsaw <barry@python.org>
parents: 20332
diff changeset
493 remotespec = args[1]
20251
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
494 else:
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
495 usage(1, 'Invalid arguments: %s' % COMMASPACE.join(args))
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
496
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
497 # split into host/port pairs
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
498 i = localspec.find(':')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
499 if i < 0:
20251
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
500 usage(1, 'Bad local spec: %s' % localspec)
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
501 options.localhost = localspec[:i]
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
502 try:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
503 options.localport = int(localspec[i+1:])
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
504 except ValueError:
20251
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
505 usage(1, 'Bad local port: %s' % localspec)
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
506 i = remotespec.find(':')
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
507 if i < 0:
20251
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
508 usage(1, 'Bad remote spec: %s' % remotespec)
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
509 options.remotehost = remotespec[:i]
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
510 try:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
511 options.remoteport = int(remotespec[i+1:])
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
512 except ValueError:
20251
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
513 usage(1, 'Bad remote port: %s' % remotespec)
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
514 return options
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
515
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
516
20251
b0ce92561e07 Script arguments localhost:localport and remotehost:remoteport are now
Barry Warsaw <barry@python.org>
parents: 19235
diff changeset
517
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
518 if __name__ == '__main__':
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
519 options = parseargs()
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
520 # Become nobody
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
521 if options.setuid:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
522 try:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
523 import pwd
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
524 except ImportError:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
525 print >> sys.stderr, \
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
526 'Cannot import module "pwd"; try running with -n option.'
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
527 sys.exit(1)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
528 nobody = pwd.getpwnam('nobody')[2]
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
529 try:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
530 os.setuid(nobody)
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
531 except OSError, e:
16948
faa52f384af6 Use != instead of <>. Sorry, Barry.
Guido van Rossum <guido@python.org>
parents: 16613
diff changeset
532 if e.errno != errno.EPERM: raise
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
533 print >> sys.stderr, \
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
534 'Cannot setuid "nobody"; try running with -n option.'
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
535 sys.exit(1)
32414
fcfb2d4220b0 Allow classes from other modules to be specified at startup. For example,
Skip Montanaro <skip@pobox.com>
parents: 23446
diff changeset
536 classname = options.classname
fcfb2d4220b0 Allow classes from other modules to be specified at startup. For example,
Skip Montanaro <skip@pobox.com>
parents: 23446
diff changeset
537 if "." in classname:
fcfb2d4220b0 Allow classes from other modules to be specified at startup. For example,
Skip Montanaro <skip@pobox.com>
parents: 23446
diff changeset
538 lastdot = classname.rfind(".")
fcfb2d4220b0 Allow classes from other modules to be specified at startup. For example,
Skip Montanaro <skip@pobox.com>
parents: 23446
diff changeset
539 mod = __import__(classname[:lastdot], globals(), locals(), [""])
fcfb2d4220b0 Allow classes from other modules to be specified at startup. For example,
Skip Montanaro <skip@pobox.com>
parents: 23446
diff changeset
540 classname = classname[lastdot+1:]
fcfb2d4220b0 Allow classes from other modules to be specified at startup. For example,
Skip Montanaro <skip@pobox.com>
parents: 23446
diff changeset
541 else:
fcfb2d4220b0 Allow classes from other modules to be specified at startup. For example,
Skip Montanaro <skip@pobox.com>
parents: 23446
diff changeset
542 import __main__ as mod
fcfb2d4220b0 Allow classes from other modules to be specified at startup. For example,
Skip Montanaro <skip@pobox.com>
parents: 23446
diff changeset
543 class_ = getattr(mod, classname)
16377
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
544 proxy = class_((options.localhost, options.localport),
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
545 (options.remotehost, options.remoteport))
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
546 try:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
547 asyncore.loop()
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
548 except KeyboardInterrupt:
0d4b6ba5eeec Long ago, Guido suggested that I add this to the standard library.
Barry Warsaw <barry@python.org>
parents:
diff changeset
549 pass