gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r30822 - msh/src


From: gnunet
Subject: [GNUnet-SVN] r30822 - msh/src
Date: Wed, 20 Nov 2013 11:18:26 +0100

Author: harsha
Date: 2013-11-20 11:18:26 +0100 (Wed, 20 Nov 2013)
New Revision: 30822

Modified:
   msh/src/Makefile.am
   msh/src/msh.c
   msh/src/mshd-server.c
   msh/src/mshd2.c
   msh/src/mtypes.h
Log:
- fork approach in mshd server


Modified: msh/src/Makefile.am
===================================================================
--- msh/src/Makefile.am 2013-11-20 09:56:22 UTC (rev 30821)
+++ msh/src/Makefile.am 2013-11-20 10:18:26 UTC (rev 30822)
@@ -4,7 +4,8 @@
 
 mshd_SOURCES = mshd.c mshd.h util.c util.h mtypes.h \
   common.h bitmap.c bitmap.h addressmap.c addressmap.h reduce.h reduce.c \
-  mshd-server.c mshd_pmonitor.c mshd_pmonitor.h
+  mshd-server.c mshd_pmonitor.c mshd_pmonitor.h \
+  ttymodes.h ttymodes.c
 mshd_LDADD = -lgnunetutil -lm
 
 msh_SOURCES = msh.c mtypes.h

Modified: msh/src/msh.c
===================================================================
--- msh/src/msh.c       2013-11-20 09:56:22 UTC (rev 30821)
+++ msh/src/msh.c       2013-11-20 10:18:26 UTC (rev 30822)
@@ -8,6 +8,7 @@
 
 #include "common.h"
 #include <gnunet/gnunet_util_lib.h>
+#include "termios.h"
 #include "mtypes.h"
 #include "util.h"
 
@@ -176,7 +177,18 @@
 
 } state;
 
+
 /**
+ * Terminal window size information
+ */
+static struct winsize ws;
+
+/**
+ * Terminal settings
+ */
+static struct termios tio;
+
+/**
  * The ip address of the remote node
  */
 static in_addr_t target;
@@ -186,8 +198,22 @@
  */
 static uint16_t target_port;
 
+/**
+ * Do not allocate pseudo-tty
+ */
+static int disable_pty;
 
 /**
+ * Are we capable of allocating pseudo-tty
+ */
+static int can_pty;
+
+/**
+ * Do we need to allocate a pseudo-tty
+ */
+static int need_pty;
+
+/**
  * Destroys a connection context
  *
  * @param ctx connection context
@@ -647,6 +673,29 @@
 
 
 /**
+ * Reads terminal settings and window size
+ *
+ * @return GNUNET_OK upon success; GNUNET_SYSERR upon error
+ */
+static int
+read_tty_settings ()
+{
+  unsigned int cnt;
+
+  if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "ioctl");
+    return GNUNET_SYSERR;
+  }
+  if (-1 == tcgetattr (0, &tio))
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "tcgetattr");
+    return GNUNET_SYSERR;
+  }
+}
+
+
+/**
  * Main function that will be run.
  *
  * @param cls closure
@@ -662,7 +711,19 @@
   char *psock_path;
   size_t arg_len;
   unsigned int cnt;
-
+  
+  if (isatty (0))
+    can_pty = 1;
+  if (need_pty && !can_pty)
+  {
+    LOG_ERROR ("Not attached to a terminal but pseudo-tty is requested (-t) 
option");
+    return;
+  }
+  if (!disable_pty && can_pty)
+  {
+    if (GNUNET_OK != read_tty_settings ())
+      return;
+  }
   state = STATE_DELIVER_CMD;
   if (NULL == (ipstr = args[0]))
   {
@@ -711,7 +772,11 @@
 main (int argc, char * const argv[])
 {
   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
-     GNUNET_GETOPT_OPTION_END
+    {'T', "disable-pty", NULL, _("do not allocate a pseudo-tty"), 0,
+     &GNUNET_GETOPT_set_one, (void *) &disable_pty},
+    {'t', "require-pty", NULL, _("exit with error if a pseudo-tty cannot be 
allocated"),
+     0, &GNUNET_GETOPT_set_one, (void *) &need_pty},
+    GNUNET_GETOPT_OPTION_END
   };
    
   result = GNUNET_SYSERR;

Modified: msh/src/mshd-server.c
===================================================================
--- msh/src/mshd-server.c       2013-11-20 09:56:22 UTC (rev 30821)
+++ msh/src/mshd-server.c       2013-11-20 10:18:26 UTC (rev 30822)
@@ -8,6 +8,7 @@
 
 #include "common.h"
 #include <gnunet/gnunet_util_lib.h>
+#include <termios.h>
 #include "mshd.h"
 #include "addressmap.h"
 #include "mshd_pmonitor.h"
@@ -73,11 +74,6 @@
   char **args;
 
   /**
-   * the process handle to the command to execute
-   */
-  struct GNUNET_OS_Process *proc;
-
-  /**
    * file handle for processes input
    */
   struct GNUNET_DISK_FileHandle *fin;
