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 24 25class Node(object): 26 27 def __init__(self, name, label=None): 28 self.name = name 29 self.label = label 30 self.marked = False 31 self.children = {} 32 33 def Find(self, components): 34 if not components: 35 return self 36 37 child = components[0] 38 if child in self.children: 39 return self.children[child].Find(components[1:]) 40 41 n = Node(child) 42 self.children[child] = n 43 return n 44 45 def __iter__(self): 46 for child in self.children.itervalues(): 47 yield self.name + '/' + child.name, child 48 for p, ch in child: 49 yield self.name + '/' + p, ch 50 51 def Mark(self, labels): 52 # Either incorrect label or already marked, we do not need to scan 53 # this path. 54 if self.marked or self.label not in labels: 55 return False 56 57 self.marked = True 58 59 for child in self.children.itervalues(): 60 child.Mark(labels) 61 62 return True 63 64 65def BuildTree(stream=sys.stdin): 66 root = Node("") 67 68 for line in stream: 69 line = line.strip() 70 if not line: 71 continue 72 73 label, path = line.split(' ', 1) 74 # u:object_r:system_data_file:s0 -> system_data_file. 75 sanitized_label = label.split(':')[2] 76 # Strip leading slash. 77 components = path[1:].split('/') 78 79 n = root.Find(components) 80 n.label = sanitized_label 81 return root 82 83 84def main(): 85 parser = argparse.ArgumentParser() 86 parser.add_argument( 87 'labels', metavar='L', type=str, nargs='+', help='labels we want to find') 88 args = parser.parse_args() 89 root = BuildTree() 90 for fullpath, elem in root: 91 if elem.Mark(args.labels): 92 print fullpath 93 94 95if __name__ == '__main__': 96 main() 97