import typing from binascii import hexlify from struct import pack, unpack from .blobs import db_write_enable from .flash import call_cleanups from .sid import SidIdentity, sid_from_bytes from .tls import tls from .util import assert_status from .fingerprint_constants import finger_names class UserStorage: def __init__(self, dbid: int, name: str): self.dbid = dbid self.name = name self.users = [] def __repr__(self): return '' % (self.dbid, repr( self.name), repr(self.users)) class User: def __init__(self, dbid: int, identity: str): self.dbid = dbid self.identity = identity self.fingers: typing.List[typing.Mapping[str, int]] = [] def __repr__(self): return '' % (self.dbid, repr( self.identity), repr(self.fingers)) def subtype_to_string(s: int): finger_name = finger_names.get(s, None) return finger_name or 'Unknown' def parse_user_storage(rsp: bytes): rc, = unpack(' 0: raise Exception('Junk at the end of the storage info response: %s' % rsp.hex()) storage = UserStorage(recid, name) while len(usrtab) > 0: rec, usrtab = usrtab[:4], usrtab[4:] urid, valsz = unpack(' 0: raise Exception('Junk at the end of the user info response: %s' % rsp.hex()) identity = parse_identity(identity) user = User(recid, identity) while len(fingertab) > 0: rec, fingertab = fingertab[:8], fingertab[8:] frid, subtype, stgid, valsz = unpack('' % ( self.dbid, self.type, self.storage, repr(self.value), repr(self.children)) class Db: class Info: def __init__(self, total: int, used: int, free: int, records: int, roots): self.total = total # partition size self.used = used # used (not deleted) self.free = free # unallocated space self.records = records # total number, including deleted self.roots = roots def __repr__(self): return 'Db.Info(total=%d, used=%d, free=%d, records=%d, roots=%s)' % ( self.total, self.used, self.free, self.records, repr(self.roots)) def get_user_storage(self, dbid=0, name=''): name = name.encode() if len(name) > 0: name += b'\0' return parse_user_storage(tls.cmd(pack(' typing.Optional[User]: stg = self.get_user_storage(name='StgWindsor') data = identity_to_bytes(identity) rsp = tls.cmd(pack(' 80: val = val[:80] + '...' print('%s%d (type %d) %s' % (' ' * depth, rec.dbid, rec.type, val)) rec = self.get_record_children(root) for c in rec.children: self.dump_raw(c['dbid'], depth + 1) def dump_all(self): stg = self.get_user_storage(name='StgWindsor') usrs = [self.get_user(u['dbid']) for u in stg.users] for u in usrs: print('%2d: User %s with %d fingers:' % (u.dbid, repr(u.identity), len(u.fingers))) for f in u.fingers: print(' %2d: %02x (%s)' % (f['dbid'], f['subtype'], subtype_to_string(f['subtype']))) db = Db()