1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * UI Command Dispatch File: ui_cmddisp.c 5 * 6 * This module contains routines to maintain the command table, 7 * parse and execute commands 8 * 9 * Author: Mitch Lichtenberg 10 * 11 ********************************************************************* 12 * 13 * Copyright 2000,2001,2002,2003 14 * Broadcom Corporation. All rights reserved. 15 * 16 * This software is furnished under license and may be used and 17 * copied only in accordance with the following terms and 18 * conditions. Subject to these conditions, you may download, 19 * copy, install, use, modify and distribute modified or unmodified 20 * copies of this software in source and/or binary form. No title 21 * or ownership is transferred hereby. 22 * 23 * 1) Any source code used, modified or distributed must reproduce 24 * and retain this copyright notice and list of conditions 25 * as they appear in the source file. 26 * 27 * 2) No right is granted to use any trade name, trademark, or 28 * logo of Broadcom Corporation. The "Broadcom Corporation" 29 * name may not be used to endorse or promote products derived 30 * from this software without the prior written permission of 31 * Broadcom Corporation. 32 * 33 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 34 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 35 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 36 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 37 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 38 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 39 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 40 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 41 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 43 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 44 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 45 * THE POSSIBILITY OF SUCH DAMAGE. 46 ********************************************************************* */ 47 48 49#include <stdarg.h> 50 51#include "cfe.h" 52#include "lib_try.h" 53#include "env_subr.h" 54#include "ui_command.h" 55 56/* ********************************************************************* 57 * Types 58 ********************************************************************* */ 59 60 61/* ********************************************************************* 62 * Globals 63 ********************************************************************* */ 64 65static jmp_buf ui_jmpbuf; /* for getting control in exceptions */ 66 67/* ********************************************************************* 68 * ui_errstring(errcode) 69 * 70 * Return a string that corresponds to a CFE error code 71 * 72 * Input parameters: 73 * errcode - code to translate 74 * 75 * Return value: 76 * string describing error code 77 ********************************************************************* */ 78 79const char *ui_errstring(int errcode) 80{ 81 return cfe_errortext(errcode); 82} 83 84 85/* ********************************************************************* 86 * ui_showerror(errcode,tmplt,...) 87 * 88 * printf-like function to display a CFE error code along with 89 * other information. Works sort of like 'perror'. You can 90 * return the value passed to this routine to a CFE UI handler 91 * since it returns its input. 92 * 93 * Input parameters: 94 * errcode - CFE error code 95 * tmplt,... - printf parameters 96 * 97 * Return value: 98 * errcode 99 ********************************************************************* */ 100 101int ui_showerror(int errcode,char *tmplt,...) 102{ 103 va_list marker; 104 105 va_start(marker,tmplt); 106 xvprintf(tmplt,marker); 107 va_end(marker); 108 xprintf(": %s\n",ui_errstring(errcode)); 109 110 return errcode; 111} 112 113 114/* ********************************************************************* 115 * ui_do_one_command(head) 116 * 117 * Process one CLI command from a command queue 118 * 119 * Input parameters: 120 * head - queue of commands 121 * 122 * Return value: 123 * return value from CFE UI function 124 ********************************************************************* */ 125 126 127static int ui_do_one_command(queue_t *head) 128{ 129 int res; 130 ui_cmdline_t cmd; 131 132 res = cmd_lookup(head, &cmd); 133 134 if (res == 0) { 135 136 res = cmd_sw_validate(&cmd,cmd.switches); 137 if (res != -1) { 138 xprintf("Invalid switch: %s\n", 139 cmd_sw_name(&cmd,res)); 140 return CFE_ERR_INV_PARAM; 141 } 142 143 if (lib_setjmp(ui_jmpbuf) != 0) return -1; 144 res = (*cmd.func)(&cmd,cmd.argc-cmd.argidx, 145 &(cmd.argv[cmd.argidx])); 146 } 147 cmd_free(&cmd); 148 return res; 149} 150 151 152/* ********************************************************************* 153 * ui_restart(arg) 154 * 155 * Restart the command interpreter -- can be called if you get 156 * deep inside a UI routine and want to bail out. 157 * 158 * Input parameters: 159 * arg - value to return from ui_do_one_command 160 * 161 * Return value: 162 * nothing 163 ********************************************************************* */ 164 165void ui_restart(int arg) 166{ 167 if (arg == 0) arg = -1; 168 169 lib_longjmp(ui_jmpbuf,arg); 170} 171 172/* ********************************************************************* 173 * ui_init_cmddisp() 174 * 175 * Initialize the command dispatcher. 176 * 177 * Input parameters: 178 * nothing 179 * 180 * Return value: 181 * 0 182 ********************************************************************* */ 183 184int ui_init_cmddisp(void) 185{ 186 cmd_init(); 187 188 return 0; 189} 190 191/* ********************************************************************* 192 * ui_showusage(cmd) 193 * 194 * Display the usage for a command, given a command line 195 * structure 196 * 197 * Input parameters: 198 * cmd - command line structure (typically passed in from 199 * the command interpreter) 200 * 201 * Return value: 202 * CFE_ERR_INV_COMMAND 203 ********************************************************************* */ 204 205int ui_showusage(ui_cmdline_t *cmd) 206{ 207 cmd_showusage(cmd); 208 209 return CFE_ERR_INV_COMMAND; 210} 211 212 213/* ********************************************************************* 214 * ui_docommands_internal(head) 215 * 216 * Process (possibly multiple) commands from a list of tokens 217 * 218 * Input parameters: 219 * buf - buffer 220 * 221 * Return value: 222 * exit status of first command that failed, or null 223 ********************************************************************* */ 224static int ui_docommands_internal(queue_t *head) 225{ 226 queue_t cmdqueue; 227 ui_command_t *cmd; 228 int status = CMD_ERR_BLANK; 229 int term; 230 231 q_init(&cmdqueue); 232 233 /* 234 * Find all the individual commands 235 */ 236 237 while ((cmd = cmd_readcommand(head))) { 238 239 if (cmd == NULL) { 240 return CMD_ERR_BLANK; 241 } 242 243 q_enqueue(&cmdqueue,(queue_t *) cmd); 244 } 245 246 /* 247 * Do each command 248 */ 249 250 while ((cmd = (ui_command_t *) q_deqnext(&(cmdqueue)))) { 251 status = ui_do_one_command(&(cmd->head)); 252 term = cmd->term; 253 KFREE(cmd); 254 if (status == CMD_ERR_BLANK) continue; 255 256 /* 257 * And causes us to stop at the first failure. 258 */ 259 if ((term == CMD_TERM_AND) && (status != 0)) break; 260 261 /* 262 * OR causes us to stop at the first success. 263 */ 264 265 if ((term == CMD_TERM_OR) && (status == 0)) break; 266 267 /* 268 * Neither AND nor OR causes us to keep chugging away. 269 */ 270 } 271 272 /* 273 * Free any remaining tokens and commands that we did not do 274 */ 275 276 while ((cmd = (ui_command_t *) q_deqnext(&(cmdqueue)))) { 277 cmd_free_tokens(&(cmd->head)); 278 KFREE(cmd); 279 } 280 281 return status; 282} 283 284 285/* ********************************************************************* 286 * ui_docommands(str) 287 * 288 * Do one or more commands. This is the main UI function. 289 * 290 * Input parameters: 291 * str - command string 292 * 293 * Return value: 294 * return value of failing command, or 0 if all commands 295 * succeeded 296 ********************************************************************* */ 297 298int ui_docommands(char *str) 299{ 300 queue_t cmd_list; 301 int res; 302 303 /* Convert the command into a token list */ 304 cmd_build_list(&cmd_list,str); 305 306 /* Walk the list and expand environment variables */ 307 cmd_walk_and_expand(&cmd_list); 308 309 /* Process each command. This removes tokens from the list */ 310 res = ui_docommands_internal(&cmd_list); 311 312 /* Free any leftover tokens. There should not be any. */ 313 cmd_free_tokens(&cmd_list); 314 315 return res; 316} 317