#!/usr/bin/env python

from twisted.internet.protocol import ClientFactory
from twisted.protocols.basic import LineReceiver
from twisted.internet import defer, task
import sys
from twisted.internet import epollreactor
epollreactor.install()
from twisted.internet import reactor
reactor.suggestThreadPoolSize(6)

#############################################
class SMTPClient(LineReceiver):
    def lineReceived(self, line):
        ip =  self.transport.getPeer().host,
        self.factory.scanFinished(ip[0] + " " + line)
        self.transport.loseConnection()
#############################################
class SMTPClientFactory(ClientFactory):
    protocol = SMTPClient
    def __init__(self, deferred):
        self.deferred = deferred
    def scanFinished(self, banner):
        if self.deferred is not None:
            d, self.deferred = self.deferred, None
            d.callback(banner)
    def clientConnectionFailed(self, connector, reason):
        if self.deferred is not None:
            d, self.deferred = self.deferred, None
            d.errback(reason)

succeFD = open( "succe.txt", 'a')
faildFD = open("faild.txt", 'a')
#############################################
def getResult(result,mx):
    succeFD.write(mx+'\t'+result+'\n')
    succeFD.flush()
def getError(reason,mx):
    err = reason.getErrorMessage()
    faildFD.write(mx+'\t'+err+'\n')
    faildFD.flush()
#############################################    
def doWork():
    i = 1
    fp = file("smtp.log", 'w')
    for mx in file("mx.short.txt"):
        mx = mx.strip().split()[0]
        d = defer.Deferred()
        factory = SMTPClientFactory(d)
        c = reactor.connectTCP(mx,25,factory)
        d.addCallback(getResult,mx)
        d.addErrback(getError,mx)
        logRecord = "%d\t%s\n" %(i, mx)
        i += 1
        fp.write(logRecord)
        fp.flush()
        yield d
def finish(igo):
    reactor.callLater(5, reactor.stop)
#############################################
def taskRun():
    deferreds = []
    coop = task.Cooperator()
    work = doWork()
    maxRun = 2000
    for i in xrange(maxRun):
        d = coop.coiterate(work)
        deferreds.append(d)
    dl = defer.DeferredList(deferreds)
    dl.addCallback(finish)
#############################################
def main():
    taskRun()
    reactor.run()
if __name__ == '__main__':
    main()
