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 (rqtbl, argc, argv, sci_idx)
     85     register ss_request_table *rqtbl;
     86     int argc;
     87     char *argv[];
     88     int sci_idx;
     89 {
     90 #ifdef __SABER__
     91     struct _ss_request_entry *request;
     92 #else
     93     register ss_request_entry *request;
     94 #endif
     95     register ss_data *info;
     96     register char const * const * name;
     97     char *string = argv[0];
     98     int i;
     99 
    100     info = ss_info(sci_idx);
    101     info->argc = argc;
    102     info->argv = argv;
    103     for (i = 0; (request = get_request(rqtbl, i))->command_names; i++) {
    104 	for (name = request->command_names; *name; name++)
    105 	    if (!strcmp(*name, string)) {
    106 		info->current_request = request->command_names[0];
    107 		(request->function)(argc, (const char *const *) argv,
    108 				    sci_idx,info->info_ptr);
    109 		info->current_request = (char *)NULL;
    110 		return(0);
    111 	    }
    112     }
    113     return(SS_ET_COMMAND_NOT_FOUND);
    114 }
    115 
    116 /*
    117  * really_execute_command(sci_idx, argc, argv)
    118  *
    119  * Function:
    120  *      Fills in the argc, argv values in the subsystem entry and
    121  *      call the appropriate routine.
    122  * Arguments:
    123  *      sci_idx (int)
    124  *              ss-internal index for subsystem control info structure
    125  *      argc (int)
    126  *              number of arguments in argument list
    127  *      argv (char **[])
    128  *              pointer to parsed argument list (may be reallocated
    129  *              on abbrev expansion)
    130  *
    131  * Returns:
    132  *      (int)
    133  *              Zero if successful, ss_et_command_not_found otherwise.
    134  * Notes:
    135  */
    136 
    137 static int really_execute_command (sci_idx, argc, argv)
    138     int sci_idx;
    139     int argc;
    140     char **argv[];
    141 {
    142     register ss_request_table **rqtbl;
    143     register ss_data *info;
    144 
    145     info = ss_info(sci_idx);
    146 
    147     for (rqtbl = info->rqt_tables; *rqtbl; rqtbl++) {
    148         if (check_request_table (*rqtbl, argc, *argv, sci_idx) == 0)
    149             return(0);
    150     }
    151     return(SS_ET_COMMAND_NOT_FOUND);
    152 }
    153 
    154 /*
    155  * ss_execute_command(sci_idx, argv)
    156  *
    157  * Function:
    158  *	Executes a parsed command list within the subsystem.
    159  * Arguments:
    160  *	sci_idx (int)
    161  *		ss-internal index for subsystem control info structure
    162  *	argv (char *[])
    163  *		parsed argument list
    164  * Returns:
    165  *	(int)
    166  *		Zero if successful, ss_et_command_not_found otherwise.
    167  * Notes:
    168  */
    169 
    170 int ss_execute_command(sci_idx, argv)
    171 	int sci_idx;
    172 	register char *argv[];
    173 {
    174 	register int i, argc;
    175 	char **argp;
    176 
    177 	argc = 0;
    178 	for (argp = argv; *argp; argp++)
    179 		argc++;
    180 	argp = (char **)malloc((argc+1)*sizeof(char *));
    181 	for (i = 0; i <= argc; i++)
    182 		argp[i] = argv[i];
    183 	i = really_execute_command(sci_idx, argc, &argp);
    184 	free(argp);
    185 	return(i);
    186 }
    187 
    188 /*
    189  * ss_execute_line(sci_idx, line_ptr)
    190  *
    191  * Function:
    192  *      Parses and executes a command line within a subsystem.
    193  * Arguments:
    194  *      sci_idx (int)
    195  *              ss-internal index for subsystem control info structure
    196  *      line_ptr (char *)
    197  *              Pointer to command line to be parsed.
    198  * Returns:
    199  *      (int)
    200  *      	Error code.
    201  * Notes:
    202  */
    203 
    204 int ss_execute_line (sci_idx, line_ptr)
    205     int sci_idx;
    206     char *line_ptr;
    207 {
    208     char **argv;
    209     int argc, ret;
    210 
    211     /* flush leading whitespace */
    212     while (line_ptr[0] == ' ' || line_ptr[0] == '\t')
    213         line_ptr++;
    214 
    215     /* check if it should be sent to operating system for execution */
    216     if (*line_ptr == '!') {
    217         if (ss_info(sci_idx)->flags.escape_disabled)
    218             return SS_ET_ESCAPE_DISABLED;
    219         else {
    220             line_ptr++;
    221             return (system(line_ptr) < 0) ? errno : 0;
    222         }
    223     }
    224 
    225     /* parse it */
    226     argv = ss_parse(sci_idx, line_ptr, &argc);
    227     if (argc == 0) {
    228 	free(argv);
    229         return 0;
    230     }
    231 
    232     /* look it up in the request tables, execute if found */
    233     ret = really_execute_command (sci_idx, argc, &argv);
    234 
    235     free(argv);
    236 
    237     return(ret);
    238 }
    239