GNUnet  0.10.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 {
45  struct WorkItem *prev;
46 
50  struct WorkItem *next;
51 
55  char *filename;
56 
62 };
63 
64 
68 static int ret;
69 
73 static unsigned int verbose;
74 
78 static const struct GNUNET_CONFIGURATION_Handle *cfg;
79 
83 static char *cfg_filename;
84 
88 static int disable_extractor;
89 
94 
99 
103 static unsigned int anonymity_level = 1;
104 
108 static unsigned int content_priority = 365;
109 
113 static unsigned int replication_level = 1;
114 
118 static const char *dir_name;
119 
123 static struct WorkItem *work_head;
124 
128 static struct WorkItem *work_tail;
129 
135 
139 static int do_shutdown;
140 
147 
152 
157 
158 
162 static char *
164 {
165  char *ret;
166 
167  GNUNET_asprintf(&ret,
168  "%s%s.auto-share",
169  dir_name,
170  (DIR_SEPARATOR == dir_name[strlen(dir_name) - 1])
171  ? ""
173  return ret;
174 }
175 
176 
180 static void
182 {
183  char *fn;
184  struct GNUNET_BIO_ReadHandle *rh;
185  uint32_t n;
186  struct GNUNET_HashCode id;
187  struct WorkItem *wi;
188  char *emsg;
189 
190  emsg = NULL;
191  fn = get_state_file();
192  rh = GNUNET_BIO_read_open(fn);
193  GNUNET_free(fn);
194  if (NULL == rh)
195  return;
196  fn = NULL;
197  if (GNUNET_OK != GNUNET_BIO_read_int32(rh, &n))
198  goto error;
199  while (n-- > 0)
200  {
201  if ((GNUNET_OK != GNUNET_BIO_read_string(rh, "filename", &fn, 1024)) ||
202  (GNUNET_OK !=
203  GNUNET_BIO_read(rh, "id", &id, sizeof(struct GNUNET_HashCode))))
204  goto error;
205  wi = GNUNET_new(struct WorkItem);
206  wi->id = id;
207  wi->filename = fn;
209  "Loaded serialization ID for `%s' is `%s'\n",
210  wi->filename,
211  GNUNET_h2s(&id));
212  fn = NULL;
213  GNUNET_CRYPTO_hash(wi->filename, strlen(wi->filename), &id);
216  work_finished,
217  &id,
218  wi,
220  }
221  if (GNUNET_OK == GNUNET_BIO_read_close(rh, &emsg))
222  return;
223  rh = NULL;
224 error:
226  if (NULL != rh)
227  (void)GNUNET_BIO_read_close(rh, &emsg);
229  _("Failed to load state: %s\n"),
230  emsg);
231  GNUNET_free_non_null(emsg);
232 }
233 
234 
243 static int
244 write_item(void *cls, const struct GNUNET_HashCode *key, void *value)
245 {
246  struct GNUNET_BIO_WriteHandle *wh = cls;
247  struct WorkItem *wi = value;
248 
250  "Saving serialization ID of file `%s' with value `%s'\n",
251  wi->filename,
252  GNUNET_h2s(&wi->id));
253  if ((GNUNET_OK != GNUNET_BIO_write_string(wh, wi->filename)) ||
254  (GNUNET_OK !=
255  GNUNET_BIO_write(wh, &wi->id, sizeof(struct GNUNET_HashCode))))
256  return GNUNET_SYSERR; /* write error, abort iteration */
257  return GNUNET_OK;
258 }
259 
260 
264 static void
266 {
267  uint32_t n;
268  struct GNUNET_BIO_WriteHandle *wh;
269  char *fn;
270 
271  n = GNUNET_CONTAINER_multihashmap_size(work_finished);
272  fn = get_state_file();
273  wh = GNUNET_BIO_write_open(fn);
274  if (NULL == wh)
275  {
277  _("Failed to save state to file %s\n"),
278  fn);
279  GNUNET_free(fn);
280  return;
281  }
282  if (GNUNET_OK != GNUNET_BIO_write_int32(wh, n))
283  {
284  (void)GNUNET_BIO_write_close(wh);
286  _("Failed to save state to file %s\n"),
287  fn);
288  GNUNET_free(fn);
289  return;
290  }
291  (void)GNUNET_CONTAINER_multihashmap_iterate(work_finished, &write_item, wh);
294  _("Failed to save state to file %s\n"),
295  fn);
296  GNUNET_free(fn);
297 }
298 
299 
305 static void
306 do_stop_task(void *cls)
307 {
309  if (NULL != publish_proc)
310  {
311  GNUNET_OS_process_kill(publish_proc, SIGKILL);
312  return;
313  }
314  if (NULL != run_task)
315  {
316  GNUNET_SCHEDULER_cancel(run_task);
317  run_task = NULL;
318  }
319 }
320 
321 
325 static void
326 schedule_next_task(void);
327 
328 
335 static void
337 {
338  struct WorkItem *wi = cls;
339  struct GNUNET_HashCode key;
341  unsigned long code;
342  int ret;
343  char c;
344  const struct GNUNET_DISK_FileHandle *pr;
345  const struct GNUNET_SCHEDULER_TaskContext *tc;
346 
347  run_task = NULL;
351  {
352  /* shutdown scheduled us, someone else will kill child,
353  we should just try again */
355  pr,
357  wi);
358  return;
359  }
360  /* consume the signal */
361  GNUNET_break(0 < GNUNET_DISK_file_read(pr, &c, sizeof(c)));
362 
363  ret = GNUNET_OS_process_status(publish_proc, &type, &code);
365  if (GNUNET_NO == ret)
366  {
367  /* process still running? Then where did the SIGCHLD come from?
368  Well, let's declare it spurious (kernel bug?) and keep rolling.
369  */
370  GNUNET_break(0);
372  pr,
374  wi);
375  return;
376  }
377  GNUNET_assert(GNUNET_OK == ret);
378 
379  GNUNET_OS_process_destroy(publish_proc);
380  publish_proc = NULL;
381 
382  if (GNUNET_YES == do_shutdown)
383  {
384  GNUNET_free(wi->filename);
385  GNUNET_free(wi);
386  return;
387  }
388  if ((GNUNET_OS_PROCESS_EXITED == type) && (0 == code))
389  {
391  _("Publication of `%s' done\n"),
392  wi->filename);
393  GNUNET_CRYPTO_hash(wi->filename, strlen(wi->filename), &key);
396  work_finished,
397  &key,
398  wi,
400  }
401  else
402  {
403  GNUNET_CONTAINER_DLL_insert_tail(work_head, work_tail, wi);
404  }
405  save_state();
407 }
408 
409 
414 static void
416 {
417  static char c;
418  int old_errno = errno; /* back-up errno */
419 
420  GNUNET_break(
421  1 ==
424  &c,
425  sizeof(c)));
426  errno = old_errno; /* restore errno */
427 }
428 
429 
435 static void
436 work(void *cls)
437 {
438  static char *argv[14];
439  static char anon_level[20];
440  static char content_prio[20];
441  static char repl_level[20];
442  struct WorkItem *wi;
443  const struct GNUNET_DISK_FileHandle *pr;
444  int argc;
445 
446  run_task = NULL;
447  wi = work_head;
448  GNUNET_CONTAINER_DLL_remove(work_head, work_tail, wi);
449  argc = 0;
450  argv[argc++] = "gnunet-publish";
451  if (verbose)
452  argv[argc++] = "-V";
453  if (disable_extractor)
454  argv[argc++] = "-D";
456  argv[argc++] = "-d";
457  argv[argc++] = "-c";
458  argv[argc++] = cfg_filename;
459  GNUNET_snprintf(anon_level, sizeof(anon_level), "%u", anonymity_level);
460  argv[argc++] = "-a";
461  argv[argc++] = anon_level;
462  GNUNET_snprintf(content_prio, sizeof(content_prio), "%u", content_priority);
463  argv[argc++] = "-p";
464  argv[argc++] = content_prio;
465  GNUNET_snprintf(repl_level, sizeof(repl_level), "%u", replication_level);
466  argv[argc++] = "-r";
467  argv[argc++] = repl_level;
468  argv[argc++] = wi->filename;
469  argv[argc] = NULL;
470  GNUNET_log(GNUNET_ERROR_TYPE_INFO, _("Publishing `%s'\n"), wi->filename);
471  GNUNET_assert(NULL == publish_proc);
473  0,
474  NULL,
475  NULL,
476  NULL,
477  "gnunet-publish",
478  argv);
479  if (NULL == publish_proc)
480  {
482  _("Failed to run `%s'\n"),
483  "gnunet-publish");
484  GNUNET_CONTAINER_DLL_insert(work_head, work_tail, wi);
485  run_task =
487  return;
488  }
491  pr,
493  wi);
494 }
495 
496 
505 static int
506 determine_id(void *cls, const char *filename)
507 {
508  struct GNUNET_HashCode *id = cls;
509  struct stat sbuf;
510  struct GNUNET_HashCode fx[2];
511  struct GNUNET_HashCode ft;
512 
513  if (0 != stat(filename, &sbuf))
514  {
516  return GNUNET_OK;
517  }
518  GNUNET_CRYPTO_hash(filename, strlen(filename), &fx[0]);
519  if (!S_ISDIR(sbuf.st_mode))
520  {
521  uint64_t fattr[2];
522 
523  fattr[0] = GNUNET_htonll(sbuf.st_size);
524  fattr[0] = GNUNET_htonll(sbuf.st_mtime);
525 
526  GNUNET_CRYPTO_hash(fattr, sizeof(fattr), &fx[1]);
527  }
528  else
529  {
530  memset(&fx[1], 1, sizeof(struct GNUNET_HashCode));
531  GNUNET_DISK_directory_scan(filename, &determine_id, &fx[1]);
532  }
533  /* use hash here to make hierarchical structure distinct from
534  all files on the same level */
535  GNUNET_CRYPTO_hash(fx, sizeof(fx), &ft);
536  /* use XOR here so that order of the files in the directory
537  does not matter! */
538  GNUNET_CRYPTO_hash_xor(&ft, id, id);
539  return GNUNET_OK;
540 }
541 
542 
552 static int
553 add_file(void *cls, const char *filename)
554 {
555  struct WorkItem *wi;
556  struct GNUNET_HashCode key;
557  struct GNUNET_HashCode id;
558 
559  if (GNUNET_YES == do_shutdown)
560  return GNUNET_SYSERR;
561  if ((NULL != strstr(filename, "/.auto-share")) ||
562  (NULL != strstr(filename, "\\.auto-share")))
563  return GNUNET_OK; /* skip internal file */
564  GNUNET_CRYPTO_hash(filename, strlen(filename), &key);
565  wi = GNUNET_CONTAINER_multihashmap_get(work_finished, &key);
566  memset(&id, 0, sizeof(struct GNUNET_HashCode));
567  determine_id(&id, filename);
568  if (NULL != wi)
569  {
570  if (0 == memcmp(&id, &wi->id, sizeof(struct GNUNET_HashCode)))
571  return GNUNET_OK; /* skip: we did this one already */
572  /* contents changed, need to re-do the directory... */
574  GNUNET_YES ==
575  GNUNET_CONTAINER_multihashmap_remove(work_finished, &key, wi));
576  }
577  else
578  {
579  wi = GNUNET_new(struct WorkItem);
580  wi->filename = GNUNET_strdup(filename);
581  }
582  wi->id = id;
583  GNUNET_CONTAINER_DLL_insert(work_head, work_tail, wi);
584  if (GNUNET_YES == do_shutdown)
585  return GNUNET_SYSERR;
586  return GNUNET_OK;
587 }
588 
589 
595 static void
596 scan(void *cls)
597 {
598  run_task = NULL;
602 }
603 
604 
608 static void
610 {
611  struct GNUNET_TIME_Relative delay;
612 
613  if (GNUNET_YES == do_shutdown)
614  return;
615  GNUNET_assert(NULL == run_task);
616  if (NULL == work_head)
617  {
618  /* delay by at most 4h, at least 1s, and otherwise in between depending
619  on how long it took to scan */
621  delay = GNUNET_TIME_relative_saturating_multiply(delay, 100);
622  delay = GNUNET_TIME_relative_min(delay, MAX_DELAY);
623  delay = GNUNET_TIME_relative_max(delay, MIN_DELAY);
624  run_task = GNUNET_SCHEDULER_add_delayed(delay, &scan, NULL);
625  }
626  else
627  {
628  run_task = GNUNET_SCHEDULER_add_now(&work, NULL);
629  }
630 }
631 
632 
641 static void
642 run(void *cls,
643  char *const *args,
644  const char *cfgfile,
645  const struct GNUNET_CONFIGURATION_Handle *c)
646 {
647  /* check arguments */
648  if ((NULL == args[0]) || (NULL != args[1]) ||
650  {
651  printf(_(
652  "You must specify one and only one directory name for automatic publication.\n"));
653  ret = -1;
654  return;
655  }
656  cfg_filename = GNUNET_strdup(cfgfile);
657  cfg = c;
658  dir_name = args[0];
659  work_finished = GNUNET_CONTAINER_multihashmap_create(1024, GNUNET_NO);
660  load_state();
662  &scan,
663  NULL);
665 }
666 
667 
676 static int
677 free_item(void *cls, const struct GNUNET_HashCode *key, void *value)
678 {
679  struct WorkItem *wi = value;
680 
681  GNUNET_free(wi->filename);
682  GNUNET_free(wi);
683  return GNUNET_OK;
684 }
685 
686 
694 int
695 main(int argc, char *const *argv)
696 {
697  struct GNUNET_GETOPT_CommandLineOption options[] = {
699  "anonymity",
700  "LEVEL",
701  gettext_noop(
702  "set the desired LEVEL of sender-anonymity"),
703  &anonymity_level),
704 
706  'd',
707  "disable-creation-time",
708  gettext_noop(
709  "disable adding the creation time to the metadata of the uploaded file"),
711 
713  'D',
714  "disable-extractor",
715  gettext_noop("do not use libextractor to add keywords or metadata"),
717 
719  "priority",
720  "PRIORITY",
721  gettext_noop(
722  "specify the priority of the content"),
724 
726  "replication",
727  "LEVEL",
728  gettext_noop(
729  "set the desired replication LEVEL"),
731 
733 
735  };
736  struct WorkItem *wi;
737  int ok;
738  struct GNUNET_SIGNAL_Context *shc_chld;
739 
740  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args(argc, argv, &argc, &argv))
741  return 2;
743  GNUNET_assert(NULL != sigpipe);
744  shc_chld =
746  ok =
747  (GNUNET_OK ==
749  argc,
750  argv,
751  "gnunet-auto-share [OPTIONS] FILENAME",
752  gettext_noop("Automatically publish files from a directory on GNUnet"),
753  options,
754  &run,
755  NULL))
756  ? ret
757  : 1;
758  if (NULL != work_finished)
759  {
760  (void)GNUNET_CONTAINER_multihashmap_iterate(work_finished,
761  &free_item,
762  NULL);
764  }
765  while (NULL != (wi = work_head))
766  {
767  GNUNET_CONTAINER_DLL_remove(work_head, work_tail, wi);
768  GNUNET_free(wi->filename);
769  GNUNET_free(wi);
770  }
772  shc_chld = NULL;
773  GNUNET_DISK_pipe_close(sigpipe);
774  sigpipe = NULL;
776  cfg_filename = NULL;
777  GNUNET_free((void *)argv);
778  return ok;
779 }
780 
781 /* 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:737
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:286
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:729
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:1284
#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:521
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:1439
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:410
#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:500
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:1615
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:75
#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:909
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:118
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:1744
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:93
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:143
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:1237
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:1191
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:44
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:817
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:1264
#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:378
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:232
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:1518
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:50
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:436
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:1706
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:83
struct GNUNET_BIO_WriteHandle * GNUNET_BIO_write_open(const char *fn)
Open a file for writing.
Definition: bio.c:408
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:373
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:131
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:580
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:193
int GNUNET_BIO_write(struct GNUNET_BIO_WriteHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition: bio.c:481
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:499
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:224
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956