int parse_line (char *line, char *argv[]) { int nargs = 0; debug_parser("parse_line: \"%s\"\n", line); while (nargs < CONFIG_SYS_MAXARGS) { /* skip any white space */ while (isblank(*line)) ++line; if (*line == '\0') { /* end of line, no more args */ argv[nargs] = NULL; debug_parser("parse_line: nargs=%d\n", nargs); return nargs; } argv[nargs++] = line; /* begin of argument string */ /* find end of string */ while (*line && !isblank(*line)) ++line; if (*line == '\0') { /* end of line, no more args */ argv[nargs] = NULL; debug_parser("parse_line: nargs=%d\n", nargs); return nargs; } *line++ = '\0'; /* terminate current arg */ } printf ("** Too many args (max. %d) **\n", CONFIG_SYS_MAXARGS); debug_parser("parse_line: nargs=%d\n", nargs); return (nargs); }
/**************************************************************************** * returns: * 1 - command executed, repeatable * 0 - command executed but not repeatable, interrupted commands are * always considered not repeatable * -1 - not executed (unrecognized, bootd recursion or too many args) * (If cmd is NULL or "" or longer than CONFIG_SYS_CBSIZE-1 it is * considered unrecognized) * * WARNING: * * We must create a temporary copy of the command since the command we get * may be the result from getenv(), which returns a pointer directly to * the environment data, which may change magicly when the command we run * creates or modifies environment variables (like "bootp" does). */ static int builtin_run_command(const char *cmd, int flag) { char cmdbuf[CONFIG_SYS_CBSIZE]; /* working copy of cmd */ char *token; /* start of token in cmdbuf */ char *sep; /* end of token (separator) in cmdbuf */ char finaltoken[CONFIG_SYS_CBSIZE]; char *str = cmdbuf; char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */ int argc, inquotes; int repeatable = 1; int rc = 0; debug_parser("[RUN_COMMAND] cmd[%p]=\"", cmd); if (DEBUG_PARSER) { /* use printf - string may be loooong */ printf(cmd ? cmd : "NULL"); printf("\"\n"); } //clear_ctrlc(); /* forget any previous Control C */ if (!cmd || !*cmd) { return -1; /* empty command */ } if (strlen(cmd) >= CONFIG_SYS_CBSIZE) { printf ("## Command too long!\n"); return -1; } strcpy (cmdbuf, cmd); /* Process separators and check for invalid * repeatable commands */ debug_parser("[PROCESS_SEPARATORS] %s\n", cmd); while (*str) { /* * Find separator, or string end * Allow simple escape of ';' by writing "\;" */ for (inquotes = 0, sep = str; *sep; sep++) { if ((*sep=='\'') && (*(sep-1) != '\\')) inquotes=!inquotes; if (!inquotes && (*sep == ';') && /* separator */ ( sep != str) && /* past string start */ (*(sep-1) != '\\')) /* and NOT escaped */ break; } /* * Limit the token to data between separators */ token = str; if (*sep) { str = sep + 1; /* start of command for next pass */ *sep = '\0'; } else str = sep; /* no more commands for next pass */ debug_parser("token: \"%s\"\n", token); /* find macros in this token and replace them */ process_macros (token, finaltoken); /* Extract arguments */ if ((argc = parse_line (finaltoken, argv)) == 0) { rc = -1; /* no command at all */ continue; } if (cmd_process(flag, argc, argv, &repeatable, NULL)) rc = -1; /* Did the user stop this? */ //if (had_ctrlc ()) // return -1; /* if stopped then not repeatable */ } return rc ? rc : repeatable; }
static void process_macros (const char *input, char *output) { char c, prev; const char *varname_start = NULL; int inputcnt = strlen (input); int outputcnt = CONFIG_SYS_CBSIZE; int state = 0; /* 0 = waiting for '$' */ /* 1 = waiting for '(' or '{' */ /* 2 = waiting for ')' or '}' */ /* 3 = waiting for ''' */ char *output_start = output; debug_parser("[PROCESS_MACROS] INPUT len %zd: \"%s\"\n", strlen(input), input); prev = '\0'; /* previous character */ while (inputcnt && outputcnt) { c = *input++; inputcnt--; if (state != 3) { /* remove one level of escape characters */ if ((c == '\\') && (prev != '\\')) { if (inputcnt-- == 0) break; prev = c; c = *input++; } } switch (state) { case 0: /* Waiting for (unescaped) $ */ if ((c == '\'') && (prev != '\\')) { state = 3; break; } if ((c == '$') && (prev != '\\')) { state++; } else { *(output++) = c; outputcnt--; } break; case 1: /* Waiting for ( */ if (c == '(' || c == '{') { state++; varname_start = input; } else { state = 0; *(output++) = '$'; outputcnt--; if (outputcnt) { *(output++) = c; outputcnt--; } } break; case 2: /* Waiting for ) */ if (c == ')' || c == '}') { int i; char envname[CONFIG_SYS_CBSIZE], *envval; int envcnt = input - varname_start - 1; /* Varname # of chars */ /* Get the varname */ for (i = 0; i < envcnt; i++) { envname[i] = varname_start[i]; } envname[i] = 0; /* Get its value */ envval = getenv (envname); /* Copy into the line if it exists */ if (envval != NULL) while ((*envval) && outputcnt) { *(output++) = *(envval++); outputcnt--; } /* Look for another '$' */ state = 0; } break; case 3: /* Waiting for ' */ if ((c == '\'') && (prev != '\\')) { state = 0; } else { *(output++) = c; outputcnt--; } break; } prev = c; } if (outputcnt) *output = 0; else *(output - 1) = 0; debug_parser("[PROCESS_MACROS] OUTPUT len %zd: \"%s\"\n", strlen(output_start), output_start); }
static void parsemessage(TCHAR *in, struct uae_prefs *p, TCHAR *out, int outsize) { int mode; out[0] = 0; my_trim (in); if (!_tcsicmp (in, _T("IPC_QUIT"))) { uae_quit (); return; } if (!_tcsicmp (in, _T("ipc_config"))) { ipcmode = 1; _tcscat (out, _T("200\n")); return; } else if (!_tcsicmp (in, _T("ipc_event"))) { ipcmode = 2; _tcscat (out, _T("200\n")); return; } else if (!_tcsicmp (in, _T("ipc_debug"))) { ipcmode = 3; _tcscat (out, _T("200\n")); return; } else if (!_tcsicmp (in, _T("ipc_restore"))) { ipcmode = 0; _tcscat (out, _T("200\n")); return; } mode = 0; if (ipcmode == 1) { mode = 1; } else if (ipcmode == 2) { mode = 1; } else if (ipcmode == 3) { mode = 2; } else if (!_tcsnicmp (in, _T("CFG "), 4) || !_tcsnicmp (in, _T("EVT "), 4)) { mode = 1; in += 4; } else if (!_tcsnicmp (in, _T("DBG "), 4)) { mode = 2; in += 4; } if (mode == 1) { TCHAR tmpout[256]; int index = -1; int cnt = 0; for (;;) { int ret; tmpout[0] = 0; ret = cfgfile_modify (index, in, _tcslen (in), tmpout, sizeof (tmpout) * sizeof (TCHAR)); index++; if (_tcslen (tmpout) > 0) { if (_tcslen (out) == 0) _tcscat (out, _T("200 ")); _tcsncat (out, _T("\n"), outsize); _tcsncat (out, tmpout, outsize); } cnt++; if (ret >= 0) break; } if (out[0] == 0) _tcscat (out, _T("404")); } else if (mode == 2) { debug_parser (in, out, outsize); if (!out[0]) _tcscpy (out, _T("404")); } else { _tcscpy (out, _T("501")); } }