def test_fmt_human(self): """Test function for human-readable output""" options = _options() inp = {"argv1": (set(["1", "2"]), set(["l1", "l2"]))} outp = '1,2 "argv1"' self.assertEqual(common.fmt_human(inp, options), outp) inp = {"argv1": (set(["1"]), set(["l1", "l2"]))} outp = '1 "argv1"' self.assertEqual(common.fmt_human(inp, options), outp) # The space at the end of this argv should go away. inp = {"argv1 argv2 ": (set(["1"]), set(["l1", "l2"]))} outp = '1 "argv1 argv2"' self.assertEqual(common.fmt_human(inp, options), outp) inp = {} outp = '' self.assertEqual(common.fmt_human(inp, options), outp)
def test_fmt_human_with_libs(self): """Test function for human-readable output""" inp = {"argv1": (set(["1", "2"]), set(["l1", "l2"]))} outp = '1,2 "argv1" uses l1,l2' options = _options() options.showitems = True self.assertEqual(common.fmt_human(inp, options), outp) inp = {"argv1": (set(["1"]), set(["l1"]))} outp = '1 "argv1" uses l1' self.assertEqual(common.fmt_human(inp, options), outp) # The space at the end of this argv should go away. inp = {"argv1 argv2 ": (set(["1"]), set(["l1", "l2"]))} outp = '1 "argv1 argv2" uses l1,l2' self.assertEqual(common.fmt_human(inp, options), outp) inp = {} outp = '' print(common.fmt_human(inp, options)) self.assertEqual(common.fmt_human(inp, options), outp)
def main(argv): """Main program""" parser = argparse.ArgumentParser() parser.add_argument('--version', action='version', version='%%(prog)s %s' % (__version__)) parser.add_argument("-m", "--machine-readable", action="store_true", help="Output machine readable info") parser.add_argument("-s", "--showlibs", action="store_true", help="In human readable mode, show deleted libs") parser.add_argument("-S", "--services", action="store_true", help="Try to find systemd services for lib users") parser.add_argument("-i", "--ignore-pattern", default=[], metavar="GLOB", action='append', help="Ignore deleted files matching %(metavar)s. " "Can be specified multiple times.") parser.add_argument("-I", "--ignore-literal", default=[], metavar="LITERAL", action='append', help="Ignore deleted files named %(metavar)s. " "Can be specified multiple times.") options = parser.parse_args(argv) options.showitems = options.showlibs NOLIBSPT.update(options.ignore_pattern) NOLIBSNP.update(options.ignore_literal) users = defaultdict(lambda: (set(), set())) read_failure = False for map_filename in glob.glob(common.LIBPROCFSPAT): deletedlibs = set() try: pid = normpath(map_filename).split("/")[2] except IndexError: # This happens if the filenames look different # than we expect (e.g. the user changed common.LIBPROCFSPAT) pid = "unknown" try: mapsfile = open(map_filename) deletedlibs = get_deleted_libs(mapsfile) except IOError as exc: read_failure = True continue mapsfile.close() if deletedlibs: argv = common.get_progargs(pid) if not argv: continue users[argv][0].add(pid) users[argv][1].update(deletedlibs) if read_failure: if os.geteuid() == 0: sys.stderr.write(PERMWARNINGUID0) else: sys.stderr.write(PERMWARNING) if len(users) > 0: if options.machine_readable: print(common.fmt_machine(users)) else: print(common.fmt_human(users, options)) if options.services: print() print(common.get_services(users))