2001-08-09 Fernando-Ruiz Casas <correo@fernando-ruiz.com>

* Makefile.am, configure.in, rtems_servers/Makefile.am,
	rtems_servers/telnetd.c, rtems_servers/telnetd.h,
	rtems_telnetd/Makefile.am, rtems_telnetd/README, rtems_telnetd/icmds.c,
	rtems_telnetd/pty.c, rtems_telnetd/pty.h, rtems_telnetd/telnetd.c,
	rtems_telnetd/telnetd.h, wrapup/Makefile.am:
	  - pty and telnetd have a new subdir rtems_telnetd to avoid
	    the side effect when ftpd change.
	  - the tcp/ip stats have been implemented into icmds.c and
	    started when telnetd daemon is started.
	* rtems_servers/telnetd.c, rtems_servers/telnetd.h: Removed.
	* rtems_telnetd: New directory.
	* rtems_telnetd/Makefile.am, rtems_telnetd/README,
	rtems_telnetd/icmds.c, rtems_telnetd/pty.c, rtems_telnetd/pty.h,
	rtems_telnetd/telnetd.c, rtems_telnetd/telnetd.h: New files.
This commit is contained in:
Joel Sherrill
2001-08-09 22:06:51 +00:00
parent 4f088aee00
commit bd520203a0
27 changed files with 1476 additions and 35 deletions

View File

@@ -1,3 +1,20 @@
2001-08-09 Fernando-Ruiz Casas <correo@fernando-ruiz.com>
* Makefile.am, configure.in, rtems_servers/Makefile.am,
rtems_servers/telnetd.c, rtems_servers/telnetd.h,
rtems_telnetd/Makefile.am, rtems_telnetd/README, rtems_telnetd/icmds.c,
rtems_telnetd/pty.c, rtems_telnetd/pty.h, rtems_telnetd/telnetd.c,
rtems_telnetd/telnetd.h, wrapup/Makefile.am:
- pty and telnetd have a new subdir rtems_telnetd to avoid
the side effect when ftpd change.
- the tcp/ip stats have been implemented into icmds.c and
started when telnetd daemon is started.
* rtems_servers/telnetd.c, rtems_servers/telnetd.h: Removed.
* rtems_telnetd: New directory.
* rtems_telnetd/Makefile.am, rtems_telnetd/README,
rtems_telnetd/icmds.c, rtems_telnetd/pty.c, rtems_telnetd/pty.h,
rtems_telnetd/telnetd.c, rtems_telnetd/telnetd.h: New files.
2001-05-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* rtems_servers/Makefile.am: Deleted blank lines.

View File

@@ -6,7 +6,7 @@ AUTOMAKE_OPTIONS = foreign 1.4
ACLOCAL_AMFLAGS = -I ../../../aclocal
SUBDIRS = arpa kern machine sys vm lib libc net netinet nfs rtems \
rtems_servers pppd modem rtems_webserver wrapup
rtems_servers pppd modem rtems_telnetd rtems_webserver wrapup
include_HEADERS = \
bpfilter.h loop.h netdb.h opt_ipfw.h opt_mrouting.h \

View File

