3 #include <environment.h>
5 static int parse_line (char *line
, char *argv
[])
10 printf ("parse_line: \"%s\"\n", line
);
12 while (nargs
< CONFIG_MAXARGS
) {
14 /* skip any white space */
15 while ((*line
== ' ') || (*line
== '\t')) {
19 if (*line
== '\0') { /* end of line, no more args */
22 printf ("parse_line: nargs=%d\n", nargs
);
27 argv
[nargs
++] = line
; /* begin of argument string */
29 /* find end of string */
30 while (*line
&& (*line
!= ' ') && (*line
!= '\t')) {
34 if (*line
== '\0') { /* end of line, no more args */
37 printf ("parse_line: nargs=%d\n", nargs
);
42 *line
++ = '\0'; /* terminate current arg */
45 printf ("** Too many args (max. %d) **\n", CONFIG_MAXARGS
);
48 printf ("parse_line: nargs=%d\n", nargs
);
53 static void process_macros (const char *input
, char *output
)
56 const char *varname_start
= NULL
;
57 int inputcnt
= strlen (input
);
58 int outputcnt
= CONFIG_CBSIZE
;
59 int state
= 0; /* 0 = waiting for '$' */
61 /* 1 = waiting for '(' or '{' */
62 /* 2 = waiting for ')' or '}' */
63 /* 3 = waiting for ''' */
65 char *output_start
= output
;
67 printf ("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", strlen (input
),
71 prev
= '\0'; /* previous character */
73 while (inputcnt
&& outputcnt
) {
78 /* remove one level of escape characters */
79 if ((c
== '\\') && (prev
!= '\\')) {
88 case 0: /* Waiting for (unescaped) $ */
89 if ((c
== '\'') && (prev
!= '\\')) {
93 if ((c
== '$') && (prev
!= '\\')) {
100 case 1: /* Waiting for ( */
101 if (c
== '(' || c
== '{') {
103 varname_start
= input
;
115 case 2: /* Waiting for ) */
116 if (c
== ')' || c
== '}') {
118 char envname
[CONFIG_CBSIZE
];
120 int envcnt
= input
- varname_start
- 1; /* Varname # of chars */
122 /* Get the varname */
123 for (i
= 0; i
< envcnt
; i
++) {
124 envname
[i
] = varname_start
[i
];
129 envval
= getenv (envname
);
131 /* Copy into the line if it exists */
133 while ((*envval
) && outputcnt
) {
134 *(output
++) = *(envval
++);
137 /* Look for another '$' */
141 case 3: /* Waiting for ' */
142 if ((c
== '\'') && (prev
!= '\\')) {
157 printf ("[PROCESS_MACROS] OUTPUT len %d: \"%s\"\n",
158 strlen (output_start
), output_start
);
162 /****************************************************************************
164 * 0 - command executed
165 * -1 - not executed (unrecognized, bootd recursion or too many args)
166 * (If cmd is NULL or "" or longer than CONFIG_CBSIZE-1 it is
167 * considered unrecognized)
171 * We must create a temporary copy of the command since the command we get
172 * may be the result from getenv(), which returns a pointer directly to
173 * the environment data, which may change magicly when the command we run
174 * creates or modifies environment variables (like "bootp" does).
177 int run_command (const char *cmd
, int flag
)
180 char cmdbuf
[CONFIG_CBSIZE
]; /* working copy of cmd */
181 char *token
; /* start of token in cmdbuf */
182 char *sep
; /* end of token (separator) in cmdbuf */
183 char finaltoken
[CONFIG_CBSIZE
];
185 char *argv
[CONFIG_MAXARGS
+ 1]; /* NULL terminated */
190 printf ("[RUN_COMMAND] cmd[%p]=\"", cmd
);
191 puts (cmd
? cmd
: "NULL"); /* use puts - string may be loooong */
196 return -1; /* empty command */
199 if (strlen(cmd
) >= CONFIG_CBSIZE
) {
200 puts ("## Command too long!\n");
204 strcpy (cmdbuf
, cmd
);
206 /* Process separators and check for invalid
207 * repeatable commands
211 printf ("[PROCESS_SEPARATORS] %s\n", cmd
);
216 * Find separator, or string end
217 * Allow simple escape of ';' by writing "\;"
219 for (inquotes
= 0, sep
= str
; *sep
; sep
++) {
225 (*sep
== ';') && /* separator */
226 ( sep
!= str
) && /* past string start */
227 (*(sep
-1) != '\\')) /* and NOT escaped */
232 * Limit the token to data between separators
236 str
= sep
+ 1; /* start of command for next pass */
240 str
= sep
; /* no more commands for next pass */
242 printf ("token: \"%s\"\n", token
);
245 /* find macros in this token and replace them */
246 process_macros (token
, finaltoken
);
248 /* Extract arguments */
249 if ((argc
= parse_line (finaltoken
, argv
)) == 0) {
250 rc
= -1; /* no command at all */
254 /* Look up command in command table */
255 if ((cmdtp
= find_cmd(argv
[0])) == NULL
) {
256 printf ("Unknown command '%s' - try 'help'\n", argv
[0]);
257 rc
= -1; /* give up after bad command */
261 /* found - check max args */
262 if (argc
> cmdtp
->maxargs
) {
263 printf ("Usage:\n%s\n", cmdtp
->usage
);
268 /* OK - call function to do the command */
269 if ((cmdtp
->cmd
) (cmdtp
, argc
, argv
) != 0)
276 static char console_buffer
[CONFIG_CBSIZE
]; /* console I/O buffer */
280 static char lastcommand
[CONFIG_CBSIZE
] = { 0, };
285 len
= readline (CONFIG_PROMPT
, console_buffer
, CONFIG_CBSIZE
);
287 flag
= 0; /* assume no special flags for now */
289 strcpy (lastcommand
, console_buffer
);
292 puts ("<INTERRUPT>\n");
294 rc
= run_command (lastcommand
, flag
);
297 /* invalid command or not repeatable, forget it */