[PATCH 6/6] telnetd: Remove CONFIGURE_MAXIMUM_PTYS

Sebastian Huber sebastian.huber at embedded-brains.de
Wed Sep 26 08:30:48 UTC 2018


Add a rtems_telnetd_config_table::client_maximum member to the Telnet
configuration.

Close #3528.
---
 cpukit/include/rtems/confdefs.h |  22 ++------
 cpukit/include/rtems/telnetd.h  |   8 +++
 cpukit/telnetd/telnetd.c        | 111 +++++++++++++++++++++++-----------------
 3 files changed, 75 insertions(+), 66 deletions(-)

diff --git a/cpukit/include/rtems/confdefs.h b/cpukit/include/rtems/confdefs.h
index 763f54bca5..f59e0f7068 100644
--- a/cpukit/include/rtems/confdefs.h
+++ b/cpukit/include/rtems/confdefs.h
@@ -155,24 +155,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
   const uint32_t rtems_libio_number_iops = RTEMS_ARRAY_SIZE(rtems_libio_iops);
 #endif
 
-/**
- * This macro specifies the number of PTYs that can be concurrently
- * active.
- */
-#ifndef CONFIGURE_MAXIMUM_PTYS
-  #define CONFIGURE_MAXIMUM_PTYS 0
-#endif
-
-/**
- * This variable contains the maximum number of PTYs that can be
- * concurrently active.
- */
-#ifdef CONFIGURE_INIT
-  int rtems_telnetd_maximum_ptys = CONFIGURE_MAXIMUM_PTYS;
-#else
-  extern int rtems_telnetd_maximum_ptys;
-#endif
-
 #ifdef CONFIGURE_SMP_MAXIMUM_PROCESSORS
   #warning "CONFIGURE_SMP_MAXIMUM_PROCESSORS has been renamed to CONFIGURE_MAXIMUM_PROCESSORS since RTEMS 5.1"
   #define CONFIGURE_MAXIMUM_PROCESSORS CONFIGURE_SMP_MAXIMUM_PROCESSORS
@@ -3474,6 +3456,10 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
   #warning "The CONFIGURE_MAXIMUM_POSIX_SPINLOCKS configuration option is obsolete since RTEMS 5.1"
 #endif
 
+#ifdef CONFIGURE_MAXIMUM_PTYS
+  #warning "The CONFIGURE_MAXIMUM_PTYS configuration option is obsolete since RTEMS 5.1"
+#endif
+
 #ifdef CONFIGURE_TERMIOS_DISABLED
   #warning "The CONFIGURE_TERMIOS_DISABLED configuration option is obsolete since RTEMS 5.1"
 #endif
diff --git a/cpukit/include/rtems/telnetd.h b/cpukit/include/rtems/telnetd.h
index 19512fbe9c..2339bad8b6 100644
--- a/cpukit/include/rtems/telnetd.h
+++ b/cpukit/include/rtems/telnetd.h
@@ -85,6 +85,14 @@ typedef struct {
    * create other tasks for the shell which listen on sockets.
    */
   bool keep_stdio;
+
+  /**
+   * @brief Maximum number of clients which can connect to the system at a
+   * time.
+   *
+   * Use 0 for the default value.
+   */
+  uint16_t client_maximum;
 } rtems_telnetd_config_table;
 
 /**
diff --git a/cpukit/telnetd/telnetd.c b/cpukit/telnetd/telnetd.c
index 1b0631e3a6..60eb1d075f 100644
--- a/cpukit/telnetd/telnetd.c
+++ b/cpukit/telnetd/telnetd.c
@@ -62,11 +62,17 @@
 
 #define PARANOIA
 
+typedef struct telnetd_context telnetd_context;
+
 struct shell_args {
   rtems_pty_context  pty;
-  void              *arg;
   char               peername[16];
-  char               delete_myself;
+  telnetd_context   *ctx;
+};
+
+struct telnetd_context {
+  rtems_telnetd_config_table config;
+  uint16_t                   active_clients;
 };
 
 typedef union uni_sa {
@@ -85,7 +91,7 @@ rtems_id telnetd_dflt_spawn(
 );
 
 /***********************************************************/
