-
Notifications
You must be signed in to change notification settings - Fork 1
/
pacmods.py
executable file
·58 lines (45 loc) · 1.5 KB
/
pacmods.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#!/usr/bin/python3
import contextlib
import hashlib
import os
import os.path
import sys
import pyalpm
DIRS = "/etc", "/usr/local/etc"
SKIP_DIRS = {
"/etc/ssl": ("certs",),
"/etc/ca-certificates": ("extracted",)
}
BUFSIZE = 65536
def errprint(s):
print(s, file=sys.stderr)
def main():
allpaths = set()
for pkg in pyalpm.Handle("/", "/var/lib/pacman").get_localdb().pkgcache:
for path, db_md5 in pkg.backup:
md5 = hashlib.md5()
try:
f = open(f"/{path}", "rb", BUFSIZE)
except FileNotFoundError:
if path in (p for p, _, _ in pkg.files):
print(f"D /{path} ({pkg.name})")
except PermissionError as e:
errprint(f"{e} ({pkg.name})")
else:
for chunk in iter(lambda: f.read(BUFSIZE), b""):
md5.update(chunk)
f.close()
if md5.hexdigest() != db_md5:
print(f"M /{path} ({pkg.name})")
allpaths.update(f"/{path}" for path, _, _ in pkg.files)
for top in DIRS:
for dirpath, dirnames, filenames in os.walk(top, onerror=errprint):
for d in SKIP_DIRS.get(dirpath, ()):
with contextlib.suppress(ValueError):
dirnames.remove(d)
for fn in filenames:
path = os.path.join(dirpath, fn)
if path not in allpaths:
print(f"A {path}")
if __name__ == "__main__":
main()