Dennis Lee Bieber wrote: > On Mon, 27 Jun 2005 13:26:12 +0200, Fredrik Normann <[EMAIL PROTECTED]> > 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 -- http://mail.python.org/mailman/listinfo/python-list