Created
April 22, 2014 09:09
-
-
Save ag4ve/11171201 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import subprocess | |
import pprint | |
pp = pprint.PrettyPrinter(indent = 4) | |
class FileAttrList: | |
""" | |
Create a list of files and directories and their attributes and libraries | |
The file list should be an array of an arrays with: | |
[[node, username, groupname, mode], ...] | |
import FileAttrList | |
fal = FileAttrList(list) | |
fmt.AddUserMap(dict) | |
fmt.AddGroupMap(dict) | |
filelist = fal.GetList() | |
""" | |
def __init__(self, list): | |
self.inlist = list | |
self.usermap = [] | |
self.groupmap = [] | |
self.outlist = [] | |
def Build(self): | |
""" | |
Compile the list of files and directories recursively (this shouldn't need | |
be run manually). | |
""" | |
self.outlist.extend(self.CheckProps(self.inlist)) | |
self.outlist.extend(self.RecurseTree([i[0] for i in self.inlist])) | |
self.inlist = [] | |
def GetList(self): | |
""" | |
Build and return the compiled list | |
""" | |
self.Build() | |
return self.outlist | |
def AddFiles(self, list): | |
self.inlist.append(list) | |
def CheckProps(self, filelist): | |
""" | |
Assure that user,group,mode is assigned to files and directories passed in. | |
files = fal.CheckProps([files]) | |
""" | |
outlist = [] | |
for attrs in filelist: | |
actual = [None]*4 | |
if type(attrs[0]) == str and len(attrs[0]) > 0: | |
actual[0] = attrs[0] | |
else: | |
continue | |
mode = [None]*4 | |
if os.path.exists(attrs[0]): | |
mode = self.__AddNode(attrs[0]) | |
# UID | |
# If a uid is given in the config | |
if len(attrs) > 1 and type(attrs[1]) == int: | |
actual[1] = attrs[1] | |
# Convert a username to an id | |
elif len(attrs) > 1 and type(attrs[1]) == str and len(attrs[1]) > 0: | |
actual[1] = self.__GetUID(attrs[1]) | |
# If no uid is not given but the file exists | |
elif len(mode) > 1: | |
actual[1] = mode[1] | |
else: | |
continue | |
# GID | |
# If a gid is given in the config | |
if len(attrs) > 2 and type(attrs[2]) == int: | |
actual[2] = attrs[2] | |
# Convert a group name to an id | |
elif len(attrs) > 2 and type(attrs[2]) == str and len(attrs[2]) > 0: | |
actual[2] = self.__GetGID(attrs[2]) | |
# If no gid is not given but the file exists | |
elif len(mode) > 2: | |
actual[2] = mode[2] | |
else: | |
continue | |
# MOD | |
# If a mode is given in the config | |
if len(attrs) > 3 and int(str(attrs[3]), 8): | |
actual[3] = attrs[3] | |
# If no mode is not given but the file exists | |
elif len(mode) > 3 and len(mode[3]) > 0: | |
actual[3] = mode[3] | |
else: | |
continue | |
outlist.append(actual) | |
return outlist | |
def RecurseTree(self, filelist): | |
""" | |
Recurse a list of files and directories going down directories, symlinks, | |
libraries programs are linked against and return a list of (files, libs) | |
list = fal.RecurseTree([list]) | |
""" | |
outlist = [] | |
for filename in filelist: | |
if not os.path.exists(filename): | |
print("HERE1 [%s]" % filename) | |
continue | |
if os.path.isfile(filename): | |
print("HERE2 [%s]" % filename) | |
outlist.append(self.RecurseTree(self.__Ldd([filename]))) | |
continue | |
for root, dirs, files in os.walk(filename): | |
print("HERE2") | |
# loop over directories and files in the path | |
for dir, file in map(lambda *x: x, dirs, files): | |
for node in [dir, file]: | |
if node is None: continue | |
# create a full path | |
filepath = root + '/' + node | |
if os.path.isfile(filepath): | |
outlist.append(self.RecurseTree(self.__Ldd([filepath]))) | |
if os.path.islink(filepath): | |
# per help: symlinks to directories are not treated as directories | |
# so it is easiest just to recurse them and see what we find | |
outlist.append(self.RecurseTree([os.path.realpath(filepath)])) | |
if not self.__InList(filepath) and not name in list: | |
outlist.append(self.__AddNode(filepath)) | |
return outlist | |
# | |
def __AddNode(self, filepath): | |
uid = self.__GetUser(filepath) | |
gid = self.__GetGroup(filepath) | |
mode = str(oct(os.stat(filepath).st_mode - 32768))[2:] | |
return [filepath, uid, gid, mode] | |
def __InList(self, name): | |
for node in self.outlist: | |
if node[0] == name: | |
return node | |
def AddUserMap(self, mapping): | |
""" | |
Add a map for [{username: uid}, ...] | |
fal.AddUserMap(dict) | |
""" | |
if type(mapping) != dict: | |
raise Exception("Must be a dictionary") | |
self.usermap = mapping | |
def AddGroupMap(self, mapping): | |
""" | |
Add a map for [{groupname: gid}, ...] | |
fal.AddGroupMap(dict) | |
""" | |
if type(mapping) != dict: | |
raise Exception("Must be a dictionary") | |
self.groupmap = mapping | |
def __GetUID(self, name): | |
print("in getuid [%s]" %(name)) | |
return self.usermap[str(name)] | |
def __GetGID(self, name): | |
return self.groupmap[str(name)] | |
# Return the UID for a file | |
def __GetUser(self, filepath): | |
return os.stat(filepath).st_uid | |
# Return the GID for a file | |
def __GetGroup(self, filepath): | |
return os.stat(filepath).st_gid | |
# Return a list of libraries that are linked to a program | |
def __Ldd(self, filename): | |
libs = [] | |
for x in filename: | |
p = subprocess.Popen(["ldd", x], | |
universal_newlines=True, | |
stdout=subprocess.PIPE, | |
stderr=subprocess.PIPE) | |
for line in p.stdout: | |
s = line.split() | |
if "=>" in s: | |
if len(s) == 3: # virtual library | |
continue | |
else: | |
libs.append(s[2]) | |
else: | |
if len(s) == 2: | |
libs.append(s[0]) | |
pp.pprint(["ldd", libs]) | |
return libs |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
from textwrap import dedent | |
from FileAttrList import FileAttrList | |
import pprint | |
pp = pprint.PrettyPrinter(indent = 4) | |
def main(): | |
fattr = [ | |
['/testroot', 0, 0, 777], | |
['/bin/dash'] | |
] | |
pp.pprint(["fattr", fattr]) | |
fal = FileAttrList(fattr) | |
filelist = fal.GetList() | |
pp.pprint(["filelist", filelist]) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment