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_file (fn);
194  GNUNET_free (fn);
195  if (NULL == rh)
196  return;
197  fn = NULL;
198  if (GNUNET_OK != GNUNET_BIO_read_int32 (rh, "number of files",
199  (int32_t *) &n))
200  goto error;
201  while (n-- > 0)
202  {
203  struct GNUNET_BIO_ReadSpec rs[] = {
204  GNUNET_BIO_read_spec_string("filename", &fn, 1024),
205  GNUNET_BIO_read_spec_object("id", &id, sizeof(struct GNUNET_HashCode)),
207  };
208  if (GNUNET_OK != GNUNET_BIO_read_spec_commit (rh, rs))
209  goto error;
210  wi = GNUNET_new (struct WorkItem);
211  wi->id = id;
212  wi->filename = fn;
214  "Loaded serialization ID for `%s' is `%s'\n",
215  wi->filename,
216  GNUNET_h2s (&id));
217  fn = NULL;
218  GNUNET_CRYPTO_hash (wi->filename, strlen (wi->filename), &id);
221  work_finished,
222  &id,
223  wi,
225  }
226  if (GNUNET_OK == GNUNET_BIO_read_close (rh, &emsg))
227  return;
228  rh = NULL;
229 error:
230  GNUNET_free (fn);
231  if (NULL != rh)
232  (void) GNUNET_BIO_read_close (rh, &emsg);
234  _ ("Failed to load state: %s\n"),
235  emsg);
236  GNUNET_free (emsg);
237 }
238 
239 
248 static int
249 write_item (void *cls, const struct GNUNET_HashCode *key, void *value)
250 {
251  struct GNUNET_BIO_WriteHandle *wh = cls;
252  struct WorkItem *wi = value;
253 
255  "Saving serialization ID of file `%s' with value `%s'\n",
256  wi->filename,
257  GNUNET_h2s (&wi->id));
258  struct GNUNET_BIO_WriteSpec ws[] = {
259  GNUNET_BIO_write_spec_string ("auto-share-write-item-filename",
260  wi->filename),
261  GNUNET_BIO_write_spec_object ("id", &wi->id, sizeof(struct GNUNET_HashCode)),
263  };
264  if (GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws))
265  return GNUNET_SYSERR; /* write error, abort iteration */
266  return GNUNET_OK;
267 }
268 
269 
273 static void
275 {
276  uint32_t n;
277  struct GNUNET_BIO_WriteHandle *wh;
278  char *fn;
279 
280  n = GNUNET_CONTAINER_multihashmap_size (work_finished);
281  fn = get_state_file ();
282  wh = GNUNET_BIO_write_open_file (fn);
283  if (NULL == wh)
284  {
286  _ ("Failed to save state to file %s\n"),
287  fn);
288  GNUNET_free (fn);
289  return;
290  }
291  if (GNUNET_OK != GNUNET_BIO_write_int32 (wh, "size of state", n))
292  {
293  (void) GNUNET_BIO_write_close (wh, NULL);
295  _ ("Failed to save state to file %s\n"),
296  fn);
297  GNUNET_free (fn);
298  return;
299  }
300  (void) GNUNET_CONTAINER_multihashmap_iterate (work_finished, &write_item, wh);
301  if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
303  _ ("Failed to save state to file %s\n"),
304  fn);
305  GNUNET_free (fn);
306 }
307 
308 
314 static void
315 do_stop_task (void *cls)
316 {
318  if (NULL != publish_proc)
319  {
320  GNUNET_OS_process_kill (publish_proc, SIGKILL);
321  return;
322  }
323  if (NULL != run_task)
324  {
325  GNUNET_SCHEDULER_cancel (run_task);
326  run_task = NULL;
327  }
328 }
329 
330 
334 static void
335 schedule_next_task (void);
336 
337 
344 static void
345 maint_child_death (void *cls)
346 {
347  struct WorkItem *wi = cls;
348  struct GNUNET_HashCode key;
350  unsigned long code;
351  int ret;
352  char c;
353  const struct GNUNET_DISK_FileHandle *pr;
354  const struct GNUNET_SCHEDULER_TaskContext *tc;
355 
356  run_task = NULL;
360  {
361  /* shutdown scheduled us, someone else will kill child,
362  we should just try again */
364  pr,
366  wi);
367  return;
368  }
369  /* consume the signal */
370  GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof(c)));
371 
372  ret = GNUNET_OS_process_status (publish_proc, &type, &code);
373  GNUNET_assert (GNUNET_SYSERR != ret);
374  if (GNUNET_NO == ret)
375  {
376  /* process still running? Then where did the SIGCHLD come from?
377  Well, let's declare it spurious (kernel bug?) and keep rolling.
378  */
379  GNUNET_break (0);
381  pr,
383  wi);
384  return;
385  }
386  GNUNET_assert (GNUNET_OK == ret);
387 
388  GNUNET_OS_process_destroy (publish_proc);
389  publish_proc = NULL;
390 
391  if (GNUNET_YES == do_shutdown)
392  {
393  GNUNET_free (wi->filename);
394  GNUNET_free (wi);
395  return;
396  }
397  if ((GNUNET_OS_PROCESS_EXITED == type) && (0 == code))
398  {
400  _ ("Publication of `%s' done\n"),
401  wi->filename);
402  GNUNET_CRYPTO_hash (wi->filename, strlen (wi->filename), &key);
405  work_finished,
406  &key,
407  wi,
409  }
410  else
411  {
412  GNUNET_CONTAINER_DLL_insert_tail (work_head, work_tail, wi);
413  }
414  save_state ();
416 }
417 
418 
423 static void
425 {
426  static char c;
427  int old_errno = errno; /* back-up errno */
428 
429  GNUNET_break (
430  1 ==
433  &c,
434  sizeof(c)));
435  errno = old_errno; /* restore errno */
436 }
437 
438 
444 static void
445 work (void *cls)
446 {
447  static char *argv[14];
448  static char anon_level[20];
449  static char content_prio[20];
450  static char repl_level[20];
451  struct WorkItem *wi;
452  const struct GNUNET_DISK_FileHandle *pr;
453  int argc;
454 
455  run_task = NULL;
456  wi = work_head;
457  GNUNET_CONTAINER_DLL_remove (work_head, work_tail, wi);
458  argc = 0;
459  argv[argc++] = "gnunet-publish";
460  if (verbose)
461  argv[argc++] = "-V";
462  if (disable_extractor)
463  argv[argc++] = "-D";
465  argv[argc++] = "-d";
466  argv[argc++] = "-c";
467  argv[argc++] = cfg_filename;
468  GNUNET_snprintf (anon_level, sizeof(anon_level), "%u", anonymity_level);
469  argv[argc++] = "-a";
470  argv[argc++] = anon_level;
471  GNUNET_snprintf (content_prio, sizeof(content_prio), "%u", content_priority);
472  argv[argc++] = "-p";
473  argv[argc++] = content_prio;
474  GNUNET_snprintf (repl_level, sizeof(repl_level), "%u", replication_level);
475  argv[argc++] = "-r";
476  argv[argc++] = repl_level;
477  argv[argc++] = wi->filename;
478  argv[argc] = NULL;
479  GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Publishing `%s'\n"), wi->filename);
480  GNUNET_assert (NULL == publish_proc);
481  publish_proc = GNUNET_OS_start_process_vap (GNUNET_YES,
482  0,
483  NULL,
484  NULL,
485  NULL,
486  "gnunet-publish",
487  argv);
488  if (NULL == publish_proc)
489  {
491  _ ("Failed to run `%s'\n"),
492  "gnunet-publish");
493  GNUNET_CONTAINER_DLL_insert (work_head, work_tail, wi);
494  run_task =
496  return;
497  }
500  pr,
502  wi);
503 }
504 
505 
514 static int
515 determine_id (void *cls, const char *filename)
516 {
517  struct GNUNET_HashCode *id = cls;
518  struct stat sbuf;
519  struct GNUNET_HashCode fx[2];
520  struct GNUNET_HashCode ft;
521 
522  if (0 != stat (filename, &sbuf))
523  {
525  return GNUNET_OK;
526  }
527  GNUNET_CRYPTO_hash (filename, strlen (filename), &fx[0]);
528  if (! S_ISDIR (sbuf.st_mode))
529  {
530  uint64_t fattr[2];
531 
532  fattr[0] = GNUNET_htonll (sbuf.st_size);
533  fattr[0] = GNUNET_htonll (sbuf.st_mtime);
534 
535  GNUNET_CRYPTO_hash (fattr, sizeof(fattr), &fx[1]);
536  }
537  else
538  {
539  memset (&fx[1], 1, sizeof(struct GNUNET_HashCode));
540  GNUNET_DISK_directory_scan (filename, &determine_id, &fx[1]);
541  }
542  /* use hash here to make hierarchical structure distinct from
543  all files on the same level */
544  GNUNET_CRYPTO_hash (fx, sizeof(fx), &ft);
545  /* use XOR here so that order of the files in the directory
546  does not matter! */
547  GNUNET_CRYPTO_hash_xor (&ft, id, id);
548  return GNUNET_OK;
549 }
550 
551 
561 static int
562 add_file (void *cls, const char *filename)
563 {
564  struct WorkItem *wi;
565  struct GNUNET_HashCode key;
566  struct GNUNET_HashCode id;
567 
568  if (GNUNET_YES == do_shutdown)
569  return GNUNET_SYSERR;
570  if ((NULL != strstr (filename, "/.auto-share")) ||
571  (NULL != strstr (filename, "\\.auto-share")))
572  return GNUNET_OK; /* skip internal file */
573  GNUNET_CRYPTO_hash (filename, strlen (filename), &key);
574  wi = GNUNET_CONTAINER_multihashmap_get (work_finished, &key);
575  memset (&id, 0, sizeof(struct GNUNET_HashCode));
576  determine_id (&id, filename);
577  if (NULL != wi)
578  {
579  if (0 == memcmp (&id, &wi->id, sizeof(struct GNUNET_HashCode)))
580  return GNUNET_OK; /* skip: we did this one already */
581  /* contents changed, need to re-do the directory... */
582  GNUNET_assert (
583  GNUNET_YES ==
584  GNUNET_CONTAINER_multihashmap_remove (work_finished, &key, wi));
585  }
586  else
587  {
588  wi = GNUNET_new (struct WorkItem);
589  wi->filename = GNUNET_strdup (filename);
590  }
591  wi->id = id;
592  GNUNET_CONTAINER_DLL_insert (work_head, work_tail, wi);
593  if (GNUNET_YES == do_shutdown)
594  return GNUNET_SYSERR;
595  return GNUNET_OK;
596 }
597 
598 
604 static void
605 scan (void *cls)
606 {
607  run_task = NULL;
611 }
612 
613 
617 static void
619 {
620  struct GNUNET_TIME_Relative delay;
621 
622  if (GNUNET_YES == do_shutdown)
623  return;
624  GNUNET_assert (NULL == run_task);
625  if (NULL == work_head)
626  {
627  /* delay by at most 4h, at least 1s, and otherwise in between depending
628  on how long it took to scan */
630  delay = GNUNET_TIME_relative_saturating_multiply (delay, 100);
631  delay = GNUNET_TIME_relative_min (delay, MAX_DELAY);
632  delay = GNUNET_TIME_relative_max (delay, MIN_DELAY);
633  run_task = GNUNET_SCHEDULER_add_delayed (delay, &scan, NULL);
634  }
635  else
636  {
637  run_task = GNUNET_SCHEDULER_add_now (&work, NULL);
638  }
639 }
640 
641 
650 static void
651 run (void *cls,
652  char *const *args,
653  const char *cfgfile,
654  const struct GNUNET_CONFIGURATION_Handle *c)
655 {
656  /* check arguments */
657  if ((NULL == args[0]) || (NULL != args[1]) ||
659  {
660  printf (_ (
661  "You must specify one and only one directory name for automatic publication.\n"));
662  ret = -1;
663  return;
664  }
665  cfg_filename = GNUNET_strdup (cfgfile);
666  cfg = c;
667  dir_name = args[0];
668  work_finished = GNUNET_CONTAINER_multihashmap_create (1024, GNUNET_NO);
669  load_state ();
671  &scan,
672  NULL);
674 }
675 
676 
685 static int
686 free_item (void *cls, const struct GNUNET_HashCode *key, void *value)
687 {
688  struct WorkItem *wi = value;
689 
690  GNUNET_free (wi->filename);
691  GNUNET_free (wi);
692  return GNUNET_OK;
693 }
694 
695 
703 int
704 main (int argc, char *const *argv)
705 {
706  struct GNUNET_GETOPT_CommandLineOption options[] = {
708  "anonymity",
709  "LEVEL",
710  gettext_noop (
711  "set the desired LEVEL of sender-anonymity"),
712  &anonymity_level),
713 
715  'd',
716  "disable-creation-time",
717  gettext_noop (
718  "disable adding the creation time to the metadata of the uploaded file"),
720 
722  'D',
723  "disable-extractor",
724  gettext_noop ("do not use libextractor to add keywords or metadata"),
726 
728  "priority",
729  "PRIORITY",
730  gettext_noop (
731  "specify the priority of the content"),
733 
735  "replication",
736  "LEVEL",
737  gettext_noop (
738  "set the desired replication LEVEL"),
740 
742 
744  };
745  struct WorkItem *wi;
746  int ok;
748 
749  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
750  return 2;
752  GNUNET_assert (NULL != sigpipe);
753  shc_chld =
755  ok =
756  (GNUNET_OK ==
758  argc,
759  argv,
760  "gnunet-auto-share [OPTIONS] FILENAME",
761  gettext_noop ("Automatically publish files from a directory on GNUnet"),
762  options,
763  &run,
764  NULL))
765  ? ret
766  : 1;
767  if (NULL != work_finished)
768  {
769  (void) GNUNET_CONTAINER_multihashmap_iterate (work_finished,
770  &free_item,
771  NULL);
773  }
774  while (NULL != (wi = work_head))
775  {
776  GNUNET_CONTAINER_DLL_remove (work_head, work_tail, wi);
777  GNUNET_free (wi->filename);
778  GNUNET_free (wi);
779  }
781  shc_chld = NULL;
782  GNUNET_DISK_pipe_close (sigpipe);
783  sigpipe = NULL;
785  cfg_filename = NULL;
786  GNUNET_free_nz ((void *) argv);
787  return ok;
788 }
789 
790 
791 /* end of gnunet-auto-share.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
Structure specifying a writing operation on an IO handle.
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
Definition: scheduler.c:752
#define GNUNET_BIO_read_spec_end()
End of specifications marker.
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.
int GNUNET_BIO_read_int32(struct GNUNET_BIO_ReadHandle *h, const char *what, int32_t *i)
Read an (u)int32_t.
Definition: bio.c:477
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.
struct GNUNET_BIO_ReadSpec GNUNET_BIO_read_spec_object(const char *what, void *result, size_t size)
Create the specification to read a certain amount of bytes.
Definition: bio.c:996
#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
struct GNUNET_BIO_ReadHandle * GNUNET_BIO_read_open_file(const char *fn)
Open a file for reading.
Definition: bio.c:119
int GNUNET_OS_process_status(struct GNUNET_OS_Process *proc, enum GNUNET_OS_ProcessStatusType *type, unsigned long *code)
Retrieve the status of a process.
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:1331
#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
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:1457
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:423
#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)
void * cls
Closure for rh.
struct WorkItem * next
PENDING Work is kept in a linked list.
int GNUNET_BIO_read_spec_commit(struct GNUNET_BIO_ReadHandle *h, struct GNUNET_BIO_ReadSpec *rs)
Execute the read specifications in order.
Definition: bio.c:1241
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:1667
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
void GNUNET_SIGNAL_handler_uninstall(struct GNUNET_SIGNAL_Context *ctx)
Uninstall a previously installed signal hander.
Definition: signal.c:77
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:911
struct GNUNET_BIO_WriteSpec GNUNET_BIO_write_spec_object(const char *what, void *source, size_t size)
Create the specification to read some bytes.
Definition: bio.c:1287
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 handle.
Definition: bio.c:166
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:1688
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:184
#define GNUNET_BIO_write_spec_end()
End of specifications marker.
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.
struct GNUNET_BIO_WriteSpec GNUNET_BIO_write_spec_string(const char *what, const char *s)
Create the specification to write a 0-terminated string.
Definition: bio.c:1334
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:1269
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:1223
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:1296
#define DIR_SEPARATOR_STR
Definition: platform.h:171
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.
Structure specifying a reading operation on an IO handle.
The reading-end of a pipe.
Handle for buffered writing.
Definition: bio.c:515
The process exited with a return code.
A 512-bit hashcode.
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:1461
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...
struct GNUNET_BIO_ReadSpec GNUNET_BIO_read_spec_string(const char *what, char **result, size_t max_length)
Create the specification to read a 0-terminated string.
Definition: bio.c:1044
#define DIR_SEPARATOR
Definition: platform.h:170
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:36
#define GNUNET_free_nz(ptr)
Wrapper around free.
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.
struct GNUNET_BIO_WriteHandle * GNUNET_BIO_write_open_file(const char *fn)
Open a file for writing.
Definition: bio.c:558
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.
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_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
int GNUNET_BIO_write_close(struct GNUNET_BIO_WriteHandle *h, char **emsg)
Close an IO handle.
Definition: bio.c:607
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_int32(struct GNUNET_BIO_WriteHandle *h, const char *what, int32_t i)
Write an (u)int32_t.
Definition: bio.c:935
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:1650
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.
int GNUNET_BIO_write_spec_commit(struct GNUNET_BIO_WriteHandle *h, struct GNUNET_BIO_WriteSpec *ws)
Execute the write specifications in order.
Definition: bio.c:1538
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:84
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_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.
static struct GNUNET_SIGNAL_Context * shc_chld
Child signal handler.
Definition: gnunet-qr.c:64
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
Time for absolute times used by GNUnet, in microseconds.
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
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:73
#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:972