fixbot/utmp.py
author Tero Marttila <terom@fixme.fi>
Fri, 05 Feb 2010 21:48:14 +0200
changeset 58 31a17b0b5159
parent 21 aa6df8f9c44a
permissions -rw-r--r--
remove concept of event_types, the event.type is now just sent as a string
21
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
     1
from twisted.internet import protocol, reactor
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
     2
from twisted.python import log
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
     3
import socket, os, time
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
     4
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
     5
import _utmp, api, sys
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
     6
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
     7
POLL_INTERVAL = 5
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
     8
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
     9
def getPidCmd (pid) :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    10
    try :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    11
        fh = open("/proc/%d/cmdline" % pid, "r")
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    12
        cmdline = fh.read()
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    13
        fh.close()
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    14
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    15
        return repr("%d:%s" % (pid, cmdline))
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    16
    except IOError, OSError :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    17
        return "[%d]" % pid
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    18
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    19
class WtmpEntry (object) :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    20
    _ATTRS = (
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    21
        "type", "pid", "line", "id", "user", "host", "exit", "session", "tv", "addr"
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    22
    )
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    23
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    24
    @staticmethod
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    25
    def fromFile (file) :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    26
        bytes = file.read(_utmp.size())
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    27
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    28
        if not bytes :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    29
            return
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    30
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    31
        result = _utmp.parse(bytes)
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    32
        
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    33
        wtmp = WtmpEntry()
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    34
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    35
        for name, field in zip(wtmp._ATTRS, result) :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    36
            if isinstance(field, str) and name not in ("addr", ) :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    37
                field = field.rstrip("\0")
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    38
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    39
            setattr(wtmp, name, field)
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    40
        
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    41
        # convert the address
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    42
        family = socket.AF_INET
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    43
        addr = wtmp.addr[0:4]
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    44
        for byte in wtmp.addr[4:] :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    45
            if byte :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    46
                family = socket.AF_INET6
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    47
                addr = wtmp.addr
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    48
                break
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    49
        
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    50
        wtmp.addr = socket.inet_ntop(family, addr)
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    51
        wtmp.pid = getPidCmd(wtmp.pid)
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    52
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    53
        return wtmp
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    54
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    55
    def __str__ (self) :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    56
        return " ".join("%s=%s" % (key, getattr(self, key)) for key in self._ATTRS)
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    57
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    58
class WtmpFile (object) :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    59
    def __init__ (self, path="/var/log/wtmp") :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    60
        self.path = path
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    61
        self.file = open(path)
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    62
        self.file.seek(0, os.SEEK_END)
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    63
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    64
    def tryRead (self) :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    65
        return WtmpEntry.fromFile(self.file)
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    66
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    67
def read_entries (file) :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    68
    while True :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    69
        wtmp = read_entry(file)
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    70
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    71
        if wtmp :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    72
            yield wtmp
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    73
        else :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    74
            return
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    75
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    76
def follow_main () :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    77
    wtmp = WtmpFile()
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    78
    
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    79
    while True :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    80
        item = wtmp.tryRead()
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    81
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    82
        if item :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    83
            print item
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    84
        else :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    85
            time.sleep(2)
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    86
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    87
def test_main () :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    88
    fh = open("/var/log/wtmp", "r")
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    89
    
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    90
    for item in read_entries(fh) :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    91
        print item
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    92
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    93
class WtmpModule (api.Module) :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    94
    name = "wtmp"
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    95
    version = 0x0001
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    96
    
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    97
    def handleConnect (self) :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    98
        log.msg("Following default wtmp file...")
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
    99
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
   100
        self.wtmp = WtmpFile()
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
   101
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
   102
        log.msg("Starting poll timer")
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
   103
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
   104
        self.poll()
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
   105
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
   106
        log.msg("Running")
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
   107
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
   108
    def poll (self) :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
   109
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
   110
        while True :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
   111
            item = self.wtmp.tryRead()
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
   112
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
   113
            if item :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
   114
                log.msg(" -- %s" % item)
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
   115
                self.sendEvent("wtmp", str(item))
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
   116
            else :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
   117
                return reactor.callLater(POLL_INTERVAL, self.poll)
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
   118
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
   119
if __name__ == '__main__' :
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
   120
    WtmpModule().run()
aa6df8f9c44a add initial code back under fixbot/, the git-convert somehow broke
terom@fixme.fi
parents:
diff changeset
   121