@@ -94,6 +90,12 @@
   char *buf;
 
   /**
+   * If this session were to be interactive, the message containing the setting
+   * to use for the pseudo-tty we create
+   */
+  struct MSH_MSG_PtyMode *pty_mode;
+
+  /**
    * The size of the input buffer
    */
   size_t bufsize;
@@ -118,6 +120,31 @@
    */
   GNUNET_SCHEDULER_TaskIdentifier fin_task;
 
+  /**
+   * The pid of the child we start
+   */
+  pid_t child_pid;
+
+  /**
+   * If this is an interactive session, this is the master side of the
+   * pseudo-tty we create
+   */
+  int master;
+
+  /**
+   * Is this an interactive session?
+   */
+  int interactive;
+
+  /**
+   * Is this session authentication?
+   */
+  int authenticated;
+
+  /**
+   * If this is an interactive session, is a pseudo-tty created?
+   */
+  int pty_created;
 };
 
 
@@ -138,10 +165,10 @@
       GNUNET_free (ctx->args[cnt]);
     GNUNET_free (ctx->args);
   }
-  if (NULL != ctx->proc)
+  if (0 != ctx->child_pid)
   {
-    MSH_monitor_process_cancel (ctx->proc);
-    GNUNET_OS_process_destroy (ctx->proc); /* we leave the processes running */
+    MSH_monitor_process_pid_cancel (ctx->child_pid);
+    GNUNET_break (0 == kill (ctx->child_pid, SIGTERM));
   }
   GNUNET_DISK_file_close (ctx->fin);
   GNUNET_DISK_file_close (ctx->fout);
@@ -151,6 +178,7 @@
     GNUNET_SCHEDULER_cancel (ctx->fout_task);
   if (NULL != ctx->buf)
     GNUNET_free (ctx->buf);
+  GNUNET_free_non_null (ctx->pty_mode);
   GNUNET_free (ctx);
 }
 
