summaryrefslogtreecommitdiffstats
path: root/cpukit/libmisc/shell/shell.c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2007-11-09 21:39:21 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2007-11-09 21:39:21 +0000
commit6dd411aa14c471b5657e3b53098ee13d772bc626 (patch)
tree738f5c2a3adcfd35f07e8157b74a7546485c348b /cpukit/libmisc/shell/shell.c
parentRegenerate. (diff)
downloadrtems-6dd411aa14c471b5657e3b53098ee13d772bc626.tar.bz2
2007-11-09 Joel Sherrill <joel.sherrill@oarcorp.com>
* libmisc/shell/shell.c, libmisc/shell/shell.h: Much cleanup but much of the focus was on the beginning stages of making the login checker pluggable just like the shell.
Diffstat (limited to 'cpukit/libmisc/shell/shell.c')
-rw-r--r--cpukit/libmisc/shell/shell.c774
1 files changed, 421 insertions, 353 deletions
diff --git a/cpukit/libmisc/shell/shell.c b/cpukit/libmisc/shell/shell.c
index 5a67d5dd24..cd2dc7c899 100644
--- a/cpukit/libmisc/shell/shell.c
+++ b/cpukit/libmisc/shell/shell.c
@@ -39,9 +39,9 @@
* This is a stupidity but is cute.
* ----------------------------------------------- */
uint32_t new_rtems_name(char * rtems_name) {
- static char b[5];
- sprintf(b,"%-4.4s",rtems_name);
- return rtems_build_name(b[0],b[1],b[2],b[3]);
+ static char b[5];
+ sprintf(b,"%-4.4s",rtems_name);
+ return rtems_build_name(b[0],b[1],b[2],b[3]);
}
/* **************************************************************
* common linked list of shell commands.
@@ -57,13 +57,16 @@ struct shell_topic_tt;
typedef struct shell_topic_tt shell_topic_t;
struct shell_topic_tt {
- char * topic;
- shell_topic_t * next;
+ char * topic;
+ shell_topic_t * next;
};
static shell_cmd_t * shell_first_cmd;
static shell_topic_t * shell_first_topic;
+
+shell_env_t *shell_init_env(shell_env_t *);
+
/* ----------------------------------------------- *
* Using Chain I can reuse the rtems code.
* I am more comfortable with this, sorry.
@@ -111,8 +114,8 @@ shell_cmd_t * shell_lookup_cmd(char * cmd) {
}
/* ----------------------------------------------- */
shell_cmd_t * shell_add_cmd(char * cmd,
- char * topic,
- char * usage,
+ char * topic,
+ char * usage,
shell_command_t command) {
int shell_help(int argc,char * argv[]);
shell_cmd_t * shell_cmd,*shell_pvt;
@@ -153,7 +156,7 @@ shell_cmd_t * shell_alias_cmd(char * cmd, char * alias) {
};
if ((shell_cmd=shell_lookup_cmd(cmd))!=NULL) {
shell_aux=shell_add_cmd(alias,shell_cmd->topic,
- shell_cmd->usage,shell_cmd->command);
+ shell_cmd->usage,shell_cmd->command);
if (shell_aux) shell_aux->alias=shell_cmd;
};
};
@@ -164,8 +167,8 @@ shell_cmd_t * shell_alias_cmd(char * cmd, char * alias) {
* TODO: Redirection capture. "" evaluate, ... C&S welcome.
* ----------------------------------------------- */
int shell_make_args(char * cmd,
- int * pargc,
- char * argv[]) {
+ int * pargc,
+ char * argv[]) {
int argc=0;
while ((cmd=strtok(cmd," \t\r\n"))!=NULL) {
argv[argc++]=cmd;
@@ -180,11 +183,11 @@ int shell_make_args(char * cmd,
int shell_help_cmd(shell_cmd_t * shell_cmd) {
char * pc;
int col,line;
- fprintf(stdout,"%-10.10s -",shell_cmd->name);
+ printf("%-10.10s -",shell_cmd->name);
col=12;
line=1;
if (shell_cmd->alias) {
- fprintf(stdout,"is an <alias> for command '%s'",shell_cmd->alias->name);
+ printf("is an <alias> for command '%s'",shell_cmd->alias->name);
} else
if (shell_cmd->usage) {
pc=shell_cmd->usage;
@@ -206,7 +209,7 @@ int shell_help_cmd(shell_cmd_t * shell_cmd) {
};
};
if (!col && *pc) {
- fprintf(stdout," ");
+ printf(" ");
col=12;line++;
};
};
@@ -224,51 +227,53 @@ int shell_help(int argc,char * argv[]) {
shell_topic_t *topic;
shell_cmd_t * shell_cmd=shell_first_cmd;
if (argc<2) {
- fprintf(stdout,"help: ('r' repeat last cmd - 'e' edit last cmd)\n"
+ printf("help: ('r' repeat last cmd - 'e' edit last cmd)\n"
" TOPIC? The topics are\n");
topic=shell_first_topic;
col=0;
while (topic) {
if (!col){
- col=fprintf(stdout," %s",topic->topic);
+ col=printf(" %s",topic->topic);
} else {
if ((col+strlen(topic->topic)+2)>78){
- fprintf(stdout,"\n");
- col=fprintf(stdout," %s",topic->topic);
+ printf("\n");
+ col=printf(" %s",topic->topic);
} else {
- col+=fprintf(stdout,", %s",topic->topic);
+ col+=printf(", %s",topic->topic);
};
};
topic=topic->next;
};
- fprintf(stdout,"\n");
+ printf("\n");
return 1;
};
line=0;
for (arg=1;arg<argc;arg++) {
if (line>16) {
- fprintf(stdout,"Press any key to continue...");getchar();
- fprintf(stdout,"\n");
+ printf("Press any key to continue...");getchar();
+ printf("\n");
line=0;
};
topic=shell_lookup_topic(argv[arg]);
if (!topic){
if ((shell_cmd=shell_lookup_cmd(argv[arg]))==NULL) {
- fprintf(stdout,"help: topic or cmd '%s' not found. Try <help> alone for a list\n",argv[arg]);
+ printf("help: topic or cmd '%s' not found. Try <help> alone for a list\n",
+ argv[arg]);
line++;
} else {
line+=shell_help_cmd(shell_cmd);
}
continue;
};
- fprintf(stdout,"help: list for the topic '%s'\n",argv[arg]);
+ printf("help: list for the topic '%s'\n",argv[arg]);
line++;
while (shell_cmd) {
if (!strcmp(topic->topic,shell_cmd->topic))
line+=shell_help_cmd(shell_cmd);
if (line>16) {
- fprintf(stdout,"Press any key to continue...");getchar();
- fprintf(stdout,"\n");
+ printf("Press any key to continue...");
+ getchar();
+ printf("\n");
line=0;
};
shell_cmd=shell_cmd->next;
@@ -287,45 +292,45 @@ int shell_scanline(char * line,int size,FILE * in,FILE * out) {
col=strlen(line);
if (out) fprintf(out,"%s",line);
};
- tcdrain(fileno(in ));
+ tcdrain(fileno(in));
if (out) tcdrain(fileno(out));
for (;;) {
line[col]=0;
- c=fgetc(in);
+ c = fgetc(in);
switch (c) {
case 0x04:/*Control-d*/
- if (col) break;
+ if (col) break;
case EOF :return 0;
case '\n':break;
case '\f':if (out) fputc('\f',out);
case 0x03:/*Control-C*/
- line[0]=0;
+ line[0]=0;
case '\r':if (out) fputc('\n',out);
- return 1;
+ return 1;
case 127:
case '\b':if (col) {
- if (out) {
- fputc('\b',out);
- fputc(' ',out);
- fputc('\b',out);
- };
- col--;
- } else {
- if (out) fputc('\a',out);
- };
- break;
+ if (out) {
+ fputc('\b',out);
+ fputc(' ',out);
+ fputc('\b',out);
+ };
+ col--;
+ } else {
+ if (out) fputc('\a',out);
+ };
+ break;
default :if (!iscntrl(c)) {
- if (col<size-1) {
- line[col++]=c;
- if (out) fputc(c,out);
- } else {
- if (out) fputc('\a',out);
- };
- } else {
- if (out)
- if (c=='\a') fputc('\a',out);
- };
- break;
+ if (col<size-1) {
+ line[col++]=c;
+ if (out) fputc(c,out);
+ } else {
+ if (out) fputc('\a',out);
+ };
+ } else {
+ if (out)
+ if (c=='\a') fputc('\a',out);
+ };
+ break;
};
};
}
@@ -334,30 +339,30 @@ int shell_scanline(char * line,int size,FILE * in,FILE * out) {
* Poor but enough..
* TODO: Redirection. Tty Signals. ENVVARs. Shell language.
* ----------------------------------------------- */
-shell_env_t global_shell_env ,
- * current_shell_env=&global_shell_env;
+shell_env_t global_shell_env;
+shell_env_t *current_shell_env;
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);
- };
- };
+ FILE * fd;
+ int c;
+ if (out) {
+ fd=fopen(name,"r");
+ if (fd) {
+ while ((c=fgetc(fd))!=EOF) fputc(c,out);
+ fclose(fd);
+ };
+ };
}
void write_file(char * name,char * content) {
- FILE * fd;
- fd=fopen(name,"w");
- if (fd) {
- fwrite(content,1,strlen(content),fd);
- fclose(fd);
- };
+ FILE * fd;
+ fd=fopen(name,"w");
+ if (fd) {
+ fwrite(content,1,strlen(content),fd);
+ fclose(fd);
+ };
}
void init_issue(void) {
@@ -368,198 +373,227 @@ void init_issue(void) {
getpwnam("root"); /* dummy call to init /etc dir */
if (stat("/etc/issue",&buf))
write_file("/etc/issue",
- "Welcome to @V\\n"
- "Login into @S(@L)\\n");
+ "Welcome to @V\\n"
+ "Login into @S\\n");
if (stat("/etc/issue.net",&buf))
write_file("/etc/issue.net",
- "Welcome to %v\n"
- "running on %m\n");
+ "Welcome to %v\n"
+ "running on %m\n");
}
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;
- init_issue();
- 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')) {
- fd=fopen("/etc/issue","r");
- if (fd) {
- while ((c=fgetc(fd))!=EOF) {
- if (c=='@') {
- switch(c=fgetc(fd)) {
- case 'L':fprintf(out,"%s",current_shell_env->devname);
- break;
- case 'B':fprintf(out,"0");
- break;
+ FILE *fd;
+ int c;
+ time_t t;
+ int times;
+ char name[128];
+ char pass[128];
+ struct passwd *passwd;
+
+ init_issue();
+ 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')) {
+ fd = fopen("/etc/issue","r");
+ if (fd) {
+ while ((c=fgetc(fd))!=EOF) {
+ if (c=='@') {
+ switch(c=fgetc(fd)) {
+ case 'L':
+ fprintf(out,"%s",current_shell_env->devname);
+ break;
+ case 'B':
+ fprintf(out,"0");
+ break;
case 'T':
- case 'D':time(&t);
- fprintf(out,"%s",ctime(&t));
- break;
- case 'S':fprintf(out,"RTEMS");
- break;
- case 'V':fprintf(out,"%s\n%s",_RTEMS_version,_Copyright_Notice);
- break;
- case '@':fprintf(out,"@");
- break;
- default :fprintf(out,"@%c",c);
- break;
- };
- } else
- if (c=='\\') {
- switch(c=fgetc(fd)) {
- case '\\':fprintf(out,"\\");
- break;
- case 'b':fprintf(out,"\b"); break;
- case 'f':fprintf(out,"\f"); break;
- case 'n':fprintf(out,"\n"); break;
- case 'r':fprintf(out,"\r"); break;
- case 's':fprintf(out," "); break;
- case 't':fprintf(out,"\t"); break;
- case '@':fprintf(out,"@"); break;
- };
- } else {
- fputc(c,out);
- };
- };
- fclose(fd);
- }
- } 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;
- strcpy(name,"");
- strcpy(pass,"");
- 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))) {
- if (strcmp(passwd->pw_passwd,"!")) { /* valid user */
- 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");
- strcpy(name,"");
- strcpy(pass,"");
- };
- return -1;
+ case 'D':
+ time(&t);
+ fprintf(out,"%s",ctime(&t));
+ break;
+ case 'S':
+ fprintf(out,"RTEMS");
+ break;
+ case 'V':
+ fprintf(out,"%s\n%s",_RTEMS_version,_Copyright_Notice);
+ break;
+ case '@':
+ fprintf(out,"@");
+ break;
+ default :
+ fprintf(out,"@%c",c);
+ break;
+ }
+ } else if (c=='\\') {
+ switch(c=fgetc(fd)) {
+ case '\\': fprintf(out,"\\"); break;
+ case 'b': fprintf(out,"\b"); break;
+ case 'f': fprintf(out,"\f"); break;
+ case 'n': fprintf(out,"\n"); break;
+ case 'r': fprintf(out,"\r"); break;
+ case 's': fprintf(out," "); break;
+ case 't': fprintf(out,"\t"); break;
+ case '@': fprintf(out,"@"); break;
+ }
+ } else {
+ fputc(c,out);
+ }
+ }
+ fclose(fd);
+ }
+ } 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;
+ strcpy(name,"");
+ strcpy(pass,"");
+ 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))) {
+ if (strcmp(passwd->pw_passwd,"!")) { /* valid user */
+ 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");
+ strcpy(name,"");
+ strcpy(pass,"");
+ }
+ return -1;
}
-rtems_task shell_shell(rtems_task_argument task_argument) {
+#if 0
+void shell_print_env(
+ shell_env_t * shell_env
+)
+{
+ if ( !shell_env ) {
+ printk( "shell_env is NULL\n" );
+ return;
+ }
+ printk( "shell_env=%p\n"
+ "shell_env->magic=0x%08x\t"
+ "shell_env->devname=%s\n"
+ "shell_env->taskname=%s\t"
+ "shell_env->tcflag=%d\n"
+ "shell_env->exit_shell=%d\t"
+ "shell_env->forever=%d\n",
+ shell_env->magic,
+ shell_env->devname,
+ ((shell_env->taskname) ? shell_env->taskname : "NOT SET"),
+ shell_env->tcflag,
+ shell_env->exit_shell,
+ shell_env->forever
+ );
+}
+#endif
+rtems_task shell_shell(rtems_task_argument task_argument)
+{
shell_env_t * shell_env =(shell_env_t*) task_argument;
- shell_cmd_t * shell_cmd;
-
- rtems_status_code sc;
-
- struct termios term;
- char * devname;
- char curdir[256];
- char cmd[256];
- char last_cmd[256]; /* to repeat 'r' */
- int argc;
- char * argv[128];
+ shell_shell_loop( shell_env );
+ rtems_task_delete( RTEMS_SELF );
+}
- sc=rtems_task_variable_add(RTEMS_SELF,(void*)&current_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;
+rtems_boolean shell_shell_loop(
+ shell_env_t *shell_env_arg
+)
+{
+ shell_env_t *shell_env;
+ shell_cmd_t *shell_cmd;
+ rtems_status_code sc;
+ struct termios term;
+ char curdir[256];
+ char cmd[256];
+ char last_cmd[256]; /* to repeat 'r' */
+ int argc;
+ char *argv[128];
- sc=rtems_libio_set_private_env();
- if (sc!=RTEMS_SUCCESSFUL) {
- rtems_error(sc,"rtems_libio_set_private_env():");
- rtems_task_delete(RTEMS_SELF);
+ sc = rtems_task_variable_add(RTEMS_SELF,(void*)&current_shell_env,free);
+ if (sc != RTEMS_SUCCESSFUL) {
+ rtems_error(sc,"rtems_task_variable_add(current_shell_env):");
+ return FALSE;
};
-
- devname=shell_env->devname;
+ shell_env =
+ current_shell_env = shell_init_env( shell_env_arg );
+
setuid(0);
setgid(0);
- rtems_current_user_env->euid=
- rtems_current_user_env->egid=0;
-
- /*
- * newlib delays the creation of default stdio 'til the
- * first I/O operation, therefore we must perform dummy
- * operations before we redirect stdio
- */
- ftell(stdin);
- ftell(stdout);
- ftell(stderr);
-
- stdin =fopen(devname,"r+");
-
- if (!stdin) {
- fprintf(stderr,"shell:unable to open stdin.%s:%s\n",devname,strerror(errno));
- rtems_task_delete(RTEMS_SELF);
- };
+ rtems_current_user_env->euid =
+ rtems_current_user_env->egid = 0;
+
setvbuf(stdin,NULL,_IONBF,0); /* Not buffered*/
- /* make a raw terminal,Linux MANuals */
+ /* make a raw terminal,Linux Manuals */
if (tcgetattr (fileno(stdin), &term)>=0) {
term.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
term.c_oflag &= ~OPOST;
@@ -569,123 +603,157 @@ rtems_task shell_shell(rtems_task_argument task_argument) {
term.c_cc[VMIN] = 1;
term.c_cc[VTIME] = 0;
if (tcsetattr (fileno(stdin), TCSADRAIN, &term) < 0) {
- fprintf(stderr,"shell:cannot set terminal attributes(%s)\n",devname);
- };
- stdout=fopen(devname,"r+");
- if (!stdout) {
- fprintf(stderr,"shell:unable to open stdout.%s:%s\n",devname,strerror(errno));
+ fprintf(stderr,
+ "shell:cannot set terminal attributes(%s)\n",shell_env->devname);
};
setvbuf(stdout,NULL,_IONBF,0); /* Not buffered*/
- stderr=fopen(devname,"r+");
- if (!stderr) {
- fprintf(stdout,"shell:unable to open stderr.%s:%s\n",devname,strerror(errno));
- };
- /* when the future user environment runs ok
- * a freopen() reopens the terminals. Now this don't work
- * (sorry but you can't use because FILENO_STDIN!=0. Better fileno(stdin))
- */
- };
+ }
+
shell_add_cmd(NULL,NULL,NULL,NULL); /* init the chain list*/
do {
- /* Set again root user and root filesystem, side effect of set_priv..*/
- sc=rtems_libio_set_private_env();
- if (sc!=RTEMS_SUCCESSFUL) {
- rtems_error(sc,"rtems_libio_set_private_env():");
- rtems_task_delete(RTEMS_SELF);
- };
- if (!shell_login(stdin,stdout)) {
- cat_file(stdout,"/etc/motd");
- strcpy(last_cmd,"");
- strcpy(cmd,"");
- fprintf(stdout,"\n"
- "RTEMS SHELL (Ver.1.0-FRC):%s. "__DATE__". 'help' to list commands.\n",devname);
- chdir("/"); /* XXX: chdir to getpwent homedir */
- shell_env->exit_shell=FALSE;
- for (;;) {
- /* Prompt section */
- /* XXX: show_prompt user adjustable */
- getcwd(curdir,sizeof(curdir));
- fprintf(stdout,"%s [%s] %c ",shell_env->taskname,curdir,geteuid()?'$':'#');
- /* getcmd section */
- if (!shell_scanline(cmd,sizeof(cmd),stdin,stdout)) break; /*EOF*/
- /* evaluate cmd section */
- if (!strcmp(cmd,"e")) { /* edit last command */
- strcpy(cmd,last_cmd);
- continue;
- } else
- if (!strcmp(cmd,"r")) { /* repeat last command */
- strcpy(cmd,last_cmd);
- } else
- 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) {
- shell_env->errorlevel=shell_cmd->command(argc,argv);
- } else {
- fprintf(stdout,"shell:%s command not found\n",argv[0]);
- shell_env->errorlevel=-1;
- };
- };
- /* end exec cmd section */
- if (shell_env->exit_shell) break;
- cmd[0]=0;
- };
- fprintf(stdout,"\nGoodbye from RTEMS SHELL :-(\n");
- };
+ /* Set again root user and root filesystem, side effect of set_priv..*/
+ sc = rtems_libio_set_private_env();
+ if (sc != RTEMS_SUCCESSFUL) {
+ rtems_error(sc,"rtems_libio_set_private_env():");
+ return FALSE;
+ }
+ if (!shell_login(stdin,stdout)) {
+ cat_file(stdout,"/etc/motd");
+ strcpy(last_cmd,"");
+ strcpy(cmd,"");
+ printf("\n"
+ "RTEMS SHELL (Ver.1.0-FRC):%s. "__DATE__". 'help' to list commands.\n",
+ shell_env->devname);
+ chdir("/"); /* XXX: chdir to getpwent homedir */
+ shell_env->exit_shell=FALSE;
+ for (;;) {
+ /* Prompt section */
+ /* XXX: show_prompt user adjustable */
+ getcwd(curdir,sizeof(curdir));
+ printf( "%s%s[%s] %c ",
+ ((shell_env->taskname) ? shell_env->taskname : ""),
+ ((shell_env->taskname) ? " " : ""),
+ curdir,
+ geteuid()?'$':'#'
+ );
+ /* getcmd section */
+ if (!shell_scanline(cmd,sizeof(cmd),stdin,stdout)) {
+ break; /*EOF*/
+ }
+
+ /* evaluate cmd section */
+ if (!strcmp(cmd,"e")) { /* edit last command */
+ strcpy(cmd,last_cmd);
+ continue;
+ } else if (!strcmp(cmd,"r")) { /* repeat last command */
+ strcpy(cmd,last_cmd);
+ } else if (!strcmp(cmd,"bye")) { /* exit to telnetd */
+ printf("Shell exiting\n" );
+ return TRUE;
+ } else if (!strcmp(cmd,"exit")) { /* exit application */
+ printf("System shutting down at user request\n" );
+ exit(0);
+ } else 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) {
+ 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;
+ strcpy(last_cmd, cmd);
+ cmd[0]=0;
+ }
+ printf("\nGoodbye from RTEMS SHELL :-(\n");
+ fflush( stdout );
+ fflush( stderr );
+ }
} while (shell_env->forever);
- fclose(stdin );
- fclose(stdout);
- fclose(stderr);
- rtems_task_delete(RTEMS_SELF);
+ return TRUE;
}
+
/* ----------------------------------------------- */
-rtems_status_code shell_init (char * task_name,
- uint32_t task_stacksize,
- rtems_task_priority task_priority,
- char * devname,
- tcflag_t tcflag,
- int forever) {
- rtems_id task_id;
- rtems_status_code sc;
- shell_env_t * shell_env;
- sc=rtems_task_create(new_rtems_name(task_name),
- task_priority,
- task_stacksize?task_stacksize:RTEMS_MINIMUM_STACK_SIZE,
- RTEMS_DEFAULT_MODES,
- RTEMS_LOCAL | RTEMS_FLOATING_POINT,
- &task_id);
- if (sc!=RTEMS_SUCCESSFUL) {
- rtems_error(sc,"creating task %s in shell_init()",task_name);
- return sc;
- };
- shell_env=malloc(sizeof(shell_env_t));
- if (!shell_env) {
- rtems_task_delete(task_id);
- sc=RTEMS_NO_MEMORY;
- rtems_error(sc,"allocating shell_env %s in shell_init()",task_name);
- return sc;
- };
- if (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.taskname ="GLOBAL";
- 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->devname =devname;
- shell_env->taskname =task_name;
- 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);
+rtems_status_code shell_init (
+ char *task_name,
+ uint32_t task_stacksize,
+ rtems_task_priority task_priority,
+ char *devname,
+ tcflag_t tcflag,
+ int forever
+)
+{
+ rtems_id task_id;
+ rtems_status_code sc;
+ shell_env_t *shell_env;
+
+ sc = rtems_task_create(
+ new_rtems_name(task_name),
+ task_priority,
+ task_stacksize?task_stacksize:RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_LOCAL | RTEMS_FLOATING_POINT,
+ &task_id
+ );
+ if (sc != RTEMS_SUCCESSFUL) {
+ rtems_error(sc,"creating task %s in shell_init()",task_name);
+ return sc;
+ }
+
+ shell_env = shell_init_env( NULL );
+ if ( !shell_env ) {
+ rtems_error(sc,"allocating shell_env %s in shell_init()",task_name);
+ return RTEMS_NO_MEMORY;
+ }
+ shell_env->devname = devname;
+ shell_env->taskname = task_name;
+ 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);
+}
+
+shell_env_t *shell_init_env(
+ shell_env_t *shell_env_arg
+)
+{
+ shell_env_t *shell_env;
+
+ shell_env = shell_env_arg;
+
+ if ( !shell_env ) {
+ shell_env = malloc(sizeof(shell_env_t));
+ if ( !shell_env )
+ return NULL;
+ }
+
+ if (global_shell_env.magic != new_rtems_name("SENV")) {
+ global_shell_env.magic = new_rtems_name("SENV");
+ global_shell_env.devname = "";
+ global_shell_env.taskname = "GLOBAL";
+ global_shell_env.tcflag = 0;
+ global_shell_env.exit_shell = 0;
+ global_shell_env.forever = TRUE;
+ }
+
+ *shell_env = global_shell_env;
+ shell_env->taskname = NULL;
+ shell_env->forever = FALSE;
+
+ return shell_env;
}