gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r28480 - msh/src


From: gnunet
Subject: [GNUnet-SVN] r28480 - msh/src
Date: Thu, 8 Aug 2013 23:00:16 +0200

Author: harsha
Date: 2013-08-08 23:00:16 +0200 (Thu, 08 Aug 2013)
New Revision: 28480

Modified:
   msh/src/msh.c
   msh/src/mshd-server.c
   msh/src/mshd.c
   msh/src/mtypes.h
Log:
- better structure


Modified: msh/src/msh.c
===================================================================
--- msh/src/msh.c       2013-08-08 17:30:02 UTC (rev 28479)
+++ msh/src/msh.c       2013-08-08 21:00:16 UTC (rev 28480)
@@ -48,31 +48,53 @@
   struct GNUNET_MessageHeader *msg;
 };
 
-/**
- * DLL head for the message queue
- */
-static struct MessageQueue *mq_head;
 
 /**
- * DLL tail for the message queue
+ * Context information for a connection
  */
-static struct MessageQueue *mq_tail;
+struct ConnCtx
+{
+  /**
+   * The transmit handle
+   */
+  struct GNUNET_CLIENT_TransmitHandle *tx;
 
-/**
- * Our connection to the parent MSHD
- */
-static struct GNUNET_CLIENT_Connection *client;
+  /**
+   * The client connection handle
+   */
+  struct GNUNET_CLIENT_Connection *conn;
 
+  /**
+   * configuration used to obtain this connection
+   */
+  struct GNUNET_CONFIGURATION_Handle *cfg;
 
+  /**
+   * DLL head for the message queue
+   */
+   struct MessageQueue *mq_head;
+
+  /**
+   * DLL tail for the message queue
+   */
+   struct MessageQueue *mq_tail;
+
+  /**
+   * retry backoff time for this connection
+   */
+  struct GNUNET_TIME_Relative backoff;
+};
+
+
 /**
- * Our connection to the parent MSHD
+ * context for the connection to parent MSHD
  */
-static struct GNUNET_CLIENT_Connection *client_remote;
+static struct ConnCtx ctx_local;
 
 /**
- * Handle for transmissions on conn
+ * context for the connection to remote MSHD
  */
-static struct GNUNET_CLIENT_TransmitHandle *th;
+static struct ConnCtx ctx_remote;
 
 /**
  * file handle for the stdin
@@ -107,16 +129,6 @@
 struct GNUNET_CLIENT_TestHandle *test;
 
 /**
- * configuration for connecting to local MSHD through client API
- */
-struct GNUNET_CONFIGURATION_Handle *cfg;
-
-/**
- * configuration for connecting to remote MSHD through client API
- */
-struct GNUNET_CONFIGURATION_Handle *remote_cfg;
-
-/**
  * length of the cmdstr
  */
 static size_t cmdstr_len;
@@ -132,11 +144,6 @@
 static GNUNET_SCHEDULER_TaskIdentifier task_fwd_stdout;
 
 /**
- * retry backoff time
- */
-static struct GNUNET_TIME_Relative retry_backoff;
-
-/**
  * flag to indicate successful completion by setting it to GNUNET_OK
  */
 static int result;
@@ -152,14 +159,25 @@
 enum State
 {
   /**
-   * Initial state where the remote command is delivered to the MSHD
+   * Address lookup of the remote instance
    */
+  STATE_LOOKUP,
+  
+  /**
+   * Remote command is delivered to remote MSHD
+   */
   STATE_DELIVER_CMD,
 
   /**
-   * State where the stdin and stdout streams are forwarded to and from the 
MSHD
+   * Get authorization credential from parent MSHD
    */
-  STATE_FORWARD_STREAMS
+  STATE_GET_CRED,
+
+  /**
+   * stdin and stdout streams are forwarded to and from the MSHD
+   */
+  STATE_FORWARD_STREAMS,
+
 } state;
 
 /**
@@ -194,22 +212,27 @@
 
 
 /**
- * Function to cleanup the message queue
+ * Destroys a connection context
  *
- * @param 
- * @return 
+ * @param ctx connection context
  */
 static void
-cleanup_mq ()
+destroy_conn_ctx (struct ConnCtx *ctx)
 {
   struct MessageQueue *mq;
 
-  while (NULL != (mq = mq_head))
+  if (NULL != ctx->tx)
+    GNUNET_CLIENT_notify_transmit_ready_cancel (ctx->tx);
+  if (NULL != ctx->conn)
+    GNUNET_CLIENT_disconnect (ctx->conn);
+  if (NULL != ctx->cfg)
+    GNUNET_CONFIGURATION_destroy (ctx->cfg);
+  while (NULL != (mq = ctx->mq_head))
   {
-    GNUNET_CONTAINER_DLL_remove (mq_head, mq_tail, mq);
+    GNUNET_CONTAINER_DLL_remove (ctx->mq_head, ctx->mq_tail, mq);
     GNUNET_free (mq->msg);
     GNUNET_free (mq);
-  }
+  } 
 }
 
 