@@ -8,7 +8,7 @@ if HAS_POSIX
POSIX_PIECES = rtems_webserver
endif
NET_O_PIECES = kern lib libc net netinet nfs rtems rtems_servers pppd modem \
NET_O_PIECES = kern lib libc net netinet nfs rtems rtems_servers rtems_telnetd pppd modem \
$(POSIX_PIECES)
OBJS = $(foreach piece, $(NET_O_PIECES), ../$(piece)/$(ARCH)/*.o)
LIB = $(ARCH)/libnetworking.a

View File

@@ -1,3 +1,20 @@
2001-08-09 Fernando-Ruiz Casas <correo@fernando-ruiz.com>
* Makefile.am, configure.in, rtems_servers/Makefile.am,
rtems_servers/telnetd.c, rtems_servers/telnetd.h,
rtems_telnetd/Makefile.am, rtems_telnetd/README, rtems_telnetd/icmds.c,
rtems_telnetd/pty.c, rtems_telnetd/pty.h, rtems_telnetd/telnetd.c,
rtems_telnetd/telnetd.h, wrapup/Makefile.am:
- pty and telnetd have a new subdir rtems_telnetd to avoid
the side effect when ftpd change.
- the tcp/ip stats have been implemented into icmds.c and
started when telnetd daemon is started.
* rtems_servers/telnetd.c, rtems_servers/telnetd.h: Removed.
* rtems_telnetd: New directory.
* rtems_telnetd/Makefile.am, rtems_telnetd/README,
rtems_telnetd/icmds.c, rtems_telnetd/pty.c, rtems_telnetd/pty.h,
rtems_telnetd/telnetd.c, rtems_telnetd/telnetd.h: New files.
2001-05-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* rtems_servers/Makefile.am: Deleted blank lines.

View File

@@ -6,7 +6,7 @@ AUTOMAKE_OPTIONS = foreign 1.4
ACLOCAL_AMFLAGS = -I ../../../aclocal
SUBDIRS = arpa kern machine sys vm lib libc net netinet nfs rtems \
rtems_servers pppd modem rtems_webserver wrapup
rtems_servers pppd modem rtems_telnetd rtems_webserver wrapup
include_HEADERS = \
bpfilter.h loop.h netdb.h opt_ipfw.h opt_mrouting.h \

View File

@@ -49,6 +49,7 @@ pppd/Makefile
modem/Makefile
rtems/Makefile
rtems_servers/Makefile
rtems_telnetd/Makefile
rtems_webserver/Makefile
wrapup/Makefile
)

View File

@@ -33,7 +33,7 @@ EXTRA_DIST = ftpd.c ftpd.h
include_HEADERS = ftpd.h
include_rtems_HEADERS = telnetd.h
include_rtems_HEADERS =
PREINSTALL_FILES += $(PROJECT_INCLUDE) \
$(include_HEADERS:%=$(PROJECT_INCLUDE)/%) \

View File

@@ -1,20 +0,0 @@
/*
* $Id$
*/
#ifndef __TELNETD_H
#define __TELNETD_H
#ifdef __cplusplus
extern "C" {
#endif
int rtems_initialize_telnetd(void);
int main_telnetd(int argc,char * argv[]);
int register_telnetd(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,44 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
include_rtemsdir = $(includedir)/rtems
LIBNAME = libtelnetd-tmp
LIB = $(ARCH)/$(LIBNAME).a
C_FILES = pty.c telnetd.c icmds.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
include_rtems_HEADERS = pty.h telnetd.h
OBJS = $(C_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../automake/compile.am
include $(top_srcdir)/../../../automake/lib.am
$(PROJECT_INCLUDE)/rtems:
@$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/rtems/%.h: %.h
$(INSTALL_DATA) $< $@
#
# (OPTIONAL) Add local stuff here using +=
#
$(LIB): $(OBJS)
$(make-library)
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems \
$(include_rtems_HEADERS:%=$(PROJECT_INCLUDE)/rtems/%)
all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS) $(LIB)
.PRECIOUS: $(LIB)
EXTRA_DIST = README pty.c telnetd.c pty.h icmds.c telnetd.h
include $(top_srcdir)/../../../automake/local.am

View File

@@ -0,0 +1,28 @@
#
# $Id$
#
Author: fernando.ruiz@ctv.es (correo@fernando-ruiz.com)
This directory contains a telnetd server
primary features:
+ create a user shell pseudo-terminal task.
This code has not been extensively tested. It is provided as a tool
for RTEMS users to open more shell tcp/ip pseudo-terminal.
Suggestions and comments are appreciated.
Read libmisc/shell for more information.
NOTES:
1. OOB not yet implemented. Only a reduced negotiation is implemented.
2. If you have tcp/ip inited you can start telnetd daemon.
You need register pseudo-terminals driver into device drivers table.
16 ptyX termios device terminales are created into /dev/.
Calling rtems_initialize_telnetd() starts the daemon.
Enjoy it.
FUTURE:

View File

@@ -0,0 +1,48 @@
#include <rtems/shell.h>
#include <rtems/rtems_bsdnet.h>
/*+++++++++++++++++++++++++++++++++++++++++++++*/
int main_inet(int argc,char * argv[]) {
rtems_bsdnet_show_inet_routes ();
return 0;
}
/*+++++++++++++++++++++++++++++++++++++++++++++*/
int main_mbuf(int argc,char * argv[]) {
rtems_bsdnet_show_mbuf_stats ();
return 0;
}
/*+++++++++++++++++++++++++++++++++++++++++++++*/
int main_if(int argc,char * argv[]) {
rtems_bsdnet_show_if_stats ();
return 0;
}
/*+++++++++++++++++++++++++++++++++++++++++++++*/
int main_ip(int argc,char * argv[]) {
rtems_bsdnet_show_ip_stats ();
return 0;
}
/*+++++++++++++++++++++++++++++++++++++++++++++*/
int main_icmp(int argc,char * argv[]) {
rtems_bsdnet_show_icmp_stats ();
return 0;
}
/*+++++++++++++++++++++++++++++++++++++++++++++*/
int main_tcp(int argc,char * argv[]) {
rtems_bsdnet_show_tcp_stats ();
return 0;
}
/*+++++++++++++++++++++++++++++++++++++++++++++*/
int main_udp(int argc,char * argv[]) {
rtems_bsdnet_show_udp_stats ();
return 0;
}
/*+++++++++++++++++++++++++++++++++++++++++++++*/
void register_icmds(void) {
shell_add_cmd("inet" ,"net","inet routes" ,main_inet);
shell_add_cmd("mbuf" ,"net","mbuf stats" ,main_mbuf);
shell_add_cmd("if" ,"net","if stats" ,main_if );
shell_add_cmd("ip" ,"net","ip stats" ,main_ip );
shell_add_cmd("icmp" ,"net","icmp stats" ,main_icmp);
shell_add_cmd("tcp" ,"net","tcp stats" ,main_tcp );
shell_add_cmd("udp" ,"net","udp stats" ,main_udp );
}

View File

@@ -0,0 +1,408 @@
/*
* /dev/ptyXX (A first version for pseudo-terminals)
*
* Author: Fernando RUIZ CASAS (fernando.ruiz@ctv.es)
* May 2001
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id$
*/
/*-----------------------------------------*/
#include <termios.h>
#include <rtems.h>
#include <rtems/libio.h>
#include <bsp.h>
#include <rtems/pty.h>
/*-----------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/*-----------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/*-----------------------------------------*/
#define printk printf
/*-----------------------------------------*/
#define IAC_ESC 255
#define IAC_DONT 254
#define IAC_DO 253
#define IAC_WONT 252
#define IAC_WILL 251
#define IAC_SB 250
#define IAC_GA 249
#define IAC_EL 248
#define IAC_EC 247
#define IAC_AYT 246
#define IAC_AO 245
#define IAC_IP 244
#define IAC_BRK 243
#define IAC_DMARK 242
#define IAC_NOP 241
#define IAC_SE 240
#define IAC_EOR 239
struct pty_tt;
typedef struct pty_tt pty_t;
struct pty_tt {
char *devname;
struct rtems_termios_tty *ttyp;
tcflag_t c_cflag;
int opened;
int socket;
int last_cr;
int iac_mode;
};
int ptys_initted=FALSE;
pty_t ptys[MAX_PTYS];
/* This procedure returns the devname for a pty slot free.
* If not slot availiable (field socket>=0)
* then the socket argument is closed
*/
char * get_pty(int socket) {
int ndx;
if (!ptys_initted) return NULL;
for (ndx=0;ndx<MAX_PTYS;ndx++) {
if (ptys[ndx].socket<0) {
ptys[ndx].socket=socket;
return ptys[ndx].devname;
};
};
close(socket);
return NULL;
}
/*-----------------------------------------------------------*/
/*
* The NVT terminal is negociated in PollRead and PollWrite
* with every BYTE sendded or received.
* A litle status machine in the pty_read_byte(int minor)
*
*/
const char IAC_AYT_RSP[]="\r\nAYT? Yes, RTEMS-SHELL is here\r\n";
const char IAC_BRK_RSP[]="<*Break*>";
const char IAC_IP_RSP []="<*Interrupt*>";
static
int send_iac(int minor,unsigned char mode,unsigned char option) {
unsigned char buf[3];
buf[0]=IAC_ESC;
buf[1]=mode;
buf[2]=option;
return write(ptys[minor].socket,buf,sizeof(buf));
}
int read_pty(int minor) { /* Characters writed in the client side*/
unsigned char value;
int count;
int result;
count=read(ptys[minor].socket,&value,sizeof(value));
if (count<1) {
fclose(stdin);
fclose(stdout);
fclose(stderr);
/* If you don't read from the socket the system ends the task */
rtems_task_delete(RTEMS_SELF);
};
switch(ptys[minor].iac_mode) {
case IAC_ESC:
ptys[minor].iac_mode=0;
switch(value) {
case IAC_ESC :
return IAC_ESC;
case IAC_DONT:
case IAC_DO :
case IAC_WONT:
case IAC_WILL:
ptys[minor].iac_mode=value;
return -1;
case IAC_SB :
return -100;
case IAC_GA :
return -1;
case IAC_EL :
return 0x03; /* Ctrl-C*/
case IAC_EC :
return '\b';
case IAC_AYT :
write(ptys[minor].socket,IAC_AYT_RSP,strlen(IAC_AYT_RSP));
return -1;
case IAC_AO :
return -1;
case IAC_IP :
write(ptys[minor].socket,IAC_IP_RSP,strlen(IAC_IP_RSP));
return -1;
case IAC_BRK :
write(ptys[minor].socket,IAC_BRK_RSP,strlen(IAC_BRK_RSP));
return -1;
case IAC_DMARK:
return -2;
case IAC_NOP :
return -1;
case IAC_SE :
return -101;
case IAC_EOR :
return -102;
default :
return -1;
};
break;
case IAC_WILL:
ptys[minor].iac_mode=0;
if (value==34){send_iac(minor,IAC_DONT, 34); /*LINEMODE*/
send_iac(minor,IAC_DO , 1);} else /*ECHO */
{send_iac(minor,IAC_DONT,value);};
return -1;
case IAC_DONT:
ptys[minor].iac_mode=0;
return -1;
case IAC_DO :
ptys[minor].iac_mode=0;
if (value==3) {send_iac(minor,IAC_WILL, 3);} else /* GO AHEAD*/
if (value==1) { } else /* ECHO */
{send_iac(minor,IAC_WONT,value);};
return -1;
case IAC_WONT:
ptys[minor].iac_mode=0;
if (value==1) {send_iac(minor,IAC_WILL, 1);} else /* ECHO */
{send_iac(minor,IAC_WONT,value);};
return -1;
default:
ptys[minor].iac_mode=0;
if (value==IAC_ESC) {
ptys[minor].iac_mode=value;
return -1;
} else {
result=value;
if ((value=='\n') && (ptys[minor].last_cr)) result=-1;
ptys[minor].last_cr=(value=='\r');
return result;
};
};
}
/*-----------------------------------------------------------*/
static int ptySetAttributes(int minor,const struct termios *t);
static int ptyPollInitialize(int major,int minor,void * arg) ;
static int ptyShutdown(int major,int minor,void * arg) ;
static int ptyPollWrite(int minor, const char * buf,int len) ;
static int ptyPollRead(int minor) ;
const rtems_termios_callbacks * pty_get_termios_handlers(int polled) ;
/*-----------------------------------------------------------*/
/* Set the 'Hardware' */
/*-----------------------------------------------------------*/
static int
ptySetAttributes(int minor,const struct termios *t) {
if (minor<MAX_PTYS) {
ptys[minor].c_cflag=t->c_cflag;
} else {
return -1;
};
return 0;
}
/*-----------------------------------------------------------*/
static int
ptyPollInitialize(int major,int minor,void * arg) {
rtems_libio_open_close_args_t * args = arg;
struct termios t;
if (minor<MAX_PTYS) {
if (ptys[minor].socket<0) return -1;
ptys[minor].opened=TRUE;
ptys[minor].ttyp=args->iop->data1;
t.c_cflag=B9600|CS8;/* termios default */
return ptySetAttributes(minor,&t);
} else {
return -1;
};
}
/*-----------------------------------------------------------*/
static int
ptyShutdown(int major,int minor,void * arg) {
if (minor<MAX_PTYS) {
ptys[minor].opened=FALSE;
if (ptys[minor].socket>=0) close(ptys[minor].socket);
ptys[minor].socket=-1;
chown(ptys[minor].devname,2,0);
} else {
return -1;
};
return 0;
}
/*-----------------------------------------------------------*/
/* Write Characters into pty device */
/*-----------------------------------------------------------*/
static int
ptyPollWrite(int minor, const char * buf,int len) {
int count;
if (minor<MAX_PTYS) {
if (ptys[minor].socket<0) return -1;
count=write(ptys[minor].socket,buf,len);
} else {
count=-1;
};
return count;
}
/*-----------------------------------------------------------*/
static int
ptyPollRead(int minor) {
int result;
if (minor<MAX_PTYS) {
if (ptys[minor].socket<0) return -1;
result=read_pty(minor);
return result;
};
return -1;
}
/*-----------------------------------------------------------*/
static const rtems_termios_callbacks pty_poll_callbacks = {
ptyPollInitialize, /* FirstOpen*/
ptyShutdown, /* LastClose*/
ptyPollRead, /* PollRead */
ptyPollWrite, /* Write */
ptySetAttributes, /* setAttributes */
NULL, /* stopRemoteTX */
NULL, /* StartRemoteTX */
0 /* outputUsesInterrupts */
};
/*-----------------------------------------------------------*/
const rtems_termios_callbacks * pty_get_termios_handlers(int polled) {
return &pty_poll_callbacks;
}
/*-----------------------------------------------------------*/
void init_ptys(void) {
int ndx;
for (ndx=0;ndx<MAX_PTYS;ndx++) {
ptys[ndx].devname=malloc(strlen("/dev/ptyXX")+1);
sprintf(ptys[ndx].devname,"/dev/pty%X",ndx);
ptys[ndx].ttyp=NULL;
ptys[ndx].c_cflag=CS8|B9600;
ptys[ndx].socket=-1;
ptys[ndx].opened=FALSE;
};
ptys_initted=TRUE;
}
/*-----------------------------------------------------------*/
/* pty_initialize
*
* This routine initializes the pty IO driver.
*
* Input parameters: NONE
*
* Output parameters: NONE
*
* Return values:
*/
/*-----------------------------------------------------------*/
rtems_device_driver pty_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
int ndx;
rtems_status_code status ;
/*
* Set up ptys
*/
init_ptys();
/*
* Register the devices
*/
for (ndx=0;ndx<MAX_PTYS;ndx++) {
status = rtems_io_register_name(ptys[ndx].devname, major, ndx);
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred(status);
chmod(ptys[ndx].devname,0660);
chown(ptys[ndx].devname,2,0); /* tty,root*/
};
printk("Device: /dev/pty%X../dev/pty%X (%d)pseudo-terminals registered.\n",0,MAX_PTYS-1,MAX_PTYS);
return RTEMS_SUCCESSFUL;
}
/*
* Open entry point
*/
rtems_device_driver pty_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
rtems_status_code sc ;
sc = rtems_termios_open(major,minor,arg,pty_get_termios_handlers(FALSE));
return sc;
}
/*
* Close entry point
*/
rtems_device_driver pty_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
return rtems_termios_close(arg);
}
/*
* read bytes from the pty
*/
rtems_device_driver pty_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
return rtems_termios_read(arg);
}
/*
* write bytes to the pty
*/
rtems_device_driver pty_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
return rtems_termios_write(arg);
}
/*
* IO Control entry point
*/
rtems_device_driver pty_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
return rtems_termios_ioctl(arg);
}

