import struct, sys def read(off, n): with open('/dev/sda3', 'rb', buffering=0) as f: f.seek(off) return f.read(n) sb = read(1024, 1024) BS = 1024 << struct.unpack_from('= 32 else 32 def inode(ino): grp = (ino - 1) // ipg idx = (ino - 1) % ipg desc = read((fdb + 1) * BS + grp * dsz2, 64) itab = struct.unpack_from('= 64: itab |= struct.unpack_from(' len(node): break if depth == 0: eblk, elen, ehi, elo = struct.unpack_from('= size: break return data[:size] def dirents(ino): res = [] for pb in blocks(ino): blk = read(pb * BS, BS) off = 0 while off + 8 <= len(blk): e_ino, reclen, namelen, ftype = struct.unpack_from(' len(blk): break if e_ino: res.append((blk[off + 8:off + 8 + namelen].decode('latin1'), e_ino, ftype)) off += reclen return res def lookup(path): ino = 2 for part in path.strip('/').split('/'): f = None for nm, i, t in dirents(ino): if nm == part: f = i break if f is None: return None ino = f return ino if __name__ == '__main__': if len(sys.argv) < 2: print("Usage: pathread.py [tail_bytes]") sys.exit(1) p = sys.argv[1] tail = int(sys.argv[2]) if len(sys.argv) > 2 else 4000 ino = lookup(p) print('== %s ino=%s ==' % (p, ino), flush=True) if ino: data = readfile(ino) print(data[-tail:].decode('latin1'), flush=True)