@@ -227,48 +250,50 @@
 static size_t
 conn_transmit_ready (void *cls, size_t size, void *buf)
 {
+  struct ConnCtx *ctx = cls;
   struct MessageQueue *mq;
   uint16_t msg_size;
   size_t wrote;
 
   wrote = 0;
-  th = NULL;
+  GNUNET_assert (NULL != ctx->tx);
+  ctx->tx = NULL;
   if ((0 == size) && (NULL == buf))
   {
     LOG_ERROR ("Connection to MSHD broken\n");
-    cleanup_mq ();
+    destroy_conn_ctx (ctx);
     return 0;
   }
-  mq = mq_head;
+  mq = ctx->mq_head;
   GNUNET_assert (NULL != mq);
   if ((0 == size) || (NULL == buf))
   {
     LOG_DEBUG ("Message sending timed out -- retrying\n");
-    retry_backoff = GNUNET_TIME_STD_BACKOFF (retry_backoff);
-    th =
-        GNUNET_CLIENT_notify_transmit_ready (client, ntohs (mq->msg->size),
-                                             retry_backoff, GNUNET_NO,
+    ctx->backoff = GNUNET_TIME_STD_BACKOFF (ctx->backoff);
+    ctx->tx =
+        GNUNET_CLIENT_notify_transmit_ready (ctx->conn, ntohs (mq->msg->size),
+                                             ctx->backoff, GNUNET_NO,
                                              &conn_transmit_ready,
-                                             NULL);
+                                             ctx);
         
     return 0;
   }
-  retry_backoff = GNUNET_TIME_UNIT_ZERO;
+  ctx->backoff = GNUNET_TIME_UNIT_ZERO;
   msg_size = ntohs (mq->msg->size);
   GNUNET_assert ( msg_size <= size);
   (void) memcpy (buf, mq->msg, msg_size);
   wrote = msg_size;
   GNUNET_free (mq->msg);
-  GNUNET_CONTAINER_DLL_remove (mq_head, mq_tail, mq);
-  GNUNET_free (mq);  
-  if (NULL != (mq = mq_head))
+  GNUNET_CONTAINER_DLL_remove (ctx->mq_head, ctx->mq_tail, mq);
+  GNUNET_free (mq);
+  if (NULL != (mq = ctx->mq_head))
   {
-    retry_backoff = GNUNET_TIME_STD_BACKOFF (retry_backoff);
-    th =
-        GNUNET_CLIENT_notify_transmit_ready (client, ntohs (mq->msg->size),
-                                             retry_backoff, GNUNET_NO,
+    ctx->backoff = GNUNET_TIME_STD_BACKOFF (ctx->backoff);
+    ctx->tx =
+        GNUNET_CLIENT_notify_transmit_ready (ctx->conn, ntohs (mq->msg->size),
+                                             ctx->backoff, GNUNET_NO,
                                              &conn_transmit_ready,
-                                             NULL);
+                                             ctx);
   }  
   return wrote;
 }
@@ -280,7 +305,7 @@
  * @param msg the message to queue
  */
 static void
-queue_message (struct GNUNET_MessageHeader *msg)
+queue_message (struct ConnCtx *ctx, struct GNUNET_MessageHeader *msg)
 {
   struct MessageQueue *mq;
   uint16_t type;
@@ -293,20 +318,30 @@
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Queueing message of type %u, size %u for sending\n", type,
        ntohs (msg->size));
-  GNUNET_CONTAINER_DLL_insert_tail (mq_head, mq_tail, mq);
-  if (NULL == th)
+  GNUNET_CONTAINER_DLL_insert_tail (ctx->mq_head, ctx->mq_tail, mq);
+  if (NULL == ctx->tx)
   {
-    retry_backoff = GNUNET_TIME_STD_BACKOFF (retry_backoff);
-    th =
-        GNUNET_CLIENT_notify_transmit_ready (client, size,
-                                             retry_backoff, GNUNET_NO,
+    ctx->backoff = GNUNET_TIME_STD_BACKOFF (ctx->backoff);
+    ctx->tx =
+        GNUNET_CLIENT_notify_transmit_ready (ctx->conn, size,
+                                             ctx->backoff, GNUNET_NO,
                                              &conn_transmit_ready,
-                                             NULL);
+                                             ctx);
   }
 }
 
 
 /**
+ * Dispatcher for received messages
+ *
+ * @param cls connection context
+ * @param msg message received, NULL on timeout or fatal error
+ */
+static void
+dispatch (void *cls, const struct GNUNET_MessageHeader *msg);
+
+
+/**
  * forward stdin data to MSHD
  *
  * @param cls NULL
@@ -314,7 +349,7 @@
  */
 static void
 fwd_stdin (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
+{  
   struct MSH_MSG_CmdIO *msg;
   ssize_t size;
   uint16_t msg_size;
@@ -344,7 +379,7 @@
   msg->header.size = htons (msg_size);
   msg->header.type = htons (MSH_MTYPE_CMD_STREAM_STDIN);
   (void) memcpy (msg->data, recv_buf, size);
-  queue_message (&msg->header);
+  queue_message (&ctx_remote, &msg->header);
 
  reschedule:
   task_fwd_stdin = 
@@ -358,11 +393,13 @@
  * Type of a function to call when we receive a message
  * from the service.
  *
- * @param cls closure
+ * @param ctx the connection context
  * @param msg message received, NULL on timeout or fatal error
+ * @return GNUNET_OK to keep the connection open; any other value to close it
  */
-static void
-forward_output (void *cls, const struct GNUNET_MessageHeader *msg_)
+static int
+handle_cmd_output (struct ConnCtx *ctx,
+                   const struct GNUNET_MessageHeader *msg_)
 {
   const struct MSH_MSG_CmdIO *msg;
   uint16_t size;
@@ -372,14 +409,13 @@
   {
     GNUNET_break (0);
     GNUNET_SCHEDULER_shutdown ();
-    return;
+    return GNUNET_SYSERR;;
   }
   size = ntohs (msg->header.size);  
   GNUNET_break (size == 
                 GNUNET_DISK_file_write (fh_stdout, msg->data,
                                         size - sizeof (struct MSH_MSG_CmdIO)));
-  GNUNET_CLIENT_receive (client_remote, &forward_output, NULL,
-                         GNUNET_TIME_UNIT_FOREVER_REL);
+  return GNUNET_OK;
 }
 
 
@@ -387,11 +423,13 @@
  * Type of a function to call when we receive a message
  * from the service.
  *
- * @param cls closure
+ * @param ctx the connection context
  * @param msg message received, NULL on timeout or fatal error
+ * @return GNUNET_OK to keep the connection open; any other value to close it
  */
-static void
-challenge_status (void *cls, const struct GNUNET_MessageHeader *msg_)
+static int
+handle_exec_begin (struct ConnCtx *ctx,
+                   const struct GNUNET_MessageHeader *msg_)
 {
   LOG (GNUNET_ERROR_TYPE_INFO, "Executing remote command\n");
   fh_stdin = GNUNET_DISK_get_handle_from_native (stdin);
@@ -399,11 +437,9 @@
   GNUNET_assert (NULL != fh_stdin);
   GNUNET_assert (NULL != fh_stdout);
   state = STATE_FORWARD_STREAMS;
-  GNUNET_CLIENT_receive (client_remote, &forward_output, NULL,
-                         GNUNET_TIME_UNIT_FOREVER_REL);
-  task_fwd_stdin = 
       GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
-                                      fh_stdin, &fwd_stdin, NULL);  
+                                      fh_stdin, &fwd_stdin, NULL);
+  return GNUNET_OK;
 }
 
 
