remove protocol violation
[oweals/gnunet.git] / src / arm / gnunet-service-arm.c
index eccd8d566255af9d1ad825f3fecdb10f93b66c2f..1249fe0030008cc488516bfb4e272aac12b068b9 100644 (file)
@@ -246,8 +246,6 @@ static struct GNUNET_SERVER_Handle *server;
 static struct GNUNET_SERVER_NotificationContext *notifier;
 
 
-#include "do_start_process.c"
-
 /**
  * Transmit a status result message.
  *
@@ -262,7 +260,7 @@ write_result (void *cls, size_t size, void *buf)
   struct GNUNET_ARM_ResultMessage *msg = cls;
   size_t msize;
 
-  if (buf == NULL)
+  if (NULL == buf)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                _("Could not send status result to client\n"));
@@ -298,7 +296,7 @@ write_list_result (void *cls, size_t size, void *buf)
   struct GNUNET_ARM_ListResultMessage *msg = cls;
   size_t rslt_size;
 
-  if (buf == NULL)
+  if (NULL == buf)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                 _("Could not send list result to client\n"));
@@ -414,6 +412,7 @@ start_process (struct ServiceList *sl,
   SOCKTYPE *lsocks;
   unsigned int ls;
   char *binary;
+  char *quotedbinary;
 
   /* calculate listen socket list */
   lsocks = NULL;
@@ -486,44 +485,59 @@ start_process (struct ServiceList *sl,
              "Starting service `%s' using binary `%s' and configuration `%s'\n",
              sl->name, sl->binary, sl->config);
   binary = GNUNET_OS_get_libexec_binary_path (sl->binary);
+  GNUNET_asprintf (&quotedbinary,
+                  "\"%s\"",
+                  binary);
+
   GNUNET_assert (NULL == sl->proc);
   if (GNUNET_YES == use_debug)
   {
     if (NULL == sl->config)
       sl->proc =
-       do_start_process (sl->pipe_control, GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
-                         lsocks, loprefix, binary, "-L",
-                         "DEBUG", options, NULL);
+       GNUNET_OS_start_process_s (sl->pipe_control,
+                                   GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
+                                   lsocks, loprefix, quotedbinary, "-L",
+                                   "DEBUG", options, NULL);
     else
       sl->proc =
-       do_start_process (sl->pipe_control, GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
-                         lsocks, loprefix, binary, "-c", sl->config, "-L",
-                         "DEBUG", options, NULL);
+          GNUNET_OS_start_process_s (sl->pipe_control,
+                                     GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
+                                     lsocks, loprefix, quotedbinary, "-c",
+                                     sl->config, "-L",
+                                     "DEBUG", options, NULL);
   }
   else
   {
     if (NULL == sl->config)
       sl->proc =
-       do_start_process (sl->pipe_control, GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
-                         lsocks, loprefix, binary,
-                         options, NULL);
+          GNUNET_OS_start_process_s (sl->pipe_control,
+                                     GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
+                                     lsocks, loprefix, quotedbinary,
+                                     options, NULL);
     else
       sl->proc =
-       do_start_process (sl->pipe_control, GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
-                         lsocks, loprefix, binary, "-c", sl->config,
-                         options, NULL);
+          GNUNET_OS_start_process_s (sl->pipe_control,
+                                     GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
+                                     lsocks, loprefix, quotedbinary, "-c",
+                                     sl->config, options, NULL);
   }
   GNUNET_free (binary);
+  GNUNET_free (quotedbinary);
   if (sl->proc == NULL)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to start service `%s'\n"),
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _("Failed to start service `%s'\n"),
                sl->name);
     if (client)
-      signal_result (client, sl->name, request_id, GNUNET_ARM_RESULT_START_FAILED);
+      signal_result (client,
+                     sl->name,
+                     request_id,
+                     GNUNET_ARM_RESULT_START_FAILED);
   }
   else
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Starting service `%s'\n"),
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                _("Starting service `%s'\n"),
                sl->name);
     broadcast_status (sl->name, GNUNET_ARM_SERVICE_STARTING, NULL);
     if (client)
@@ -651,7 +665,12 @@ create_listen_socket (struct sockaddr *sa, socklen_t addr_len,
     return;
   }
 #ifndef WINDOWS
