| #! /usr/bin/env python | |
| # 3) System Test | |
| # | |
| # Given a list of directories, report any bogus symbolic links contained | |
| # anywhere in those subtrees. A bogus symbolic link is one that cannot | |
| # be resolved because it points to a nonexistent or otherwise | |
| # unresolvable file. Do *not* use an external find executable. | |
| # Directories may be very very deep. Print a warning immediately if the | |
| # system you're running on doesn't support symbolic links. | |
| # This implementation: | |
| # - takes one optional argument, using the current directory as default | |
| # - uses chdir to increase performance | |
| # - sorts the names per directory | |
| # - prints output lines of the form "path1 -> path2" as it goes | |
| # - prints error messages about directories it can't list or chdir into | |
| import os | |
| import sys | |
| from stat import * | |
| def main(): | |
| try: | |
| # Note: can't test for presence of lstat -- it's always there | |
| dummy = os.readlink | |
| except AttributeError: | |
| print "This system doesn't have symbolic links" | |
| sys.exit(0) | |
| if sys.argv[1:]: | |
| prefix = sys.argv[1] | |
| else: | |
| prefix = '' | |
| if prefix: | |
| os.chdir(prefix) | |
| if prefix[-1:] != '/': prefix = prefix + '/' | |
| reportboguslinks(prefix) | |
| else: | |
| reportboguslinks('') | |
| def reportboguslinks(prefix): | |
| try: | |
| names = os.listdir('.') | |
| except os.error, msg: | |
| print "%s%s: can't list: %s" % (prefix, '.', msg) | |
| return | |
| names.sort() | |
| for name in names: | |
| if name == os.curdir or name == os.pardir: | |
| continue | |
| try: | |
| mode = os.lstat(name)[ST_MODE] | |
| except os.error: | |
| print "%s%s: can't stat: %s" % (prefix, name, msg) | |
| continue | |
| if S_ISLNK(mode): | |
| try: | |
| os.stat(name) | |
| except os.error: | |
| print "%s%s -> %s" % \ | |
| (prefix, name, os.readlink(name)) | |
| elif S_ISDIR(mode): | |
| try: | |
| os.chdir(name) | |
| except os.error, msg: | |
| print "%s%s: can't chdir: %s" % \ | |
| (prefix, name, msg) | |
| continue | |
| try: | |
| reportboguslinks(prefix + name + '/') | |
| finally: | |
| os.chdir('..') | |
| main() |