From d5cfe4c295d7136a4c82fea0ccd927f2a9a900d3 Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Sat, 2 Mar 2019 11:00:53 +0100 Subject: gnunet-qr: Reimplement in C - yet only a proof of concept. Still to-do: * running gnunet-uri * Proper error handling * integration into build system (automake) Reimplementing in C was chosen since - official zbar python-bindings support python 2 only, - none of the other bindings available at PyPI supports the high-level "processor" interface which gnunet-qr uses - implementing bindings for zbar using ctypes required addin a lot of low-level error handling code, thus implementing in C seamed to be easier, - the programm is short, thus re-implementing is not such complicated, and - this allows to reduce the number of dependencies (here: another Python version), which should ease porting to other plattforms (zbar is a dependency anyway). --- src/util/gnunet-qr.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/util/gnunet-qr.in | 46 --------------- src/util/gnunet-qr.py | 110 ---------------------------------- 3 files changed, 160 insertions(+), 156 deletions(-) create mode 100644 src/util/gnunet-qr.c delete mode 100755 src/util/gnunet-qr.in delete mode 100644 src/util/gnunet-qr.py diff --git a/src/util/gnunet-qr.c b/src/util/gnunet-qr.c new file mode 100644 index 000000000..c02212a51 --- /dev/null +++ b/src/util/gnunet-qr.c @@ -0,0 +1,160 @@ +/* + This file is part of GNUnet. + Copyright (C) 2013-2019 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet 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 + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later +*/ + +#include +#include +#include +#include + +static const char *usage_note = + "gnunet-qr\n" + "Scan a QR code using a video device and import\n" + "\n" + "Arguments mandatory for long options are also mandatory for short options.\n" + " -c, --config FILENAME use configuration file FILENAME\n" + " -d, --device DEVICE use device DEVICE\n" + " -s, --silent do not show preview windows\n" + " -h, --help print this help\n" + " -v, --verbose be verbose\n" + "Report bugs to gnunet-developers@gnu.org.\n" + "\n" + "GNUnet home page: https://gnunet.org/\n" + "General help using GNU software: https://www.gnu.org/gethelp/\n"; + +int main (int argc, char **argv) +{ + const char* configuration = NULL; + const char* device = "/dev/video0"; + static bool verbose = false; + static bool silent = false; + + static struct option long_options[] = { + {"verbose", no_argument, 0, 'v'}, + {"silent", no_argument, 0, 's'}, + {"help", no_argument, 0, 'h'}, + {"config", required_argument, 0, 'c'}, + {"device", required_argument, 0, 'd'}, + {0, 0, 0, 0} + }; + while (1) { + int opt; + opt = getopt_long (argc, argv, "c:hd:sv", + long_options, NULL); + if (opt == -1) + break; + + switch (opt) { + case 'h': + printf(usage_note); + return 0; + case 'c': + configuration = optarg; + break; + case 'd': + device = optarg; + break; + case 's': + silent = true; + break; + case 'v': + verbose = true; + break; + default: + printf(usage_note); + return 1; + } + } + + /* create a Processor */ + if (verbose == true) { + printf("Initializing\n"); + }; + zbar_processor_t *proc = zbar_processor_create(1); + + // FIXME: Wrap all this into a function which returns an error on + // failure. And here ensure the processor is destroyed at the end. + + /* configure the Processor */ + zbar_processor_parse_config(proc, "enable"); + + /* initialize the Processor */ + if (verbose == true) { + printf("Opening video device %s\n", device); + }; + // FIXME: error handling + zbar_processor_init(proc, device, 1); + + /* enable the preview window */ + zbar_processor_set_visible(proc, 1); + zbar_processor_set_active(proc, 1); + + /* keep scanning until user provides key/mouse input */ + //zbar_processor_user_wait(proc, -1); + + // read at least one barcode (or until window closed) + if (verbose == true) { + printf("Capturing\n"); + } + int n; + n = zbar_process_one(proc, -1); + if (verbose == true) { + printf("Got %i images\n", n); + }; + // FIXME: Error handling (n = -1) + + // hide the preview window + zbar_processor_set_active(proc, 0); + zbar_processor_set_visible(proc, 0); + + // extract results + int rc = 1; + + const zbar_symbol_set_t* symbols = zbar_processor_get_results(proc); + const zbar_symbol_t* symbol = zbar_symbol_set_first_symbol(symbols); + + if (symbol != NULL) { + const char* data = zbar_symbol_get_data(symbol); + if (verbose = true) { + zbar_symbol_type_t type = + printf("Found %s \"%s\"\n", + zbar_get_symbol_name(zbar_symbol_get_type(symbol)), data); + } + /* TODO + args = ["gnunet-uri", + // FIXME: "-c", configuration, + data]; + if (verbose = true) { + // TODO: print arguments: + printf("Running `%s %s %s %s`", *args, "", ""); // FIXME variable num args + }; + rc = popen("gnunet-uri", *args); + */ + if (rc != 0) { + printf("Failed to add URI %s\n", data); + } else { + printf("Added URI %s\n", data); + } + } + + /* clean up */ + zbar_processor_destroy(proc); + + return(rc); +} diff --git a/src/util/gnunet-qr.in b/src/util/gnunet-qr.in deleted file mode 100755 index ce7a19b69..000000000 --- a/src/util/gnunet-qr.in +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh -# -# From curl's buildconf, making this script subject to the -# curl license: https://curl.haxx.se/docs/copyright.html -# Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. -# Copyright (C) 2019 GNUnet e.V. - -# findtool works like which without relying on which (which is a problem -# for some limited shells. -findtool(){ - file="$1" - - if { echo "$file" | grep "/" >/dev/null 2>&1; } then - # when file is given with a path check it first - if test -f "$file"; then - echo "$file" - return - fi - fi - - old_IFS=$IFS; IFS=':' - for path in $PATH - do - IFS=$old_IFS - # echo "checks for $file in $path" >&2 - if test "$path" -a "$path" != '.' -a -f "$path/$file"; then - echo "$path/$file" - return - fi - done - IFS=$old_IFS -} - -# end curl licensed code -pythonize=`findtool python2.7 2>/dev/null` -if test ! -x "$pythonize"; then - pythonize=`findtool ${PYTHON2:-python2.7}` -fi - -if test -z "$pythonize"; then - echo "ERROR: python2.7 not found." - echo " You need python2.7 installed." - exit 1 -fi - -${pythonize} @PREFIX@/share/gnunet/gnunet-qr.py $@ diff --git a/src/util/gnunet-qr.py b/src/util/gnunet-qr.py deleted file mode 100644 index 0ee0b9507..000000000 --- a/src/util/gnunet-qr.py +++ /dev/null @@ -1,110 +0,0 @@ -import sys -import getopt -import subprocess -from sys import argv -try: - import zbar -except ImportError as e: - print('Cannot run gnunet-qr, please install the zbar module.') - print('For Debian, you can obtain it as "python-zbar".') - print('Upstream: http://zbar.sourceforge.net/') - sys.exit(1) - - -def help(): - print('gnunet-qr\n\ -Scan a QR code using a video device and import\n\ -Arguments mandatory for long options are also mandatory for short options.\n\ - -c, --config FILENAME use configuration file FILENAME\n\ - -d, --device DEVICE use device DEVICE\n\ - -s, --silent do not show preview windows\n\ - -h, --help print this help\n\ - -v, --verbose be verbose\n\ -Report bugs to gnunet-developers@gnu.org.\n\ -GNUnet home page: https://gnunet.org/\n\ -General help using GNU software: https://www.gnu.org/gethelp/') - - -if __name__ == '__main__': - configuration = '' - device = '/dev/video0' - url = '' - verbose = False - silent = False - # Parse arguments - try: - opts, args = getopt.gnu_getopt(sys.argv[1:], "c:hd:sv", ["config", "help", "device", "silent", "verbose"]) - except getopt.GetoptError as e: - help() - print(str(e)) - exit(1) - for o, a in opts: - if o in ("-h", "--help"): - help() - sys.exit(0) - elif o in ("-c", "--config"): - configuration = a - elif o in ("-d", "--device"): - device = a - elif o in ("-s", "--silent"): - silent = True - elif o in ("-v", "--verbose"): - verbose = True - if (True == verbose): - print('Initializing') - # create a Processor - proc = zbar.Processor() - - # configure the Processor - proc.parse_config('enable') - - # initialize the Processor - try: - if (True == verbose): - print('Opening video device ' + device) - proc.init(device) - except Exception as e: - print('Failed to open device ' + device) - exit(1) - - # enable the preview window - # if (True == silent): - # proc.visible = True - # else: - # proc.visible = False - - proc.visible = True - # read at least one barcode (or until window closed) - try: - if (True == verbose): - print('Capturing') - proc.process_one() - except Exception as e: - # Window was closed without finding code - exit(1) - - # hide the preview window - proc.visible = False - - # extract results - for symbol in proc.results: - # do something useful with results - if (True == verbose): - print('Found ', symbol.type, ' symbol ', '"%s"' % symbol.data) - args = list() - args.append("gnunet-uri") - if (configuration != ''): - args.append(str("-c " + str(configuration))) - args.append(str(symbol.data)) - cmd = '' - for a in args: - cmd += " " + str(a) - if (verbose): - print('Running `' + cmd +'`') - res = subprocess.call(args) - if (0 != res): - print('Failed to add URI ' + str(symbol.data)) - else: - print('Added URI ' + str(symbol.data)) - exit(res) - exit(1) -- cgit v1.2.3 From eaf7440ec8e19df09b0ae632c4b200a0511069aa Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Sat, 2 Mar 2019 12:37:46 +0100 Subject: gnunet-qr: Simplify verbose messaging. --- src/util/gnunet-qr.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/src/util/gnunet-qr.c b/src/util/gnunet-qr.c index c02212a51..b375d20a7 100644 --- a/src/util/gnunet-qr.c +++ b/src/util/gnunet-qr.c @@ -38,6 +38,8 @@ static const char *usage_note = "GNUnet home page: https://gnunet.org/\n" "General help using GNU software: https://www.gnu.org/gethelp/\n"; +#define LOG(fmt, ...) if (verbose == true) printf(fmt, ## __VA_ARGS__) + int main (int argc, char **argv) { const char* configuration = NULL; @@ -83,9 +85,7 @@ int main (int argc, char **argv) } /* create a Processor */ - if (verbose == true) { - printf("Initializing\n"); - }; + LOG("Initializing\n"); zbar_processor_t *proc = zbar_processor_create(1); // FIXME: Wrap all this into a function which returns an error on @@ -95,9 +95,7 @@ int main (int argc, char **argv) zbar_processor_parse_config(proc, "enable"); /* initialize the Processor */ - if (verbose == true) { - printf("Opening video device %s\n", device); - }; + LOG("Opening video device %s\n", device); // FIXME: error handling zbar_processor_init(proc, device, 1); @@ -109,14 +107,10 @@ int main (int argc, char **argv) //zbar_processor_user_wait(proc, -1); // read at least one barcode (or until window closed) - if (verbose == true) { - printf("Capturing\n"); - } + LOG("Capturing\n"); int n; n = zbar_process_one(proc, -1); - if (verbose == true) { - printf("Got %i images\n", n); - }; + LOG("Got %i images\n", n); // FIXME: Error handling (n = -1) // hide the preview window @@ -131,11 +125,9 @@ int main (int argc, char **argv) if (symbol != NULL) { const char* data = zbar_symbol_get_data(symbol); - if (verbose = true) { - zbar_symbol_type_t type = - printf("Found %s \"%s\"\n", - zbar_get_symbol_name(zbar_symbol_get_type(symbol)), data); - } + LOG("Found %s \"%s\"\n", + zbar_get_symbol_name(zbar_symbol_get_type(symbol)), data); + /* TODO args = ["gnunet-uri", // FIXME: "-c", configuration, -- cgit v1.2.3 From a5de52ae3c590a829055d9233c4feb2813a5fbe9 Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Sat, 2 Mar 2019 17:26:35 +0100 Subject: Add helper lib "gnunet-qr-utils.h". These functions are copied from dns/gnunet-helper-dns.c, move them into a common library. Or think about implementing a even more elaborate version. --- src/util/gnunet-qr-utils.h | 111 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 src/util/gnunet-qr-utils.h diff --git a/src/util/gnunet-qr-utils.h b/src/util/gnunet-qr-utils.h new file mode 100644 index 000000000..6d821633c --- /dev/null +++ b/src/util/gnunet-qr-utils.h @@ -0,0 +1,111 @@ +/* + This file is part of GNUnet. + Copyright (C) 2010, 2011, 2012 Christian Grothoff + Copyright (C) 2019 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet 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 + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later +*/ + +#include "platform.h" + +// +// FIXME: These functions are copied from dns/gnunet-helper-dns.c, +// move them into a common library. Or think about implementing a even +// more elaborate version. +// + +/** + * Open '/dev/null' and make the result the given + * file descriptor. + * + * @param target_fd desired FD to point to /dev/null + * @param flags open flags (O_RDONLY, O_WRONLY) + */ +static void +open_dev_null (int target_fd, + int flags) +{ + int fd; + + fd = open ("/dev/null", flags); + if (-1 == fd) + abort (); + if (fd == target_fd) + return; + if (-1 == dup2 (fd, target_fd)) + { + (void) close (fd); + abort (); + } + (void) close (fd); +} + +/** + * Run the given command and wait for it to complete. + * + * @param file name of the binary to run + * @param cmd command line arguments (as given to 'execv') + * @return 0 on success, 1 on any error + */ +static int +fork_and_exec (const char *file, + char *const cmd[]) +{ + int status; + pid_t pid; + pid_t ret; + + pid = fork (); + if (-1 == pid) + { + fprintf (stderr, + "fork failed: %s\n", + strerror (errno)); + return 1; + } + if (0 == pid) + { + /* we are the child process */ + /* close stdin/stdout to not cause interference + with the helper's main protocol! */ + (void) close (0); + open_dev_null (0, O_RDONLY); + (void) close (1); + open_dev_null (1, O_WRONLY); + (void) execv (file, cmd); + /* can only get here on error */ + fprintf (stderr, + "exec `%s' failed: %s\n", + file, + strerror (errno)); + _exit (1); + } + /* keep running waitpid as long as the only error we get is 'EINTR' */ + while ( (-1 == (ret = waitpid (pid, &status, 0))) && + (errno == EINTR) ); + if (-1 == ret) + { + fprintf (stderr, + "waitpid failed: %s\n", + strerror (errno)); + return 1; + } + if (! (WIFEXITED (status) && (0 == WEXITSTATUS (status)))) + return 1; + /* child process completed and returned success, we're happy */ + return 0; +} + -- cgit v1.2.3 From e8e2d599bca5e88fa210c61676d8370fc112c66a Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Sat, 2 Mar 2019 17:27:36 +0100 Subject: gnunet-qr: Actually run gnunet-uri. --- src/util/gnunet-qr.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/util/gnunet-qr.c b/src/util/gnunet-qr.c index b375d20a7..c8919dae4 100644 --- a/src/util/gnunet-qr.c +++ b/src/util/gnunet-qr.c @@ -22,6 +22,7 @@ #include #include #include +#include "gnunet-qr-utils.h" static const char *usage_note = "gnunet-qr\n" @@ -128,16 +129,16 @@ int main (int argc, char **argv) LOG("Found %s \"%s\"\n", zbar_get_symbol_name(zbar_symbol_get_type(symbol)), data); - /* TODO - args = ["gnunet-uri", - // FIXME: "-c", configuration, - data]; - if (verbose = true) { - // TODO: print arguments: - printf("Running `%s %s %s %s`", *args, "", ""); // FIXME variable num args + if (configuration == NULL) { + char* command_args[] = {"gnunet-uri", data, NULL }; + LOG("Running `gnunet-uri %s`\n", data); + rc = fork_and_exec("gnunet-uri", command_args); + } else { + char* command_args[] = {"gnunet-uri", "-c", configuration, data, NULL }; + LOG("Running `gnunet-uri -c '%s' %s`\n", configuration, data); + rc = fork_and_exec("gnunet-uri", command_args); }; - rc = popen("gnunet-uri", *args); - */ + if (rc != 0) { printf("Failed to add URI %s\n", data); } else { -- cgit v1.2.3 From a89292d9bcc7e4a0f5e2d6d877993a6a496f27b6 Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Sun, 3 Mar 2019 01:04:08 +0100 Subject: Add Hartmut Goebel to the AUTHORS file. --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 829a0803e..3c337737f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -49,6 +49,7 @@ Eric Noack Felix von Leitner [ diet libc snprintf for win32 ] Gerd Knorr Glenn McGrath +Hartmut Goebel Hendrik Pagenhardt Heikki Lindholm Igor Wronsky -- cgit v1.2.3 From db1ae389da242b97dfe06882e9950e3b881cd378 Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Sun, 3 Mar 2019 02:04:16 +0100 Subject: configure.ac: Add check for libzbar (using pkgconfig). libzbar is required for gnunet-qr, which is optional. --- configure.ac | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/configure.ac b/configure.ac index 53dac3003..851f6543b 100644 --- a/configure.ac +++ b/configure.ac @@ -1402,6 +1402,10 @@ AC_DEFINE_UNQUOTED([HAVE_GNUTLS], $gnutls, [We have GnuTLS]) AM_CONDITIONAL(HAVE_GNUTLS_DANE, test x$gnutls_dane = x1) AC_DEFINE_UNQUOTED([HAVE_GNUTLS_DANE], $gnutls_dane, [We have GnuTLS with DANE support]) +# check for libzbar library, required for optional gnunet-qr +PKG_CHECK_MODULES([libzbar], [zbar >= 0.10], [have_zbar=1 ], [have_zbar=0 ]) +AM_CONDITIONAL([HAVE_ZBAR], [test "$have_zbar" = 1]) + # Test if we are building for superMUC AC_MSG_CHECKING(if GNUnet is being configured to run on the SuperMUC) @@ -1907,6 +1911,10 @@ AS_IF([test x$gnutls != xtrue], [AS_IF([test "x$gnutls_dane" != "x1"], [AC_MSG_NOTICE([WARNING: GnuTLS has no DANE support, DANE validation will not be possible])])]) +# warn user if libzbar is not found +AS_IF([test "$have_zbar" = 0], + [AC_MSG_NOTICE([WARNING: zbar not found, gnunet-qr will not be built.])]) + # java ports AS_IF([test "x$enable_java_ports" = "xyes"], [AC_MSG_NOTICE([NOTICE: Opening ports for gnunet-java bindings by default.])]) -- cgit v1.2.3 From d60866a5dfb1a3529d40ee4c445b891c68a362c8 Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Sun, 3 Mar 2019 02:06:31 +0100 Subject: gnunet-qr: Add into Makefile.am and pofiles, --- po/POTFILES.in | 1 + src/util/Makefile.am | 26 +++++++++++--------------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/po/POTFILES.in b/po/POTFILES.in index 09e4c533d..deeffe180 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -480,6 +480,7 @@ src/util/gnunet-config-diff.c src/util/gnunet-config.c src/util/gnunet-ecc.c src/util/gnunet-helper-w32-console.c +src/util/gnunet-qr.c src/util/gnunet-resolver.c src/util/gnunet-scrypt.c src/util/gnunet-service-resolver.c diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 645289f59..ba3c98ad1 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -204,24 +204,15 @@ libexec_PROGRAMS = \ gnunet-timeout \ $(W32CONSOLEHELPER) -do_subst = $(SED) -e 's,[@]PREFIX[@],$(prefix),g' - -gnunet-qr: gnunet-qr.in Makefile - $(do_subst) < $(srcdir)/gnunet-qr.in > gnunet-qr - chmod +x gnunet-qr - -CLEANFILES = gnunet-qr - -bin_SCRIPTS =\ - gnunet-qr \ - gnunet-qr.py - bin_PROGRAMS = \ gnunet-resolver \ gnunet-config \ $(GNUNET_ECC) \ $(GNUNET_SCRYPT) \ gnunet-uri +if HAVE_ZBAR +bin_PROGRAMS += gnunet-qr +endif noinst_PROGRAMS = \ gnunet-config-diff \ @@ -281,13 +272,19 @@ gnunet_config_LDADD = \ libgnunetutil.la \ $(GN_LIBINTL) - gnunet_uri_SOURCES = \ gnunet-uri.c gnunet_uri_LDADD = \ libgnunetutil.la \ $(GN_LIBINTL) + +gnunet_qr_SOURCES = \ + gnunet-qr.c \ + gnunet-qr-utils.h +gnunet_qr_LDFLAGS= $(libzbar_LIBS) +gnunet_qr_CFLAGS = $(libzbar_CFLAGS) + plugin_LTLIBRARIES = \ libgnunet_plugin_test.la @@ -668,5 +665,4 @@ EXTRA_DIST = \ test_program_data.conf \ test_resolver_api_data.conf \ test_service_data.conf \ - test_speedup_data.conf \ - gnunet-qr.in + test_speedup_data.conf -- cgit v1.2.3 From 70a749982e4ed34468d11affebe03a718facf3f4 Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Sun, 3 Mar 2019 02:10:13 +0100 Subject: gnunet-qr: Use the `gnunet-uri` binary installed into PREFIX. This helps keeping environments concise and functional package managers like guix this will ensure `gnunet-uri` from the same environment is used. --- src/util/Makefile.am | 2 +- src/util/gnunet-qr.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/util/Makefile.am b/src/util/Makefile.am index ba3c98ad1..98997efbd 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -283,7 +283,7 @@ gnunet_qr_SOURCES = \ gnunet-qr.c \ gnunet-qr-utils.h gnunet_qr_LDFLAGS= $(libzbar_LIBS) -gnunet_qr_CFLAGS = $(libzbar_CFLAGS) +gnunet_qr_CFLAGS = $(libzbar_CFLAGS) -DBINDIR=\"@bindir@/\" plugin_LTLIBRARIES = \ libgnunet_plugin_test.la diff --git a/src/util/gnunet-qr.c b/src/util/gnunet-qr.c index c8919dae4..ea0e0fea2 100644 --- a/src/util/gnunet-qr.c +++ b/src/util/gnunet-qr.c @@ -132,11 +132,11 @@ int main (int argc, char **argv) if (configuration == NULL) { char* command_args[] = {"gnunet-uri", data, NULL }; LOG("Running `gnunet-uri %s`\n", data); - rc = fork_and_exec("gnunet-uri", command_args); + rc = fork_and_exec(BINDIR "gnunet-uri", command_args); } else { char* command_args[] = {"gnunet-uri", "-c", configuration, data, NULL }; LOG("Running `gnunet-uri -c '%s' %s`\n", configuration, data); - rc = fork_and_exec("gnunet-uri", command_args); + rc = fork_and_exec(BINDIR "gnunet-uri", command_args); }; if (rc != 0) { -- cgit v1.2.3 From ee3ec8e4e24221db9a77e4356607e1a484f05128 Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Sun, 3 Mar 2019 10:56:01 +0100 Subject: gnunet-qr: Update documentation and scripts to changed dependencies. Requirement python-zbar is gone, and thus the requirement for Python 2.7. Instead development package for libzbar is required now. --- README | 3 +-- contrib/vagrant/bootstrap.ubuntu.sh | 2 +- doc/system_specific/FROM_SOURCE | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/README b/README index 37ca19a0d..b5ba741f2 100644 --- a/README +++ b/README @@ -75,8 +75,7 @@ These are the optional dependencies: - libpulse >= 2.0 (for experimental conversation tool) - libogg >= 1.3.0 (for experimental conversation tool) - libnss (certtool binary (for convenient installation of GNS proxy)) -- python2.7 = 2.7 (for gnunet-qr, only python 2.7 supported) -- python-zbar >= 0.10 (for gnunet-qr, not optional) +- libzbar >= 0.10 (for gnunet-qr) - TeX Live >= 2012 (for gnunet-bcd[*]) - texi2mdoc (for automatic mdoc generation [*2]) - libglpk >= 4.45 (for experimental code) diff --git a/contrib/vagrant/bootstrap.ubuntu.sh b/contrib/vagrant/bootstrap.ubuntu.sh index 6b28d3075..f0b7c454e 100644 --- a/contrib/vagrant/bootstrap.ubuntu.sh +++ b/contrib/vagrant/bootstrap.ubuntu.sh @@ -27,7 +27,7 @@ apt-get -y install zlib1g-dev # optional for gnunet-conversation # apt-get -y install libpulse-dev libopus-dev libogg-dev gstreamer1.0 # optional for gnunet-qr -apt-get -y install python-zbar +apt-get -y install libzbar-dev # optional for experimental code apt-get -y install libglpk-dev # diff --git a/doc/system_specific/FROM_SOURCE b/doc/system_specific/FROM_SOURCE index 72660798d..7b0ebf436 100644 --- a/doc/system_specific/FROM_SOURCE +++ b/doc/system_specific/FROM_SOURCE @@ -534,7 +534,7 @@ at all. We begin by installing a few Debian packages from stable:@ @example -# apt-get install gcc make python-zbar libltdl-dev libsqlite3-dev \ +# apt-get install gcc make libzbar-dev libltdl-dev libsqlite3-dev \ libunistring-dev libopus-dev libpulse-dev openssl libglpk-dev \ texlive libidn11-dev libmysqlclient-dev libpq-dev libarchive-dev \ libbz2-dev libexiv2-dev libflac-dev libgif-dev libglib2.0-dev \ @@ -778,7 +778,7 @@ as a normal user. We begin by installing a few Debian packages from stable: @example -# apt-get install gcc make python-zbar libltdl-dev libsqlite3-dev \ +# apt-get install gcc make libzbar-dev libltdl-dev libsqlite3-dev \ libunistring-dev libopus-dev libpulse-dev openssl libglpk-dev texlive \ libidn11-dev libmysqlclient-dev libpq-dev libarchive-dev libbz2-dev \ libflac-dev libgif-dev libglib2.0-dev libgtk-3-dev libmpeg2-4-dev \ -- cgit v1.2.3 From e14a51a2bb759429cb624cf4eba59454b6af24e7 Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Sun, 3 Mar 2019 22:08:53 +0100 Subject: gnunet-qr: Use GNUNET_PROGRAM_run to simplify the code. --- src/util/Makefile.am | 3 ++ src/util/gnunet-qr.c | 115 ++++++++++++++++++++++----------------------------- 2 files changed, 53 insertions(+), 65 deletions(-) diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 98997efbd..89d0462c5 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -282,6 +282,9 @@ gnunet_uri_LDADD = \ gnunet_qr_SOURCES = \ gnunet-qr.c \ gnunet-qr-utils.h +gnunet_qr_LDADD = \ + libgnunetutil.la \ + $(GN_LIBINTL) gnunet_qr_LDFLAGS= $(libzbar_LIBS) gnunet_qr_CFLAGS = $(libzbar_CFLAGS) -DBINDIR=\"@bindir@/\" diff --git a/src/util/gnunet-qr.c b/src/util/gnunet-qr.c index ea0e0fea2..b54f352d5 100644 --- a/src/util/gnunet-qr.c +++ b/src/util/gnunet-qr.c @@ -21,70 +21,34 @@ #include #include #include -#include +#include "platform.h" +#include "gnunet_util_lib.h" #include "gnunet-qr-utils.h" -static const char *usage_note = - "gnunet-qr\n" - "Scan a QR code using a video device and import\n" - "\n" - "Arguments mandatory for long options are also mandatory for short options.\n" - " -c, --config FILENAME use configuration file FILENAME\n" - " -d, --device DEVICE use device DEVICE\n" - " -s, --silent do not show preview windows\n" - " -h, --help print this help\n" - " -v, --verbose be verbose\n" - "Report bugs to gnunet-developers@gnu.org.\n" - "\n" - "GNUnet home page: https://gnunet.org/\n" - "General help using GNU software: https://www.gnu.org/gethelp/\n"; - #define LOG(fmt, ...) if (verbose == true) printf(fmt, ## __VA_ARGS__) -int main (int argc, char **argv) +// Command line options +// program exit code +static long unsigned int exit_code = 1; + +static char* device = "/dev/video0"; +static int verbose = false; +static int silent = false; + +/** + * Main function that will be run by the scheduler. + * + * @param cls closure + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param cfg configuration + */ +static void +run (void *cls, + char *const *args, + const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) { - const char* configuration = NULL; - const char* device = "/dev/video0"; - static bool verbose = false; - static bool silent = false; - - static struct option long_options[] = { - {"verbose", no_argument, 0, 'v'}, - {"silent", no_argument, 0, 's'}, - {"help", no_argument, 0, 'h'}, - {"config", required_argument, 0, 'c'}, - {"device", required_argument, 0, 'd'}, - {0, 0, 0, 0} - }; - while (1) { - int opt; - opt = getopt_long (argc, argv, "c:hd:sv", - long_options, NULL); - if (opt == -1) - break; - - switch (opt) { - case 'h': - printf(usage_note); - return 0; - case 'c': - configuration = optarg; - break; - case 'd': - device = optarg; - break; - case 's': - silent = true; - break; - case 'v': - verbose = true; - break; - default: - printf(usage_note); - return 1; - } - } - /* create a Processor */ LOG("Initializing\n"); zbar_processor_t *proc = zbar_processor_create(1); @@ -119,8 +83,6 @@ int main (int argc, char **argv) zbar_processor_set_visible(proc, 0); // extract results - int rc = 1; - const zbar_symbol_set_t* symbols = zbar_processor_get_results(proc); const zbar_symbol_t* symbol = zbar_symbol_set_first_symbol(symbols); @@ -132,14 +94,14 @@ int main (int argc, char **argv) if (configuration == NULL) { char* command_args[] = {"gnunet-uri", data, NULL }; LOG("Running `gnunet-uri %s`\n", data); - rc = fork_and_exec(BINDIR "gnunet-uri", command_args); + exit_code = fork_and_exec(BINDIR "gnunet-uri", command_args); } else { char* command_args[] = {"gnunet-uri", "-c", configuration, data, NULL }; LOG("Running `gnunet-uri -c '%s' %s`\n", configuration, data); - rc = fork_and_exec(BINDIR "gnunet-uri", command_args); + exit_code = fork_and_exec(BINDIR "gnunet-uri", command_args); }; - if (rc != 0) { + if (exit_code != 0) { printf("Failed to add URI %s\n", data); } else { printf("Added URI %s\n", data); @@ -148,6 +110,29 @@ int main (int argc, char **argv) /* clean up */ zbar_processor_destroy(proc); +}; - return(rc); + +int +main (int argc, char *const *argv) +{ + static int ret; + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_option_string ('d', "device", "DEVICE", + gettext_noop ("use video-device DEVICE (default: /dev/video0"), + &device), + GNUNET_GETOPT_option_flag ('\0', "verbose", + gettext_noop ("be verbose"), + &verbose), + GNUNET_GETOPT_option_flag ('s', "silent", + gettext_noop ("do not show preview windows"), + &silent), + GNUNET_GETOPT_OPTION_END + }; + ret = GNUNET_PROGRAM_run (argc, + argv, + "gnunet-qr", + gettext_noop ("Scan a QR code using a video device and import the uri read"), + options, &run, NULL); + return ((GNUNET_OK == ret) && (0 == exit_code)) ? 0 : 1; } -- cgit v1.2.3 From 7b85927fece0e8ae0f3a693543a8d006840a05c4 Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Tue, 5 Mar 2019 22:17:41 +0100 Subject: contrib/guix: Add package zbar (for gnunet-qr). --- contrib/guix/gnu/packages/gnunet.scm | 120 +++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/contrib/guix/gnu/packages/gnunet.scm b/contrib/guix/gnu/packages/gnunet.scm index 6089ee2fa..c10517c75 100644 --- a/contrib/guix/gnu/packages/gnunet.scm +++ b/contrib/guix/gnu/packages/gnunet.scm @@ -43,6 +43,7 @@ #:use-module (gnu packages gtk) #:use-module (gnu packages guile) #:use-module (gnu packages gstreamer) + #:use-module (gnu packages imagemagick) #:use-module (gnu packages libidn) #:use-module (gnu packages linux) #:use-module (gnu packages image) @@ -56,11 +57,14 @@ #:use-module (gnu packages perl) #:use-module (gnu packages pulseaudio) #:use-module (gnu packages python) + #:use-module (gnu packages qt) #:use-module (gnu packages databases) #:use-module (gnu packages tls) #:use-module (gnu packages video) #:use-module (gnu packages web) #:use-module (gnu packages xiph) + #:use-module (gnu packages xml) + #:use-module (gnu packages xorg) #:use-module (gnu packages backup) #:use-module ((guix licenses) #:prefix license:) #:use-module ((guix build utils) #:prefix build-utils:) @@ -191,6 +195,122 @@ authentication and support for SSL3 and TLS.") (license license:lgpl2.1+) (home-page "https://www.gnu.org/software/libmicrohttpd/"))) +(define-public zbar + (package + (name "zbar") + (version "0.22") + (source (origin + (method url-fetch) + (uri (string-append "https://www.linuxtv.org/downloads/zbar/zbar-" + version ".tar.bz2")) + (sha256 + (base32 + "1dsffj42gbasfq4sfhgirmi3lfgdygfspwzr00wbva0pf96fka8v")))) + (build-system gnu-build-system) + (outputs '("out" "gtk" "qt")) + (native-inputs + `(;;("coreutils" ,coreutils) + ("dbus" ,dbus) + ("glib:bin", glib "bin") + ("pkg-config" ,pkg-config) + ;; for testing + ("perl" ,perl) + ("python2" ,python-2.7) + )) + (inputs + `(("gtk+-2" ,gtk+-2) + ("imagemagick" ,imagemagick) + ("libjpeg" ,libjpeg) + ("libxv" ,libxv) + ;;("python2-pygtk" ,python2-pygtk) + ("qtbase" ,qtbase) + ("qt11extras" ,qtx11extras) + ("v4l-utils" ,v4l-utils) + ("xmlto" ,xmlto))) + (arguments + `(#:configure-flags + (list "--without-python2" + "--without-java" + (string-append + "--with-dbusconfdir=" (assoc-ref %outputs "out") "/etc") + "CXXFLAGS=-std=gnu++11" ;; for qt related + ;; Add the other outputs lib directories to the RUNPATH. + ;; (string-append "LDFLAGS=" + ;; "-Wl,-rpath=" (assoc-ref %outputs "gtk") "/lib" + ;; " " + ;; "-Wl,-rpath=" (assoc-ref %outputs "qt") "/lib" + ;; ) + ) + #:tests? #f + #:validate-runpath? #f + #:phases + (modify-phases %standard-phases + (add-before 'configure 'create-missing-file + ;; Create a file missing in the distribution archive, + ;; see https://github.com/mchehab/zbar/issues/35 + (lambda _ + (with-output-to-file "examples/sha1sum" + (lambda _ + (display " +a56811d078ea5cfac9be5deb4b6796177763e152 zbarimg codabar.png +cc53bf34878f769fc3611020c11e572f2853bd2a zbarimg code-128.png +7537d593ea42393a43bc0eda0a896c0e31017dd8 zbarimg code-39.png +f8f55b828eb7d0400f300be021d29293bd4a3191 zbarimg code-93.png +aebbdbed0b32d7fd72f1245e3fb384822d492062 zbarimg databar.png +9e245874d3229a575eabfdba1c668369c55960e3 zbarimg databar-exp.png +53429fc04dfcf674349e2db6cfbaf73e301fc3dc zbarimg ean-13.png +4095418b74efbb026dd730543558fefdda46f5b9 zbarimg ean-8.png +5501245dbba21c153f690787fc97ab50c973b846 zbarimg i2-5.png +b350ca7efad7a50c5ac082d5c683a8e8d8d380a7 zbarimg qr-code.png +84c0ce7072e2227073dc8bd1e5f4518d8f42ae3d zbarimg sqcode1-generated.png +84c0ce7072e2227073dc8bd1e5f4518d8f42ae3d zbarimg sqcode1-scanned.png +5ab2b518e2c9d827cedc5825d2e3c9646d43713a zbarimg -Sean2.enable ean-2.png +668fef8cb9caac34df8cb8564c2cde62e4af5e65 zbarimg -Sean5.enable ean-5.png +b567e550216fe24f7652f683146365a9fe7ee867 zbarimg -Sisbn10.enable ean-13.png +d0f37aa076d42c270f7231c5490beea5605e2ba0 zbarimg -Sisbn13.enable ean-13.png +3f041225df3b8364b5fd0daf9cf402e8a4731f9b zbarimg -Supca.enable code-upc-a.png +b350ca7efad7a50c5ac082d5c683a8e8d8d380a7 zbarimg -Stest-inverted qr-code-inverted.png\n"))))) + (replace 'check + ;; Run test-suite under a dbus session. + (lambda _ + ;; Don't fail on missing '/etc/machine-id'. + (setenv "DBUS_FATAL_WARNINGS" "0") + (invoke "dbus-launch" "make" "check"))) + (add-after 'install 'split + (lambda* (#:key inputs outputs #:allow-other-keys) + ;; Split the binaries to the various outputs. + (let* ((out (assoc-ref outputs "out")) + (gtk (assoc-ref outputs "gtk")) + (qt (assoc-ref outputs "qt")) + (mv (lambda (dest-out dir pattern) + (mkdir-p (string-append dest-out dir)) + (for-each + (lambda (file) + (rename-file + file + (string-append dest-out dir "/" (basename file)))) + (find-files (string-append out dir) pattern))))) + (mv qt "/bin" "zbarcam-qt") + (mv gtk "/bin" "zbarcam-gtk") + (mv qt "/lib" "libzbarqt\\..*") + (mv gtk "/lib" "libzbargtk\\..*") + (mv qt "/lib/pkgconfig" "zbar-qt\\.pc" ) + (mv gtk "/lib/pkgconfig" "zbar-gtk\\.pc" ) + (mv qt "/include/zbar" "QZBar.*\\.h") + (mv gtk "/include/zbar" "zbargtk\\.h")) + #t))))) + (synopsis "Read bar-codes from various sources") + (description "ZBar is a software suite for reading bar codes from +various sources, such as video streams, image files and raw intensity +sensors. It supports EAN-13/UPC-A, UPC-E, EAN-8, Code 128, Code 39, +Interleaved 2 of 5 and QR Code. Included with the library are basic +applications for decoding captured bar code images and using a video +device (eg, webcam) as a bar code scanner. For application developers, +language bindings are included for C, C++ and Perl as well as +GUI widgets for Qt and GTK") + (license license:lgpl2.1+) + (home-page "http://zbar.sourceforge.net/"))) + (define-public gnurl (package (name "gnurl") -- cgit v1.2.3 From ca946e556e3cff3bc3ab9557c9dfe6f2d11edf9f Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Tue, 5 Mar 2019 22:18:47 +0100 Subject: contrib/guix: Add zbar as dependency for package gnunet. --- contrib/guix/gnu/packages/gnunet.scm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/guix/gnu/packages/gnunet.scm b/contrib/guix/gnu/packages/gnunet.scm index c10517c75..0039eeca4 100644 --- a/contrib/guix/gnu/packages/gnunet.scm +++ b/contrib/guix/gnu/packages/gnunet.scm @@ -421,7 +421,8 @@ newspace." ("bluez" ,bluez) ; gnunet-transport ("glib" ,glib) ("libogg" ,libogg) ; gnunet-conversation - ("python-2" ,python-2))) ; tests, gnunet-qr + ("zbar" ,zbar) ; gnunet-qr + ("python-2" ,python-2))) ; tests (native-inputs `(("pkg-config" ,pkg-config) ("autoconf" ,autoconf) -- cgit v1.2.3 From 9f8374622c5b258cabb51b115a839d6cb2faeed6 Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Tue, 5 Mar 2019 23:43:25 +0100 Subject: gnunet-qr: Implement functionality of gnunet-uri, don't spawn. This copies the central part of gnunet-uri. Should better be in some shared code. Also eliminate helper lib "gnunet-qr-utils.h", which is no longer used. --- src/util/gnunet-qr-utils.h | 111 --------------------------------------------- src/util/gnunet-qr.c | 103 +++++++++++++++++++++++++++++++++++------ 2 files changed, 89 insertions(+), 125 deletions(-) delete mode 100644 src/util/gnunet-qr-utils.h diff --git a/src/util/gnunet-qr-utils.h b/src/util/gnunet-qr-utils.h deleted file mode 100644 index 6d821633c..000000000 --- a/src/util/gnunet-qr-utils.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2010, 2011, 2012 Christian Grothoff - Copyright (C) 2019 GNUnet e.V. - - GNUnet is free software: you can redistribute it and/or modify it - under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - GNUnet 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 - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - SPDX-License-Identifier: AGPL3.0-or-later -*/ - -#include "platform.h" - -// -// FIXME: These functions are copied from dns/gnunet-helper-dns.c, -// move them into a common library. Or think about implementing a even -// more elaborate version. -// - -/** - * Open '/dev/null' and make the result the given - * file descriptor. - * - * @param target_fd desired FD to point to /dev/null - * @param flags open flags (O_RDONLY, O_WRONLY) - */ -static void -open_dev_null (int target_fd, - int flags) -{ - int fd; - - fd = open ("/dev/null", flags); - if (-1 == fd) - abort (); - if (fd == target_fd) - return; - if (-1 == dup2 (fd, target_fd)) - { - (void) close (fd); - abort (); - } - (void) close (fd); -} - -/** - * Run the given command and wait for it to complete. - * - * @param file name of the binary to run - * @param cmd command line arguments (as given to 'execv') - * @return 0 on success, 1 on any error - */ -static int -fork_and_exec (const char *file, - char *const cmd[]) -{ - int status; - pid_t pid; - pid_t ret; - - pid = fork (); - if (-1 == pid) - { - fprintf (stderr, - "fork failed: %s\n", - strerror (errno)); - return 1; - } - if (0 == pid) - { - /* we are the child process */ - /* close stdin/stdout to not cause interference - with the helper's main protocol! */ - (void) close (0); - open_dev_null (0, O_RDONLY); - (void) close (1); - open_dev_null (1, O_WRONLY); - (void) execv (file, cmd); - /* can only get here on error */ - fprintf (stderr, - "exec `%s' failed: %s\n", - file, - strerror (errno)); - _exit (1); - } - /* keep running waitpid as long as the only error we get is 'EINTR' */ - while ( (-1 == (ret = waitpid (pid, &status, 0))) && - (errno == EINTR) ); - if (-1 == ret) - { - fprintf (stderr, - "waitpid failed: %s\n", - strerror (errno)); - return 1; - } - if (! (WIFEXITED (status) && (0 == WEXITSTATUS (status)))) - return 1; - /* child process completed and returned success, we're happy */ - return 0; -} - diff --git a/src/util/gnunet-qr.c b/src/util/gnunet-qr.c index b54f352d5..1106d5cb2 100644 --- a/src/util/gnunet-qr.c +++ b/src/util/gnunet-qr.c @@ -23,18 +23,102 @@ #include #include "platform.h" #include "gnunet_util_lib.h" -#include "gnunet-qr-utils.h" #define LOG(fmt, ...) if (verbose == true) printf(fmt, ## __VA_ARGS__) // Command line options -// program exit code -static long unsigned int exit_code = 1; - static char* device = "/dev/video0"; static int verbose = false; static int silent = false; +// Handler exit code +static long unsigned int exit_code = 1; + +// Helper process we started. +static struct GNUNET_OS_Process *p; + +// Pipe used to communicate shutdown via signal. +static struct GNUNET_DISK_PipeHandle *sigpipe; + + +/** + * Task triggered whenever we receive a SIGCHLD (child + * process died) or when user presses CTRL-C. + * + * @param cls closure, NULL + */ +static void +maint_child_death (void *cls) +{ + enum GNUNET_OS_ProcessStatusType type; + + if ( (GNUNET_OK != + GNUNET_OS_process_status (p, &type, &exit_code)) || + (type != GNUNET_OS_PROCESS_EXITED) ) + GNUNET_break (0 == GNUNET_OS_process_kill (p, GNUNET_TERM_SIG)); + GNUNET_OS_process_destroy (p); +} + + +/** + * Dispatch URIs to the appropriate GNUnet helper process + * + * @param cls closure + * @param uri uri to dispatch + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param cfg configuration + */ +static void +gnunet_uri (void *cls, const char *uri, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + const char *orig_uri; + const char *slash; + char *subsystem; + char *program; + struct GNUNET_SCHEDULER_Task * rt; + + orig_uri = uri; + if (0 != strncasecmp ("gnunet://", uri, strlen ("gnunet://"))) { + fprintf (stderr, + _("Invalid URI: does not start with `%s'\n"), + "gnunet://"); + return; + } + uri += strlen ("gnunet://"); + if (NULL == (slash = strchr (uri, '/'))) + { + fprintf (stderr, _("Invalid URI: fails to specify subsystem\n")); + return; + } + subsystem = GNUNET_strndup (uri, slash - uri); + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, + "uri", + subsystem, + &program)) + { + fprintf (stderr, _("No handler known for subsystem `%s'\n"), subsystem); + GNUNET_free (subsystem); + return; + } + GNUNET_free (subsystem); + rt = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, + GNUNET_DISK_pipe_handle (sigpipe, + GNUNET_DISK_PIPE_END_READ), + &maint_child_death, NULL); + p = GNUNET_OS_start_process (GNUNET_NO, 0, + NULL, NULL, NULL, + program, + program, + orig_uri, + NULL); + GNUNET_free (program); + if (NULL == p) + GNUNET_SCHEDULER_cancel (rt); +} + + /** * Main function that will be run by the scheduler. * @@ -91,16 +175,7 @@ run (void *cls, LOG("Found %s \"%s\"\n", zbar_get_symbol_name(zbar_symbol_get_type(symbol)), data); - if (configuration == NULL) { - char* command_args[] = {"gnunet-uri", data, NULL }; - LOG("Running `gnunet-uri %s`\n", data); - exit_code = fork_and_exec(BINDIR "gnunet-uri", command_args); - } else { - char* command_args[] = {"gnunet-uri", "-c", configuration, data, NULL }; - LOG("Running `gnunet-uri -c '%s' %s`\n", configuration, data); - exit_code = fork_and_exec(BINDIR "gnunet-uri", command_args); - }; - + gnunet_uri(cls, data, cfgfile, cfg); if (exit_code != 0) { printf("Failed to add URI %s\n", data); } else { -- cgit v1.2.3 From c7ec9cc03a383a33315c9cc126ebbf73135a17cc Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Sat, 2 Mar 2019 11:00:53 +0100 Subject: gnunet-qr: Reimplement in C - yet only a proof of concept. Still to-do: * running gnunet-uri * Proper error handling * integration into build system (automake) Reimplementing in C was chosen since - official zbar python-bindings support python 2 only, - none of the other bindings available at PyPI supports the high-level "processor" interface which gnunet-qr uses - implementing bindings for zbar using ctypes required addin a lot of low-level error handling code, thus implementing in C seamed to be easier, - the programm is short, thus re-implementing is not such complicated, and - this allows to reduce the number of dependencies (here: another Python version), which should ease porting to other plattforms (zbar is a dependency anyway). --- src/util/gnunet-qr.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/util/gnunet-qr.in | 46 --------------- src/util/gnunet-qr.py | 110 ---------------------------------- 3 files changed, 160 insertions(+), 156 deletions(-) create mode 100644 src/util/gnunet-qr.c delete mode 100755 src/util/gnunet-qr.in delete mode 100644 src/util/gnunet-qr.py diff --git a/src/util/gnunet-qr.c b/src/util/gnunet-qr.c new file mode 100644 index 000000000..c02212a51 --- /dev/null +++ b/src/util/gnunet-qr.c @@ -0,0 +1,160 @@ +/* + This file is part of GNUnet. + Copyright (C) 2013-2019 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet 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 + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later +*/ + +#include +#include +#include +#include + +static const char *usage_note = + "gnunet-qr\n" + "Scan a QR code using a video device and import\n" + "\n" + "Arguments mandatory for long options are also mandatory for short options.\n" + " -c, --config FILENAME use configuration file FILENAME\n" + " -d, --device DEVICE use device DEVICE\n" + " -s, --silent do not show preview windows\n" + " -h, --help print this help\n" + " -v, --verbose be verbose\n" + "Report bugs to gnunet-developers@gnu.org.\n" + "\n" + "GNUnet home page: https://gnunet.org/\n" + "General help using GNU software: https://www.gnu.org/gethelp/\n"; + +int main (int argc, char **argv) +{ + const char* configuration = NULL; + const char* device = "/dev/video0"; + static bool verbose = false; + static bool silent = false; + + static struct option long_options[] = { + {"verbose", no_argument, 0, 'v'}, + {"silent", no_argument, 0, 's'}, + {"help", no_argument, 0, 'h'}, + {"config", required_argument, 0, 'c'}, + {"device", required_argument, 0, 'd'}, + {0, 0, 0, 0} + }; + while (1) { + int opt; + opt = getopt_long (argc, argv, "c:hd:sv", + long_options, NULL); + if (opt == -1) + break; + + switch (opt) { + case 'h': + printf(usage_note); + return 0; + case 'c': + configuration = optarg; + break; + case 'd': + device = optarg; + break; + case 's': + silent = true; + break; + case 'v': + verbose = true; + break; + default: + printf(usage_note); + return 1; + } + } + + /* create a Processor */ + if (verbose == true) { + printf("Initializing\n"); + }; + zbar_processor_t *proc = zbar_processor_create(1); + + // FIXME: Wrap all this into a function which returns an error on + // failure. And here ensure the processor is destroyed at the end. + + /* configure the Processor */ + zbar_processor_parse_config(proc, "enable"); + + /* initialize the Processor */ + if (verbose == true) { + printf("Opening video device %s\n", device); + }; + // FIXME: error handling + zbar_processor_init(proc, device, 1); + + /* enable the preview window */ + zbar_processor_set_visible(proc, 1); + zbar_processor_set_active(proc, 1); + + /* keep scanning until user provides key/mouse input */ + //zbar_processor_user_wait(proc, -1); + + // read at least one barcode (or until window closed) + if (verbose == true) { + printf("Capturing\n"); + } + int n; + n = zbar_process_one(proc, -1); + if (verbose == true) { + printf("Got %i images\n", n); + }; + // FIXME: Error handling (n = -1) + + // hide the preview window + zbar_processor_set_active(proc, 0); + zbar_processor_set_visible(proc, 0); + + // extract results + int rc = 1; + + const zbar_symbol_set_t* symbols = zbar_processor_get_results(proc); + const zbar_symbol_t* symbol = zbar_symbol_set_first_symbol(symbols); + + if (symbol != NULL) { + const char* data = zbar_symbol_get_data(symbol); + if (verbose = true) { + zbar_symbol_type_t type = + printf("Found %s \"%s\"\n", + zbar_get_symbol_name(zbar_symbol_get_type(symbol)), data); + } + /* TODO + args = ["gnunet-uri", + // FIXME: "-c", configuration, + data]; + if (verbose = true) { + // TODO: print arguments: + printf("Running `%s %s %s %s`", *args, "", ""); // FIXME variable num args + }; + rc = popen("gnunet-uri", *args); + */ + if (rc != 0) { + printf("Failed to add URI %s\n", data); + } else { + printf("Added URI %s\n", data); + } + } + + /* clean up */ + zbar_processor_destroy(proc); + + return(rc); +} diff --git a/src/util/gnunet-qr.in b/src/util/gnunet-qr.in deleted file mode 100755 index ce7a19b69..000000000 --- a/src/util/gnunet-qr.in +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh -# -# From curl's buildconf, making this script subject to the -# curl license: https://curl.haxx.se/docs/copyright.html -# Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. -# Copyright (C) 2019 GNUnet e.V. - -# findtool works like which without relying on which (which is a problem -# for some limited shells. -findtool(){ - file="$1" - - if { echo "$file" | grep "/" >/dev/null 2>&1; } then - # when file is given with a path check it first - if test -f "$file"; then - echo "$file" - return - fi - fi - - old_IFS=$IFS; IFS=':' - for path in $PATH - do - IFS=$old_IFS - # echo "checks for $file in $path" >&2 - if test "$path" -a "$path" != '.' -a -f "$path/$file"; then - echo "$path/$file" - return - fi - done - IFS=$old_IFS -} - -# end curl licensed code -pythonize=`findtool python2.7 2>/dev/null` -if test ! -x "$pythonize"; then - pythonize=`findtool ${PYTHON2:-python2.7}` -fi - -if test -z "$pythonize"; then - echo "ERROR: python2.7 not found." - echo " You need python2.7 installed." - exit 1 -fi - -${pythonize} @PREFIX@/share/gnunet/gnunet-qr.py $@ diff --git a/src/util/gnunet-qr.py b/src/util/gnunet-qr.py deleted file mode 100644 index 0ee0b9507..000000000 --- a/src/util/gnunet-qr.py +++ /dev/null @@ -1,110 +0,0 @@ -import sys -import getopt -import subprocess -from sys import argv -try: - import zbar -except ImportError as e: - print('Cannot run gnunet-qr, please install the zbar module.') - print('For Debian, you can obtain it as "python-zbar".') - print('Upstream: http://zbar.sourceforge.net/') - sys.exit(1) - - -def help(): - print('gnunet-qr\n\ -Scan a QR code using a video device and import\n\ -Arguments mandatory for long options are also mandatory for short options.\n\ - -c, --config FILENAME use configuration file FILENAME\n\ - -d, --device DEVICE use device DEVICE\n\ - -s, --silent do not show preview windows\n\ - -h, --help print this help\n\ - -v, --verbose be verbose\n\ -Report bugs to gnunet-developers@gnu.org.\n\ -GNUnet home page: https://gnunet.org/\n\ -General help using GNU software: https://www.gnu.org/gethelp/') - - -if __name__ == '__main__': - configuration = '' - device = '/dev/video0' - url = '' - verbose = False - silent = False - # Parse arguments - try: - opts, args = getopt.gnu_getopt(sys.argv[1:], "c:hd:sv", ["config", "help", "device", "silent", "verbose"]) - except getopt.GetoptError as e: - help() - print(str(e)) - exit(1) - for o, a in opts: - if o in ("-h", "--help"): - help() - sys.exit(0) - elif o in ("-c", "--config"): - configuration = a - elif o in ("-d", "--device"): - device = a - elif o in ("-s", "--silent"): - silent = True - elif o in ("-v", "--verbose"): - verbose = True - if (True == verbose): - print('Initializing') - # create a Processor - proc = zbar.Processor() - - # configure the Processor - proc.parse_config('enable') - - # initialize the Processor - try: - if (True == verbose): - print('Opening video device ' + device) - proc.init(device) - except Exception as e: - print('Failed to open device ' + device) - exit(1) - - # enable the preview window - # if (True == silent): - # proc.visible = True - # else: - # proc.visible = False - - proc.visible = True - # read at least one barcode (or until window closed) - try: - if (True == verbose): - print('Capturing') - proc.process_one() - except Exception as e: - # Window was closed without finding code - exit(1) - - # hide the preview window - proc.visible = False - - # extract results - for symbol in proc.results: - # do something useful with results - if (True == verbose): - print('Found ', symbol.type, ' symbol ', '"%s"' % symbol.data) - args = list() - args.append("gnunet-uri") - if (configuration != ''): - args.append(str("-c " + str(configuration))) - args.append(str(symbol.data)) - cmd = '' - for a in args: - cmd += " " + str(a) - if (verbose): - print('Running `' + cmd +'`') - res = subprocess.call(args) - if (0 != res): - print('Failed to add URI ' + str(symbol.data)) - else: - print('Added URI ' + str(symbol.data)) - exit(res) - exit(1) -- cgit v1.2.3 From 2a302e5716711e4bae796ac3c272972859a3a122 Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Sat, 2 Mar 2019 12:37:46 +0100 Subject: gnunet-qr: Simplify verbose messaging. --- src/util/gnunet-qr.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/src/util/gnunet-qr.c b/src/util/gnunet-qr.c index c02212a51..b375d20a7 100644 --- a/src/util/gnunet-qr.c +++ b/src/util/gnunet-qr.c @@ -38,6 +38,8 @@ static const char *usage_note = "GNUnet home page: https://gnunet.org/\n" "General help using GNU software: https://www.gnu.org/gethelp/\n"; +#define LOG(fmt, ...) if (verbose == true) printf(fmt, ## __VA_ARGS__) + int main (int argc, char **argv) { const char* configuration = NULL; @@ -83,9 +85,7 @@ int main (int argc, char **argv) } /* create a Processor */ - if (verbose == true) { - printf("Initializing\n"); - }; + LOG("Initializing\n"); zbar_processor_t *proc = zbar_processor_create(1); // FIXME: Wrap all this into a function which returns an error on @@ -95,9 +95,7 @@ int main (int argc, char **argv) zbar_processor_parse_config(proc, "enable"); /* initialize the Processor */ - if (verbose == true) { - printf("Opening video device %s\n", device); - }; + LOG("Opening video device %s\n", device); // FIXME: error handling zbar_processor_init(proc, device, 1); @@ -109,14 +107,10 @@ int main (int argc, char **argv) //zbar_processor_user_wait(proc, -1); // read at least one barcode (or until window closed) - if (verbose == true) { - printf("Capturing\n"); - } + LOG("Capturing\n"); int n; n = zbar_process_one(proc, -1); - if (verbose == true) { - printf("Got %i images\n", n); - }; + LOG("Got %i images\n", n); // FIXME: Error handling (n = -1) // hide the preview window @@ -131,11 +125,9 @@ int main (int argc, char **argv) if (symbol != NULL) { const char* data = zbar_symbol_get_data(symbol); - if (verbose = true) { - zbar_symbol_type_t type = - printf("Found %s \"%s\"\n", - zbar_get_symbol_name(zbar_symbol_get_type(symbol)), data); - } + LOG("Found %s \"%s\"\n", + zbar_get_symbol_name(zbar_symbol_get_type(symbol)), data); + /* TODO args = ["gnunet-uri", // FIXME: "-c", configuration, -- cgit v1.2.3 From 6f4f14aa56a879587ae731751d51ea062e3d0956 Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Sat, 2 Mar 2019 17:26:35 +0100 Subject: Add helper lib "gnunet-qr-utils.h". These functions are copied from dns/gnunet-helper-dns.c, move them into a common library. Or think about implementing a even more elaborate version. --- src/util/gnunet-qr-utils.h | 111 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 src/util/gnunet-qr-utils.h diff --git a/src/util/gnunet-qr-utils.h b/src/util/gnunet-qr-utils.h new file mode 100644 index 000000000..6d821633c --- /dev/null +++ b/src/util/gnunet-qr-utils.h @@ -0,0 +1,111 @@ +/* + This file is part of GNUnet. + Copyright (C) 2010, 2011, 2012 Christian Grothoff + Copyright (C) 2019 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet 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 + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later +*/ + +#include "platform.h" + +// +// FIXME: These functions are copied from dns/gnunet-helper-dns.c, +// move them into a common library. Or think about implementing a even +// more elaborate version. +// + +/** + * Open '/dev/null' and make the result the given + * file descriptor. + * + * @param target_fd desired FD to point to /dev/null + * @param flags open flags (O_RDONLY, O_WRONLY) + */ +static void +open_dev_null (int target_fd, + int flags) +{ + int fd; + + fd = open ("/dev/null", flags); + if (-1 == fd) + abort (); + if (fd == target_fd) + return; + if (-1 == dup2 (fd, target_fd)) + { + (void) close (fd); + abort (); + } + (void) close (fd); +} + +/** + * Run the given command and wait for it to complete. + * + * @param file name of the binary to run + * @param cmd command line arguments (as given to 'execv') + * @return 0 on success, 1 on any error + */ +static int +fork_and_exec (const char *file, + char *const cmd[]) +{ + int status; + pid_t pid; + pid_t ret; + + pid = fork (); + if (-1 == pid) + { + fprintf (stderr, + "fork failed: %s\n", + strerror (errno)); + return 1; + } + if (0 == pid) + { + /* we are the child process */ + /* close stdin/stdout to not cause interference + with the helper's main protocol! */ + (void) close (0); + open_dev_null (0, O_RDONLY); + (void) close (1); + open_dev_null (1, O_WRONLY); + (void) execv (file, cmd); + /* can only get here on error */ + fprintf (stderr, + "exec `%s' failed: %s\n", + file, + strerror (errno)); + _exit (1); + } + /* keep running waitpid as long as the only error we get is 'EINTR' */ + while ( (-1 == (ret = waitpid (pid, &status, 0))) && + (errno == EINTR) ); + if (-1 == ret) + { + fprintf (stderr, + "waitpid failed: %s\n", + strerror (errno)); + return 1; + } + if (! (WIFEXITED (status) && (0 == WEXITSTATUS (status)))) + return 1; + /* child process completed and returned success, we're happy */ + return 0; +} + -- cgit v1.2.3 From e729040833049ada5bb642e1084b603ec428742d Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Sat, 2 Mar 2019 17:27:36 +0100 Subject: gnunet-qr: Actually run gnunet-uri. --- src/util/gnunet-qr.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/util/gnunet-qr.c b/src/util/gnunet-qr.c index b375d20a7..c8919dae4 100644 --- a/src/util/gnunet-qr.c +++ b/src/util/gnunet-qr.c @@ -22,6 +22,7 @@ #include #include #include +#include "gnunet-qr-utils.h" static const char *usage_note = "gnunet-qr\n" @@ -128,16 +129,16 @@ int main (int argc, char **argv) LOG("Found %s \"%s\"\n", zbar_get_symbol_name(zbar_symbol_get_type(symbol)), data); - /* TODO - args = ["gnunet-uri", - // FIXME: "-c", configuration, - data]; - if (verbose = true) { - // TODO: print arguments: - printf("Running `%s %s %s %s`", *args, "", ""); // FIXME variable num args + if (configuration == NULL) { + char* command_args[] = {"gnunet-uri", data, NULL }; + LOG("Running `gnunet-uri %s`\n", data); + rc = fork_and_exec("gnunet-uri", command_args); + } else { + char* command_args[] = {"gnunet-uri", "-c", configuration, data, NULL }; + LOG("Running `gnunet-uri -c '%s' %s`\n", configuration, data); + rc = fork_and_exec("gnunet-uri", command_args); }; - rc = popen("gnunet-uri", *args); - */ + if (rc != 0) { printf("Failed to add URI %s\n", data); } else { -- cgit v1.2.3 From 7dd9b38648dc428d728a966026f0e3d0b105c536 Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Sun, 3 Mar 2019 01:04:08 +0100 Subject: Add Hartmut Goebel to the AUTHORS file. --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 829a0803e..3c337737f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -49,6 +49,7 @@ Eric Noack Felix von Leitner [ diet libc snprintf for win32 ] Gerd Knorr Glenn McGrath +Hartmut Goebel Hendrik Pagenhardt Heikki Lindholm Igor Wronsky -- cgit v1.2.3 From e35cd05d91025475e31c88eb8f46a6ef723f3dae Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Sun, 3 Mar 2019 02:04:16 +0100 Subject: configure.ac: Add check for libzbar (using pkgconfig). libzbar is required for gnunet-qr, which is optional. --- configure.ac | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/configure.ac b/configure.ac index 96d7cbbc0..793612df3 100644 --- a/configure.ac +++ b/configure.ac @@ -1431,6 +1431,10 @@ AC_DEFINE_UNQUOTED([HAVE_GNUTLS], $gnutls, [We have GnuTLS]) AM_CONDITIONAL(HAVE_GNUTLS_DANE, test x$gnutls_dane = x1) AC_DEFINE_UNQUOTED([HAVE_GNUTLS_DANE], $gnutls_dane, [We have GnuTLS with DANE support]) +# check for libzbar library, required for optional gnunet-qr +PKG_CHECK_MODULES([libzbar], [zbar >= 0.10], [have_zbar=1 ], [have_zbar=0 ]) +AM_CONDITIONAL([HAVE_ZBAR], [test "$have_zbar" = 1]) + # Test if we are building for superMUC AC_MSG_CHECKING(if GNUnet is being configured to run on the SuperMUC) @@ -1938,6 +1942,10 @@ AS_IF([test x$gnutls != xtrue], [AS_IF([test "x$gnutls_dane" != "x1"], [AC_MSG_NOTICE([WARNING: GnuTLS has no DANE support, DANE validation will not be possible])])]) +# warn user if libzbar is not found +AS_IF([test "$have_zbar" = 0], + [AC_MSG_NOTICE([WARNING: zbar not found, gnunet-qr will not be built.])]) + # java ports AS_IF([test "x$enable_java_ports" = "xyes"], [AC_MSG_NOTICE([NOTICE: Opening ports for gnunet-java bindings by default.])]) -- cgit v1.2.3 From 4cecaf9d96ef62430ad81fe5e7a24ca68cd27095 Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Sun, 3 Mar 2019 02:06:31 +0100 Subject: gnunet-qr: Add into Makefile.am and pofiles, --- po/POTFILES.in | 1 + src/util/Makefile.am | 29 ++++++++++++++--------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/po/POTFILES.in b/po/POTFILES.in index fe788fdae..67c22aaed 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -480,6 +480,7 @@ src/util/gnunet-config.c src/util/gnunet-config-diff.c src/util/gnunet-ecc.c src/util/gnunet-helper-w32-console.c +src/util/gnunet-qr.c src/util/gnunet-resolver.c src/util/gnunet-scrypt.c src/util/gnunet-service-resolver.c diff --git a/src/util/Makefile.am b/src/util/Makefile.am index cd14fb4ca..02dede372 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -204,26 +204,15 @@ libexec_PROGRAMS = \ gnunet-timeout \ $(W32CONSOLEHELPER) -do_subst = $(SED) -e 's,[@]PREFIX[@],$(prefix),g' - -gnunet-qr: gnunet-qr.in Makefile - $(do_subst) < $(srcdir)/gnunet-qr.in > gnunet-qr - chmod +x gnunet-qr - -CLEANFILES = gnunet-qr - -pkgdata_DATA = \ - gnunet-qr.py - -bin_SCRIPTS =\ - gnunet-qr - bin_PROGRAMS = \ gnunet-resolver \ gnunet-config \ $(GNUNET_ECC) \ $(GNUNET_SCRYPT) \ gnunet-uri +if HAVE_ZBAR +bin_PROGRAMS += gnunet-qr +endif noinst_PROGRAMS = \ gnunet-config-diff \ @@ -283,13 +272,19 @@ gnunet_config_LDADD = \ libgnunetutil.la \ $(GN_LIBINTL) - gnunet_uri_SOURCES = \ gnunet-uri.c gnunet_uri_LDADD = \ libgnunetutil.la \ $(GN_LIBINTL) + +gnunet_qr_SOURCES = \ + gnunet-qr.c \ + gnunet-qr-utils.h +gnunet_qr_LDFLAGS= $(libzbar_LIBS) +gnunet_qr_CFLAGS = $(libzbar_CFLAGS) + plugin_LTLIBRARIES = \ libgnunet_plugin_test.la @@ -670,6 +665,10 @@ EXTRA_DIST = \ test_program_data.conf \ test_resolver_api_data.conf \ test_service_data.conf \ +<<<<<<< HEAD test_speedup_data.conf \ gnunet-qr.in \ gnunet-qr.py +======= + test_speedup_data.conf +>>>>>>> gnunet-qr: Add into Makefile.am and pofiles, -- cgit v1.2.3 From 8f07aace2f2842b506350e608616c8055a2c71f9 Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Sun, 3 Mar 2019 02:10:13 +0100 Subject: gnunet-qr: Use the `gnunet-uri` binary installed into PREFIX. This helps keeping environments concise and functional package managers like guix this will ensure `gnunet-uri` from the same environment is used. --- src/util/Makefile.am | 2 +- src/util/gnunet-qr.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 02dede372..548af6305 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -283,7 +283,7 @@ gnunet_qr_SOURCES = \ gnunet-qr.c \ gnunet-qr-utils.h gnunet_qr_LDFLAGS= $(libzbar_LIBS) -gnunet_qr_CFLAGS = $(libzbar_CFLAGS) +gnunet_qr_CFLAGS = $(libzbar_CFLAGS) -DBINDIR=\"@bindir@/\" plugin_LTLIBRARIES = \ libgnunet_plugin_test.la diff --git a/src/util/gnunet-qr.c b/src/util/gnunet-qr.c index c8919dae4..ea0e0fea2 100644 --- a/src/util/gnunet-qr.c +++ b/src/util/gnunet-qr.c @@ -132,11 +132,11 @@ int main (int argc, char **argv) if (configuration == NULL) { char* command_args[] = {"gnunet-uri", data, NULL }; LOG("Running `gnunet-uri %s`\n", data); - rc = fork_and_exec("gnunet-uri", command_args); + rc = fork_and_exec(BINDIR "gnunet-uri", command_args); } else { char* command_args[] = {"gnunet-uri", "-c", configuration, data, NULL }; LOG("Running `gnunet-uri -c '%s' %s`\n", configuration, data); - rc = fork_and_exec("gnunet-uri", command_args); + rc = fork_and_exec(BINDIR "gnunet-uri", command_args); }; if (rc != 0) { -- cgit v1.2.3 From 88c55363e17beaa1c2d7344b3d4a90e1d639dc67 Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Sun, 3 Mar 2019 10:56:01 +0100 Subject: gnunet-qr: Update documentation and scripts to changed dependencies. Requirement python-zbar is gone, and thus the requirement for Python 2.7. Instead development package for libzbar is required now. --- README | 2 +- contrib/vagrant/bootstrap.ubuntu.sh | 2 +- doc/system_specific/FROM_SOURCE | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README b/README index 0e676b491..1d31a0a6a 100644 --- a/README +++ b/README @@ -124,6 +124,7 @@ These are the optional dependencies: - libogg >= 1.3.0 (for experimental conversation tool) - libnss (certtool binary (for convenient installation of GNS proxy)) +- libzbar >= 0.10 (for gnunet-qr) - libpbc >= 0.5.14 (for Attribute-Based Encryption and Identity Provider functionality) - libgabe (for Attribute-Based Encryption and @@ -135,7 +136,6 @@ These are the optional dependencies: - perl5 (for some utilities) - python2.7 = 2.7 (for gnunet-qr, only python 2.7 supported) -- python-zbar >= 0.10 (for gnunet-qr, not optional) - TeX Live >= 2012 (for gnunet-bcd[*]) - texi2mdoc (for automatic mdoc generation [*2]) diff --git a/contrib/vagrant/bootstrap.ubuntu.sh b/contrib/vagrant/bootstrap.ubuntu.sh index 6b28d3075..f0b7c454e 100644 --- a/contrib/vagrant/bootstrap.ubuntu.sh +++ b/contrib/vagrant/bootstrap.ubuntu.sh @@ -27,7 +27,7 @@ apt-get -y install zlib1g-dev # optional for gnunet-conversation # apt-get -y install libpulse-dev libopus-dev libogg-dev gstreamer1.0 # optional for gnunet-qr -apt-get -y install python-zbar +apt-get -y install libzbar-dev # optional for experimental code apt-get -y install libglpk-dev # diff --git a/doc/system_specific/FROM_SOURCE b/doc/system_specific/FROM_SOURCE index 72660798d..7b0ebf436 100644 --- a/doc/system_specific/FROM_SOURCE +++ b/doc/system_specific/FROM_SOURCE @@ -534,7 +534,7 @@ at all. We begin by installing a few Debian packages from stable:@ @example -# apt-get install gcc make python-zbar libltdl-dev libsqlite3-dev \ +# apt-get install gcc make libzbar-dev libltdl-dev libsqlite3-dev \ libunistring-dev libopus-dev libpulse-dev openssl libglpk-dev \ texlive libidn11-dev libmysqlclient-dev libpq-dev libarchive-dev \ libbz2-dev libexiv2-dev libflac-dev libgif-dev libglib2.0-dev \ @@ -778,7 +778,7 @@ as a normal user. We begin by installing a few Debian packages from stable: @example -# apt-get install gcc make python-zbar libltdl-dev libsqlite3-dev \ +# apt-get install gcc make libzbar-dev libltdl-dev libsqlite3-dev \ libunistring-dev libopus-dev libpulse-dev openssl libglpk-dev texlive \ libidn11-dev libmysqlclient-dev libpq-dev libarchive-dev libbz2-dev \ libflac-dev libgif-dev libglib2.0-dev libgtk-3-dev libmpeg2-4-dev \ -- cgit v1.2.3 From ac123283d47ff2418111cb194a7aa92e9dfa0cd0 Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Sun, 3 Mar 2019 22:08:53 +0100 Subject: gnunet-qr: Use GNUNET_PROGRAM_run to simplify the code. --- src/util/Makefile.am | 3 ++ src/util/gnunet-qr.c | 115 ++++++++++++++++++++++----------------------------- 2 files changed, 53 insertions(+), 65 deletions(-) diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 548af6305..a5a7ff288 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -282,6 +282,9 @@ gnunet_uri_LDADD = \ gnunet_qr_SOURCES = \ gnunet-qr.c \ gnunet-qr-utils.h +gnunet_qr_LDADD = \ + libgnunetutil.la \ + $(GN_LIBINTL) gnunet_qr_LDFLAGS= $(libzbar_LIBS) gnunet_qr_CFLAGS = $(libzbar_CFLAGS) -DBINDIR=\"@bindir@/\" diff --git a/src/util/gnunet-qr.c b/src/util/gnunet-qr.c index ea0e0fea2..b54f352d5 100644 --- a/src/util/gnunet-qr.c +++ b/src/util/gnunet-qr.c @@ -21,70 +21,34 @@ #include #include #include -#include +#include "platform.h" +#include "gnunet_util_lib.h" #include "gnunet-qr-utils.h" -static const char *usage_note = - "gnunet-qr\n" - "Scan a QR code using a video device and import\n" - "\n" - "Arguments mandatory for long options are also mandatory for short options.\n" - " -c, --config FILENAME use configuration file FILENAME\n" - " -d, --device DEVICE use device DEVICE\n" - " -s, --silent do not show preview windows\n" - " -h, --help print this help\n" - " -v, --verbose be verbose\n" - "Report bugs to gnunet-developers@gnu.org.\n" - "\n" - "GNUnet home page: https://gnunet.org/\n" - "General help using GNU software: https://www.gnu.org/gethelp/\n"; - #define LOG(fmt, ...) if (verbose == true) printf(fmt, ## __VA_ARGS__) -int main (int argc, char **argv) +// Command line options +// program exit code +static long unsigned int exit_code = 1; + +static char* device = "/dev/video0"; +static int verbose = false; +static int silent = false; + +/** + * Main function that will be run by the scheduler. + * + * @param cls closure + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param cfg configuration + */ +static void +run (void *cls, + char *const *args, + const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) { - const char* configuration = NULL; - const char* device = "/dev/video0"; - static bool verbose = false; - static bool silent = false; - - static struct option long_options[] = { - {"verbose", no_argument, 0, 'v'}, - {"silent", no_argument, 0, 's'}, - {"help", no_argument, 0, 'h'}, - {"config", required_argument, 0, 'c'}, - {"device", required_argument, 0, 'd'}, - {0, 0, 0, 0} - }; - while (1) { - int opt; - opt = getopt_long (argc, argv, "c:hd:sv", - long_options, NULL); - if (opt == -1) - break; - - switch (opt) { - case 'h': - printf(usage_note); - return 0; - case 'c': - configuration = optarg; - break; - case 'd': - device = optarg; - break; - case 's': - silent = true; - break; - case 'v': - verbose = true; - break; - default: - printf(usage_note); - return 1; - } - } - /* create a Processor */ LOG("Initializing\n"); zbar_processor_t *proc = zbar_processor_create(1); @@ -119,8 +83,6 @@ int main (int argc, char **argv) zbar_processor_set_visible(proc, 0); // extract results - int rc = 1; - const zbar_symbol_set_t* symbols = zbar_processor_get_results(proc); const zbar_symbol_t* symbol = zbar_symbol_set_first_symbol(symbols); @@ -132,14 +94,14 @@ int main (int argc, char **argv) if (configuration == NULL) { char* command_args[] = {"gnunet-uri", data, NULL }; LOG("Running `gnunet-uri %s`\n", data); - rc = fork_and_exec(BINDIR "gnunet-uri", command_args); + exit_code = fork_and_exec(BINDIR "gnunet-uri", command_args); } else { char* command_args[] = {"gnunet-uri", "-c", configuration, data, NULL }; LOG("Running `gnunet-uri -c '%s' %s`\n", configuration, data); - rc = fork_and_exec(BINDIR "gnunet-uri", command_args); + exit_code = fork_and_exec(BINDIR "gnunet-uri", command_args); }; - if (rc != 0) { + if (exit_code != 0) { printf("Failed to add URI %s\n", data); } else { printf("Added URI %s\n", data); @@ -148,6 +110,29 @@ int main (int argc, char **argv) /* clean up */ zbar_processor_destroy(proc); +}; - return(rc); + +int +main (int argc, char *const *argv) +{ + static int ret; + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_option_string ('d', "device", "DEVICE", + gettext_noop ("use video-device DEVICE (default: /dev/video0"), + &device), + GNUNET_GETOPT_option_flag ('\0', "verbose", + gettext_noop ("be verbose"), + &verbose), + GNUNET_GETOPT_option_flag ('s', "silent", + gettext_noop ("do not show preview windows"), + &silent), + GNUNET_GETOPT_OPTION_END + }; + ret = GNUNET_PROGRAM_run (argc, + argv, + "gnunet-qr", + gettext_noop ("Scan a QR code using a video device and import the uri read"), + options, &run, NULL); + return ((GNUNET_OK == ret) && (0 == exit_code)) ? 0 : 1; } -- cgit v1.2.3 From 6dd5119b1b7d4b0d313a7272feaddfac3cfd808f Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Tue, 5 Mar 2019 22:17:41 +0100 Subject: contrib/guix: Add package zbar (for gnunet-qr). --- contrib/guix/gnu/packages/gnunet.scm | 120 +++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/contrib/guix/gnu/packages/gnunet.scm b/contrib/guix/gnu/packages/gnunet.scm index 6089ee2fa..c10517c75 100644 --- a/contrib/guix/gnu/packages/gnunet.scm +++ b/contrib/guix/gnu/packages/gnunet.scm @@ -43,6 +43,7 @@ #:use-module (gnu packages gtk) #:use-module (gnu packages guile) #:use-module (gnu packages gstreamer) + #:use-module (gnu packages imagemagick) #:use-module (gnu packages libidn) #:use-module (gnu packages linux) #:use-module (gnu packages image) @@ -56,11 +57,14 @@ #:use-module (gnu packages perl) #:use-module (gnu packages pulseaudio) #:use-module (gnu packages python) + #:use-module (gnu packages qt) #:use-module (gnu packages databases) #:use-module (gnu packages tls) #:use-module (gnu packages video) #:use-module (gnu packages web) #:use-module (gnu packages xiph) + #:use-module (gnu packages xml) + #:use-module (gnu packages xorg) #:use-module (gnu packages backup) #:use-module ((guix licenses) #:prefix license:) #:use-module ((guix build utils) #:prefix build-utils:) @@ -191,6 +195,122 @@ authentication and support for SSL3 and TLS.") (license license:lgpl2.1+) (home-page "https://www.gnu.org/software/libmicrohttpd/"))) +(define-public zbar + (package + (name "zbar") + (version "0.22") + (source (origin + (method url-fetch) + (uri (string-append "https://www.linuxtv.org/downloads/zbar/zbar-" + version ".tar.bz2")) + (sha256 + (base32 + "1dsffj42gbasfq4sfhgirmi3lfgdygfspwzr00wbva0pf96fka8v")))) + (build-system gnu-build-system) + (outputs '("out" "gtk" "qt")) + (native-inputs + `(;;("coreutils" ,coreutils) + ("dbus" ,dbus) + ("glib:bin", glib "bin") + ("pkg-config" ,pkg-config) + ;; for testing + ("perl" ,perl) + ("python2" ,python-2.7) + )) + (inputs + `(("gtk+-2" ,gtk+-2) + ("imagemagick" ,imagemagick) + ("libjpeg" ,libjpeg) + ("libxv" ,libxv) + ;;("python2-pygtk" ,python2-pygtk) + ("qtbase" ,qtbase) + ("qt11extras" ,qtx11extras) + ("v4l-utils" ,v4l-utils) + ("xmlto" ,xmlto))) + (arguments + `(#:configure-flags + (list "--without-python2" + "--without-java" + (string-append + "--with-dbusconfdir=" (assoc-ref %outputs "out") "/etc") + "CXXFLAGS=-std=gnu++11" ;; for qt related + ;; Add the other outputs lib directories to the RUNPATH. + ;; (string-append "LDFLAGS=" + ;; "-Wl,-rpath=" (assoc-ref %outputs "gtk") "/lib" + ;; " " + ;; "-Wl,-rpath=" (assoc-ref %outputs "qt") "/lib" + ;; ) + ) + #:tests? #f + #:validate-runpath? #f + #:phases + (modify-phases %standard-phases + (add-before 'configure 'create-missing-file + ;; Create a file missing in the distribution archive, + ;; see https://github.com/mchehab/zbar/issues/35 + (lambda _ + (with-output-to-file "examples/sha1sum" + (lambda _ + (display " +a56811d078ea5cfac9be5deb4b6796177763e152 zbarimg codabar.png +cc53bf34878f769fc3611020c11e572f2853bd2a zbarimg code-128.png +7537d593ea42393a43bc0eda0a896c0e31017dd8 zbarimg code-39.png +f8f55b828eb7d0400f300be021d29293bd4a3191 zbarimg code-93.png +aebbdbed0b32d7fd72f1245e3fb384822d492062 zbarimg databar.png +9e245874d3229a575eabfdba1c668369c55960e3 zbarimg databar-exp.png +53429fc04dfcf674349e2db6cfbaf73e301fc3dc zbarimg ean-13.png +4095418b74efbb026dd730543558fefdda46f5b9 zbarimg ean-8.png +5501245dbba21c153f690787fc97ab50c973b846 zbarimg i2-5.png +b350ca7efad7a50c5ac082d5c683a8e8d8d380a7 zbarimg qr-code.png +84c0ce7072e2227073dc8bd1e5f4518d8f42ae3d zbarimg sqcode1-generated.png +84c0ce7072e2227073dc8bd1e5f4518d8f42ae3d zbarimg sqcode1-scanned.png +5ab2b518e2c9d827cedc5825d2e3c9646d43713a zbarimg -Sean2.enable ean-2.png +668fef8cb9caac34df8cb8564c2cde62e4af5e65 zbarimg -Sean5.enable ean-5.png +b567e550216fe24f7652f683146365a9fe7ee867 zbarimg -Sisbn10.enable ean-13.png +d0f37aa076d42c270f7231c5490beea5605e2ba0 zbarimg -Sisbn13.enable ean-13.png +3f041225df3b8364b5fd0daf9cf402e8a4731f9b zbarimg -Supca.enable code-upc-a.png +b350ca7efad7a50c5ac082d5c683a8e8d8d380a7 zbarimg -Stest-inverted qr-code-inverted.png\n"))))) + (replace 'check + ;; Run test-suite under a dbus session. + (lambda _ + ;; Don't fail on missing '/etc/machine-id'. + (setenv "DBUS_FATAL_WARNINGS" "0") + (invoke "dbus-launch" "make" "check"))) + (add-after 'install 'split + (lambda* (#:key inputs outputs #:allow-other-keys) + ;; Split the binaries to the various outputs. + (let* ((out (assoc-ref outputs "out")) + (gtk (assoc-ref outputs "gtk")) + (qt (assoc-ref outputs "qt")) + (mv (lambda (dest-out dir pattern) + (mkdir-p (string-append dest-out dir)) + (for-each + (lambda (file) + (rename-file + file + (string-append dest-out dir "/" (basename file)))) + (find-files (string-append out dir) pattern))))) + (mv qt "/bin" "zbarcam-qt") + (mv gtk "/bin" "zbarcam-gtk") + (mv qt "/lib" "libzbarqt\\..*") + (mv gtk "/lib" "libzbargtk\\..*") + (mv qt "/lib/pkgconfig" "zbar-qt\\.pc" ) + (mv gtk "/lib/pkgconfig" "zbar-gtk\\.pc" ) + (mv qt "/include/zbar" "QZBar.*\\.h") + (mv gtk "/include/zbar" "zbargtk\\.h")) + #t))))) + (synopsis "Read bar-codes from various sources") + (description "ZBar is a software suite for reading bar codes from +various sources, such as video streams, image files and raw intensity +sensors. It supports EAN-13/UPC-A, UPC-E, EAN-8, Code 128, Code 39, +Interleaved 2 of 5 and QR Code. Included with the library are basic +applications for decoding captured bar code images and using a video +device (eg, webcam) as a bar code scanner. For application developers, +language bindings are included for C, C++ and Perl as well as +GUI widgets for Qt and GTK") + (license license:lgpl2.1+) + (home-page "http://zbar.sourceforge.net/"))) + (define-public gnurl (package (name "gnurl") -- cgit v1.2.3 From e04ce03cf8fd6b166823c04e48cfc1b80b73a9fd Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Tue, 5 Mar 2019 22:18:47 +0100 Subject: contrib/guix: Add zbar as dependency for package gnunet. --- contrib/guix/gnu/packages/gnunet.scm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/guix/gnu/packages/gnunet.scm b/contrib/guix/gnu/packages/gnunet.scm index c10517c75..0039eeca4 100644 --- a/contrib/guix/gnu/packages/gnunet.scm +++ b/contrib/guix/gnu/packages/gnunet.scm @@ -421,7 +421,8 @@ newspace." ("bluez" ,bluez) ; gnunet-transport ("glib" ,glib) ("libogg" ,libogg) ; gnunet-conversation - ("python-2" ,python-2))) ; tests, gnunet-qr + ("zbar" ,zbar) ; gnunet-qr + ("python-2" ,python-2))) ; tests (native-inputs `(("pkg-config" ,pkg-config) ("autoconf" ,autoconf) -- cgit v1.2.3 From 9915d8f8a7b67b6eff91a8afbcb99c3b33df95f5 Mon Sep 17 00:00:00 2001 From: Hartmut Goebel Date: Tue, 5 Mar 2019 23:43:25 +0100 Subject: gnunet-qr: Implement functionality of gnunet-uri, don't spawn. This copies the central part of gnunet-uri. Should better be in some shared code. Also eliminate helper lib "gnunet-qr-utils.h", which is no longer used. --- src/util/gnunet-qr-utils.h | 111 --------------------------------------------- src/util/gnunet-qr.c | 103 +++++++++++++++++++++++++++++++++++------ 2 files changed, 89 insertions(+), 125 deletions(-) delete mode 100644 src/util/gnunet-qr-utils.h diff --git a/src/util/gnunet-qr-utils.h b/src/util/gnunet-qr-utils.h deleted file mode 100644 index 6d821633c..000000000 --- a/src/util/gnunet-qr-utils.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2010, 2011, 2012 Christian Grothoff - Copyright (C) 2019 GNUnet e.V. - - GNUnet is free software: you can redistribute it and/or modify it - under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - GNUnet 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 - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - SPDX-License-Identifier: AGPL3.0-or-later -*/ - -#include "platform.h" - -// -// FIXME: These functions are copied from dns/gnunet-helper-dns.c, -// move them into a common library. Or think about implementing a even -// more elaborate version. -// - -/** - * Open '/dev/null' and make the result the given - * file descriptor. - * - * @param target_fd desired FD to point to /dev/null - * @param flags open flags (O_RDONLY, O_WRONLY) - */ -static void -open_dev_null (int target_fd, - int flags) -{ - int fd; - - fd = open ("/dev/null", flags); - if (-1 == fd) - abort (); - if (fd == target_fd) - return; - if (-1 == dup2 (fd, target_fd)) - { - (void) close (fd); - abort (); - } - (void) close (fd); -} - -/** - * Run the given command and wait for it to complete. - * - * @param file name of the binary to run - * @param cmd command line arguments (as given to 'execv') - * @return 0 on success, 1 on any error - */ -static int -fork_and_exec (const char *file, - char *const cmd[]) -{ - int status; - pid_t pid; - pid_t ret; - - pid = fork (); - if (-1 == pid) - { - fprintf (stderr, - "fork failed: %s\n", - strerror (errno)); - return 1; - } - if (0 == pid) - { - /* we are the child process */ - /* close stdin/stdout to not cause interference - with the helper's main protocol! */ - (void) close (0); - open_dev_null (0, O_RDONLY); - (void) close (1); - open_dev_null (1, O_WRONLY); - (void) execv (file, cmd); - /* can only get here on error */ - fprintf (stderr, - "exec `%s' failed: %s\n", - file, - strerror (errno)); - _exit (1); - } - /* keep running waitpid as long as the only error we get is 'EINTR' */ - while ( (-1 == (ret = waitpid (pid, &status, 0))) && - (errno == EINTR) ); - if (-1 == ret) - { - fprintf (stderr, - "waitpid failed: %s\n", - strerror (errno)); - return 1; - } - if (! (WIFEXITED (status) && (0 == WEXITSTATUS (status)))) - return 1; - /* child process completed and returned success, we're happy */ - return 0; -} - diff --git a/src/util/gnunet-qr.c b/src/util/gnunet-qr.c index b54f352d5..1106d5cb2 100644 --- a/src/util/gnunet-qr.c +++ b/src/util/gnunet-qr.c @@ -23,18 +23,102 @@ #include #include "platform.h" #include "gnunet_util_lib.h" -#include "gnunet-qr-utils.h" #define LOG(fmt, ...) if (verbose == true) printf(fmt, ## __VA_ARGS__) // Command line options -// program exit code -static long unsigned int exit_code = 1; - static char* device = "/dev/video0"; static int verbose = false; static int silent = false; +// Handler exit code +static long unsigned int exit_code = 1; + +// Helper process we started. +static struct GNUNET_OS_Process *p; + +// Pipe used to communicate shutdown via signal. +static struct GNUNET_DISK_PipeHandle *sigpipe; + + +/** + * Task triggered whenever we receive a SIGCHLD (child + * process died) or when user presses CTRL-C. + * + * @param cls closure, NULL + */ +static void +maint_child_death (void *cls) +{ + enum GNUNET_OS_ProcessStatusType type; + + if ( (GNUNET_OK != + GNUNET_OS_process_status (p, &type, &exit_code)) || + (type != GNUNET_OS_PROCESS_EXITED) ) + GNUNET_break (0 == GNUNET_OS_process_kill (p, GNUNET_TERM_SIG)); + GNUNET_OS_process_destroy (p); +} + + +/** + * Dispatch URIs to the appropriate GNUnet helper process + * + * @param cls closure + * @param uri uri to dispatch + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param cfg configuration + */ +static void +gnunet_uri (void *cls, const char *uri, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + const char *orig_uri; + const char *slash; + char *subsystem; + char *program; + struct GNUNET_SCHEDULER_Task * rt; + + orig_uri = uri; + if (0 != strncasecmp ("gnunet://", uri, strlen ("gnunet://"))) { + fprintf (stderr, + _("Invalid URI: does not start with `%s'\n"), + "gnunet://"); + return; + } + uri += strlen ("gnunet://"); + if (NULL == (slash = strchr (uri, '/'))) + { + fprintf (stderr, _("Invalid URI: fails to specify subsystem\n")); + return; + } + subsystem = GNUNET_strndup (uri, slash - uri); + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, + "uri", + subsystem, + &program)) + { + fprintf (stderr, _("No handler known for subsystem `%s'\n"), subsystem); + GNUNET_free (subsystem); + return; + } + GNUNET_free (subsystem); + rt = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, + GNUNET_DISK_pipe_handle (sigpipe, + GNUNET_DISK_PIPE_END_READ), + &maint_child_death, NULL); + p = GNUNET_OS_start_process (GNUNET_NO, 0, + NULL, NULL, NULL, + program, + program, + orig_uri, + NULL); + GNUNET_free (program); + if (NULL == p) + GNUNET_SCHEDULER_cancel (rt); +} + + /** * Main function that will be run by the scheduler. * @@ -91,16 +175,7 @@ run (void *cls, LOG("Found %s \"%s\"\n", zbar_get_symbol_name(zbar_symbol_get_type(symbol)), data); - if (configuration == NULL) { - char* command_args[] = {"gnunet-uri", data, NULL }; - LOG("Running `gnunet-uri %s`\n", data); - exit_code = fork_and_exec(BINDIR "gnunet-uri", command_args); - } else { - char* command_args[] = {"gnunet-uri", "-c", configuration, data, NULL }; - LOG("Running `gnunet-uri -c '%s' %s`\n", configuration, data); - exit_code = fork_and_exec(BINDIR "gnunet-uri", command_args); - }; - + gnunet_uri(cls, data, cfgfile, cfg); if (exit_code != 0) { printf("Failed to add URI %s\n", data); } else { -- cgit v1.2.3 From 311795caa390858b627428629a6621def8949a7c Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 3 Apr 2019 13:42:07 +0200 Subject: add error handling for gnunet-qr --- src/util/gnunet-qr.c | 221 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 161 insertions(+), 60 deletions(-) diff --git a/src/util/gnunet-qr.c b/src/util/gnunet-qr.c index 1106d5cb2..fa95d6c05 100644 --- a/src/util/gnunet-qr.c +++ b/src/util/gnunet-qr.c @@ -17,7 +17,12 @@ SPDX-License-Identifier: AGPL3.0-or-later */ - +/** + * @file util/gnunet-qr.c + * @author Hartmut Goebel (original implementation) + * @author Martin Schanzenbach (integrate gnunet-uri) + * @author Christian Grothoff (error handling) + */ #include #include #include @@ -26,18 +31,35 @@ #define LOG(fmt, ...) if (verbose == true) printf(fmt, ## __VA_ARGS__) -// Command line options +/** + * Video device to capture from. Sane default for GNU/Linux systems. + */ static char* device = "/dev/video0"; + +/** + * --verbose option + */ static int verbose = false; + +/** + * --silent option + */ static int silent = false; -// Handler exit code +/** + * Handler exit code + */ static long unsigned int exit_code = 1; -// Helper process we started. +/** + * Helper process we started. + */ static struct GNUNET_OS_Process *p; -// Pipe used to communicate shutdown via signal. + +/** + * Pipe used to communicate child death via signal. + */ static struct GNUNET_DISK_PipeHandle *sigpipe; @@ -69,8 +91,10 @@ maint_child_death (void *cls) * @param cfg configuration */ static void -gnunet_uri (void *cls, const char *uri, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) +gnunet_uri (void *cls, + const char *uri, + const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) { const char *orig_uri; const char *slash; @@ -88,7 +112,8 @@ gnunet_uri (void *cls, const char *uri, const char *cfgfile, uri += strlen ("gnunet://"); if (NULL == (slash = strchr (uri, '/'))) { - fprintf (stderr, _("Invalid URI: fails to specify subsystem\n")); + fprintf (stderr, + _("Invalid URI: fails to specify subsystem\n")); return; } subsystem = GNUNET_strndup (uri, slash - uri); @@ -98,7 +123,9 @@ gnunet_uri (void *cls, const char *uri, const char *cfgfile, subsystem, &program)) { - fprintf (stderr, _("No handler known for subsystem `%s'\n"), subsystem); + fprintf (stderr, + _("No handler known for subsystem `%s'\n"), + subsystem); GNUNET_free (subsystem); return; } @@ -119,6 +146,111 @@ gnunet_uri (void *cls, const char *uri, const char *cfgfile, } +/** + * Obtain QR code 'symbol' from @a proc. + * + * @param proc zbar processor to use + * @return NULL on error + */ +static const zbar_symbol_t * +get_symbol (zbar_processor_t *proc) +{ + const zbar_symbol_set_t* symbols; + int rc; + int n; + + if (0 != + zbar_processor_parse_config (proc, "enable")) + { + GNUNET_break (0); + return NULL; + } + + /* initialize the Processor */ + if (0 != + (rc = zbar_processor_init(proc, device, 1))) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to open device `%s': %d\n", + device, + rc); + return NULL; + } + + /* enable the preview window */ + if ( (0 != (rc = zbar_processor_set_visible (proc, 1))) || + (0 != (rc = zbar_processor_set_active(proc, 1))) ) + { + GNUNET_break (0); + return NULL; + } + + /* read at least one barcode (or until window closed) */ + LOG ("Capturing\n"); + n = zbar_process_one (proc, -1); + + /* hide the preview window */ + (void) zbar_processor_set_active (proc, 0); + (void) zbar_processor_set_visible (proc, 0); + if (-1 == n) + return NULL; /* likely user closed the window */ + LOG ("Got %i images\n", + n); + /* extract results */ + symbols = zbar_processor_get_results (proc); + if (NULL == symbols) + { + GNUNET_break (0); + return NULL; + } + return zbar_symbol_set_first_symbol (symbols); +} + + +/** + * Run zbar QR code parser. + * + * @return NULL on error, otherwise the URI that we found + */ +static char * +run_zbar () +{ + zbar_processor_t *proc; + const char *data; + char *ret; + const zbar_symbol_t* symbol; + + /* configure the Processor */ + proc = zbar_processor_create (1); + if (NULL == proc) + { + GNUNET_break (0); + return NULL; + } + + symbol = get_symbol (proc); + if (NULL == symbol) + { + zbar_processor_destroy (proc); + return NULL; + } + data = zbar_symbol_get_data (symbol); + if (NULL == data) + { + GNUNET_break (0); + zbar_processor_destroy (proc); + return NULL; + } + LOG ("Found %s \"%s\"\n", + zbar_get_symbol_name (zbar_symbol_get_type(symbol)), + data); + ret = GNUNET_strdup (data); + /* clean up */ + zbar_processor_destroy(proc); + return ret; +} + + /** * Main function that will be run by the scheduler. * @@ -133,65 +265,33 @@ run (void *cls, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { - /* create a Processor */ - LOG("Initializing\n"); - zbar_processor_t *proc = zbar_processor_create(1); - - // FIXME: Wrap all this into a function which returns an error on - // failure. And here ensure the processor is destroyed at the end. - - /* configure the Processor */ - zbar_processor_parse_config(proc, "enable"); - - /* initialize the Processor */ - LOG("Opening video device %s\n", device); - // FIXME: error handling - zbar_processor_init(proc, device, 1); - - /* enable the preview window */ - zbar_processor_set_visible(proc, 1); - zbar_processor_set_active(proc, 1); - - /* keep scanning until user provides key/mouse input */ - //zbar_processor_user_wait(proc, -1); + char *data; - // read at least one barcode (or until window closed) - LOG("Capturing\n"); - int n; - n = zbar_process_one(proc, -1); - LOG("Got %i images\n", n); - // FIXME: Error handling (n = -1) - - // hide the preview window - zbar_processor_set_active(proc, 0); - zbar_processor_set_visible(proc, 0); - - // extract results - const zbar_symbol_set_t* symbols = zbar_processor_get_results(proc); - const zbar_symbol_t* symbol = zbar_symbol_set_first_symbol(symbols); - - if (symbol != NULL) { - const char* data = zbar_symbol_get_data(symbol); - LOG("Found %s \"%s\"\n", - zbar_get_symbol_name(zbar_symbol_get_type(symbol)), data); - - gnunet_uri(cls, data, cfgfile, cfg); - if (exit_code != 0) { - printf("Failed to add URI %s\n", data); - } else { - printf("Added URI %s\n", data); - } + data = run_zbar (); + if (NULL == data) + return; + gnunet_uri (cls, + data, + cfgfile, + cfg); + if (exit_code != 0) + { + printf ("Failed to add URI %s\n", + data); } - - /* clean up */ - zbar_processor_destroy(proc); + else + { + printf ("Added URI %s\n", + data); + } + GNUNET_free (data); }; int main (int argc, char *const *argv) { - static int ret; + int ret; struct GNUNET_GETOPT_CommandLineOption options[] = { GNUNET_GETOPT_option_string ('d', "device", "DEVICE", gettext_noop ("use video-device DEVICE (default: /dev/video0"), @@ -204,6 +304,7 @@ main (int argc, char *const *argv) &silent), GNUNET_GETOPT_OPTION_END }; + ret = GNUNET_PROGRAM_run (argc, argv, "gnunet-qr", -- cgit v1.2.3 From af57a5b89896f734e1ebef947625647fcf5d79bd Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 3 Apr 2019 13:53:09 +0200 Subject: fix libzbar detection --- configure.ac | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 793612df3..ac8ed60c2 100644 --- a/configure.ac +++ b/configure.ac @@ -534,6 +534,39 @@ else AC_DEFINE([HAVE_LIBBLUETOOTH],[0],[Lacking bluetooth library]) fi +# check for zbar library +zbar=0 +AC_MSG_CHECKING(for libzbar) +AC_ARG_WITH(zbar, + [ --with-zbar=PFX base of libzbar installation], + [AC_MSG_RESULT([$with_zbar]) + case $with_zbar in + no) + ;; + yes) + AC_CHECK_HEADERS(zbar.h, + AC_CHECK_LIB([zbar], [zbar_processor_create], + zbar=1)) + ;; + *) + LDFLAGS="-L$with_zbar/lib $LDFLAGS" + CPPFLAGS="-I$with_zbar/include $CPPFLAGS" + AC_CHECK_HEADERS(zbar.h, + AC_CHECK_LIB([zbar], [zbar_processor_create], + EXT_LIB_PATH="-L$with_zbar/lib $EXT_LIB_PATH" + zbar=1)) + ;; + esac + ], + [AC_MSG_RESULT([--with-zbar not specified]) + AC_CHECK_HEADERS(zbar.h, + AC_CHECK_LIB([zbar], [zbar_processor_create], + zbar=1))]) +AM_CONDITIONAL(HAVE_ZBAR, [test "$zbar" = 1]) +AS_IF([test "x$zbar" = x1], + [AC_DEFINE([HAVE_ZBAR],[1],[Have zbar library])], + [AC_DEFINE([HAVE_ZBAR],[0],[Lacking zbar library])]) + # check for jansson library jansson=0 AC_MSG_CHECKING(for libjansson) @@ -563,6 +596,7 @@ AC_ARG_WITH(jansson, AC_CHECK_LIB([jansson], [json_loads], jansson=1))]) AM_CONDITIONAL(HAVE_JANSSON, [test "$jansson" = 1]) +AM_CONDITIONAL(HAVE_JSON, [test x$jansson = x1]) AS_IF([test "x$jansson" = x1], [AC_DEFINE([HAVE_JANSSON],[1],[Have jansson library])], [AC_DEFINE([HAVE_JANSSON],[0],[Lacking jansson library])]) @@ -1431,9 +1465,6 @@ AC_DEFINE_UNQUOTED([HAVE_GNUTLS], $gnutls, [We have GnuTLS]) AM_CONDITIONAL(HAVE_GNUTLS_DANE, test x$gnutls_dane = x1) AC_DEFINE_UNQUOTED([HAVE_GNUTLS_DANE], $gnutls_dane, [We have GnuTLS with DANE support]) -# check for libzbar library, required for optional gnunet-qr -PKG_CHECK_MODULES([libzbar], [zbar >= 0.10], [have_zbar=1 ], [have_zbar=0 ]) -AM_CONDITIONAL([HAVE_ZBAR], [test "$have_zbar" = 1]) # Test if we are building for superMUC -- cgit v1.2.3