summaryrefslogtreecommitdiffstats
path: root/packaging/cull-options
diff options
context:
space:
mode:
Diffstat (limited to 'packaging/cull-options')
-rwxr-xr-xpackaging/cull-options148
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