@@ -422,24 +450,23 @@
 
 
 /**
- * Functions with this signature are called whenever a message is
- * received.
+ * Handle session open message and start challenge authentication.
  *
  * @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)
+handle_session_open (void *cls,
+                     struct GNUNET_SERVER_Client *client,
+                     const struct GNUNET_MessageHeader* message)
 {
   struct ExecCtx *exec_ctx;
-  const struct MSH_MSG_RunCmd *msg;
+  const struct MSH_MSG_SessionOpen *msg;
   struct GNUNET_MessageHeader *reply;
   uint16_t size;
   
-  LOG_DEBUG ("Received a RUN_CMD message\n");
+  LOG_DEBUG ("Received a SESSION_OPEN message\n");
   exec_ctx = GNUNET_SERVER_client_get_user_context (client, struct ExecCtx);
   GNUNET_assert (NULL != exec_ctx);
   if (NULL != exec_ctx->args)
@@ -447,20 +474,8 @@
     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;
-  if (0 == parse_strings (msg->cmd,
-                          size - sizeof (struct MSH_MSG_RunCmd),
-                          &exec_ctx->args))
-  {
-    GNUNET_break_op (0);
-    goto close_conn;
-  }
+  if (MSH_SESSION_TYPE_INTERACTIVE == ntohl (msg->type))
+    exec_ctx->interactive = GNUNET_YES;
   reply = create_challenge_message (exec_ctx);
   LOG_DEBUG ("Sending AUTH_CHALLENGE\n");
   GNUNET_SERVER_notification_context_unicast (daemon_serv_nc, client, reply,
@@ -515,6 +530,87 @@
 
 
 /**
+ * Configure the terminal for the child
+ */
+static int
+parse_term_mode (const struct MSH_MSG_PtyMode *msg,
+                 struct termios *tio,
+                 struct winsize *ws,
+                 char **termstr)
+{
+  uint16_t *params;
+  char *str;
+  unsigned int cnt;
+  unsigned int ns;
+  uint16_t msize;
+  size_t expected;
+  speed_t ospeed;
+  speed_t ispeed;
+
+  msize = ntohs (msg->header.size);
+  ns = ntohs (msg->nsettings);
+  expected = (sizeof (struct MSH_MSG_PtyMode) + (sizeof (uint16_t) * ns * 2));
+  if (msize < expected)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+#define PARSE_WIN_SIZE(field) \
+  ws->field = ntohs (msg->field);
+  PARSE_WIN_SIZE (ws_row);
+  PARSE_WIN_SIZE (ws_col);
+  PARSE_WIN_SIZE (ws_xpixel);
+  PARSE_WIN_SIZE (ws_ypixel);
+#undef PARSE_WIN_SIZE
+  ospeed = baud_to_speed (ntohl (msg->ospeed));
+  ispeed = baud_to_speed (ntohl (msg->ispeed));
+  if (0 != cfsetospeed (tio, ospeed))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  if (0 != cfsetispeed (tio, ispeed))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  params = (uint16_t *) &msg[1];
+  for (cnt = 0; cnt < ns; cnt++)
+  {
+    switch (ntohs (params[2 * cnt]))
+    {
+#define TTYCHAR(NAME,OP)                                \
+      case OP:                                          \
+        tio->c_cc[NAME] = ntohs (params[(2 * cnt)+1]);   \
+        break;
+#define TTYMODE(NAME, FIELD, OP)                \
+      case OP:                                  \
+        if (1 == ntohs (params[(2 * cnt)+1]))   \
+          tio->FIELD |= NAME;                    \
+        break;
+#include "ttymodes.h"
+#undef TTYCHAR
+#undef TTYMODE
+      
+    default:
+      GNUNET_assert (0);
+    }
+  }
+  if (0 == (msize - expected))
+    return GNUNET_OK;
+  str = ((void *) msg) + expected;
+  if ('\0' != str[(msize - expected) - 1])
+  {
+    GNUNET_break (0);
+    str = NULL;
+    return GNUNET_OK;
+  }
+  *termstr = GNUNET_strdup (str);
+  return GNUNET_OK;
+}
+
+
+/**
  * Callback that will be called when a child processes terminates.  The
  * associated client context for the client which requested this process will 
be
  * destroyed 
@@ -529,8 +625,7 @@
   struct ExecCtx *exec_ctx = cls;
   
   LOG_DEBUG ("Command `%s' exited.\n", exec_ctx->args[0]);
-  GNUNET_OS_process_destroy (exec_ctx->proc);
-  exec_ctx->proc = NULL;
+  exec_ctx->child_pid = 0;
   GNUNET_SCHEDULER_cancel (exec_ctx->fout_task);
   exec_ctx->fout_task = GNUNET_SCHEDULER_add_now (&read_fout, exec_ctx);
 }
@@ -547,32 +642,206 @@
 {
   struct GNUNET_DISK_PipeHandle *pin;
   struct GNUNET_DISK_PipeHandle *pout;
+  struct GNUNET_OS_Process *proc;
+  char *fnpty;
+  char *termstr;
+  struct winsize ws;
+  struct termios tio;
+  int ret;
+  int slave;
   
-  pin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_NO, 0, 0);
-  pout = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_YES, 0, 0);
-  GNUNET_assert ((NULL != pin && (NULL != pout)));
-  ctx->proc = GNUNET_OS_start_process_vap (GNUNET_NO,
-                                           GNUNET_OS_INHERIT_STD_NONE,
-                                           pin,
-                                           pout,
-                                           ctx->args[0],
-                                           ctx->args);
-  if (NULL == ctx->proc)
+  if (!ctx->interactive)
+  {
+    pin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_NO, 0, 0);
+    pout = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_YES, 0, 0);
+    GNUNET_assert ((NULL != pin && (NULL != pout)));
+    proc = GNUNET_OS_start_process_vap (GNUNET_NO,
+                                        GNUNET_OS_INHERIT_STD_NONE,
+                                        pin,
+                                        pout,
+                                        ctx->args[0],
+                                        ctx->args);
+    if (NULL == proc)
+      return GNUNET_SYSERR;
+    ctx->child_pid = GNUNET_OS_process_get_pid (proc);
+    GNUNET_OS_process_destroy (proc);
+    MSH_monitor_process_pid (ctx->child_pid, &proc_exit_cb, ctx);
+    ctx->fin = GNUNET_DISK_pipe_detach_end (pin, GNUNET_DISK_PIPE_END_WRITE);
+    ctx->fout = GNUNET_DISK_pipe_detach_end (pout, GNUNET_DISK_PIPE_END_READ);
+    GNUNET_assert ((NULL != ctx->fin && (NULL != ctx->fout)));
+    GNUNET_assert (GNUNET_OK == GNUNET_DISK_pipe_close (pin));
+    GNUNET_assert (GNUNET_OK == GNUNET_DISK_pipe_close (pout));
+    ctx->fout_task = 
+        GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
+                                        ctx->fout, &read_fout, ctx);
+    return GNUNET_OK;
+  }
+  if (NULL == (fnpty = ptsname (ctx->master)))
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "ptsname");
     return GNUNET_SYSERR;
-  MSH_monitor_process (ctx->proc, &proc_exit_cb, ctx);
-  ctx->fin = GNUNET_DISK_pipe_detach_end (pin, GNUNET_DISK_PIPE_END_WRITE);
-  ctx->fout = GNUNET_DISK_pipe_detach_end (pout, GNUNET_DISK_PIPE_END_READ);
-  GNUNET_assert ((NULL != ctx->fin && (NULL != ctx->fout)));
-  GNUNET_assert (GNUNET_OK == GNUNET_DISK_pipe_close (pin));
-  GNUNET_assert (GNUNET_OK == GNUNET_DISK_pipe_close (pout));
-  ctx->fout_task = 
-      GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
-                                      ctx->fout, &read_fout, ctx);
-  return GNUNET_OK;
+  }
+  ret = fork ();
+  if (-1 == ret)
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork");
+    return GNUNET_SYSERR;
+  }
+  if (0 != ret)
+  {
+    int fd;
+
+    LOG_DEBUG ("Forked child successfully\n");
+    ctx->child_pid = ret;
+    MSH_monitor_process_pid (ctx->child_pid, &proc_exit_cb, ctx);
+    /* forward streams to and from child */
+    ctx->fin = GNUNET_DISK_get_handle_from_int_fd (ctx->master);
+    fd = dup (ctx->master);
+    if (-1 == fd)
+    {
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "dup");
+      GNUNET_assert (0 == kill (ret, SIGTERM));
+      return GNUNET_SYSERR;
+    }
+    ctx->fout = GNUNET_DISK_get_handle_from_int_fd (fd);
+    ctx->fout_task =
+        GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 
ctx->fout,
+                                        &read_fout, ctx);
+
+    return GNUNET_OK;
+  }
+  close (ctx->master);
+  LOG_DEBUG ("Opening slave PTY %s\n", fnpty);
+  slave = open (fnpty, O_RDWR);
+  if (-1 == slave)
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "open");
+    _exit (1);
+  }
+  if (-1 == tcgetattr (slave, &tio))
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "tcgetattr");
+    _exit (1);
+  }
+  termstr = NULL;
+  parse_term_mode (ctx->pty_mode, &tio, &ws, &termstr);
+  GNUNET_free (ctx->pty_mode);
+  ctx->pty_mode = NULL;
+  if (NULL != termstr)
+  {
+    GNUNET_break (0 == setenv ("TERM", termstr, 1));
+    GNUNET_free (termstr);
+  }
+  else
+    GNUNET_break (0 == setenv ("TERM", "MSH", 1));
+  if (-1 == tcsetattr (slave, TCSANOW, &tio))
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "tcsetattr");
+    //_exit (1);                /* Ignore for now */
+  }
+  if (-1 == ioctl (slave, TIOCSWINSZ, &ws))
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "ioctl");
+    _exit (1);
+  }
+  if (-1 == setsid ())
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "setsid");
+    _exit (1);
+  }
+  close (0);
+  close (1);
+  //close (2);
+  if ( (-1 == dup2 (slave, 0)) ||
+       (-1 == dup2 (slave, 1)) ) //||
+    //(-1 == dup2 (slave, 2)) )
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "dup");
+    _exit (2);
+  }
+  close (slave);
+  LOG_DEBUG ("Execing %s\n", ctx->args[0]);
+  if (-1 == execvp (ctx->args[0], ctx->args))
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "execvp");
+    _exit (1);
+  }
+  GNUNET_assert (0);            /* This should never be reached */
 }
 
 
 /**
+ * Handle session open message and start challenge authentication.
+ *
+ * @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)
+{
+  const struct MSH_MSG_RunCmd *msg;
+  struct ExecCtx *exec_ctx;
+  struct GNUNET_MessageHeader *reply;
+  uint16_t size;
+  
+  LOG_DEBUG ("Received a RUN_CMD message\n");
+  exec_ctx = GNUNET_SERVER_client_get_user_context (client, struct ExecCtx);
+  GNUNET_assert (NULL != exec_ctx);
+  if (GNUNET_YES != exec_ctx->authenticated)
+  {
+    GNUNET_break_op (0);
+    goto close_conn;
+  }
+  if (exec_ctx->interactive && !exec_ctx->pty_created)
+  {
+    GNUNET_break_op (0);
+    goto close_conn;
+  }
+  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;
+  if (0 == parse_strings (msg->cmd,
+                          size - sizeof (struct MSH_MSG_RunCmd),
+                          &exec_ctx->args))
+  {
+    GNUNET_break_op (0);
+    goto close_conn;
+  }
+  GNUNET_SCHEDULER_cancel (exec_ctx->timeout_task);
+  exec_ctx->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+  if (GNUNET_OK != proc_exec (exec_ctx))
+  {
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+         "Command `%s' not found or not executable\n", exec_ctx->args[0]);
+    goto close_conn;
+  }
+  reply = GNUNET_malloc (sizeof (struct GNUNET_MessageHeader));
+  reply->size = htons (sizeof (struct GNUNET_MessageHeader));
+  reply->type = htons (MSH_MTYPE_EXEC_BEGIN);
+  GNUNET_SERVER_notification_context_unicast (daemon_serv_nc, exec_ctx->client,
+                                              reply, GNUNET_NO);
+  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  return;
+  
+ close_conn:
+  GNUNET_break_op (0);
+  GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+}
+
+
+/**
  * Functions with this signature are called whenever a message is
  * received.
  *
@@ -605,20 +874,7 @@
     GNUNET_break (0);
     goto err_ret;
   }
-  GNUNET_SCHEDULER_cancel (exec_ctx->timeout_task);
-  exec_ctx->timeout_task = GNUNET_SCHEDULER_NO_TASK;
-  if (GNUNET_OK != proc_exec (exec_ctx))
-  {
-    LOG (GNUNET_ERROR_TYPE_WARNING,
-         "Command `%s' not found or not executable\n", exec_ctx->args[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);
-  GNUNET_SERVER_notification_context_unicast (daemon_serv_nc, exec_ctx->client,
-                                              reply, GNUNET_NO);
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  exec_ctx->authenticated = GNUNET_YES;
   return;
   
  err_ret:
@@ -730,6 +986,70 @@
 
 
 /**
+ * Handler for messages containing the settings to be used while creating a
+ * psuedo-tty.  This message must only be received for interactive sessions
+ * before #MSH_MSG_RunCmd message is received.
+ *
+ * @param cls NULL
+ * @param client identification of the client
+ * @param message the actual message
+ */
+static void
+handle_pty_mode (void *cls,
+                 struct GNUNET_SERVER_Client *client,
+                 const struct GNUNET_MessageHeader* message)
+{
+  struct winsize ws;
+  struct termios tio;
+  const struct MSH_MSG_PtyMode *msg;
+  uint16_t *params;
+  char *termstr;
+  struct ExecCtx *exec_ctx;
+  size_t expected;
+  speed_t ospeed;
+  speed_t ispeed;
+  int master;
+  unsigned int cnt;
+  unsigned int ns;
+  uint16_t size;
+
+  size = ntohs (message->size);
+  if (size <= sizeof (struct MSH_MSG_PtyMode))
+  {
+    GNUNET_break (0);
+    goto close_conn;
+  }
+  exec_ctx = GNUNET_SERVER_client_get_user_context (client, struct ExecCtx);
+  GNUNET_assert (NULL != exec_ctx);
+  msg = (const struct MSH_MSG_PtyMode *) message;
+  master = posix_openpt (O_RDWR);
+  if (-1 == master)
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "posix_openpt");
+    goto close_conn;
+  }
+  if (-1 == grantpt (master))
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "grantpt");
+    goto close_conn;
+  }
+  if (-1 == unlockpt (master))
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "unlockpt");
+    goto close_conn;
+  }
+  exec_ctx->master = master;
+  exec_ctx->pty_created = GNUNET_YES;
+  exec_ctx->pty_mode = (struct MSH_MSG_PtyMode *) GNUNET_copy_message 
(message);
+  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  return;
+  
+ close_conn:
+  GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+}
+
+
+/**
  * Callback to be called when ever a client connects to the daemon server
  *
  * @param cls NULL
@@ -758,10 +1078,13 @@
 init_daemon_server ()
 {
   static const struct GNUNET_SERVER_MessageHandler handlers[] = {
+    {&handle_session_open, NULL, MSH_MTYPE_SESSION_OPEN,
+     sizeof (struct MSH_MSG_SessionOpen)}, 
     {&handle_runcmd, NULL, MSH_MTYPE_RUNCMD, 0},
     {&handle_auth_challenge_response, NULL, MSH_MTYPE_CHALLENGE_RESPONSE, 
      sizeof (struct MSH_MSG_ChallengeResponse)},
     {&handle_command_input, NULL, MSH_MTYPE_CMD_STREAM_STDIN, 0},
+    {&handle_pty_mode, NULL, MSH_MTYPE_PTY_MODE, 0},
     {NULL, NULL, 0, 0}
   };
   
@@ -803,7 +1126,7 @@
  */
 void
 daemon_server_add_connection (struct GNUNET_CONNECTION_Handle *conn)
