1#!/usr/bin/env python
2#
3# Copyright 2017 - The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16"""debugfs-related utilities."""
17
18import logging
19import os
20import re
21
22from gsi_util.utils.cmd_utils import run_command
23
24_DEBUGFS = 'debugfs'
25
26
27def dump(image_file, file_spec, out_file):
28  """Dumps the content of the file file_spec to the output file out_file.
29
30  Args:
31    image_file: The image file to be query.
32    file_spec: The full file/directory in the image_file to be copied.
33    out_file: The output file name in the local directory.
34  Returns:
35    True if 'debugfs' command success. False otherwise.
36  """
37  debugfs_command = 'dump {} {}'.format(file_spec, out_file)
38  run_command([_DEBUGFS, '-R', debugfs_command, image_file], log_stderr=True)
39  if not os.path.isfile(out_file):
40    logging.debug('debugfs failed to dump the file %s', file_spec)
41    return False
42
43  return True
44
45
46def get_type(image_file, file_spec):
47  """Gets the type of the given file_spec.
48
49  Args:
50    image_file: The image file to be query.
51    file_spec: The full file/directory in the image_file to be query.
52  Returns:
53    None if file_spec does not exist.
54    'regular' if file_spec is a file.
55    'directory' if file_spec is a directory.
56  """
57  debugfs_command = 'stat {}'.format(file_spec)
58  _, output, error = run_command(
59      [_DEBUGFS, '-R', debugfs_command, image_file],
60      read_stdout=True,
61      read_stderr=True,
62      log_stderr=True)
63  if re.search('File not found', error):
64    logging.debug('get_type() returns None')
65    return None
66
67  # Search the "type:" field in the output, it should be 'regular' (for a file)
68  # or 'directory'
69  m = re.search('Type:\\s*([^\\s]+)', output)
70  assert m is not None, '{} outputs with an unknown format.'.format(_DEBUGFS)
71
72  ret = m.group(1)
73  logging.debug('get_type() returns \'%s\'', ret)
74
75  return ret
76