diff options
-rw-r--r-- | cpukit/include/rtems/telnetd.h | 23 | ||||
-rw-r--r-- | cpukit/telnetd/telnetd.c | 112 | ||||
-rw-r--r-- | testsuites/libtests/Makefile.am | 12 | ||||
-rw-r--r-- | testsuites/libtests/configure.ac | 1 | ||||
-rw-r--r-- | testsuites/libtests/telnetd01/init.c | 118 | ||||
-rw-r--r-- | testsuites/libtests/telnetd01/telnetd01.doc | 24 | ||||
-rw-r--r-- | testsuites/libtests/telnetd01/telnetd01.scn | 12 |
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 *** |