forked from Imagelibrary/rtems
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.
This commit is contained in:
@@ -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;
|
||||
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;
|
||||
}
|
||||
FILE *fd;
|
||||
int c;
|
||||
time_t t;
|
||||
int times;
|
||||
char name[128];
|
||||
char pass[128];
|
||||
struct passwd *passwd;
|
||||
|
||||
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];
|
||||
|
||||
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();
|
||||
if (sc!=RTEMS_SUCCESSFUL) {
|
||||
rtems_error(sc,"rtems_libio_set_private_env():");
|
||||
rtems_task_delete(RTEMS_SELF);
|
||||
};
|
||||
|
||||
|
||||
devname=shell_env->devname;
|
||||
init_issue();
|
||||
setuid(0);
|
||||
setgid(0);
|
||||
rtems_current_user_env->euid=
|
||||
rtems_current_user_env->egid=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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stdin =fopen(devname,"r+");
|
||||
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;
|
||||
}
|
||||
|
||||
if (!stdin) {
|
||||
fprintf(stderr,"shell:unable to open stdin.%s:%s\n",devname,strerror(errno));
|
||||
rtems_task_delete(RTEMS_SELF);
|
||||
#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_shell_loop( shell_env );
|
||||
rtems_task_delete( RTEMS_SELF );
|
||||
}
|
||||
|
||||
|
||||
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_task_variable_add(RTEMS_SELF,(void*)¤t_shell_env,free);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
rtems_error(sc,"rtems_task_variable_add(current_shell_env):");
|
||||
return FALSE;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user