forked from Imagelibrary/rtems
2000-05-24 Fernando Ruiz Casas <fernando.ruiz@ctv.es>
* monitor/mon-prmisc.c: Correct print line. * shell/Makefile.am: Added new file telnetd.c. * shell/telnetd.c, shell/telnetd.h, shell/pty.c: New files. * shell/shell.c, shell/cmds.c, shell/shell.h: Numerous improvments: - The shell_init has a new parameter 'forever' because in /dev/console you need that this process runs forever but in tcp/ip not. (respawn?) - A new task for every session opened trought tcp/ip telnet client. (the chargen,daytime and more are possible of implementation but I ask me if they are necesary) - Exit from the session delete the task and when the client fails too. - More cmds have been implemented. (very reduced version of these) umask, chmod, id, whoami, rm, cat, ... - A reduced line edit has been implemented. Ctrl-C abort the input, Ctrl-d in the first position gives EOF (logout). '\b' and DEL makes the rubout operation. I think that readline() for every session spents a lot of resources.
This commit is contained in:
@@ -1,3 +1,24 @@
|
|||||||
|
2000-05-24 Fernando Ruiz Casas <fernando.ruiz@ctv.es>
|
||||||
|
|
||||||
|
* monitor/mon-prmisc.c: Correct print line.
|
||||||
|
* shell/Makefile.am: Added new file telnetd.c.
|
||||||
|
* shell/telnetd.c, shell/telnetd.h, shell/pty.c: New files.
|
||||||
|
* shell/shell.c, shell/cmds.c, shell/shell.h: Numerous improvments:
|
||||||
|
- The shell_init has a new parameter 'forever' because in
|
||||||
|
/dev/console you need that this process runs forever but in
|
||||||
|
tcp/ip not. (respawn?)
|
||||||
|
- A new task for every session opened trought tcp/ip telnet client.
|
||||||
|
(the chargen,daytime and more are possible of implementation but
|
||||||
|
I ask me if they are necesary)
|
||||||
|
- Exit from the session delete the task and when the client fails too.
|
||||||
|
- More cmds have been implemented. (very reduced version of these)
|
||||||
|
umask, chmod, id, whoami, rm, cat, ...
|
||||||
|
- A reduced line edit has been implemented.
|
||||||
|
Ctrl-C abort the input,
|
||||||
|
Ctrl-d in the first position gives EOF (logout).
|
||||||
|
'\b' and DEL makes the rubout operation.
|
||||||
|
I think that readline() for every session spents a lot of resources.
|
||||||
|
|
||||||
2001-04-28 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
2001-04-28 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
||||||
|
|
||||||
* shell/cmds.c, shell/shell.c: Remove fileno-hacks.
|
* shell/cmds.c, shell/shell.c: Remove fileno-hacks.
|
||||||
|
|||||||
@@ -108,8 +108,8 @@ rtems_monitor_dump_name(rtems_name name)
|
|||||||
for (i=0; i<sizeof(u.c); i++)
|
for (i=0; i<sizeof(u.c); i++)
|
||||||
length += rtems_monitor_dump_char(u.c[i]);
|
length += rtems_monitor_dump_char(u.c[i]);
|
||||||
#else
|
#else
|
||||||
for (i=sizeof(u.c)-1; i ; i--)
|
for (i=0; i<sizeof(u.c); i++)
|
||||||
length += rtems_monitor_dump_char(u.c[i]);
|
length += rtems_monitor_dump_char(u.c[sizeof(u.c)-1-i]);
|
||||||
#endif
|
#endif
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ include_rtemsdir = $(includedir)/rtems
|
|||||||
LIBNAME = libshell-tmp
|
LIBNAME = libshell-tmp
|
||||||
LIB = $(ARCH)/$(LIBNAME).a
|
LIB = $(ARCH)/$(LIBNAME).a
|
||||||
|
|
||||||
C_FILES = cmds.c shell.c
|
C_FILES = cmds.c shell.c pty.c telnetd.c
|
||||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
|
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
|
||||||
|
|
||||||
include_rtems_HEADERS = shell.h
|
include_rtems_HEADERS = shell.h telnetd.h
|
||||||
|
|
||||||
OBJS = $(C_O_FILES)
|
OBJS = $(C_O_FILES)
|
||||||
|
|
||||||
@@ -39,6 +39,6 @@ all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS) $(LIB)
|
|||||||
|
|
||||||
.PRECIOUS: $(LIB)
|
.PRECIOUS: $(LIB)
|
||||||
|
|
||||||
EXTRA_DIST = README shell.c cmds.c shell.h
|
EXTRA_DIST = README shell.c cmds.c pty.c telnetd.c shell.h telnetd.h
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/local.am
|
include $(top_srcdir)/../../../automake/local.am
|
||||||
|
|||||||
@@ -19,10 +19,12 @@ NOTES:
|
|||||||
2. You only need a termios dev to start a new session, add your new commands
|
2. You only need a termios dev to start a new session, add your new commands
|
||||||
and enjoy it.
|
and enjoy it.
|
||||||
|
|
||||||
|
3. 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:
|
FUTURE:
|
||||||
|
|
||||||
1. Adding new commands in cmds.c to give file manegement to shell.
|
1. Adding new commands in cmds.c to give file manegement to shell.
|
||||||
|
|
||||||
2. Create a telnetd daemon. (pseudo-terminal needed)
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
* MINIX date.c is adapted to run here. Like a exercise only....
|
* MINIX date.c is adapted to run here. Like a exercise only....
|
||||||
*
|
*
|
||||||
* TODO: A lot of improvements of course.
|
* TODO: A lot of improvements of course.
|
||||||
* cat, cp, rm, mv, ...
|
* cp, mv, ...
|
||||||
* hexdump,
|
* hexdump,
|
||||||
*
|
*
|
||||||
* More? Say me it, please...
|
* More? Say me it, please...
|
||||||
@@ -34,6 +34,8 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <grp.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@@ -257,6 +259,10 @@ int main_ls(int argc, char *argv[])
|
|||||||
DIR *dirp;
|
DIR *dirp;
|
||||||
struct dirent *dp;
|
struct dirent *dp;
|
||||||
struct stat stat_buf;
|
struct stat stat_buf;
|
||||||
|
struct passwd * pwd;
|
||||||
|
struct group * grp;
|
||||||
|
char * user;
|
||||||
|
char * group;
|
||||||
char sbuf[256];
|
char sbuf[256];
|
||||||
char nbuf[1024];
|
char nbuf[1024];
|
||||||
int n,size;
|
int n,size;
|
||||||
@@ -279,7 +285,11 @@ int main_ls(int argc, char *argv[])
|
|||||||
if (stat(nbuf, &stat_buf) == 0)
|
if (stat(nbuf, &stat_buf) == 0)
|
||||||
{ /* AWFUL buts works...*/
|
{ /* AWFUL buts works...*/
|
||||||
strftime(sbuf,sizeof(sbuf)-1,"%b %d %H:%M",gmtime(&stat_buf.st_atime));
|
strftime(sbuf,sizeof(sbuf)-1,"%b %d %H:%M",gmtime(&stat_buf.st_atime));
|
||||||
printf("%c%c%c%c%c%c%c%c%c%c %3d rtems rtems %11d %s %s%c\n",
|
pwd=getpwuid(stat_buf.st_uid);
|
||||||
|
user=pwd?pwd->pw_name:"nouser";
|
||||||
|
grp=getgrgid(stat_buf.st_gid);
|
||||||
|
group=grp?grp->gr_name:"nogrp";
|
||||||
|
printf("%c%c%c%c%c%c%c%c%c%c %3d %6.6s %6.6s %11d %s %s%c\n",
|
||||||
(S_ISLNK(stat_buf.st_mode)?('l'):
|
(S_ISLNK(stat_buf.st_mode)?('l'):
|
||||||
(S_ISDIR(stat_buf.st_mode)?('d'):('-'))),
|
(S_ISDIR(stat_buf.st_mode)?('d'):('-'))),
|
||||||
(stat_buf.st_mode & S_IRUSR)?('r'):('-'),
|
(stat_buf.st_mode & S_IRUSR)?('r'):('-'),
|
||||||
@@ -292,6 +302,7 @@ int main_ls(int argc, char *argv[])
|
|||||||
(stat_buf.st_mode & S_IWOTH)?('w'):('-'),
|
(stat_buf.st_mode & S_IWOTH)?('w'):('-'),
|
||||||
(stat_buf.st_mode & S_IXOTH)?('x'):('-'),
|
(stat_buf.st_mode & S_IXOTH)?('x'):('-'),
|
||||||
(int)stat_buf.st_nlink,
|
(int)stat_buf.st_nlink,
|
||||||
|
user,group,
|
||||||
(int)stat_buf.st_size,
|
(int)stat_buf.st_size,
|
||||||
sbuf,
|
sbuf,
|
||||||
dp->d_name,
|
dp->d_name,
|
||||||
@@ -352,6 +363,28 @@ int main_chroot(int argc,char * argv[]) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
int main_cat (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
n=1;
|
||||||
|
while (n<argc) cat_file(stdout,argv[n++]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
int main_rm (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
n=1;
|
||||||
|
while (n<argc) {
|
||||||
|
if (unlink(argv[n])) {
|
||||||
|
printf("error %s:rm %s\n",strerror(errno),argv[n]);
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
n++;
|
||||||
|
};
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
/* date - print or set time and date Author: Jan Looyen */
|
/* date - print or set time and date Author: Jan Looyen */
|
||||||
/* MINIX 1.5 GPL'ed */
|
/* MINIX 1.5 GPL'ed */
|
||||||
|
|
||||||
@@ -424,6 +457,67 @@ int main_date(int argc,char *argv[])
|
|||||||
printf("%s", ctime(&t));
|
printf("%s", ctime(&t));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
int main_logoff(int argc,char *argv[])
|
||||||
|
{
|
||||||
|
printf("logoff from the system...");
|
||||||
|
current_shell_env->exit_shell=TRUE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
int main_tty (int argc,char *argv[])
|
||||||
|
{
|
||||||
|
printf("%s\n",ttyname(fileno(stdin)));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
int main_whoami(int argc,char *argv[])
|
||||||
|
{
|
||||||
|
struct passwd * pwd;
|
||||||
|
pwd=getpwuid(getuid());
|
||||||
|
printf("%s\n",pwd?pwd->pw_name:"nobody");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
int main_id (int argc,char *argv[])
|
||||||
|
{
|
||||||
|
struct passwd * pwd;
|
||||||
|
struct group * grp;
|
||||||
|
pwd=getpwuid(getuid());
|
||||||
|
grp=getgrgid(getgid());
|
||||||
|
printf("uid=%d(%s),gid=%d(%s),",
|
||||||
|
getuid(),pwd?pwd->pw_name:"",
|
||||||
|
getgid(),grp?grp->gr_name:"");
|
||||||
|
pwd=getpwuid(geteuid());
|
||||||
|
grp=getgrgid(getegid());
|
||||||
|
printf("euid=%d(%s),egid=%d(%s)\n",
|
||||||
|
geteuid(),pwd?pwd->pw_name:"",
|
||||||
|
getegid(),grp?grp->gr_name:"");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
int main_umask(int argc,char *argv[])
|
||||||
|
{
|
||||||
|
mode_t msk=umask(0);
|
||||||
|
if (argc == 2) msk=str2int(argv[1]);
|
||||||
|
umask(msk);
|
||||||
|
msk=umask(0);
|
||||||
|
printf("0%o\n",msk);
|
||||||
|
umask(msk);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
int main_chmod(int argc,char *argv[])
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
mode_t mode;
|
||||||
|
if (argc > 2){
|
||||||
|
mode=str2int(argv[1])&0777;
|
||||||
|
n=2;
|
||||||
|
while (n<argc) chmod(argv[n++],mode);
|
||||||
|
};
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
/*-----------------------------------------------------------*
|
/*-----------------------------------------------------------*
|
||||||
* with this you can call at all the rtems monitor commands.
|
* with this you can call at all the rtems monitor commands.
|
||||||
* Not all work fine but you can show the rtems status and more.
|
* Not all work fine but you can show the rtems status and more.
|
||||||
@@ -442,6 +536,14 @@ int main_monitor(int argc,char * argv[]) {
|
|||||||
void register_cmds(void) {
|
void register_cmds(void) {
|
||||||
rtems_monitor_command_entry_t *command;
|
rtems_monitor_command_entry_t *command;
|
||||||
extern rtems_monitor_command_entry_t rtems_monitor_commands[];
|
extern rtems_monitor_command_entry_t rtems_monitor_commands[];
|
||||||
|
/* monitor topic */
|
||||||
|
command=rtems_monitor_commands;
|
||||||
|
while (command) {
|
||||||
|
if (strcmp("exit",command->command)) /*Exclude EXIT (alias quit)*/
|
||||||
|
shell_add_cmd(command->command,"monitor",
|
||||||
|
command->usage ,main_monitor);
|
||||||
|
command=command->next;
|
||||||
|
};
|
||||||
/* dir[ectories] topic */
|
/* dir[ectories] topic */
|
||||||
shell_add_cmd ("ls" ,"dir","ls [dir] # list files in the directory" ,main_ls );
|
shell_add_cmd ("ls" ,"dir","ls [dir] # list files in the directory" ,main_ls );
|
||||||
shell_add_cmd ("chdir" ,"dir","chdir [dir] # change the current directory",main_chdir);
|
shell_add_cmd ("chdir" ,"dir","chdir [dir] # change the current directory",main_chdir);
|
||||||
@@ -449,14 +551,24 @@ void register_cmds(void) {
|
|||||||
shell_add_cmd ("mkdir" ,"dir","mkdir dir # make a directory" ,main_mkdir);
|
shell_add_cmd ("mkdir" ,"dir","mkdir dir # make a directory" ,main_mkdir);
|
||||||
shell_add_cmd ("pwd" ,"dir","pwd # print work directory" ,main_pwd );
|
shell_add_cmd ("pwd" ,"dir","pwd # print work directory" ,main_pwd );
|
||||||
shell_add_cmd ("chroot","dir","chroot [dir] # change the root directory" ,main_chroot);
|
shell_add_cmd ("chroot","dir","chroot [dir] # change the root directory" ,main_chroot);
|
||||||
|
shell_add_cmd ("cat" ,"dir","cat n1 [n2 [n3...]]# show the ascii contents",main_cat );
|
||||||
|
shell_add_cmd ("rm" ,"dir","rm n1 [n2 [n3...]]# remove files" ,main_rm );
|
||||||
|
shell_add_cmd ("chmod" ,"dir","chmod 0777 n1 n2... #change filemode" ,main_chmod);
|
||||||
|
|
||||||
shell_alias_cmd("ls" ,"dir");
|
shell_alias_cmd("ls" ,"dir");
|
||||||
shell_alias_cmd("chdir" ,"cd");
|
shell_alias_cmd("chdir" ,"cd");
|
||||||
|
|
||||||
/* misc. topic */
|
/* misc. topic */
|
||||||
|
shell_add_cmd ("logoff","misc","logoff from the system" ,main_logoff);
|
||||||
|
shell_alias_cmd("logoff","exit");
|
||||||
shell_add_cmd ("date" ,"misc","date [[MMDDYY]hhmm[ss]]" ,main_date);
|
shell_add_cmd ("date" ,"misc","date [[MMDDYY]hhmm[ss]]" ,main_date);
|
||||||
shell_add_cmd ("reset","misc","reset the BSP" ,main_reset);
|
shell_add_cmd ("reset","misc","reset the BSP" ,main_reset);
|
||||||
shell_add_cmd ("alias","misc","alias old new" ,main_alias);
|
shell_add_cmd ("alias","misc","alias old new" ,main_alias);
|
||||||
|
shell_add_cmd ("tty" ,"misc","show ttyname" ,main_tty );
|
||||||
|
shell_add_cmd ("whoami","misc","show current user" ,main_whoami);
|
||||||
|
shell_add_cmd ("id" ,"misc","show uid,gid,euid,egid" ,main_id );
|
||||||
|
shell_add_cmd ("umask" ,"misc","umask [new_umask]" ,main_umask );
|
||||||
|
|
||||||
|
|
||||||
/* memory topic */
|
/* memory topic */
|
||||||
shell_add_cmd ("mdump","mem" ,"mdump [adr [size]]" ,main_mdump);
|
shell_add_cmd ("mdump","mem" ,"mdump [adr [size]]" ,main_mdump);
|
||||||
@@ -467,12 +579,5 @@ void register_cmds(void) {
|
|||||||
#ifdef MALLOC_STATS /* /rtems/s/src/lib/libc/malloc.c */
|
#ifdef MALLOC_STATS /* /rtems/s/src/lib/libc/malloc.c */
|
||||||
shell_add_cmd ("malloc","mem","mem show memory malloc'ed" ,main_mem);
|
shell_add_cmd ("malloc","mem","mem show memory malloc'ed" ,main_mem);
|
||||||
#endif
|
#endif
|
||||||
/* monitor topic */
|
|
||||||
command=rtems_monitor_commands;
|
|
||||||
while (command) {
|
|
||||||
shell_add_cmd(command->command,"monitor",
|
|
||||||
command->usage ,main_monitor);
|
|
||||||
command=command->next;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|||||||
406
c/src/libmisc/shell/pty.c
Normal file
406
c/src/libmisc/shell/pty.c
Normal file
@@ -0,0 +1,406 @@
|
|||||||
|
/*
|
||||||
|
* /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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
/*-----------------------------------------*/
|
||||||
|
#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;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAX_PTYS 16
|
||||||
|
|
||||||
|
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;
|
||||||
|
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 []="<*Interupt*>";
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
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 void
|
||||||
|
ptyStopRemoteTX(int minor) {
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
ptyStartRemoteTX(int minor) {
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
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;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
/* 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);
|
||||||
|
};
|
||||||
|
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);
|
||||||
|
}
|
||||||
@@ -12,6 +12,9 @@
|
|||||||
*
|
*
|
||||||
* $Id$
|
* $Id$
|
||||||
*/
|
*/
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@@ -19,6 +22,8 @@
|
|||||||
#include <rtems/error.h>
|
#include <rtems/error.h>
|
||||||
#include <rtems/libio.h>
|
#include <rtems/libio.h>
|
||||||
#include <rtems/libio_.h>
|
#include <rtems/libio_.h>
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/shell.h>
|
||||||
|
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -26,8 +31,8 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
|
||||||
#include <rtems/shell.h>
|
|
||||||
/* ----------------------------------------------- *
|
/* ----------------------------------------------- *
|
||||||
* This is a stupidity but is cute.
|
* This is a stupidity but is cute.
|
||||||
* ----------------------------------------------- */
|
* ----------------------------------------------- */
|
||||||
@@ -275,13 +280,21 @@ int shell_help(int argc,char * argv[]) {
|
|||||||
int shell_scanline(char * line,int size,FILE * in,FILE * out) {
|
int shell_scanline(char * line,int size,FILE * in,FILE * out) {
|
||||||
int c,col;
|
int c,col;
|
||||||
col=0;
|
col=0;
|
||||||
|
tcdrain(fileno(out));
|
||||||
for (;;) {
|
for (;;) {
|
||||||
line[col]=0;
|
line[col]=0;
|
||||||
c=fgetc(in);
|
c=fgetc(in);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case 0x04:/*Control-d*/
|
||||||
|
if (col) break;
|
||||||
case EOF :return 0;
|
case EOF :return 0;
|
||||||
|
case '\n':break;
|
||||||
|
case '\f':if (out) fputc('\f',out);
|
||||||
|
case 0x03:/*Control-C*/
|
||||||
|
line[0]=0;
|
||||||
case '\r':if (out) fputc('\n',out);
|
case '\r':if (out) fputc('\n',out);
|
||||||
return 1;
|
return 1;
|
||||||
|
case 127:
|
||||||
case '\b':if (col) {
|
case '\b':if (col) {
|
||||||
if (out) {
|
if (out) {
|
||||||
fputc('\b',out);
|
fputc('\b',out);
|
||||||
@@ -301,7 +314,8 @@ int shell_scanline(char * line,int size,FILE * in,FILE * out) {
|
|||||||
if (out) fputc('\a',out);
|
if (out) fputc('\a',out);
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
if (out) fputc('\a',out);
|
if (out)
|
||||||
|
if (c=='\a') fputc('\a',out);
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
@@ -317,6 +331,101 @@ shell_env_t global_shell_env ,
|
|||||||
|
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
|
|
||||||
|
void cat_file(FILE * out,char * name) {
|
||||||
|
FILE * fd;
|
||||||
|
int c;
|
||||||
|
if (out) {
|
||||||
|
fd=fopen(name,"r");
|
||||||
|
if (fd) {
|
||||||
|
while ((c=fgetc(fd))!=EOF) fputc(c,out);
|
||||||
|
fclose(fd);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
int shell_login(FILE * in,FILE * out) {
|
||||||
|
FILE * fd;
|
||||||
|
int c;
|
||||||
|
time_t t;
|
||||||
|
int times;
|
||||||
|
char name[128];
|
||||||
|
char pass[128];
|
||||||
|
struct passwd * passwd;
|
||||||
|
setuid(0);
|
||||||
|
setgid(0);
|
||||||
|
rtems_current_user_env->euid=
|
||||||
|
rtems_current_user_env->egid=0;
|
||||||
|
if (out) {
|
||||||
|
if((current_shell_env->devname[5]!='p')||
|
||||||
|
(current_shell_env->devname[6]!='t')||
|
||||||
|
(current_shell_env->devname[7]!='y')) {
|
||||||
|
cat_file(out,"/etc/issue");
|
||||||
|
} else {
|
||||||
|
fd=fopen("/etc/issue.net","r");
|
||||||
|
if (fd) {
|
||||||
|
while ((c=fgetc(fd))!=EOF) {
|
||||||
|
if (c=='%') {
|
||||||
|
switch(c=fgetc(fd)) {
|
||||||
|
case 't':fprintf(out,"%s",current_shell_env->devname);
|
||||||
|
break;
|
||||||
|
case 'h':fprintf(out,"0");
|
||||||
|
break;
|
||||||
|
case 'D':fprintf(out," ");
|
||||||
|
break;
|
||||||
|
case 'd':time(&t);
|
||||||
|
fprintf(out,"%s",ctime(&t));
|
||||||
|
break;
|
||||||
|
case 's':fprintf(out,"RTEMS");
|
||||||
|
break;
|
||||||
|
case 'm':fprintf(out,"(" CPU_NAME "/" CPU_MODEL_NAME ")");
|
||||||
|
break;
|
||||||
|
case 'r':fprintf(out,_RTEMS_version);
|
||||||
|
break;
|
||||||
|
case 'v':fprintf(out,"%s\n%s",_RTEMS_version,_Copyright_Notice);
|
||||||
|
break;
|
||||||
|
case '%':fprintf(out,"%%");
|
||||||
|
break;
|
||||||
|
default :fprintf(out,"%%%c",c);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
fputc(c,out);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
fclose(fd);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
times=0;
|
||||||
|
for (;;) {
|
||||||
|
times++;
|
||||||
|
if (times>3) break;
|
||||||
|
if (out) fprintf(out,"\nlogin: ");
|
||||||
|
if (!shell_scanline(name,sizeof(name),in,out )) break;
|
||||||
|
if (out) fprintf(out,"Password: ");
|
||||||
|
if (!shell_scanline(pass,sizeof(pass),in,NULL)) break;
|
||||||
|
if (out) fprintf(out,"\n");
|
||||||
|
if ((passwd=getpwnam(name))) {
|
||||||
|
setuid(passwd->pw_uid);
|
||||||
|
setgid(passwd->pw_gid);
|
||||||
|
rtems_current_user_env->euid=
|
||||||
|
rtems_current_user_env->egid=0;
|
||||||
|
chown(current_shell_env->devname,passwd->pw_uid,0);
|
||||||
|
rtems_current_user_env->euid=passwd->pw_uid;
|
||||||
|
rtems_current_user_env->egid=passwd->pw_gid;
|
||||||
|
if (!strcmp(passwd->pw_passwd,"*")) {
|
||||||
|
/* /etc/shadow */
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
/* crypt() */
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
if (out) fprintf(out,"Login incorrect\n");
|
||||||
|
};
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
rtems_task shell_shell(rtems_task_argument task_argument) {
|
rtems_task shell_shell(rtems_task_argument task_argument) {
|
||||||
|
|
||||||
shell_env_t * shell_env =(shell_env_t*) task_argument;
|
shell_env_t * shell_env =(shell_env_t*) task_argument;
|
||||||
@@ -326,36 +435,38 @@ rtems_task shell_shell(rtems_task_argument task_argument) {
|
|||||||
|
|
||||||
struct termios term;
|
struct termios term;
|
||||||
char * devname;
|
char * devname;
|
||||||
char * curdir;
|
|
||||||
|
|
||||||
|
char curdir[256];
|
||||||
char cmd[256];
|
char cmd[256];
|
||||||
char last_cmd[256]; /* to repeat 'r' */
|
char last_cmd[256]; /* to repeat 'r' */
|
||||||
int argc;
|
int argc;
|
||||||
char * argv[128];
|
char * argv[128];
|
||||||
|
|
||||||
|
sc=rtems_task_variable_add(RTEMS_SELF,(void*)¤t_shell_env,free);
|
||||||
|
if (sc!=RTEMS_SUCCESSFUL) {
|
||||||
|
rtems_error(sc,"rtems_task_variable_add(current_shell_env):");
|
||||||
|
rtems_task_delete(RTEMS_SELF);
|
||||||
|
};
|
||||||
|
|
||||||
|
current_shell_env=shell_env;
|
||||||
|
|
||||||
sc=rtems_libio_set_private_env();
|
sc=rtems_libio_set_private_env();
|
||||||
if (sc!=RTEMS_SUCCESSFUL) {
|
if (sc!=RTEMS_SUCCESSFUL) {
|
||||||
rtems_error(sc,"rtems_libio_set_private_env():");
|
rtems_error(sc,"rtems_libio_set_private_env():");
|
||||||
printk("rtems_libio_set_private_env():%d",sc);
|
|
||||||
rtems_task_delete(RTEMS_SELF);
|
rtems_task_delete(RTEMS_SELF);
|
||||||
};
|
};
|
||||||
|
|
||||||
sc=rtems_task_variable_add(RTEMS_SELF,(void*)¤t_shell_env,free);
|
|
||||||
if (sc!=RTEMS_SUCCESSFUL) {
|
|
||||||
rtems_error(sc,"rtems_task_variable_add():");
|
|
||||||
printk("rtems_task_variable_add():%d",sc);
|
|
||||||
rtems_task_delete(RTEMS_SELF);
|
|
||||||
};
|
|
||||||
|
|
||||||
current_shell_env=shell_env; /* Set the task var */
|
|
||||||
|
|
||||||
devname=shell_env->devname;
|
devname=shell_env->devname;
|
||||||
|
setuid(0);
|
||||||
|
setgid(0);
|
||||||
|
rtems_current_user_env->euid=
|
||||||
|
rtems_current_user_env->egid=0;
|
||||||
|
|
||||||
stdin =fopen(devname,"r+");
|
stdin =fopen(devname,"r+");
|
||||||
|
|
||||||
if (!stdin) {
|
if (!stdin) {
|
||||||
fprintf(stderr,"shell:unable to open stdin.%s:%s\n",devname,strerror(errno));
|
fprintf(stderr,"shell:unable to open stdin.%s:%s\n",devname,strerror(errno));
|
||||||
printk("shell:unable to open stdin.(%s)",strerror(errno));
|
|
||||||
rtems_task_delete(RTEMS_SELF);
|
rtems_task_delete(RTEMS_SELF);
|
||||||
};
|
};
|
||||||
setvbuf(stdin,NULL,_IONBF,0); /* Not buffered*/
|
setvbuf(stdin,NULL,_IONBF,0); /* Not buffered*/
|
||||||
@@ -363,7 +474,7 @@ rtems_task shell_shell(rtems_task_argument task_argument) {
|
|||||||
if (tcgetattr (fileno(stdin), &term)>=0) {
|
if (tcgetattr (fileno(stdin), &term)>=0) {
|
||||||
term.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
|
term.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
|
||||||
term.c_oflag &= ~OPOST;
|
term.c_oflag &= ~OPOST;
|
||||||
term.c_oflag |= (OPOST|ONLCR);
|
term.c_oflag |= (OPOST|ONLCR); /* But with cr+nl on output */
|
||||||
term.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
|
term.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
|
||||||
term.c_cflag = CLOCAL | CREAD |(shell_env->tcflag);
|
term.c_cflag = CLOCAL | CREAD |(shell_env->tcflag);
|
||||||
term.c_cc[VMIN] = 1;
|
term.c_cc[VMIN] = 1;
|
||||||
@@ -385,46 +496,53 @@ rtems_task shell_shell(rtems_task_argument task_argument) {
|
|||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
shell_add_cmd(NULL,NULL,NULL,NULL); /* init the chain list*/
|
shell_add_cmd(NULL,NULL,NULL,NULL); /* init the chain list*/
|
||||||
strcpy(cmd,"");
|
do {
|
||||||
printf("\n"
|
if (!shell_login(stdin,stdout)) {
|
||||||
"RTEMS-SHELL:%s. "__DATE__". 'help' to list commands.\n",devname);
|
cat_file(stdout,"/etc/motd");
|
||||||
curdir=malloc(1024);
|
strcpy(last_cmd,"");
|
||||||
chdir("/");
|
strcpy(cmd,"");
|
||||||
for (;;) {
|
printf("\n"
|
||||||
/* Prompt section */
|
"RTEMS SHELL (Version 1.0-FRC):%s. "__DATE__". 'help' to list commands.\n",devname);
|
||||||
/* XXX: show_prompt user adjustable */
|
chdir("/");
|
||||||
getcwd(curdir,1024);
|
shell_env->exit_shell=FALSE;
|
||||||
printf("%s [%s] # ",devname,curdir);
|
for (;;) {
|
||||||
/* getcmd section */
|
/* Prompt section */
|
||||||
if (!shell_scanline(cmd,sizeof(cmd),stdin,stdout)) {
|
/* XXX: show_prompt user adjustable */
|
||||||
printf("shell:unable scanline(%s)\n",devname);
|
getcwd(curdir,sizeof(curdir));
|
||||||
break;
|
printf("%s [%s] %c ",shell_env->taskname,curdir,geteuid()?'$':'#');
|
||||||
};
|
/* getcmd section */
|
||||||
/* evaluate cmd section */
|
if (!shell_scanline(cmd,sizeof(cmd),stdin,stdout)) break; /*EOF*/
|
||||||
if (!strcmp(cmd,"r")) { /* repeat last command, forced, not automatic */
|
/* evaluate cmd section */
|
||||||
strcpy(cmd,last_cmd);
|
if (!strcmp(cmd,"r")) { /* repeat last command, forced, not automatic */
|
||||||
} else
|
strcpy(cmd,last_cmd);
|
||||||
if (strcmp(cmd,"")) { /* only for get a new prompt */
|
} else
|
||||||
strcpy(last_cmd,cmd);
|
if (strcmp(cmd,"")) { /* only for get a new prompt */
|
||||||
};
|
strcpy(last_cmd,cmd);
|
||||||
/* exec cmd section */
|
|
||||||
/* TODO:
|
|
||||||
* To avoid user crash catch the signals.
|
|
||||||
* Open a new stdio files with posibility of redirection *
|
|
||||||
* Run in a new shell task background. (unix &)
|
|
||||||
* Resuming. A little bash.
|
|
||||||
*/
|
|
||||||
if (shell_make_args(cmd,&argc,argv)) {
|
|
||||||
if ((shell_cmd=shell_lookup_cmd(argv[0]))!=NULL) {
|
|
||||||
current_shell_env->errorlevel=shell_cmd->command(argc,argv);
|
|
||||||
} else {
|
|
||||||
printf("shell:%s command not found\n",argv[0]);
|
|
||||||
current_shell_env->errorlevel=-1;
|
|
||||||
};
|
};
|
||||||
|
/* exec cmd section */
|
||||||
|
/* TODO:
|
||||||
|
* To avoid user crash catch the signals.
|
||||||
|
* Open a new stdio files with posibility of redirection *
|
||||||
|
* Run in a new shell task background. (unix &)
|
||||||
|
* Resuming. A little bash.
|
||||||
|
*/
|
||||||
|
if (shell_make_args(cmd,&argc,argv)) {
|
||||||
|
if ((shell_cmd=shell_lookup_cmd(argv[0]))!=NULL) {
|
||||||
|
shell_env->errorlevel=shell_cmd->command(argc,argv);
|
||||||
|
} else {
|
||||||
|
printf("shell:%s command not found\n",argv[0]);
|
||||||
|
shell_env->errorlevel=-1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/* end exec cmd section */
|
||||||
|
if (shell_env->exit_shell) break;
|
||||||
};
|
};
|
||||||
/* end exec cmd section */
|
printf("\nGoodbye from RTEMS SHELL :-(\n");
|
||||||
};
|
};
|
||||||
free(curdir);
|
} while (shell_env->forever);
|
||||||
|
fclose(stdin );
|
||||||
|
fclose(stdout);
|
||||||
|
fclose(stderr);
|
||||||
rtems_task_delete(RTEMS_SELF);
|
rtems_task_delete(RTEMS_SELF);
|
||||||
}
|
}
|
||||||
/* ----------------------------------------------- */
|
/* ----------------------------------------------- */
|
||||||
@@ -432,14 +550,15 @@ rtems_status_code shell_init (char * task_name,
|
|||||||
rtems_unsigned32 task_stacksize,
|
rtems_unsigned32 task_stacksize,
|
||||||
rtems_task_priority task_priority,
|
rtems_task_priority task_priority,
|
||||||
char * devname,
|
char * devname,
|
||||||
tcflag_t tcflag) {
|
tcflag_t tcflag,
|
||||||
|
int forever) {
|
||||||
rtems_id task_id;
|
rtems_id task_id;
|
||||||
rtems_status_code sc;
|
rtems_status_code sc;
|
||||||
shell_env_t * shell_env;
|
shell_env_t * shell_env;
|
||||||
sc=rtems_task_create(new_rtems_name(task_name),
|
sc=rtems_task_create(new_rtems_name(task_name),
|
||||||
task_priority,
|
task_priority,
|
||||||
task_stacksize?task_stacksize:RTEMS_MINIMUM_STACK_SIZE,
|
task_stacksize?task_stacksize:RTEMS_MINIMUM_STACK_SIZE,
|
||||||
(RTEMS_DEFAULT_MODES&~RTEMS_ASR_MASK)|RTEMS_ASR,
|
RTEMS_DEFAULT_MODES,
|
||||||
RTEMS_DEFAULT_ATTRIBUTES,
|
RTEMS_DEFAULT_ATTRIBUTES,
|
||||||
&task_id);
|
&task_id);
|
||||||
if (sc!=RTEMS_SUCCESSFUL) {
|
if (sc!=RTEMS_SUCCESSFUL) {
|
||||||
@@ -454,16 +573,19 @@ rtems_status_code shell_init (char * task_name,
|
|||||||
return sc;
|
return sc;
|
||||||
};
|
};
|
||||||
if (global_shell_env.magic!=new_rtems_name("SENV")) {
|
if (global_shell_env.magic!=new_rtems_name("SENV")) {
|
||||||
global_shell_env.magic =new_rtems_name("SENV");
|
global_shell_env.magic =new_rtems_name("SENV");
|
||||||
global_shell_env.devname ="/dev/console";
|
global_shell_env.devname ="/dev/console";
|
||||||
global_shell_env.taskname="GLOBAL";
|
global_shell_env.taskname ="GLOBAL";
|
||||||
global_shell_env.tcflag =0;
|
global_shell_env.tcflag =0;
|
||||||
|
global_shell_env.exit_shell=0;
|
||||||
|
global_shell_env.forever =TRUE;
|
||||||
};
|
};
|
||||||
shell_env->magic =global_shell_env.magic;
|
shell_env->magic =global_shell_env.magic;
|
||||||
shell_env->devname =devname;
|
shell_env->devname =devname;
|
||||||
shell_env->taskname=task_name;
|
shell_env->taskname =task_name;
|
||||||
shell_env->tcflag =tcflag;
|
shell_env->tcflag =tcflag;
|
||||||
|
shell_env->exit_shell=FALSE;
|
||||||
|
shell_env->forever =forever;
|
||||||
return rtems_task_start(task_id,shell_shell,(rtems_task_argument) shell_env);
|
return rtems_task_start(task_id,shell_shell,(rtems_task_argument) shell_env);
|
||||||
}
|
}
|
||||||
/* ----------------------------------------------- */
|
/* ----------------------------------------------- */
|
||||||
|
|
||||||
|
|||||||
@@ -45,21 +45,61 @@ typedef struct {
|
|||||||
char * taskname;
|
char * taskname;
|
||||||
tcflag_t tcflag;
|
tcflag_t tcflag;
|
||||||
/* user extensions */
|
/* user extensions */
|
||||||
|
int exit_shell; /* logout */
|
||||||
|
int forever ; /* repeat login */
|
||||||
int errorlevel;
|
int errorlevel;
|
||||||
int mdump_adr;
|
int mdump_adr;
|
||||||
} shell_env_t;
|
} shell_env_t;
|
||||||
|
|
||||||
int shell_scanline(char * line,int size,FILE * in,FILE * out) ;
|
int shell_scanline(char * line,int size,FILE * in,FILE * out) ;
|
||||||
|
void cat_file(FILE * out,char *name);
|
||||||
|
|
||||||
rtems_status_code shell_init(char * task_name ,
|
rtems_status_code shell_init(char * task_name ,
|
||||||
rtems_unsigned32 task_stacksize,/*0 default*/
|
rtems_unsigned32 task_stacksize,/*0 default*/
|
||||||
rtems_task_priority task_priority ,
|
rtems_task_priority task_priority ,
|
||||||
char * devname ,
|
char * devname ,
|
||||||
tcflag_t tcflag );
|
tcflag_t tcflag ,
|
||||||
|
int forever );
|
||||||
|
|
||||||
extern shell_env_t global_shell_env,
|
extern shell_env_t global_shell_env,
|
||||||
* current_shell_env;
|
* current_shell_env;
|
||||||
/*--------*/
|
/*--------*/
|
||||||
|
/* pty.c */
|
||||||
|
/*--------*/
|
||||||
|
|
||||||
|
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 }
|
||||||
|
/*--------*/
|
||||||
/* cmds.c */
|
/* cmds.c */
|
||||||
/*--------*/
|
/*--------*/
|
||||||
int str2int(char * s);
|
int str2int(char * s);
|
||||||
|
|||||||
107
c/src/libmisc/shell/telnetd.c
Normal file
107
c/src/libmisc/shell/telnetd.c
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtems.h>
|
||||||
|
#include <rtems/error.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("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("bind");
|
||||||
|
close(des_socket);
|
||||||
|
rtems_task_delete(RTEMS_SELF);
|
||||||
|
};
|
||||||
|
if ((listen(des_socket,5))<0) {
|
||||||
|
perror("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");
|
||||||
|
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) {
|
||||||
|
rtems_status_code sc;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
/***********************************************************/
|
||||||
20
c/src/libmisc/shell/telnetd.h
Normal file
20
c/src/libmisc/shell/telnetd.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* $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
|
||||||
107
c/src/libnetworking/rtems_servers/telnetd.c
Normal file
107
c/src/libnetworking/rtems_servers/telnetd.c
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtems.h>
|
||||||
|
#include <rtems/error.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("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("bind");
|
||||||
|
close(des_socket);
|
||||||
|
rtems_task_delete(RTEMS_SELF);
|
||||||
|
};
|
||||||
|
if ((listen(des_socket,5))<0) {
|
||||||
|
perror("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");
|
||||||
|
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) {
|
||||||
|
rtems_status_code sc;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
/***********************************************************/
|
||||||
20
c/src/libnetworking/rtems_servers/telnetd.h
Normal file
20
c/src/libnetworking/rtems_servers/telnetd.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* $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
|
||||||
@@ -1,3 +1,24 @@
|
|||||||
|
2000-05-24 Fernando Ruiz Casas <fernando.ruiz@ctv.es>
|
||||||
|
|
||||||
|
* monitor/mon-prmisc.c: Correct print line.
|
||||||
|
* shell/Makefile.am: Added new file telnetd.c.
|
||||||
|
* shell/telnetd.c, shell/telnetd.h, shell/pty.c: New files.
|
||||||
|
* shell/shell.c, shell/cmds.c, shell/shell.h: Numerous improvments:
|
||||||
|
- The shell_init has a new parameter 'forever' because in
|
||||||
|
/dev/console you need that this process runs forever but in
|
||||||
|
tcp/ip not. (respawn?)
|
||||||
|
- A new task for every session opened trought tcp/ip telnet client.
|
||||||
|
(the chargen,daytime and more are possible of implementation but
|
||||||
|
I ask me if they are necesary)
|
||||||
|
- Exit from the session delete the task and when the client fails too.
|
||||||
|
- More cmds have been implemented. (very reduced version of these)
|
||||||
|
umask, chmod, id, whoami, rm, cat, ...
|
||||||
|
- A reduced line edit has been implemented.
|
||||||
|
Ctrl-C abort the input,
|
||||||
|
Ctrl-d in the first position gives EOF (logout).
|
||||||
|
'\b' and DEL makes the rubout operation.
|
||||||
|
I think that readline() for every session spents a lot of resources.
|
||||||
|
|
||||||
2001-04-28 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
2001-04-28 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
||||||
|
|
||||||
* shell/cmds.c, shell/shell.c: Remove fileno-hacks.
|
* shell/cmds.c, shell/shell.c: Remove fileno-hacks.
|
||||||
|
|||||||
@@ -108,8 +108,8 @@ rtems_monitor_dump_name(rtems_name name)
|
|||||||
for (i=0; i<sizeof(u.c); i++)
|
for (i=0; i<sizeof(u.c); i++)
|
||||||
length += rtems_monitor_dump_char(u.c[i]);
|
length += rtems_monitor_dump_char(u.c[i]);
|
||||||
#else
|
#else
|
||||||
for (i=sizeof(u.c)-1; i ; i--)
|
for (i=0; i<sizeof(u.c); i++)
|
||||||
length += rtems_monitor_dump_char(u.c[i]);
|
length += rtems_monitor_dump_char(u.c[sizeof(u.c)-1-i]);
|
||||||
#endif
|
#endif
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ include_rtemsdir = $(includedir)/rtems
|
|||||||
LIBNAME = libshell-tmp
|
LIBNAME = libshell-tmp
|
||||||
LIB = $(ARCH)/$(LIBNAME).a
|
LIB = $(ARCH)/$(LIBNAME).a
|
||||||
|
|
||||||
C_FILES = cmds.c shell.c
|
C_FILES = cmds.c shell.c pty.c telnetd.c
|
||||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
|
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
|
||||||
|
|
||||||
include_rtems_HEADERS = shell.h
|
include_rtems_HEADERS = shell.h telnetd.h
|
||||||
|
|
||||||
OBJS = $(C_O_FILES)
|
OBJS = $(C_O_FILES)
|
||||||
|
|
||||||
@@ -39,6 +39,6 @@ all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS) $(LIB)
|
|||||||
|
|
||||||
.PRECIOUS: $(LIB)
|
.PRECIOUS: $(LIB)
|
||||||
|
|
||||||
EXTRA_DIST = README shell.c cmds.c shell.h
|
EXTRA_DIST = README shell.c cmds.c pty.c telnetd.c shell.h telnetd.h
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/local.am
|
include $(top_srcdir)/../../../automake/local.am
|
||||||
|
|||||||
@@ -19,10 +19,12 @@ NOTES:
|
|||||||
2. You only need a termios dev to start a new session, add your new commands
|
2. You only need a termios dev to start a new session, add your new commands
|
||||||
and enjoy it.
|
and enjoy it.
|
||||||
|
|
||||||
|
3. 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:
|
FUTURE:
|
||||||
|
|
||||||
1. Adding new commands in cmds.c to give file manegement to shell.
|
1. Adding new commands in cmds.c to give file manegement to shell.
|
||||||
|
|
||||||
2. Create a telnetd daemon. (pseudo-terminal needed)
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
* MINIX date.c is adapted to run here. Like a exercise only....
|
* MINIX date.c is adapted to run here. Like a exercise only....
|
||||||
*
|
*
|
||||||
* TODO: A lot of improvements of course.
|
* TODO: A lot of improvements of course.
|
||||||
* cat, cp, rm, mv, ...
|
* cp, mv, ...
|
||||||
* hexdump,
|
* hexdump,
|
||||||
*
|
*
|
||||||
* More? Say me it, please...
|
* More? Say me it, please...
|
||||||
@@ -34,6 +34,8 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <grp.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@@ -257,6 +259,10 @@ int main_ls(int argc, char *argv[])
|
|||||||
DIR *dirp;
|
DIR *dirp;
|
||||||
struct dirent *dp;
|
struct dirent *dp;
|
||||||
struct stat stat_buf;
|
struct stat stat_buf;
|
||||||
|
struct passwd * pwd;
|
||||||
|
struct group * grp;
|
||||||
|
char * user;
|
||||||
|
char * group;
|
||||||
char sbuf[256];
|
char sbuf[256];
|
||||||
char nbuf[1024];
|
char nbuf[1024];
|
||||||
int n,size;
|
int n,size;
|
||||||
@@ -279,7 +285,11 @@ int main_ls(int argc, char *argv[])
|
|||||||
if (stat(nbuf, &stat_buf) == 0)
|
if (stat(nbuf, &stat_buf) == 0)
|
||||||
{ /* AWFUL buts works...*/
|
{ /* AWFUL buts works...*/
|
||||||
strftime(sbuf,sizeof(sbuf)-1,"%b %d %H:%M",gmtime(&stat_buf.st_atime));
|
strftime(sbuf,sizeof(sbuf)-1,"%b %d %H:%M",gmtime(&stat_buf.st_atime));
|
||||||
printf("%c%c%c%c%c%c%c%c%c%c %3d rtems rtems %11d %s %s%c\n",
|
pwd=getpwuid(stat_buf.st_uid);
|
||||||
|
user=pwd?pwd->pw_name:"nouser";
|
||||||
|
grp=getgrgid(stat_buf.st_gid);
|
||||||
|
group=grp?grp->gr_name:"nogrp";
|
||||||
|
printf("%c%c%c%c%c%c%c%c%c%c %3d %6.6s %6.6s %11d %s %s%c\n",
|
||||||
(S_ISLNK(stat_buf.st_mode)?('l'):
|
(S_ISLNK(stat_buf.st_mode)?('l'):
|
||||||
(S_ISDIR(stat_buf.st_mode)?('d'):('-'))),
|
(S_ISDIR(stat_buf.st_mode)?('d'):('-'))),
|
||||||
(stat_buf.st_mode & S_IRUSR)?('r'):('-'),
|
(stat_buf.st_mode & S_IRUSR)?('r'):('-'),
|
||||||
@@ -292,6 +302,7 @@ int main_ls(int argc, char *argv[])
|
|||||||
(stat_buf.st_mode & S_IWOTH)?('w'):('-'),
|
(stat_buf.st_mode & S_IWOTH)?('w'):('-'),
|
||||||
(stat_buf.st_mode & S_IXOTH)?('x'):('-'),
|
(stat_buf.st_mode & S_IXOTH)?('x'):('-'),
|
||||||
(int)stat_buf.st_nlink,
|
(int)stat_buf.st_nlink,
|
||||||
|
user,group,
|
||||||
(int)stat_buf.st_size,
|
(int)stat_buf.st_size,
|
||||||
sbuf,
|
sbuf,
|
||||||
dp->d_name,
|
dp->d_name,
|
||||||
@@ -352,6 +363,28 @@ int main_chroot(int argc,char * argv[]) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
int main_cat (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
n=1;
|
||||||
|
while (n<argc) cat_file(stdout,argv[n++]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
int main_rm (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
n=1;
|
||||||
|
while (n<argc) {
|
||||||
|
if (unlink(argv[n])) {
|
||||||
|
printf("error %s:rm %s\n",strerror(errno),argv[n]);
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
n++;
|
||||||
|
};
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
/* date - print or set time and date Author: Jan Looyen */
|
/* date - print or set time and date Author: Jan Looyen */
|
||||||
/* MINIX 1.5 GPL'ed */
|
/* MINIX 1.5 GPL'ed */
|
||||||
|
|
||||||
@@ -424,6 +457,67 @@ int main_date(int argc,char *argv[])
|
|||||||
printf("%s", ctime(&t));
|
printf("%s", ctime(&t));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
int main_logoff(int argc,char *argv[])
|
||||||
|
{
|
||||||
|
printf("logoff from the system...");
|
||||||
|
current_shell_env->exit_shell=TRUE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
int main_tty (int argc,char *argv[])
|
||||||
|
{
|
||||||
|
printf("%s\n",ttyname(fileno(stdin)));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
int main_whoami(int argc,char *argv[])
|
||||||
|
{
|
||||||
|
struct passwd * pwd;
|
||||||
|
pwd=getpwuid(getuid());
|
||||||
|
printf("%s\n",pwd?pwd->pw_name:"nobody");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
int main_id (int argc,char *argv[])
|
||||||
|
{
|
||||||
|
struct passwd * pwd;
|
||||||
|
struct group * grp;
|
||||||
|
pwd=getpwuid(getuid());
|
||||||
|
grp=getgrgid(getgid());
|
||||||
|
printf("uid=%d(%s),gid=%d(%s),",
|
||||||
|
getuid(),pwd?pwd->pw_name:"",
|
||||||
|
getgid(),grp?grp->gr_name:"");
|
||||||
|
pwd=getpwuid(geteuid());
|
||||||
|
grp=getgrgid(getegid());
|
||||||
|
printf("euid=%d(%s),egid=%d(%s)\n",
|
||||||
|
geteuid(),pwd?pwd->pw_name:"",
|
||||||
|
getegid(),grp?grp->gr_name:"");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
int main_umask(int argc,char *argv[])
|
||||||
|
{
|
||||||
|
mode_t msk=umask(0);
|
||||||
|
if (argc == 2) msk=str2int(argv[1]);
|
||||||
|
umask(msk);
|
||||||
|
msk=umask(0);
|
||||||
|
printf("0%o\n",msk);
|
||||||
|
umask(msk);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
int main_chmod(int argc,char *argv[])
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
mode_t mode;
|
||||||
|
if (argc > 2){
|
||||||
|
mode=str2int(argv[1])&0777;
|
||||||
|
n=2;
|
||||||
|
while (n<argc) chmod(argv[n++],mode);
|
||||||
|
};
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
/*-----------------------------------------------------------*
|
/*-----------------------------------------------------------*
|
||||||
* with this you can call at all the rtems monitor commands.
|
* with this you can call at all the rtems monitor commands.
|
||||||
* Not all work fine but you can show the rtems status and more.
|
* Not all work fine but you can show the rtems status and more.
|
||||||
@@ -442,6 +536,14 @@ int main_monitor(int argc,char * argv[]) {
|
|||||||
void register_cmds(void) {
|
void register_cmds(void) {
|
||||||
rtems_monitor_command_entry_t *command;
|
rtems_monitor_command_entry_t *command;
|
||||||
extern rtems_monitor_command_entry_t rtems_monitor_commands[];
|
extern rtems_monitor_command_entry_t rtems_monitor_commands[];
|
||||||
|
/* monitor topic */
|
||||||
|
command=rtems_monitor_commands;
|
||||||
|
while (command) {
|
||||||
|
if (strcmp("exit",command->command)) /*Exclude EXIT (alias quit)*/
|
||||||
|
shell_add_cmd(command->command,"monitor",
|
||||||
|
command->usage ,main_monitor);
|
||||||
|
command=command->next;
|
||||||
|
};
|
||||||
/* dir[ectories] topic */
|
/* dir[ectories] topic */
|
||||||
shell_add_cmd ("ls" ,"dir","ls [dir] # list files in the directory" ,main_ls );
|
shell_add_cmd ("ls" ,"dir","ls [dir] # list files in the directory" ,main_ls );
|
||||||
shell_add_cmd ("chdir" ,"dir","chdir [dir] # change the current directory",main_chdir);
|
shell_add_cmd ("chdir" ,"dir","chdir [dir] # change the current directory",main_chdir);
|
||||||
@@ -449,14 +551,24 @@ void register_cmds(void) {
|
|||||||
shell_add_cmd ("mkdir" ,"dir","mkdir dir # make a directory" ,main_mkdir);
|
shell_add_cmd ("mkdir" ,"dir","mkdir dir # make a directory" ,main_mkdir);
|
||||||
shell_add_cmd ("pwd" ,"dir","pwd # print work directory" ,main_pwd );
|
shell_add_cmd ("pwd" ,"dir","pwd # print work directory" ,main_pwd );
|
||||||
shell_add_cmd ("chroot","dir","chroot [dir] # change the root directory" ,main_chroot);
|
shell_add_cmd ("chroot","dir","chroot [dir] # change the root directory" ,main_chroot);
|
||||||
|
shell_add_cmd ("cat" ,"dir","cat n1 [n2 [n3...]]# show the ascii contents",main_cat );
|
||||||
|
shell_add_cmd ("rm" ,"dir","rm n1 [n2 [n3...]]# remove files" ,main_rm );
|
||||||
|
shell_add_cmd ("chmod" ,"dir","chmod 0777 n1 n2... #change filemode" ,main_chmod);
|
||||||
|
|
||||||
shell_alias_cmd("ls" ,"dir");
|
shell_alias_cmd("ls" ,"dir");
|
||||||
shell_alias_cmd("chdir" ,"cd");
|
shell_alias_cmd("chdir" ,"cd");
|
||||||
|
|
||||||
/* misc. topic */
|
/* misc. topic */
|
||||||
|
shell_add_cmd ("logoff","misc","logoff from the system" ,main_logoff);
|
||||||
|
shell_alias_cmd("logoff","exit");
|
||||||
shell_add_cmd ("date" ,"misc","date [[MMDDYY]hhmm[ss]]" ,main_date);
|
shell_add_cmd ("date" ,"misc","date [[MMDDYY]hhmm[ss]]" ,main_date);
|
||||||
shell_add_cmd ("reset","misc","reset the BSP" ,main_reset);
|
shell_add_cmd ("reset","misc","reset the BSP" ,main_reset);
|
||||||
shell_add_cmd ("alias","misc","alias old new" ,main_alias);
|
shell_add_cmd ("alias","misc","alias old new" ,main_alias);
|
||||||
|
shell_add_cmd ("tty" ,"misc","show ttyname" ,main_tty );
|
||||||
|
shell_add_cmd ("whoami","misc","show current user" ,main_whoami);
|
||||||
|
shell_add_cmd ("id" ,"misc","show uid,gid,euid,egid" ,main_id );
|
||||||
|
shell_add_cmd ("umask" ,"misc","umask [new_umask]" ,main_umask );
|
||||||
|
|
||||||
|
|
||||||
/* memory topic */
|
/* memory topic */
|
||||||
shell_add_cmd ("mdump","mem" ,"mdump [adr [size]]" ,main_mdump);
|
shell_add_cmd ("mdump","mem" ,"mdump [adr [size]]" ,main_mdump);
|
||||||
@@ -467,12 +579,5 @@ void register_cmds(void) {
|
|||||||
#ifdef MALLOC_STATS /* /rtems/s/src/lib/libc/malloc.c */
|
#ifdef MALLOC_STATS /* /rtems/s/src/lib/libc/malloc.c */
|
||||||
shell_add_cmd ("malloc","mem","mem show memory malloc'ed" ,main_mem);
|
shell_add_cmd ("malloc","mem","mem show memory malloc'ed" ,main_mem);
|
||||||
#endif
|
#endif
|
||||||
/* monitor topic */
|
|
||||||
command=rtems_monitor_commands;
|
|
||||||
while (command) {
|
|
||||||
shell_add_cmd(command->command,"monitor",
|
|
||||||
command->usage ,main_monitor);
|
|
||||||
command=command->next;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|||||||
@@ -12,6 +12,9 @@
|
|||||||
*
|
*
|
||||||
* $Id$
|
* $Id$
|
||||||
*/
|
*/
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@@ -19,6 +22,8 @@
|
|||||||
#include <rtems/error.h>
|
#include <rtems/error.h>
|
||||||
#include <rtems/libio.h>
|
#include <rtems/libio.h>
|
||||||
#include <rtems/libio_.h>
|
#include <rtems/libio_.h>
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/shell.h>
|
||||||
|
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -26,8 +31,8 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
|
||||||
#include <rtems/shell.h>
|
|
||||||
/* ----------------------------------------------- *
|
/* ----------------------------------------------- *
|
||||||
* This is a stupidity but is cute.
|
* This is a stupidity but is cute.
|
||||||
* ----------------------------------------------- */
|
* ----------------------------------------------- */
|
||||||
@@ -275,13 +280,21 @@ int shell_help(int argc,char * argv[]) {
|
|||||||
int shell_scanline(char * line,int size,FILE * in,FILE * out) {
|
int shell_scanline(char * line,int size,FILE * in,FILE * out) {
|
||||||
int c,col;
|
int c,col;
|
||||||
col=0;
|
col=0;
|
||||||
|
tcdrain(fileno(out));
|
||||||
for (;;) {
|
for (;;) {
|
||||||
line[col]=0;
|
line[col]=0;
|
||||||
c=fgetc(in);
|
c=fgetc(in);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case 0x04:/*Control-d*/
|
||||||
|
if (col) break;
|
||||||
case EOF :return 0;
|
case EOF :return 0;
|
||||||
|
case '\n':break;
|
||||||
|
case '\f':if (out) fputc('\f',out);
|
||||||
|
case 0x03:/*Control-C*/
|
||||||
|
line[0]=0;
|
||||||
case '\r':if (out) fputc('\n',out);
|
case '\r':if (out) fputc('\n',out);
|
||||||
return 1;
|
return 1;
|
||||||
|
case 127:
|
||||||
case '\b':if (col) {
|
case '\b':if (col) {
|
||||||
if (out) {
|
if (out) {
|
||||||
fputc('\b',out);
|
fputc('\b',out);
|
||||||
@@ -301,7 +314,8 @@ int shell_scanline(char * line,int size,FILE * in,FILE * out) {
|
|||||||
if (out) fputc('\a',out);
|
if (out) fputc('\a',out);
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
if (out) fputc('\a',out);
|
if (out)
|
||||||
|
if (c=='\a') fputc('\a',out);
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
@@ -317,6 +331,101 @@ shell_env_t global_shell_env ,
|
|||||||
|
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
|
|
||||||
|
void cat_file(FILE * out,char * name) {
|
||||||
|
FILE * fd;
|
||||||
|
int c;
|
||||||
|
if (out) {
|
||||||
|
fd=fopen(name,"r");
|
||||||
|
if (fd) {
|
||||||
|
while ((c=fgetc(fd))!=EOF) fputc(c,out);
|
||||||
|
fclose(fd);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
int shell_login(FILE * in,FILE * out) {
|
||||||
|
FILE * fd;
|
||||||
|
int c;
|
||||||
|
time_t t;
|
||||||
|
int times;
|
||||||
|
char name[128];
|
||||||
|
char pass[128];
|
||||||
|
struct passwd * passwd;
|
||||||
|
setuid(0);
|
||||||
|
setgid(0);
|
||||||
|
rtems_current_user_env->euid=
|
||||||
|
rtems_current_user_env->egid=0;
|
||||||
|
if (out) {
|
||||||
|
if((current_shell_env->devname[5]!='p')||
|
||||||
|
(current_shell_env->devname[6]!='t')||
|
||||||
|
(current_shell_env->devname[7]!='y')) {
|
||||||
|
cat_file(out,"/etc/issue");
|
||||||
|
} else {
|
||||||
|
fd=fopen("/etc/issue.net","r");
|
||||||
|
if (fd) {
|
||||||
|
while ((c=fgetc(fd))!=EOF) {
|
||||||
|
if (c=='%') {
|
||||||
|
switch(c=fgetc(fd)) {
|
||||||
|
case 't':fprintf(out,"%s",current_shell_env->devname);
|
||||||
|
break;
|
||||||
|
case 'h':fprintf(out,"0");
|
||||||
|
break;
|
||||||
|
case 'D':fprintf(out," ");
|
||||||
|
break;
|
||||||
|
case 'd':time(&t);
|
||||||
|
fprintf(out,"%s",ctime(&t));
|
||||||
|
break;
|
||||||
|
case 's':fprintf(out,"RTEMS");
|
||||||
|
break;
|
||||||
|
case 'm':fprintf(out,"(" CPU_NAME "/" CPU_MODEL_NAME ")");
|
||||||
|
break;
|
||||||
|
case 'r':fprintf(out,_RTEMS_version);
|
||||||
|
break;
|
||||||
|
case 'v':fprintf(out,"%s\n%s",_RTEMS_version,_Copyright_Notice);
|
||||||
|
break;
|
||||||
|
case '%':fprintf(out,"%%");
|
||||||
|
break;
|
||||||
|
default :fprintf(out,"%%%c",c);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
fputc(c,out);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
fclose(fd);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
times=0;
|
||||||
|
for (;;) {
|
||||||
|
times++;
|
||||||
|
if (times>3) break;
|
||||||
|
if (out) fprintf(out,"\nlogin: ");
|
||||||
|
if (!shell_scanline(name,sizeof(name),in,out )) break;
|
||||||
|
if (out) fprintf(out,"Password: ");
|
||||||
|
if (!shell_scanline(pass,sizeof(pass),in,NULL)) break;
|
||||||
|
if (out) fprintf(out,"\n");
|
||||||
|
if ((passwd=getpwnam(name))) {
|
||||||
|
setuid(passwd->pw_uid);
|
||||||
|
setgid(passwd->pw_gid);
|
||||||
|
rtems_current_user_env->euid=
|
||||||
|
rtems_current_user_env->egid=0;
|
||||||
|
chown(current_shell_env->devname,passwd->pw_uid,0);
|
||||||
|
rtems_current_user_env->euid=passwd->pw_uid;
|
||||||
|
rtems_current_user_env->egid=passwd->pw_gid;
|
||||||
|
if (!strcmp(passwd->pw_passwd,"*")) {
|
||||||
|
/* /etc/shadow */
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
/* crypt() */
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
if (out) fprintf(out,"Login incorrect\n");
|
||||||
|
};
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
rtems_task shell_shell(rtems_task_argument task_argument) {
|
rtems_task shell_shell(rtems_task_argument task_argument) {
|
||||||
|
|
||||||
shell_env_t * shell_env =(shell_env_t*) task_argument;
|
shell_env_t * shell_env =(shell_env_t*) task_argument;
|
||||||
@@ -326,36 +435,38 @@ rtems_task shell_shell(rtems_task_argument task_argument) {
|
|||||||
|
|
||||||
struct termios term;
|
struct termios term;
|
||||||
char * devname;
|
char * devname;
|
||||||
char * curdir;
|
|
||||||
|
|
||||||
|
char curdir[256];
|
||||||
char cmd[256];
|
char cmd[256];
|
||||||
char last_cmd[256]; /* to repeat 'r' */
|
char last_cmd[256]; /* to repeat 'r' */
|
||||||
int argc;
|
int argc;
|
||||||
char * argv[128];
|
char * argv[128];
|
||||||
|
|
||||||
|
sc=rtems_task_variable_add(RTEMS_SELF,(void*)¤t_shell_env,free);
|
||||||
|
if (sc!=RTEMS_SUCCESSFUL) {
|
||||||
|
rtems_error(sc,"rtems_task_variable_add(current_shell_env):");
|
||||||
|
rtems_task_delete(RTEMS_SELF);
|
||||||
|
};
|
||||||
|
|
||||||
|
current_shell_env=shell_env;
|
||||||
|
|
||||||
sc=rtems_libio_set_private_env();
|
sc=rtems_libio_set_private_env();
|
||||||
if (sc!=RTEMS_SUCCESSFUL) {
|
if (sc!=RTEMS_SUCCESSFUL) {
|
||||||
rtems_error(sc,"rtems_libio_set_private_env():");
|
rtems_error(sc,"rtems_libio_set_private_env():");
|
||||||
printk("rtems_libio_set_private_env():%d",sc);
|
|
||||||
rtems_task_delete(RTEMS_SELF);
|
rtems_task_delete(RTEMS_SELF);
|
||||||
};
|
};
|
||||||
|
|
||||||
sc=rtems_task_variable_add(RTEMS_SELF,(void*)¤t_shell_env,free);
|
|
||||||
if (sc!=RTEMS_SUCCESSFUL) {
|
|
||||||
rtems_error(sc,"rtems_task_variable_add():");
|
|
||||||
printk("rtems_task_variable_add():%d",sc);
|
|
||||||
rtems_task_delete(RTEMS_SELF);
|
|
||||||
};
|
|
||||||
|
|
||||||
current_shell_env=shell_env; /* Set the task var */
|
|
||||||
|
|
||||||
devname=shell_env->devname;
|
devname=shell_env->devname;
|
||||||
|
setuid(0);
|
||||||
|
setgid(0);
|
||||||
|
rtems_current_user_env->euid=
|
||||||
|
rtems_current_user_env->egid=0;
|
||||||
|
|
||||||
stdin =fopen(devname,"r+");
|
stdin =fopen(devname,"r+");
|
||||||
|
|
||||||
if (!stdin) {
|
if (!stdin) {
|
||||||
fprintf(stderr,"shell:unable to open stdin.%s:%s\n",devname,strerror(errno));
|
fprintf(stderr,"shell:unable to open stdin.%s:%s\n",devname,strerror(errno));
|
||||||
printk("shell:unable to open stdin.(%s)",strerror(errno));
|
|
||||||
rtems_task_delete(RTEMS_SELF);
|
rtems_task_delete(RTEMS_SELF);
|
||||||
};
|
};
|
||||||
setvbuf(stdin,NULL,_IONBF,0); /* Not buffered*/
|
setvbuf(stdin,NULL,_IONBF,0); /* Not buffered*/
|
||||||
@@ -363,7 +474,7 @@ rtems_task shell_shell(rtems_task_argument task_argument) {
|
|||||||
if (tcgetattr (fileno(stdin), &term)>=0) {
|
if (tcgetattr (fileno(stdin), &term)>=0) {
|
||||||
term.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
|
term.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
|
||||||
term.c_oflag &= ~OPOST;
|
term.c_oflag &= ~OPOST;
|
||||||
term.c_oflag |= (OPOST|ONLCR);
|
term.c_oflag |= (OPOST|ONLCR); /* But with cr+nl on output */
|
||||||
term.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
|
term.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
|
||||||
term.c_cflag = CLOCAL | CREAD |(shell_env->tcflag);
|
term.c_cflag = CLOCAL | CREAD |(shell_env->tcflag);
|
||||||
term.c_cc[VMIN] = 1;
|
term.c_cc[VMIN] = 1;
|
||||||
@@ -385,46 +496,53 @@ rtems_task shell_shell(rtems_task_argument task_argument) {
|
|||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
shell_add_cmd(NULL,NULL,NULL,NULL); /* init the chain list*/
|
shell_add_cmd(NULL,NULL,NULL,NULL); /* init the chain list*/
|
||||||
strcpy(cmd,"");
|
do {
|
||||||
printf("\n"
|
if (!shell_login(stdin,stdout)) {
|
||||||
"RTEMS-SHELL:%s. "__DATE__". 'help' to list commands.\n",devname);
|
cat_file(stdout,"/etc/motd");
|
||||||
curdir=malloc(1024);
|
strcpy(last_cmd,"");
|
||||||
chdir("/");
|
strcpy(cmd,"");
|
||||||
for (;;) {
|
printf("\n"
|
||||||
/* Prompt section */
|
"RTEMS SHELL (Version 1.0-FRC):%s. "__DATE__". 'help' to list commands.\n",devname);
|
||||||
/* XXX: show_prompt user adjustable */
|
chdir("/");
|
||||||
getcwd(curdir,1024);
|
shell_env->exit_shell=FALSE;
|
||||||
printf("%s [%s] # ",devname,curdir);
|
for (;;) {
|
||||||
/* getcmd section */
|
/* Prompt section */
|
||||||
if (!shell_scanline(cmd,sizeof(cmd),stdin,stdout)) {
|
/* XXX: show_prompt user adjustable */
|
||||||
printf("shell:unable scanline(%s)\n",devname);
|
getcwd(curdir,sizeof(curdir));
|
||||||
break;
|
printf("%s [%s] %c ",shell_env->taskname,curdir,geteuid()?'$':'#');
|
||||||
};
|
/* getcmd section */
|
||||||
/* evaluate cmd section */
|
if (!shell_scanline(cmd,sizeof(cmd),stdin,stdout)) break; /*EOF*/
|
||||||
if (!strcmp(cmd,"r")) { /* repeat last command, forced, not automatic */
|
/* evaluate cmd section */
|
||||||
strcpy(cmd,last_cmd);
|
if (!strcmp(cmd,"r")) { /* repeat last command, forced, not automatic */
|
||||||
} else
|
strcpy(cmd,last_cmd);
|
||||||
if (strcmp(cmd,"")) { /* only for get a new prompt */
|
} else
|
||||||
strcpy(last_cmd,cmd);
|
if (strcmp(cmd,"")) { /* only for get a new prompt */
|
||||||
};
|
strcpy(last_cmd,cmd);
|
||||||
/* exec cmd section */
|
|
||||||
/* TODO:
|
|
||||||
* To avoid user crash catch the signals.
|
|
||||||
* Open a new stdio files with posibility of redirection *
|
|
||||||
* Run in a new shell task background. (unix &)
|
|
||||||
* Resuming. A little bash.
|
|
||||||
*/
|
|
||||||
if (shell_make_args(cmd,&argc,argv)) {
|
|
||||||
if ((shell_cmd=shell_lookup_cmd(argv[0]))!=NULL) {
|
|
||||||
current_shell_env->errorlevel=shell_cmd->command(argc,argv);
|
|
||||||
} else {
|
|
||||||
printf("shell:%s command not found\n",argv[0]);
|
|
||||||
current_shell_env->errorlevel=-1;
|
|
||||||
};
|
};
|
||||||
|
/* exec cmd section */
|
||||||
|
/* TODO:
|
||||||
|
* To avoid user crash catch the signals.
|
||||||
|
* Open a new stdio files with posibility of redirection *
|
||||||
|
* Run in a new shell task background. (unix &)
|
||||||
|
* Resuming. A little bash.
|
||||||
|
*/
|
||||||
|
if (shell_make_args(cmd,&argc,argv)) {
|
||||||
|
if ((shell_cmd=shell_lookup_cmd(argv[0]))!=NULL) {
|
||||||
|
shell_env->errorlevel=shell_cmd->command(argc,argv);
|
||||||
|
} else {
|
||||||
|
printf("shell:%s command not found\n",argv[0]);
|
||||||
|
shell_env->errorlevel=-1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/* end exec cmd section */
|
||||||
|
if (shell_env->exit_shell) break;
|
||||||
};
|
};
|
||||||
/* end exec cmd section */
|
printf("\nGoodbye from RTEMS SHELL :-(\n");
|
||||||
};
|
};
|
||||||
free(curdir);
|
} while (shell_env->forever);
|
||||||
|
fclose(stdin );
|
||||||
|
fclose(stdout);
|
||||||
|
fclose(stderr);
|
||||||
rtems_task_delete(RTEMS_SELF);
|
rtems_task_delete(RTEMS_SELF);
|
||||||
}
|
}
|
||||||
/* ----------------------------------------------- */
|
/* ----------------------------------------------- */
|
||||||
@@ -432,14 +550,15 @@ rtems_status_code shell_init (char * task_name,
|
|||||||
rtems_unsigned32 task_stacksize,
|
rtems_unsigned32 task_stacksize,
|
||||||
rtems_task_priority task_priority,
|
rtems_task_priority task_priority,
|
||||||
char * devname,
|
char * devname,
|
||||||
tcflag_t tcflag) {
|
tcflag_t tcflag,
|
||||||
|
int forever) {
|
||||||
rtems_id task_id;
|
rtems_id task_id;
|
||||||
rtems_status_code sc;
|
rtems_status_code sc;
|
||||||
shell_env_t * shell_env;
|
shell_env_t * shell_env;
|
||||||
sc=rtems_task_create(new_rtems_name(task_name),
|
sc=rtems_task_create(new_rtems_name(task_name),
|
||||||
task_priority,
|
task_priority,
|
||||||
task_stacksize?task_stacksize:RTEMS_MINIMUM_STACK_SIZE,
|
task_stacksize?task_stacksize:RTEMS_MINIMUM_STACK_SIZE,
|
||||||
(RTEMS_DEFAULT_MODES&~RTEMS_ASR_MASK)|RTEMS_ASR,
|
RTEMS_DEFAULT_MODES,
|
||||||
RTEMS_DEFAULT_ATTRIBUTES,
|
RTEMS_DEFAULT_ATTRIBUTES,
|
||||||
&task_id);
|
&task_id);
|
||||||
if (sc!=RTEMS_SUCCESSFUL) {
|
if (sc!=RTEMS_SUCCESSFUL) {
|
||||||
@@ -454,16 +573,19 @@ rtems_status_code shell_init (char * task_name,
|
|||||||
return sc;
|
return sc;
|
||||||
};
|
};
|
||||||
if (global_shell_env.magic!=new_rtems_name("SENV")) {
|
if (global_shell_env.magic!=new_rtems_name("SENV")) {
|
||||||
global_shell_env.magic =new_rtems_name("SENV");
|
global_shell_env.magic =new_rtems_name("SENV");
|
||||||
global_shell_env.devname ="/dev/console";
|
global_shell_env.devname ="/dev/console";
|
||||||
global_shell_env.taskname="GLOBAL";
|
global_shell_env.taskname ="GLOBAL";
|
||||||
global_shell_env.tcflag =0;
|
global_shell_env.tcflag =0;
|
||||||
|
global_shell_env.exit_shell=0;
|
||||||
|
global_shell_env.forever =TRUE;
|
||||||
};
|
};
|
||||||
shell_env->magic =global_shell_env.magic;
|
shell_env->magic =global_shell_env.magic;
|
||||||
shell_env->devname =devname;
|
shell_env->devname =devname;
|
||||||
shell_env->taskname=task_name;
|
shell_env->taskname =task_name;
|
||||||
shell_env->tcflag =tcflag;
|
shell_env->tcflag =tcflag;
|
||||||
|
shell_env->exit_shell=FALSE;
|
||||||
|
shell_env->forever =forever;
|
||||||
return rtems_task_start(task_id,shell_shell,(rtems_task_argument) shell_env);
|
return rtems_task_start(task_id,shell_shell,(rtems_task_argument) shell_env);
|
||||||
}
|
}
|
||||||
/* ----------------------------------------------- */
|
/* ----------------------------------------------- */
|
||||||
|
|
||||||
|
|||||||
@@ -45,21 +45,61 @@ typedef struct {
|
|||||||
char * taskname;
|
char * taskname;
|
||||||
tcflag_t tcflag;
|
tcflag_t tcflag;
|
||||||
/* user extensions */
|
/* user extensions */
|
||||||
|
int exit_shell; /* logout */
|
||||||
|
int forever ; /* repeat login */
|
||||||
int errorlevel;
|
int errorlevel;
|
||||||
int mdump_adr;
|
int mdump_adr;
|
||||||
} shell_env_t;
|
} shell_env_t;
|
||||||
|
|
||||||
int shell_scanline(char * line,int size,FILE * in,FILE * out) ;
|
int shell_scanline(char * line,int size,FILE * in,FILE * out) ;
|
||||||
|
void cat_file(FILE * out,char *name);
|
||||||
|
|
||||||
rtems_status_code shell_init(char * task_name ,
|
rtems_status_code shell_init(char * task_name ,
|
||||||
rtems_unsigned32 task_stacksize,/*0 default*/
|
rtems_unsigned32 task_stacksize,/*0 default*/
|
||||||
rtems_task_priority task_priority ,
|
rtems_task_priority task_priority ,
|
||||||
char * devname ,
|
char * devname ,
|
||||||
tcflag_t tcflag );
|
tcflag_t tcflag ,
|
||||||
|
int forever );
|
||||||
|
|
||||||
extern shell_env_t global_shell_env,
|
extern shell_env_t global_shell_env,
|
||||||
* current_shell_env;
|
* current_shell_env;
|
||||||
/*--------*/
|
/*--------*/
|
||||||
|
/* pty.c */
|
||||||
|
/*--------*/
|
||||||
|
|
||||||
|
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 }
|
||||||
|
/*--------*/
|
||||||
/* cmds.c */
|
/* cmds.c */
|
||||||
/*--------*/
|
/*--------*/
|
||||||
int str2int(char * s);
|
int str2int(char * s);
|
||||||
|
|||||||
Reference in New Issue
Block a user