From f2f6d091e12393ed0bb7680d60c862b724fb1bd7 Mon Sep 17 00:00:00 2001 From: Johannes Bauer Date: Sat, 24 Sep 2016 11:16:58 +0200 Subject: [PATCH] Have a fairly decent help page Reused the help page generator from luksipc. --- Makefile | 2 +- cmdline.c | 22 +++++++++- cmdline.h | 3 +- codegen/TwoColPrint.py | 80 +++++++++++++++++++++++++++++++++++++ codegen/print_help | 91 ++++++++++++++++++++++++++++++++++++++++++ luksrku.c | 2 +- 6 files changed, 195 insertions(+), 5 deletions(-) create mode 100644 codegen/TwoColPrint.py create mode 100755 codegen/print_help diff --git a/Makefile b/Makefile index 9423454..9b3ff6e 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ all: luksrku luksrku-config INSTALL_PREFIX := /usr/local/ -OPENSSL_DIR := `pwd`/openssl-1.1.0/ +OPENSSL_DIR := `pwd`/openssl-1.1.0a/ #OPENSSL_DIR := /home/joe/openssl/ #LIBDIR := /usr/lib/x86_64-linux-gnu/ LIBDIR := $(OPENSSL_DIR) diff --git a/cmdline.c b/cmdline.c index fdf1218..6e0b154 100644 --- a/cmdline.c +++ b/cmdline.c @@ -36,8 +36,26 @@ enum longopts_t { LONGOPT_KEYDB }; -void print_syntax(void) { - fprintf(stderr, "Help page here\n"); +void print_syntax(const char *pgmname) { + fprintf(stderr, "%s (-c, --client-mode) (-s, --server-mode) (-k, --keydb=FILE) (-p, --port=PORT)\n", pgmname); + fprintf(stderr, " (-v, --verbose)\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -c, --client-mode Specifies client mode, i.e., that this host will unlock the LUKS disk\n"); + fprintf(stderr, " of a different machine.\n"); + fprintf(stderr, " -s, --server-mode Specifies server mode, i.e., that this host will announce its\n"); + fprintf(stderr, " presence via UDP broadcasts and then receive the LUKS credentials\n"); + fprintf(stderr, " from a peer.\n"); + fprintf(stderr, " -k, --keydb=FILE Gives the binary key database file which will be used. In server\n"); + fprintf(stderr, " mode, this contains only one entry (specifying the UUID of the host,\n"); + fprintf(stderr, " the PSK and the UUIDs and names of the disks to be unlocked), while\n"); + fprintf(stderr, " in client mode this may contain multiple entries (to unlock many\n"); + fprintf(stderr, " different peers) and also contains the LUKS credentials for the\n"); + fprintf(stderr, " respective disks.\n"); + fprintf(stderr, " -p, --port=PORT Specifies the port on which is listened for UDP broadcasts and also\n"); + fprintf(stderr, " the port on which TCP requests are sent out (the two are always\n"); + fprintf(stderr, " identical).\n"); + fprintf(stderr, " -v, --verbose Increase logging verbosity.\n"); + fprintf(stderr, "\n"); } static void set_default_arguments(struct options_t *options) { diff --git a/cmdline.h b/cmdline.h index 2df9a88..286b696 100644 --- a/cmdline.h +++ b/cmdline.h @@ -40,7 +40,8 @@ struct options_t { }; /*************** AUTO GENERATED SECTION FOLLOWS ***************/ -void print_syntax(void); +enum longopts_t; +void print_syntax(const char *pgmname); bool parse_cmdline_arguments(struct options_t *options, int argc, char **argv); /*************** AUTO GENERATED SECTION ENDS ***************/ diff --git a/codegen/TwoColPrint.py b/codegen/TwoColPrint.py new file mode 100644 index 0000000..25b0a88 --- /dev/null +++ b/codegen/TwoColPrint.py @@ -0,0 +1,80 @@ +#!/usr/bin/python3 +# +# TwoColPrint - Print text in two columns, wrap as appropriate. +# Copyright (C) 2011-2012 Johannes Bauer +# +# This file is part of jpycommon. +# +# jpycommon is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; this program is ONLY licensed under +# version 3 of the License, later versions are explicitly excluded. +# +# jpycommon is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with jpycommon; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Johannes Bauer +# +# File UUID c2de9b77-c699-490d-930f-21689e04b12f + +import sys +import textwrap +import collections + +_Row = collections.namedtuple("Row", [ "left", "right", "annotation" ]) + +class TwoColPrint(object): + def __init__(self, prefix = "", total_width = 120, spacer_width = 3, width_ratio = 0.25): + self._rows = [ ] + self._prefix = prefix + self._total_width = total_width + self._spacer_width = spacer_width + self._width_ratio = width_ratio + + def addrow(self, left_col, right_col, annotation = None): + self._rows.append(_Row(left = left_col, right = right_col, annotation = annotation)) + return self + + def __iter__(self): + text_width = self._total_width - len(self._prefix) - self._spacer_width + assert(text_width > 2) + left_width = round(self._width_ratio * text_width) + right_width = text_width - left_width + assert(len(self._prefix) + left_width + self._spacer_width + right_width == self._total_width) + + spacer = " " * self._spacer_width + for row in self._rows: + left_break = textwrap.wrap(row.left, width = left_width) + right_break = textwrap.wrap(row.right, width = right_width) + + if len(left_break) < len(right_break): + left_break += [ "" ] * (len(right_break) - len(left_break)) + elif len(left_break) > len(right_break): + right_break += [ "" ] * (len(left_break) - len(right_break)) + + for (leftline, rightline) in zip(left_break, right_break): + + yield ("%s%-*s%s%s" % (self._prefix, left_width, leftline, spacer, rightline), row.annotation) + + def print(self, f = None): + if f is None: + f = sys.stdout + for (line, annotation) in self: + print(line, file = f) + +if __name__ == "__main__": + t = TwoColPrint(prefix = " ") + t.addrow("foobar", "This is the first piece, which is foobar. A foobar is very cool! This is the first piece, which is foobar. A foobar is very cool!") + t.addrow("barfjdiojf", "And here's a barwhatever And here's a barwhatever And here's a barwhatever") + t.addrow("x", "Cool, a x.") + t.addrow("And here's a barwhatever And here's a barwhatever And here's a barwhatever", "barfjdiojf") + t.print() + + + diff --git a/codegen/print_help b/codegen/print_help new file mode 100755 index 0000000..47c0827 --- /dev/null +++ b/codegen/print_help @@ -0,0 +1,91 @@ +#!/usr/bin/python3 +import textwrap + +class HelpPagePrinter(object): + def __init__(self): + self._entries = [ ] + self._lcolsize = None + + def add(self, lhs, rhs): + if isinstance(lhs, str): + lhs = (lhs, ) + else: + lhs = (", ".join(lhs), ) + if isinstance(rhs, str): + rhs = (rhs, ) + self._entries.append((lhs, rhs)) + + def _format_entry(self, entry): + (lhs, rhs) = entry + lhs = list(lhs) + rhs = list(rhs) + + right_lines = [ ] + for block in rhs: + right_lines += textwrap.wrap(block, width = 86 - self._lcolsize) + + if len(lhs) < len(right_lines): + lhs += [ "" ] * (len(right_lines) - len(lhs)) + elif len(lhs) > len(right_lines): + right_lines += [ "" ] * (len(lhs) - len(right_lines)) + for (left, right) in zip(lhs, right_lines): + yield "%-*s %s" % (self._lcolsize, left, right.replace("\xa0", " ")) + + def _determine_lcolsize(self): + self._lcolsize = 0 + for (lhs, rhs) in self._entries: + for line in lhs: + self._lcolsize = max(self._lcolsize, len(line)) + + def format_params(self): + lines = [ "" ] + for (lhs, rhs) in self._entries: + par = lhs[0].strip() + + newline = lines[-1] + (" (%s)" % (par)) + if len(newline) < 80: + lines[-1] = newline + else: + lines.append("(%s)" % (par)) + yield from lines + + + def format_help(self): + self._determine_lcolsize() + for entry in self._entries: + yield from self._format_entry(entry) + +hpp = HelpPagePrinter() +hpp.add([ "-c", "--client-mode" ], "Specifies client mode, i.e., that this host will unlock the LUKS disk of a different machine.") +hpp.add([ "-s", "--server-mode" ], "Specifies server mode, i.e., that this host will announce its presence via UDP broadcasts and then receive the LUKS credentials from a peer.") +hpp.add([ "-k", "--keydb=FILE" ], "Gives the binary key database file which will be used. In server mode, this contains only one entry (specifying the UUID of the host, the PSK and the UUIDs and names of the disks to be unlocked), while in client mode this may contain multiple entries (to unlock many different peers) and also contains the LUKS credentials for the respective disks.") +hpp.add([ "-p", "--port=PORT" ], "Specifies the port on which is listened for UDP broadcasts and also the port on which TCP requests are sent out (the two are always identical).") +hpp.add([ "-v", "--verbose" ], "Increase logging verbosity.") +for (index, line) in enumerate(hpp.format_params()): + if index == 0: + print("fprintf(stderr, \"%%s%s\\n\", argv[0]);" % (line)) + else: + print("fprintf(stderr, \" %s\\n\");" % (line)) +print("fprintf(stderr, \"\\n\");") +for line in hpp.format_help(): + print("fprintf(stderr, \" %s\\n\");" % (line)) +print("fprintf(stderr, \"\\n\");") + + +#examples = [ +# ("--client-mode ", +# "Converts {device} to a LUKS partition with default parameters."), +# ("-d {device} --resume-file myresume.dat", +# "Converts {device} to a LUKS partition with default parameters and store resume information in myresume.dat in case of an abort."), +# ("-d {device} -k /root/secure_key/keyfile.bin --luksparams='-c,twofish-lrw-benbi,-s,320,-h,sha256'", +# "Converts {device} to a LUKS partition and stores the initially used keyfile in /root/secure_key/keyfile.bin. Additionally some LUKS parameters are passed that specify that the Twofish cipher should be used with a 320 bit keysize and SHA-256 as a hash function."), +# ("-d {device} --resume --resume-file /root/resume.bin", +# "Resumes a crashed LUKS conversion of {device} using the file /root/resume.bin which was generated at the first (crashed) luksipc run."), +# ("-d {device} --readdev /dev/mapper/oldluks", +# "Convert the raw device {device}, which is already a LUKS container, to a new LUKS container. For example, this can be used to change the encryption parameters of the LUKS container (different cipher) or to change the bulk encryption key. In this example the old container is unlocked and accessible under /dev/mapper/oldluks."), +#] +#print("fprintf(stderr, \"Examples:\\n\");") +#for (cmd, desc) in examples: +# print("fprintf(stderr, \" %%s %s\\n\", argv[0]);" % (cmd.replace("{device}", device))) +# for line in textwrap.wrap(desc.replace("{device}", device), width = 80): +# print("fprintf(stderr, \" %s\\n\");" % (line)) diff --git a/luksrku.c b/luksrku.c index ad3fab8..b643f3e 100644 --- a/luksrku.c +++ b/luksrku.c @@ -40,7 +40,7 @@ int main(int argc, char **argv) { struct options_t options; if (!parse_cmdline_arguments(&options, argc, argv)) { - print_syntax(); + print_syntax(argv[0]); exit(EXIT_FAILURE); } if (options.verbose) {