telnetd: Always build telnet daemon

Add support for libbsd initialization.

Update #3419.
This commit is contained in:
Sebastian Huber
2018-04-30 10:54:50 +02:00
parent b771cb48a6
commit b80b34c38d
4 changed files with 76 additions and 31 deletions

View File

@@ -87,6 +87,11 @@ typedef struct {
bool keep_stdio; bool keep_stdio;
} rtems_telnetd_config_table; } rtems_telnetd_config_table;
/**
* @brief Start the Telnet subsystem with the provided configuration.
*/
rtems_status_code rtems_telnetd_start(const rtems_telnetd_config_table *config);
/** /**
* @brief Telnet configuration. * @brief Telnet configuration.
* *

View File

@@ -1,6 +1,5 @@
include $(top_srcdir)/automake/compile.am include $(top_srcdir)/automake/compile.am
if LIBNETWORKING
if LIBSHELL if LIBSHELL
project_lib_LIBRARIES = libtelnetd.a project_lib_LIBRARIES = libtelnetd.a
@@ -8,10 +7,8 @@ $(PROJECT_LIB)/libtelnetd.a: libtelnetd.a
$(INSTALL_DATA) $< $(PROJECT_LIB)/libtelnetd.a $(INSTALL_DATA) $< $(PROJECT_LIB)/libtelnetd.a
TMPINSTALL_FILES = $(PROJECT_LIB)/libtelnetd.a TMPINSTALL_FILES = $(PROJECT_LIB)/libtelnetd.a
libtelnetd_a_SOURCES = check_passwd.c des.c pty.c telnetd.c libtelnetd_a_SOURCES = check_passwd.c des.c pty.c telnetd.c telnetd-init.c
libtelnetd_a_CPPFLAGS = $(AM_CPPFLAGS) libtelnetd_a_CPPFLAGS = $(AM_CPPFLAGS)
endif endif
endif
include $(top_srcdir)/automake/local.am include $(top_srcdir)/automake/local.am

View File

@@ -0,0 +1,18 @@
/*
* Copyright (c) 2018 embedded brains GmbH. All rights reserved.
*
* 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.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/telnetd.h>
rtems_status_code rtems_telnetd_initialize( void )
{
return rtems_telnetd_start( &rtems_telnetd_config );
}

View File

@@ -57,7 +57,10 @@
#include <rtems/userenv.h> #include <rtems/userenv.h>
#include <rtems/error.h> #include <rtems/error.h>
#ifdef RTEMS_NETWORKING
#include <rtems/rtems_bsdnet.h> #include <rtems/rtems_bsdnet.h>
#endif
#define PARANOIA #define PARANOIA
@@ -87,9 +90,16 @@ rtems_id telnetd_dflt_spawn(
); );
/***********************************************************/ /***********************************************************/
static rtems_id telnetd_task_id = RTEMS_ID_NONE; static rtems_telnetd_config_table *telnetd_config;
static rtems_id telnetd_task_id;
rtems_id (*telnetd_spawn_task)( /*
* chrisj: this variable was global and with no declared interface in a header
* file and with no means to set it so I have stopped it being global;
* if this breaks any user they will have be to provide a formal
* interface to get this change reverted.
*/
static const rtems_id (*telnetd_spawn_task)(
const char *, const char *,
unsigned, unsigned,
unsigned, unsigned,
@@ -207,24 +217,24 @@ rtems_task_telnetd(void *task_argument)
}; };
/* we don't redirect stdio as this probably /* we don't redirect stdio as this probably
* was started from the console anyways.. * was started from the console anyway ..
*/ */
do { do {
if (rtems_telnetd_config.keep_stdio) { if (telnetd_config->keep_stdio) {
bool start = true; bool start = true;
char device_name [32]; char device_name [32];
ttyname_r( 1, device_name, sizeof( device_name)); ttyname_r( 1, device_name, sizeof( device_name));
if (rtems_telnetd_config.login_check != NULL) { if (telnetd_config->login_check != NULL) {
start = rtems_shell_login_prompt( start = rtems_shell_login_prompt(
stdin, stdin,
stderr, stderr,
device_name, device_name,
rtems_telnetd_config.login_check telnetd_config->login_check
); );
} }
if (start) { if (start) {
rtems_telnetd_config.command( device_name, arg->arg); telnetd_config->command( device_name, arg->arg);
} else { } else {
syslog( syslog(
LOG_AUTHPRIV | LOG_WARNING, LOG_AUTHPRIV | LOG_WARNING,
@@ -244,13 +254,13 @@ rtems_task_telnetd(void *task_argument)
arg = malloc( sizeof(*arg) ); arg = malloc( sizeof(*arg) );
arg->devname = devname; arg->devname = devname;
arg->arg = rtems_telnetd_config.arg; arg->arg = telnetd_config->arg;
strncpy(arg->peername, peername, sizeof(arg->peername)); strncpy(arg->peername, peername, sizeof(arg->peername));
telnetd_task_id = telnetd_spawn_task( telnetd_task_id = telnetd_spawn_task(
devname, devname,
rtems_telnetd_config.priority, telnetd_config->priority,
rtems_telnetd_config.stack_size, telnetd_config->stack_size,
spawned_shell, spawned_shell,
arg arg
); );
@@ -287,55 +297,70 @@ rtems_task_telnetd(void *task_argument)
telnetd_task_id = RTEMS_ID_NONE; telnetd_task_id = RTEMS_ID_NONE;
} }
rtems_status_code rtems_telnetd_initialize( void) rtems_status_code rtems_telnetd_start(const rtems_telnetd_config_table* config)
{ {
if (telnetd_task_id != RTEMS_ID_NONE) { if (telnetd_config != NULL) {
fprintf(stderr, "telnetd already started\n"); fprintf(stderr, "telnetd already started\n");
return RTEMS_RESOURCE_IN_USE; return RTEMS_RESOURCE_IN_USE;
} }
if (rtems_telnetd_config.command == NULL) { if (config->command == NULL) {
fprintf(stderr, "telnetd setup with invalid command\n"); fprintf(stderr, "telnetd setup with invalid command\n");
return RTEMS_IO_ERROR; 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 ( !telnet_pty_initialize() ) { if ( !telnet_pty_initialize() ) {
fprintf(stderr, "telnetd cannot initialize PTY driver\n"); fprintf(stderr, "telnetd cannot initialize PTY driver\n");
free(telnetd_config);
telnetd_config = NULL;
return RTEMS_IO_ERROR; return RTEMS_IO_ERROR;
} }
*telnetd_config = *config;
/* Check priority */ /* Check priority */
if (rtems_telnetd_config.priority <= 0) { #ifdef RTEMS_NETWORKING
rtems_telnetd_config.priority = rtems_bsdnet_config.network_task_priority; if (telnetd_config->priority <= 0) {
telnetd_config->priority = rtems_bsdnet_config.network_task_priority;
} }
if (rtems_telnetd_config.priority < 2) { #endif
rtems_telnetd_config.priority = 100; if (telnetd_config->priority < 2) {
telnetd_config->priority = 100;
} }
/* Check stack size */ /* Check stack size */
if (rtems_telnetd_config.stack_size <= 0) { if (telnetd_config->stack_size <= 0) {
rtems_telnetd_config.stack_size = (size_t)32 * 1024; telnetd_config->stack_size = (size_t)32 * 1024;
} }
/* Spawn task */ /* Spawn task */
telnetd_task_id = telnetd_spawn_task( telnetd_task_id = telnetd_spawn_task(
"TNTD", "TNTD",
rtems_telnetd_config.priority, telnetd_config->priority,
rtems_telnetd_config.stack_size, telnetd_config->stack_size,
rtems_task_telnetd, rtems_task_telnetd,
0 0
); );
if (telnetd_task_id == RTEMS_ID_NONE) { if (telnetd_task_id == RTEMS_ID_NONE) {
free(telnetd_config);
telnetd_config = NULL;
return RTEMS_IO_ERROR; return RTEMS_IO_ERROR;
} }
/* Print status */ /* Print status */
if (!rtems_telnetd_config.keep_stdio) { if (!telnetd_config->keep_stdio) {
fprintf( fprintf(
stderr, stderr,
"telnetd started with stacksize = %u and priority = %d\n", "telnetd started with stacksize = %u and priority = %d\n",
(unsigned) rtems_telnetd_config.stack_size, (unsigned) telnetd_config->stack_size,
(unsigned) rtems_telnetd_config.priority (unsigned) telnetd_config->priority
); );
} }
@@ -389,17 +414,17 @@ spawned_shell(void *targ)
#endif #endif
/* call their routine */ /* call their routine */
if (rtems_telnetd_config.login_check != NULL) { if (telnetd_config->login_check != NULL) {
start = rtems_shell_login_prompt( start = rtems_shell_login_prompt(
stdin, stdin,
stderr, stderr,
arg->devname, arg->devname,
rtems_telnetd_config.login_check telnetd_config->login_check
); );
login_failed = !start; login_failed = !start;
} }
if (start) { if (start) {
rtems_telnetd_config.command( arg->devname, arg->arg); telnetd_config->command( arg->devname, arg->arg);
} }
stdin = ostd[0]; stdin = ostd[0];