gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r20135 - in gnunet/src: arm include


From: gnunet
Subject: [GNUnet-SVN] r20135 - in gnunet/src: arm include
Date: Wed, 29 Feb 2012 09:59:39 +0100

Author: szengel
Date: 2012-02-29 09:59:39 +0100 (Wed, 29 Feb 2012)
New Revision: 20135

Modified:
   gnunet/src/arm/arm.h
   gnunet/src/arm/arm_api.c
   gnunet/src/arm/gnunet-arm.c
   gnunet/src/arm/gnunet-service-arm.c
   gnunet/src/include/gnunet_arm_service.h
   gnunet/src/include/gnunet_protocols.h
Log:
Adding arm list/info feature.


Modified: gnunet/src/arm/arm.h
===================================================================
--- gnunet/src/arm/arm.h        2012-02-29 08:59:09 UTC (rev 20134)
+++ gnunet/src/arm/arm.h        2012-02-29 08:59:39 UTC (rev 20135)
@@ -51,6 +51,27 @@
    */
   uint32_t status;
 };
+
+/**
+ * Reply from ARM to client for the 
+ * GNUNET_MESSAGE_TYPE_ARM_LIST request followed by count 
+ * '\0' terminated strings. header->size contains the
+ * total size (including all strings).
+ */
+struct GNUNET_ARM_ListResultMessage
+{
+  /**
+   * Reply to client is of type GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * Number of '\0' terminated strings that follow
+   * this message.
+   */
+  uint16_t count;
+};
+
 GNUNET_NETWORK_STRUCT_END
 
 #endif

Modified: gnunet/src/arm/arm_api.c
===================================================================
--- gnunet/src/arm/arm_api.c    2012-02-29 08:59:09 UTC (rev 20134)
+++ gnunet/src/arm/arm_api.c    2012-02-29 08:59:39 UTC (rev 20135)
@@ -52,7 +52,6 @@
 
 };
 
-
 /**
  * Context for handling the shutdown of a service.
  */
@@ -487,8 +486,96 @@
   GNUNET_free (sc);
 }
 