-{  
+{
   struct ExecCtx *exec_ctx;
   struct GNUNET_SERVER_Client *client;
 

Modified: msh/src/mshd2.c
===================================================================
--- msh/src/mshd2.c     2013-11-20 09:56:22 UTC (rev 30821)
+++ msh/src/mshd2.c     2013-11-20 10:18:26 UTC (rev 30822)
@@ -510,7 +510,7 @@
     GNUNET_CONTAINER_DLL_insert_tail (rhead, rtail, rctx);    
     break;
   case MODE_SERV:
-    pid = spawn_worker (NULL);
+    pid = spawn_worker (1);
     if (-1 == pid)
     {
       GNUNET_break (0);
@@ -544,7 +544,6 @@
 static void
 poll_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
-  MPI_Status status;
   int flag;
 
   poll_shutdown_task = GNUNET_SCHEDULER_NO_TASK;
@@ -961,17 +960,30 @@
     up %= nproc;
     source = status.MPI_SOURCE;
     if (lb == up) 
+    {
       if (source != lb)
       {
         GNUNET_break (0);
         LOG_ERROR ("%d: Error: source %d; lb: %d; up: %d\n", rank, source, lb, 
up);
         goto err_ret;
       }
-    else if ((source > up) || (source < lb))
+    }
+    else if(lb < up)
     {
-      GNUNET_break (0);
-      goto err_ret;
+      if ((source < lb) || (source > up))
+      {
+        GNUNET_break (0);
+        goto err_ret;
+      }
     }
+    else if (up < lb)
+    {
+      if ((source > up) && (source < lb))
+      {
+        GNUNET_break (0);
+        goto err_ret;
+      }
+    }
     msg = GNUNET_malloc (rsize);
     if (MPI_SUCCESS != MPI_Recv (msg, rsize, MPI_BYTE, source,
                                  MSH_MTYPE_VERIFY_ADDRESSES, MPI_COMM_WORLD,
@@ -1173,7 +1185,6 @@
 run (void *cls, char *const *args, const char *cfgfile,
      const struct GNUNET_CONFIGURATION_Handle *cfg)
 {
-  const struct GNUNET_DISK_FileHandle *fh;
   struct sockaddr_in addr;
   socklen_t addrlen;
   unsigned int cnt;
@@ -1245,7 +1256,6 @@
     GNUNET_GETOPT_OPTION_END
   };
   int ret;
-  int c;
 
   ret = 1;
   rwidth = 1;

Modified: msh/src/mtypes.h
===================================================================
--- msh/src/mtypes.h    2013-11-20 09:56:22 UTC (rev 30821)
+++ msh/src/mtypes.h    2013-11-20 10:18:26 UTC (rev 30822)
@@ -133,13 +133,48 @@
 
 #define MSH_MTYPE_EXEC_BEGIN 208
 
+#define MSH_MTYPE_SESSION_OPEN 209
+
+
 /***********************/
 /* MSH waiter messages */
 /***********************/
 
 #define MSH_MTYPE_PTY_MODE 300
 
+
+/*********************/
+/* MSH Session types */
+/*********************/
+
 /**
+ * Non interactive session; a pseudo-tty is not created at the server-side
+ */
+#define MSH_SESSION_TYPE_NONINTERACTIVE 0
+
+/**
+ * Interactive session; a pseudo-tty is created at the server-side
+ */
+#define MSH_SESSION_TYPE_INTERACTIVE 1
+
+/**
+ * Message for opening a session
+ */
+struct MSH_MSG_SessionOpen
+{
+  /**
+   * header; set type to MSH_MTYPE_SESSION_OPEN
+   */
+  struct GNUNET_MessageHeader header;
+  
+  /**
+   * Type of the session; Must be one of the MSH_MTYPE_SESSION_TYPE_*
+   */
+  uint32_t type GNUNET_PACKED;
+};
+
+
+/**
  * Message for sending a remote command and its arguments to MSHD
  */
 struct MSH_MSG_RunCmd




reply via email to

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