gnunet-qr: Use GNUNET_PROGRAM_run to simplify the code.
[oweals/gnunet.git] / src / util / gnunet-qr.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2013-2019 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Affero General Public License for more details.
14
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21 #include <stdio.h>
22 #include <zbar.h>
23 #include <stdbool.h>
24 #include "platform.h"
25 #include "gnunet_util_lib.h"
26 #include "gnunet-qr-utils.h"
27
28 #define LOG(fmt, ...) if (verbose == true) printf(fmt, ## __VA_ARGS__)
29
30 // Command line options
31 // program exit code
32 static long unsigned int exit_code = 1;
33
34 static char* device = "/dev/video0";
35 static int verbose = false;
36 static int silent = false;
37
38 /**
39  * Main function that will be run by the scheduler.
40  *
41  * @param cls closure
42  * @param args remaining command-line arguments
43  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
44  * @param cfg configuration
45  */
46 static void
47 run (void *cls,
48      char *const *args,
49      const char *cfgfile,
50      const struct GNUNET_CONFIGURATION_Handle *cfg)
51 {
52   /* create a Processor */
53   LOG("Initializing\n");
54   zbar_processor_t *proc = zbar_processor_create(1);
55
56   // FIXME: Wrap all this into a function which returns an error on
57   // failure. And here ensure the processor is destroyed at the end.
58
59   /* configure the Processor */
60   zbar_processor_parse_config(proc, "enable");
61
62   /* initialize the Processor */
63   LOG("Opening video device %s\n", device);
64   // FIXME: error handling
65   zbar_processor_init(proc, device, 1);
66
67   /* enable the preview window */
68   zbar_processor_set_visible(proc, 1);
69   zbar_processor_set_active(proc, 1);
70
71   /* keep scanning until user provides key/mouse input */
72   //zbar_processor_user_wait(proc, -1);
73
74   // read at least one barcode (or until window closed)
75   LOG("Capturing\n");
76   int n;
77   n = zbar_process_one(proc, -1);
78   LOG("Got %i images\n", n);
79   // FIXME: Error handling (n = -1)
80
81   // hide the preview window
82   zbar_processor_set_active(proc, 0);
83   zbar_processor_set_visible(proc, 0);
84
85   // extract results
86   const zbar_symbol_set_t* symbols = zbar_processor_get_results(proc);
87   const zbar_symbol_t* symbol = zbar_symbol_set_first_symbol(symbols);
88
89   if (symbol != NULL) {
90     const char* data = zbar_symbol_get_data(symbol);
91     LOG("Found %s \"%s\"\n",
92         zbar_get_symbol_name(zbar_symbol_get_type(symbol)), data);
93
94     if (configuration == NULL) {
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) {
105       printf("Failed to add URI %s\n", data);
106     } else {
107       printf("Added URI %s\n", data);
108     }
109   }
110
111   /* clean up */
112   zbar_processor_destroy(proc);
113 };
114
115
116 int
117 main (int argc, char *const *argv)
118 {
119   static int ret;
120   struct GNUNET_GETOPT_CommandLineOption options[] = {
121     GNUNET_GETOPT_option_string ('d', "device", "DEVICE",
122      gettext_noop ("use video-device DEVICE (default: /dev/video0"),
123      &device),
124     GNUNET_GETOPT_option_flag ('\0', "verbose",
125      gettext_noop ("be verbose"),
126      &verbose),
127     GNUNET_GETOPT_option_flag ('s', "silent",
128      gettext_noop ("do not show preview windows"),
129                                &silent),
130     GNUNET_GETOPT_OPTION_END
131   };
132   ret = GNUNET_PROGRAM_run (argc,
133                             argv,
134                             "gnunet-qr",
135                             gettext_noop ("Scan a QR code using a video device and import the uri read"),
136                             options, &run, NULL);
137   return ((GNUNET_OK == ret) && (0 == exit_code)) ? 0 : 1;
138 }