@@ -411,21 +447,20 @@
  * Type of a function to call when we receive a message
  * from the service.
  *
- * @param cls closure
+ * @param ctx the connection context
  * @param msg message received, NULL on timeout or fatal error
+ * @return GNUNET_OK to keep the connection open; any other value to close it
  */
-static void
-auth_challenge_response (void *cls, const struct GNUNET_MessageHeader *msg_)
+static int
+handle_challenge_response (struct ConnCtx *ctx,
+                           const struct GNUNET_MessageHeader *msg_)
 {
-  const struct MSH_MSG_ChallengeResponse *msg;
+  struct GNUNET_MessageHeader *msg;
 
-  //msg = (const struct MSH_MSG_ChallengeResponse *) msg_;
-  GNUNET_CLIENT_transmit_and_get_response (client_remote,
-                                           msg_,
-                                           GNUNET_TIME_UNIT_MINUTES,
-                                           GNUNET_NO,
-                                           &challenge_status,
-                                           NULL);
+  msg = GNUNET_copy_message (msg_);
+  queue_message (&ctx_remote, msg);
+  destroy_conn_ctx (&ctx_local);
+  return GNUNET_OK;
 }
 
 
@@ -433,82 +468,70 @@
  * Type of a function to call when we receive a message
  * from the service.
  *
- * @param cls closure
+ * @param ctx the connection context
  * @param msg message received, NULL on timeout or fatal error
+ * @return GNUNET_OK to keep the connection open; any other value to close it
  */
-static void
-auth_challenge (void *cls, const struct GNUNET_MessageHeader *msg_)
+static int
+handle_challenge (struct ConnCtx *ctx,
+                  const struct GNUNET_MessageHeader *msg_)
 {
-  if (MSH_MTYPE_CHALLENGE != ntohs (msg_->type))
-  {
-    GNUNET_break (0);
-    GNUNET_SCHEDULER_shutdown ();
-    return;
-  }
+  struct GNUNET_MessageHeader *msg;
   if (sizeof (struct MSH_MSG_Challenge) >= ntohs (msg_->size))
   {
     GNUNET_break (0);
-    GNUNET_SCHEDULER_shutdown ();
-    return;
+    return GNUNET_SYSERR;
   }
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_CLIENT_transmit_and_get_response (client,
-                                                          msg_,
-                                                          
GNUNET_TIME_UNIT_SECONDS,
-                                                          GNUNET_NO,
-                                                          
&auth_challenge_response,
-                                                          NULL));
+  msg = GNUNET_copy_message (msg_);
+  queue_message (&ctx_local, msg);
+  return GNUNET_OK;
 }
 
 
