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