aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHartmut Goebel <h.goebel@crazy-compilers.com>2019-03-05 23:43:25 +0100
committerChristian Grothoff <christian@grothoff.org>2019-04-03 13:44:54 +0200
commit9915d8f8a7b67b6eff91a8afbcb99c3b33df95f5 (patch)
tree75483e986c8fc0b48fd64f7d40a840ec7baaff34
parente04ce03cf8fd6b166823c04e48cfc1b80b73a9fd (diff)
downloadgnunet-9915d8f8a7b67b6eff91a8afbcb99c3b33df95f5.tar.gz
gnunet-9915d8f8a7b67b6eff91a8afbcb99c3b33df95f5.zip
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.
-rw-r--r--src/util/gnunet-qr-utils.h111
-rw-r--r--src/util/gnunet-qr.c103
2 files changed, 89 insertions, 125 deletions
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 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010, 2011, 2012 Christian Grothoff
4 Copyright (C) 2019 GNUnet e.V.
5
6 GNUnet is free software: you can redistribute it and/or modify it
7 under the terms of the GNU Affero General Public License as published
8 by the Free Software Foundation, either version 3 of the License,
9 or (at your option) any later version.
10
11 GNUnet is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Affero General Public License for more details.
15
16 You should have received a copy of the GNU Affero General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19 SPDX-License-Identifier: AGPL3.0-or-later
20*/
21
22#include "platform.h"
23
24//
25// FIXME: These functions are copied from dns/gnunet-helper-dns.c,
26// move them into a common library. Or think about implementing a even
27// more elaborate version.
28//
29
30/**
31 * Open '/dev/null' and make the result the given
32 * file descriptor.
33 *
34 * @param target_fd desired FD to point to /dev/null
35 * @param flags open flags (O_RDONLY, O_WRONLY)
36 */
37static void
38open_dev_null (int target_fd,
39 int flags)
40{
41 int fd;
42
43 fd = open ("/dev/null", flags);
44 if (-1 == fd)
45 abort ();
46 if (fd == target_fd)
47 return;
48 if (-1 == dup2 (fd, target_fd))
49 {
50 (void) close (fd);
51 abort ();
52 }
53 (void) close (fd);
54}
55
56/**
57 * Run the given command and wait for it to complete.
58 *
59 * @param file name of the binary to run
60 * @param cmd command line arguments (as given to 'execv')
61 * @return 0 on success, 1 on any error
62 */
63static int
64fork_and_exec (const char *file,
65 char *const cmd[])
66{
67 int status;
68 pid_t pid;
69 pid_t ret;
70
71 pid = fork ();
72 if (-1 == pid)
73 {
74 fprintf (stderr,
75 "fork failed: %s\n",
76 strerror (errno));
77 return 1;
78 }
79 if (0 == pid)
80 {
81 /* we are the child process */
82 /* close stdin/stdout to not cause interference
83 with the helper's main protocol! */
84 (void) close (0);
85 open_dev_null (0, O_RDONLY);
86 (void) close (1);
87 open_dev_null (1, O_WRONLY);
88 (void) execv (file, cmd);
89 /* can only get here on error */
90 fprintf (stderr,
91 "exec `%s' failed: %s\n",
92 file,
93 strerror (errno));
94 _exit (1);
95 }
96 /* keep running waitpid as long as the only error we get is 'EINTR' */
97 while ( (-1 == (ret = waitpid (pid, &status, 0))) &&
98 (errno == EINTR) );
99 if (-1 == ret)
100 {
101 fprintf (stderr,
102 "waitpid failed: %s\n",
103 strerror (errno));
104 return 1;
105 }
106 if (! (WIFEXITED (status) && (0 == WEXITSTATUS (status))))
107 return 1;
108 /* child process completed and returned success, we're happy */
109 return 0;
110}
111
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 @@
23#include <stdbool.h> 23#include <stdbool.h>
24#include "platform.h" 24#include "platform.h"
25#include "gnunet_util_lib.h" 25#include "gnunet_util_lib.h"
26#include "gnunet-qr-utils.h"
27 26
28#define LOG(fmt, ...) if (verbose == true) printf(fmt, ## __VA_ARGS__) 27#define LOG(fmt, ...) if (verbose == true) printf(fmt, ## __VA_ARGS__)
29 28
30// Command line options 29// Command line options
31// program exit code
32static long unsigned int exit_code = 1;
33
34static char* device = "/dev/video0"; 30static char* device = "/dev/video0";
35static int verbose = false; 31static int verbose = false;
36static int silent = false; 32static int silent = false;
37 33
34// Handler exit code
35static long unsigned int exit_code = 1;
36
37// Helper process we started.
38static struct GNUNET_OS_Process *p;
39
40// Pipe used to communicate shutdown via signal.
41static struct GNUNET_DISK_PipeHandle *sigpipe;
42
43
44/**
45 * Task triggered whenever we receive a SIGCHLD (child
46 * process died) or when user presses CTRL-C.
47 *
48 * @param cls closure, NULL
49 */
50static void
51maint_child_death (void *cls)
52{
53 enum GNUNET_OS_ProcessStatusType type;
54
55 if ( (GNUNET_OK !=
56 GNUNET_OS_process_status (p, &type, &exit_code)) ||
57 (type != GNUNET_OS_PROCESS_EXITED) )
58 GNUNET_break (0 == GNUNET_OS_process_kill (p, GNUNET_TERM_SIG));
59 GNUNET_OS_process_destroy (p);
60}
61
62
63/**
64 * Dispatch URIs to the appropriate GNUnet helper process
65 *
66 * @param cls closure
67 * @param uri uri to dispatch
68 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
69 * @param cfg configuration
70 */
71static void
72gnunet_uri (void *cls, const char *uri, const char *cfgfile,
73 const struct GNUNET_CONFIGURATION_Handle *cfg)
74{
75 const char *orig_uri;
76 const char *slash;
77 char *subsystem;
78 char *program;
79 struct GNUNET_SCHEDULER_Task * rt;
80
81 orig_uri = uri;
82 if (0 != strncasecmp ("gnunet://", uri, strlen ("gnunet://"))) {
83 fprintf (stderr,
84 _("Invalid URI: does not start with `%s'\n"),
85 "gnunet://");
86 return;
87 }
88 uri += strlen ("gnunet://");
89 if (NULL == (slash = strchr (uri, '/')))
90 {
91 fprintf (stderr, _("Invalid URI: fails to specify subsystem\n"));
92 return;
93 }
94 subsystem = GNUNET_strndup (uri, slash - uri);
95 if (GNUNET_OK !=
96 GNUNET_CONFIGURATION_get_value_string (cfg,
97 "uri",
98 subsystem,
99 &program))
100 {
101 fprintf (stderr, _("No handler known for subsystem `%s'\n"), subsystem);
102 GNUNET_free (subsystem);
103 return;
104 }
105 GNUNET_free (subsystem);
106 rt = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
107 GNUNET_DISK_pipe_handle (sigpipe,
108 GNUNET_DISK_PIPE_END_READ),
109 &maint_child_death, NULL);
110 p = GNUNET_OS_start_process (GNUNET_NO, 0,
111 NULL, NULL, NULL,
112 program,
113 program,
114 orig_uri,
115 NULL);
116 GNUNET_free (program);
117 if (NULL == p)
118 GNUNET_SCHEDULER_cancel (rt);
119}
120
121
38/** 122/**
39 * Main function that will be run by the scheduler. 123 * Main function that will be run by the scheduler.
40 * 124 *
@@ -91,16 +175,7 @@ run (void *cls,
91 LOG("Found %s \"%s\"\n", 175 LOG("Found %s \"%s\"\n",
92 zbar_get_symbol_name(zbar_symbol_get_type(symbol)), data); 176 zbar_get_symbol_name(zbar_symbol_get_type(symbol)), data);
93 177
94 if (configuration == NULL) { 178 gnunet_uri(cls, data, cfgfile, cfg);
95 char* command_args[] = {"gnunet-uri", data, NULL };
96 LOG("Running `gnunet-uri %s`\n", data);
97 exit_code = fork_and_exec(BINDIR "gnunet-uri", command_args);
98 } else {
99 char* command_args[] = {"gnunet-uri", "-c", configuration, data, NULL };
100 LOG("Running `gnunet-uri -c '%s' %s`\n", configuration, data);
101 exit_code = fork_and_exec(BINDIR "gnunet-uri", command_args);
102 };
103
104 if (exit_code != 0) { 179 if (exit_code != 0) {
105 printf("Failed to add URI %s\n", data); 180 printf("Failed to add URI %s\n", data);
106 } else { 181 } else {