GNUnet  0.11.x
gnunet-auto-share.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2001--2012 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  */
29 #include "platform.h"
30 #include "gnunet_util_lib.h"
31 
32 #define MAX_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
33 
34 #define MIN_DELAY GNUNET_TIME_UNIT_MINUTES
35 
36 
41 struct WorkItem
42 {
46  struct WorkItem *prev;
47 
51  struct WorkItem *next;
52 
56  char *filename;
57 
63 };
64 
65 
69 static int ret;
70 
74 static unsigned int verbose;
75 
79 static const struct GNUNET_CONFIGURATION_Handle *cfg;
80 
84 static char *cfg_filename;
85 
89 static int disable_extractor;
90 
95 
100 
104 static unsigned int anonymity_level = 1;
105 
109 static unsigned int content_priority = 365;
110 
114 static unsigned int replication_level = 1;
115 
119 static const char *dir_name;
120 
124 static struct WorkItem *work_head;
125 
129 static struct WorkItem *work_tail;
130 
136 
140 static int do_shutdown;
141 
148 
153 
158 
159 
163 static char *
165 {
166  char *ret;
167 
168  GNUNET_asprintf (&ret,
169  "%s%s.auto-share",
170  dir_name,
171  (DIR_SEPARATOR == dir_name[strlen (dir_name) - 1])
172  ? ""
174  return ret;
175 }
176 
177 
181 static void
183 {
184  char *fn;
185  struct GNUNET_BIO_ReadHandle *rh;
186  uint32_t n;
187  struct GNUNET_HashCode id;
188  struct WorkItem *wi;
189  char *emsg;
190 
191  emsg = NULL;
192  fn = get_state_file ();
193  rh = GNUNET_BIO_read_open (fn);
194  GNUNET_free (fn);
195  if (NULL == rh)
196  return;
197  fn = NULL;
198  if (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &n))
199  goto error;
200  while (n-- > 0)
201  {
202  if ((GNUNET_OK != GNUNET_BIO_read_string (rh, "filename", &fn, 1024)) ||
203  (GNUNET_OK !=
204  GNUNET_BIO_read (rh, "id", &id, sizeof(struct GNUNET_HashCode))))
205  goto error;
206  wi = GNUNET_new (struct WorkItem);
207  wi->id = id;
208  wi->filename = fn;
210  "Loaded serialization ID for `%s' is `%s'\n",
211  wi->filename,
212  GNUNET_h2s (&id));
213  fn = NULL;
214  GNUNET_CRYPTO_hash (wi->filename, strlen (wi->filename), &id);
217  work_finished,
218  &id,
219  wi,
221  }
222  if (GNUNET_OK == GNUNET_BIO_read_close (rh, &emsg))
223  return;
224  rh = NULL;
225 error:
227  if (NULL != rh)
228  (void) GNUNET_BIO_read_close (rh, &emsg);
230  _ ("Failed to load state: %s\n"),
231  emsg);
232  GNUNET_free_non_null (emsg);
233 }
234 
235 
244 static int
245 write_item (void *cls, const struct GNUNET_HashCode *key, void *value)
246 {
247  struct GNUNET_BIO_WriteHandle *wh = cls;
248  struct WorkItem *wi = value;
249 
251  "Saving serialization ID of file `%s' with value `%s'\n",
252  wi->filename,
253  GNUNET_h2s (&wi->id));
254  if ((GNUNET_OK != GNUNET_BIO_write_string (wh, wi->filename)) ||
255  (GNUNET_OK !=
256  GNUNET_BIO_write (wh, &wi->id, sizeof(struct GNUNET_HashCode))))
257  return GNUNET_SYSERR; /* write error, abort iteration */
258  return GNUNET_OK;
259 }
260 
261 
265 static void
267 {
268  uint32_t n;
269  struct GNUNET_BIO_WriteHandle *wh;
270  char *fn;
271 
272  n = GNUNET_CONTAINER_multihashmap_size (work_finished);
273  fn = get_state_file ();
274  wh = GNUNET_BIO_write_open (fn);
275  if (NULL == wh)
276  {
278  _ ("Failed to save state to file %s\n"),
279  fn);
280  GNUNET_free (fn);
281  return;
282  }
283  if (GNUNET_OK != GNUNET_BIO_write_int32 (wh, n))
284  {
285  (void) GNUNET_BIO_write_close (wh);
287  _ ("Failed to save state to file %s\n"),
288  fn);
289  GNUNET_free (fn);
290  return;
291  }
292  (void) GNUNET_CONTAINER_multihashmap_iterate (work_finished, &write_item, wh);
293  if (GNUNET_OK != GNUNET_BIO_write_close (wh))
295  _ ("Failed to save state to file %s\n"),
296  fn);
297  GNUNET_free (fn);
298 }
299 
300 
306 static void
307 do_stop_task (void *cls)
308 {
310  if (NULL != publish_proc)
311  {
312  GNUNET_OS_process_kill (publish_proc, SIGKILL);
313  return;
314  }
315  if (NULL != run_task)
316  {
317  GNUNET_SCHEDULER_cancel (run_task);
318  run_task = NULL;
319  }
320 }
321 
322 
326 static void
327 schedule_next_task (void);
328 
329 
336 static void
337 maint_child_death (void *cls)
338 {
339  struct WorkItem *wi = cls;
340  struct GNUNET_HashCode key;
342  unsigned long code;
343  int ret;
344  char c;
345  const struct GNUNET_DISK_FileHandle *pr;
346  const struct GNUNET_SCHEDULER_TaskContext *tc;
347 
348  run_task = NULL;
352  {
353  /* shutdown scheduled us, someone else will kill child,
354  we should just try again */
356  pr,
358  wi);
359  return;
360  }
361  /* consume the signal */
362  GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof(c)));
363 
364  ret = GNUNET_OS_process_status (publish_proc, &type, &code);
365  GNUNET_assert (GNUNET_SYSERR != ret);
366  if (GNUNET_NO == ret)
367  {
368  /* process still running? Then where did the SIGCHLD come from?
369  Well, let's declare it spurious (kernel bug?) and keep rolling.
370  */
371  GNUNET_break (0);
373  pr,
375  wi);
376  return;
377  }
378  GNUNET_assert (GNUNET_OK == ret);
379 
380  GNUNET_OS_process_destroy (publish_proc);
381  publish_proc = NULL;
382 
383  if (GNUNET_YES == do_shutdown)
384  {
385  GNUNET_free (wi->filename);
386  GNUNET_free (wi);
387  return;
388  }
389  if ((GNUNET_OS_PROCESS_EXITED == type) && (0 == code))
390  {
392  _ ("Publication of `%s' done\n"),
393  wi->filename);
394  GNUNET_CRYPTO_hash (wi->filename, strlen (wi->filename), &key);
397  work_finished,
398  &key,
399  wi,
401  }
402  else
403  {
404  GNUNET_CONTAINER_DLL_insert_tail (work_head, work_tail, wi);
405  }
406  save_state ();
408 }
409 
410 
415 static void
417 {
418  static char c;
419  int old_errno = errno; /* back-up errno */
420 
421  GNUNET_break (
422  1 ==
425  &c,
426  sizeof(c)));
427  errno = old_errno; /* restore errno */
428 }
429 
430 
436 static void
437 work (void *cls)
438 {
439  static char *argv[14];
440  static char anon_level[20];
441  static char content_prio[20];
442  static char repl_level[20];
443  struct WorkItem *wi;
444  const struct GNUNET_DISK_FileHandle *pr;
445  int argc;
446 
447  run_task = NULL;
448  wi = work_head;
449  GNUNET_CONTAINER_DLL_remove (work_head, work_tail, wi);
450  argc = 0;
451  argv[argc++] = "gnunet-publish";
452  if (verbose)
453  argv[argc++] = "-V";
454  if (disable_extractor)
455  argv[argc++] = "-D";
457  argv[argc++] = "-d";
458  argv[argc++] = "-c";
459  argv[argc++] = cfg_filename;
460  GNUNET_snprintf (anon_level, sizeof(anon_level), "%u", anonymity_level);
461  argv[argc++] = "-a";
462  argv[argc++] = anon_level;
463  GNUNET_snprintf (content_prio, sizeof(content_prio), "%u", content_priority);
464  argv[argc++] = "-p";
465  argv[argc++] = content_prio;
466  GNUNET_snprintf (repl_level, sizeof(repl_level), "%u", replication_level);
467  argv[argc++] = "-r";
468  argv[argc++] = repl_level;
469  argv[argc++] = wi->filename;
470  argv[argc] = NULL;
471  GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Publishing `%s'\n"), wi->filename);
472  GNUNET_assert (NULL == publish_proc);
473  publish_proc = GNUNET_OS_start_process_vap (GNUNET_YES,
474  0,
475  NULL,
476  NULL,
477  NULL,
478  "gnunet-publish",
479  argv);
480  if (NULL == publish_proc)
481  {
483  _ ("Failed to run `%s'\n"),
484  "gnunet-publish");
485  GNUNET_CONTAINER_DLL_insert (work_head, work_tail, wi);
486  run_task =
488  return;
489  }
492  pr,
494  wi);
495 }
496 
497 
506 static int
507 determine_id (void *cls, const char *filename)
508 {
509  struct GNUNET_HashCode *id = cls;
510  struct stat sbuf;
511  struct GNUNET_HashCode fx[2];
512  struct GNUNET_HashCode ft;
513 
514  if (0 != stat (filename, &sbuf))
515  {
517  return GNUNET_OK;
518  }
519  GNUNET_CRYPTO_hash (filename, strlen (filename), &fx[0]);
520  if (! S_ISDIR (sbuf.st_mode))
521  {
522  uint64_t fattr[2];
523 
524  fattr[0] = GNUNET_htonll (sbuf.st_size);
525  fattr[0] = GNUNET_htonll (sbuf.st_mtime);
526 
527  GNUNET_CRYPTO_hash (fattr, sizeof(fattr), &fx[1]);
528  }
529  else
530  {
531  memset (&fx[1], 1, sizeof(struct GNUNET_HashCode));
532  GNUNET_DISK_directory_scan (filename, &determine_id, &fx[1]);
533  }
534  /* use hash here to make hierarchical structure distinct from
535  all files on the same level */
536  GNUNET_CRYPTO_hash (fx, sizeof(fx), &ft);
537  /* use XOR here so that order of the files in the directory
538  does not matter! */
539  GNUNET_CRYPTO_hash_xor (&ft, id, id);
540  return GNUNET_OK;
541 }
542 
543 
553 static int
554 add_file (void *cls, const char *filename)
555 {
556  struct WorkItem *wi;
557  struct GNUNET_HashCode key;
558  struct GNUNET_HashCode id;
559 
560  if (GNUNET_YES == do_shutdown)
561  return GNUNET_SYSERR;
562  if ((NULL != strstr (filename, "/.auto-share")) ||
563  (NULL != strstr (filename, "\\.auto-share")))
564  return GNUNET_OK; /* skip internal file */
565  GNUNET_CRYPTO_hash (filename, strlen (filename), &key);
566  wi = GNUNET_CONTAINER_multihashmap_get (work_finished, &key);
567  memset (&id, 0, sizeof(struct GNUNET_HashCode));
568  determine_id (&id, filename);
569  if (NULL != wi)
570  {
571  if (0 == memcmp (&id, &wi->id, sizeof(struct GNUNET_HashCode)))
572  return GNUNET_OK; /* skip: we did this one already */
573  /* contents changed, need to re-do the directory... */
574  GNUNET_assert (
575  GNUNET_YES ==
576  GNUNET_CONTAINER_multihashmap_remove (work_finished, &key, wi));
577  }
578  else
579  {
580  wi = GNUNET_new (struct WorkItem);
581  wi->filename = GNUNET_strdup (filename);
582  }
583  wi->id = id;
584  GNUNET_CONTAINER_DLL_insert (work_head, work_tail, wi);
585  if (GNUNET_YES == do_shutdown)
586  return GNUNET_SYSERR;
587  return GNUNET_OK;
588 }
589 
590 
596 static void
597 scan (void *cls)
598 {
599  run_task = NULL;
603 }
604 
605 
609 static void
611 {
612  struct GNUNET_TIME_Relative delay;
613 
614  if (GNUNET_YES == do_shutdown)
615  return;
616  GNUNET_assert (NULL == run_task);
617  if (NULL == work_head)
618  {
619  /* delay by at most 4h, at least 1s, and otherwise in between depending
620  on how long it took to scan */
622  delay = GNUNET_TIME_relative_saturating_multiply (delay, 100);
623  delay = GNUNET_TIME_relative_min (delay, MAX_DELAY);
624  delay = GNUNET_TIME_relative_max (delay, MIN_DELAY);
625  run_task = GNUNET_SCHEDULER_add_delayed (delay, &scan, NULL);
626  }
627  else
628  {
629  run_task = GNUNET_SCHEDULER_add_now (&work, NULL);
630  }
631 }
632 
633 
642 static void
643 run (void *cls,
644  char *const *args,
645  const char *cfgfile,
646  const struct GNUNET_CONFIGURATION_Handle *c)
647 {
648  /* check arguments */
649  if ((NULL == args[0]) || (NULL != args[1]) ||
651  {
652  printf (_ (
653  "You must specify one and only one directory name for automatic publication.\n"));
654  ret = -1;
655  return;
656  }
657  cfg_filename = GNUNET_strdup (cfgfile);
658  cfg = c;
659  dir_name = args[0];
660  work_finished = GNUNET_CONTAINER_multihashmap_create (1024, GNUNET_NO);
661  load_state ();
663  &scan,
664  NULL);
666 }
667 
668 
677 static int
678 free_item (void *cls, const struct GNUNET_HashCode *key, void *value)
679 {
680  struct WorkItem *wi = value;
681 
682  GNUNET_free (wi->filename);
683  GNUNET_free (wi);
684  return GNUNET_OK;
685 }
686 
687 
695 int
696 main (int argc, char *const *argv)
697 {
698  struct GNUNET_GETOPT_CommandLineOption options[] = {
700  "anonymity",
701  "LEVEL",
702  gettext_noop (
703  "set the desired LEVEL of sender-anonymity"),
704  &anonymity_level),
705 
707  'd',
708  "disable-creation-time",
709  gettext_noop (
710  "disable adding the creation time to the metadata of the uploaded file"),
712 
714  'D',
715  "disable-extractor",
716  gettext_noop ("do not use libextractor to add keywords or metadata"),
718 
720  "priority",
721  "PRIORITY",
722  gettext_noop (
723  "specify the priority of the content"),
725 
727  "replication",
728  "LEVEL",
729  gettext_noop (
730  "set the desired replication LEVEL"),
732 
734 
736  };
737  struct WorkItem *wi;
738  int ok;
739  struct GNUNET_SIGNAL_Context *shc_chld;
740 
741  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
742  return 2;
744  GNUNET_assert (NULL != sigpipe);
745  shc_chld =
747  ok =
748  (GNUNET_OK ==
750  argc,
751  argv,
752  "gnunet-auto-share [OPTIONS] FILENAME",
753  gettext_noop ("Automatically publish files from a directory on GNUnet"),
754  options,
755  &run,
756  NULL))
757  ? ret
758  : 1;
759  if (NULL != work_finished)
760  {
761  (void) GNUNET_CONTAINER_multihashmap_iterate (work_finished,
762  &free_item,
763  NULL);
765  }
766  while (NULL != (wi = work_head))
767  {
768  GNUNET_CONTAINER_DLL_remove (work_head, work_tail, wi);
769  GNUNET_free (wi->filename);
770  GNUNET_free (wi);
771  }
773  shc_chld = NULL;
774  GNUNET_DISK_pipe_close (sigpipe);
775  sigpipe = NULL;
777  cfg_filename = NULL;
778  GNUNET_free ((void *) argv);
779  return ok;
780 }
781 
782 
783 /* end of gnunet-auto-share.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
Definition: scheduler.c:747
static char * cfg_filename
Name of the configuration file.
static int ret
Global return value from &#39;main&#39;.
static const char * dir_name
Top-level directory we monitor to auto-publish.
struct WorkItem * prev
PENDING Work is kept in a linked list.
Item in our work queue (or in the set of files/directories we have successfully published).
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_OS_process_destroy(struct GNUNET_OS_Process *proc)
Cleans up process structure contents (OS-dependent) and deallocates it.
Definition: os_priority.c:287
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_SIGCHLD
Definition: platform.h:42
ssize_t GNUNET_DISK_file_read(const struct GNUNET_DISK_FileHandle *h, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:732
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:963
static unsigned int verbose
Are we running &#39;verbosely&#39;?
The reading socket is ready.
Context information passed to each scheduler task.
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, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1300
#define GNUNET_TIME_UNIT_MINUTES
One minute.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_max(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the maximum of two relative time values.
Definition: time.c:287
int GNUNET_BIO_write_string(struct GNUNET_BIO_WriteHandle *h, const char *s)
Write a string to a file.
Definition: bio.c:523
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_verbose(unsigned int *level)
Define the &#39;-V&#39; verbosity option.
int GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1438
char * filename
Filename of the work item.
static void maint_child_death(void *cls)
Task triggered whenever we receive a SIGCHLD (child process died).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:418
#define MIN_DELAY
int GNUNET_DISK_directory_test(const char *fil, int is_readable)
Test if fil is a directory and listable.
Definition: disk.c:503
static int ok
Return value from &#39;main&#39; (0 == success)
struct WorkItem * next
PENDING Work is kept in a linked list.
#define GNUNET_NO
Definition: gnunet_common.h:78
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:1636
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
void GNUNET_SIGNAL_handler_uninstall(struct GNUNET_SIGNAL_Context *ctx)
Uninstall a previously installed signal hander.
Definition: signal.c:77
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
static void work(void *cls)
Function called to process work items.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Definition of a command line option.
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
Definition: disk.c:912
static void do_stop_task(void *cls)
Task run on shutdown.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static struct GNUNET_CONTAINER_MultiHashMap * work_finished
Map from the hash of the filename (!) to a struct WorkItem that was finished.
enum GNUNET_SCHEDULER_Reason reason
Reason why the task is run now.
Internal representation of the hash map.
int GNUNET_BIO_read_close(struct GNUNET_BIO_ReadHandle *h, char **emsg)
Close an open file.
Definition: bio.c:119
static unsigned int anonymity_level
Anonymity level option to use for publishing.
#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:1753
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
static void schedule_next_task(void)
Decide what the next task is (working or scanning) and schedule it.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
struct GNUNET_BIO_ReadHandle * GNUNET_BIO_read_open(const char *fn)
Open a file for reading.
Definition: bio.c:94
static int do_shutdown
Set to GNUNET_YES if we are shutting down.
static void load_state()
Load the set of work_finished items from disk.
int GNUNET_BIO_read(struct GNUNET_BIO_ReadHandle *h, const char *what, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: bio.c:144
static struct GNUNET_OS_Process * publish_proc
Handle to the &#39;gnunet-publish&#39; process that we executed.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
#define MAX_DELAY
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1253
static int determine_id(void *cls, const char *filename)
Recursively scan the given file/directory structure to determine a unique ID that represents the curr...
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_with_priority(enum GNUNET_SCHEDULER_Priority prio, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified priority.
Definition: scheduler.c:1207
static char * value
Value of the record to add/remove.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
static char * fn
Filename of the unique file.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition: disk.c:820
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1280
#define DIR_SEPARATOR_STR
Definition: platform.h:168
GNUNET_OS_ProcessStatusType
Process status types.
struct GNUNET_OS_Process * GNUNET_OS_start_process_vap(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, char *const argv[])
Start a process.
Definition: os_priority.c:607
static int disable_extractor
Disable extractor option to use for publishing.
int GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
The writing-end of a pipe.
The reading-end of a pipe.
Handle for buffered writing.
Definition: bio.c:379
The process exited with a return code.
A 512-bit hashcode.
int GNUNET_BIO_read_string(struct GNUNET_BIO_ReadHandle *h, const char *what, char **result, size_t max_length)
Read 0-terminated string from a file.
Definition: bio.c:233
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
struct GNUNET_DISK_PipeHandle * GNUNET_DISK_pipe(int blocking_read, int blocking_write, int inherit_read, int inherit_write)
Creates an interprocess channel.
Definition: disk.c:1526
Run when otherwise idle.
static void sighandler_child_death()
Signal handler called for SIGCHLD.
static struct GNUNET_TIME_Absolute start_time
Start time of the current round; used to determine how long one iteration takes (which influences how...
#define DIR_SEPARATOR
Definition: platform.h:167
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:35
struct GNUNET_SIGNAL_Context * GNUNET_SIGNAL_handler_install(int signal, GNUNET_SIGNAL_Handler handler)
Install a signal handler that will be run if the given signal is received.
Definition: signal.c:51
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
struct GNUNET_TIME_Relative GNUNET_TIME_relative_min(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the minimum of two relative time values.
Definition: time.c:272
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static void save_state()
Save the set of work_finished items on disk.
static unsigned int content_priority
Content priority option to use for publishing.
static struct WorkItem * work_head
Head of linked list of files still to publish.
#define GNUNET_BIO_read_int32(h, i)
Read an (u)int32_t.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
static struct GNUNET_DISK_PipeHandle * sigpipe
Pipe used to communicate &#39;gnunet-publish&#39; completion (SIGCHLD) via signal.
static struct GNUNET_TESTBED_BarrierWaitHandle * wh
Our barrier wait handle.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Main function that will be run by the scheduler.
int GNUNET_BIO_write_close(struct GNUNET_BIO_WriteHandle *h)
Close an open file for writing.
Definition: bio.c:438
int main(int argc, char *const *argv)
The main function to automatically publish content to GNUnet.
struct GNUNET_HashCode id
Unique identity for this work item (used to detect if we need to do the work again).
int GNUNET_DISK_pipe_close(struct GNUNET_DISK_PipeHandle *p)
Closes an interprocess channel.
Definition: disk.c:1715
static int do_disable_creation_time
Disable creation time option to use for publishing.
static char * get_state_file()
Compute the name of the state database file we will use.
static int free_item(void *cls, const struct GNUNET_HashCode *key, void *value)
Free memory associated with the work item from the work_finished map.
configuration data
Definition: configuration.c:85
struct GNUNET_BIO_WriteHandle * GNUNET_BIO_write_open(const char *fn)
Open a file for writing.
Definition: bio.c:410
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:375
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
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
int GNUNET_BIO_write_int32(struct GNUNET_BIO_WriteHandle *h, int32_t i)
Write an (u)int32_t.
Definition: bio.c:582
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:367
static unsigned int replication_level
Replication level option to use for publishing.
static int write_item(void *cls, const struct GNUNET_HashCode *key, void *value)
Write work item from the work_finished map to the given write handle.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
void GNUNET_CRYPTO_hash_xor(const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *b, struct GNUNET_HashCode *result)
compute result = a ^ b
Definition: crypto_hash.c:202
int GNUNET_BIO_write(struct GNUNET_BIO_WriteHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition: bio.c:483
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_uint(char shortName, const char *name, const char *argumentHelp, const char *description, unsigned int *val)
Allow user to specify an unsigned int.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
Handle used to access files (and pipes).
struct GNUNET_TIME_Relative GNUNET_TIME_relative_saturating_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Saturating multiply relative time by a given factor.
Definition: time.c:501
Handle used to manage a pipe.
Definition: disk.c:68
static void scan(void *cls)
Periodically run task to update our view of the directory to share.
static struct GNUNET_SCHEDULER_Task * run_task
Handle for the main task that does scanning and working.
Handle for buffered reading.
Definition: bio.c:53
#define GNUNET_free(ptr)
Wrapper around free.
static int add_file(void *cls, const char *filename)
Function called with a filename (or directory name) to publish (if it has changed since the last time...
Time for relative time used by GNUnet, in microseconds.
static struct WorkItem * work_tail
Tail of linked list of files still to publish.
#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:225
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966