121 lines
4.3 KiB
Python
121 lines
4.3 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
import os
|
|
|
|
|
|
def scanfs(file) -> dict:
|
|
filesystem_config = {}
|
|
with open(file, "r") as file_:
|
|
for i in file_.readlines():
|
|
filepath, *other = i.strip().split()
|
|
filesystem_config[filepath] = other
|
|
if long := len(other) > 4:
|
|
print(f"[Warn] {i[0]} has too much data-{long}.")
|
|
return filesystem_config
|
|
|
|
|
|
def scan_dir(folder) -> list:
|
|
allfiles = ['/']
|
|
if os.name == 'nt':
|
|
yield os.path.basename(folder).replace('\\', '')
|
|
elif os.name == 'posix':
|
|
yield os.path.basename(folder).replace('/', '')
|
|
else:
|
|
return ''
|
|
for root, dirs, files in os.walk(folder, topdown=True):
|
|
for dir_ in dirs:
|
|
yield os.path.join(root, dir_).replace(folder, os.path.basename(folder)).replace('\\', '/')
|
|
for file in files:
|
|
yield os.path.join(root, file).replace(folder, os.path.basename(folder)).replace('\\', '/')
|
|
for rv in allfiles:
|
|
yield rv
|
|
|
|
|
|
def islink(file) -> str and None:
|
|
if os.name == 'nt':
|
|
if not os.path.isdir(file):
|
|
with open(file, 'rb') as f:
|
|
if f.read(12) == b'!<symlink>\xff\xfe':
|
|
return f.read().decode("utf-8").replace('\x00', '')
|
|
else:
|
|
return
|
|
elif os.name == 'posix':
|
|
if os.path.islink(file):
|
|
return os.readlink(file)
|
|
else:
|
|
return
|
|
|
|
|
|
def fs_patch(fs_file, dir_path) -> tuple: # 接收两个字典对比
|
|
new_fs = {}
|
|
new_add = 0
|
|
r_fs = {}
|
|
print("FsPatcher: Load origin %d" % (len(fs_file.keys())) + " entries")
|
|
for i in scan_dir(os.path.abspath(dir_path)):
|
|
if fs_file.get(i):
|
|
new_fs[i] = fs_file[i]
|
|
else:
|
|
if r_fs.get(i):
|
|
continue
|
|
if os.name == 'nt':
|
|
filepath = os.path.abspath(dir_path + os.sep + ".." + os.sep + i.replace('/', '\\'))
|
|
elif os.name == 'posix':
|
|
filepath = os.path.abspath(dir_path + os.sep + ".." + os.sep + i)
|
|
else:
|
|
filepath = os.path.abspath(dir_path + os.sep + ".." + os.sep + i)
|
|
if os.path.isdir(filepath):
|
|
uid = '0'
|
|
if "system/bin" in i or "system/xbin" in i or "vendor/bin" in i:
|
|
gid = '2000'
|
|
else:
|
|
gid = '0'
|
|
mode = '0755' # dir path always 755
|
|
config = [uid, gid, mode]
|
|
elif islink(filepath):
|
|
uid = '0'
|
|
if ("system/bin" in i) or ("system/xbin" in i) or ("vendor/bin" in i):
|
|
gid = '2000'
|
|
else:
|
|
gid = '0'
|
|
if ("/bin" in i) or ("/xbin" in i):
|
|
mode = '0755'
|
|
elif ".sh" in i:
|
|
mode = "0750"
|
|
else:
|
|
mode = "0644"
|
|
link = islink(filepath)
|
|
config = [uid, gid, mode, link]
|
|
elif ("/bin" in i) or ("/xbin" in i):
|
|
uid = '0'
|
|
mode = '0755'
|
|
if ("system/bin" in i) or ("system/xbin" in i) or ("vendor/bin" in i):
|
|
gid = '2000'
|
|
else:
|
|
gid = '0'
|
|
mode = '0755'
|
|
if ".sh" in i:
|
|
mode = "0750"
|
|
else:
|
|
for s in ["/bin/su", "/xbin/su", "disable_selinux.sh", "daemon", "ext/.su", "install-recovery",
|
|
'installed_su', 'bin/rw-system.sh', 'bin/getSPL']:
|
|
if s in i:
|
|
mode = "0755"
|
|
config = [uid, gid, mode]
|
|
else:
|
|
uid = '0'
|
|
gid = '0'
|
|
mode = '0644'
|
|
config = [uid, gid, mode]
|
|
print(f'Add [{i}{config}]')
|
|
r_fs[i] = 1
|
|
new_add += 1
|
|
new_fs[i] = config
|
|
return new_fs, new_add
|
|
|
|
|
|
def main(dir_path, fs_config) -> None:
|
|
new_fs, new_add = fs_patch(scanfs(os.path.abspath(fs_config)), dir_path)
|
|
with open(fs_config, "w", encoding='utf-8', newline='\n') as f:
|
|
f.writelines([i + " " + " ".join(new_fs[i]) + "\n" for i in sorted(new_fs.keys())])
|
|
print('FsPatcher: Add %d' % new_add + " entries")
|