10Sstevel@tonic-gate /* 2*2881Smp153739 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 30Sstevel@tonic-gate * Use is subject to license terms. 40Sstevel@tonic-gate */ 50Sstevel@tonic-gate 60Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 70Sstevel@tonic-gate 80Sstevel@tonic-gate /* 90Sstevel@tonic-gate * Copyright 1987, 1988, 1989 by Massachusetts Institute of Technology 100Sstevel@tonic-gate * 110Sstevel@tonic-gate * For copyright info, see copyright.h. 120Sstevel@tonic-gate */ 130Sstevel@tonic-gate 140Sstevel@tonic-gate #include "ss_internal.h" 150Sstevel@tonic-gate #include "copyright.h" 160Sstevel@tonic-gate #include <stdio.h> 170Sstevel@tonic-gate 180Sstevel@tonic-gate 190Sstevel@tonic-gate /* 200Sstevel@tonic-gate * get_request(tbl, idx) 210Sstevel@tonic-gate * 220Sstevel@tonic-gate * Function: 230Sstevel@tonic-gate * Gets the idx'th request from the request table pointed to 240Sstevel@tonic-gate * by tbl. 250Sstevel@tonic-gate * Arguments: 260Sstevel@tonic-gate * tbl (ss_request_table *) 270Sstevel@tonic-gate * pointer to request table 280Sstevel@tonic-gate * idx (int) 290Sstevel@tonic-gate * index into table 300Sstevel@tonic-gate * Returns: 310Sstevel@tonic-gate * (ss_request_entry *) 320Sstevel@tonic-gate * pointer to request table entry 330Sstevel@tonic-gate * Notes: 340Sstevel@tonic-gate * Has been replaced by a macro. 350Sstevel@tonic-gate */ 360Sstevel@tonic-gate 370Sstevel@tonic-gate #ifdef __SABER__ 380Sstevel@tonic-gate /* sigh. saber won't deal with pointer-to-const-struct */ 390Sstevel@tonic-gate static struct _ss_request_entry * get_request (tbl, idx) 400Sstevel@tonic-gate ss_request_table * tbl; 410Sstevel@tonic-gate int idx; 420Sstevel@tonic-gate { 430Sstevel@tonic-gate struct _ss_request_table *tbl1 = (struct _ss_request_table *) tbl; 440Sstevel@tonic-gate struct _ss_request_entry *e = (struct _ss_request_entry *) tbl1->requests; 450Sstevel@tonic-gate return e + idx; 460Sstevel@tonic-gate } 470Sstevel@tonic-gate #else 480Sstevel@tonic-gate #define get_request(tbl,idx) ((tbl) -> requests + (idx)) 490Sstevel@tonic-gate #endif 500Sstevel@tonic-gate 510Sstevel@tonic-gate /* 520Sstevel@tonic-gate * check_request_table(rqtbl, argc, argv, sci_idx) 530Sstevel@tonic-gate * 540Sstevel@tonic-gate * Function: 550Sstevel@tonic-gate * If the command string in argv[0] is in the request table, execute 560Sstevel@tonic-gate * the commands and return error code 0. Otherwise, return error 570Sstevel@tonic-gate * code ss_et_command_not_found. 580Sstevel@tonic-gate * Arguments: 590Sstevel@tonic-gate * rqtbl (ss_request_table *) 600Sstevel@tonic-gate * pointer to request table 610Sstevel@tonic-gate * argc (int) 620Sstevel@tonic-gate * number of elements in argv[] 630Sstevel@tonic-gate * argv (char *[]) 640Sstevel@tonic-gate * argument string array 650Sstevel@tonic-gate * sci_idx (int) 660Sstevel@tonic-gate * ss-internal index for subsystem control info structure 670Sstevel@tonic-gate * Returns: 680Sstevel@tonic-gate * (int) 690Sstevel@tonic-gate * zero if command found, ss_et_command_not_found otherwise 700Sstevel@tonic-gate * Notes: 710Sstevel@tonic-gate */ 720Sstevel@tonic-gate 730Sstevel@tonic-gate static int check_request_table (rqtbl, argc, argv, sci_idx) 740Sstevel@tonic-gate register ss_request_table *rqtbl; 750Sstevel@tonic-gate int argc; 760Sstevel@tonic-gate char *argv[]; 770Sstevel@tonic-gate int sci_idx; 780Sstevel@tonic-gate { 790Sstevel@tonic-gate #ifdef __SABER__ 800Sstevel@tonic-gate struct _ss_request_entry *request; 810Sstevel@tonic-gate #else 820Sstevel@tonic-gate register ss_request_entry *request; 830Sstevel@tonic-gate #endif 840Sstevel@tonic-gate register ss_data *info; 850Sstevel@tonic-gate register char const * const * name; 860Sstevel@tonic-gate char *string = argv[0]; 870Sstevel@tonic-gate int i; 880Sstevel@tonic-gate 890Sstevel@tonic-gate info = ss_info(sci_idx); 900Sstevel@tonic-gate info->argc = argc; 910Sstevel@tonic-gate info->argv = argv; 920Sstevel@tonic-gate for (i = 0; (request = get_request(rqtbl, i))->command_names; i++) { 930Sstevel@tonic-gate for (name = request->command_names; *name; name++) 940Sstevel@tonic-gate if (!strcmp(*name, string)) { 950Sstevel@tonic-gate info->current_request = request->command_names[0]; 960Sstevel@tonic-gate (request->function)(argc, (const char *const *) argv, 970Sstevel@tonic-gate sci_idx,info->info_ptr); 980Sstevel@tonic-gate info->current_request = (char *)NULL; 990Sstevel@tonic-gate return(0); 1000Sstevel@tonic-gate } 1010Sstevel@tonic-gate } 1020Sstevel@tonic-gate return(SS_ET_COMMAND_NOT_FOUND); 1030Sstevel@tonic-gate } 1040Sstevel@tonic-gate 1050Sstevel@tonic-gate /* 1060Sstevel@tonic-gate * really_execute_command(sci_idx, argc, argv) 1070Sstevel@tonic-gate * 1080Sstevel@tonic-gate * Function: 1090Sstevel@tonic-gate * Fills in the argc, argv values in the subsystem entry and 1100Sstevel@tonic-gate * call the appropriate routine. 1110Sstevel@tonic-gate * Arguments: 1120Sstevel@tonic-gate * sci_idx (int) 1130Sstevel@tonic-gate * ss-internal index for subsystem control info structure 1140Sstevel@tonic-gate * argc (int) 1150Sstevel@tonic-gate * number of arguments in argument list 1160Sstevel@tonic-gate * argv (char **[]) 1170Sstevel@tonic-gate * pointer to parsed argument list (may be reallocated 1180Sstevel@tonic-gate * on abbrev expansion) 1190Sstevel@tonic-gate * 1200Sstevel@tonic-gate * Returns: 1210Sstevel@tonic-gate * (int) 1220Sstevel@tonic-gate * Zero if successful, ss_et_command_not_found otherwise. 1230Sstevel@tonic-gate * Notes: 1240Sstevel@tonic-gate */ 1250Sstevel@tonic-gate 1260Sstevel@tonic-gate static int really_execute_command (sci_idx, argc, argv) 1270Sstevel@tonic-gate int sci_idx; 1280Sstevel@tonic-gate int argc; 1290Sstevel@tonic-gate char **argv[]; 1300Sstevel@tonic-gate { 1310Sstevel@tonic-gate register ss_request_table **rqtbl; 1320Sstevel@tonic-gate register ss_data *info; 1330Sstevel@tonic-gate 1340Sstevel@tonic-gate info = ss_info(sci_idx); 1350Sstevel@tonic-gate 1360Sstevel@tonic-gate for (rqtbl = info->rqt_tables; *rqtbl; rqtbl++) { 1370Sstevel@tonic-gate if (check_request_table (*rqtbl, argc, *argv, sci_idx) == 0) 1380Sstevel@tonic-gate return(0); 1390Sstevel@tonic-gate } 1400Sstevel@tonic-gate return(SS_ET_COMMAND_NOT_FOUND); 1410Sstevel@tonic-gate } 1420Sstevel@tonic-gate 1430Sstevel@tonic-gate /* 1440Sstevel@tonic-gate * ss_execute_command(sci_idx, argv) 1450Sstevel@tonic-gate * 1460Sstevel@tonic-gate * Function: 1470Sstevel@tonic-gate * Executes a parsed command list within the subsystem. 1480Sstevel@tonic-gate * Arguments: 1490Sstevel@tonic-gate * sci_idx (int) 1500Sstevel@tonic-gate * ss-internal index for subsystem control info structure 1510Sstevel@tonic-gate * argv (char *[]) 1520Sstevel@tonic-gate * parsed argument list 1530Sstevel@tonic-gate * Returns: 1540Sstevel@tonic-gate * (int) 1550Sstevel@tonic-gate * Zero if successful, ss_et_command_not_found otherwise. 1560Sstevel@tonic-gate * Notes: 1570Sstevel@tonic-gate */ 1580Sstevel@tonic-gate 1590Sstevel@tonic-gate int 1600Sstevel@tonic-gate ss_execute_command(sci_idx, argv) 1610Sstevel@tonic-gate int sci_idx; 1620Sstevel@tonic-gate register char *argv[]; 1630Sstevel@tonic-gate { 1640Sstevel@tonic-gate register int i, argc; 1650Sstevel@tonic-gate char **argp; 1660Sstevel@tonic-gate 1670Sstevel@tonic-gate argc = 0; 1680Sstevel@tonic-gate for (argp = argv; *argp; argp++) 1690Sstevel@tonic-gate argc++; 1700Sstevel@tonic-gate argp = (char **)malloc((argc+1)*sizeof(char *)); 1710Sstevel@tonic-gate for (i = 0; i <= argc; i++) 1720Sstevel@tonic-gate argp[i] = argv[i]; 1730Sstevel@tonic-gate i = really_execute_command(sci_idx, argc, &argp); 1740Sstevel@tonic-gate free(argp); 1750Sstevel@tonic-gate return(i); 1760Sstevel@tonic-gate } 1770Sstevel@tonic-gate 1780Sstevel@tonic-gate /* 1790Sstevel@tonic-gate * ss_execute_line(sci_idx, line_ptr) 1800Sstevel@tonic-gate * 1810Sstevel@tonic-gate * Function: 1820Sstevel@tonic-gate * Parses and executes a command line within a subsystem. 1830Sstevel@tonic-gate * Arguments: 1840Sstevel@tonic-gate * sci_idx (int) 1850Sstevel@tonic-gate * ss-internal index for subsystem control info structure 1860Sstevel@tonic-gate * line_ptr (char *) 1870Sstevel@tonic-gate * Pointer to command line to be parsed. 1880Sstevel@tonic-gate * Returns: 1890Sstevel@tonic-gate * (int) 1900Sstevel@tonic-gate * Error code. 1910Sstevel@tonic-gate * Notes: 1920Sstevel@tonic-gate */ 1930Sstevel@tonic-gate 1940Sstevel@tonic-gate int ss_execute_line (sci_idx, line_ptr) 1950Sstevel@tonic-gate int sci_idx; 1960Sstevel@tonic-gate char *line_ptr; 1970Sstevel@tonic-gate { 1980Sstevel@tonic-gate char **argv; 199*2881Smp153739 int argc, ret; 2000Sstevel@tonic-gate 2010Sstevel@tonic-gate /* flush leading whitespace */ 2020Sstevel@tonic-gate while (line_ptr[0] == ' ' || line_ptr[0] == '\t') 2030Sstevel@tonic-gate line_ptr++; 2040Sstevel@tonic-gate 2050Sstevel@tonic-gate /* check if it should be sent to operating system for execution */ 2060Sstevel@tonic-gate if (*line_ptr == '!') { 2070Sstevel@tonic-gate if (ss_info(sci_idx)->flags.escape_disabled) 2080Sstevel@tonic-gate return SS_ET_ESCAPE_DISABLED; 2090Sstevel@tonic-gate else { 2100Sstevel@tonic-gate line_ptr++; 2110Sstevel@tonic-gate system(line_ptr); 2120Sstevel@tonic-gate return 0; 2130Sstevel@tonic-gate } 2140Sstevel@tonic-gate } 2150Sstevel@tonic-gate 2160Sstevel@tonic-gate /* parse it */ 2170Sstevel@tonic-gate argv = ss_parse(sci_idx, line_ptr, &argc); 2180Sstevel@tonic-gate if (argc == 0) 2190Sstevel@tonic-gate return 0; 2200Sstevel@tonic-gate 2210Sstevel@tonic-gate /* look it up in the request tables, execute if found */ 222*2881Smp153739 ret = really_execute_command (sci_idx, argc, &argv); 2230Sstevel@tonic-gate 2240Sstevel@tonic-gate free(argv); 2250Sstevel@tonic-gate 226*2881Smp153739 return(ret); 2270Sstevel@tonic-gate } 228