diff options
Diffstat (limited to 'packaging/cull-options')
-rwxr-xr-x | packaging/cull-options | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/packaging/cull-options b/packaging/cull-options new file mode 100755 index 0000000..e71818c --- /dev/null +++ b/packaging/cull-options @@ -0,0 +1,148 @@ +#!/usr/bin/env python3 +# This script outputs either perl or python code that parses all possible options +# that the code in options.c might send to the server. The resulting code is then +# included in the rrsync script. + +import re, argparse + +short_no_arg = { } +short_with_num = { '@': 1 } +long_opts = { # These include some extra long-args that BackupPC uses: + 'block-size': 1, + 'daemon': -1, + 'debug': 1, + 'fake-super': 0, + 'fuzzy': 0, + 'group': 0, + 'hard-links': 0, + 'ignore-times': 0, + 'info': 1, + 'links': 0, + 'log-file': 3, + 'munge-links': 0, + 'no-munge-links': -1, + 'one-file-system': 0, + 'owner': 0, + 'perms': 0, + 'recursive': 0, + 'stderr': 1, + 'times': 0, + 'copy-devices': -1, + 'write-devices': -1, + } + +def main(): + last_long_opt = None + + with open('../options.c') as fh: + for line in fh: + m = re.search(r"argstr\[x\+\+\] = '([^.ie])'", line) + if m: + short_no_arg[m.group(1)] = 1 + last_long_opt = None + continue + + m = re.search(r'asprintf\([^,]+, "-([a-zA-Z0-9])\%l?[ud]"', line) + if m: + short_with_num[m.group(1)] = 1 + last_long_opt = None + continue + + m = re.search(r'args\[ac\+\+\] = "--([^"=]+)"', line) + if m: + last_long_opt = m.group(1) + if last_long_opt not in long_opts: + long_opts[last_long_opt] = 0 + else: + last_long_opt = None + continue + + if last_long_opt: + m = re.search(r'args\[ac\+\+\] = safe_arg\("", ([^[("\s]+)\);', line) + if m: + long_opts[last_long_opt] = 2 + last_long_opt = None + continue + if 'args[ac++] = ' in line: + last_long_opt = None + + m = re.search(r'return "--([^"]+-dest)";', line) + if m: + long_opts[m.group(1)] = 2 + last_long_opt = None + continue + + m = re.search(r'asprintf\([^,]+, "--([^"=]+)=', line) + if not m: + m = re.search(r'args\[ac\+\+\] = "--([^"=]+)=', line) + if not m: + m = re.search(r'args\[ac\+\+\] = safe_arg\("--([^"=]+)"', line) + if not m: + m = re.search(r'fmt = .*: "--([^"=]+)=', line) + if m: + long_opts[m.group(1)] = 1 + last_long_opt = None + + long_opts['files-from'] = 3 + + txt = """\ +### START of options data produced by the cull-options script. ### + +# To disable a short-named option, add its letter to this string: +""" + + txt += str_assign('short_disabled', 's') + "\n" + txt += '# These are also disabled when the restricted dir is not "/":\n' + txt += str_assign('short_disabled_subdir', 'KLk') + "\n" + txt += '# These are all possible short options that we will accept (when not disabled above):\n' + txt += str_assign('short_no_arg', ''.join(sorted(short_no_arg)), 'DO NOT REMOVE ANY') + txt += str_assign('short_with_num', ''.join(sorted(short_with_num)), 'DO NOT REMOVE ANY') + + txt += """ +# To disable a long-named option, change its value to a -1. The values mean: +# 0 = the option has no arg; 1 = the arg doesn't need any checking; 2 = only +# check the arg when receiving; and 3 = always check the arg. +""" + + print(txt, end='') + + if args.python: + print("long_opts = {") + sep = ':' + else: + print("our %long_opt = (") + sep = ' =>' + + for opt in sorted(long_opts): + if opt.startswith(('min-', 'max-')): + val = 1 + else: + val = long_opts[opt] + print(' ', repr(opt) + sep, str(val) + ',') + + if args.python: + print("}") + else: + print(");") + print("\n### END of options data produced by the cull-options script. ###") + + +def str_assign(name, val, comment=None): + comment = ' # ' + comment if comment else '' + if args.python: + return name + ' = ' + repr(val) + comment + "\n" + return 'our $' + name + ' = ' + repr(val) + ';' + comment + "\n" + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description="Output culled rsync options for rrsync.", add_help=False) + out_group = parser.add_mutually_exclusive_group() + out_group.add_argument('--perl', action='store_true', help="Output perl code.") + out_group.add_argument('--python', action='store_true', help="Output python code (the default).") + parser.add_argument('--help', '-h', action='help', help="Output this help message and exit.") + args = parser.parse_args() + if not args.perl: + args.python = True + main() + +# vim: sw=4 et |