-only trigger check config if we actually need it
[oweals/gnunet.git] / src / fs / gnunet-auto-share.c
index fc85b29e45f79121cc5c3fe116ae44b28f19b795..96f86bf5d43c3347ed01b44ce8336dcd4026859c 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2001--2012 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2001--2012 GNUnet e.V.
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -94,11 +94,6 @@ static int disable_extractor;
  */
 static int do_disable_creation_time;
 
-/**
- * Handle for the 'shutdown' task.
- */
-static struct GNUNET_SCHEDULER_Task *kill_task;
-
 /**
  * Handle for the main task that does scanning and working.
  */
@@ -317,17 +312,14 @@ save_state ()
  * Task run on shutdown.  Serializes our current state to disk.
  *
  * @param cls closure, unused
- * @param tc scheduler context, unused
  */
 static void
-do_stop_task (void *cls, 
-             const struct GNUNET_SCHEDULER_TaskContext *tc)
+do_stop_task (void *cls)
 {
-  kill_task = NULL;
   do_shutdown = GNUNET_YES;
   if (NULL != publish_proc)
   {
-    GNUNET_OS_process_kill (publish_proc, 
+    GNUNET_OS_process_kill (publish_proc,
                            SIGKILL);
     return;
   }
@@ -351,11 +343,9 @@ schedule_next_task (void);
  * process died).
  *
  * @param cls the `struct WorkItem` we were working on
- * @param tc context
  */
 static void
-maint_child_death (void *cls, 
-                  const struct GNUNET_SCHEDULER_TaskContext *tc)
+maint_child_death (void *cls)
 {
   struct WorkItem *wi = cls;
   struct GNUNET_HashCode key;
@@ -364,10 +354,12 @@ maint_child_death (void *cls,
   int ret;
   char c;
   const struct GNUNET_DISK_FileHandle *pr;
+  const struct GNUNET_SCHEDULER_TaskContext *tc;
 
   run_task = NULL;
   pr = GNUNET_DISK_pipe_handle (sigpipe,
                                GNUNET_DISK_PIPE_END_READ);
+  tc = GNUNET_SCHEDULER_get_task_context ();
   if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY))
   {
     /* shutdown scheduled us, someone else will kill child,
@@ -378,6 +370,8 @@ maint_child_death (void *cls,
                                      &maint_child_death, wi);
     return;
   }
+  /* consume the signal */
+  GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof (c)));
 
   ret = GNUNET_OS_process_status (publish_proc,
                                  &type,
@@ -385,21 +379,20 @@ maint_child_death (void *cls,
   GNUNET_assert (GNUNET_SYSERR != ret);
   if (GNUNET_NO == ret)
   {
-    /* process still running? Well, how did we get here?
-       Anyway, answer is to kill it! */
+    /* process still running? Then where did the SIGCHLD come from?
+       Well, let's declare it spurious (kernel bug?) and keep rolling.
+    */
     GNUNET_break (0);
-    GNUNET_OS_process_kill (publish_proc, 
-                           SIGKILL);
-    ret = GNUNET_OS_process_status (publish_proc,
-                                   &type,
-                                   &code);
+    run_task =
+      GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
+                                     pr,
+                                     &maint_child_death, wi);
+    return;
   }
   GNUNET_assert (GNUNET_OK == ret);
-  
+
   GNUNET_OS_process_destroy (publish_proc);
   publish_proc = NULL;
-  /* consume the signal */
-  GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof (c)));
 
   if (GNUNET_YES == do_shutdown)
   {
@@ -456,11 +449,9 @@ sighandler_child_death ()
  * Function called to process work items.
  *
  * @param cls closure, NULL
- * @param tc scheduler context (unused)
  */
 static void
-work (void *cls,
-      const struct GNUNET_SCHEDULER_TaskContext *tc)
+work (void *cls)
 {
   static char *argv[14];
   static char anon_level[20];
@@ -520,7 +511,7 @@ work (void *cls,
                                             NULL);
     return;
   }
-  pr = GNUNET_DISK_pipe_handle (sigpipe, 
+  pr = GNUNET_DISK_pipe_handle (sigpipe,
                                GNUNET_DISK_PIPE_END_READ);
   run_task =
     GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
@@ -548,13 +539,13 @@ determine_id (void *cls,
 
   if (0 != STAT (filename, &sbuf))
   {
-    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, 
-                             "stat", 
+    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+                             "stat",
                              filename);
     return GNUNET_OK;
   }
-  GNUNET_CRYPTO_hash (filename, 
-                     strlen (filename), 
+  GNUNET_CRYPTO_hash (filename,
+                     strlen (filename),
                      &fx[0]);
   if (!S_ISDIR (sbuf.st_mode))
   {
@@ -563,8 +554,8 @@ determine_id (void *cls,
     fattr[0] = GNUNET_htonll (sbuf.st_size);
     fattr[0] = GNUNET_htonll (sbuf.st_mtime);
 
-    GNUNET_CRYPTO_hash (fattr, 
-                       sizeof (fattr), 
+    GNUNET_CRYPTO_hash (fattr,
+                       sizeof (fattr),
                        &fx[1]);
   }
   else
@@ -578,7 +569,7 @@ determine_id (void *cls,
   }
   /* use hash here to make hierarchical structure distinct from
      all files on the same level */
-  GNUNET_CRYPTO_hash (fx, 
+  GNUNET_CRYPTO_hash (fx,
                      sizeof (fx),
                      &ft);
   /* use XOR here so that order of the files in the directory
@@ -652,11 +643,9 @@ add_file (void *cls,
  * Periodically run task to update our view of the directory to share.
  *
  * @param cls NULL
- * @param tc scheduler context, unused
  */
 static void
-scan (void *cls, 
-      const struct GNUNET_SCHEDULER_TaskContext *tc)
+scan (void *cls)
 {
   run_task = NULL;
   start_time = GNUNET_TIME_absolute_get ();
@@ -694,7 +683,7 @@ schedule_next_task ()
   }
   else
   {
-    run_task = GNUNET_SCHEDULER_add_now (&work, 
+    run_task = GNUNET_SCHEDULER_add_now (&work,
                                         NULL);
   }
 }
@@ -709,15 +698,15 @@ schedule_next_task ()
  * @param c configuration
  */
 static void
-run (void *cls, 
-     char *const *args, 
+run (void *cls,
+     char *const *args,
      const char *cfgfile,
      const struct GNUNET_CONFIGURATION_Handle *c)
 {
   /* check arguments */
-  if ( (NULL == args[0]) || 
+  if ( (NULL == args[0]) ||
        (NULL != args[1]) ||
-       (GNUNET_YES != 
+       (GNUNET_YES !=
        GNUNET_DISK_directory_test (args[0],
                                    GNUNET_YES)) )
   {
@@ -728,16 +717,14 @@ run (void *cls,
   cfg_filename = GNUNET_strdup (cfgfile);
   cfg = c;
   dir_name = args[0];
-  work_finished = GNUNET_CONTAINER_multihashmap_create (1024, 
+  work_finished = GNUNET_CONTAINER_multihashmap_create (1024,
                                                        GNUNET_NO);
   load_state ();
   run_task = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE,
-                                                &scan, 
+                                                &scan,
                                                 NULL);
-  kill_task =
-      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, 
-                                   &do_stop_task,
-                                    NULL);
+  GNUNET_SCHEDULER_add_shutdown (&do_stop_task,
+                                NULL);
 }
 
 
@@ -798,17 +785,17 @@ main (int argc, char *const *argv)
   int ok;
   struct GNUNET_SIGNAL_Context *shc_chld;
 
-  if (GNUNET_OK != 
+  if (GNUNET_OK !=
       GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
     return 2;
-  sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, 
+  sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO,
                              GNUNET_NO, GNUNET_NO);
   GNUNET_assert (NULL != sigpipe);
   shc_chld =
     GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD,
                                   &sighandler_child_death);
   ok = (GNUNET_OK ==
-       GNUNET_PROGRAM_run (argc, argv, 
+       GNUNET_PROGRAM_run (argc, argv,
                            "gnunet-auto-share [OPTIONS] FILENAME",
                            gettext_noop
                            ("Automatically publish files from a directory on GNUnet"),
@@ -822,7 +809,7 @@ main (int argc, char *const *argv)
   }
   while (NULL != (wi = work_head))
   {
-    GNUNET_CONTAINER_DLL_remove (work_head, 
+    GNUNET_CONTAINER_DLL_remove (work_head,
                                 work_tail,
                                 wi);
     GNUNET_free (wi->filename);
@@ -832,7 +819,7 @@ main (int argc, char *const *argv)
   shc_chld = NULL;
   GNUNET_DISK_pipe_close (sigpipe);
   sigpipe = NULL;
-  GNUNET_free (cfg_filename);
+  GNUNET_free_non_null (cfg_filename);
   cfg_filename = NULL;
   GNUNET_free ((void*) argv);
   return ok;