Reading files in /var/spool/rwho/whod.*
Fredrik Normann
fredrin at ifi.uio.no
Thu Jun 30 04:57:16 EDT 2005
Dennis Lee Bieber wrote:
> On Mon, 27 Jun 2005 13:26:12 +0200, Fredrik Normann <fredrin at ifi.uio.no>
> declaimed the following in comp.lang.python:
>
>
>>Hello,
>>
>>I'm trying to read the binary files under /var/spool/rwho/ so I'm wondering if
>>anyone has done that before or could give me some clues on how to read those
>>files. I've tried to use the binascii module without any luck.
>>
>
> Have you looked at the struct module?
>
Thanks for the tip. A friend of mine helped me with making this small script:
#!/usr/bin/env python
"""whod file parser.
Made by: Igor V. Rafienko
This tiny script tries to grock whod files.
"""
from struct import calcsize, unpack, pack
from socket import ntohl
import time
outmp_format = '8s8s4s'
whoent_format = '%ds4s' % calcsize(outmp_format)
almost_whod = 'cc2s4s4s32s12s4s'
def make_string(s):
"""Stupid C. Chop the string off at the first '\0'."""
index = s.find('\0')
if index != -1:
return s[:index]
# fi
# end make_string
def make_time(seconds):
"""Convert from seconds since Epoch to ISO8601."""
return time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime(seconds))
# end make_time
def make_int(binary):
"""Convert binary from network representation to host int."""
assert len(binary) == 4, "ints are 4 bytes long here"
if calcsize("i") == 4:
return ntohl(unpack("i", binary)[0])
elif calcsize("l") == 4:
return ntohl(unpack("l", binary)[0])
else:
raise "Dammit! no suitable integral type"
# fi
# end make_int
def parse_one_outmp(binary_data):
"""Parse an outmp struct."""
out_line, out_name, out_time = unpack(outmp_format, binary_data)
out_time = make_int(out_time)
return out_line, out_name, out_time
# end parse_one_outmp
def parse_one_whoent(binary_data):
"""Parse a whoent struct."""
outmp_part, we_idle = unpack(whoent_format, binary_data)
we_idle = make_int(we_idle)
out_line, out_name, out_time = parse_one_outmp(outmp_part)
return out_line, out_name, out_time, we_idle
# end parse_one_whoent
def parse_one_file(binary_data):
"""Parse the entire thing."""
# First we parse everything, except for the whoent-array
prefix = unpack(almost_whod, binary_data[:calcsize(almost_whod)])
print "prefix has %d elemenets" % len(prefix)
print "wd_vers:", ord(prefix[0])
print "wd_type:", ord(prefix[1])
print "wd_fill:", make_string(prefix[2])
print "wd_sendtime:", make_time(make_int(prefix[3]))
print "wd_recvtime:", make_time(make_int(prefix[4]))
print "wd_host: ", make_string(prefix[5])
load = prefix[6]
print "wd_load avg: %d, %d, %d" % tuple([make_int(x) for x in
(load[:4], load[4:8], load[8:])])
print "wd_boottime", make_time(make_int(prefix[7]))
sz = calcsize(whoent_format)
array_data = binary_data[calcsize(almost_whod):]
assert len(array_data) % sz == 0, "Aiee! corrupt chunk?"
whoent_chunks = [ array_data[sz*x:sz*(x+1)] for x in range(len(array_data)
/ sz) ]
print "%d whoent chunks" % len(whoent_chunks)
for out_line, out_name, out_time, we_idle in [parse_one_whoent(x)
for x in whoent_chunks]:
print "\tout_line:", make_string(out_line)
print "\tout_name:", make_string(out_name)
print "\tout_time:", make_time(out_time)
print "\twe_idle:", we_idle
# od
# end parse_one_file
More information about the Python-list
mailing list