-static rtems_telnetd_config_table *telnetd_config;
+static telnetd_context telnetd_instance;
 
 /*
  * chrisj: this variable was global and with no declared interface in a header
@@ -102,33 +108,39 @@ static const rtems_id (*telnetd_spawn_task)(
 ) = telnetd_dflt_spawn;
 
 static struct shell_args *grab_a_Connection(
+  telnetd_context *ctx,
   int des_socket,
   uni_sa *srv,
   char *peername,
   int sz
 )
 {
-  struct shell_args *args = NULL;
+  struct shell_args *args;
   socklen_t size_adr = sizeof(srv->sin);
   int acp_sock;
 
+  if (ctx->active_clients >= ctx->config.client_maximum) {
+    return NULL;
+  }
+
   args = malloc(sizeof(*args));
   if (args == NULL) {
     perror("telnetd:malloc");
-    goto bailout;
+    return NULL;
   }
 
   acp_sock = accept(des_socket,&srv->sa,&size_adr);
-
   if (acp_sock<0) {
     perror("telnetd:accept");
-    goto bailout;
+    free(args);
+    return NULL;
   };
 
   if (telnet_get_pty(&args->pty, acp_sock) == NULL) {
     syslog( LOG_DAEMON | LOG_ERR, "telnetd: unable to obtain PTY");
     /* NOTE: failing 'do_get_pty()' closed the socket */
-    goto bailout;
+    free(args);
+    return NULL;
   }
 
   if (sockpeername(acp_sock, peername, sz))
@@ -141,13 +153,14 @@ static struct shell_args *grab_a_Connection(
       args->pty.name);
 #endif
 
-bailout:
-
+  ++ctx->active_clients;
+  args->ctx = ctx;
   return args;
 }
 
 
