GNUnet  0.10.x
gnunet-qr.c
Go to the documentation of this file.
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 */
26 #include <stdio.h>
27 #include <zbar.h>
28 #include <stdbool.h>
29 #include "platform.h"
30 #include "gnunet_util_lib.h"
31 
32 #define LOG(fmt, ...) \
33  if (verbose == true) \
34  printf (fmt, ##__VA_ARGS__)
35 
39 static char *device = "/dev/video0";
40 
44 static int verbose = false;
45 
49 static int silent = false;
50 
54 static long unsigned int exit_code = 1;
55 
59 static struct GNUNET_OS_Process *p;
60 
61 
66 
67 
74 static void
75 maint_child_death (void *cls)
76 {
78 
79  if ((GNUNET_OK != GNUNET_OS_process_status (p, &type, &exit_code)) ||
80  (type != GNUNET_OS_PROCESS_EXITED))
83 }
84 
85 
94 static void
95 gnunet_uri (void *cls,
96  const char *uri,
97  const char *cfgfile,
98  const struct GNUNET_CONFIGURATION_Handle *cfg)
99 {
100  const char *orig_uri;
101  const char *slash;
102  char *subsystem;
103  char *program;
104  struct GNUNET_SCHEDULER_Task *rt;
105 
106  orig_uri = uri;
107  if (0 != strncasecmp ("gnunet://", uri, strlen ("gnunet://")))
108  {
109  fprintf (stderr,
110  _ ("Invalid URI: does not start with `%s'\n"),
111  "gnunet://");
112  return;
113  }
114  uri += strlen ("gnunet://");
115  if (NULL == (slash = strchr (uri, '/')))
116  {
117  fprintf (stderr, _ ("Invalid URI: fails to specify subsystem\n"));
118  return;
119  }
120  subsystem = GNUNET_strndup (uri, slash - uri);
121  if (GNUNET_OK !=
122  GNUNET_CONFIGURATION_get_value_string (cfg, "uri", subsystem, &program))
123  {
124  fprintf (stderr, _ ("No handler known for subsystem `%s'\n"), subsystem);
125  GNUNET_free (subsystem);
126  return;
127  }
128  GNUNET_free (subsystem);
133  NULL);
135  0,
136  NULL,
137  NULL,
138  NULL,
139  program,
140  program,
141  orig_uri,
142  NULL);
143  GNUNET_free (program);
144  if (NULL == p)
146 }
147 
148 
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 != zbar_processor_parse_config (proc, "enable"))
163  {
164  GNUNET_break (0);
165  return NULL;
166  }
167 
168  /* initialize the Processor */
169  if (0 != (rc = zbar_processor_init (proc, device, 1)))
170  {
172  "Failed to open device `%s': %d\n",
173  device,
174  rc);
175  return NULL;
176  }
177 
178  /* enable the preview window */
179  if ((0 != (rc = zbar_processor_set_visible (proc, 1))) ||
180  (0 != (rc = zbar_processor_set_active (proc, 1))))
181  {
182  GNUNET_break (0);
183  return NULL;
184  }
185 
186  /* read at least one barcode (or until window closed) */
187  LOG ("Capturing\n");
188  n = zbar_process_one (proc, -1);
189 
190  /* hide the preview window */
191  (void) zbar_processor_set_active (proc, 0);
192  (void) zbar_processor_set_visible (proc, 0);
193  if (-1 == n)
194  return NULL; /* likely user closed the window */
195  LOG ("Got %i images\n", n);
196  /* extract results */
197  symbols = zbar_processor_get_results (proc);
198  if (NULL == symbols)
199  {
200  GNUNET_break (0);
201  return NULL;
202  }
203  return zbar_symbol_set_first_symbol (symbols);
204 }
205 
206 
212 static char *
214 {
215  zbar_processor_t *proc;
216  const char *data;
217  char *ret;
218  const zbar_symbol_t *symbol;
219 
220  /* configure the Processor */
221  proc = zbar_processor_create (1);
222  if (NULL == proc)
223  {
224  GNUNET_break (0);
225  return NULL;
226  }
227 
228  symbol = get_symbol (proc);
229  if (NULL == symbol)
230  {
231  zbar_processor_destroy (proc);
232  return NULL;
233  }
234  data = zbar_symbol_get_data (symbol);
235  if (NULL == data)
236  {
237  GNUNET_break (0);
238  zbar_processor_destroy (proc);
239  return NULL;
240  }
241  LOG ("Found %s \"%s\"\n",
242  zbar_get_symbol_name (zbar_symbol_get_type (symbol)),
243  data);
244  ret = GNUNET_strdup (data);
245  /* clean up */
246  zbar_processor_destroy (proc);
247  return ret;
248 }
249 
250 
259 static void
260 run (void *cls,
261  char *const *args,
262  const char *cfgfile,
263  const struct GNUNET_CONFIGURATION_Handle *cfg)
264 {
265  char *data;
266 
267  data = run_zbar ();
268  if (NULL == data)
269  return;
270  gnunet_uri (cls, data, cfgfile, cfg);
271  if (exit_code != 0)
272  {
273  printf ("Failed to add URI %s\n", data);
274  }
275  else
276  {
277  printf ("Added URI %s\n", data);
278  }
279  GNUNET_free (data);
280 };
281 
282 
283 int
284 main (int argc, char *const *argv)
285 {
286  int ret;
287  struct GNUNET_GETOPT_CommandLineOption options[] =
289  'd',
290  "device",
291  "DEVICE",
292  gettext_noop ("use video-device DEVICE (default: /dev/video0"),
293  &device),
295  "verbose",
296  gettext_noop ("be verbose"),
297  &verbose),
299  "silent",
300  gettext_noop ("do not show preview windows"),
301  &silent),
303 
304  ret = GNUNET_PROGRAM_run (
305  argc,
306  argv,
307  "gnunet-qr",
308  gettext_noop (
309  "Scan a QR code using a video device and import the uri read"),
310  options,
311  &run,
312  NULL);
313  return ((GNUNET_OK == ret) && (0 == exit_code)) ? 0 : 1;
314 }
static char * subsystem
Set to subsystem that we&#39;re going to get stats for (or NULL for all).
static struct GNUNET_DISK_PipeHandle * sigpipe
Pipe used to communicate child death via signal.
Definition: gnunet-qr.c:65
void GNUNET_OS_process_destroy(struct GNUNET_OS_Process *proc)
Cleans up process structure contents (OS-dependent) and deallocates it.
Definition: os_priority.c:364
static char * device
Video device to capture from.
Definition: gnunet-qr.c:39
int GNUNET_OS_process_status(struct GNUNET_OS_Process *proc, enum GNUNET_OS_ProcessStatusType *type, unsigned long *code)
Retrieve the status of a process, waiting on it if dead.
Definition: os_priority.c:1719
struct GNUNET_OS_Process * GNUNET_OS_start_process(int pipe_control, enum GNUNET_OS_InheritStdioFlags std_inheritance, struct GNUNET_DISK_PipeHandle *pipe_stdin, struct GNUNET_DISK_PipeHandle *pipe_stdout, struct GNUNET_DISK_PipeHandle *pipe_stderr, const char *filename,...)
Start a process.
Definition: os_priority.c:1400
static const zbar_symbol_t * get_symbol(zbar_processor_t *proc)
Obtain QR code &#39;symbol&#39; from proc.
Definition: gnunet-qr.c:156
#define GNUNET_NO
Definition: gnunet_common.h:81
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_file(struct GNUNET_TIME_Relative delay, const struct GNUNET_DISK_FileHandle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1643
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
Definition of a command line option.
static void gnunet_uri(void *cls, const char *uri, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
Dispatch URIs to the appropriate GNUnet helper process.
Definition: gnunet-qr.c:95
static int ret
Final status code.
Definition: gnunet-arm.c:89
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
const struct GNUNET_DISK_FileHandle * GNUNET_DISK_pipe_handle(const struct GNUNET_DISK_PipeHandle *p, enum GNUNET_DISK_PipeEnd n)
Get the handle to a particular pipe end.
Definition: disk.c:2641
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_string(char shortName, const char *name, const char *argumentHelp, const char *description, char **str)
Allow user to specify a string.
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
int main(int argc, char *const *argv)
Definition: gnunet-qr.c:284
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
static int silent
–silent option
Definition: gnunet-qr.c:49
GNUNET_OS_ProcessStatusType
Process status types.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
The reading-end of a pipe.
The process exited with a return code.
int GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
static char * run_zbar()
Run zbar QR code parser.
Definition: gnunet-qr.c:213
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
#define LOG(fmt,...)
Definition: gnunet-qr.c:32
configuration data
Definition: configuration.c:85
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_flag(char shortName, const char *name, const char *description, int *val)
Allow user to specify a flag (which internally means setting an integer to 1/GNUNET_YES/GNUNET_OK.
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
int GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration, parse options).
Definition: program.c:361
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
#define GNUNET_TERM_SIG
The termination signal.
Definition: platform.h:282
uint32_t data
The data value.
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
Main function that will be run by the scheduler.
Definition: gnunet-qr.c:260
Handle used to manage a pipe.
Definition: disk.c:66
static int verbose
–verbose option
Definition: gnunet-qr.c:44
#define GNUNET_free(ptr)
Wrapper around free.
static void maint_child_death(void *cls)
Task triggered whenever we receive a SIGCHLD (child process died) or when user presses CTRL-C...
Definition: gnunet-qr.c:75
#define gettext_noop(String)
Definition: gettext.h:69
int GNUNET_OS_process_kill(struct GNUNET_OS_Process *proc, int sig)
Sends a signal to the process.
Definition: os_priority.c:251
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
static long unsigned int exit_code
Handler exit code.
Definition: gnunet-qr.c:54