#!/usr/bin/env python # # Copyright (C) 2022 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """list_image is a tool that prints out content of an .img file. To print content of an image to stdout: list_image foo.img """ from __future__ import print_function import argparse import os import sys import subprocess class ImageEntry(object): def __init__(self, name, base_dir, is_directory=False): self._name = name self._base_dir = base_dir self._is_directory = is_directory @property def name(self): return self._name @property def full_path(self): return os.path.join(self._base_dir, self._name) @property def is_directory(self): return self._is_directory class Image(object): def __init__(self, debugfs_path, img_path): self._debugfs = debugfs_path self._img_path = img_path def list(self, path): print(path) process = subprocess.Popen([self._debugfs, '-R', 'ls -l -p %s' % path, self._img_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) stdout, _ = process.communicate() res = str(stdout) entries = [] for line in res.split('\n'): if not line: continue parts = line.split('/') if len(parts) != 8: continue name = parts[5] if not name: continue bits = parts[2] is_directory = bits[1] == '4' entries.append(ImageEntry(name, path, is_directory)) for e in sorted(entries, key=lambda e: e.name): yield e if e.is_directory and e.name != '.' and e.name != '..': yield from self.list(path + e.name + '/') def main(argv): parser = argparse.ArgumentParser() debugfs_default = None if 'ANDROID_HOST_OUT' in os.environ: debugfs_default = '%s/bin/debugfs_static' % os.environ['ANDROID_HOST_OUT'] parser.add_argument('--debugfs_path', help='The path to debugfs binary', default=debugfs_default) parser.add_argument('img_path', type=str, help='.img file') args = parser.parse_args(argv) if not args.debugfs_path: print('ANDROID_HOST_OUT environment variable is not defined, --debugfs_path must be set', file=sys.stderr) sys.exit(1) for e in Image(args.debugfs_path, args.img_path).list('./'): if e.is_directory: continue print(e.full_path) if __name__ == '__main__': main(sys.argv[1:])