/*
 * 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);
}
