# HG changeset patch # User Tero Marttila # Date 1206059853 -7200 # Node ID 2d33d62cd8f80e0084b675ecd37c2c0090172103 # Parent 687b797f709ccde31fcf488a1d2746d3091e4f41 fix utmp.py, it's a proper module, doesn't tightloop and OOM, etc committer: Tero Marttila diff -r 687b797f709c -r 2d33d62cd8f8 utmp.py --- a/utmp.py Fri Mar 21 02:06:52 2008 +0200 +++ b/utmp.py Fri Mar 21 02:37:33 2008 +0200 @@ -1,10 +1,24 @@ +from twisted.internet import protocol, reactor +from twisted.python import log import socket, os, time -import _utmp +import _utmp, api, sys + +POLL_INTERVAL = 5 + +def getPidCmd (pid) : + try : + fh = open("/proc/%d/cmdline" % pid, "r") + cmdline = fh.read() + fh.close() + + return repr("%d:%s" % (pid, cmdline)) + except IOError, OSError : + return "[%d]" % pid class WtmpEntry (object) : _ATTRS = ( - "type", "pid", "line", "id", "user", "host", "exit", "session", "tv", "addr_v6" + "type", "pid", "line", "id", "user", "host", "exit", "session", "tv", "addr" ) @staticmethod @@ -19,12 +33,22 @@ wtmp = WtmpEntry() for name, field in zip(wtmp._ATTRS, result) : - if isinstance(field, str) and name not in ("addr_v6", ) : + if isinstance(field, str) and name not in ("addr", ) : field = field.rstrip("\0") setattr(wtmp, name, field) - wtmp.addr_v6 = socket.inet_ntop(socket.AF_INET6, wtmp.addr_v6) + # convert the address + family = socket.AF_INET + addr = wtmp.addr[0:4] + for byte in wtmp.addr[4:] : + if byte : + family = socket.AF_INET6 + addr = wtmp.addr + break + + wtmp.addr = socket.inet_ntop(family, addr) + wtmp.pid = getPidCmd(wtmp.pid) return wtmp @@ -66,6 +90,36 @@ for item in read_entries(fh) : print item +class WtmpModule (api.Module) : + name = "wtmp" + version = 0x0001 + + event_types = [ + "wtmp", + ] + + def handleConnect (self) : + log.msg("Following default wtmp file...") + + self.wtmp = WtmpFile() + + log.msg("Starting poll timer") + + self.poll() + + log.msg("Running") + + def poll (self) : + + while True : + item = self.wtmp.tryRead() + + if item : + log.msg(" -- %s" % item) + self.sendEvent("wtmp", str(item)) + else : + return reactor.callLater(POLL_INTERVAL, self.poll) + if __name__ == '__main__' : - follow_main() + WtmpModule().run()