View File

@@ -0,0 +1,63 @@
/*
* /dev/ptyXX (A first version for pseudo-terminals)
*
* Author: Fernando RUIZ CASAS (fernando.ruiz@ctv.es)
* May 2001
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id$
*/
#ifndef __PTY_H
#define __PTY_H
#ifdef __cplusplus
extern "C" {
#endif
#include <rtems.h>
#ifndef MAX_PTYS
#define MAX_PTYS 16
#endif
char * get_pty(int socket);
rtems_device_driver pty_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg);
rtems_device_driver pty_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg);
rtems_device_driver pty_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg);
rtems_device_driver pty_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg);
rtems_device_driver pty_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg);
rtems_device_driver pty_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg);
#define PTY_DRIVER_TABLE_ENTRY \
{ pty_initialize , pty_open , pty_close , \
pty_read , pty_write , pty_control }
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,9 +1,30 @@
/***********************************************************/
/*
* $Id$
*
* The telnet DAEMON
*
* Author: 17,may 2001
*
* WORK: fernando.ruiz@ctv.es
* HOME: correo@fernando-ruiz.com
*
* After start the net you can start this daemon.
* It uses the previously inited pseudo-terminales (pty.c)
* getting a new terminal with getpty(). This function
* gives a terminal name passing a opened socket like parameter.
*
* With register_telnetd() you add a new command in the shell to start
* this daemon interactively. (Login in /dev/console of course)
*
* Sorry but OOB is not still implemented. (This is the first version)
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems.h>
#include <rtems/error.h>
#include <rtems/pty.h>
#include <rtems/shell.h>
#include <rtems/telnetd.h>
#include <sys/socket.h>
@@ -25,7 +46,7 @@ rtems_task rtems_task_telnetd(rtems_task_argument task_argument) {
int i=1;
int size_adr;
if ((des_socket=socket(PF_INET,SOCK_STREAM,0))<0) {
perror("socket");
perror("telnetd:socket");
rtems_task_delete(RTEMS_SELF);
};
setsockopt(des_socket,SOL_SOCKET,0,&i,sizeof(i));
@@ -34,22 +55,22 @@ rtems_task rtems_task_telnetd(rtems_task_argument task_argument) {
srv.sin_port=htons(23);
size_adr=sizeof(srv);
if ((bind(des_socket,(struct sockaddr *)&srv,size_adr))<0) {
perror("bind");
perror("telnetd:bind");
close(des_socket);
rtems_task_delete(RTEMS_SELF);
};
if ((listen(des_socket,5))<0) {
perror("listen");
perror("telnetd:listen");
close(des_socket);
rtems_task_delete(RTEMS_SELF);
};
do {
acp_socket=accept(des_socket,(struct sockaddr*)&srv,&size_adr);
if (acp_socket<0) {
perror("accept");
perror("telnetd:accept");
break;
};
if (devname = get_pty(acp_socket) ) {
if ((devname = get_pty(acp_socket)) ) {
shell_init(&devname[5],
telnetd_stack_size,
telnetd_task_priority,
@@ -63,11 +84,15 @@ rtems_task rtems_task_telnetd(rtems_task_argument task_argument) {
}
/***********************************************************/
int rtems_initialize_telnetd(void) {
void register_icmds(void);
rtems_status_code sc;
register_icmds(); /* stats for tcp/ip */
if (telnetd_task_id ) return RTEMS_RESOURCE_IN_USE;
if (telnetd_stack_size<=0 ) telnetd_stack_size =16384;
if (telnetd_task_priority<=2) telnetd_task_priority=100;
sc=rtems_task_create(new_rtems_name("TLND"),
sc=rtems_task_create(new_rtems_name("tlnd"),
100,RTEMS_MINIMUM_STACK_SIZE,
RTEMS_DEFAULT_MODES,
RTEMS_DEFAULT_ATTRIBUTES,

View File

@@ -0,0 +1,35 @@
/*
* (A first version for telnetd)
*
* Author: Fernando RUIZ CASAS (fernando.ruiz@ctv.es)
* May 2001
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* rtems_initialize_telnetd() starts the daemon.
* main_telnetd() is the main_proc for the command telnetd in the shell
* register_telnetd() add a new command in the shell to start
* interactively the telnetd daemon.
*
* $Id$
*/
#ifndef __TELNETD_H
#define __TELNETD_H
#ifdef __cplusplus
extern "C" {
#endif
int rtems_initialize_telnetd(void);
int main_telnetd(int argc,char * argv[]);
int register_telnetd(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -8,7 +8,7 @@ if HAS_POSIX
POSIX_PIECES = rtems_webserver
endif
NET_O_PIECES = kern lib libc net netinet nfs rtems rtems_servers pppd modem \
NET_O_PIECES = kern lib libc net netinet nfs rtems rtems_servers rtems_telnetd pppd modem \
$(POSIX_PIECES)
OBJS = $(foreach piece, $(NET_O_PIECES), ../$(piece)/$(ARCH)/*.o)
LIB = $(ARCH)/libnetworking.a

View File

@@ -33,7 +33,7 @@ EXTRA_DIST = ftpd.c ftpd.h
include_HEADERS = ftpd.h
include_rtems_HEADERS = telnetd.h
include_rtems_HEADERS =
PREINSTALL_FILES += $(PROJECT_INCLUDE) \
$(include_HEADERS:%=$(PROJECT_INCLUDE)/%) \

View File

@@ -1,3 +1,20 @@
2001-08-09 Fernando-Ruiz Casas <correo@fernando-ruiz.com>
* Makefile.am, configure.in, rtems_servers/Makefile.am,
rtems_servers/telnetd.c, rtems_servers/telnetd.h,
rtems_telnetd/Makefile.am, rtems_telnetd/README, rtems_telnetd/icmds.c,
rtems_telnetd/pty.c, rtems_telnetd/pty.h, rtems_telnetd/telnetd.c,
rtems_telnetd/telnetd.h, wrapup/Makefile.am:
- pty and telnetd have a new subdir rtems_telnetd to avoid
the side effect when ftpd change.
- the tcp/ip stats have been implemented into icmds.c and
started when telnetd daemon is started.
* rtems_servers/telnetd.c, rtems_servers/telnetd.h: Removed.
* rtems_telnetd: New directory.
* rtems_telnetd/Makefile.am, rtems_telnetd/README,
rtems_telnetd/icmds.c, rtems_telnetd/pty.c, rtems_telnetd/pty.h,
rtems_telnetd/telnetd.c, rtems_telnetd/telnetd.h: New files.
2001-05-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* rtems_servers/Makefile.am: Deleted blank lines.

View File

@@ -6,7 +6,7 @@ AUTOMAKE_OPTIONS = foreign 1.4
ACLOCAL_AMFLAGS = -I ../../../aclocal
SUBDIRS = arpa kern machine sys vm lib libc net netinet nfs rtems \
rtems_servers pppd modem rtems_webserver wrapup
rtems_servers pppd modem rtems_telnetd rtems_webserver wrapup
include_HEADERS = \
bpfilter.h loop.h netdb.h opt_ipfw.h opt_mrouting.h \

View File

@@ -8,7 +8,7 @@ if HAS_POSIX
POSIX_PIECES = rtems_webserver
endif
NET_O_PIECES = kern lib libc net netinet nfs rtems rtems_servers pppd modem \
NET_O_PIECES = kern lib libc net netinet nfs rtems rtems_servers rtems_telnetd pppd modem \
$(POSIX_PIECES)
OBJS = $(foreach piece, $(NET_O_PIECES), ../$(piece)/$(ARCH)/*.o)
LIB = $(ARCH)/libnetworking.a

View File

@@ -0,0 +1,44 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
include_rtemsdir = $(includedir)/rtems
LIBNAME = libtelnetd-tmp
LIB = $(ARCH)/$(LIBNAME).a
C_FILES = pty.c telnetd.c icmds.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
include_rtems_HEADERS = pty.h telnetd.h
OBJS = $(C_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../automake/compile.am
include $(top_srcdir)/../../../automake/lib.am
$(PROJECT_INCLUDE)/rtems:
@$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/rtems/%.h: %.h
$(INSTALL_DATA) $< $@
#
# (OPTIONAL) Add local stuff here using +=
#
$(LIB): $(OBJS)
$(make-library)
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems \
$(include_rtems_HEADERS:%=$(PROJECT_INCLUDE)/rtems/%)
all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS) $(LIB)
.PRECIOUS: $(LIB)
EXTRA_DIST = README pty.c telnetd.c pty.h icmds.c telnetd.h
include $(top_srcdir)/../../../automake/local.am

28
cpukit/telnetd/README Normal file
View File

@@ -0,0 +1,28 @@
#
# $Id$
#
Author: fernando.ruiz@ctv.es (correo@fernando-ruiz.com)
This directory contains a telnetd server
primary features:
+ create a user shell pseudo-terminal task.
This code has not been extensively tested. It is provided as a tool
for RTEMS users to open more shell tcp/ip pseudo-terminal.
Suggestions and comments are appreciated.
Read libmisc/shell for more information.
NOTES:
1. OOB not yet implemented. Only a reduced negotiation is implemented.
2. If you have tcp/ip inited you can start telnetd daemon.
You need register pseudo-terminals driver into device drivers table.
16 ptyX termios device terminales are created into /dev/.
Calling rtems_initialize_telnetd() starts the daemon.
Enjoy it.
FUTURE:

48
cpukit/telnetd/icmds.c Normal file
View File

@@ -0,0 +1,48 @@
#include <rtems/shell.h>
#include <rtems/rtems_bsdnet.h>
/*+++++++++++++++++++++++++++++++++++++++++++++*/
int main_inet(int argc,char * argv[]) {
rtems_bsdnet_show_inet_routes ();
return 0;
}
/*+++++++++++++++++++++++++++++++++++++++++++++*/
int main_mbuf(int argc,char * argv[]) {
rtems_bsdnet_show_mbuf_stats ();
return 0;
}
/*+++++++++++++++++++++++++++++++++++++++++++++*/
int main_if(int argc,char * argv[]) {
rtems_bsdnet_show_if_stats ();
return 0;
}
/*+++++++++++++++++++++++++++++++++++++++++++++*/
int main_ip(int argc,char * argv[]) {
rtems_bsdnet_show_ip_stats ();
return 0;
}
/*+++++++++++++++++++++++++++++++++++++++++++++*/
int main_icmp(int argc,char * argv[]) {
rtems_bsdnet_show_icmp_stats ();
return 0;
}
/*+++++++++++++++++++++++++++++++++++++++++++++*/
int main_tcp(int argc,char * argv[]) {
rtems_bsdnet_show_tcp_stats ();
return 0;
}
/*+++++++++++++++++++++++++++++++++++++++++++++*/
int main_udp(int argc,char * argv[]) {
rtems_bsdnet_show_udp_stats ();
return 0;
}
/*+++++++++++++++++++++++++++++++++++++++++++++*/
void register_icmds(void) {
shell_add_cmd("inet" ,"net","inet routes" ,main_inet);
shell_add_cmd("mbuf" ,"net","mbuf stats" ,main_mbuf);
shell_add_cmd("if" ,"net","if stats" ,main_if );
shell_add_cmd("ip" ,"net","ip stats" ,main_ip );
shell_add_cmd("icmp" ,"net","icmp stats" ,main_icmp);
shell_add_cmd("tcp" ,"net","tcp stats" ,main_tcp );
shell_add_cmd("udp" ,"net","udp stats" ,main_udp );
}

408
cpukit/telnetd/pty.c Normal file
View File

@@ -0,0 +1,408 @@
/*
* /dev/ptyXX (A first version for pseudo-terminals)
*
* Author: Fernando RUIZ CASAS (fernando.ruiz@ctv.es)
* May 2001
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id$
*/
/*-----------------------------------------*/
#include <termios.h>
#include <rtems.h>
#include <rtems/libio.h>
#include <bsp.h>
#include <rtems/pty.h>
/*-----------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/*-----------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/*-----------------------------------------*/
#define printk printf
/*-----------------------------------------*/
#define IAC_ESC 255
#define IAC_DONT 254
#define IAC_DO 253
#define IAC_WONT 252
#define IAC_WILL 251
#define IAC_SB 250
#define IAC_GA 249
#define IAC_EL 248
#define IAC_EC 247
#define IAC_AYT 246
#define IAC_AO 245
#define IAC_IP 244
#define IAC_BRK 243
#define IAC_DMARK 242
#define IAC_NOP 241
#define IAC_SE 240
#define IAC_EOR 239
struct pty_tt;
typedef struct pty_tt pty_t;
struct pty_tt {
char *devname;
struct rtems_termios_tty *ttyp;
tcflag_t c_cflag;
int opened;
int socket;
int last_cr;
int iac_mode;
};
int ptys_initted=FALSE;
pty_t ptys[MAX_PTYS];
/* This procedure returns the devname for a pty slot free.
* If not slot availiable (field socket>=0)
* then the socket argument is closed
*/
char * get_pty(int socket) {
int ndx;
if (!ptys_initted) return NULL;
for (ndx=0;ndx<MAX_PTYS;ndx++) {
if (ptys[ndx].socket<0) {
ptys[ndx].socket=socket;
return ptys[ndx].devname;
};
};
close(socket);
return NULL;
}
/*-----------------------------------------------------------*/
/*
* The NVT terminal is negociated in PollRead and PollWrite
* with every BYTE sendded or received.
* A litle status machine in the pty_read_byte(int minor)
*
*/
const char IAC_AYT_RSP[]="\r\nAYT? Yes, RTEMS-SHELL is here\r\n";
const char IAC_BRK_RSP[]="<*Break*>";
const char IAC_IP_RSP []="<*Interrupt*>";
static
int send_iac(int minor,unsigned char mode,unsigned char option) {
unsigned char buf[3];
buf[0]=IAC_ESC;
buf[1]=mode;
buf[2]=option;
return write(ptys[minor].socket,buf,sizeof(buf));
}
int read_pty(int minor) { /* Characters writed in the client side*/
unsigned char value;
int count;
int result;
count=read(ptys[minor].socket,&value,sizeof(value));
if (count<1) {
fclose(stdin);
fclose(stdout);
fclose(stderr);
/* If you don't read from the socket the system ends the task */
rtems_task_delete(RTEMS_SELF);
};
switch(ptys[minor].iac_mode) {
case IAC_ESC:
ptys[minor].iac_mode=0;
switch(value) {
case IAC_ESC :
return IAC_ESC;
case IAC_DONT:
case IAC_DO :
case IAC_WONT:
case IAC_WILL:
ptys[minor].iac_mode=value;
return -1;
case IAC_SB :
return -100;
case IAC_GA :
return -1;
case IAC_EL :
return 0x03; /* Ctrl-C*/
case IAC_EC :
return '\b';
case IAC_AYT :
write(ptys[minor].socket,IAC_AYT_RSP,strlen(IAC_AYT_RSP));
return -1;
case IAC_AO :
return -1;
case IAC_IP :
write(ptys[minor].socket,IAC_IP_RSP,strlen(IAC_IP_RSP));
return -1;
case IAC_BRK :
write(ptys[minor].socket,IAC_BRK_RSP,strlen(IAC_BRK_RSP));
return -1;
case IAC_DMARK:
return -2;
case IAC_NOP :
return -1;
case IAC_SE :
return -101;
case IAC_EOR :
return -102;
default :
return -1;
};
break;
case IAC_WILL:
ptys[minor].iac_mode=0;
if (value==34){send_iac(minor,IAC_DONT, 34); /*LINEMODE*/
send_iac(minor,IAC_DO , 1);} else /*ECHO */
{send_iac(minor,IAC_DONT,value);};
return -1;
case IAC_DONT:
ptys[minor].iac_mode=0;
return -1;
case IAC_DO :
ptys[minor].iac_mode=0;
if (value==3) {send_iac(minor,IAC_WILL, 3);} else /* GO AHEAD*/
if (value==1) { } else /* ECHO */
{send_iac(minor,IAC_WONT,value);};
return -1;
case IAC_WONT:
ptys[minor].iac_mode=0;
if (value==1) {send_iac(minor,IAC_WILL, 1);} else /* ECHO */
{send_iac(minor,IAC_WONT,value);};
return -1;
default:
ptys[minor].iac_mode=0;
if (value==IAC_ESC) {
ptys[minor].iac_mode=value;
return -1;
} else {
result=value;
if ((value=='\n') && (ptys[minor].last_cr)) result=-1;
ptys[minor].last_cr=(value=='\r');
return result;
};
};
}
/*-----------------------------------------------------------*/
static int ptySetAttributes(int minor,const struct termios *t);
static int ptyPollInitialize(int major,int minor,void * arg) ;
static int ptyShutdown(int major,int minor,void * arg) ;
static int ptyPollWrite(int minor, const char * buf,int len) ;
static int ptyPollRead(int minor) ;
const rtems_termios_callbacks * pty_get_termios_handlers(int polled) ;
/*-----------------------------------------------------------*/
/* Set the 'Hardware' */
/*-----------------------------------------------------------*/
static int
ptySetAttributes(int minor,const struct termios *t) {
if (minor<MAX_PTYS) {
ptys[minor].c_cflag=t->c_cflag;
} else {
return -1;
};
return 0;
}
/*-----------------------------------------------------------*/
static int
ptyPollInitialize(int major,int minor,void * arg) {
rtems_libio_open_close_args_t * args = arg;
struct termios t;
if (minor<MAX_PTYS) {
if (ptys[minor].socket<0) return -1;
ptys[minor].opened=TRUE;
ptys[minor].ttyp=args->iop->data1;
t.c_cflag=B9600|CS8;/* termios default */
return ptySetAttributes(minor,&t);
} else {
return -1;
};
}
/*-----------------------------------------------------------*/
static int
ptyShutdown(int major,int minor,void * arg) {
if (minor<MAX_PTYS) {
ptys[minor].opened=FALSE;
if (ptys[minor].socket>=0) close(ptys[minor].socket);
ptys[minor].socket=-1;
chown(ptys[minor].devname,2,0);
} else {
return -1;
};
return 0;
}
/*-----------------------------------------------------------*/
/* Write Characters into pty device */
/*-----------------------------------------------------------*/
static int
ptyPollWrite(int minor, const char * buf,int len) {
int count;
if (minor<MAX_PTYS) {
if (ptys[minor].socket<0) return -1;
count=write(ptys[minor].socket,buf,len);
} else {
count=-1;
};
return count;
}
/*-----------------------------------------------------------*/
static int
ptyPollRead(int minor) {
int result;
if (minor<MAX_PTYS) {
if (ptys[minor].socket<0) return -1;
result=read_pty(minor);
return result;
};
return -1;
}
/*-----------------------------------------------------------*/
static const rtems_termios_callbacks pty_poll_callbacks = {
ptyPollInitialize, /* FirstOpen*/
ptyShutdown, /* LastClose*/
ptyPollRead, /* PollRead */
ptyPollWrite, /* Write */
ptySetAttributes, /* setAttributes */
NULL, /* stopRemoteTX */
NULL, /* StartRemoteTX */
0 /* outputUsesInterrupts */
};
/*-----------------------------------------------------------*/
const rtems_termios_callbacks * pty_get_termios_handlers(int polled) {
return &pty_poll_callbacks;
}
/*-----------------------------------------------------------*/
void init_ptys(void) {
int ndx;
for (ndx=0;ndx<MAX_PTYS;ndx++) {
ptys[ndx].devname=malloc(strlen("/dev/ptyXX")+1);
sprintf(ptys[ndx].devname,"/dev/pty%X",ndx);
ptys[ndx].ttyp=NULL;
ptys[ndx].c_cflag=CS8|B9600;
ptys[ndx].socket=-1;
ptys[ndx].opened=FALSE;
};
ptys_initted=TRUE;
}
/*-----------------------------------------------------------*/
/* pty_initialize
*
* This routine initializes the pty IO driver.
*
* Input parameters: NONE
*
* Output parameters: NONE
*
* Return values:
*/
/*-----------------------------------------------------------*/
rtems_device_driver pty_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
int ndx;
rtems_status_code status ;
/*
* Set up ptys
*/
init_ptys();
/*
* Register the devices
*/
for (ndx=0;ndx<MAX_PTYS;ndx++) {
status = rtems_io_register_name(ptys[ndx].devname, major, ndx);
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred(status);
chmod(ptys[ndx].devname,0660);
chown(ptys[ndx].devname,2,0); /* tty,root*/
};
printk("Device: /dev/pty%X../dev/pty%X (%d)pseudo-terminals registered.\n",0,MAX_PTYS-1,MAX_PTYS);
return RTEMS_SUCCESSFUL;
}
/*
* Open entry point
*/
rtems_device_driver pty_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
rtems_status_code sc ;
sc = rtems_termios_open(major,minor,arg,pty_get_termios_handlers(FALSE));
return sc;
}
/*
* Close entry point
*/
rtems_device_driver pty_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
return rtems_termios_close(arg);
}
/*
* read bytes from the pty
*/
rtems_device_driver pty_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
return rtems_termios_read(arg);
}
/*
* write bytes to the pty
*/
rtems_device_driver pty_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
return rtems_termios_write(arg);
}
/*
* IO Control entry point
*/
rtems_device_driver pty_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
return rtems_termios_ioctl(arg);
}

