summaryrefslogtreecommitdiff
path: root/smtp.py
diff options
context:
space:
mode:
Diffstat (limited to 'smtp.py')
-rw-r--r--smtp.py126
1 files changed, 86 insertions, 40 deletions
diff --git a/smtp.py b/smtp.py
index c23917b..03019e1 100644
--- a/smtp.py
+++ b/smtp.py
@@ -24,6 +24,12 @@ class SMTPChannel(asynchat.async_chat):
self.server.logger.debug("Write: " + data)
asynchat.async_chat.push(self,data)
+ def log(self, message):
+ self.server.logger.info(message)
+
+ def log_info(self, message, type='info'):
+ self.server.logger.error("%s %s" % (type, message))
+
def handle_close(self):
asynchat.async_chat.handle_close(self)
if self.read_data and len(self.data) > 10:
@@ -68,23 +74,23 @@ class SMTPChannel(asynchat.async_chat):
class SMTPServer(asyncore.dispatcher):
- def __init__(self):
+ def __init__(self,interface,maildir_dir):
asyncore.dispatcher.__init__(self)
self.port = 25
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
- self.bind(("", self.port))
+ self.bind((interface, self.port))
self.listen(5)
- self.maildir = mailbox.Maildir("Maildir", create=True)
- self.logger = logging.getLogger('MyLogger')
+ self.maildir = mailbox.Maildir(maildir_dir, create=True)
+ self.logger = logging.getLogger('smtplogger')
self.logger.setLevel(logging.DEBUG)
handler = logging.handlers.TimedRotatingFileHandler("log/smtp.log", "D", 1)
self.logger.addHandler(handler)
def handle_accept(self):
conn, addr = self.accept()
- self.logger.info("New Client %s:%s" % conn.getpeername())
try:
+ self.logger.info("New Client %s:%s" % conn.getpeername())
SMTPChannel(self, conn, addr)
except Exception,e:
self.logger.error(str(e))
@@ -92,43 +98,83 @@ class SMTPServer(asyncore.dispatcher):
if __name__ == '__main__':
- s = SMTPServer()
-
- #user change
- pwinfo = pwd.getpwnam('nobody')
- os.setregid(pwinfo[3],pwinfo[3])
- os.setreuid(pwinfo[2],pwinfo[2])
+ import getopt
+ def usage():
+ print """smtp.py
+-d debug
+-f foreground (no fork, no user changing)
+-u USER setuserid to USER, else "nobody", see -f
+-m MAILDIR set maildir path, else "Maildir/"
+-s ADDR Bind to interface with ip ADDR, else 0.0.0.0
+-h help"""
- #"Robustly turn into a UNIX daemon, running in our_home_dir."
- # First fork
try:
- if os.fork() > 0:
- sys.exit(0) # kill off parent
- except OSError, e:
- sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror))
- sys.exit(1)
- os.setsid()
- os.chdir('/')
- os.umask(0)
-
- # Second fork
- try:
- pid = os.fork()
- if pid > 0:
- os._exit(0)
- except OSError, e:
- sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror))
- os._exit(1)
-
- si = open('/dev/null', 'r')
- so = open('/dev/null', 'a+', 0)
- se = open('/dev/null', 'a+', 0)
- os.dup2(si.fileno(), sys.stdin.fileno())
- os.dup2(so.fileno(), sys.stdout.fileno())
- os.dup2(se.fileno(), sys.stderr.fileno())
- # Set custom file descriptors so that they get proper buffering.
- sys.stdout, sys.stderr = so, se
- #"""
+ opts, args = getopt.getopt(sys.argv[1:], "dfu:s:m:h")
+ except getopt.GetoptError, err:
+ print str(err)
+ usage();
+ sys.exit(2)
+
+ debug = False
+ foreground = False
+ user = "nobody"
+ maildir_dir = "Maildir"
+ interface = "0.0.0.0"
+ for o, a in opts:
+ if o == "-d":
+ debug = True
+ elif o == "-f":
+ foreground = True
+ elif o == "-u":
+ user = a
+ elif o == "-m":
+ maildir_dir = a
+ elif o == "-s":
+ interface = a
+ elif o == "-h":
+ usage()
+ sys.exit(0);
+ else:
+ assert False, "unhandled option:" + o
+
+ s = SMTPServer(interface, maildir_dir)
+
+ if not foreground:
+ #user change
+ pwinfo = pwd.getpwnam(user)
+ os.setregid(pwinfo[3],pwinfo[3])
+ os.setreuid(pwinfo[2],pwinfo[2])
+
+ #"Robustly turn into a UNIX daemon, running in our_home_dir."
+ # First fork
+ try:
+ if os.fork() > 0:
+ sys.exit(0) # kill off parent
+ except OSError, e:
+ sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror))
+ sys.exit(1)
+ os.setsid()
+ os.chdir('/')
+ os.umask(0)
+
+ # Second fork
+ try:
+ pid = os.fork()
+ if pid > 0:
+ os._exit(0)
+ except OSError, e:
+ sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror))
+ os._exit(1)
+
+ si = open('/dev/null', 'r')
+ so = open('/dev/null', 'a+', 0)
+ se = open('/dev/null', 'a+', 0)
+ os.dup2(si.fileno(), sys.stdin.fileno())
+ os.dup2(so.fileno(), sys.stdout.fileno())
+ os.dup2(se.fileno(), sys.stderr.fileno())
+ # Set custom file descriptors so that they get proper buffering.
+ sys.stdout, sys.stderr = so, se
+ #"""
s.logger.info("Startup; pid=%s" % os.getpid())
asyncore.loop()