1#!/usr/bin/env python 2# Copyright (C) 2018 The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16# Takes output of 17# adb shell 'find /data -print0 | xargs -0 ls -ldZ' | awk '{print $5 " " $9}' 18# in standard input and generates list of directories we need to scan to cover 19# the labels given on the command line. 20 21import sys 22import argparse 23 24class Node(object): 25 def __init__(self, name, label=None): 26 self.name = name 27 self.label = label 28 self.marked = False 29 self.children = {} 30 31 def Find(self, components): 32 if not components: 33 return self 34 35 child = components[0] 36 if child in self.children: 37 return self.children[child].Find(components[1:]) 38 39 n = Node(child) 40 self.children[child] = n 41 return n 42 43 def __iter__(self): 44 for child in self.children.itervalues(): 45 yield self.name + '/' + child.name, child 46 for p, ch in child: 47 yield self.name + '/' + p, ch 48 49 def Mark(self, labels): 50 # Either incorrect label or already marked, we do not need to scan 51 # this path. 52 if self.marked or self.label not in labels: 53 return False 54 55 self.marked = True 56 57 for child in self.children.itervalues(): 58 child.Mark(labels) 59 60 return True 61 62 63def BuildTree(stream=sys.stdin): 64 root = Node("") 65 66 for line in stream: 67 line = line.strip() 68 if not line: 69 continue 70 71 label, path = line.split(' ', 1) 72 # u:object_r:system_data_file:s0 -> system_data_file. 73 sanitized_label = label.split(':')[2] 74 # Strip leading slash. 75 components = path[1:].split('/') 76 77 n = root.Find(components) 78 n.label = sanitized_label 79 return root 80 81 82def main(): 83 parser = argparse.ArgumentParser() 84 parser.add_argument('labels', metavar='L', type=str, nargs='+', 85 help='labels we want to find') 86 args = parser.parse_args() 87 root = BuildTree() 88 for fullpath, elem in root: 89 if elem.Mark(args.labels): 90 print fullpath 91 92 93if __name__ == '__main__': 94 main() 95