63
cpukit/telnetd/pty.h Normal file
View File

@@ -0,0 +1,63 @@
/*
* /dev/ptyXX (A first version for pseudo-terminals)
*
* Author: Fernando RUIZ CASAS (fernando.ruiz@ctv.es)
* May 2001
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id$
*/
#ifndef __PTY_H
#define __PTY_H
#ifdef __cplusplus
extern "C" {
#endif
#include <rtems.h>
#ifndef MAX_PTYS
#define MAX_PTYS 16
#endif
char * get_pty(int socket);
rtems_device_driver pty_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg);
rtems_device_driver pty_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg);
rtems_device_driver pty_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg);
rtems_device_driver pty_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg);
rtems_device_driver pty_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg);
rtems_device_driver pty_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg);
#define PTY_DRIVER_TABLE_ENTRY \
{ pty_initialize , pty_open , pty_close , \
pty_read , pty_write , pty_control }
#ifdef __cplusplus
}
#endif
#endif

132
cpukit/telnetd/telnetd.c Normal file
View File

@@ -0,0 +1,132 @@
/***********************************************************/
/*
*
* The telnet DAEMON
*
* Author: 17,may 2001
*
* WORK: fernando.ruiz@ctv.es
* HOME: correo@fernando-ruiz.com
*
* After start the net you can start this daemon.
* It uses the previously inited pseudo-terminales (pty.c)
* getting a new terminal with getpty(). This function
* gives a terminal name passing a opened socket like parameter.
*
* With register_telnetd() you add a new command in the shell to start
* this daemon interactively. (Login in /dev/console of course)
*
* Sorry but OOB is not still implemented. (This is the first version)
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems.h>
#include <rtems/error.h>
#include <rtems/pty.h>
#include <rtems/shell.h>
#include <rtems/telnetd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
/***********************************************************/
rtems_id telnetd_task_id =0;
rtems_unsigned32 telnetd_stack_size =16384;
rtems_task_priority telnetd_task_priority=100;
/***********************************************************/
rtems_task rtems_task_telnetd(rtems_task_argument task_argument) {
int des_socket,
acp_socket;
struct sockaddr_in srv;
char * devname;
int i=1;
int size_adr;
if ((des_socket=socket(PF_INET,SOCK_STREAM,0))<0) {
perror("telnetd:socket");
rtems_task_delete(RTEMS_SELF);
};
setsockopt(des_socket,SOL_SOCKET,0,&i,sizeof(i));
memset(&srv,0,sizeof(srv));
srv.sin_family=AF_INET;
srv.sin_port=htons(23);
size_adr=sizeof(srv);
if ((bind(des_socket,(struct sockaddr *)&srv,size_adr))<0) {
perror("telnetd:bind");
close(des_socket);
rtems_task_delete(RTEMS_SELF);
};
if ((listen(des_socket,5))<0) {
perror("telnetd:listen");
close(des_socket);
rtems_task_delete(RTEMS_SELF);
};
do {
acp_socket=accept(des_socket,(struct sockaddr*)&srv,&size_adr);
if (acp_socket<0) {
perror("telnetd:accept");
break;
};
if ((devname = get_pty(acp_socket)) ) {
shell_init(&devname[5],
telnetd_stack_size,
telnetd_task_priority,
devname,B9600|CS8,FALSE);
} else {
close(acp_socket);
};
} while(1);
close(des_socket);
rtems_task_delete(RTEMS_SELF);
}
/***********************************************************/
int rtems_initialize_telnetd(void) {
void register_icmds(void);
rtems_status_code sc;
register_icmds(); /* stats for tcp/ip */
if (telnetd_task_id ) return RTEMS_RESOURCE_IN_USE;
if (telnetd_stack_size<=0 ) telnetd_stack_size =16384;
if (telnetd_task_priority<=2) telnetd_task_priority=100;
sc=rtems_task_create(new_rtems_name("tlnd"),
100,RTEMS_MINIMUM_STACK_SIZE,
RTEMS_DEFAULT_MODES,
RTEMS_DEFAULT_ATTRIBUTES,
&telnetd_task_id);
if (sc!=RTEMS_SUCCESSFUL) {
rtems_error(sc,"creating task telnetd");
return (int)sc;
};
sc=rtems_task_start(telnetd_task_id,
rtems_task_telnetd,
(rtems_task_argument)NULL);
if (sc!=RTEMS_SUCCESSFUL) {
rtems_error(sc,"starting task telnetd");
};
return (int)sc;
}
/***********************************************************/
int main_telnetd(int argc,char * argv[]) {
rtems_status_code sc;
if (telnetd_task_id) {
printf("ERROR:telnetd already started\n");
return 1;
};
if (argc>1) telnetd_stack_size =str2int(argv[1]);
if (argc>2) telnetd_task_priority=str2int(argv[2]);
sc=rtems_initialize_telnetd();
if (sc!=RTEMS_SUCCESSFUL) return sc;
printf("rtems_telnetd() started with stacksize=%u,priority=%d\n",
telnetd_stack_size,telnetd_task_priority);
return 0;
}
/***********************************************************/
int register_telnetd(void) {
shell_add_cmd("telnetd","telnet","telnetd [stacksize [tsk_priority]]",main_telnetd);
return 0;
}
/***********************************************************/

35
cpukit/telnetd/telnetd.h Normal file
View File

@@ -0,0 +1,35 @@
/*
* (A first version for telnetd)
*
* Author: Fernando RUIZ CASAS (fernando.ruiz@ctv.es)
* May 2001
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* rtems_initialize_telnetd() starts the daemon.
* main_telnetd() is the main_proc for the command telnetd in the shell
* register_telnetd() add a new command in the shell to start
* interactively the telnetd daemon.
*
* $Id$
*/
#ifndef __TELNETD_H
#define __TELNETD_H
#ifdef __cplusplus
extern "C" {
#endif
int rtems_initialize_telnetd(void);
int main_telnetd(int argc,char * argv[]);
int register_telnetd(void);
#ifdef __cplusplus
}
#endif
#endif