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

4.104.114.84.95
Last change on this file since dd74e612 was dd74e612, checked in by Joel Sherrill <joel.sherrill@…>, on Apr 20, 2001 at 8:35:45 PM

2001-04-20 Correo Fernando-ruiz <correo@…>

  • Added initial shell functionality.
  • Makefile.am, configure.in, wrapup/Makefile.am:
  • shell/.cvsignore, shell/Makefile.am, shell/README, shell/cmds.c, shell/shell.c, shell/shell.h: New files.
  • Property mode set to 100644
File size: 13.2 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 *      cat, cp, rm, 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#undef  __STRICT_ANSI__ /* fileno() */
29#include <stdio.h>
30#include <termios.h>
31#include <string.h>
32#include <stdlib.h>
33#include <ctype.h>
34#include <dirent.h>
35#include <time.h>
36#include <fcntl.h>
37#include <unistd.h>
38#include <errno.h>
39#include <sys/types.h>
40#include <stddef.h>
41
42#include <rtems.h>
43#include <rtems/monitor.h>
44#include <rtems/score/tod.h>
45
46#include <imfs.h>
47#include <rtems/shell.h>
48
49/* ----------------------------------------------- *
50  - str to int "0xaffe" "0b010010" "0123" "192939"
51 * ----------------------------------------------- */
52int str2int(char * s) {
53 int sign=1;   
54 int base=10;
55 int value=0;
56 int digit;
57 if (!s) return 0;
58 if (*s) {
59  if (*s=='-') {
60   sign=-1;
61   s++;
62   if (!*s) return 0;
63  };
64  if (*s=='0') {
65   s++;
66   switch(*s) {
67    case 'x':
68    case 'X':s++;
69             base=16;
70             break;
71    case 'b':
72    case 'B':s++;
73             base=2;
74             break;
75    default :base=8;
76             break;
77   }
78  }; 
79  while (*s) {
80   switch(*s) {
81    case '0':
82    case '1':
83    case '2':
84    case '3':
85    case '4':
86    case '5':
87    case '6':
88    case '7':
89    case '8':
90    case '9':digit=*s-'0';
91             break;
92    case 'A':     
93    case 'B':     
94    case 'C':     
95    case 'D':     
96    case 'E':     
97    case 'F':digit=*s-'A'+10;
98             break;
99    case 'a':     
100    case 'b':     
101    case 'c':     
102    case 'd':     
103    case 'e':     
104    case 'f':digit=*s-'a'+10;
105             break;
106    default:return value*sign;       
107   };
108   if (digit>base) return value*sign;
109   value=value*base+digit;
110   s++;
111  };
112 };
113 return value*sign;     
114}
115/*----------------------------------------------------------------------------*
116 * RAM MEMORY COMMANDS
117 *----------------------------------------------------------------------------*/
118
119#define mdump_adr (current_shell_env->mdump_adr)  /* static value */
120
121int main_mdump(int argc,char * argv[]) {
122 unsigned char n,m,max=0;
123 int adr=mdump_adr;
124 unsigned char * pb;
125 if (argc>1) adr=str2int(argv[1]);
126 if (argc>2) max=str2int(argv[2]);
127 max/=16;
128 if (!max) max=20;
129 for (m=0;m<max;m++) {
130  printf("0x%08X ",adr);
131  pb=(unsigned char*) adr;
132  for (n=0;n<16;n++)
133   printf("%02X%c",pb[n],n==7?'-':' ');
134  for (n=0;n<16;n++) {
135   printf("%c",isprint(pb[n])?pb[n]:'.');
136  };
137  printf("\n");
138  adr+=16;
139 };
140 mdump_adr=adr;
141 return 0;
142}
143/*----------------------------------------------------------------------------*/
144int main_mwdump(int argc,char * argv[]) {
145 unsigned char n,m,max=0;
146 int adr=mdump_adr;
147 unsigned short * pw;
148 if (argc>1) adr=str2int(argv[1]);
149 if (argc>2) max=str2int(argv[2]);
150 max/=16;
151 if (!max) max=20;
152 for (m=0;m<max;m++) {
153  printf("0x%08X ",adr);
154  pw=(unsigned short*) adr;
155  for (n=0;n<8;n++)
156   printf("%02X %02X%c",pw[n]/0x100,pw[n]%0x100,n==3?'-':' ');
157  for (n=0;n<8;n++) {
158   printf("%c",isprint(pw[n]/0x100)?pw[n]/0x100:'.');
159   printf("%c",isprint(pw[n]%0x100)?pw[n]%0x100:'.');
160  };
161  printf("\n");
162  adr+=16;
163 };
164 mdump_adr=adr;
165 return 0;
166}
167/*----------------------------------------------------------------------------*/
168int main_medit(int argc,char * argv[]) {
169 unsigned char * pb;
170 int n,i;
171 if (argc<3) {
172  printf("too few arguments\n");
173  return 0;
174 };
175 pb=(unsigned char*)str2int(argv[1]);
176 i=2;
177 n=0;
178 while (i<=argc) {
179  pb[n++]=str2int(argv[i++])%0x100;
180 }
181 mdump_adr=(int)pb;
182 return main_mdump(0,NULL);
183}
184/*----------------------------------------------------------------------------*/
185int main_mfill(int argc,char * argv[]) {
186 int  adr;
187 int  size;
188 unsigned char value;
189 if (argc<4) {
190  printf("too few arguments\n");
191  return 0;
192 };
193 adr  =str2int(argv[1]);
194 size =str2int(argv[2]);
195 value=str2int(argv[3])%0x100;
196 memset((unsigned char*)adr,size,value);
197 mdump_adr=adr;
198 return main_mdump(0,NULL);
199}
200/*----------------------------------------------------------------------------*/
201int main_mmove(int argc,char * argv[]) {
202 int  src;
203 int  dst;
204 int  size;
205 if (argc<4) {
206  printf("too few arguments\n");
207  return 0;
208 };
209 dst  =str2int(argv[1]);
210 src  =str2int(argv[2]);
211 size =str2int(argv[3]);
212 memcpy((unsigned char*)dst,(unsigned char*)src,size);
213 mdump_adr=dst;
214 return main_mdump(0,NULL);
215}
216/*----------------------------------------------------------------------------*/
217#ifdef MALLOC_STATS  /* /rtems/s/src/lib/libc/malloc.c */
218int main_malloc_dump(int argc,char * argv[]) {
219 void malloc_dump(void); 
220 malloc_dump(); 
221 return 0;
222}
223#endif
224/*----------------------------------------------------------------------------
225 * Reset. Assumes that the watchdog is present.
226 *----------------------------------------------------------------------------*/
227int main_reset (int argc, char **argv)
228{
229  rtems_interrupt_level level;
230  printf ("Waiting for watchdog ... ");
231  tcdrain(fileno(stdout));
232
233  rtems_interrupt_disable (level);
234  for (;;) 
235      ;
236  return 0;
237}
238/*----------------------------------------------------------------------------
239 * Alias. make an alias
240 *----------------------------------------------------------------------------*/
241int main_alias (int argc, char **argv)
242{
243 if (argc<3) {
244  printf("too few arguments\n");
245  return 1;
246 };
247 if (!shell_alias_cmd(argv[1],argv[2])) {
248  printf("unable to make an alias(%s,%s)\n",argv[1],argv[2]);
249 };
250 return 0;
251} 
252/*-----------------------------------------------------------*         
253 * Directory commands
254 *-----------------------------------------------------------*/
255int main_ls(int argc, char *argv[])
256{
257   char * fname;
258   DIR                 *dirp;
259   struct dirent       *dp;
260   struct stat         stat_buf;
261   char   sbuf[256];
262   char   nbuf[1024];
263   int  n,size;
264
265   fname=".";
266   if (argc>1) fname=argv[1];
267
268   if ((dirp = opendir(fname)) == NULL)
269   {
270      printf("%s: No such file or directory.\n", fname);
271      return errno;
272   }
273   n=0;
274   size=0;
275   while ((dp = readdir(dirp)) != NULL)
276   {
277      strcpy(nbuf,fname);
278      if (nbuf[strlen(nbuf)-1]!='/') strcat(nbuf,"/");
279      strcat(nbuf,dp->d_name); /* always the fullpathname. Avoid ftpd problem.*/
280      if (stat(nbuf, &stat_buf) == 0)
281      { /* AWFUL buts works...*/
282         strftime(sbuf,sizeof(sbuf)-1,"%b %d %H:%M",gmtime(&stat_buf.st_atime));     
283         printf("%c%c%c%c%c%c%c%c%c%c %3d rtems  rtems  %11d %s %s%c\n",
284                 (S_ISLNK(stat_buf.st_mode)?('l'):
285                    (S_ISDIR(stat_buf.st_mode)?('d'):('-'))),
286                 (stat_buf.st_mode & S_IRUSR)?('r'):('-'),
287                 (stat_buf.st_mode & S_IWUSR)?('w'):('-'),
288                 (stat_buf.st_mode & S_IXUSR)?('x'):('-'),
289                 (stat_buf.st_mode & S_IRGRP)?('r'):('-'),
290                 (stat_buf.st_mode & S_IWGRP)?('w'):('-'),
291                 (stat_buf.st_mode & S_IXGRP)?('x'):('-'),
292                 (stat_buf.st_mode & S_IROTH)?('r'):('-'),
293                 (stat_buf.st_mode & S_IWOTH)?('w'):('-'),
294                 (stat_buf.st_mode & S_IXOTH)?('x'):('-'),
295                 (int)stat_buf.st_nlink,
296                 (int)stat_buf.st_size,
297                 sbuf,
298                 dp->d_name,
299                 S_ISDIR(stat_buf.st_mode)?'/':' ');
300         n++;
301         size+=stat_buf.st_size;
302      }
303   }
304   printf("%d files %d bytes occupied\n",n,size);
305   closedir(dirp);
306   return 0;
307}
308/*-----------------------------------------------------------*/         
309int main_pwd (int argc, char *argv[]) {
310   char dir[1024];
311   getcwd(dir,1024);
312   printf("%s\n",dir);
313   return 0;
314}
315/*-----------------------------------------------------------*/         
316int main_chdir (int argc, char *argv[]) {
317   char *dir;
318   dir="/";
319   if (argc>1) dir=argv[1];
320   if (chdir(dir)) {
321    printf("chdir to '%s' failed:%s\n",dir,strerror(errno));
322    return errno;
323   }; 
324   return 0;
325}
326/*-----------------------------------------------------------*/         
327int main_mkdir (int argc, char *argv[]) {
328   char *dir;
329   dir=NULL;
330   if (argc>1) dir=argv[1];
331   if (mkdir(dir,S_IRWXU|S_IRWXG|S_IRWXO)) {
332     printf("mkdir '%s' failed:%s\n",dir,strerror(errno));
333   }; 
334   return errno;
335}
336/*-----------------------------------------------------------*/         
337int main_rmdir (int argc, char *argv[])
338{
339   char *dir;
340   dir=NULL;
341   if (argc>1) dir=argv[1];
342   if (rmdir(dir)) printf("rmdir '%s' failed:%s\n",dir,strerror(errno));
343   return errno;
344}
345/*-----------------------------------------------------------*/         
346int main_chroot(int argc,char * argv[]) {
347 char * new_root="/";
348 if (argc==2) new_root=argv[1];
349 if (chroot(new_root)<0) {
350  printf("error %s:chroot(%s);\n",strerror(errno),new_root);
351  return -1;
352 };
353 return 0;
354}
355/*-----------------------------------------------------------*/         
356/* date - print or set time and date            Author: Jan Looyen */
357/* MINIX 1.5 GPL'ed */
358
359
360#define MIN     60L             /* # seconds in a minute */
361#define HOUR    (60 * MIN)      /* # seconds in an hour */
362#define DAY     (24 * HOUR)     /* # seconds in a day */
363#define YEAR    (365 * DAY)     /* # seconds in a year */
364
365static int conv(unsigned32 *value,char **ptr,unsigned32 max) 
366{
367  int buf;
368  *ptr -= 2;
369  buf = atoi(*ptr);
370  **ptr = 0;
371  if (buf < 0 || buf > max) {
372   fprintf(stderr, "Date: bad conversion\n");
373   return 0;
374  }; 
375  *value=buf;
376  return 1;
377}
378
379static int set_time(char *t) 
380{
381  rtems_time_of_day tod;       
382  FILE * rtc;
383  char *tp;
384  int len;
385  if (rtems_clock_get(RTEMS_CLOCK_GET_TOD,&tod)!=RTEMS_SUCCESSFUL) 
386          memset(&tod,0,sizeof(tod));
387  len = strlen(t);
388  if (len != 12 && len != 10 && len != 6 && len != 4) return 0;
389  tp = t;
390  while (*tp)
391   if (!isdigit(*tp++)) {
392    fprintf(stderr, "date: bad conversion\n");
393    return 0;
394   };
395  if (len == 6 || len == 12) 
396   if (!conv(&tod.second,&tp, 59)) return 0;
397  if (!conv(&tod.minute,&tp, 59)) return 0;
398  if (!conv(&tod.hour,&tp, 23)) return 0;
399  if (len == 12 || len == 10) {
400   if (!conv(&tod.year,&tp, 99)) return 0;
401   tod.year+=1900;
402   if (tod.year<TOD_BASE_YEAR) tod.year+=100;
403   if (!conv(&tod.day   ,&tp, 31)) return 0;
404   if (!conv(&tod.month ,&tp, 12)) return 0;
405  }
406  if (!_TOD_Validate(&tod)) {
407    fprintf(stderr, "Invalid date value\n");
408  } else {
409   rtems_clock_set(&tod);         
410   rtems_clock_get(RTEMS_CLOCK_GET_TOD,&tod);     
411   rtc=fopen("/dev/rtc","r+");
412   if (rtc) {
413    fwrite(&tod,sizeof(tod),1,rtc);
414    fclose(rtc);
415   };
416  };
417  return 1;
418}
419
420int main_date(int argc,char *argv[]) 
421{
422  time_t t;
423  if (argc == 2) set_time(argv[1]);
424  time(&t);
425  printf("%s", ctime(&t));
426  return 0;
427}
428/*-----------------------------------------------------------*         
429 * with this you can call at all the rtems monitor commands.
430 * Not all work fine but you can show the rtems status and more.
431 *-----------------------------------------------------------*/         
432int main_monitor(int argc,char * argv[]) {
433 rtems_monitor_command_entry_t *command;
434 extern rtems_monitor_command_entry_t rtems_monitor_commands[];
435 rtems_task_ident(RTEMS_SELF,0,&rtems_monitor_task_id);
436 rtems_monitor_node = rtems_get_node(rtems_monitor_task_id);
437 rtems_monitor_default_node = rtems_monitor_node;
438 if ((command=rtems_monitor_command_lookup(rtems_monitor_commands,argc,argv)))
439  command->command_function(argc, argv, command->command_arg, 0);
440 return 0;
441}
442/*-----------------------------------------------------------*/         
443void register_cmds(void) {
444  rtems_monitor_command_entry_t *command;
445  extern rtems_monitor_command_entry_t rtems_monitor_commands[];
446  /* dir[ectories] topic */
447  shell_add_cmd  ("ls"    ,"dir","ls [dir]     # list files in the directory" ,main_ls   );
448  shell_add_cmd  ("chdir" ,"dir","chdir [dir]  # change the current directory",main_chdir);
449  shell_add_cmd  ("rmdir" ,"dir","rmdir  dir   # remove directory"            ,main_rmdir);
450  shell_add_cmd  ("mkdir" ,"dir","mkdir  dir   # make a directory"            ,main_mkdir);
451  shell_add_cmd  ("pwd"   ,"dir","pwd          # print work directory"        ,main_pwd  );
452  shell_add_cmd  ("chroot","dir","chroot [dir] # change the root directory"   ,main_chroot);
453
454  shell_alias_cmd("ls"    ,"dir");
455  shell_alias_cmd("chdir" ,"cd");
456
457  /* misc. topic */
458  shell_add_cmd  ("date" ,"misc","date [[MMDDYY]hhmm[ss]]"                    ,main_date);
459  shell_add_cmd  ("reset","misc","reset the BSP"                              ,main_reset);
460  shell_add_cmd  ("alias","misc","alias old new"                              ,main_alias);
461
462  /* memory topic */
463  shell_add_cmd  ("mdump","mem"  ,"mdump [adr [size]]"           ,main_mdump);
464  shell_add_cmd  ("wdump","mem"  ,"wdump [adr [size]]"           ,main_mwdump);
465  shell_add_cmd  ("medit","mem"  ,"medit adr value [value ...]"  ,main_medit);
466  shell_add_cmd  ("mfill","mem"  ,"mfill adr size value"         ,main_mfill);
467  shell_add_cmd  ("mmove","mem"  ,"mmove dst src size"           ,main_mmove);
468#ifdef MALLOC_STATS  /* /rtems/s/src/lib/libc/malloc.c */
469  shell_add_cmd  ("malloc","mem","mem  show memory malloc'ed"                 ,main_mem);
470#endif 
471  /* monitor topic */
472  command=rtems_monitor_commands;
473  while (command) {
474   shell_add_cmd(command->command,"monitor",
475                 command->usage  ,main_monitor);
476   command=command->next;
477  };
478}
479/*-----------------------------------------------------------*/         
Note: See TracBrowser for help on using the repository browser.