stuff
[oweals/gnunet.git] / src / util / service.c
index aa07eecde9908025b454417fbe4894b984fb4e3c..2214efe108d2edb44a7232db9ff336a61c7ebcbd 100644 (file)
@@ -570,6 +570,50 @@ handle_test (void *cls,
 }
 
 
+static size_t
+transmit_shutdown_deny (void *cls, size_t size, void *buf)
+{
+  struct GNUNET_SERVER_Client *client = cls;
+  struct GNUNET_MessageHeader *msg;
+
+  if (size < sizeof (struct GNUNET_MessageHeader))
+    {
+      GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+      return 0;                 /* client disconnected */
+    }
+  msg = (struct GNUNET_MessageHeader *) buf;
+  msg->type = htons (GNUNET_MESSAGE_TYPE_SHUTDOWN_REFUSE);
+  msg->size = htons (sizeof (struct GNUNET_MessageHeader));
+  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  GNUNET_SERVER_client_drop(client);
+  return sizeof (struct GNUNET_MessageHeader);
+}
+
+static size_t
+transmit_shutdown_ack (void *cls, size_t size, void *buf)
+{
+  struct GNUNET_SERVER_Client *client = cls;
+  struct GNUNET_MessageHeader *msg;
+
+  if (size < sizeof (struct GNUNET_MessageHeader))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                  _("Failed to transmit shutdown ACK.\n"));
+      GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+      return 0;                 /* client disconnected */
+    }
+
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              _("Transmitting shutdown ACK.\n"));
+
+  msg = (struct GNUNET_MessageHeader *) buf;
+  msg->type = htons (GNUNET_MESSAGE_TYPE_SHUTDOWN_ACK);
+  msg->size = htons (sizeof (struct GNUNET_MessageHeader));
+  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  GNUNET_SERVER_client_drop(client);
+  return sizeof (struct GNUNET_MessageHeader);
+}
+
 /**
  * Handler for SHUTDOWN message.
  *
@@ -583,19 +627,30 @@ handle_shutdown (void *cls,
                  const struct GNUNET_MessageHeader *message)
 {
   struct GNUNET_SERVICE_Context *service = cls;
+
+  GNUNET_SERVER_client_keep(client);
   if (!service->allow_shutdown)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                   _
                   ("Received shutdown request, but configured to ignore!\n"));
-      GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+      GNUNET_SERVER_notify_transmit_ready (client,
+                                           sizeof(struct GNUNET_MessageHeader),
+                                           GNUNET_TIME_UNIT_FOREVER_REL,
+                                           &transmit_shutdown_deny, client);
       return;
     }
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               _("Initiating shutdown as requested by client.\n"));
+
+  GNUNET_SERVER_notify_transmit_ready (client,
+                                       sizeof(struct GNUNET_MessageHeader),
+                                       GNUNET_TIME_UNIT_FOREVER_REL,
+                                       &transmit_shutdown_ack, client);
+
   GNUNET_assert (service->sched != NULL);
+  GNUNET_SERVER_client_persist_ (client);
   GNUNET_SCHEDULER_shutdown (service->sched);
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
 }
 
 
@@ -781,7 +836,6 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
 
   *addrs = NULL;
   *addr_lens = NULL;
-  resi = 0;
   if (GNUNET_CONFIGURATION_have_value (cfg,
                                        serviceName, "DISABLEV6"))
     {
@@ -959,7 +1013,6 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
 #endif
           ((struct sockaddr_in *) saddrs[1])->sin_family = AF_INET;
           ((struct sockaddr_in *) saddrs[1])->sin_port = htons (port);
-
         }
     }
   *addrs = saddrs;
@@ -1000,8 +1053,13 @@ setup_service (struct GNUNET_SERVICE_Context *sctx)
           GNUNET_CONFIGURATION_get_value_time (sctx->cfg,
                                                sctx->serviceName,
                                                "TIMEOUT", &idleout))
-        return GNUNET_SYSERR;
-
+       {
+         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                     _("Specified value for `%s' of service `%s' is invalid\n"),
+                     "TIMEOUT",
+                     sctx->serviceName);
+         return GNUNET_SYSERR;
+       }
       sctx->timeout = idleout;
     }
   else
@@ -1013,7 +1071,13 @@ setup_service (struct GNUNET_SERVICE_Context *sctx)
           GNUNET_CONFIGURATION_get_value_number (sctx->cfg,
                                                  sctx->serviceName,
                                                  "MAXBUF", &maxbuf))
-        return GNUNET_SYSERR;
+       {
+         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                     _("Specified value for `%s' of service `%s' is invalid\n"),
+                     "MAXBUF",
+                     sctx->serviceName);
+         return GNUNET_SYSERR;
+       }
     }
   else
     maxbuf = GNUNET_SERVER_MAX_MESSAGE_SIZE;
@@ -1024,7 +1088,13 @@ setup_service (struct GNUNET_SERVICE_Context *sctx)
           (sctx->allow_shutdown =
            GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->serviceName,
                                                  "ALLOW_SHUTDOWN")))
-        return GNUNET_SYSERR;
+       {
+         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                     _("Specified value for `%s' of service `%s' is invalid\n"),
+                     "ALLOW_SHUTDOWN",
+                     sctx->serviceName);
+         return GNUNET_SYSERR;
+       }
     }
   else
     sctx->allow_shutdown = GNUNET_NO;
@@ -1037,7 +1107,13 @@ setup_service (struct GNUNET_SERVICE_Context *sctx)
           (tolerant = GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg,
                                                             sctx->serviceName,
                                                             "TOLERANT")))
-        return GNUNET_SYSERR;
+       {
+         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                     _("Specified value for `%s' of service `%s' is invalid\n"),
+                     "TOLERANT",
+                     sctx->serviceName);
+         return GNUNET_SYSERR;
+       }
     }
   else
     tolerant = GNUNET_NO;
@@ -1418,17 +1494,17 @@ GNUNET_SERVICE_run (int argc,
   /* setup subsystems */
   if (GNUNET_SYSERR == GNUNET_GETOPT_run (serviceName, service_options, argc,
       argv))    
-    HANDLE_ERROR;
+    goto shutdown;
   if (GNUNET_OK != GNUNET_log_setup (serviceName, loglev, logfile))
     HANDLE_ERROR;
   if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg, cfg_fn))
-    HANDLE_ERROR;
+    goto shutdown;
   if (GNUNET_OK != setup_service (&sctx))
-    HANDLE_ERROR;
+    goto shutdown;
   if ( (do_daemonize == 1) && (GNUNET_OK != detach_terminal (&sctx)))    
     HANDLE_ERROR;
   if (GNUNET_OK != set_user_id (&sctx))
-    HANDLE_ERROR;
+    goto shutdown;
 #if DEBUG_SERVICE
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Service `%s' runs with configuration from `%s'\n",