You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
230 lines
5.9 KiB
230 lines
5.9 KiB
/*
|
|
* Copyright 1987, 1988, 1989 by Massachusetts Institute of Technology
|
|
*
|
|
* Permission to use, copy, modify, and distribute this software and
|
|
* its documentation for any purpose is hereby granted, provided that
|
|
* the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
|
|
* advertising or publicity pertaining to distribution of the software
|
|
* without specific, written prior permission. M.I.T. and the
|
|
* M.I.T. S.I.P.B. make no representations about the suitability of
|
|
* this software for any purpose. It is provided "as is" without
|
|
* express or implied warranty.
|
|
*/
|
|
|
|
#include "config.h"
|
|
#ifdef HAS_STDLIB_H
|
|
#include <stdlib.h>
|
|
#endif
|
|
#ifdef HAVE_ERRNO_H
|
|
#include <errno.h>
|
|
#else
|
|
extern int errno;
|
|
#endif
|
|
#include "ss_internal.h"
|
|
#include <stdio.h>
|
|
|
|
static int check_request_table PROTOTYPE((ss_request_table *rqtbl, int argc,
|
|
char *argv[], int sci_idx));
|
|
static int really_execute_command PROTOTYPE((int sci_idx, int argc,
|
|
char **argv[]));
|
|
|
|
/*
|
|
* get_request(tbl, idx)
|
|
*
|
|
* Function:
|
|
* Gets the idx'th request from the request table pointed to
|
|
* by tbl.
|
|
* Arguments:
|
|
* tbl (ss_request_table *)
|
|
* pointer to request table
|
|
* idx (int)
|
|
* index into table
|
|
* Returns:
|
|
* (ss_request_entry *)
|
|
* pointer to request table entry
|
|
* Notes:
|
|
* Has been replaced by a macro.
|
|
*/
|
|
|
|
#ifdef __SABER__
|
|
/* sigh. saber won't deal with pointer-to-const-struct */
|
|
static struct _ss_request_entry * get_request (tbl, idx)
|
|
ss_request_table * tbl;
|
|
int idx;
|
|
{
|
|
struct _ss_request_table *tbl1 = (struct _ss_request_table *) tbl;
|
|
struct _ss_request_entry *e = (struct _ss_request_entry *) tbl1->requests;
|
|
return e + idx;
|
|
}
|
|
#else
|
|
#define get_request(tbl,idx) ((tbl) -> requests + (idx))
|
|
#endif
|
|
|
|
/*
|
|
* check_request_table(rqtbl, argc, argv, sci_idx)
|
|
*
|
|
* Function:
|
|
* If the command string in argv[0] is in the request table, execute
|
|
* the commands and return error code 0. Otherwise, return error
|
|
* code ss_et_command_not_found.
|
|
* Arguments:
|
|
* rqtbl (ss_request_table *)
|
|
* pointer to request table
|
|
* argc (int)
|
|
* number of elements in argv[]
|
|
* argv (char *[])
|
|
* argument string array
|
|
* sci_idx (int)
|
|
* ss-internal index for subsystem control info structure
|
|
* Returns:
|
|
* (int)
|
|
* zero if command found, ss_et_command_not_found otherwise
|
|
* Notes:
|
|
*/
|
|
|
|
static int check_request_table(register ss_request_table *rqtbl, int argc,
|
|
char *argv[], int sci_idx)
|
|
{
|
|
#ifdef __SABER__
|
|
struct _ss_request_entry *request;
|
|
#else
|
|
register ss_request_entry *request;
|
|
#endif
|
|
register ss_data *info;
|
|
register char const * const * name;
|
|
char *string = argv[0];
|
|
int i;
|
|
|
|
info = ss_info(sci_idx);
|
|
info->argc = argc;
|
|
info->argv = argv;
|
|
for (i = 0; (request = get_request(rqtbl, i))->command_names; i++) {
|
|
for (name = request->command_names; *name; name++)
|
|
if (!strcmp(*name, string)) {
|
|
info->current_request = request->command_names[0];
|
|
(request->function)(argc, (const char *const *) argv,
|
|
sci_idx,info->info_ptr);
|
|
info->current_request = (char *)NULL;
|
|
return(0);
|
|
}
|
|
}
|
|
return(SS_ET_COMMAND_NOT_FOUND);
|
|
}
|
|
|
|
/*
|
|
* really_execute_command(sci_idx, argc, argv)
|
|
*
|
|
* Function:
|
|
* Fills in the argc, argv values in the subsystem entry and
|
|
* call the appropriate routine.
|
|
* Arguments:
|
|
* sci_idx (int)
|
|
* ss-internal index for subsystem control info structure
|
|
* argc (int)
|
|
* number of arguments in argument list
|
|
* argv (char **[])
|
|
* pointer to parsed argument list (may be reallocated
|
|
* on abbrev expansion)
|
|
*
|
|
* Returns:
|
|
* (int)
|
|
* Zero if successful, ss_et_command_not_found otherwise.
|
|
* Notes:
|
|
*/
|
|
|
|
static int really_execute_command(int sci_idx, int argc, char **argv[])
|
|
{
|
|
register ss_request_table **rqtbl;
|
|
register ss_data *info;
|
|
|
|
info = ss_info(sci_idx);
|
|
|
|
for (rqtbl = info->rqt_tables; *rqtbl; rqtbl++) {
|
|
if (check_request_table (*rqtbl, argc, *argv, sci_idx) == 0)
|
|
return(0);
|
|
}
|
|
return(SS_ET_COMMAND_NOT_FOUND);
|
|
}
|
|
|
|
/*
|
|
* ss_execute_command(sci_idx, argv)
|
|
*
|
|
* Function:
|
|
* Executes a parsed command list within the subsystem.
|
|
* Arguments:
|
|
* sci_idx (int)
|
|
* ss-internal index for subsystem control info structure
|
|
* argv (char *[])
|
|
* parsed argument list
|
|
* Returns:
|
|
* (int)
|
|
* Zero if successful, ss_et_command_not_found otherwise.
|
|
* Notes:
|
|
*/
|
|
|
|
int ss_execute_command(int sci_idx, register char *argv[])
|
|
{
|
|
register int i, argc;
|
|
char **argp;
|
|
|
|
argc = 0;
|
|
for (argp = argv; *argp; argp++)
|
|
argc++;
|
|
argp = (char **)malloc((argc+1)*sizeof(char *));
|
|
for (i = 0; i <= argc; i++)
|
|
argp[i] = argv[i];
|
|
i = really_execute_command(sci_idx, argc, &argp);
|
|
free(argp);
|
|
return(i);
|
|
}
|
|
|
|
/*
|
|
* ss_execute_line(sci_idx, line_ptr)
|
|
*
|
|
* Function:
|
|
* Parses and executes a command line within a subsystem.
|
|
* Arguments:
|
|
* sci_idx (int)
|
|
* ss-internal index for subsystem control info structure
|
|
* line_ptr (char *)
|
|
* Pointer to command line to be parsed.
|
|
* Returns:
|
|
* (int)
|
|
* Error code.
|
|
* Notes:
|
|
*/
|
|
|
|
int ss_execute_line(int sci_idx, char *line_ptr)
|
|
{
|
|
char **argv;
|
|
int argc, ret;
|
|
|
|
/* flush leading whitespace */
|
|
while (line_ptr[0] == ' ' || line_ptr[0] == '\t')
|
|
line_ptr++;
|
|
|
|
/* check if it should be sent to operating system for execution */
|
|
if (*line_ptr == '!') {
|
|
if (ss_info(sci_idx)->flags.escape_disabled)
|
|
return SS_ET_ESCAPE_DISABLED;
|
|
else {
|
|
line_ptr++;
|
|
return (system(line_ptr) < 0) ? errno : 0;
|
|
}
|
|
}
|
|
|
|
/* parse it */
|
|
argv = ss_parse(sci_idx, line_ptr, &argc);
|
|
if (argc == 0) {
|
|
free(argv);
|
|
return 0;
|
|
}
|
|
|
|
/* look it up in the request tables, execute if found */
|
|
ret = really_execute_command (sci_idx, argc, &argv);
|
|
|
|
free(argv);
|
|
|
|
return(ret);
|
|
}
|