source: rtems/cpukit/libmisc/shell/cmds.c @ b2712e3

4.104.114.84.95
Last change on this file since b2712e3 was b2712e3, checked in by Joel Sherrill <joel.sherrill@…>, on 05/24/01 at 21:58:39

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.

  • Property mode set to 100644
File size: 16.3 KB
Line 
1/*
2 * Author: Fernando RUIZ CASAS
3 *
4 *  Work: fernando.ruiz@ctv.es
5 *  Home: correo@fernando-ruiz.com
6 *
7 * This file is inspired in rtems_monitor & Chris John MyRightBoot
8 *
9 * But I want to make it more user friendly
10 * A 'monitor' command is added to adapt the call rtems monitor commands
11 * at my call procedure
12 *
13 * MINIX date.c is adapted to run here. Like a exercise only....
14 *
15 * TODO: A lot of improvements of course.
16 *      cp, mv, ...
17 *      hexdump,
18 *     
19 *      More? Say me it, please...
20 *     
21 *      The BSP Specific are not welcome here.
22 *     
23 * C&S welcome...
24 *
25 *  $Id$
26 */
27
28#include <stdio.h>
29#include <termios.h>
30#include <string.h>
31#include <stdlib.h>
32#include <ctype.h>
33#include <dirent.h>
34#include <time.h>
35#include <fcntl.h>
36#include <unistd.h>
37#include <pwd.h>
38#include <grp.h>
39#include <errno.h>
40#include <sys/types.h>
41#include <stddef.h>
42
43#include <rtems.h>
44#include <rtems/monitor.h>
45#include <rtems/score/tod.h>
46
47#include <imfs.h>
48#include <rtems/shell.h>
49
50/* ----------------------------------------------- *
51  - str to int "0xaffe" "0b010010" "0123" "192939"
52 * ----------------------------------------------- */
53int str2int(char * s) {
54 int sign=1;   
55 int base=10;
56 int value=0;
57 int digit;
58 if (!s) return 0;
59 if (*s) {
60  if (*s=='-') {
61   sign=-1;
62   s++;
63   if (!*s) return 0;
64  };
65  if (*s=='0') {
66   s++;
67   switch(*s) {
68    case 'x':
69    case 'X':s++;
70             base=16;
71             break;
72    case 'b':
73    case 'B':s++;
74             base=2;
75             break;
76    default :base=8;
77             break;
78   }
79  };
80  while (*s) {
81   switch(*s) {
82    case '0':
83    case '1':
84    case '2':
85    case '3':
86    case '4':
87    case '5':
88    case '6':
89    case '7':
90    case '8':
91    case '9':digit=*s-'0';
92             break;
93    case 'A':     
94    case 'B':     
95    case 'C':     
96    case 'D':     
97    case 'E':     
98    case 'F':digit=*s-'A'+10;
99             break;
100    case 'a':     
101    case 'b':     
102    case 'c':     
103    case 'd':     
104    case 'e':     
105    case 'f':digit=*s-'a'+10;
106             break;
107    default:return value*sign;       
108   };
109   if (digit>base) return value*sign;
110   value=value*base+digit;
111   s++;
112  };
113 };
114 return value*sign;     
115}
116/*----------------------------------------------------------------------------*
117 * RAM MEMORY COMMANDS
118 *----------------------------------------------------------------------------*/
119
120#define mdump_adr (current_shell_env->mdump_adr)  /* static value */
121
122int main_mdump(int argc,char * argv[]) {
123 unsigned char n,m,max=0;
124 int adr=mdump_adr;
125 unsigned char * pb;
126 if (argc>1) adr=str2int(argv[1]);
127 if (argc>2) max=str2int(argv[2]);
128 max/=16;
129 if (!max) max=20;
130 for (m=0;m<max;m++) {
131  printf("0x%08X ",adr);
132  pb=(unsigned char*) adr;
133  for (n=0;n<16;n++)
134   printf("%02X%c",pb[n],n==7?'-':' ');
135  for (n=0;n<16;n++) {
136   printf("%c",isprint(pb[n])?pb[n]:'.');
137  };
138  printf("\n");
139  adr+=16;
140 };
141 mdump_adr=adr;
142 return 0;
143}
144/*----------------------------------------------------------------------------*/
145int main_mwdump(int argc,char * argv[]) {
146 unsigned char n,m,max=0;
147 int adr=mdump_adr;
148 unsigned short * pw;
149 if (argc>1) adr=str2int(argv[1]);
150 if (argc>2) max=str2int(argv[2]);
151 max/=16;
152 if (!max) max=20;
153 for (m=0;m<max;m++) {
154  printf("0x%08X ",adr);
155  pw=(unsigned short*) adr;
156  for (n=0;n<8;n++)
157   printf("%02X %02X%c",pw[n]/0x100,pw[n]%0x100,n==3?'-':' ');
158  for (n=0;n<8;n++) {
159   printf("%c",isprint(pw[n]/0x100)?pw[n]/0x100:'.');
160   printf("%c",isprint(pw[n]%0x100)?pw[n]%0x100:'.');
161  };
162  printf("\n");
163  adr+=16;
164 };
165 mdump_adr=adr;
166 return 0;
167}
168/*----------------------------------------------------------------------------*/
169int main_medit(int argc,char * argv[]) {
170 unsigned char * pb;
171 int n,i;
172 if (argc<3) {
173  printf("too few arguments\n");
174  return 0;
175 };
176 pb=(unsigned char*)str2int(argv[1]);
177 i=2;
178 n=0;
179 while (i<=argc) {
180  pb[n++]=str2int(argv[i++])%0x100;
181 }
182 mdump_adr=(int)pb;
183 return main_mdump(0,NULL);
184}
185/*----------------------------------------------------------------------------*/
186int main_mfill(int argc,char * argv[]) {
187 int  adr;
188 int  size;
189 unsigned char value;
190 if (argc<4) {
191  printf("too few arguments\n");
192  return 0;
193 };
194 adr  =str2int(argv[1]);
195 size =str2int(argv[2]);
196 value=str2int(argv[3])%0x100;
197 memset((unsigned char*)adr,size,value);
198 mdump_adr=adr;
199 return main_mdump(0,NULL);
200}
201/*----------------------------------------------------------------------------*/
202int main_mmove(int argc,char * argv[]) {
203 int  src;
204 int  dst;
205 int  size;
206 if (argc<4) {
207  printf("too few arguments\n");
208  return 0;
209 };
210 dst  =str2int(argv[1]);
211 src  =str2int(argv[2]);
212 size =str2int(argv[3]);
213 memcpy((unsigned char*)dst,(unsigned char*)src,size);
214 mdump_adr=dst;
215 return main_mdump(0,NULL);
216}
217/*----------------------------------------------------------------------------*/
218#ifdef MALLOC_STATS  /* /rtems/s/src/lib/libc/malloc.c */
219int main_malloc_dump(int argc,char * argv[]) {
220 void malloc_dump(void);
221 malloc_dump();
222 return 0;
223}
224#endif
225/*----------------------------------------------------------------------------
226 * Reset. Assumes that the watchdog is present.
227 *----------------------------------------------------------------------------*/
228int main_reset (int argc, char **argv)
229{
230  rtems_interrupt_level level;
231  printf ("Waiting for watchdog ... ");
232  tcdrain(fileno(stdout));
233
234  rtems_interrupt_disable (level);
235  for (;;)
236      ;
237  return 0;
238}
239/*----------------------------------------------------------------------------
240 * Alias. make an alias
241 *----------------------------------------------------------------------------*/
242int main_alias (int argc, char **argv)
243{
244 if (argc<3) {
245  printf("too few arguments\n");
246  return 1;
247 };
248 if (!shell_alias_cmd(argv[1],argv[2])) {
249  printf("unable to make an alias(%s,%s)\n",argv[1],argv[2]);
250 };
251 return 0;
252
253/*-----------------------------------------------------------*         
254 * Directory commands
255 *-----------------------------------------------------------*/
256int main_ls(int argc, char *argv[])
257{
258   char * fname;
259   DIR                 *dirp;
260   struct dirent       *dp;
261   struct stat         stat_buf;
262   struct passwd     * pwd;
263   struct group      * grp;
264   char * user;
265   char * group;
266   char   sbuf[256];
267   char   nbuf[1024];
268   int  n,size;
269
270   fname=".";
271   if (argc>1) fname=argv[1];
272
273   if ((dirp = opendir(fname)) == NULL)
274   {
275      printf("%s: No such file or directory.\n", fname);
276      return errno;
277   }
278   n=0;
279   size=0;
280   while ((dp = readdir(dirp)) != NULL)
281   {
282      strcpy(nbuf,fname);
283      if (nbuf[strlen(nbuf)-1]!='/') strcat(nbuf,"/");
284      strcat(nbuf,dp->d_name); /* always the fullpathname. Avoid ftpd problem.*/
285      if (stat(nbuf, &stat_buf) == 0)
286      { /* AWFUL buts works...*/
287         strftime(sbuf,sizeof(sbuf)-1,"%b %d %H:%M",gmtime(&stat_buf.st_atime));     
288         pwd=getpwuid(stat_buf.st_uid);
289         user=pwd?pwd->pw_name:"nouser";
290         grp=getgrgid(stat_buf.st_gid);
291         group=grp?grp->gr_name:"nogrp";
292         printf("%c%c%c%c%c%c%c%c%c%c %3d %6.6s %6.6s %11d %s %s%c\n",
293                 (S_ISLNK(stat_buf.st_mode)?('l'):
294                    (S_ISDIR(stat_buf.st_mode)?('d'):('-'))),
295                 (stat_buf.st_mode & S_IRUSR)?('r'):('-'),
296                 (stat_buf.st_mode & S_IWUSR)?('w'):('-'),
297                 (stat_buf.st_mode & S_IXUSR)?('x'):('-'),
298                 (stat_buf.st_mode & S_IRGRP)?('r'):('-'),
299                 (stat_buf.st_mode & S_IWGRP)?('w'):('-'),
300                 (stat_buf.st_mode & S_IXGRP)?('x'):('-'),
301                 (stat_buf.st_mode & S_IROTH)?('r'):('-'),
302                 (stat_buf.st_mode & S_IWOTH)?('w'):('-'),
303                 (stat_buf.st_mode & S_IXOTH)?('x'):('-'),
304                 (int)stat_buf.st_nlink,
305                 user,group,
306                 (int)stat_buf.st_size,
307                 sbuf,
308                 dp->d_name,
309                 S_ISDIR(stat_buf.st_mode)?'/':' ');
310         n++;
311         size+=stat_buf.st_size;
312      }
313   }
314   printf("%d files %d bytes occupied\n",n,size);
315   closedir(dirp);
316   return 0;
317}
318/*-----------------------------------------------------------*/         
319int main_pwd (int argc, char *argv[]) {
320   char dir[1024];
321   getcwd(dir,1024);
322   printf("%s\n",dir);
323   return 0;
324}
325/*-----------------------------------------------------------*/         
326int main_chdir (int argc, char *argv[]) {
327   char *dir;
328   dir="/";
329   if (argc>1) dir=argv[1];
330   if (chdir(dir)) {
331    printf("chdir to '%s' failed:%s\n",dir,strerror(errno));
332    return errno;
333   };
334   return 0;
335}
336/*-----------------------------------------------------------*/         
337int main_mkdir (int argc, char *argv[]) {
338   char *dir;
339   dir=NULL;
340   if (argc>1) dir=argv[1];
341   if (mkdir(dir,S_IRWXU|S_IRWXG|S_IRWXO)) {
342     printf("mkdir '%s' failed:%s\n",dir,strerror(errno));
343   }; 
344   return errno;
345}
346/*-----------------------------------------------------------*/         
347int main_rmdir (int argc, char *argv[])
348{
349   char *dir;
350   dir=NULL;
351   if (argc>1) dir=argv[1];
352   if (rmdir(dir)) printf("rmdir '%s' failed:%s\n",dir,strerror(errno));
353   return errno;
354}
355/*-----------------------------------------------------------*/         
356int main_chroot(int argc,char * argv[]) {
357 char * new_root="/";
358 if (argc==2) new_root=argv[1];
359 if (chroot(new_root)<0) {
360  printf("error %s:chroot(%s);\n",strerror(errno),new_root);
361  return -1;
362 };
363 return 0;
364}
365/*-----------------------------------------------------------*/         
366int main_cat   (int argc, char *argv[])
367{
368   int n;
369   n=1;
370   while (n<argc) cat_file(stdout,argv[n++]);
371   return 0;
372}
373/*-----------------------------------------------------------*/         
374int main_rm    (int argc, char *argv[])
375{
376   int n;
377   n=1;
378   while (n<argc) {
379    if (unlink(argv[n])) {
380     printf("error %s:rm %s\n",strerror(errno),argv[n]);
381     return -1;
382    };
383    n++;
384   };
385   return 0;
386}
387/*-----------------------------------------------------------*/         
388/* date - print or set time and date            Author: Jan Looyen */
389/* MINIX 1.5 GPL'ed */
390
391
392#define MIN     60L             /* # seconds in a minute */
393#define HOUR    (60 * MIN)      /* # seconds in an hour */
394#define DAY     (24 * HOUR)     /* # seconds in a day */
395#define YEAR    (365 * DAY)     /* # seconds in a year */
396
397static int conv(unsigned32 *value,char **ptr,unsigned32 max)
398{
399  int buf;
400  *ptr -= 2;
401  buf = atoi(*ptr);
402  **ptr = 0;
403  if (buf < 0 || buf > max) {
404   fprintf(stderr, "Date: bad conversion\n");
405   return 0;
406  };
407  *value=buf;
408  return 1;
409}
410
411static int set_time(char *t)
412{
413  rtems_time_of_day tod;       
414  FILE * rtc;
415  char *tp;
416  int len;
417  if (rtems_clock_get(RTEMS_CLOCK_GET_TOD,&tod)!=RTEMS_SUCCESSFUL)
418          memset(&tod,0,sizeof(tod));
419  len = strlen(t);
420  if (len != 12 && len != 10 && len != 6 && len != 4) return 0;
421  tp = t;
422  while (*tp)
423   if (!isdigit(*tp++)) {
424    fprintf(stderr, "date: bad conversion\n");
425    return 0;
426   };
427  if (len == 6 || len == 12)
428   if (!conv(&tod.second,&tp, 59)) return 0;
429  if (!conv(&tod.minute,&tp, 59)) return 0;
430  if (!conv(&tod.hour,&tp, 23)) return 0;
431  if (len == 12 || len == 10) {
432   if (!conv(&tod.year,&tp, 99)) return 0;
433   tod.year+=1900;
434   if (tod.year<TOD_BASE_YEAR) tod.year+=100;
435   if (!conv(&tod.day   ,&tp, 31)) return 0;
436   if (!conv(&tod.month ,&tp, 12)) return 0;
437  }
438  if (!_TOD_Validate(&tod)) {
439    fprintf(stderr, "Invalid date value\n");
440  } else {
441   rtems_clock_set(&tod);         
442   rtems_clock_get(RTEMS_CLOCK_GET_TOD,&tod);     
443   rtc=fopen("/dev/rtc","r+");
444   if (rtc) {
445    fwrite(&tod,sizeof(tod),1,rtc);
446    fclose(rtc);
447   };
448  };
449  return 1;
450}
451
452int main_date(int argc,char *argv[])
453{
454  time_t t;
455  if (argc == 2) set_time(argv[1]);
456  time(&t);
457  printf("%s", ctime(&t));
458  return 0;
459}
460/*-----------------------------------------------------------*/
461int main_logoff(int argc,char *argv[])
462{
463  printf("logoff from the system..."); 
464  current_shell_env->exit_shell=TRUE;   
465  return 0;
466}
467/*-----------------------------------------------------------*/
468int main_tty   (int argc,char *argv[])
469{
470  printf("%s\n",ttyname(fileno(stdin)));
471  return 0;
472}
473/*-----------------------------------------------------------*/
474int main_whoami(int argc,char *argv[])
475{
476   struct passwd     * pwd;
477   pwd=getpwuid(getuid());
478   printf("%s\n",pwd?pwd->pw_name:"nobody");
479   return 0;
480}
481/*-----------------------------------------------------------*/
482int main_id    (int argc,char *argv[])
483{
484   struct passwd     * pwd;
485   struct group      * grp;
486   pwd=getpwuid(getuid());
487   grp=getgrgid(getgid());
488   printf("uid=%d(%s),gid=%d(%s),",
489                   getuid(),pwd?pwd->pw_name:"",
490                   getgid(),grp?grp->gr_name:"");
491   pwd=getpwuid(geteuid());
492   grp=getgrgid(getegid());
493   printf("euid=%d(%s),egid=%d(%s)\n",
494                   geteuid(),pwd?pwd->pw_name:"",
495                   getegid(),grp?grp->gr_name:"");
496   return 0;
497}
498/*-----------------------------------------------------------*/
499int main_umask(int argc,char *argv[])
500{
501   mode_t msk=umask(0);
502   if (argc == 2) msk=str2int(argv[1]);
503   umask(msk);
504   msk=umask(0);
505   printf("0%o\n",msk);
506   umask(msk);
507   return 0;
508}
509/*-----------------------------------------------------------*/
510int main_chmod(int argc,char *argv[])
511{
512   int n;
513   mode_t mode;
514   if (argc > 2){
515    mode=str2int(argv[1])&0777;
516    n=2;
517    while (n<argc) chmod(argv[n++],mode);
518   };
519   return 0;
520}
521/*-----------------------------------------------------------*         
522 * with this you can call at all the rtems monitor commands.
523 * Not all work fine but you can show the rtems status and more.
524 *-----------------------------------------------------------*/         
525int main_monitor(int argc,char * argv[]) {
526 rtems_monitor_command_entry_t *command;
527 extern rtems_monitor_command_entry_t rtems_monitor_commands[];
528 rtems_task_ident(RTEMS_SELF,0,&rtems_monitor_task_id);
529 rtems_monitor_node = rtems_get_node(rtems_monitor_task_id);
530 rtems_monitor_default_node = rtems_monitor_node;
531 if ((command=rtems_monitor_command_lookup(rtems_monitor_commands,argc,argv)))
532  command->command_function(argc, argv, command->command_arg, 0);
533 return 0;
534}
535/*-----------------------------------------------------------*/         
536void register_cmds(void) {
537  rtems_monitor_command_entry_t *command;
538  extern rtems_monitor_command_entry_t rtems_monitor_commands[];
539  /* monitor topic */
540  command=rtems_monitor_commands;
541  while (command) {
542   if (strcmp("exit",command->command)) /*Exclude EXIT (alias quit)*/
543    shell_add_cmd(command->command,"monitor",
544                  command->usage  ,main_monitor);
545   command=command->next;
546  };
547  /* dir[ectories] topic */
548  shell_add_cmd  ("ls"    ,"dir","ls [dir]     # list files in the directory" ,main_ls   );
549  shell_add_cmd  ("chdir" ,"dir","chdir [dir]  # change the current directory",main_chdir);
550  shell_add_cmd  ("rmdir" ,"dir","rmdir  dir   # remove directory"            ,main_rmdir);
551  shell_add_cmd  ("mkdir" ,"dir","mkdir  dir   # make a directory"            ,main_mkdir);
552  shell_add_cmd  ("pwd"   ,"dir","pwd          # print work directory"        ,main_pwd  );
553  shell_add_cmd  ("chroot","dir","chroot [dir] # change the root directory"   ,main_chroot);
554  shell_add_cmd  ("cat"   ,"dir","cat n1 [n2 [n3...]]# show the ascii contents",main_cat );
555  shell_add_cmd  ("rm"    ,"dir","rm n1 [n2 [n3...]]# remove files"           ,main_rm   );
556  shell_add_cmd  ("chmod" ,"dir","chmod 0777 n1 n2... #change filemode"       ,main_chmod);
557
558  shell_alias_cmd("ls"    ,"dir");
559  shell_alias_cmd("chdir" ,"cd");
560
561  /* misc. topic */
562  shell_add_cmd  ("logoff","misc","logoff from the system"                    ,main_logoff);
563  shell_alias_cmd("logoff","exit");
564  shell_add_cmd  ("date" ,"misc","date [[MMDDYY]hhmm[ss]]"                    ,main_date);
565  shell_add_cmd  ("reset","misc","reset the BSP"                              ,main_reset);
566  shell_add_cmd  ("alias","misc","alias old new"                              ,main_alias);
567  shell_add_cmd  ("tty"  ,"misc","show ttyname"                               ,main_tty  );
568  shell_add_cmd  ("whoami","misc","show current user"                         ,main_whoami);
569  shell_add_cmd  ("id"    ,"misc","show uid,gid,euid,egid"                    ,main_id    );
570  shell_add_cmd  ("umask" ,"misc","umask [new_umask]"                         ,main_umask );
571
572
573  /* memory topic */
574  shell_add_cmd  ("mdump","mem"  ,"mdump [adr [size]]"           ,main_mdump);
575  shell_add_cmd  ("wdump","mem"  ,"wdump [adr [size]]"           ,main_mwdump);
576  shell_add_cmd  ("medit","mem"  ,"medit adr value [value ...]"  ,main_medit);
577  shell_add_cmd  ("mfill","mem"  ,"mfill adr size value"         ,main_mfill);
578  shell_add_cmd  ("mmove","mem"  ,"mmove dst src size"           ,main_mmove);
579#ifdef MALLOC_STATS  /* /rtems/s/src/lib/libc/malloc.c */
580  shell_add_cmd  ("malloc","mem","mem  show memory malloc'ed"                 ,main_mem);
581#endif 
582}
583/*-----------------------------------------------------------*/         
Note: See TracBrowser for help on using the repository browser.