+/**
+ * Tries to establish a connection to the target remote MSHD
+ */
 static void
 target_connect ()
 {
   struct MSH_MSG_RunCmd *msg;
+  struct GNUNET_CONFIGURATION_Handle *cfg;
   uint16_t size;
 
-  remote_cfg = GNUNET_CONFIGURATION_create ();
-  GNUNET_CONFIGURATION_set_value_string (remote_cfg, MSHD_REMOTE, "LISTEN",
+  cfg = GNUNET_CONFIGURATION_create ();
+  GNUNET_CONFIGURATION_set_value_string (cfg, MSHD_REMOTE, "LISTEN",
                                          ip2str (target));
-  GNUNET_CONFIGURATION_set_value_number (remote_cfg, MSHD_REMOTE, "PORT",
+  GNUNET_CONFIGURATION_set_value_number (cfg, MSHD_REMOTE, "PORT",
                                          target_port);
-  client_remote = GNUNET_CLIENT_connect (MSHD_REMOTE, remote_cfg);
-  if (NULL == client_remote)
-    return;
+  ctx_remote.cfg = cfg;
+  ctx_remote.conn = GNUNET_CLIENT_connect (MSHD_REMOTE, ctx_remote.cfg);
+  GNUNET_assert (NULL != ctx_remote.conn);
   size = sizeof (struct MSH_MSG_RunCmd) + cmdstr_len;
   msg = GNUNET_malloc (size);
   msg->header.size = htons (size);
   msg->header.type = htons (MSH_MTYPE_RUNCMD);
   (void) memcpy (msg->cmd, cmdstr, cmdstr_len);
-  GNUNET_assert (GNUNET_OK == 
-                 GNUNET_CLIENT_transmit_and_get_response (client_remote,
-                                                          &msg->header,
-                                                          
GNUNET_TIME_UNIT_SECONDS,
-                                                          GNUNET_NO,
-                                                          &auth_challenge,
-                                                          NULL));
-  GNUNET_free (msg);
-}
+  queue_message (&ctx_remote, &msg->header);
+  GNUNET_CLIENT_receive (ctx_remote.conn, &dispatch, &ctx_remote,
+                         GNUNET_TIME_UNIT_FOREVER_REL);
+ }
 
 
 /**
  * Type of a function to call when we receive a message
  * from the service.
  *
- * @param cls closure
+ * @param ctx the connection context
  * @param msg message received, NULL on timeout or fatal error
+ * @return GNUNET_OK to keep the connection open; any other value to close it
  */
-static void
-lookup_status (void *cls, const struct GNUNET_MessageHeader *msg_)
+static int
+handle_lookup_reply (struct ConnCtx *ctx,
+                     const struct GNUNET_MessageHeader *msg_)
 {
   const struct MSH_MSG_AddressLookupReply *msg;
   uint16_t size;
-  if (MSH_MTYPE_ADDRESS_LOOKUP_REPLY != ntohs (msg_->type))
-  {
-    GNUNET_break (0);
-    GNUNET_SCHEDULER_shutdown ();
-    return;
-  }
+
   size = ntohs (msg_->size);
   msg = (const struct MSH_MSG_AddressLookupReply *) msg_;
   if (0 == (target_port = ntohs (msg->port)))
@@ -516,22 +539,65 @@
     if ('\0' != msg->emsg[(size - sizeof (struct MSH_MSG_AddressLookup)) - 1])
     {
       GNUNET_break (0);
-      GNUNET_SCHEDULER_shutdown ();
-      return;
+      return GNUNET_SYSERR;
     }
     LOG_ERROR ("Address lookup for IP:%s failed with error: %s\n",
                ip2str (target), msg->emsg);
-    GNUNET_SCHEDULER_shutdown ();
-    return;
+    return GNUNET_SYSERR;
   }
   target_connect ();
+  return GNUNET_OK;
 }
 
 
 /**
+ * Dispatcher for received messages
+ *
+ * @param cls connection context
+ * @param msg message received, NULL on timeout or fatal error
+ */
+static void
+dispatch (void *cls, const struct GNUNET_MessageHeader *msg)
+{
+  struct ConnCtx *ctx = cls;
+  int ret;
+  
+  if (NULL == msg)
+    goto err_ret;
+  switch (ntohs (msg->type))
+  {
+  case MSH_MTYPE_ADDRESS_LOOKUP_REPLY:
+    ret = handle_lookup_reply (ctx, msg);
+    break;
+  case MSH_MTYPE_CHALLENGE:
+    ret = handle_challenge (ctx, msg);
+    break;
+  case MSH_MTYPE_CHALLENGE_RESPONSE:
+    ret = handle_challenge_response (ctx, msg);
+    break;
+  case MSH_MTYPE_EXEC_BEGIN:
+    ret = handle_exec_begin (ctx, msg);
+    break;
+  case MSH_MTYPE_CMD_STREAM_STDOUT:
+    ret = handle_cmd_output (ctx, msg);
+    break;
+  default:
+    LOG (GNUNET_ERROR_TYPE_WARNING, "Unrecognised message of type %u 
received\n", 
+         ntohs (msg->type));
+    goto err_ret;
+  }
+  GNUNET_CLIENT_receive (ctx->conn, &dispatch, ctx, 
GNUNET_TIME_UNIT_FOREVER_REL);
+  return;
+
+ err_ret:
+  destroy_conn_ctx (ctx);
+}
+
+
+/**
  * Function called with the result on the service test.
  *
- * @param cls closure
+ * @param cls NULL
  * @param result GNUNET_YES if the service is running,
  *               GNUNET_NO if the service is not running
  *               GNUNET_SYSERR if the configuration is invalid
@@ -548,21 +614,17 @@
     LOG_ERROR ("Service not running\n");
     return;
   }
-  client = GNUNET_CLIENT_connect (MSHD_LOCAL, cfg);
-  GNUNET_assert (NULL != client);
+  ctx_local.conn = GNUNET_CLIENT_connect (MSHD_LOCAL, ctx_local.cfg);
+  GNUNET_assert (NULL != ctx_local.conn);
   GNUNET_assert (0 != cmdstr_len);
   size = sizeof (struct MSH_MSG_AddressLookup);
   msg = GNUNET_malloc (size);
   msg->header.size = htons (size);
   msg->header.type = htons (MSH_MTYPE_ADDRESS_LOOKUP);
   msg->ip = htonl ((uint32_t) target);
-  GNUNET_assert (GNUNET_OK == 
-                 GNUNET_CLIENT_transmit_and_get_response (client, &msg->header,
-                                                          
GNUNET_TIME_UNIT_SECONDS,
-                                                          GNUNET_NO,
-                                                          &lookup_status,
-                                                          NULL));
-  GNUNET_free (msg);
+  queue_message (&ctx_local, &msg->header);
+  GNUNET_CLIENT_receive (ctx_local.conn, &dispatch, &ctx_local,
+                         GNUNET_TIME_UNIT_FOREVER_REL);
 }
 
 
@@ -614,14 +676,11 @@
     LOG_ERROR ("Could not find socket for local MSHD.  Are we running under 
MSHD?\n");
     return;
   }
-  cfg = GNUNET_CONFIGURATION_dup (cfg_);
-  GNUNET_CONFIGURATION_set_value_string (cfg, MSHD_LOCAL, "UNIXPATH", 
psock_path);
-  if (NULL == client)
-  {
-    LOG_ERROR ("Cannot open connection to MSHD\n");
-    return;
-  }
-  test = GNUNET_CLIENT_service_test (MSHD_LOCAL, cfg, GNUNET_TIME_UNIT_SECONDS,
+  ctx_local.cfg = GNUNET_CONFIGURATION_dup (cfg_);
+  GNUNET_CONFIGURATION_set_value_string (ctx_local.cfg, MSHD_LOCAL,
+                                         "UNIXPATH", psock_path);
+  test = GNUNET_CLIENT_service_test (MSHD_LOCAL, ctx_local.cfg,
+                                     GNUNET_TIME_UNIT_SECONDS,
                                      &result_cb, NULL);
 }
 

Modified: msh/src/mshd-server.c
===================================================================
--- msh/src/mshd-server.c       2013-08-08 17:30:02 UTC (rev 28479)
+++ msh/src/mshd-server.c       2013-08-08 21:00:16 UTC (rev 28480)
@@ -14,6 +14,16 @@
 #define MESSAGE_SEND_TIMEOUT(s) \
   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, s)
 
+#define LOG(kind,...)                           \
+  GNUNET_log_from (kind, "mshd-server", __VA_ARGS__)
+
+#define LOG_DEBUG(...) LOG(GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
+
+#define LOG_ERROR(...) LOG(GNUNET_ERROR_TYPE_ERROR, __VA_ARGS__)
+
+#define LOG_STRERROR(kind,cmd)                  \
+  GNUNET_log_from_strerror (kind, "mshd-error", cmd)
+
 /**
  * server handle for accepting requests from local MSH instances
  */
@@ -36,32 +46,74 @@
 
 
 /**
- * Tranmission context
+ * Message queue for transmitting messages
  */
-struct TransmitCtx
+struct MessageQueue
 {
-  struct GNUNET_SERVER_Client *client;
-  
+  /**
+   * next pointer for DLL
+   */
+  struct MessageQueue *next;
+
+  /**
+   * prev pointer for DLL
+   */
+  struct MessageQueue *prev;
+
+  /**
+   * The message to be sent
+   */
   struct GNUNET_MessageHeader *msg;
-  
 };
 
+
 /**
+ * Context associated with each client instance
+ */
+struct ClientCtx;
+
+
+/**
  * Context for connections requiring to execute commands
  */
