Changeset b2712e3 in rtems for cpukit/libmisc/shell/shell.c


Ignore:
Timestamp:
May 24, 2001, 9:58:39 PM (20 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
87fb080d
Parents:
e565720a
Message:

2000-05-24 Fernando Ruiz Casas <fernando.ruiz@…>

  • 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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libmisc/shell/shell.c

    re565720a rb2712e3  
    1313 *  $Id$
    1414 */
     15#ifdef HAVE_CONFIG_H
     16#include "config.h"
     17#endif
    1518
    1619#include <stdio.h>
     
    2023#include <rtems/libio.h>
    2124#include <rtems/libio_.h>
     25#include <rtems/system.h>
     26#include <rtems/shell.h>
    2227
    2328#include <termios.h>
     
    2732#include <unistd.h>
    2833#include <errno.h>
    29 
    30 #include <rtems/shell.h>
     34#include <pwd.h>
     35
    3136/* ----------------------------------------------- *
    3237 * This is a stupidity but is cute.
     
    276281  int c,col;
    277282  col=0;
     283  tcdrain(fileno(out));
    278284  for (;;) {
    279285   line[col]=0;   
    280286   c=fgetc(in);
    281287   switch (c) {
     288    case 0x04:/*Control-d*/
     289              if (col) break;
    282290    case EOF :return 0;
     291    case '\n':break;
     292    case '\f':if (out) fputc('\f',out);
     293    case 0x03:/*Control-C*/
     294              line[0]=0;
    283295    case '\r':if (out) fputc('\n',out);
    284296              return 1;
     297    case  127:
    285298    case '\b':if (col) {
    286299               if (out) {
     
    302315                };
    303316              } else {
    304                 if (out) fputc('\a',out);
     317                if (out)
     318                 if (c=='\a') fputc('\a',out);
    305319              };
    306320              break;
     
    318332extern char **environ;   
    319333
     334void cat_file(FILE * out,char * name) {
     335        FILE * fd;
     336        int c;
     337        if (out) {
     338          fd=fopen(name,"r");
     339          if (fd) {
     340           while ((c=fgetc(fd))!=EOF) fputc(c,out);
     341           fclose(fd);
     342          };
     343        }; 
     344}
     345
     346int shell_login(FILE * in,FILE * out) {
     347        FILE * fd;
     348        int c;
     349        time_t t;
     350        int times;
     351        char name[128];
     352        char pass[128];
     353        struct passwd * passwd;
     354        setuid(0);
     355        setgid(0);
     356        rtems_current_user_env->euid=
     357        rtems_current_user_env->egid=0;
     358        if (out) {
     359         if((current_shell_env->devname[5]!='p')||
     360            (current_shell_env->devname[6]!='t')||
     361            (current_shell_env->devname[7]!='y')) {
     362           cat_file(out,"/etc/issue");
     363         } else { 
     364          fd=fopen("/etc/issue.net","r");
     365          if (fd) {
     366           while ((c=fgetc(fd))!=EOF) {
     367            if (c=='%')  {
     368             switch(c=fgetc(fd)) {
     369              case 't':fprintf(out,"%s",current_shell_env->devname);
     370                      break;
     371              case 'h':fprintf(out,"0");
     372                      break;
     373              case 'D':fprintf(out," ");
     374                      break;
     375              case 'd':time(&t);
     376                      fprintf(out,"%s",ctime(&t));
     377                      break;
     378              case 's':fprintf(out,"RTEMS");
     379                      break;
     380              case 'm':fprintf(out,"(" CPU_NAME "/" CPU_MODEL_NAME ")");
     381                      break;
     382              case 'r':fprintf(out,_RTEMS_version);
     383                      break;
     384              case 'v':fprintf(out,"%s\n%s",_RTEMS_version,_Copyright_Notice);
     385                      break;
     386              case '%':fprintf(out,"%%");
     387                      break;
     388              default :fprintf(out,"%%%c",c);
     389                      break;
     390             };
     391            } else {
     392             fputc(c,out);                             
     393            };
     394           };
     395           fclose(fd);
     396          }
     397         };
     398        };
     399        times=0;
     400        for (;;) {
     401                times++;
     402                if (times>3) break;
     403                if (out) fprintf(out,"\nlogin: ");
     404                if (!shell_scanline(name,sizeof(name),in,out )) break;
     405                if (out) fprintf(out,"Password: ");
     406                if (!shell_scanline(pass,sizeof(pass),in,NULL)) break;
     407                if (out) fprintf(out,"\n");
     408                if ((passwd=getpwnam(name))) {
     409                 setuid(passwd->pw_uid);                       
     410                 setgid(passwd->pw_gid);                       
     411                 rtems_current_user_env->euid=
     412                 rtems_current_user_env->egid=0;
     413                 chown(current_shell_env->devname,passwd->pw_uid,0);
     414                 rtems_current_user_env->euid=passwd->pw_uid;                   
     415                 rtems_current_user_env->egid=passwd->pw_gid;                   
     416                 if (!strcmp(passwd->pw_passwd,"*")) {
     417                 /* /etc/shadow */
     418                  return 0;
     419                 } else {
     420                  /* crypt() */
     421                  return 0;
     422                 };
     423                };
     424                if (out) fprintf(out,"Login incorrect\n");
     425        };
     426        return -1;
     427}
     428
    320429rtems_task shell_shell(rtems_task_argument task_argument) {
    321430
     
    327436  struct termios term; 
    328437  char * devname;
    329   char * curdir;
    330 
     438
     439  char curdir[256];
    331440  char cmd[256];
    332441  char last_cmd[256]; /* to repeat 'r' */
     
    334443  char * argv[128];
    335444
     445  sc=rtems_task_variable_add(RTEMS_SELF,(void*)&current_shell_env,free);
     446  if (sc!=RTEMS_SUCCESSFUL) {
     447   rtems_error(sc,"rtems_task_variable_add(current_shell_env):");       
     448   rtems_task_delete(RTEMS_SELF);
     449  };
     450
     451  current_shell_env=shell_env; 
     452 
    336453  sc=rtems_libio_set_private_env();
    337454  if (sc!=RTEMS_SUCCESSFUL) {
    338455   rtems_error(sc,"rtems_libio_set_private_env():");     
    339    printk("rtems_libio_set_private_env():%d",sc);       
    340456   rtems_task_delete(RTEMS_SELF);
    341457  };
    342458
    343   sc=rtems_task_variable_add(RTEMS_SELF,(void*)&current_shell_env,free);
    344   if (sc!=RTEMS_SUCCESSFUL) {
    345    rtems_error(sc,"rtems_task_variable_add():");         
    346    printk("rtems_task_variable_add():%d",sc);   
    347    rtems_task_delete(RTEMS_SELF);
    348   };
    349 
    350   current_shell_env=shell_env; /* Set the task var */
    351459
    352460  devname=shell_env->devname;
     461  setuid(0);
     462  setgid(0);
     463  rtems_current_user_env->euid=
     464  rtems_current_user_env->egid=0;
    353465
    354466  stdin =fopen(devname,"r+");
     
    356468  if (!stdin) {
    357469   fprintf(stderr,"shell:unable to open stdin.%s:%s\n",devname,strerror(errno));
    358    printk("shell:unable to open stdin.(%s)",strerror(errno));   
    359470   rtems_task_delete(RTEMS_SELF);
    360471  };
     
    364475   term.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
    365476   term.c_oflag &= ~OPOST;
    366    term.c_oflag |= (OPOST|ONLCR);
     477   term.c_oflag |= (OPOST|ONLCR); /* But with cr+nl on output */
    367478   term.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
    368479   term.c_cflag  = CLOCAL | CREAD |(shell_env->tcflag);
     
    386497  };
    387498  shell_add_cmd(NULL,NULL,NULL,NULL); /* init the chain list*/
    388   strcpy(cmd,"");
    389   printf("\n"
    390          "RTEMS-SHELL:%s. "__DATE__". 'help' to list commands.\n",devname);
    391   curdir=malloc(1024);
    392   chdir("/");
    393   for (;;) {
    394    /* Prompt section */   
    395    /* XXX: show_prompt user adjustable */
    396    getcwd(curdir,1024);
    397    printf("%s [%s] # ",devname,curdir);
    398    /* getcmd section */   
    399    if (!shell_scanline(cmd,sizeof(cmd),stdin,stdout)) {
    400     printf("shell:unable scanline(%s)\n",devname);     
    401     break;
    402    };
    403    /* evaluate cmd section */     
    404    if (!strcmp(cmd,"r")) {  /* repeat last command, forced, not automatic */
    405     strcpy(cmd,last_cmd);
    406    } else
    407    if (strcmp(cmd,"")) { /* only for get a new prompt */
    408     strcpy(last_cmd,cmd);
    409    };
    410    /* exec cmd section */         
    411    /* TODO:
    412     *  To avoid user crash catch the signals.
    413     *  Open a new stdio files with posibility of redirection *
    414     *  Run in a new shell task background. (unix &)
    415     *  Resuming. A little bash.
    416     */   
    417    if (shell_make_args(cmd,&argc,argv)) {
    418     if ((shell_cmd=shell_lookup_cmd(argv[0]))!=NULL) {
    419      current_shell_env->errorlevel=shell_cmd->command(argc,argv);
    420     } else {
    421      printf("shell:%s command not found\n",argv[0]);
    422      current_shell_env->errorlevel=-1;
     499  do {
     500  if (!shell_login(stdin,stdout))  {
     501   cat_file(stdout,"/etc/motd");
     502   strcpy(last_cmd,"");
     503   strcpy(cmd,"");
     504   printf("\n"
     505          "RTEMS SHELL (Version 1.0-FRC):%s. "__DATE__". 'help' to list commands.\n",devname);
     506   chdir("/");
     507   shell_env->exit_shell=FALSE;
     508   for (;;) {
     509    /* Prompt section */         
     510    /* XXX: show_prompt user adjustable */
     511    getcwd(curdir,sizeof(curdir));
     512    printf("%s [%s] %c ",shell_env->taskname,curdir,geteuid()?'$':'#');
     513    /* getcmd section */         
     514    if (!shell_scanline(cmd,sizeof(cmd),stdin,stdout)) break; /*EOF*/
     515    /* evaluate cmd section */   
     516    if (!strcmp(cmd,"r")) {  /* repeat last command, forced, not automatic */
     517     strcpy(cmd,last_cmd);
     518    } else
     519    if (strcmp(cmd,"")) { /* only for get a new prompt */
     520     strcpy(last_cmd,cmd);
     521    };
     522    /* exec cmd section */       
     523    /* TODO:
     524     *  To avoid user crash catch the signals.
     525     *  Open a new stdio files with posibility of redirection *
     526     *  Run in a new shell task background. (unix &)
     527     *  Resuming. A little bash.
     528     */   
     529    if (shell_make_args(cmd,&argc,argv)) {
     530     if ((shell_cmd=shell_lookup_cmd(argv[0]))!=NULL) {
     531      shell_env->errorlevel=shell_cmd->command(argc,argv);
     532     } else {
     533      printf("shell:%s command not found\n",argv[0]);
     534      shell_env->errorlevel=-1;
     535     };
    423536    };
    424    };
    425    /* end exec cmd section */     
    426   };
    427   free(curdir);
     537    /* end exec cmd section */   
     538    if (shell_env->exit_shell)  break;
     539   };
     540   printf("\nGoodbye from RTEMS SHELL :-(\n");
     541  };
     542  } while (shell_env->forever);
     543  fclose(stdin );
     544  fclose(stdout);
     545  fclose(stderr);
    428546  rtems_task_delete(RTEMS_SELF);
    429547}
     
    433551                                rtems_task_priority task_priority,
    434552                                char * devname,
    435                                 tcflag_t tcflag) {
     553                                tcflag_t tcflag,
     554                                int forever) {
    436555 rtems_id task_id;
    437556 rtems_status_code sc;
     
    440559                     task_priority,
    441560                     task_stacksize?task_stacksize:RTEMS_MINIMUM_STACK_SIZE,
    442                      (RTEMS_DEFAULT_MODES&~RTEMS_ASR_MASK)|RTEMS_ASR,
     561                     RTEMS_DEFAULT_MODES,
    443562                     RTEMS_DEFAULT_ATTRIBUTES,
    444563                     &task_id);
     
    455574 };
    456575 if (global_shell_env.magic!=new_rtems_name("SENV")) {
    457   global_shell_env.magic   =new_rtems_name("SENV");
    458   global_shell_env.devname ="/dev/console";
    459   global_shell_env.taskname="GLOBAL";
    460   global_shell_env.tcflag   =0;
     576  global_shell_env.magic     =new_rtems_name("SENV");
     577  global_shell_env.devname   ="/dev/console";
     578  global_shell_env.taskname  ="GLOBAL";
     579  global_shell_env.tcflag    =0;
     580  global_shell_env.exit_shell=0;
     581  global_shell_env.forever   =TRUE;
    461582 };
    462  shell_env->magic   =global_shell_env.magic;
    463  shell_env->devname =devname;
    464  shell_env->taskname=task_name;
    465  shell_env->tcflag  =tcflag;
     583 shell_env->magic     =global_shell_env.magic;
     584 shell_env->devname   =devname;
     585 shell_env->taskname  =task_name;
     586 shell_env->tcflag    =tcflag;
     587 shell_env->exit_shell=FALSE;
     588 shell_env->forever   =forever;
    466589 return rtems_task_start(task_id,shell_shell,(rtems_task_argument) shell_env);
    467590}
    468591/* ----------------------------------------------- */
    469 
Note: See TracChangeset for help on using the changeset viewer.