2N/A/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2N/A/*
2N/A * Copyright 1987, 1988, 1989 by Massachusetts Institute of Technology
2N/A *
2N/A * For copyright info, see copyright.h.
2N/A */
2N/A/*
2N/A * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
2N/A */
2N/A
2N/A#include "ss_internal.h"
2N/A#include "copyright.h"
2N/A#include <stdio.h>
2N/A
2N/A
2N/A/*
2N/A * get_request(tbl, idx)
2N/A *
2N/A * Function:
2N/A * Gets the idx'th request from the request table pointed to
2N/A * by tbl.
2N/A * Arguments:
2N/A * tbl (ss_request_table *)
2N/A * pointer to request table
2N/A * idx (int)
2N/A * index into table
2N/A * Returns:
2N/A * (ss_request_entry *)
2N/A * pointer to request table entry
2N/A * Notes:
2N/A * Has been replaced by a macro.
2N/A */
2N/A
2N/A#ifdef __SABER__
2N/A/* sigh. saber won't deal with pointer-to-const-struct */
2N/Astatic struct _ss_request_entry * get_request (tbl, idx)
2N/A ss_request_table * tbl;
2N/A int idx;
2N/A{
2N/A struct _ss_request_table *tbl1 = (struct _ss_request_table *) tbl;
2N/A struct _ss_request_entry *e = (struct _ss_request_entry *) tbl1->requests;
2N/A return e + idx;
2N/A}
2N/A#else
2N/A#define get_request(tbl,idx) ((tbl) -> requests + (idx))
2N/A#endif
2N/A
2N/A/*
2N/A * check_request_table(rqtbl, argc, argv, sci_idx)
2N/A *
2N/A * Function:
2N/A * If the command string in argv[0] is in the request table, execute
2N/A * the commands and return error code 0. Otherwise, return error
2N/A * code ss_et_command_not_found.
2N/A * Arguments:
2N/A * rqtbl (ss_request_table *)
2N/A * pointer to request table
2N/A * argc (int)
2N/A * number of elements in argv[]
2N/A * argv (char *[])
2N/A * argument string array
2N/A * sci_idx (int)
2N/A * ss-internal index for subsystem control info structure
2N/A * Returns:
2N/A * (int)
2N/A * Solaris Kerberos:
2N/A * zero or SS_ET_COMMAND_ERR if command found,
2N/A * ss_et_command_not_found otherwise
2N/A * Notes:
2N/A */
2N/A
2N/Astatic int check_request_table (rqtbl, argc, argv, sci_idx)
2N/A register ss_request_table *rqtbl;
2N/A int argc;
2N/A char *argv[];
2N/A int sci_idx;
2N/A{
2N/A#ifdef __SABER__
2N/A struct _ss_request_entry *request;
2N/A#else
2N/A register ss_request_entry *request;
2N/A#endif
2N/A register ss_data *info;
2N/A register char const * const * name;
2N/A char *string = argv[0];
2N/A /* Solaris Kerberos */
2N/A int i, ret;
2N/A
2N/A info = ss_info(sci_idx);
2N/A info->argc = argc;
2N/A info->argv = argv;
2N/A for (i = 0; (request = get_request(rqtbl, i))->command_names; i++) {
2N/A for (name = request->command_names; *name; name++)
2N/A if (!strcmp(*name, string)) {
2N/A info->current_request = request->command_names[0];
2N/A /* Solaris Kerberos */
2N/A ret = (request->function)(argc, (const char *const *) argv,
2N/A sci_idx,info->info_ptr);
2N/A info->current_request = (char *)NULL;
2N/A return(ret == 0 ? 0 : SS_ET_COMMAND_ERR);
2N/A }
2N/A }
2N/A return(SS_ET_COMMAND_NOT_FOUND);
2N/A}
2N/A
2N/A/*
2N/A * really_execute_command(sci_idx, argc, argv)
2N/A *
2N/A * Function:
2N/A * Fills in the argc, argv values in the subsystem entry and
2N/A * call the appropriate routine.
2N/A * Arguments:
2N/A * sci_idx (int)
2N/A * ss-internal index for subsystem control info structure
2N/A * argc (int)
2N/A * number of arguments in argument list
2N/A * argv (char **[])
2N/A * pointer to parsed argument list (may be reallocated
2N/A * on abbrev expansion)
2N/A *
2N/A * Returns:
2N/A * (int)
2N/A * Solaris Kerberos:
2N/A * Zero if successful, SS_ET_COMMAND_NOT_FOUND if unsucessful,
2N/A * ss_et_command_not_found otherwise.
2N/A * Notes:
2N/A */
2N/A
2N/Astatic int really_execute_command (sci_idx, argc, argv)
2N/A int sci_idx;
2N/A int argc;
2N/A char **argv[];
2N/A{
2N/A register ss_request_table **rqtbl;
2N/A register ss_data *info;
2N/A /* Solaris Kerberos */
2N/A int ret;
2N/A
2N/A info = ss_info(sci_idx);
2N/A
2N/A for (rqtbl = info->rqt_tables; *rqtbl; rqtbl++) {
2N/A /* Solaris Kerberos */
2N/A ret = check_request_table (*rqtbl, argc, *argv, sci_idx);
2N/A if (ret == 0 || ret == SS_ET_COMMAND_ERR)
2N/A return (ret);
2N/A }
2N/A return(SS_ET_COMMAND_NOT_FOUND);
2N/A}
2N/A
2N/A/*
2N/A * ss_execute_command(sci_idx, argv)
2N/A *
2N/A * Function:
2N/A * Executes a parsed command list within the subsystem.
2N/A * Arguments:
2N/A * sci_idx (int)
2N/A * ss-internal index for subsystem control info structure
2N/A * argv (char *[])
2N/A * parsed argument list
2N/A * Returns:
2N/A * (int)
2N/A * Solaris Kerberos:
2N/A * Zero if successful, SS_ET_COMMAND_NOT_FOUND if unsucessful,
2N/A * ss_et_command_not_found otherwise.
2N/A * Notes:
2N/A */
2N/A
2N/Aint
2N/Ass_execute_command(sci_idx, argv)
2N/A int sci_idx;
2N/A register char *argv[];
2N/A{
2N/A register int i, argc;
2N/A char **argp;
2N/A
2N/A argc = 0;
2N/A for (argp = argv; *argp; argp++)
2N/A argc++;
2N/A argp = (char **)malloc((argc+1)*sizeof(char *));
2N/A for (i = 0; i <= argc; i++)
2N/A argp[i] = argv[i];
2N/A i = really_execute_command(sci_idx, argc, &argp);
2N/A free(argp);
2N/A return(i);
2N/A}
2N/A
2N/A/*
2N/A * ss_execute_line(sci_idx, line_ptr)
2N/A *
2N/A * Function:
2N/A * Parses and executes a command line within a subsystem.
2N/A * Arguments:
2N/A * sci_idx (int)
2N/A * ss-internal index for subsystem control info structure
2N/A * line_ptr (char *)
2N/A * Pointer to command line to be parsed.
2N/A * Returns:
2N/A * (int)
2N/A * Error code.
2N/A * Notes:
2N/A */
2N/A
2N/Aint ss_execute_line (sci_idx, line_ptr)
2N/A int sci_idx;
2N/A char *line_ptr;
2N/A{
2N/A char **argv;
2N/A int argc, ret;
2N/A
2N/A /* flush leading whitespace */
2N/A while (line_ptr[0] == ' ' || line_ptr[0] == '\t')
2N/A line_ptr++;
2N/A
2N/A /* check if it should be sent to operating system for execution */
2N/A if (*line_ptr == '!') {
2N/A if (ss_info(sci_idx)->flags.escape_disabled)
2N/A return SS_ET_ESCAPE_DISABLED;
2N/A else {
2N/A line_ptr++;
2N/A system(line_ptr);
2N/A return 0;
2N/A }
2N/A }
2N/A
2N/A /* parse it */
2N/A /* Solaris Kerberos */
2N/A (void) ss_parse(sci_idx, line_ptr, &argc, &argv, 0);
2N/A if (argc == 0)
2N/A return 0;
2N/A
2N/A /* look it up in the request tables, execute if found */
2N/A ret = really_execute_command (sci_idx, argc, &argv);
2N/A
2N/A free(argv);
2N/A
2N/A return(ret);
2N/A}