Mini Shell
#!/opt/imh-python/bin/python3
"""Fraud Hunter Tool for Chuck H."""
import multiprocessing
import argparse
import os
import signal
import sys
import rads
def get_args():
"""Parse arguments"""
parser = argparse.ArgumentParser(description=__doc__)
# fmt: off
parser.add_argument(
'-n', '--name', dest='filenames', nargs='+', required=True,
help='File name(s) to look for',
)
parser.add_argument(
'-e', '--exclude', dest='exc_user', nargs='+', default=[],
help='User(s) to exclude',
)
parser.add_argument(
'-x', '--max', type=int, help='Max file size (in bytes)'
)
parser.add_argument(
'-m', '--min', type=int, help='Min file size (in bytes)'
)
# fmt: on
args = parser.parse_args()
if args.min > args.max:
print("The minimum size needs to be larger than the maximum size")
sys.exit(1)
return args.filenames, args.exc_user, args.max, args.min
def targets(excluded):
"""Get a list of users that aren't suspended, sys. users, or excluded"""
return [
user
for user in rads.all_cpusers()
if user not in rads.OUR_RESELLERS
and not rads.cpuser_suspended(user)
and user not in excluded
]
def check_size(filename, maxsize, minsize):
"""Confirm filesize within argument constraints"""
size = os.path.getsize(filename)
if maxsize is not None:
if size > maxsize:
return False
if minsize is not None:
if size < minsize:
return False
return True
def hunter(gdtuple):
"""Print any file that matches the filenames"""
user, filenames, maxsize, minsize = gdtuple
try:
homedir = rads.get_homedir(user)
except rads.CpuserError as exc:
print(exc, file=sys.stderr)
return
for root, _, files in os.walk(homedir, topdown=False):
for name in files:
if name in filenames:
fullpath = os.path.join(root, name)
if maxsize is None and minsize is None:
print(fullpath)
continue
if check_size(fullpath, maxsize, minsize):
print(fullpath)
def start_the_hunt(target_users, filenames, maxsize, minsize):
"""set up a multiprocessing queue to loop through accounts"""
args = ((user, filenames, maxsize, minsize) for user in target_users)
# shenanigans to deal with keyboard interrupts
original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN)
with multiprocessing.Pool(multiprocessing.cpu_count()) as pool:
signal.signal(signal.SIGINT, original_sigint_handler)
try:
results = pool.map_async(hunter, args)
# dealing with Python bug https://bugs.python.org/issue8296
results.get(10)
except multiprocessing.TimeoutError:
pass
except KeyboardInterrupt:
print("Caught KeyboardInterrupt.")
pool.terminate()
pool.close()
def main():
'''Main function: get args'''
filenames, excluded, maxsize, minsize = get_args()
target_users = targets(excluded)
start_the_hunt(target_users, filenames, maxsize, minsize)
if __name__ == "__main__":
main()
Zerion Mini Shell 1.0