-struct ExecConnCtx
+struct ExecCtx
 {
   /**
-   * the client handle
+   * associated client context
    */
-  struct GNUNET_SERVER_Client *client;
-
+  struct ClientCtx *client_ctx;
+  
   /**
    * The command strings to execute
    */
   char **args;
 
   /**
+   * the process handle to the command to execute
+   */
+  struct GNUNET_OS_Process *proc;
+
+  /**
+   * Input pipe handle for the process
+   */
+  struct GNUNET_DISK_PipeHandle *pin;
+
+  /**
+   * Input pipe handle for the process
+   */
+  struct GNUNET_DISK_PipeHandle *pout;
+
+  /**
+   * file handle for processes input
+   */
+  struct GNUNET_DISK_FileHandle *fin;
+
+  /**
+   * file handle for processes output
+   */
+  struct GNUNET_DISK_FileHandle *fout;
+
+  /**
    * salt hash used for authentication
    */
   struct GNUNET_HashCode salt;
@@ -72,6 +124,11 @@
   GNUNET_SCHEDULER_TaskIdentifier timeout_task;
 
   /**
+   * task to read the output from the process
+   */
+  GNUNET_SCHEDULER_TaskIdentifier fout_task;
+
+  /**
    * the file descriptor associated with the client connection
    */
   int conn_fd;
@@ -79,12 +136,98 @@
 
 
 /**
+ * Context associated with each client instance
+ */
+struct ClientCtx
+{
+  /**
+   * The client handle
+   */
+  struct GNUNET_SERVER_Client *client;
+
+  /**
+   * The server to which this client has connected to
+   */
+  //struct GNUNET_SERVER_Handle *serv;
+
+  /**
+   * the transmission handle
+   */
+  struct GNUNET_SERVER_TransmitHandle *tx;
+
+  /**
+   * message queue head
+   */
+  struct MessageQueue *mq_head;
+
+  /**
+   * message queue tail
+   */
+  struct MessageQueue *mq_tail;
+
+  /**
+   * execution context.  Set this for remote clients which ask us to execute a
+   * command
+   */
+  struct ExecCtx *exec_ctx;
+};
+
+
+/**
+ * Destroys an execution context
+ * 
+ * @param ctx execution context
+ */
+static void
+destroy_exec_ctx (struct ExecCtx *ctx)
+{
+  unsigned int cnt;
+
+  GNUNET_break (0);
+  if (NULL != ctx->args)
+  {
+    for (cnt = 0; NULL != ctx->args[cnt]; cnt++)
+      GNUNET_free (ctx->args[cnt]);
+    GNUNET_free (ctx->args);
+  }
+  if (GNUNET_SCHEDULER_NO_TASK != ctx->timeout_task)
+    GNUNET_SCHEDULER_cancel (ctx->timeout_task);
+  GNUNET_free (ctx);
+}
+
+
+/**
+ * Destroys a client context
+ *
+ * @param ctx the client context
+ */
+static void
+destroy_client_ctx (struct ClientCtx *ctx)
+{
+  struct MessageQueue *mq;
+
+  GNUNET_SERVER_client_drop (ctx->client);
+  if (NULL != ctx->tx)
+    GNUNET_SERVER_notify_transmit_ready_cancel (ctx->tx);
+  while (NULL != (mq = ctx->mq_head))
+  {
+    GNUNET_free (mq->msg);
+    GNUNET_CONTAINER_DLL_remove (ctx->mq_head, ctx->mq_tail, mq);
+    GNUNET_free (mq);
+  }
+  if (NULL != ctx->exec_ctx)
+    destroy_exec_ctx (ctx->exec_ctx);
+  GNUNET_free (ctx);
+}
+
+
+/**
  * Function called to notify a client about the connection
  * begin ready to queue more data.  "buf" will be
  * NULL and "size" zero if the connection was closed for
  * writing in the meantime.
  *
- * @param cls closure
+ * @param cls client context
  * @param size number of bytes available in buf
  * @param buf where the callee should write the message
  * @return number of bytes written to buf
@@ -92,43 +235,67 @@
 static size_t 
 transmit_ready_cb (void *cls, size_t size, void *buf)
 {
-  struct TransmitCtx *ctx = cls;
+  struct ClientCtx *ctx = cls;
   struct GNUNET_SERVER_Client *client = ctx->client;
-  struct GNUNET_MessageHeader *msg = ctx->msg;
+  struct MessageQueue *mq;
+  struct GNUNET_MessageHeader *msg;
   size_t wrote;
 
+  ctx->tx = NULL;
   wrote = 0;
   if ((0 == size) || (NULL == buf))
-    goto cleanup;
+  {
+    destroy_client_ctx (ctx);
+    return 0;
+  }
+  mq = ctx->mq_head;
+  msg = mq->msg;
   wrote = ntohs (msg->size);
   GNUNET_assert (size >= wrote);
   (void) memcpy (buf, msg, wrote);
-  
- cleanup:
-  GNUNET_free (msg);
-  GNUNET_SERVER_client_drop (client);
+  GNUNET_CONTAINER_DLL_remove (ctx->mq_head, ctx->mq_tail, mq);
+  GNUNET_free (mq->msg);
+  GNUNET_free (mq);
+  if (NULL != (mq = ctx->mq_head))
+    ctx->tx = GNUNET_SERVER_notify_transmit_ready (client, ntohs (msg->size),
+                                                  MESSAGE_SEND_TIMEOUT (30),
+                                                  &transmit_ready_cb, ctx);
   GNUNET_SERVER_receive_done (client, GNUNET_YES);
   return wrote;
 }
 
 
+/**
+ * Queue a message into a clients message queue
+ *
+ * @param ctx the context associated with the client
+ * @param msg the message to queue.  Will be consumed
+ */
 static void
-send_message (struct GNUNET_SERVER_Client *client,
-              struct GNUNET_MessageHeader *msg)
+queue_message (struct ClientCtx *ctx, struct GNUNET_MessageHeader *msg)
 {
-  struct TransmitCtx *ctx;
+  struct MessageQueue *mq;
+  struct GNUNET_SERVER_Client *client = ctx->client;
 
   GNUNET_SERVER_client_keep (client);
-  ctx = GNUNET_malloc (sizeof (struct TransmitCtx));
-  ctx->client = client;
-  ctx->msg = msg;
-  (void) GNUNET_SERVER_notify_transmit_ready (client, ntohs (msg->size),
-                                              MESSAGE_SEND_TIMEOUT (30),
-                                              &transmit_ready_cb, ctx);
-
+  mq = GNUNET_malloc (sizeof (struct MessageQueue));
+  mq->msg = msg;
+  GNUNET_CONTAINER_DLL_insert_tail (ctx->mq_head, ctx->mq_tail, mq);
+  if (NULL == ctx->tx)
+   ctx->tx = GNUNET_SERVER_notify_transmit_ready (client, ntohs (msg->size),
+                                                  MESSAGE_SEND_TIMEOUT (30),
+                                                  &transmit_ready_cb, ctx);
 }
 
 
+/**
+ * Parse contingious 0-terminated strings from a buffer of given length
+ *
+ * @param buf the buffer
+ * @param size the size of the buffer
+ * @param s will contain the array of strings upon return
+ * @return the number of strings returned in the array
+ */
 static int
 parse_strings (const char *buf, size_t size, char ***s)
 {
@@ -155,8 +322,15 @@
   return cnt;
 }
 
+
+/**
+ * Create a challenge message 
+ *
+ * @param ctx the execution context
+ * @return the challenge message
+ */
 static struct GNUNET_MessageHeader *
-create_challenge_message (struct ExecConnCtx *ctx)
+create_challenge_message (struct ExecCtx *ctx)
 {
   struct MSH_MSG_Challenge *msg;
   uint16_t size;
@@ -171,25 +345,6 @@
 }
 
 
-static void
-destroy_ctx (struct ExecConnCtx *ctx)
-{
-  unsigned int cnt;
-
-  if (NULL != ctx->client)
-    GNUNET_SERVER_client_drop (ctx->client);
-  if (NULL != ctx->args)
-  {
-    for (cnt = 0; NULL != ctx->args[cnt]; cnt++)
-      GNUNET_free (ctx->args[cnt]);
-    GNUNET_free (ctx->args);
-  }
-  if (GNUNET_SCHEDULER_NO_TASK != ctx->timeout_task)
-    GNUNET_SCHEDULER_cancel (ctx->timeout_task);
-  GNUNET_free (ctx);
-}
-
-
 /**
  * Functions with this signature are called whenever a message is
  * received.
@@ -199,58 +354,22 @@
  * @param message the actual message
  */
 static void
-handle_runcmd (void *cls,
-               struct GNUNET_SERVER_Client *client,
-               const struct GNUNET_MessageHeader* message)
-{
-  struct ExecConnCtx *ctx;
-  const struct MSH_MSG_RunCmd *msg;
-  struct GNUNET_MessageHeader *reply;
-  uint16_t size;
-  
-  ctx = GNUNET_SERVER_client_get_user_context (client, struct ExecConnCtx);
-  size = ntohs (message->size);
-  if ( size <= sizeof (struct MSH_MSG_RunCmd))
-    goto close_conn;
-  msg = (const struct MSH_MSG_RunCmd *) message;
-  if (0 == parse_strings (msg->cmd,
-                          size - sizeof (struct MSH_MSG_RunCmd),
-                          &ctx->args))
-    goto close_conn;
-  reply = create_challenge_message (ctx);
-  send_message (client, reply);
-  return;
-
- close_conn:
-  GNUNET_break_op (0);
-  destroy_ctx (ctx);
-  GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-}
-
-
-/**
- * Functions with this signature are called whenever a message is
- * received.
- *
- * @param cls closure
- * @param client identification of the client
- * @param message the actual message
- */
-static void
 handle_addresslookup (void *cls, struct GNUNET_SERVER_Client *client,
                       const struct GNUNET_MessageHeader* message)
 {
+  struct ClientCtx *ctx;
   const struct MSH_MSG_AddressLookup *msg;
   struct MSH_MSG_AddressLookupReply *reply;
-  struct TransmitCtx *ctx;
   struct InstanceAddr *iaddr;
   char *emsg;
   in_addr_t ip;
   uint16_t port;
   uint16_t reply_size;
-
+  
   emsg = NULL;
   port = 0;
+  ctx = GNUNET_SERVER_client_get_user_context (client, struct ClientCtx);
+  GNUNET_assert (NULL != ctx);
   msg = (const struct MSH_MSG_AddressLookup *) message;
   ip = ntohl (msg->ip);
   if (GNUNET_NO == reversemap_check (rmap, ip))
@@ -272,11 +391,27 @@
   reply->port = htons (port);
   if (NULL != emsg)
     (void) strcpy (reply->emsg, emsg);
-  send_message (client, &reply->header);
+  queue_message (ctx, &reply->header);
 }
 
 
 /**
+ * Generate the credential for the given challenge 
+ *
+ * @param c the challenge
+ * @param cred output parameter for the credential
+ */
+static void
+auth_challenge_cred (struct GNUNET_HashCode *c, struct GNUNET_HashCode *cred)
+{
+  struct GNUNET_HashCode xor;
+
+  GNUNET_CRYPTO_hash_xor (c, &shash, &xor);
+  GNUNET_CRYPTO_hash (&xor, sizeof (struct GNUNET_HashCode), cred);
+}
+
+
+/**
  * Functions with this signature are called whenever a message is
  * received.
  *
@@ -288,23 +423,25 @@
 handle_auth_challenge (void *cls, struct GNUNET_SERVER_Client *client,
                        const struct GNUNET_MessageHeader* message)
 {
+  struct ClientCtx *ctx;
   const struct MSH_MSG_Challenge *msg;
   struct MSH_MSG_ChallengeResponse *reply;
-  struct GNUNET_HashCode salt;
-  struct GNUNET_HashCode xor;
+  struct GNUNET_HashCode c;
+  struct GNUNET_HashCode cred;
 
+  ctx = GNUNET_SERVER_client_get_user_context (client, struct ClientCtx);
+  GNUNET_assert (NULL != ctx);
   msg = (const struct MSH_MSG_Challenge *) message;
   GNUNET_assert (GNUNET_OK == 
                  GNUNET_CRYPTO_hash_from_string2 (msg->salt.encoding,
                                                   sizeof (msg->salt),
-                                                  &salt));
-  GNUNET_CRYPTO_hash_xor (&salt, &shash, &xor);
-  GNUNET_CRYPTO_hash (&xor, sizeof (struct GNUNET_HashCode), &salt);
+                                                  &c));
+  auth_challenge_cred (&c, &cred);
   reply = GNUNET_malloc (sizeof (struct MSH_MSG_ChallengeResponse));
   reply->header.size = htons (sizeof (struct MSH_MSG_ChallengeResponse));
   reply->header.type = htons (MSH_MTYPE_CHALLENGE_RESPONSE);
-  GNUNET_CRYPTO_hash_to_enc (&salt, &reply->auth);
-  send_message (client, &reply->header);
+  GNUNET_CRYPTO_hash_to_enc (&cred, &reply->auth);
+  queue_message (ctx, &reply->header);
 }
 
 
@@ -329,6 +466,24 @@
 }
 
 
+/**
+ * Callback to be called when ever a client connects to the local server
+ *
+ * @param cls NULL
+ * @param client the client handle
+ */
+static void
+local_server_client_connect (void *cls, struct GNUNET_SERVER_Client *client)
+{
+  struct ClientCtx *ctx;
+  
+  ctx = GNUNET_malloc (sizeof (struct ClientCtx ));
+  ctx->client = client;
+  GNUNET_SERVER_client_set_user_context (client, ctx);
+}
+
+
+
 int
 init_local_server (const char *unixpath)
 {
@@ -363,6 +518,7 @@
     return GNUNET_SYSERR;
   }
   GNUNET_SERVER_add_handlers (local_serv, handlers);
+  GNUNET_SERVER_connect_notify (local_serv, &local_server_client_connect, 
NULL);
   return GNUNET_OK;
 }
 
