Home | History | Annotate | Download | only in ss
      1 /*
      2  * Copyright 1987, 1988, 1989 by Massachusetts Institute of Technology
      3  *
      4  * Permission to use, copy, modify, and distribute this software and
      5  * its documentation for any purpose is hereby granted, provided that
      6  * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
      7  * advertising or publicity pertaining to distribution of the software
      8  * without specific, written prior permission.  M.I.T. and the
      9  * M.I.T. S.I.P.B. make no representations about the suitability of
     10  * this software for any purpose.  It is provided "as is" without
     11  * express or implied warranty.
     12  */
     13 
     14 #ifdef HAS_STDLIB_H
     15 #include <stdlib.h>
     16 #endif
     17 #include "ss_internal.h"
     18 #include <stdio.h>
     19 
     20 static int check_request_table PROTOTYPE((ss_request_table *rqtbl, int argc,
     21 					  char *argv[], int sci_idx));
     22 static int really_execute_command PROTOTYPE((int sci_idx, int argc,
     23 					     char **argv[]));
     24 
     25 /*
     26  * get_request(tbl, idx)
     27  *
     28  * Function:
     29  *      Gets the idx'th request from the request table pointed to
     30  *      by tbl.
     31  * Arguments:
     32  *      tbl (ss_request_table *)
     33  *              pointer to request table
     34  *      idx (int)
     35  *              index into table
     36  * Returns:
     37  *      (ss_request_entry *)
     38  *              pointer to request table entry
     39  * Notes:
     40  *      Has been replaced by a macro.
     41  */
     42 
     43 #ifdef __SABER__
     44 /* sigh.  saber won't deal with pointer-to-const-struct */
     45 static struct _ss_request_entry * get_request (tbl, idx)
     46     ss_request_table * tbl;
     47     int idx;
     48 {
     49     struct _ss_request_table *tbl1 = (struct _ss_request_table *) tbl;
     50     struct _ss_request_entry *e = (struct _ss_request_entry *) tbl1->requests;
     51     return e + idx;
     52 }
     53 #else
     54 #define get_request(tbl,idx)    ((tbl) -> requests + (idx))
     55 #endif
     56 
     57 /*
     58  * check_request_table(rqtbl, argc, argv, sci_idx)
     59  *
     60  * Function:
     61  *      If the command string in argv[0] is in the request table, execute
     62  *      the commands and return error code 0.  Otherwise, return error
     63  *      code ss_et_command_not_found.
     64  * Arguments:
     65  *      rqtbl (ss_request_table *)
     66  *              pointer to request table
     67  *      argc (int)
     68  *              number of elements in argv[]
     69  *      argv (char *[])
     70  *              argument string array
     71  *      sci_idx (int)
     72  *              ss-internal index for subsystem control info structure
     73  * Returns:
     74  *      (int)
     75  *              zero if command found, ss_et_command_not_found otherwise
     76  * Notes:
     77  */
     78 
     79 static int check_request_table (rqtbl, argc, argv, sci_idx)
     80     register ss_request_table *rqtbl;
     81     int argc;
     82     char *argv[];
     83     int sci_idx;
     84 {
     85 #ifdef __SABER__
     86     struct _ss_request_entry *request;
     87 #else
     88     register ss_request_entry *request;
     89 #endif
     90     register ss_data *info;
     91     register char const * const * name;
     92     char *string = argv[0];
     93     int i;
     94 
     95     info = ss_info(sci_idx);
     96     info->argc = argc;
     97     info->argv = argv;
     98     for (i = 0; (request = get_request(rqtbl, i))->command_names; i++) {
     99 	for (name = request->command_names; *name; name++)
    100 	    if (!strcmp(*name, string)) {
    101 		info->current_request = request->command_names[0];
    102 		(request->function)(argc, (const char *const *) argv,
    103 				    sci_idx,info->info_ptr);
    104 		info->current_request = (char *)NULL;
    105 		return(0);
    106 	    }
    107     }
    108     return(SS_ET_COMMAND_NOT_FOUND);
    109 }
    110 
    111 /*
    112  * really_execute_command(sci_idx, argc, argv)
    113  *
    114  * Function:
    115  *      Fills in the argc, argv values in the subsystem entry and
    116  *      call the appropriate routine.
    117  * Arguments:
    118  *      sci_idx (int)
    119  *              ss-internal index for subsystem control info structure
    120  *      argc (int)
    121  *              number of arguments in argument list
    122  *      argv (char **[])
    123  *              pointer to parsed argument list (may be reallocated
    124  *              on abbrev expansion)
    125  *
    126  * Returns:
    127  *      (int)
    128  *              Zero if successful, ss_et_command_not_found otherwise.
    129  * Notes:
    130  */
    131 
    132 static int really_execute_command (sci_idx, argc, argv)
    133     int sci_idx;
    134     int argc;
    135     char **argv[];
    136 {
    137     register ss_request_table **rqtbl;
    138     register ss_data *info;
    139 
    140     info = ss_info(sci_idx);
    141 
    142     for (rqtbl = info->rqt_tables; *rqtbl; rqtbl++) {
    143         if (check_request_table (*rqtbl, argc, *argv, sci_idx) == 0)
    144             return(0);
    145     }
    146     return(SS_ET_COMMAND_NOT_FOUND);
    147 }
    148 
    149 /*
    150  * ss_execute_command(sci_idx, argv)
    151  *
    152  * Function:
    153  *	Executes a parsed command list within the subsystem.
    154  * Arguments:
    155  *	sci_idx (int)
    156  *		ss-internal index for subsystem control info structure
    157  *	argv (char *[])
    158  *		parsed argument list
    159  * Returns:
    160  *	(int)
    161  *		Zero if successful, ss_et_command_not_found otherwise.
    162  * Notes:
    163  */
    164 
    165 int ss_execute_command(sci_idx, argv)
    166 	int sci_idx;
    167 	register char *argv[];
    168 {
    169 	register int i, argc;
    170 	char **argp;
    171 
    172 	argc = 0;
    173 	for (argp = argv; *argp; argp++)
    174 		argc++;
    175 	argp = (char **)malloc((argc+1)*sizeof(char *));
    176 	for (i = 0; i <= argc; i++)
    177 		argp[i] = argv[i];
    178 	i = really_execute_command(sci_idx, argc, &argp);
    179 	free(argp);
    180 	return(i);
    181 }
    182 
    183 /*
    184  * ss_execute_line(sci_idx, line_ptr)
    185  *
    186  * Function:
    187  *      Parses and executes a command line within a subsystem.
    188  * Arguments:
    189  *      sci_idx (int)
    190  *              ss-internal index for subsystem control info structure
    191  *      line_ptr (char *)
    192  *              Pointer to command line to be parsed.
    193  * Returns:
    194  *      (int)
    195  *      	Error code.
    196  * Notes:
    197  */
    198 
    199 int ss_execute_line (sci_idx, line_ptr)
    200     int sci_idx;
    201     char *line_ptr;
    202 {
    203     char **argv;
    204     int argc, ret;
    205 
    206     /* flush leading whitespace */
    207     while (line_ptr[0] == ' ' || line_ptr[0] == '\t')
    208         line_ptr++;
    209 
    210     /* check if it should be sent to operating system for execution */
    211     if (*line_ptr == '!') {
    212         if (ss_info(sci_idx)->flags.escape_disabled)
    213             return SS_ET_ESCAPE_DISABLED;
    214         else {
    215             line_ptr++;
    216             system(line_ptr);
    217 	    return 0;
    218         }
    219     }
    220 
    221     /* parse it */
    222     argv = ss_parse(sci_idx, line_ptr, &argc);
    223     if (argc == 0) {
    224 	if (argv)
    225 	    free(argv);
    226         return 0;
    227     }
    228 
    229     /* look it up in the request tables, execute if found */
    230     ret = really_execute_command (sci_idx, argc, &argv);
    231 
    232     free(argv);
    233 
    234     return(ret);
    235 }
    236