GNUnet  0.17.6
gnunet-bcd.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2013 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 
27 #include "platform.h"
28 #include <microhttpd.h>
29 #include "gnunet_util_lib.h"
31 #include "gnunet_mhd_compat.h"
32 
34 {
39 
43  uint64_t size;
44 
48  struct MHD_Response *response;
49 };
50 
52 {
56  char *name;
57 
61  char *definition;
62 };
63 
67 static struct MHD_Daemon *httpd = NULL;
68 
72 static struct GNUNET_SCHEDULER_Task *httpd_task = NULL;
73 
77 static struct StaticResource *index_simple = NULL;
78 
82 static struct StaticResource *index_full = NULL;
83 
87 static struct StaticResource *key_error = NULL;
88 
92 static struct StaticResource *notfound_error = NULL;
93 
97 static struct StaticResource *internal_error = NULL;
98 
102 static struct StaticResource *forbidden_error = NULL;
103 
107 static char *tex_file_simple = NULL;
108 
112 static char *tex_file_full = NULL;
113 
117 static char *tex_file_png = NULL;
118 
122 static int continue_100 = 100;
123 
127 static const struct ParameterMap pmap[] = {
128  {"prefix", "prefix"},
129  {"name", "name"},
130  {"suffix", "suffix"},
131  {"street", "street"},
132  {"city", "city"},
133  {"phone", "phone"},
134  {"fax", "fax"},
135  {"email", "email"},
136  {"homepage", "homepage"},
137  {"org", "organization"},
138  {"department", "department"},
139  {"subdepartment", "subdepartment"},
140  {"jobtitle", "jobtitle"},
141  {NULL, NULL},
142 };
143 
147 static uint16_t port = 8888;
148 
154 static void
155 do_shutdown (void *cls)
156 {
157  /* We cheat a bit here: the file descriptor is implicitly closed by MHD, so
158  calling `GNUNET_DISK_file_close' would generate a spurious warning message
159  in the log. Since that function does nothing but close the descriptor and
160  free the allocated memory, After destroying the response all that's left to
161  do is call `GNUNET_free'. */
162  if (NULL != index_simple)
163  {
164  MHD_destroy_response (index_simple->response);
167  }
168  if (NULL != index_full)
169  {
170  MHD_destroy_response (index_full->response);
173  }
174  if (NULL != key_error)
175  {
176  MHD_destroy_response (key_error->response);
179  }
180  if (NULL != notfound_error)
181  {
182  MHD_destroy_response (notfound_error->response);
185  }
186  if (NULL != internal_error)
187  {
188  MHD_destroy_response (internal_error->response);
191  }
192  if (NULL != forbidden_error)
193  {
194  MHD_destroy_response (forbidden_error->response);
197  }
198 
199  if (NULL != httpd_task)
200  {
202  }
203  if (NULL != httpd)
204  {
205  MHD_stop_daemon (httpd);
206  }
207 }
208 
214 static void
215 do_httpd (void *cls);
216 
220 static void
221 run_httpd (void)
222 {
223  fd_set rs;
224  fd_set ws;
225  fd_set es;
226 
230 
231  FD_ZERO (&rs);
232  FD_ZERO (&ws);
233  FD_ZERO (&es);
234 
235  int max = -1;
236  GNUNET_assert (MHD_YES == MHD_get_fdset (httpd, &rs, &ws, &es, &max));
237 
238  unsigned MHD_LONG_LONG timeout = 0;
240  if (MHD_YES == MHD_get_timeout (httpd, &timeout))
241  {
243  timeout);
244  }
245 
246  GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1);
247  GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1);
248  GNUNET_NETWORK_fdset_copy_native (ges, &es, max + 1);
249 
251  gtime,
252  grs,
253  gws,
254  &do_httpd,
255  NULL);
259 }
260 
266 static void
267 do_httpd (void *cls)
268 {
269  httpd_task = NULL;
270  MHD_run (httpd);
271  run_httpd ();
272 }
273 
287 static MHD_RESULT
288 create_response (void *cls,
289  struct MHD_Connection *connection,
290  const char *url,
291  const char *method,
292  const char *version,
293  const char *upload_data,
294  size_t *upload_data_size,
295  void **ptr)
296 {
297  (void) cls;
298  (void) version;
299  (void) upload_data;
300  (void) upload_data_size;
301 
302  bool isget = (0 == strcmp (method, MHD_HTTP_METHOD_GET));
303  bool ishead = (0 == strcmp (method, MHD_HTTP_METHOD_HEAD));
304 
305  if (!isget && !ishead)
306  {
307  return MHD_queue_response (connection,
308  MHD_HTTP_NOT_IMPLEMENTED,
310  }
311 
312  if (ishead)
313  {
314  /* Dedicated branch in case we want to provide a different result for some
315  reason (e.g. a non-web browser application using the web UI) */
316  return MHD_queue_response (connection,
317  MHD_HTTP_OK,
319  }
320 
321  /* Send a 100 CONTINUE response to tell clients that the result of the
322  request might take some time */
323  if (NULL == *ptr)
324  {
325  *ptr = &continue_100;
326  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending 100 CONTINUE\n");
327  return MHD_YES;
328  }
329 
330  if (0 == strcmp ("/", url))
331  {
332  return MHD_queue_response (connection,
333  MHD_HTTP_OK,
335  }
336 
337  if (0 == strcmp ("/full", url))
338  {
339  return MHD_queue_response (connection,
340  MHD_HTTP_OK,
342  }
343 
344  bool isfull = (0 == strcmp ("/submit/full", url));
345  bool issimple = (0 == strcmp ("/submit/simple", url));
346 
347  if (!isfull && !issimple)
348  {
349  return MHD_queue_response (connection,
350  MHD_HTTP_NOT_FOUND,
352  }
353 
354  const char *gpgfp = MHD_lookup_connection_value (connection,
355  MHD_GET_ARGUMENT_KIND,
356  "gpgfingerprint");
357  const char *gnsnick = MHD_lookup_connection_value (connection,
358  MHD_GET_ARGUMENT_KIND,
359  "gnsnick");
360  const char *gnskey = MHD_lookup_connection_value (connection,
361  MHD_GET_ARGUMENT_KIND,
362  "gnskey");
363  const char *qrpng = MHD_lookup_connection_value (connection,
364  MHD_GET_ARGUMENT_KIND,
365  "gnspng");
366 
368  if (NULL == gnskey
370  {
371  return MHD_queue_response (connection,
372  MHD_HTTP_BAD_REQUEST,
374  }
375 
376  char *tmpd = GNUNET_DISK_mkdtemp (gnskey);
377  if (NULL == tmpd)
378  {
380  return MHD_queue_response (connection,
381  MHD_HTTP_INTERNAL_SERVER_ERROR,
383  }
384 
385  char *defpath = NULL;
386  GNUNET_asprintf (&defpath, "%s%s%s", tmpd, DIR_SEPARATOR_STR, "def.tex");
387 
388  FILE *deffile = fopen (defpath, "w");
389  if (NULL == deffile)
390  {
392  GNUNET_free (defpath);
394  GNUNET_free (tmpd);
395  return MHD_queue_response (connection,
396  MHD_HTTP_INTERNAL_SERVER_ERROR,
398  }
399 
400  GNUNET_free (defpath);
401 
402  for (size_t i=0; NULL!=pmap[i].name; ++i)
403  {
404  const char *value = MHD_lookup_connection_value (connection,
405  MHD_GET_ARGUMENT_KIND,
406  pmap[i].name);
407  fprintf (deffile,
408  "\\def\\%s{%s}\n",
409  pmap[i].definition,
410  (NULL == value) ? "" : value);
411  }
412 
413  if (NULL != gpgfp)
414  {
415  size_t len = strlen (gpgfp);
416  char *line1 = GNUNET_strndup (gpgfp, len/2);
417  char *line2 = GNUNET_strdup (&gpgfp[len/2]);
418  fprintf (deffile,
419  "\\def\\gpglineone{%s}\n\\def\\gpglinetwo{%s}\n",
420  line1,
421  line2);
422  GNUNET_free (line1);
423  GNUNET_free (line2);
424  }
425 
426  fprintf (deffile,
427  "\\def\\gns{%s/%s}\n",
428  gnskey,
429  (NULL == gnsnick) ? "" : gnsnick);
430 
431  fclose (deffile);
432 
433  char *command = NULL;
434  GNUNET_asprintf (&command,
435  "cd %s; cp %s gns-bcd.tex; "
436  "pdflatex %s gns-bcd.tex >/dev/null 2>&1",
437  tmpd,
438  (isfull) ? tex_file_full :
439  ((NULL == qrpng) ? tex_file_simple : tex_file_png),
440  (NULL == qrpng) ? "" : "-shell-escape");
441 
442  int ret = system (command);
443 
444  GNUNET_free (command);
445 
446  if (WIFSIGNALED (ret) || 0 != WEXITSTATUS (ret))
447  {
449  }
450 
451  GNUNET_asprintf (&defpath,
452  "%s%s%s",
453  tmpd,
455  (NULL == qrpng) ? "gns-bcd.pdf" : "gns-bcd.png");
456 
457  int pdf = open (defpath, O_RDONLY);
458  if (-1 == pdf)
459  {
461  GNUNET_free (defpath);
463  GNUNET_free (tmpd);
464  return MHD_queue_response (connection,
465  MHD_HTTP_INTERNAL_SERVER_ERROR,
467  }
468 
469  struct stat statret;
470  GNUNET_break (0 == stat (defpath, &statret));
471 
472  GNUNET_free (defpath);
473 
474  struct MHD_Response *pdfrs =
475  MHD_create_response_from_fd ((size_t) statret.st_size, pdf);
476  if (NULL == pdfrs)
477  {
478  GNUNET_break (0);
479  GNUNET_break (0 == close (pdf));
481  GNUNET_free (tmpd);
482  return MHD_queue_response (connection,
483  MHD_HTTP_INTERNAL_SERVER_ERROR,
485  }
486 
487  MHD_add_response_header (pdfrs,
488  MHD_HTTP_HEADER_CONTENT_TYPE,
489  (NULL == qrpng) ? "application/pdf" : "image/png");
490  MHD_add_response_header (pdfrs,
491  MHD_HTTP_HEADER_CONTENT_DISPOSITION,
492  (NULL == qrpng) ?
493  "attachment; filename=\"gns-business-card.pdf\"" :
494  "attachment; filename=\"gns-qr-code.png\"");
495  MHD_RESULT r = MHD_queue_response (connection, MHD_HTTP_OK, pdfrs);
496 
497  MHD_destroy_response (pdfrs);
499  GNUNET_free (tmpd);
500 
501  return r;
502 }
503 
511 static struct StaticResource *
512 open_static_resource (const char *name, const char *basedir)
513 {
514  char *fullname = NULL;
515  GNUNET_asprintf (&fullname, "%s%s%s", basedir, DIR_SEPARATOR_STR, name);
516 
517  struct GNUNET_DISK_FileHandle *f =
518  GNUNET_DISK_file_open (fullname,
521 
522  GNUNET_free (fullname);
523 
524  if (NULL == f)
525  {
526  return NULL;
527  }
528 
529  off_t size = 0;
531  {
533  return NULL;
534  }
535 
536  struct MHD_Response *response = MHD_create_response_from_fd64 (size, f->fd);
537 
538  if (NULL == response)
539  {
541  return NULL;
542  }
543 
544  struct StaticResource *res = GNUNET_new (struct StaticResource);
545  res->handle = f;
546  res->size = (uint64_t) size;
547  res->response = response;
548 
549  return res;
550 }
551 
560 static void
561 run (void *cls,
562  char *const *args,
563  const char *cfgfile,
564  const struct GNUNET_CONFIGURATION_Handle *c)
565 {
566  (void) cls;
567  (void) args;
568  (void) cfgfile;
569 
570  if (0 == port)
571  {
573  _ ("Invalid port number %u\n"),
574  port);
576  return;
577  }
578 
580 
582  GNUNET_assert (NULL != datadir);
583 
585  "%s%s%s",
586  datadir,
588  "gns-bcd.tex");
590  "%s%s%s",
591  datadir,
593  "gns-bcd-simple.tex");
595  "%s%s%s",
596  datadir,
598  "gns-bcd-png.tex");
599 
600  index_simple = open_static_resource ("gns-bcd-simple.html", datadir);
601  index_full = open_static_resource ("gns-bcd.html", datadir);
602  key_error = open_static_resource ("gns-bcd-invalid-key.html", datadir);
603  notfound_error = open_static_resource ("gns-bcd-not-found.html", datadir);
604  internal_error = open_static_resource ("gns-bcd-internal-error.html", datadir);
605  forbidden_error = open_static_resource ("gns-bcd-forbidden.html", datadir);
606 
607  GNUNET_free (datadir);
608 
609  if ((NULL == index_simple) || (NULL == index_full)
610  || (NULL == key_error) || (NULL == notfound_error)
611  || (NULL == internal_error) || (NULL == forbidden_error))
612  {
614  _ ("Unable to set up the daemon\n"));
616  return;
617  }
618 
619  int flags = MHD_USE_DUAL_STACK | MHD_USE_DEBUG | MHD_ALLOW_SUSPEND_RESUME;
620  do
621  {
622  httpd = MHD_start_daemon (flags,
623  port,
624  NULL, NULL,
625  &create_response, NULL,
626  MHD_OPTION_CONNECTION_LIMIT, 512,
627  MHD_OPTION_PER_IP_CONNECTION_LIMIT, 2,
628  MHD_OPTION_CONNECTION_TIMEOUT, 60,
629  MHD_OPTION_CONNECTION_MEMORY_LIMIT, 16 * 1024,
630  MHD_OPTION_END);
631  flags = MHD_USE_DEBUG;
632  } while (NULL == httpd && flags != MHD_USE_DEBUG);
633 
634  if (NULL == httpd)
635  {
637  _ ("Failed to start HTTP server\n"));
639  return;
640  }
641 
642  run_httpd ();
643 }
644 
652 int
653 main (int argc, char *const *argv)
654 {
657  'p',
658  "port",
659  "PORT",
660  gettext_noop ("Run HTTP server on port PORT (default is 8888)"),
661  &port),
663  };
664 
665  return ((GNUNET_OK ==
666  GNUNET_PROGRAM_run (argc,
667  argv,
668  "gnunet-bcd",
669  _ ("GNUnet HTTP server to create business cards"),
670  options,
671  &run,
672  NULL))
673  ? 0
674  : 1);
675 }
676 
677 /* end of gnunet-bcd.c */
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
#define gettext_noop(String)
Definition: gettext.h:69
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no timeout).
Definition: gnunet-abd.c:61
static int res
static char * tex_file_full
Full path to the TeX template file (full result)
Definition: gnunet-bcd.c:112
static struct StaticResource * key_error
Error: invalid gns key.
Definition: gnunet-bcd.c:87
static MHD_RESULT create_response(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **ptr)
Send a response back to a connected client.
Definition: gnunet-bcd.c:288
static struct StaticResource * index_full
Index file resource (full result).
Definition: gnunet-bcd.c:82
static int continue_100
Used as a sort of singleton to send exactly one 100 CONTINUE per request.
Definition: gnunet-bcd.c:122
static const struct ParameterMap pmap[]
Map of names with TeX definitions, used during PDF generation.
Definition: gnunet-bcd.c:127
static struct MHD_Daemon * httpd
Handle to the HTTP server as provided by libmicrohttpd.
Definition: gnunet-bcd.c:67
static char * tex_file_png
Full path to the TeX template file (PNG result)
Definition: gnunet-bcd.c:117
static struct StaticResource * forbidden_error
Other errors.
Definition: gnunet-bcd.c:102
static struct StaticResource * index_simple
Index file resource (simple result).
Definition: gnunet-bcd.c:77
static void do_shutdown(void *cls)
Task ran at shutdown to clean up everything.
Definition: gnunet-bcd.c:155
static void run_httpd(void)
Schedule a task to run MHD.
Definition: gnunet-bcd.c:221
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Main function that will be run.
Definition: gnunet-bcd.c:561
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static void do_httpd(void *cls)
Called when the HTTP server has some pending operations.
Definition: gnunet-bcd.c:267
static char * tex_file_simple
Full path to the TeX template file (simple result)
Definition: gnunet-bcd.c:107
static struct GNUNET_SCHEDULER_Task * httpd_task
Our primary task for the HTTPD.
Definition: gnunet-bcd.c:72
int main(int argc, char *const *argv)
The main function for gnunet-gns.
Definition: gnunet-bcd.c:653
static struct StaticResource * internal_error
Errors after receiving the form data.
Definition: gnunet-bcd.c:97
static struct StaticResource * open_static_resource(const char *name, const char *basedir)
Open a file on disk and generate a response for it.
Definition: gnunet-bcd.c:512
static struct StaticResource * notfound_error
Error: 404.
Definition: gnunet-bcd.c:92
static struct MHD_Response * response
Our canonical response.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
struct GNUNET_IDENTITY_PrivateKey pk
Private key from command line option, or NULL.
static char * value
Value of the record to add/remove.
Identity service; implements identity management for GNUnet.
#define MHD_RESULT
Data type to use for functions return an "MHD result".
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
Definition: disk.c:1235
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_remove(const char *filename)
Remove all files in a directory (rm -rf).
Definition: disk.c:1085
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1306
enum GNUNET_GenericReturnValue GNUNET_DISK_file_handle_size(struct GNUNET_DISK_FileHandle *fh, off_t *size)
Get the size of an open file.
Definition: disk.c:193
char * GNUNET_DISK_mkdtemp(const char *t)
Create an (empty) temporary directory on disk.
Definition: disk.c:340
@ GNUNET_DISK_OPEN_READ
Open the file for reading.
@ GNUNET_DISK_PERM_NONE
Nobody is allowed to do anything to the file.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_uint16(char shortName, const char *name, const char *argumentHelp, const char *description, uint16_t *val)
Allow user to specify an uint16_t.
enum GNUNET_GenericReturnValue GNUNET_IDENTITY_public_key_from_string(const char *str, struct GNUNET_IDENTITY_PublicKey *key)
Parses a (Base32) string representation of the public key.
#define GNUNET_log(kind,...)
@ GNUNET_SCHEDULER_PRIORITY_HIGH
Run with high priority (important requests).
@ GNUNET_OK
Definition: gnunet_common.h:99
@ GNUNET_SYSERR
Definition: gnunet_common.h:97
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_NETWORK_FDSet * GNUNET_NETWORK_fdset_create(void)
Creates an fd set.
Definition: network.c:1193
void GNUNET_NETWORK_fdset_destroy(struct GNUNET_NETWORK_FDSet *fds)
Releases the associated memory of an fd set.
Definition: network.c:1209
void GNUNET_NETWORK_fdset_copy_native(struct GNUNET_NETWORK_FDSet *to, const fd_set *from, int nfds)
Copy a native fd set into the GNUnet representation.
Definition: network.c:1063
char * GNUNET_OS_installation_get_path(enum GNUNET_OS_InstallationPathKind dirkind)
Get the path to a specific GNUnet installation directory or, with GNUNET_OS_IPK_SELF_PREFIX,...
@ GNUNET_OS_IPK_DATADIR
Return the directory where data is installed (share/gnunet/)
enum GNUNET_GenericReturnValue 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,...
Definition: program.c:399
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:533
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_select(enum GNUNET_SCHEDULER_Priority prio, struct GNUNET_TIME_Relative delay, const struct GNUNET_NETWORK_FDSet *rs, const struct GNUNET_NETWORK_FDSet *ws, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when any of the specified file descriptor set...
Definition: scheduler.c:1826
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1316
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:957
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition: time.c:483
#define max(x, y)
static unsigned int size
Size of the "table".
Definition: peer.c:67
#define DIR_SEPARATOR_STR
Definition: platform.h:165
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
const char * name
Handle used to access files (and pipes).
Definition of a command line option.
An identity key as per LSD0001.
collection of IO descriptors
Entry in list of pending tasks.
Definition: scheduler.c:135
Time for relative time used by GNUnet, in microseconds.
char * name
Name of the parameter from the request.
Definition: gnunet-bcd.c:56
char * definition
Name of the definition in the TeX output.
Definition: gnunet-bcd.c:61
struct MHD_Response * response
Cached response object to send to clients.
Definition: gnunet-bcd.c:48
struct GNUNET_DISK_FileHandle * handle
Handle to file on disk.
Definition: gnunet-bcd.c:38
uint64_t size
Size in bytes of the file.
Definition: gnunet-bcd.c:43