summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cpukit/include/rtems/telnetd.h23
-rw-r--r--cpukit/telnetd/telnetd.c112
-rw-r--r--testsuites/libtests/Makefile.am12
-rw-r--r--testsuites/libtests/configure.ac1
-rw-r--r--testsuites/libtests/telnetd01/init.c118
-rw-r--r--testsuites/libtests/telnetd01/telnetd01.doc24
-rw-r--r--testsuites/libtests/telnetd01/telnetd01.scn12
7 files changed, 222 insertions, 80 deletions
diff --git a/cpukit/include/rtems/telnetd.h b/cpukit/include/rtems/telnetd.h
index 2339bad8b6..e662874a81 100644
--- a/cpukit/include/rtems/telnetd.h
+++ b/cpukit/include/rtems/telnetd.h
@@ -59,13 +59,14 @@ typedef struct {
/**
* @brief Task priority.
*
- * If this parameter is equal to zero, then the priority of network task is
- * used or 100 if this priority is less than two.
+ * Use 0 for the default value.
*/
rtems_task_priority priority;
/**
* @brief Task stack size.
+ *
+ * Use 0 for the default value.
*/
size_t stack_size;
@@ -77,12 +78,10 @@ typedef struct {
rtems_shell_login_check_t login_check;
/**
- * @brief Keep standard IO of the caller.
+ * @brief This is an obsolete configuration option.
*
- * Telnet takes over the standard input, output and error associated with
- * task, if this parameter is set to @c true. In this case, it will @b not
- * listen on any sockets. When this parameter is @c false, Telnet will
- * create other tasks for the shell which listen on sockets.
+ * It must be set to false, otherwise rtems_telnetd_start() will do nothing
+ * and returns with a status of RTEMS_NOT_IMPLEMENTED.
*/
bool keep_stdio;
@@ -96,7 +95,15 @@ typedef struct {
} rtems_telnetd_config_table;
/**
- * @brief Start the Telnet subsystem with the provided configuration.
+ * @brief Starts the Telnet server using the provided configuration.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ADDRESS The command function in the configuration is
+ * @c NULL.
+ * @retval RTEMS_RESOURCE_IN_USE The Telnet server was already started.
+ * @retval RTEMS_NOT_IMPLEMENTED The keep stdio configuration option is true.
+ * @retval RTEMS_UNSATISFIED Not enough resources to start the Telnet server or
+ * task priority in configuration is invalid.
*/
rtems_status_code rtems_telnetd_start(const rtems_telnetd_config_table *config);
diff --git a/cpukit/telnetd/telnetd.c b/cpukit/telnetd/telnetd.c
index 650b0f9418..56e48b9d78 100644
--- a/cpukit/telnetd/telnetd.c
+++ b/cpukit/telnetd/telnetd.c
@@ -234,67 +234,43 @@ rtems_task_telnetd(void *task_argument)
* was started from the console anyway ..
*/
do {
- if (ctx->config.keep_stdio) {
- bool start = true;
- char device_name [32];
-
- ttyname_r( 1, device_name, sizeof( device_name));
- if (ctx->config.login_check != NULL) {
- start = rtems_shell_login_prompt(
- stdin,
- stderr,
- device_name,
- ctx->config.login_check
- );
- }
- if (start) {
- ctx->config.command( device_name, ctx->config.arg);
- } else {
- syslog(
- LOG_AUTHPRIV | LOG_WARNING,
- "telnetd: to many wrong passwords entered from %s",
- device_name
- );
- }
- } else {
- arg = grab_a_Connection(ctx, des_socket, &srv, peername,
- sizeof(peername));
-
- if (arg == NULL) {
- /* if something went wrong, sleep for some time */
- sleep(10);
- continue;
- }
+ arg = grab_a_Connection(ctx, des_socket, &srv, peername,
+ sizeof(peername));
- strncpy(arg->peername, peername, sizeof(arg->peername));
-
- task_id = telnetd_spawn_task(
- arg->pty.name,
- ctx->config.priority,
- ctx->config.stack_size,
- spawned_shell,
- arg
- );
- if (task_id == RTEMS_ID_NONE) {
- FILE *dummy;
-
- if ( telnetd_spawn_task != telnetd_dflt_spawn ) {
- fprintf(stderr,"Telnetd: Unable to spawn child task\n");
- }
-
- /* hmm - the pty driver slot can only be
- * released by opening and subsequently
- * closing the PTY - this also closes
- * the underlying socket. So we mock up
- * a stream...
- */
+ if (arg == NULL) {
+ /* if something went wrong, sleep for some time */
+ sleep(10);
+ continue;
+ }
+
+ strncpy(arg->peername, peername, sizeof(arg->peername));
+
+ task_id = telnetd_spawn_task(
+ arg->pty.name,
+ ctx->config.priority,
+ ctx->config.stack_size,
+ spawned_shell,
+ arg
+ );
+ if (task_id == RTEMS_ID_NONE) {
+ FILE *dummy;
- if ( !(dummy=fopen(arg->pty.name,"r+")) )
- perror("Unable to dummy open the pty, losing a slot :-(");
- release_a_Connection(ctx, arg->pty.name, peername, &dummy, 1);
- free(arg);
- sleep(2); /* don't accept connections too fast */
+ if ( telnetd_spawn_task != telnetd_dflt_spawn ) {
+ fprintf(stderr,"Telnetd: Unable to spawn child task\n");
}
+
+ /* hmm - the pty driver slot can only be
+ * released by opening and subsequently
+ * closing the PTY - this also closes
+ * the underlying socket. So we mock up
+ * a stream...
+ */
+
+ if ( !(dummy=fopen(arg->pty.name,"r+")) )
+ perror("Unable to dummy open the pty, losing a slot :-(");
+ release_a_Connection(ctx, arg->pty.name, peername, &dummy, 1);
+ free(arg);
+ sleep(2); /* don't accept connections too fast */
}
} while(1);
@@ -313,12 +289,12 @@ rtems_status_code rtems_telnetd_start(const rtems_telnetd_config_table* config)
rtems_id task_id;
if (config->command == NULL) {
- fprintf(stderr, "telnetd setup with invalid command\n");
- return RTEMS_IO_ERROR;
+ syslog(LOG_DAEMON | LOG_ERR, "telnetd: configuration with invalid command");
+ return RTEMS_INVALID_ADDRESS;
}
if (ctx->config.command != NULL) {
- fprintf(stderr, "telnetd already started\n");
+ syslog(LOG_DAEMON | LOG_ERR, "telnetd: already started");
return RTEMS_RESOURCE_IN_USE;
}
@@ -353,19 +329,11 @@ rtems_status_code rtems_telnetd_start(const rtems_telnetd_config_table* config)
);
if (task_id == RTEMS_ID_NONE) {
ctx->config.command = NULL;
- return RTEMS_IO_ERROR;
- }
-
- /* Print status */
- if (!ctx->config.keep_stdio) {
- fprintf(
- stderr,
- "telnetd started with stacksize = %u and priority = %d\n",
- (unsigned) ctx->config.stack_size,
- (unsigned) ctx->config.priority
- );
+ syslog(LOG_DAEMON | LOG_ERR, "telnetd: cannot create server task");
+ return RTEMS_UNSATISFIED;
}
+ syslog(LOG_DAEMON | LOG_INFO, "telnetd: started successfully");
return RTEMS_SUCCESSFUL;
}
diff --git a/testsuites/libtests/Makefile.am b/testsuites/libtests/Makefile.am
index 52bbc3e3fb..240b04c74c 100644
--- a/testsuites/libtests/Makefile.am
+++ b/testsuites/libtests/Makefile.am
@@ -1134,6 +1134,18 @@ tar03_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_tar03) \
$(support_includes)
endif
+if NETTESTS
+if TEST_telnetd01
+lib_tests += telnetd01
+lib_screens += telnetd01/telnetd01.scn
+lib_docs += telnetd01/telnetd01.doc
+telnetd01_SOURCES = telnetd01/init.c
+telnetd01_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_telnetd01) \
+ $(support_includes) -I$(RTEMS_SOURCE_ROOT)/cpukit/libnetworking
+telnetd01_LDADD = $(RTEMS_ROOT)cpukit/libtelnetd.a $(LDADD)
+endif
+endif
+
if TEST_termios
lib_tests += termios
termios_SOURCES = termios/init.c
diff --git a/testsuites/libtests/configure.ac b/testsuites/libtests/configure.ac
index c529b27660..303a165731 100644
--- a/testsuites/libtests/configure.ac
+++ b/testsuites/libtests/configure.ac
@@ -208,6 +208,7 @@ RTEMS_TEST_CHECK([syscall01])
RTEMS_TEST_CHECK([tar01])
RTEMS_TEST_CHECK([tar02])
RTEMS_TEST_CHECK([tar03])
+RTEMS_TEST_CHECK([telnetd01])
RTEMS_TEST_CHECK([termios])
RTEMS_TEST_CHECK([termios01])
RTEMS_TEST_CHECK([termios02])
diff --git a/testsuites/libtests/telnetd01/init.c b/testsuites/libtests/telnetd01/init.c
new file mode 100644
index 0000000000..f2243d9dd8
--- /dev/null
+++ b/testsuites/libtests/telnetd01/init.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2018 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include <rtems.h>
+#include <rtems/rtems_bsdnet.h>
+#include <rtems/telnetd.h>
+
+#include <tmacros.h>
+
+const char rtems_test_name[] = "TELNETD 1";
+
+struct rtems_bsdnet_config rtems_bsdnet_config;
+
+static void command(char *device_name, void *arg)
+{
+}
+
+static void test_command_null(void)
+{
+ static const rtems_telnetd_config_table config = {
+ .command = NULL
+ };
+ rtems_status_code sc;
+
+ sc = rtems_telnetd_start(&config);
+ rtems_test_assert(sc == RTEMS_INVALID_ADDRESS);
+}
+
+static void test_cannot_start_server_task(void)
+{
+ static const rtems_telnetd_config_table config = {
+ .command = command,
+ .priority = UINT32_MAX
+ };
+ rtems_status_code sc;
+
+ sc = rtems_telnetd_start(&config);
+ rtems_test_assert(sc == RTEMS_UNSATISFIED);
+}
+
+static void test_successful_start(void)
+{
+ static const rtems_telnetd_config_table config = {
+ .command = command,
+ .stack_size = RTEMS_MINIMUM_STACK_SIZE
+ };
+ rtems_status_code sc;
+
+ sc = rtems_telnetd_start(&config);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void test_already_started(void)
+{
+ static const rtems_telnetd_config_table config = {
+ .command = command
+ };
+ rtems_status_code sc;
+
+ sc = rtems_telnetd_start(&config);
+ rtems_test_assert(sc == RTEMS_RESOURCE_IN_USE);
+}
+
+static rtems_task Init(rtems_task_argument argument)
+{
+ int rv;
+
+ TEST_BEGIN();
+
+ rv = rtems_bsdnet_initialize_network();
+ rtems_test_assert(rv == 0);
+
+ test_command_null();
+ test_cannot_start_server_task();
+ test_successful_start();
+ test_already_started();
+
+ TEST_END();
+ rtems_test_exit(0);
+}
+
+#define CONFIGURE_INIT
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 10000
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
+
+#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32
+
+#define CONFIGURE_MAXIMUM_TASKS 7
+
+#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/libtests/telnetd01/telnetd01.doc b/testsuites/libtests/telnetd01/telnetd01.doc
new file mode 100644
index 0000000000..fe1a4d31a3
--- /dev/null
+++ b/testsuites/libtests/telnetd01/telnetd01.doc
@@ -0,0 +1,24 @@
+#
+# Copyright (c) 2018 embedded brains GmbH. All rights reserved.
+#
+# embedded brains GmbH
+# Dornierstr. 4
+# 82178 Puchheim
+# Germany
+# <rtems@embedded-brains.de>
+#
+# The license and distribution terms for this file may be
+# found in the file LICENSE in this distribution or at
+# http://www.rtems.org/license/LICENSE.
+
+This file describes the directives and concepts tested by this test set.
+
+test set name: telnetd01
+
+directives:
+
+ - rtems_telnetd_start()
+
+concepts:
+
++ Check if Telnet server works.
diff --git a/testsuites/libtests/telnetd01/telnetd01.scn b/testsuites/libtests/telnetd01/telnetd01.scn
new file mode 100644
index 0000000000..2dc2c60846
--- /dev/null
+++ b/testsuites/libtests/telnetd01/telnetd01.scn
@@ -0,0 +1,12 @@
+*** BEGIN OF TEST TELNETD 1 ***
+*** TEST VERSION: 5.0.0.dc32b6aa0807fb70f9b26bc0bc6e164ddb49bd3a
+*** TEST STATE: EXPECTED-PASS
+*** TEST BUILD: RTEMS_NETWORKING
+*** TEST TOOLS: 7.3.0 20180125 (RTEMS 5, RSB 9670d7541e0621915e521fe76e7bb33de8cee661, Newlib d13c84eb07e35984bf7a974cd786a6cdac29e6b9)
+syslog: telnetd: configuration with invalid command
+Telnetd: spawning task failed (status: RTEMS_INVALID_PRIORITY)
+syslog: telnetd: cannot create server task
+syslog: telnetd: started successfully
+syslog: telnetd: already started
+
+*** END OF TEST TELNETD 1 ***