-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathimmutable.py
More file actions
executable file
·75 lines (64 loc) · 2.67 KB
/
immutable.py
File metadata and controls
executable file
·75 lines (64 loc) · 2.67 KB
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#!/usr/bin/env python3
#
# Author: Jim Clausing
#
import os
import subprocess
import argparse
import shutil
import sys
__version_info__ = (0, 1, 0)
__version__ = ".".join(map(str, __version_info__))
def check_lsattr_exists():
if not shutil.which('lsattr'):
print("Error: 'lsattr' command not found. Please ensure it is installed and available in your PATH.")
sys.exit(1)
def is_immutable(file_path):
try:
# Run the lsattr command and capture the output
lsattr = shutil.which('lsattr')
result = subprocess.run([lsattr, file_path], capture_output=True, text=True, check=True)
# The immutable attribute is represented by an 'i'
return 'i' in result.stdout.split()[0]
except subprocess.CalledProcessError:
# If lsattr fails, we assume the file is not immutable
return False
def search_immutable_files(directory, recursive, follow_symlinks):
immutable_files = []
if recursive:
for root, _, files in os.walk(directory):
for file in files:
file_path = os.path.join(root, file)
if is_immutable(file_path):
immutable_files.append(file_path)
else:
for item in os.listdir(directory):
file_path = os.path.join(directory, item)
if os.path.isfile(file_path) or (follow_symlinks and os.path.islink(file_path)):
if is_immutable(file_path):
immutable_files.append(file_path)
return immutable_files
def main():
check_lsattr_exists()
parser = argparse.ArgumentParser(description="Search for immutable files.")
parser.add_argument('paths', metavar='PATH', type=str, nargs='+', help='Path to file or directory')
parser.add_argument('-r', '--recursive', action='store_true', help='Recursively search directories')
parser.add_argument('-f', '--fullpath', action='store_true', help='Print full path rather than relative')
parser.add_argument('-l', '--follow-symlinks', action='store_true', help='Follow symbolic links')
args = parser.parse_args()
immutable_files = []
for path in args.paths:
if args.fullpath:
path = os.path.abspath(path)
if os.path.isfile(path) or (args.follow_symlinks and os.path.islink(path)):
if is_immutable(path):
immutable_files.append(path)
elif os.path.isdir(path):
immutable_files.extend(search_immutable_files(path, args.recursive, args.follow_symlinks))
else:
print(f"Path '{path}' is neither a file nor a directory.")
if immutable_files:
for file in immutable_files:
print(file)
if __name__ == "__main__":
main()