-  if (AF_UNIX == sa->sa_family)
+  if ((AF_UNIX == sa->sa_family)
+#ifdef LINUX
+      /* Permission settings are not required when abstract sockets are used */
+      && ('\0' != ((const struct sockaddr_un *)sa)->sun_path[0])
+#endif      
+      )
   {
     match_uid =
       GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name,
@@ -731,31 +750,34 @@ handle_start (void *cls, struct GNUNET_SERVER_Client *client,
   size -= sizeof (struct GNUNET_ARM_Message);
   servicename = (const char *) &amsg[1];
   if ((size == 0) || (servicename[size - 1] != '\0'))
-    {
-      GNUNET_break (0);
-      GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-      return;
-    }
+  {
+    GNUNET_break (0);
+    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    return;
+  }
   if (GNUNET_YES == in_shutdown)
-    {
-      signal_result (client, servicename, request_id, GNUNET_ARM_RESULT_IN_SHUTDOWN);
-      GNUNET_SERVER_receive_done (client, GNUNET_OK);
-      return;
-    }
+  {
+    signal_result (client, servicename, request_id,
+                  GNUNET_ARM_RESULT_IN_SHUTDOWN);
+    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    return;
+  }
   sl = find_service (servicename);
   if (NULL == sl)
-    {
-      signal_result (client, servicename, request_id, GNUNET_ARM_RESULT_IS_NOT_KNOWN);
-      GNUNET_SERVER_receive_done (client, GNUNET_OK);
-      return;
-    }
+  {
+    signal_result (client, servicename, request_id,
+                  GNUNET_ARM_RESULT_IS_NOT_KNOWN);
+    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    return;
+  }
   sl->is_default = GNUNET_YES;
-  if (sl->proc != NULL)
-    {
-      signal_result (client, servicename, request_id, GNUNET_ARM_RESULT_IS_STARTED_ALREADY);
-      GNUNET_SERVER_receive_done (client, GNUNET_OK);
-      return;
-    }
+  if (NULL != sl->proc)
+  {
+    signal_result (client, servicename, request_id,
+                  GNUNET_ARM_RESULT_IS_STARTED_ALREADY);
+    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    return;
+  }
   start_process (sl, client, request_id);
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
 }
@@ -806,7 +828,8 @@ handle_stop (void *cls, struct GNUNET_SERVER_Client *client,
       return;
     }
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-             _("Preparing to stop `%s'\n"), servicename);
+             _("Preparing to stop `%s'\n"),
+             servicename);
   if (0 == strcasecmp (servicename, "arm"))
   {
     broadcast_status (servicename, GNUNET_ARM_SERVICE_STOPPING, NULL);
@@ -831,22 +854,22 @@ handle_stop (void *cls, struct GNUNET_SERVER_Client *client,
       GNUNET_SERVER_receive_done (client, GNUNET_OK);
       return;
     }
-  if (sl->killing_client != NULL)
-    {
-      /* killing already in progress */
-      signal_result (client, servicename, request_id,
-          GNUNET_ARM_RESULT_IS_STOPPING_ALREADY);
-      GNUNET_SERVER_receive_done (client, GNUNET_OK);
-      return;
-    }
-  if (sl->proc == NULL)
-    {
-      /* process is down */
-      signal_result (client, servicename, request_id,
-          GNUNET_ARM_RESULT_IS_STOPPED_ALREADY);
-      GNUNET_SERVER_receive_done (client, GNUNET_OK);
-      return;
-    }
+  if (NULL != sl->killing_client)
+  {
+    /* killing already in progress */
+    signal_result (client, servicename, request_id,
+                  GNUNET_ARM_RESULT_IS_STOPPING_ALREADY);
+    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    return;
+  }
+  if (NULL == sl->proc)
+  {
+    /* process is down */
+    signal_result (client, servicename, request_id,
+                  GNUNET_ARM_RESULT_IS_STOPPED_ALREADY);
+    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    return;
+  }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Sending kill signal to service `%s', waiting for process to die.\n",
              servicename);
@@ -884,12 +907,13 @@ handle_list (void *cls, struct GNUNET_SERVER_Client *client,
     return;
 
   request = (struct GNUNET_ARM_Message *) message;
+  GNUNET_break (0 == ntohl (request->reserved));
   count = 0;
   string_list_size = 0;
   /* first count the running processes get their name's size */
-  for (sl = running_head; sl != NULL; sl = sl->next)
+  for (sl = running_head; NULL != sl; sl = sl->next)
   {
-    if (sl->proc != NULL)
+    if (NULL != sl->proc)
     {
       string_list_size += strlen (sl->name);
       string_list_size += strlen (sl->binary);
@@ -903,24 +927,24 @@ handle_list (void *cls, struct GNUNET_SERVER_Client *client,
   msg = GNUNET_malloc (total_size);
   msg->arm_msg.header.size = total_size;
   msg->arm_msg.header.type = GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT;
+  msg->arm_msg.reserved = htonl (0);
   msg->arm_msg.request_id = GNUNET_ntohll (request->request_id);
   msg->count = count;
 
   char *pos = (char *)&msg[1];
-  for (sl = running_head; sl != NULL; sl = sl->next)
+  for (sl = running_head; NULL != sl; sl = sl->next)
   {
-    if (sl->proc != NULL)
+    if (NULL != sl->proc)
     {
       size_t s = strlen (sl->name) + strlen (sl->binary) + 4;
-      GNUNET_snprintf(pos, s, "%s (%s)", sl->name, sl->binary);
+      GNUNET_snprintf (pos, s, "%s (%s)", sl->name, sl->binary);
       pos += s;
     }
   }
-
   GNUNET_SERVER_notify_transmit_ready (client,
                                        total_size,
                                        GNUNET_TIME_UNIT_FOREVER_REL,
-                                       write_list_result, msg);
+                                       &write_list_result, msg);
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
 }
 
@@ -951,6 +975,12 @@ do_shutdown ()
 }
 
 
+/**
+ * Count how many services are still active.
+ *
+ * @param running_head list of services
+ * @return number of active services found
+ */
 static unsigned int
 list_count (struct ServiceList *running_head)
 {
@@ -1284,22 +1314,28 @@ setup_service (void *cls, const char *section)
     return;
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_string (cfg, section, "BINARY", &binary))
-    {
-      /* not a service section */
-      return;
-    }
+  {
+    /* not a service section */
+    return;
+  }
   if ((GNUNET_YES ==
        GNUNET_CONFIGURATION_have_value (cfg, section, "USER_SERVICE")) &&
       (GNUNET_YES ==
        GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "USER_SERVICE")))
   {
     if (GNUNET_NO == start_user)
+    {
+      GNUNET_free (binary);
       return; /* user service, and we don't deal with those */
+    }
   }
   else
   {
     if (GNUNET_NO == start_system)
+    {
+      GNUNET_free (binary);
       return; /* system service, and we don't deal with those */
+    }
   }
   sl = find_service (section);
   if (NULL != sl)
@@ -1421,8 +1457,9 @@ run (void *cls, struct GNUNET_SERVER_Handle *serv,
 
   cfg = c;
   server = serv;
-  GNUNET_assert (serv != NULL);
-  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
+  GNUNET_assert (NULL != serv);
+  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
+                                &shutdown_task,
                                NULL);
   child_death_task =
     GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
@@ -1443,50 +1480,49 @@ run (void *cls, struct GNUNET_SERVER_Handle *serv,
   {
     GNUNET_break (GNUNET_YES == start_user);
     start_system = GNUNET_NO;
-    return;
   }
   if (GNUNET_YES ==
       GNUNET_CONFIGURATION_get_value_yesno (cfg, "ARM", "SYSTEM_ONLY"))
   {
     GNUNET_break (GNUNET_YES == start_system);
     start_user = GNUNET_NO;
-    return;
   }
   GNUNET_CONFIGURATION_iterate_sections (cfg, &setup_service, NULL);
 
   /* start default services... */
   if (GNUNET_OK ==
-      GNUNET_CONFIGURATION_get_value_string (cfg, "ARM", "DEFAULTSERVICES",
+      GNUNET_CONFIGURATION_get_value_string (cfg,
+                                             "ARM",
+                                             "DEFAULTSERVICES",
                                             &defaultservices))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                _("Starting default services `%s'\n"),
+                defaultservices);
+    if (0 < strlen (defaultservices))
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                 _("Starting default services `%s'\n"), defaultservices);
-      if (0 < strlen (defaultservices))
-       {
-         for (pos = strtok (defaultservices, " "); NULL != pos;
-              pos = strtok (NULL, " "))
-           {
-             sl = find_service (pos);
-             if (NULL == sl)
-               {
-                 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                             _
-                             ("Default service `%s' not configured correctly!\n"),
-                             pos);
-                 continue;
-               }
-             sl->is_default = GNUNET_YES;
-             start_process (sl, NULL, 0);
-           }
-       }
-      GNUNET_free (defaultservices);
+      for (pos = strtok (defaultservices, " "); NULL != pos;
+           pos = strtok (NULL, " "))
+      {
+        sl = find_service (pos);
+        if (NULL == sl)
+        {
+          GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                      _("Default service `%s' not configured correctly!\n"),
+                      pos);
+          continue;
+        }
+        sl->is_default = GNUNET_YES;
+        start_process (sl, NULL, 0);
+      }
     }
+    GNUNET_free (defaultservices);
+  }
   else
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                 _
-                 ("No default services configured, GNUnet will not really start right now.\n"));
-    }
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                _("No default services configured, GNUnet will not really start right now.\n"));
+  }
 
   notifier =
       GNUNET_SERVER_notification_context_create (server, MAX_NOTIFY_QUEUE);