summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorng0 <ng0@n0.is>2019-04-03 12:19:26 +0000
committerng0 <ng0@n0.is>2019-04-03 12:19:26 +0000
commitcc3d270b525cdc4756fa706221fd4ad510539700 (patch)
treed7199304b17651d285dd09d41c2bc7fbc70950e9 /src
parentf002ecb549ec33da77e4a034ad1cffe27922112d (diff)
parente96ba10771f6c6932607624c4645cf50b3d5b71f (diff)
Merge branch 'master' of gnunet.org:gnunet
Diffstat (limited to 'src')
-rw-r--r--src/util/Makefile.am32
-rw-r--r--src/util/gnunet-qr.c314
-rwxr-xr-xsrc/util/gnunet-qr.in46
-rw-r--r--src/util/gnunet-qr.py110
4 files changed, 328 insertions, 174 deletions
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index cd14fb4ca..89d0462c5 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,22 @@ 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_LDADD = \
+ libgnunetutil.la \
+ $(GN_LIBINTL)
+gnunet_qr_LDFLAGS= $(libzbar_LIBS)
+gnunet_qr_CFLAGS = $(libzbar_CFLAGS) -DBINDIR=\"@bindir@/\"
+
plugin_LTLIBRARIES = \
libgnunet_plugin_test.la
@@ -670,6 +668,4 @@ EXTRA_DIST = \
test_program_data.conf \
test_resolver_api_data.conf \
test_service_data.conf \
- test_speedup_data.conf \
- gnunet-qr.in \
- gnunet-qr.py
+ test_speedup_data.conf
diff --git a/src/util/gnunet-qr.c b/src/util/gnunet-qr.c
new file mode 100644
index 000000000..fa95d6c05
--- /dev/null
+++ b/src/util/gnunet-qr.c
@@ -0,0 +1,314 @@
+/*
+ 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 <http://www.gnu.org/licenses/>.
+
+ 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 <stdio.h>
+#include <zbar.h>
+#include <stdbool.h>
+#include "platform.h"
+#include "gnunet_util_lib.h"
+
+#define LOG(fmt, ...) if (verbose == true) printf(fmt, ## __VA_ARGS__)
+
+/**
+ * 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
+ */
+static long unsigned int exit_code = 1;
+
+/**
+ * Helper process we started.
+ */
+static struct GNUNET_OS_Process *p;
+
+
+/**
+ * Pipe used to communicate child death 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);
+}
+
+
+/**
+ * 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.
+ *
+ * @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)
+{
+ char *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);
+ }
+ else
+ {
+ printf ("Added URI %s\n",
+ data);
+ }
+ GNUNET_free (data);
+};
+
+
+int
+main (int argc, char *const *argv)
+{
+ 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;
+}
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, <daniel@haxx.se>, 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)