-static void release_a_Connection(char *devname, char *peername, FILE **pstd, int n)
+static void release_a_Connection(telnetd_context *ctx, const char *devname,
+  const char *peername, FILE **pstd, int n)
 {
 
 #ifdef PARANOIA
@@ -157,6 +170,8 @@ static void release_a_Connection(char *devname, char *peername, FILE **pstd, int
       devname );
 #endif
 
+  --ctx->active_clients;
+
   while (--n>=0)
     if (pstd[n]) fclose(pstd[n]);
 
@@ -192,6 +207,7 @@ rtems_task_telnetd(void *task_argument)
   int                size_adr;
   struct shell_args *arg = NULL;
   rtems_id           task_id;
+  telnetd_context   *ctx = task_argument;
 
   if ((des_socket=socket(PF_INET,SOCK_STREAM,0))<0) {
     perror("telnetd:socket");
@@ -218,21 +234,21 @@ rtems_task_telnetd(void *task_argument)
    * was started from the console anyway ..
    */
   do {
-    if (telnetd_config->keep_stdio) {
+    if (ctx->config.keep_stdio) {
       bool start = true;
       char device_name [32];
 
       ttyname_r( 1, device_name, sizeof( device_name));
-      if (telnetd_config->login_check != NULL) {
+      if (ctx->config.login_check != NULL) {
         start = rtems_shell_login_prompt(
           stdin,
           stderr,
           device_name,
-          telnetd_config->login_check
+          ctx->config.login_check
         );
       }
       if (start) {
-        telnetd_config->command( device_name, arg->arg);
+        ctx->config.command( device_name, ctx->config.arg);
       } else {
         syslog(
           LOG_AUTHPRIV | LOG_WARNING,
@@ -241,7 +257,8 @@ rtems_task_telnetd(void *task_argument)
         );
       }
     } else {
-      arg = grab_a_Connection(des_socket, &srv, peername, sizeof(peername));
+      arg = grab_a_Connection(ctx, des_socket, &srv, peername,
+        sizeof(peername));
 
       if (arg == NULL) {
         /* if something went wrong, sleep for some time */
@@ -249,13 +266,12 @@ rtems_task_telnetd(void *task_argument)
         continue;
       }
 
-      arg->arg = telnetd_config->arg;
       strncpy(arg->peername, peername, sizeof(arg->peername));
 
       task_id = telnetd_spawn_task(
         arg->pty.name,
-        telnetd_config->priority,
-        telnetd_config->stack_size,
+        ctx->config.priority,
+        ctx->config.stack_size,
         spawned_shell,
         arg
       );
@@ -275,7 +291,7 @@ rtems_task_telnetd(void *task_argument)
 
         if ( !(dummy=fopen(arg->pty.name,"r+")) )
           perror("Unable to dummy open the pty, losing a slot :-(");
-        release_a_Connection(arg->pty.name, peername, &dummy, 1);
+        release_a_Connection(ctx, arg->pty.name, peername, &dummy, 1);
         free(arg);
         sleep(2); /* don't accept connections too fast */
       }
@@ -293,62 +309,60 @@ rtems_task_telnetd(void *task_argument)
 
 rtems_status_code rtems_telnetd_start(const rtems_telnetd_config_table* config)
 {
+  telnetd_context *ctx = &telnetd_instance;
   rtems_id task_id;
 
-  if (telnetd_config != NULL) {
-    fprintf(stderr, "telnetd already started\n");
-    return RTEMS_RESOURCE_IN_USE;
-  }
-
   if (config->command == NULL) {
     fprintf(stderr, "telnetd setup with invalid command\n");
     return RTEMS_IO_ERROR;
   }
 
-  telnetd_config = calloc(1, sizeof(*telnetd_config));
-  if (telnetd_config == NULL) {
-    fprintf(stderr, "telnetd cannot alloc telnetd config table\n");
-    return RTEMS_NO_MEMORY;
+  if (ctx->config.command != NULL) {
+    fprintf(stderr, "telnetd already started\n");
+    return RTEMS_RESOURCE_IN_USE;
   }
 
-  *telnetd_config = *config;
+  ctx->config = *config;
 
   /* Check priority */
 #ifdef RTEMS_NETWORKING
-  if (telnetd_config->priority <= 0) {
-    telnetd_config->priority = rtems_bsdnet_config.network_task_priority;
+  if (ctx->config.priority <= 0) {
+    ctx->config.priority = rtems_bsdnet_config.network_task_priority;
   }
 #endif
-  if (telnetd_config->priority < 2) {
-    telnetd_config->priority = 100;
+  if (ctx->config.priority < 2) {
+    ctx->config.priority = 100;
   }
 
   /* Check stack size */
-  if (telnetd_config->stack_size <= 0) {
-    telnetd_config->stack_size = (size_t)32 * 1024;
+  if (ctx->config.stack_size <= 0) {
+    ctx->config.stack_size = (size_t)32 * 1024;
+  }
+
+  if (ctx->config.client_maximum == 0) {
+    ctx->config.client_maximum = 5;
   }
 
   /* Spawn task */
   task_id = telnetd_spawn_task(
     "TNTD",
-    telnetd_config->priority,
-    telnetd_config->stack_size,
+    ctx->config.priority,
+    ctx->config.stack_size,
     rtems_task_telnetd,
-    0
+    ctx
   );
   if (task_id == RTEMS_ID_NONE) {
-    free(telnetd_config);
-    telnetd_config = NULL;
+    ctx->config.command = NULL;
     return RTEMS_IO_ERROR;
   }
 
   /* Print status */
-  if (!telnetd_config->keep_stdio) {
+  if (!ctx->config.keep_stdio) {
     fprintf(
       stderr,
       "telnetd started with stacksize = %u and priority = %d\n",
-      (unsigned) telnetd_config->stack_size,
-      (unsigned) telnetd_config->priority
+      (unsigned) ctx->config.stack_size,
+      (unsigned) ctx->config.priority
     );
   }
 
@@ -364,6 +378,7 @@ spawned_shell(void *targ)
   FILE                *ostd[3]={ stdin, stdout, stderr };
   int                  i=0;
   struct shell_args  *arg = targ;
+  telnetd_context    *ctx = arg->ctx;
   bool login_failed = false;
   bool start = true;
 
@@ -395,17 +410,17 @@ spawned_shell(void *targ)
   stderr = nstd[2];
 
   /* call their routine */
-  if (telnetd_config->login_check != NULL) {
+  if (ctx->config.login_check != NULL) {
     start = rtems_shell_login_prompt(
       stdin,
       stderr,
       arg->pty.name,
-      telnetd_config->login_check
+      ctx->config.login_check
     );
     login_failed = !start;
   }
   if (start) {
-    telnetd_config->command( arg->pty.name, arg->arg);
+    ctx->config.command( arg->pty.name, ctx->config.arg);
   }
 
   stdin  = ostd[0];
@@ -421,7 +436,7 @@ spawned_shell(void *targ)
   }
 
 cleanup:
-  release_a_Connection(arg->pty.name, arg->peername, nstd, i);
+  release_a_Connection(ctx, arg->pty.name, arg->peername, nstd, i);
   free(arg);
 }
 
-- 
2.16.4




More information about the devel mailing list