diff options
author | Christian Grothoff <christian@grothoff.org> | 2019-04-03 13:42:07 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2019-04-03 13:44:54 +0200 |
commit | 311795caa390858b627428629a6621def8949a7c (patch) | |
tree | 4e6dd9a9577ef2cd85b6e27b2dfcf1f3b9560a1c /src/util | |
parent | 9915d8f8a7b67b6eff91a8afbcb99c3b33df95f5 (diff) | |
download | gnunet-311795caa390858b627428629a6621def8949a7c.tar.gz gnunet-311795caa390858b627428629a6621def8949a7c.zip |
add error handling for gnunet-qr
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/gnunet-qr.c | 221 |
1 files 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 @@ | |||
17 | 17 | ||
18 | SPDX-License-Identifier: AGPL3.0-or-later | 18 | SPDX-License-Identifier: AGPL3.0-or-later |
19 | */ | 19 | */ |
20 | 20 | /** | |
21 | * @file util/gnunet-qr.c | ||
22 | * @author Hartmut Goebel (original implementation) | ||
23 | * @author Martin Schanzenbach (integrate gnunet-uri) | ||
24 | * @author Christian Grothoff (error handling) | ||
25 | */ | ||
21 | #include <stdio.h> | 26 | #include <stdio.h> |
22 | #include <zbar.h> | 27 | #include <zbar.h> |
23 | #include <stdbool.h> | 28 | #include <stdbool.h> |
@@ -26,18 +31,35 @@ | |||
26 | 31 | ||
27 | #define LOG(fmt, ...) if (verbose == true) printf(fmt, ## __VA_ARGS__) | 32 | #define LOG(fmt, ...) if (verbose == true) printf(fmt, ## __VA_ARGS__) |
28 | 33 | ||
29 | // Command line options | 34 | /** |
35 | * Video device to capture from. Sane default for GNU/Linux systems. | ||
36 | */ | ||
30 | static char* device = "/dev/video0"; | 37 | static char* device = "/dev/video0"; |
38 | |||
39 | /** | ||
40 | * --verbose option | ||
41 | */ | ||
31 | static int verbose = false; | 42 | static int verbose = false; |
43 | |||
44 | /** | ||
45 | * --silent option | ||
46 | */ | ||
32 | static int silent = false; | 47 | static int silent = false; |
33 | 48 | ||
34 | // Handler exit code | 49 | /** |
50 | * Handler exit code | ||
51 | */ | ||
35 | static long unsigned int exit_code = 1; | 52 | static long unsigned int exit_code = 1; |
36 | 53 | ||
37 | // Helper process we started. | 54 | /** |
55 | * Helper process we started. | ||
56 | */ | ||
38 | static struct GNUNET_OS_Process *p; | 57 | static struct GNUNET_OS_Process *p; |
39 | 58 | ||
40 | // Pipe used to communicate shutdown via signal. | 59 | |
60 | /** | ||
61 | * Pipe used to communicate child death via signal. | ||
62 | */ | ||
41 | static struct GNUNET_DISK_PipeHandle *sigpipe; | 63 | static struct GNUNET_DISK_PipeHandle *sigpipe; |
42 | 64 | ||
43 | 65 | ||
@@ -69,8 +91,10 @@ maint_child_death (void *cls) | |||
69 | * @param cfg configuration | 91 | * @param cfg configuration |
70 | */ | 92 | */ |
71 | static void | 93 | static void |
72 | gnunet_uri (void *cls, const char *uri, const char *cfgfile, | 94 | gnunet_uri (void *cls, |
73 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 95 | const char *uri, |
96 | const char *cfgfile, | ||
97 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
74 | { | 98 | { |
75 | const char *orig_uri; | 99 | const char *orig_uri; |
76 | const char *slash; | 100 | const char *slash; |
@@ -88,7 +112,8 @@ gnunet_uri (void *cls, const char *uri, const char *cfgfile, | |||
88 | uri += strlen ("gnunet://"); | 112 | uri += strlen ("gnunet://"); |
89 | if (NULL == (slash = strchr (uri, '/'))) | 113 | if (NULL == (slash = strchr (uri, '/'))) |
90 | { | 114 | { |
91 | fprintf (stderr, _("Invalid URI: fails to specify subsystem\n")); | 115 | fprintf (stderr, |
116 | _("Invalid URI: fails to specify subsystem\n")); | ||
92 | return; | 117 | return; |
93 | } | 118 | } |
94 | subsystem = GNUNET_strndup (uri, slash - uri); | 119 | subsystem = GNUNET_strndup (uri, slash - uri); |
@@ -98,7 +123,9 @@ gnunet_uri (void *cls, const char *uri, const char *cfgfile, | |||
98 | subsystem, | 123 | subsystem, |
99 | &program)) | 124 | &program)) |
100 | { | 125 | { |
101 | fprintf (stderr, _("No handler known for subsystem `%s'\n"), subsystem); | 126 | fprintf (stderr, |
127 | _("No handler known for subsystem `%s'\n"), | ||
128 | subsystem); | ||
102 | GNUNET_free (subsystem); | 129 | GNUNET_free (subsystem); |
103 | return; | 130 | return; |
104 | } | 131 | } |
@@ -120,6 +147,111 @@ gnunet_uri (void *cls, const char *uri, const char *cfgfile, | |||
120 | 147 | ||
121 | 148 | ||
122 | /** | 149 | /** |
150 | * Obtain QR code 'symbol' from @a proc. | ||
151 | * | ||
152 | * @param proc zbar processor to use | ||
153 | * @return NULL on error | ||
154 | */ | ||
155 | static const zbar_symbol_t * | ||
156 | get_symbol (zbar_processor_t *proc) | ||
157 | { | ||
158 | const zbar_symbol_set_t* symbols; | ||
159 | int rc; | ||
160 | int n; | ||
161 | |||
162 | if (0 != | ||
163 | zbar_processor_parse_config (proc, "enable")) | ||
164 | { | ||
165 | GNUNET_break (0); | ||
166 | return NULL; | ||
167 | } | ||
168 | |||
169 | /* initialize the Processor */ | ||
170 | if (0 != | ||
171 | (rc = zbar_processor_init(proc, device, 1))) | ||
172 | { | ||
173 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
174 | "Failed to open device `%s': %d\n", | ||
175 | device, | ||
176 | rc); | ||
177 | return NULL; | ||
178 | } | ||
179 | |||
180 | /* enable the preview window */ | ||
181 | if ( (0 != (rc = zbar_processor_set_visible (proc, 1))) || | ||
182 | (0 != (rc = zbar_processor_set_active(proc, 1))) ) | ||
183 | { | ||
184 | GNUNET_break (0); | ||
185 | return NULL; | ||
186 | } | ||
187 | |||
188 | /* read at least one barcode (or until window closed) */ | ||
189 | LOG ("Capturing\n"); | ||
190 | n = zbar_process_one (proc, -1); | ||
191 | |||
192 | /* hide the preview window */ | ||
193 | (void) zbar_processor_set_active (proc, 0); | ||
194 | (void) zbar_processor_set_visible (proc, 0); | ||
195 | if (-1 == n) | ||
196 | return NULL; /* likely user closed the window */ | ||
197 | LOG ("Got %i images\n", | ||
198 | n); | ||
199 | /* extract results */ | ||
200 | symbols = zbar_processor_get_results (proc); | ||
201 | if (NULL == symbols) | ||
202 | { | ||
203 | GNUNET_break (0); | ||
204 | return NULL; | ||
205 | } | ||
206 | return zbar_symbol_set_first_symbol (symbols); | ||
207 | } | ||
208 | |||
209 | |||
210 | /** | ||
211 | * Run zbar QR code parser. | ||
212 | * | ||
213 | * @return NULL on error, otherwise the URI that we found | ||
214 | */ | ||
215 | static char * | ||
216 | run_zbar () | ||
217 | { | ||
218 | zbar_processor_t *proc; | ||
219 | const char *data; | ||
220 | char *ret; | ||
221 | const zbar_symbol_t* symbol; | ||
222 | |||
223 | /* configure the Processor */ | ||
224 | proc = zbar_processor_create (1); | ||
225 | if (NULL == proc) | ||
226 | { | ||
227 | GNUNET_break (0); | ||
228 | return NULL; | ||
229 | } | ||
230 | |||
231 | symbol = get_symbol (proc); | ||
232 | if (NULL == symbol) | ||
233 | { | ||
234 | zbar_processor_destroy (proc); | ||
235 | return NULL; | ||
236 | } | ||
237 | data = zbar_symbol_get_data (symbol); | ||
238 | if (NULL == data) | ||
239 | { | ||
240 | GNUNET_break (0); | ||
241 | zbar_processor_destroy (proc); | ||
242 | return NULL; | ||
243 | } | ||
244 | LOG ("Found %s \"%s\"\n", | ||
245 | zbar_get_symbol_name (zbar_symbol_get_type(symbol)), | ||
246 | data); | ||
247 | ret = GNUNET_strdup (data); | ||
248 | /* clean up */ | ||
249 | zbar_processor_destroy(proc); | ||
250 | return ret; | ||
251 | } | ||
252 | |||
253 | |||
254 | /** | ||
123 | * Main function that will be run by the scheduler. | 255 | * Main function that will be run by the scheduler. |
124 | * | 256 | * |
125 | * @param cls closure | 257 | * @param cls closure |
@@ -133,65 +265,33 @@ run (void *cls, | |||
133 | const char *cfgfile, | 265 | const char *cfgfile, |
134 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 266 | const struct GNUNET_CONFIGURATION_Handle *cfg) |
135 | { | 267 | { |
136 | /* create a Processor */ | 268 | char *data; |
137 | LOG("Initializing\n"); | ||
138 | zbar_processor_t *proc = zbar_processor_create(1); | ||
139 | |||
140 | // FIXME: Wrap all this into a function which returns an error on | ||
141 | // failure. And here ensure the processor is destroyed at the end. | ||
142 | |||
143 | /* configure the Processor */ | ||
144 | zbar_processor_parse_config(proc, "enable"); | ||
145 | |||
146 | /* initialize the Processor */ | ||
147 | LOG("Opening video device %s\n", device); | ||
148 | // FIXME: error handling | ||
149 | zbar_processor_init(proc, device, 1); | ||
150 | |||
151 | /* enable the preview window */ | ||
152 | zbar_processor_set_visible(proc, 1); | ||
153 | zbar_processor_set_active(proc, 1); | ||
154 | |||
155 | /* keep scanning until user provides key/mouse input */ | ||
156 | //zbar_processor_user_wait(proc, -1); | ||
157 | 269 | ||
158 | // read at least one barcode (or until window closed) | 270 | data = run_zbar (); |
159 | LOG("Capturing\n"); | 271 | if (NULL == data) |
160 | int n; | 272 | return; |
161 | n = zbar_process_one(proc, -1); | 273 | gnunet_uri (cls, |
162 | LOG("Got %i images\n", n); | 274 | data, |
163 | // FIXME: Error handling (n = -1) | 275 | cfgfile, |
164 | 276 | cfg); | |
165 | // hide the preview window | 277 | if (exit_code != 0) |
166 | zbar_processor_set_active(proc, 0); | 278 | { |
167 | zbar_processor_set_visible(proc, 0); | 279 | printf ("Failed to add URI %s\n", |
168 | 280 | data); | |
169 | // extract results | ||
170 | const zbar_symbol_set_t* symbols = zbar_processor_get_results(proc); | ||
171 | const zbar_symbol_t* symbol = zbar_symbol_set_first_symbol(symbols); | ||
172 | |||
173 | if (symbol != NULL) { | ||
174 | const char* data = zbar_symbol_get_data(symbol); | ||
175 | LOG("Found %s \"%s\"\n", | ||
176 | zbar_get_symbol_name(zbar_symbol_get_type(symbol)), data); | ||
177 | |||
178 | gnunet_uri(cls, data, cfgfile, cfg); | ||
179 | if (exit_code != 0) { | ||
180 | printf("Failed to add URI %s\n", data); | ||
181 | } else { | ||
182 | printf("Added URI %s\n", data); | ||
183 | } | ||
184 | } | 281 | } |
185 | 282 | else | |
186 | /* clean up */ | 283 | { |
187 | zbar_processor_destroy(proc); | 284 | printf ("Added URI %s\n", |
285 | data); | ||
286 | } | ||
287 | GNUNET_free (data); | ||
188 | }; | 288 | }; |
189 | 289 | ||
190 | 290 | ||
191 | int | 291 | int |
192 | main (int argc, char *const *argv) | 292 | main (int argc, char *const *argv) |
193 | { | 293 | { |
194 | static int ret; | 294 | int ret; |
195 | struct GNUNET_GETOPT_CommandLineOption options[] = { | 295 | struct GNUNET_GETOPT_CommandLineOption options[] = { |
196 | GNUNET_GETOPT_option_string ('d', "device", "DEVICE", | 296 | GNUNET_GETOPT_option_string ('d', "device", "DEVICE", |
197 | gettext_noop ("use video-device DEVICE (default: /dev/video0"), | 297 | gettext_noop ("use video-device DEVICE (default: /dev/video0"), |
@@ -204,6 +304,7 @@ main (int argc, char *const *argv) | |||
204 | &silent), | 304 | &silent), |
205 | GNUNET_GETOPT_OPTION_END | 305 | GNUNET_GETOPT_OPTION_END |
206 | }; | 306 | }; |
307 | |||
207 | ret = GNUNET_PROGRAM_run (argc, | 308 | ret = GNUNET_PROGRAM_run (argc, |
208 | argv, | 309 | argv, |
209 | "gnunet-qr", | 310 | "gnunet-qr", |