diff options
author | Hartmut Goebel <h.goebel@crazy-compilers.com> | 2019-03-05 23:43:25 +0100 |
---|---|---|
committer | Hartmut Goebel <h.goebel@crazy-compilers.com> | 2019-03-13 18:22:11 +0100 |
commit | 9f8374622c5b258cabb51b115a839d6cb2faeed6 (patch) | |
tree | 162050af38b2aed01658ced5cf8492336e1ecf98 /src/util | |
parent | ca946e556e3cff3bc3ab9557c9dfe6f2d11edf9f (diff) | |
download | gnunet-9f8374622c5b258cabb51b115a839d6cb2faeed6.tar.gz gnunet-9f8374622c5b258cabb51b115a839d6cb2faeed6.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.
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/gnunet-qr-utils.h | 111 | ||||
-rw-r--r-- | src/util/gnunet-qr.c | 103 |
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 | */ | ||
37 | static void | ||
38 | open_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 | */ | ||
63 | static int | ||
64 | fork_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 | ||
32 | static long unsigned int exit_code = 1; | ||
33 | |||
34 | static char* device = "/dev/video0"; | 30 | static char* device = "/dev/video0"; |
35 | static int verbose = false; | 31 | static int verbose = false; |
36 | static int silent = false; | 32 | static int silent = false; |
37 | 33 | ||
34 | // Handler exit code | ||
35 | static long unsigned int exit_code = 1; | ||
36 | |||
37 | // Helper process we started. | ||
38 | static struct GNUNET_OS_Process *p; | ||
39 | |||
40 | // Pipe used to communicate shutdown via signal. | ||
41 | static 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 | */ | ||
50 | static void | ||
51 | maint_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 | */ | ||
71 | static void | ||
72 | gnunet_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 { |