2 # This script will either prefix all symlink values with the string
3 # "/rsyncd-munged/" or remove that prefix.
5 import os, sys, argparse
7 SYMLINK_PREFIX = '/rsyncd-munged/'
8 PREFIX_LEN = len(SYMLINK_PREFIX)
11 for arg in args.names:
12 if os.path.islink(arg):
14 elif os.path.isdir(arg):
15 for fn in find_symlinks(arg):
18 print("Arg is not a symlink or a dir:", arg, file=sys.stderr)
21 def find_symlinks(path):
22 for entry in os.scandir(path):
23 if entry.is_symlink():
25 elif entry.is_dir(follow_symlinks=False):
26 yield from find_symlinks(entry.path)
29 def process_one_arg(fn):
32 if not lnk.startswith(SYMLINK_PREFIX):
34 lnk = lnk[PREFIX_LEN:]
35 while args.all and lnk.startswith(SYMLINK_PREFIX):
36 lnk = lnk[PREFIX_LEN:]
38 if not args.all and lnk.startswith(SYMLINK_PREFIX):
40 lnk = SYMLINK_PREFIX + lnk
45 print("Unable to unlink symlink:", str(e), file=sys.stderr)
50 print("Unable to recreate symlink", fn, '->', lnk + ':', str(e), file=sys.stderr)
55 if __name__ == '__main__':
57 Adds or removes the %s prefix to/from the start of each symlink's value.
58 When given the name of a directory, affects all the symlinks in that directory hierarchy.
60 epilog = 'See the "munge symlinks" option in the rsyncd.conf manpage for more details.'
61 parser = argparse.ArgumentParser(description=our_desc, epilog=epilog, add_help=False)
62 uniq_group = parser.add_mutually_exclusive_group()
63 uniq_group.add_argument('--munge', action='store_true', help="Add the prefix to symlinks (the default).")
64 uniq_group.add_argument('--unmunge', action='store_true', help="Remove the prefix from symlinks.")
65 parser.add_argument('--all', action='store_true', help="Always adds the prefix when munging (even if already munged) or removes multiple instances of the prefix when unmunging.")
66 parser.add_argument('--help', '-h', action='help', help="Output this help message and exit.")
67 parser.add_argument('names', metavar='NAME', nargs='+', help="One or more directories and/or symlinks to process.")
68 args = parser.parse_args()