@@ -374,7 +530,69 @@
 }
 
 
+/******************************************************************************/
+/* Daemon server.  Responsbile for executing commands submitted by remote MSH 
*/
+/* clients                                                                    
*/
+/******************************************************************************/
+
+
 /**
+ * Functions with this signature are called whenever a message is
+ * received.
+ *
+ * @param cls closure
+ * @param client identification of the client
+ * @param message the actual message
+ */
+static void
+handle_runcmd (void *cls,
+               struct GNUNET_SERVER_Client *client,
+               const struct GNUNET_MessageHeader* message)
+{
+  struct ClientCtx *ctx;
+  struct ExecCtx *exec_ctx;
+  const struct MSH_MSG_RunCmd *msg;
+  struct GNUNET_MessageHeader *reply;
+  uint16_t size;
+  
+  LOG_DEBUG ("Received a RUN_CMD message\n");
+  ctx = GNUNET_SERVER_client_get_user_context (client, struct ClientCtx);
+  exec_ctx = ctx->exec_ctx;
+  GNUNET_assert (NULL != exec_ctx);
+  if (NULL != exec_ctx->args)
+  {
+    GNUNET_break (0);
+    goto close_conn;
+  }
+  size = ntohs (message->size);
+  if ( size <= sizeof (struct MSH_MSG_RunCmd))
+  {
+    GNUNET_break_op (0);
+    goto close_conn; 
+  }
+  msg = (const struct MSH_MSG_RunCmd *) message;
+  exec_ctx = GNUNET_malloc (sizeof (struct ExecCtx));
+  ctx->exec_ctx = exec_ctx;
+  if (0 == parse_strings (msg->cmd,
+                          size - sizeof (struct MSH_MSG_RunCmd),
+                          &exec_ctx->args))
+  {
+    GNUNET_break_op (0);
+    goto close_conn;
+  }
+  reply = create_challenge_message (exec_ctx);
+  LOG_DEBUG ("Sending AUTH_CHALLENGE\n");
+  queue_message (ctx, reply);
+  return;
+
+ close_conn:
+  GNUNET_break_op (0);
+  destroy_client_ctx (ctx);
+  GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+}
+
+
+/**
  * Function to call for access control checks.
  *
  * @param cls closure
@@ -394,6 +612,122 @@
 
 
 /**
+ * Task to read the output from a process and send it to client
+ *
+ * @param cls the execution context
+ * @param tc scheduler task context
+ */
+static void
+read_fout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct ExecCtx *ctx = cls;
+  struct MSH_MSG_CmdIO *msg;
+  static char data[MAX_IO_DATA];
+  ssize_t size;
+  uint16_t msize;
+
+  ctx->fout_task = GNUNET_SCHEDULER_NO_TASK;
+  if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
+  {
+    return;
+  }
+  size = GNUNET_DISK_file_read_non_blocking (ctx->fout, data, MAX_IO_DATA);
+  GNUNET_assert (size > 0);
+  msize = size + sizeof (struct MSH_MSG_CmdIO);
+  msg = GNUNET_malloc (msize);
+  msg->header.type = htons (MSH_MTYPE_CMD_STREAM_STDOUT);
+  msg->header.size = htons (msize);
+  memcpy (msg->data, data, size);
+  queue_message (ctx->client_ctx, &msg->header);
+}
+
+
+/**
+ * start the process from the execution process
+ *
+ * @param ctx the execution context
+ * @return GNUNET_OK upon success; GNUNET_SYSERR upon failure
+ */
+static int
+exec_proc (struct ExecCtx *ctx)
+{
+  ctx->pin = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, 0, 0);
+  ctx->pout = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, 0, 0);
+  GNUNET_assert ((NULL != ctx->pin && (NULL != ctx->pout)));
+  ctx->fin = GNUNET_DISK_pipe_detach_end (ctx->pin, 
GNUNET_DISK_PIPE_END_WRITE);
+  ctx->fout = GNUNET_DISK_pipe_detach_end (ctx->pin, 
GNUNET_DISK_PIPE_END_READ);
+  GNUNET_assert ((NULL != ctx->fin && (NULL != ctx->fout)));
+  ctx->proc = GNUNET_OS_start_process_vap (GNUNET_NO,
+                                           GNUNET_OS_INHERIT_STD_NONE,
+                                           ctx->pin,
+                                           ctx->pout,
+                                           ctx->args[0],
+                                           ctx->args);
+  if (NULL == ctx->proc)
+    return GNUNET_SYSERR;
+  ctx->fout_task = 
+      GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
+                                      ctx->fout, read_fout, ctx);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Functions with this signature are called whenever a message is
+ * received.
+ *
+ * @param cls closure
+ * @param client identification of the client
+ * @param message the actual message
+ */
+static void
+handle_auth_challenge_response (void *cls,
+                                struct GNUNET_SERVER_Client *client,
+                                const struct GNUNET_MessageHeader* message)
+{
+  const struct MSH_MSG_ChallengeResponse *msg;
+  struct GNUNET_MessageHeader *reply;
+  struct ClientCtx *ctx;
+  struct ExecCtx *exec_ctx;
+  struct GNUNET_HashCode cred;
+  struct GNUNET_CRYPTO_HashAsciiEncoded enc;
+  
+  ctx = GNUNET_SERVER_client_get_user_context (client, struct ClientCtx);
+  if (NULL == ctx)
+  {
+    GNUNET_break_op (0);
+    goto err_ret;
+  }
+  exec_ctx = ctx->exec_ctx;
+  GNUNET_assert (NULL != exec_ctx);
+  auth_challenge_cred (&exec_ctx->salt, &cred);
+  GNUNET_CRYPTO_hash_to_enc (&cred, &enc);
+  msg = (const struct MSH_MSG_ChallengeResponse *) message;
+  if (0 != memcmp (&msg->auth, &cred,
+                   sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)))
+  {
+    GNUNET_break (0);
+    goto err_ret;
+  }
+  if (GNUNET_OK != exec_proc (exec_ctx))
+  {
+    GNUNET_break (0);
+    goto err_ret;
+  }
+  reply = GNUNET_malloc (sizeof (struct GNUNET_MessageHeader));
+  reply->size = htons (sizeof (struct GNUNET_MessageHeader));
+  reply->type = htons (MSH_MTYPE_EXEC_BEGIN);
+  queue_message (ctx, reply);
+  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  return;
+  
+ err_ret:
+  GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+  destroy_client_ctx (ctx);
+}
+
+
+/**
  * Initialises the server which spawns processes and forwards it stdin and 
stdout
  *
  * @param h the network handle of the socket to listen for incoming connections
@@ -403,6 +737,8 @@
 {
   static const struct GNUNET_SERVER_MessageHandler handlers[] = {
     {&handle_runcmd, NULL, MSH_MTYPE_RUNCMD, 0},
+    {&handle_auth_challenge_response, NULL, MSH_MTYPE_CHALLENGE_RESPONSE, 
+     sizeof (struct MSH_MSG_ChallengeResponse)},
     {NULL, NULL, 0, 0}
   };
   
@@ -421,10 +757,11 @@
 static void
 timeout_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
-  struct ExecConnCtx *ctx = cls;
+  struct ClientCtx *ctx = cls;
+  struct ExecCtx *exec_ctx = ctx->exec_ctx;
 
-  ctx->timeout_task = GNUNET_SCHEDULER_NO_TASK;
-  destroy_ctx (ctx);
+  exec_ctx->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+  destroy_client_ctx (ctx);
 }
 
 
@@ -432,13 +769,17 @@
 daemon_server_add_connection (struct GNUNET_CONNECTION_Handle *conn, 
                               int conn_fd)
 {
-  struct ExecConnCtx *ctx;
+  struct ClientCtx *ctx;
+  struct ExecCtx *exec_ctx;
 
-  ctx = GNUNET_malloc (sizeof (struct ExecConnCtx));
-  ctx->conn_fd = conn_fd;
+  ctx = GNUNET_malloc (sizeof (struct ClientCtx));
+  exec_ctx = GNUNET_malloc (sizeof (struct ExecCtx));
+  exec_ctx->client_ctx = ctx;
+  ctx->exec_ctx = exec_ctx;
+  exec_ctx->conn_fd = conn_fd;
   ctx->client = GNUNET_SERVER_connect_socket (daemon_serv, conn);
   GNUNET_SERVER_client_set_user_context (ctx->client, ctx);
-  ctx->timeout_task = 
+  exec_ctx->timeout_task = 
       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, &timeout_cb, 
ctx);
 }
 

Modified: msh/src/mshd.c
===================================================================
--- msh/src/mshd.c      2013-08-08 17:30:02 UTC (rev 28479)
+++ msh/src/mshd.c      2013-08-08 21:00:16 UTC (rev 28480)
@@ -178,6 +178,11 @@
 static struct GNUNET_NETWORK_Handle *listen_socket;
 
 /**
+ * The process handle of the process started by instance running with rank 0
+ */
+static struct GNUNET_OS_Process *proc;
+
+/**
  * Task for running a round
  */
 static GNUNET_SCHEDULER_TaskIdentifier rtask;
