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