+/**
+ * Internal state for a list request with ARM.
+ */
+struct ListRequestContext
+{
 
+  /**
+   * Pointer to our handle with ARM.
+   */
+  struct GNUNET_ARM_Handle *h;
+
+  /**
+   * Function to call with a status code for the requested operation.
+   */
+  GNUNET_ARM_List_Callback callback;
+
+  /**
+   * Closure for "callback".
+   */
+  void *cls;
+
+  /**
+   * Timeout for the operation.
+   */
+  struct GNUNET_TIME_Absolute timeout;
+};
+
 /**
+ * Process a response from ARM for the list request.
+ *
+ * @param cls the list request context
+ * @param msg the response
+ */
+static void
+handle_list_response (void *cls, const struct GNUNET_MessageHeader *msg)
+{
+  struct ListRequestContext *sc = cls;
+  const struct GNUNET_ARM_ListResultMessage *res;
+  int success;
+  
+   if (msg == NULL)
+   {
+      LOG (GNUNET_ERROR_TYPE_WARNING,
+           "Error receiving response to LIST request from ARM\n");
+      GNUNET_CLIENT_disconnect (sc->h->client, GNUNET_NO);
+      sc->h->client = GNUNET_CLIENT_connect ("arm", sc->h->cfg);
+      GNUNET_assert (NULL != sc->h->client);
+      if (sc->callback != NULL)
+        sc->callback (sc->cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR, 0, 
NULL);
+      GNUNET_free (sc);
+      return;
+   }
+   
+   if (sc->callback != NULL) 
+   {
+     char **list;
+     const char *pos;
+     uint16_t size_check;
+     
+     size_check = 0;
+     res = (const struct GNUNET_ARM_ListResultMessage *) msg;
+     success = (ntohs (res->header.type) 
+                == GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT ? 
+                GNUNET_YES : GNUNET_NO);
+     list = GNUNET_malloc (ntohs (res->count) * sizeof (char *));
+     pos = (const char *)&res[1];
+     
+     int i;
+     for (i=0; i<ntohs (res->count); i++)
+     {
+       list[i] = GNUNET_malloc (strlen (pos) + 1);
+       memcpy (list[i], pos, strlen (pos) + 1);
+       pos += strlen (pos) + 1;
+       size_check += strlen (pos) +1;
+       
+       if (size_check > ntohs (res->header.size))
+       {
+          GNUNET_free (list);
+          GNUNET_free (sc);
+          sc->callback (sc->cls, GNUNET_NO, 0, NULL);
+          return;
+       }
+     }
+     
+     sc->callback (sc->cls, success, ntohs (res->count), (const char**)list);
+   }
+   GNUNET_free (sc);
+}
+
+/**
  * Start or stop a service.
  *
  * @param h handle to ARM
@@ -677,5 +764,69 @@
                  GNUNET_MESSAGE_TYPE_ARM_STOP);
 }
 
+/**
+ * List all running services.
+ * 
+ * @param h handle to ARM
+ * @param timeout how long to wait before failing for good
+ * @param cb callback to invoke when service is ready
+ * @param cb_cls closure for callback
+ */
+void
+GNUNET_ARM_list_running_services (struct GNUNET_ARM_Handle *h,
+                                  struct GNUNET_TIME_Relative timeout,
+                                  GNUNET_ARM_List_Callback cb, void *cb_cls)
+{
+  struct ListRequestContext *sctx;
+  struct GNUNET_MessageHeader *msg;
+  struct GNUNET_CLIENT_Connection *client;
+  
+    if (h->client == NULL)
+    {
+      client = GNUNET_CLIENT_connect ("arm", h->cfg);
+      if (client == NULL)
+        {
+          LOG (GNUNET_ERROR_TYPE_DEBUG,
+               "arm_api, GNUNET_CLIENT_connect returned NULL\n");
+          cb (cb_cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR, 0, NULL);
+          return;
+        }
+      LOG (GNUNET_ERROR_TYPE_DEBUG,
+           "arm_api, GNUNET_CLIENT_connect returned non-NULL\n");
+      h->client = client;
+    }
 
+  sctx = GNUNET_malloc (sizeof (struct RequestContext));
+  sctx->h = h;
+  sctx->callback = cb;
+  sctx->cls = cb_cls;
+  sctx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
+  msg = GNUNET_malloc (sizeof (struct GNUNET_MessageHeader));
+  msg->size = htons (sizeof (struct GNUNET_MessageHeader));
+  msg->type = htons (GNUNET_MESSAGE_TYPE_ARM_LIST);
+  
+  LOG(GNUNET_ERROR_TYPE_DEBUG, 
+      "Requesting LIST from ARM service with timeout: %llu ms\n", 
+      (unsigned long long)timeout.rel_value);
+  
+    if (GNUNET_OK !=
+      GNUNET_CLIENT_transmit_and_get_response (sctx->h->client, 
+                                               msg,
+                                               
GNUNET_TIME_absolute_get_remaining
+                                               (sctx->timeout), 
+                                               GNUNET_YES,
+                                               &handle_list_response, 
+                                               sctx))
+    {
+      LOG (GNUNET_ERROR_TYPE_WARNING, 
+           "Error while trying to transmit request to list services to ARM\n");
+      if (cb != NULL)
+        cb (cb_cls, GNUNET_SYSERR, 0, NULL);
+      GNUNET_free (sctx);
+      GNUNET_free (msg);
+      return;
+    }
+  GNUNET_free (msg);
+}
+
 /* end of arm_api.c */

Modified: gnunet/src/arm/gnunet-arm.c
===================================================================
--- gnunet/src/arm/gnunet-arm.c 2012-02-29 08:59:09 UTC (rev 20134)
+++ gnunet/src/arm/gnunet-arm.c 2012-02-29 08:59:39 UTC (rev 20135)
@@ -49,6 +49,11 @@
 #define START_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 
1)
 
 /**
+ * Timeout for listing all running services.
+ */
+#define LIST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 
2)
+
+/**
  * Set if we are to shutdown all services (including ARM).
  */
 static int end;
@@ -74,6 +79,11 @@
 static int quiet;
 
 /**
+ * Set if we should print a list of currently running services.
+ */
+static int list;
+
+/**
  * Set to the name of a service to start.
  */
 static char *init;
@@ -193,6 +203,31 @@
                                     GNUNET_SCHEDULER_REASON_PREREQ_DONE);
 }
 
+/**
+ * Callback invoked with the list of running services.  
+ * Reports to the user and then runs the next phase in the FSM.
+ *
+ * @param cls currently not used
+ * @param result result of the operation
+ * @param count number of running services
+ * @param list copy of the list of running services
+ */
+static void
+list_cb (void *cls, int result, uint16_t count, const char **list)
+{
+  if (result == GNUNET_YES && list != NULL)
+  {
+    FPRINTF (stdout, _("Running services:\n-----------------\n"));
+    int i;
+    for (i=0; i<count; i++)
+    {
+      FPRINTF (stdout, "%s\n", list[i]);
+    }
+    GNUNET_free (list);
+  } else {
+    FPRINTF (stderr, "%s", _("Error communicating with ARM. ARM not 
running?\n"));
+  }
+}
 
 /**
  * Main function that will be run by the scheduler.
@@ -328,6 +363,24 @@
              GNUNET_SCHEDULER_add_now (&cps_loop, NULL);
              return;
            }
+        case 5:
+          if (list) {
+              GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Going to list all running services controlled by ARM.\n");
+  
+              if (h == NULL) 
+              {
+               GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                              _("Fatal error initializing ARM API.\n"));
+               return;
+              }
+              
+              GNUNET_ARM_list_running_services (h, 
+                                                (0 == 
+                                                 timeout.rel_value) ? 
LIST_TIMEOUT : 
+                                                 timeout, &list_cb, NULL);
+            return;
+          }
          /* Fall through */
        default:                /* last phase */
          GNUNET_ARM_disconnect (h);
@@ -371,6 +424,8 @@
     {'T', "timeout", NULL,
      gettext_noop ("timeout for completing current operation"),
      GNUNET_YES, &GNUNET_GETOPT_set_ulong, &temp_timeout_ms},
+    {'I', "info", NULL, gettext_noop ("List currently running services"),
+     GNUNET_NO, &GNUNET_GETOPT_set_one, &list},
     GNUNET_GETOPT_OPTION_END
   };
 

Modified: gnunet/src/arm/gnunet-service-arm.c
===================================================================
--- gnunet/src/arm/gnunet-service-arm.c 2012-02-29 08:59:09 UTC (rev 20134)
+++ gnunet/src/arm/gnunet-service-arm.c 2012-02-29 08:59:39 UTC (rev 20135)
@@ -370,7 +370,44 @@
   return sizeof (struct GNUNET_ARM_ResultMessage);
 }
 
+/**
+ * Transmit the list of running services.
+ * 
+ * @param cls pointer to struct GNUNET_ARM_ListResultMessage with the message
+ * @param size number of bytes available in buf
+ * @param buf where to copy the message, NULL on error
+ * @return number of bytes copied to buf
+ */
+static size_t
+write_list_result (void *cls, size_t size, void *buf)
+{
+  struct GNUNET_ARM_ListResultMessage *msg = cls;
+  struct GNUNET_ARM_ListResultMessage *rslt;
+  size_t rslt_size;
+  
+  if (buf == NULL)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                _("Could not send list result to client\n"));
+    return 0;                   /* error, not much we can do */
+  }
+  
+  GNUNET_assert (size >= msg->header.size);
+  rslt = buf;
+  rslt->header.size = htons (msg->header.size);
+  rslt->header.type = htons (msg->header.type);
+  rslt->count = htons (msg->count);
+  
+  size_t list_size = msg->header.size 
+                     - sizeof (struct GNUNET_ARM_ListResultMessage);  
+  memcpy (&rslt[1], &msg[1], list_size);
 
+  rslt_size = msg->header.size;
+  GNUNET_free (msg);
+  return rslt_size;
+}
+
+
 /**
  * Signal our client that we will start or stop the
  * service.
@@ -566,7 +603,7 @@
   const char *servicename;
   struct ServiceList *sl;
   uint16_t size;
-
+  
   size = ntohs (message->size);
   size -= sizeof (struct GNUNET_MessageHeader);
   servicename = (const char *) &message[1];
@@ -663,6 +700,64 @@
   GNUNET_SERVER_client_keep (client);
 }
 
+/**
+ * Handle LIST-message.
+ *
+ * @param cls closure (always NULL)
+ * @param client identification of the client
+ * @param message the actual message
+ */
+static void
+handle_list (void *cls, struct GNUNET_SERVER_Client *client,
+             const struct GNUNET_MessageHeader *message)
+{
+  struct GNUNET_ARM_ListResultMessage *msg;
+  size_t string_list_size;
+  size_t total_size;
+  struct ServiceList *sl;
+  uint16_t count;
+  
+  if (NULL == client)
+    return;
+  
+  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)
+  {
+    if (sl->proc != NULL)
+    {
+      string_list_size += strlen (sl->name);
+      string_list_size += 3;
+      string_list_size += strlen (sl->binary) + 1;
+      count++;
+    }
+  }
+  total_size = sizeof (struct GNUNET_ARM_ListResultMessage) 
+               + string_list_size;
+  msg = GNUNET_malloc (total_size);
+  msg->header.size = total_size;
+  msg->header.type = GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT;
+  msg->count = count;
+  
+  char *pos = (char *)&msg[1];
+  for (sl = running_head; sl != NULL; sl = sl->next) 
+  {
+    if (sl->proc != NULL)
+    {
+      //memcpy (pos, sl->name, strlen (sl->name) + 1);
+      size_t s = strlen (sl->name) + strlen (sl->binary) + 4;
+      snprintf(pos, s, "%s (%s)", sl->name, sl->binary);
+      pos += s;
+    }
+  }
+  
+  GNUNET_SERVER_notify_transmit_ready (client,
+                                       msg->header.size,
+                                       GNUNET_TIME_UNIT_FOREVER_REL,
+                                       &write_list_result, msg);
+  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+}
 
 /**
  * We are done with everything.  Stop remaining
@@ -1002,7 +1097,6 @@
   GNUNET_SERVER_client_persist_ (client);
 }
 
-
 /**
  * Signal handler called for SIGCHLD.  Triggers the
  * respective handler by writing to the trigger pipe.
@@ -1114,6 +1208,8 @@
     {&handle_stop, NULL, GNUNET_MESSAGE_TYPE_ARM_STOP, 0},
     {&handle_shutdown, NULL, GNUNET_MESSAGE_TYPE_ARM_SHUTDOWN,
      sizeof (struct GNUNET_MessageHeader)},
+    {&handle_list, NULL, GNUNET_MESSAGE_TYPE_ARM_LIST, 
+     sizeof (struct GNUNET_MessageHeader)},
     {NULL, NULL, 0, 0}
   };
   char *defaultservices;

Modified: gnunet/src/include/gnunet_arm_service.h
===================================================================
--- gnunet/src/include/gnunet_arm_service.h     2012-02-29 08:59:09 UTC (rev 
20134)
+++ gnunet/src/include/gnunet_arm_service.h     2012-02-29 08:59:39 UTC (rev 
20135)
@@ -111,7 +111,20 @@
 typedef void (*GNUNET_ARM_Callback) (void *cls, 
                                     enum GNUNET_ARM_ProcessStatus result);
 
+/**
+ * Callback function invoked when list operation is complete.
+ *
+ * @param cls closure
+ * @param result outcome of the operation (GNUNET_YES if successful)
+ * @param count number of strings in the list
+ * @param list list of running services
+ */
+typedef void (*GNUNET_ARM_List_Callback) (void *cls, 
+                                          int result,
+                                          uint16_t count,
+                                          const char **list);
 
+
 /**
  * Handle for interacting with ARM.
  */
@@ -183,6 +196,18 @@
                          GNUNET_ARM_Callback cb, void *cb_cls);
 
 
+/**
+ * List all running services.
+ * 
+ * @param h handle to ARM
+ * @param timeout how long to wait before failing for good
+ * @param cb callback to invoke when service is ready
+ * @param cb_cls closure for callback
+ */
+void
+GNUNET_ARM_list_running_services (struct GNUNET_ARM_Handle *h,
+                                  struct GNUNET_TIME_Relative timeout,
+                                  GNUNET_ARM_List_Callback cb, void *cb_cls);
 
 #if 0                           /* keep Emacsens' auto-indent happy */
 {

Modified: gnunet/src/include/gnunet_protocols.h
===================================================================
--- gnunet/src/include/gnunet_protocols.h       2012-02-29 08:59:09 UTC (rev 
20134)
+++ gnunet/src/include/gnunet_protocols.h       2012-02-29 08:59:39 UTC (rev 
20135)
@@ -87,7 +87,16 @@
  */
 #define GNUNET_MESSAGE_TYPE_ARM_RESULT 11
 
+/**
+ * Request to ARM to list all currently running services
+ */
+#define GNUNET_MESSAGE_TYPE_ARM_LIST 12
 
+/**
+ * Response from ARM for listing currently running services
+ */
+#define GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT 13
+
 
/*******************************************************************************
  * HELLO message types
  
******************************************************************************/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]