@@ -425,8 +430,18 @@
 
     (void) unlink (unixpath);
     setenv (MSHD_SOCK_NAME, unixpath, 1);
-    GNUNET_break (0);           /* FIXME: start process */
-    /* process = GNUNET_OS_start_process_vap () */
+    proc = GNUNET_OS_start_process_vap (GNUNET_NO,
+                                        GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
+                                        NULL,
+                                        NULL,
+                                        run_args[0],
+                                        run_args);
+    if (NULL == proc)
+    {
+      GNUNET_break (0);
+      GNUNET_SCHEDULER_shutdown ();
+      return;
+    }
   }
 }
 

Modified: msh/src/mtypes.h
===================================================================
--- msh/src/mtypes.h    2013-08-08 17:30:02 UTC (rev 28479)
+++ msh/src/mtypes.h    2013-08-08 21:00:16 UTC (rev 28480)
@@ -108,8 +108,6 @@
 
 #define MSH_MTYPE_RUNCMD 200
 
-#define MSH_MTYPE_RUNCMDSTATUS 201
-
 #define MSH_MTYPE_CMD_STREAM_STDIN 202
 
 #define MSH_MTYPE_CMD_STREAM_STDOUT 203
@@ -122,6 +120,8 @@
 
 #define MSH_MTYPE_CHALLENGE_RESPONSE 207
 
+#define MSH_MTYPE_EXEC_BEGIN 208
+
 /**
  * Message for sending a remote command and its arguments to MSHD
  */
@@ -175,6 +175,7 @@
   char data[0];
 };
 
+#define MAX_IO_DATA (GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct 
MSH_MSG_CmdIO))
 
 struct MSH_MSG_AddressLookup
 {




reply via email to

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