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