mirror of
https://github.com/python/cpython.git
synced 2026-01-06 15:32:22 +00:00
Script arguments localhost:localport and remotehost:remoteport are now
optional, and default to `localhost' and ports 8025 and 25 respectively. SMTPChannel.__init__(): Calculate __fqdn using socket.getfqdn() instead of gethostby*() and friends. This allows us to run this script even if we don't have access to dns (assuming the localhost is configured properly). Also, restore my precious page breaks. Hands off, oh Whitespace Normalizer!
This commit is contained in:
parent
a645b30294
commit
0e8427e4f2
1 changed files with 28 additions and 18 deletions
46
Lib/smtpd.py
46
Lib/smtpd.py
|
|
@ -1,7 +1,7 @@
|
|||
#! /usr/bin/env python
|
||||
"""An RFC 2821 smtp proxy.
|
||||
|
||||
Usage: %(program)s [options] localhost:port remotehost:port
|
||||
Usage: %(program)s [options] [localhost:localport [remotehost:remoteport]]
|
||||
|
||||
Options:
|
||||
|
||||
|
|
@ -30,8 +30,12 @@
|
|||
|
||||
Version: %(__version__)s
|
||||
|
||||
If localhost is not given then `localhost' is used, and if localport is not
|
||||
given then 8025 is used. If remotehost is not given then `localhost' is used,
|
||||
and if remoteport is not given, then 25 is used.
|
||||
"""
|
||||
|
||||
|
||||
# Overview:
|
||||
#
|
||||
# This file implements the minimal SMTP protocol as defined in RFC 821. It
|
||||
|
|
@ -89,9 +93,10 @@ def flush(self): pass
|
|||
DEBUGSTREAM = Devnull()
|
||||
NEWLINE = '\n'
|
||||
EMPTYSTRING = ''
|
||||
COMMASPACE = ', '
|
||||
|
||||
|
||||
|
||||
|
||||
def usage(code, msg=''):
|
||||
print >> sys.stderr, __doc__ % globals()
|
||||
if msg:
|
||||
|
|
@ -99,7 +104,7 @@ def usage(code, msg=''):
|
|||
sys.exit(code)
|
||||
|
||||
|
||||
|
||||
|
||||
class SMTPChannel(asynchat.async_chat):
|
||||
COMMAND = 0
|
||||
DATA = 1
|
||||
|
|
@ -115,8 +120,7 @@ def __init__(self, server, conn, addr):
|
|||
self.__mailfrom = None
|
||||
self.__rcpttos = []
|
||||
self.__data = ''
|
||||
self.__fqdn = socket.gethostbyaddr(
|
||||
socket.gethostbyname(socket.gethostname()))[0]
|
||||
self.__fqdn = socket.getfqdn()
|
||||
self.__peer = conn.getpeername()
|
||||
print >> DEBUGSTREAM, 'Peer:', repr(self.__peer)
|
||||
self.push('220 %s %s' % (self.__fqdn, __version__))
|
||||
|
|
@ -265,7 +269,7 @@ def smtp_DATA(self, arg):
|
|||
self.push('354 End data with <CR><LF>.<CR><LF>')
|
||||
|
||||
|
||||
|
||||
|
||||
class SMTPServer(asyncore.dispatcher):
|
||||
def __init__(self, localaddr, remoteaddr):
|
||||
self._localaddr = localaddr
|
||||
|
|
@ -313,6 +317,7 @@ def process_message(self, peer, mailfrom, rcpttos, data):
|
|||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
class DebuggingServer(SMTPServer):
|
||||
# Do something with the gathered message
|
||||
def process_message(self, peer, mailfrom, rcpttos, data):
|
||||
|
|
@ -328,7 +333,7 @@ def process_message(self, peer, mailfrom, rcpttos, data):
|
|||
print '------------ END MESSAGE ------------'
|
||||
|
||||
|
||||
|
||||
|
||||
class PureProxy(SMTPServer):
|
||||
def process_message(self, peer, mailfrom, rcpttos, data):
|
||||
lines = data.split('\n')
|
||||
|
|
@ -369,7 +374,7 @@ def _deliver(self, mailfrom, rcpttos, data):
|
|||
return refused
|
||||
|
||||
|
||||
|
||||
|
||||
class MailmanProxy(PureProxy):
|
||||
def process_message(self, peer, mailfrom, rcpttos, data):
|
||||
from cStringIO import StringIO
|
||||
|
|
@ -448,12 +453,13 @@ def process_message(self, peer, mailfrom, rcpttos, data):
|
|||
msg.Enqueue(mlist, torequest=1)
|
||||
|
||||
|
||||
|
||||
|
||||
class Options:
|
||||
setuid = 1
|
||||
classname = 'PureProxy'
|
||||
|
||||
|
||||
|
||||
def parseargs():
|
||||
global DEBUGSTREAM
|
||||
try:
|
||||
|
|
@ -478,32 +484,36 @@ def parseargs():
|
|||
DEBUGSTREAM = sys.stderr
|
||||
|
||||
# parse the rest of the arguments
|
||||
try:
|
||||
if len(args) < 1:
|
||||
localspec = 'localhost:8025'
|
||||
remotespec = 'localhost:25'
|
||||
elif len(args) < 2:
|
||||
localspec = args[0]
|
||||
remotespec = args[1]
|
||||
except IndexError:
|
||||
usage(1, 'Not enough arguments')
|
||||
remotespec = 'localhost:25'
|
||||
else:
|
||||
usage(1, 'Invalid arguments: %s' % COMMASPACE.join(args))
|
||||
|
||||
# split into host/port pairs
|
||||
i = localspec.find(':')
|
||||
if i < 0:
|
||||
usage(1, 'Bad local spec: "%s"' % localspec)
|
||||
usage(1, 'Bad local spec: %s' % localspec)
|
||||
options.localhost = localspec[:i]
|
||||
try:
|
||||
options.localport = int(localspec[i+1:])
|
||||
except ValueError:
|
||||
usage(1, 'Bad local port: "%s"' % localspec)
|
||||
usage(1, 'Bad local port: %s' % localspec)
|
||||
i = remotespec.find(':')
|
||||
if i < 0:
|
||||
usage(1, 'Bad remote spec: "%s"' % remotespec)
|
||||
usage(1, 'Bad remote spec: %s' % remotespec)
|
||||
options.remotehost = remotespec[:i]
|
||||
try:
|
||||
options.remoteport = int(remotespec[i+1:])
|
||||
except ValueError:
|
||||
usage(1, 'Bad remote port: "%s"' % remotespec)
|
||||
usage(1, 'Bad remote port: %s' % remotespec)
|
||||
return options
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
options = parseargs()
|
||||
# Become nobody
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue