MIT SIPB subsystem' library, needed for kadmin' and some other MIT programs.

This commit is contained in:
Garrett Wollman 1995-01-19 21:28:01 +00:00
parent 0cd34073b2
commit 282244c5b6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/sipb/; revision=5717
17 changed files with 1445 additions and 0 deletions

19
lib/libss/copyright.h Normal file
View File

@ -0,0 +1,19 @@
/*
Copyright 1987, 1989 by the Student Information Processing Board
of the Massachusetts Institute of Technology
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is
hereby granted, provided that the above copyright notice
appear in all copies and that both that copyright notice and
this permission notice appear in supporting documentation,
and 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.
*/

16
lib/libss/data.c Normal file
View File

@ -0,0 +1,16 @@
/*
* Copyright 1987, 1988, 1989 Massachusetts Institute of Technology
* (Student Information Processing Board)
*
* For copyright info, see copyright.h.
*/
#include <stdio.h>
#include "ss_internal.h"
#include "copyright.h"
const static char copyright[] =
"Copyright 1987, 1988, 1989 by the Massachusetts Institute of Technology";
ss_data **_ss_table = (ss_data **)NULL;
char *_ss_pager_name = (char *)NULL;

98
lib/libss/error.c Normal file
View File

@ -0,0 +1,98 @@
/*
* Copyright 1987, 1988, 1989 by MIT Student Information Processing
* Board
*
* For copyright information, see copyright.h.
*/
#include <stdio.h>
/*
* Our standalone dpANS environment on the RT doesn't include any
* header files.
*/
#if defined(__STDC__) && !defined(ibm032)
#include <stdarg.h>
#define STDARG
#else
#include <varargs.h>
#define ss_error ss_error_external
#endif
#include "copyright.h"
#include <com_err.h>
#include "ss_internal.h"
#undef ss_error
char * ss_name(sci_idx)
int sci_idx;
{
register char *ret_val;
register ss_data *infop;
infop = ss_info(sci_idx);
if (infop->current_request == (char const *)NULL) {
ret_val = malloc((unsigned)
(strlen(infop->subsystem_name)+1)
* sizeof(char));
if (ret_val == (char *)NULL)
return((char *)NULL);
strcpy(ret_val, infop->subsystem_name);
return(ret_val);
}
else {
register char *cp;
register char const *cp1;
ret_val = malloc((unsigned)sizeof(char) *
(strlen(infop->subsystem_name)+
strlen(infop->current_request)+
4));
cp = ret_val;
cp1 = infop->subsystem_name;
while (*cp1)
*cp++ = *cp1++;
*cp++ = ' ';
*cp++ = '(';
cp1 = infop->current_request;
while (*cp1)
*cp++ = *cp1++;
*cp++ = ')';
*cp = '\0';
return(ret_val);
}
}
#ifdef STDARG
void ss_error (int sci_idx, long code, const char * fmt, ...)
#else
void ss_error (va_alist)
va_dcl
#endif
{
register char const *whoami;
va_list pvar;
#ifndef STDARG
int sci_idx;
long code;
char * fmt;
va_start (pvar);
sci_idx = va_arg (pvar, int);
code = va_arg (pvar, long);
fmt = va_arg (pvar, char *);
#else
va_start (pvar, fmt);
#endif
whoami = ss_name (sci_idx);
com_err_va (whoami, code, fmt, pvar);
free (whoami);
va_end(pvar);
}
void ss_perror (sci_idx, code, msg) /* for compatibility */
int sci_idx;
long code;
char const *msg;
{
ss_error (sci_idx, code, "%s", msg);
}

219
lib/libss/execute_cmd.c Normal file
View File

@ -0,0 +1,219 @@
/*
* Copyright 1987, 1988, 1989 by Massachusetts Institute of Technology
*
* For copyright info, see copyright.h.
*/
#include "ss_internal.h"
#include "copyright.h"
#include <stdio.h>
#ifndef lint
static char const rcsid[] =
"Header: execute_cmd.c,v 1.7 89/01/25 08:27:43 raeburn Exp ";
#endif
/*
* 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 (rqtbl, argc, argv, sci_idx)
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 (sci_idx, argc, argv)
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:
*/
ss_execute_command(sci_idx, argv)
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 (sci_idx, line_ptr)
int sci_idx;
char *line_ptr;
{
char **argv;
int argc;
/* 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++;
system(line_ptr);
return 0;
}
}
/* parse it */
argv = ss_parse(sci_idx, line_ptr, &argc);
if (argc == 0)
return 0;
/* look it up in the request tables, execute if found */
return really_execute_command (sci_idx, argc, &argv);
}

143
lib/libss/help.c Normal file
View File

@ -0,0 +1,143 @@
/*
* Copyright 1987, 1988 by MIT Student Information Processing Board
*
* For copyright info, see copyright.h.
*/
#include <sys/param.h>
#include <sys/file.h>
#include <sys/wait.h>
#include "ss_internal.h"
#include "copyright.h"
extern int errno;
void ss_help (argc, argv, sci_idx, info_ptr)
int argc;
char const * const *argv;
int sci_idx;
pointer info_ptr;
{
char buffer[MAXPATHLEN];
char const *request_name;
int code;
int fd, child;
register int idx;
register ss_data *info;
request_name = ss_current_request(sci_idx, &code);
if (code != 0) {
ss_perror(sci_idx, code, "");
return; /* no ss_abort_line, if invalid invocation */
}
if (argc == 1) {
ss_list_requests(argc, argv, sci_idx, info_ptr);
return;
}
else if (argc != 2) {
/* should do something better than this */
sprintf(buffer, "usage:\n\t%s [topic|command]\nor\t%s\n",
request_name, request_name);
ss_perror(sci_idx, 0, buffer);
return;
}
info = ss_info(sci_idx);
if (info->info_dirs == (char **)NULL) {
ss_perror(sci_idx, SS_ET_NO_INFO_DIR, (char *)NULL);
return;
}
if (info->info_dirs[0] == (char *)NULL) {
ss_perror(sci_idx, SS_ET_NO_INFO_DIR, (char *)NULL);
return;
}
for (idx = 0; info->info_dirs[idx] != (char *)NULL; idx++) {
(void) strcpy(buffer, info->info_dirs[idx]);
(void) strcat(buffer, "/");
(void) strcat(buffer, argv[1]);
(void) strcat(buffer, ".info");
if ((fd = open(&buffer[0], O_RDONLY, 0)) >= 0) goto got_it;
}
if ((fd = open(&buffer[0], O_RDONLY, 0)) < 0) {
char buf[MAXPATHLEN];
strcpy(buf, "No info found for ");
strcat(buf, argv[1]);
ss_perror(sci_idx, 0, buf);
return;
}
got_it:
switch (child = fork()) {
case -1:
ss_perror(sci_idx, errno, "Can't fork for pager");
return;
case 0:
(void) dup2(fd, 0); /* put file on stdin */
ss_page_stdin();
default:
(void) close(fd); /* what can we do if it fails? */
while (wait((union wait *)NULL) != child) {
/* do nothing if wrong pid */
};
}
}
#include <sys/types.h>
#include <sys/dir.h>
void ss_add_info_dir(sci_idx, info_dir, code_ptr)
int sci_idx;
char *info_dir;
int *code_ptr;
{
register ss_data *info;
DIR *d;
int n_dirs;
register char **dirs;
info = ss_info(sci_idx);
if (info_dir == NULL && *info_dir) {
*code_ptr = SS_ET_NO_INFO_DIR;
return;
}
if ((d = opendir(info_dir)) == (DIR *)NULL) {
*code_ptr = errno;
return;
}
closedir(d);
dirs = info->info_dirs;
for (n_dirs = 0; dirs[n_dirs] != (char *)NULL; n_dirs++)
; /* get number of non-NULL dir entries */
dirs = (char **)realloc((char *)dirs,
(unsigned)(n_dirs + 2)*sizeof(char *));
if (dirs == (char **)NULL) {
info->info_dirs = (char **)NULL;
*code_ptr = errno;
return;
}
info->info_dirs = dirs;
dirs[n_dirs + 1] = (char *)NULL;
dirs[n_dirs] = malloc((unsigned)strlen(info_dir)+1);
strcpy(dirs[n_dirs], info_dir);
*code_ptr = 0;
}
void ss_delete_info_dir(sci_idx, info_dir, code_ptr)
int sci_idx;
char *info_dir;
int *code_ptr;
{
register char **i_d;
register char **info_dirs;
info_dirs = ss_info(sci_idx)->info_dirs;
for (i_d = info_dirs; *i_d; i_d++) {
if (!strcmp(*i_d, info_dir)) {
while (*i_d) {
*i_d = *(i_d+1);
i_d++;
}
*code_ptr = 0;
return;
}
}
*code_ptr = SS_ET_NO_INFO_DIR;
}

82
lib/libss/invocation.c Normal file
View File

@ -0,0 +1,82 @@
/*
* Copyright 1987, 1988 by MIT Student Information Processing Board
*
* For copyright information, see copyright.h.
*/
#include "ss_internal.h"
#include "copyright.h"
#define size sizeof(ss_data *)
#ifndef lint
static char const rcsid[] =
"Header: invocation.c,v 1.6 89/01/25 07:45:47 raeburn Exp ";
#endif
int ss_create_invocation(subsystem_name, version_string, info_ptr,
request_table_ptr, code_ptr)
char *subsystem_name, *version_string;
char *info_ptr;
ss_request_table *request_table_ptr;
int *code_ptr;
{
register int sci_idx;
register ss_data *new_table;
register ss_data **table;
*code_ptr = 0;
table = _ss_table;
new_table = (ss_data *) malloc(sizeof(ss_data));
if (table == (ss_data **) NULL) {
table = (ss_data **) malloc(2 * size);
table[0] = table[1] = (ss_data *)NULL;
}
initialize_ss_error_table ();
for (sci_idx = 1; table[sci_idx] != (ss_data *)NULL; sci_idx++)
;
table = (ss_data **) realloc((char *)table,
((unsigned)sci_idx+2)*size);
table[sci_idx+1] = (ss_data *) NULL;
table[sci_idx] = new_table;
new_table->subsystem_name = subsystem_name;
new_table->subsystem_version = version_string;
new_table->argv = (char **)NULL;
new_table->current_request = (char *)NULL;
new_table->info_dirs = (char **)malloc(sizeof(char *));
*new_table->info_dirs = (char *)NULL;
new_table->info_ptr = info_ptr;
new_table->prompt = malloc((unsigned)strlen(subsystem_name)+4);
strcpy(new_table->prompt, subsystem_name);
strcat(new_table->prompt, ": ");
#ifdef silly
new_table->abbrev_info = ss_abbrev_initialize("/etc/passwd", code_ptr);
#else
new_table->abbrev_info = NULL;
#endif
new_table->flags.escape_disabled = 0;
new_table->flags.abbrevs_disabled = 0;
new_table->rqt_tables =
(ss_request_table **) calloc(2, sizeof(ss_request_table *));
*(new_table->rqt_tables) = request_table_ptr;
*(new_table->rqt_tables+1) = (ss_request_table *) NULL;
_ss_table = table;
return(sci_idx);
}
void
ss_delete_invocation(sci_idx)
int sci_idx;
{
register ss_data *t;
int ignored_code;
t = ss_info(sci_idx);
free(t->prompt);
free((char *)t->rqt_tables);
while(t->info_dirs[0] != (char *)NULL)
ss_delete_info_dir(sci_idx, t->info_dirs[0], &ignored_code);
free((char *)t->info_dirs);
free((char *)t);
}

89
lib/libss/list_rqs.c Normal file
View File

@ -0,0 +1,89 @@
/*
* Copyright 1987, 1988 by MIT Student Information Processing Board
*
* For copyright information, see copyright.h.
*/
#include "copyright.h"
#include "ss_internal.h"
#include <signal.h>
#include <setjmp.h>
#include <sys/types.h>
#include <sys/wait.h>
#ifdef lint /* "lint returns a value which is sometimes ignored" */
#define DONT_USE(x) x=x;
#else /* !lint */
#define DONT_USE(x) ;
#endif /* lint */
static char const twentyfive_spaces[26] =
" ";
static char const NL[2] = "\n";
ss_list_requests(argc, argv, sci_idx, info_ptr)
int argc;
char **argv;
int sci_idx;
pointer info_ptr;
{
register ss_request_entry *entry;
register char const * const *name;
register int spacing;
register ss_request_table **table;
char buffer[BUFSIZ];
FILE *output;
int fd;
int mask;
#ifdef POSIX
void (*func)();
#else
int (*func)();
#endif
union wait waitb;
DONT_USE(argc);
DONT_USE(argv);
mask = sigblock(sigmask(SIGINT));
func = signal(SIGINT, SIG_IGN);
fd = ss_pager_create();
output = fdopen(fd, "w");
sigsetmask(mask);
fprintf (output, "Available %s requests:\n\n",
ss_info (sci_idx) -> subsystem_name);
for (table = ss_info(sci_idx)->rqt_tables; *table; table++) {
entry = (*table)->requests;
for (; entry->command_names; entry++) {
spacing = -2;
buffer[0] = '\0';
if (entry->flags & SS_OPT_DONT_LIST)
continue;
for (name = entry->command_names; *name; name++) {
register int len = strlen(*name);
strncat(buffer, *name, len);
spacing += len + 2;
if (name[1]) {
strcat(buffer, ", ");
}
}
if (spacing > 23) {
strcat(buffer, NL);
fputs(buffer, output);
spacing = 0;
buffer[0] = '\0';
}
strncat(buffer, twentyfive_spaces, 25-spacing);
strcat(buffer, entry->info_string);
strcat(buffer, NL);
fputs(buffer, output);
}
}
fclose(output);
#ifndef NO_FORK
wait(&waitb);
#endif
(void) signal(SIGINT, func);
}

151
lib/libss/listen.c Normal file
View File

@ -0,0 +1,151 @@
/*
* Listener loop for subsystem library libss.a.
*
* Header: /afs/rel-eng.athena.mit.edu/project/release/current/source/athena/athena.lib/ss/RCS/listen.c,v 1.2 90/07/12 12:28:58 epeisach Exp
* $Locker: $
*
* Copyright 1987, 1988 by MIT Student Information Processing Board
*
* For copyright information, see copyright.h.
*/
#include "copyright.h"
#include "ss_internal.h"
#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
#include <sys/param.h>
#ifdef BSD
#include <sgtty.h>
#endif
#ifndef lint
static char const rcs_id[] =
"Header: /afs/rel-eng.athena.mit.edu/project/release/current/source/athena/athena.lib/ss/RCS/listen.c,v 1.2 90/07/12 12:28:58 epeisach Exp ";
#endif
#ifdef POSIX
#define sigtype void
#else
#define sigtype int
#endif POSIX
extern char *index();
static ss_data *current_info;
static jmp_buf listen_jmpb;
static sigtype print_prompt()
{
#ifdef BSD
/* put input into a reasonable mode */
struct sgttyb ttyb;
if (ioctl(fileno(stdin), TIOCGETP, &ttyb) != -1) {
if (ttyb.sg_flags & (CBREAK|RAW)) {
ttyb.sg_flags &= ~(CBREAK|RAW);
(void) ioctl(0, TIOCSETP, &ttyb);
}
}
#endif
(void) fputs(current_info->prompt, stdout);
(void) fflush(stdout);
}
static sigtype listen_int_handler()
{
putc('\n', stdout);
longjmp(listen_jmpb, 1);
}
int ss_listen (sci_idx)
int sci_idx;
{
register char *cp;
register sigtype (*sig_cont)();
register ss_data *info;
sigtype (*sig_int)(), (*old_sig_cont)();
char input[BUFSIZ];
char expanded_input[BUFSIZ];
char buffer[BUFSIZ];
char *end = buffer;
int mask;
int code;
jmp_buf old_jmpb;
ss_data *old_info = current_info;
static sigtype print_prompt();
current_info = info = ss_info(sci_idx);
sig_cont = (sigtype (*)())0;
info->abort = 0;
mask = sigblock(sigmask(SIGINT));
bcopy(listen_jmpb, old_jmpb, sizeof(jmp_buf));
sig_int = signal(SIGINT, listen_int_handler);
setjmp(listen_jmpb);
(void) sigsetmask(mask);
while(!info->abort) {
print_prompt();
*end = '\0';
old_sig_cont = sig_cont;
sig_cont = signal(SIGCONT, print_prompt);
#ifdef mips
/* The mips compiler breaks on determining the types,
we help */
if ( (sigtype *) sig_cont == (sigtype *) print_prompt)
#else
if ( sig_cont == print_prompt)
#endif
sig_cont = old_sig_cont;
if (fgets(input, BUFSIZ, stdin) != input) {
code = SS_ET_EOF;
goto egress;
}
cp = index(input, '\n');
if (cp) {
*cp = '\0';
if (cp == input)
continue;
}
(void) signal(SIGCONT, sig_cont);
for (end = input; *end; end++)
;
code = ss_execute_line (sci_idx, input);
if (code == SS_ET_COMMAND_NOT_FOUND) {
register char *c = input;
while (*c == ' ' || *c == '\t')
c++;
cp = index (c, ' ');
if (cp)
*cp = '\0';
cp = index (c, '\t');
if (cp)
*cp = '\0';
ss_error (sci_idx, 0,
"Unknown request \"%s\". Type \"?\" for a request list.",
c);
}
}
code = 0;
egress:
(void) signal(SIGINT, sig_int);
bcopy(old_jmpb, listen_jmpb, sizeof(jmp_buf));
current_info = old_info;
return code;
}
void ss_abort_subsystem(sci_idx, code)
int sci_idx;
{
ss_info(sci_idx)->abort = 1;
ss_info(sci_idx)->exit_status = code;
}
int ss_quit(argc, argv, sci_idx, infop)
int argc;
char **argv;
int sci_idx;
pointer infop;
{
ss_abort_subsystem(sci_idx, 0);
}

90
lib/libss/pager.c Normal file
View File

@ -0,0 +1,90 @@
/*
* Pager: Routines to create a "more" running out of a particular file
* descriptor.
*
* Copyright 1987, 1988 by MIT Student Information Processing Board
*
* For copyright information, see copyright.h.
*/
#include "ss_internal.h"
#include "copyright.h"
#include <stdio.h>
#include <sys/file.h>
#include <signal.h>
static char MORE[] = "more";
extern char *_ss_pager_name;
extern char *getenv();
extern int errno;
/*
* this needs a *lot* of work....
*
* run in same process
* handle SIGINT sensibly
* allow finer control -- put-page-break-here
*/
void ss_page_stdin();
#ifndef NO_FORK
int ss_pager_create()
{
int filedes[2];
if (pipe(filedes) != 0)
return(-1);
switch(fork()) {
case -1:
return(-1);
case 0:
/*
* Child; dup read half to 0, close all but 0, 1, and 2
*/
if (dup2(filedes[0], 0) == -1)
exit(1);
ss_page_stdin();
default:
/*
* Parent: close "read" side of pipe, return
* "write" side.
*/
(void) close(filedes[0]);
return(filedes[1]);
}
}
#else /* don't fork */
int ss_pager_create()
{
int fd;
fd = open("/dev/tty", O_WRONLY, 0);
return fd;
}
#endif
void ss_page_stdin()
{
int i;
for (i = 3; i < 32; i++)
(void) close(i);
(void) signal(SIGINT, SIG_DFL);
{
register int mask = sigblock(0);
mask &= ~sigmask(SIGINT);
sigsetmask(mask);
}
if (_ss_pager_name == (char *)NULL) {
if ((_ss_pager_name = getenv("PAGER")) == (char *)NULL)
_ss_pager_name = MORE;
}
(void) execlp(_ss_pager_name, _ss_pager_name, (char *) NULL);
{
/* minimal recovery if pager program isn't found */
char buf[80];
register int n;
while ((n = read(0, buf, 80)) > 0)
write(1, buf, n);
}
exit(errno);
}

137
lib/libss/parse.c Normal file
View File

@ -0,0 +1,137 @@
/*
* Copyright 1987, 1988 by MIT Student Information Processing Board
*
* For copyright info, see copyright.h.
*/
#include "ss_internal.h"
#include "copyright.h"
#ifndef lint
static char const rcsid[] =
"Header: parse.c,v 1.1 89/01/25 07:53:13 raeburn Exp ";
#endif
enum parse_mode { WHITESPACE, TOKEN, QUOTED_STRING };
/*
* parse(line_ptr, argc_ptr)
*
* Function:
* Parses line, dividing at whitespace, into tokens, returns
* the "argc" and "argv" values.
* Arguments:
* line_ptr (char *)
* Pointer to text string to be parsed.
* argc_ptr (int *)
* Where to put the "argc" (number of tokens) value.
* Returns:
* argv (char **)
* Series of pointers to parsed tokens.
*/
#define NEW_ARGV(old,n) (char **)realloc((char *)old,\
(unsigned)(n+2)*sizeof(char*))
char **ss_parse (sci_idx, line_ptr, argc_ptr)
int sci_idx;
register char *line_ptr;
int *argc_ptr;
{
register char **argv, *cp;
register int argc;
register enum parse_mode parse_mode;
argv = (char **) malloc (sizeof(char *));
if (argv == (char **)NULL) {
ss_error(sci_idx, errno, "Can't allocate storage");
return(argv);
}
*argv = (char *)NULL;
argc = 0;
parse_mode = WHITESPACE; /* flushing whitespace */
cp = line_ptr; /* cp is for output */
while (1) {
#ifdef DEBUG
{
printf ("character `%c', mode %d\n", *line_ptr, parse_mode);
}
#endif
while (parse_mode == WHITESPACE) {
if (*line_ptr == '\0')
goto end_of_line;
if (*line_ptr == ' ' || *line_ptr == '\t') {
line_ptr++;
continue;
}
if (*line_ptr == '"') {
/* go to quoted-string mode */
parse_mode = QUOTED_STRING;
cp = line_ptr++;
argv = NEW_ARGV (argv, argc);
argv[argc++] = cp;
argv[argc] = NULL;
}
else {
/* random-token mode */
parse_mode = TOKEN;
cp = line_ptr;
argv = NEW_ARGV (argv, argc);
argv[argc++] = line_ptr;
argv[argc] = NULL;
}
}
while (parse_mode == TOKEN) {
if (*line_ptr == '\0') {
*cp++ = '\0';
goto end_of_line;
}
else if (*line_ptr == ' ' || *line_ptr == '\t') {
*cp++ = '\0';
line_ptr++;
parse_mode = WHITESPACE;
}
else if (*line_ptr == '"') {
line_ptr++;
parse_mode = QUOTED_STRING;
}
else {
*cp++ = *line_ptr++;
}
}
while (parse_mode == QUOTED_STRING) {
if (*line_ptr == '\0') {
ss_error (sci_idx, 0,
"Unbalanced quotes in command line");
free (argv);
return NULL;
}
else if (*line_ptr == '"') {
if (*++line_ptr == '"') {
*cp++ = '"';
line_ptr++;
}
else {
parse_mode = TOKEN;
}
}
else {
*cp++ = *line_ptr++;
}
}
}
end_of_line:
*argc_ptr = argc;
#ifdef DEBUG
{
int i;
printf ("argc = %d\n", argc);
for (i = 0; i <= argc; i++)
printf ("\targv[%2d] = `%s'\n", i,
argv[i] ? argv[i] : "<NULL>");
}
#endif
return(argv);
}

31
lib/libss/prompt.c Normal file
View File

@ -0,0 +1,31 @@
/*
* prompt.c: Routines for retrieving and setting a prompt.
*
* Header: prompt.c,v 1.2 89/01/18 18:27:02 raeburn Exp
* $Locker: $
*
* Copyright 1987, 1988 by MIT Student Information Processing Board
*
* For copyright information, see copyright.h.
*/
#include "copyright.h"
#include <stdio.h>
#include "ss_internal.h"
static const char rcsid[] =
"Header: prompt.c,v 1.2 89/01/18 18:27:02 raeburn Exp ";
ss_set_prompt(sci_idx, new_prompt)
int sci_idx;
char *new_prompt;
{
ss_info(sci_idx)->prompt = new_prompt;
}
char *
ss_get_prompt(sci_idx)
int sci_idx;
{
return(ss_info(sci_idx)->prompt);
}

63
lib/libss/request_tbl.c Normal file
View File

@ -0,0 +1,63 @@
/*
* Copyright 1987, 1988 by MIT Student Information Processing Board
*
* For copyright information, see copyright.h.
*/
#include "copyright.h"
#include "ss_internal.h"
#define ssrt ss_request_table /* for some readable code... */
ss_add_request_table(sci_idx, rqtbl_ptr, position, code_ptr)
int sci_idx;
ssrt *rqtbl_ptr;
int position; /* 1 -> becomes second... */
int *code_ptr;
{
register ss_data *info;
register int i, size;
info = ss_info(sci_idx);
for (size=0; info->rqt_tables[size] != (ssrt *)NULL; size++)
;
/* size == C subscript of NULL == #elements */
size += 2; /* new element, and NULL */
info->rqt_tables = (ssrt **)realloc((char *)info->rqt_tables,
(unsigned)size*sizeof(ssrt));
if (info->rqt_tables == (ssrt **)NULL) {
*code_ptr = errno;
return;
}
if (position > size - 2)
position = size - 2;
if (size > 1)
for (i = size - 2; i >= position; i--)
info->rqt_tables[i+1] = info->rqt_tables[i];
info->rqt_tables[position] = rqtbl_ptr;
info->rqt_tables[size-1] = (ssrt *)NULL;
*code_ptr = 0;
}
ss_delete_request_table(sci_idx, rqtbl_ptr, code_ptr)
int sci_idx;
ssrt *rqtbl_ptr;
int *code_ptr;
{
register ss_data *info;
register ssrt **rt1, **rt2;
*code_ptr = SS_ET_TABLE_NOT_FOUND;
info = ss_info(sci_idx);
rt1 = info->rqt_tables;
for (rt2 = rt1; *rt1; rt1++) {
if (*rt1 != rqtbl_ptr) {
*rt2++ = *rt1;
*code_ptr = 0;
}
}
*rt2 = (ssrt *)NULL;
return;
}

48
lib/libss/requests.c Normal file
View File

@ -0,0 +1,48 @@
/*
* Various minor routines...
*
* Copyright 1987, 1988, 1989 by MIT
*
* For copyright information, see mit-sipb-copyright.h.
*/
#include "mit-sipb-copyright.h"
#include <stdio.h>
#include "ss_internal.h"
#define DECLARE(name) name(argc,argv,sci_idx)int argc,sci_idx;char **argv;
/*
* ss_self_identify -- assigned by default to the "." request
*/
DECLARE(ss_self_identify)
{
register ss_data *info = ss_info(sci_idx);
printf("%s version %s\n", info->subsystem_name,
info->subsystem_version);
}
/*
* ss_subsystem_name -- print name of subsystem
*/
DECLARE(ss_subsystem_name)
{
printf("%s\n", ss_info(sci_idx)->subsystem_name);
}
/*
* ss_subsystem_version -- print version of subsystem
*/
DECLARE(ss_subsystem_version)
{
printf("%s\n", ss_info(sci_idx)->subsystem_version);
}
/*
* ss_unimplemented -- routine not implemented (should be
* set up as (dont_list,dont_summarize))
*/
DECLARE(ss_unimplemented)
{
ss_perror(sci_idx, SS_ET_UNIMPLEMENTED, "");
}

61
lib/libss/ss.h Normal file
View File

@ -0,0 +1,61 @@
/*
* Copyright 1987, 1988 by MIT Student Information Processing Board
*
* For copyright information, see mit-sipb-copyright.h.
*/
#ifndef _ss_h
#define _ss_h __FILE__
#include <ss/mit-sipb-copyright.h>
#include <ss/ss_err.h>
extern int errno;
#ifdef __STDC__
#define __SS_CONST const
#define __SS_PROTO (int, const char * const *, int, void *)
#else
#define __SS_CONST
#define __SS_PROTO ()
#endif
typedef __SS_CONST struct _ss_request_entry {
__SS_CONST char * __SS_CONST *command_names; /* whatever */
void (* __SS_CONST function) __SS_PROTO; /* foo */
__SS_CONST char * __SS_CONST info_string; /* NULL */
int flags; /* 0 */
} ss_request_entry;
typedef __SS_CONST struct _ss_request_table {
int version;
ss_request_entry *requests;
} ss_request_table;
#define SS_RQT_TBL_V2 2
typedef struct _ss_rp_options { /* DEFAULT VALUES */
int version; /* SS_RP_V1 */
void (*unknown) __SS_PROTO; /* call for unknown command */
int allow_suspend;
int catch_int;
} ss_rp_options;
#define SS_RP_V1 1
#define SS_OPT_DONT_LIST 0x0001
#define SS_OPT_DONT_SUMMARIZE 0x0002
void ss_help __SS_PROTO;
char *ss_current_request();
char *ss_name();
#ifdef __STDC__
void ss_error (int, long, char const *, ...);
void ss_perror (int, long, char const *);
#else
void ss_error ();
void ss_perror ();
#endif
void ss_abort_subsystem();
extern ss_request_table ss_std_requests;
#endif /* _ss_h */

39
lib/libss/ss_err.et Normal file
View File

@ -0,0 +1,39 @@
error_table ss
ec SS_ET_SUBSYSTEM_ABORTED,
"Subsystem aborted"
ec SS_ET_VERSION_MISMATCH,
"Version mismatch"
ec SS_ET_NULL_INV,
"No current invocation"
ec SS_ET_NO_INFO_DIR,
"No info directory"
ec SS_ET_COMMAND_NOT_FOUND,
"Command not found"
ec SS_ET_LINE_ABORTED,
"Command line aborted"
ec SS_ET_EOF,
"End-of-file reached"
ec SS_ET_PERMISSION_DENIED,
"Permission denied"
ec SS_ET_TABLE_NOT_FOUND,
"Request table not found"
ec SS_ET_NO_HELP_FILE,
"No info available"
ec SS_ET_ESCAPE_DISABLED,
"Shell escapes are disabled"
ec SS_ET_UNIMPLEMENTED,
"Sorry, this request is not yet implemented"
end

113
lib/libss/ss_internal.h Normal file
View File

@ -0,0 +1,113 @@
/*
* Copyright 1987, 1988 by MIT Student Information Processing Board
*
* For copyright information, see copyright.h.
*/
#ifndef _ss_ss_internal_h
#define _ss_ss_internal_h __FILE__
#include <stdio.h>
#include <string.h>
#ifdef __STDC__
#define PROTOTYPE(p) p
typedef void * pointer;
#else
#define const
#define volatile
#define PROTOTYPE(p) ()
typedef char * pointer;
#endif /* not __STDC__ */
#include "ss.h"
#if defined(__GNUC__)
#define LOCAL_ALLOC(x) __builtin_alloca(x)
#define LOCAL_FREE(x)
#else
#if defined(vax)
#define LOCAL_ALLOC(x) alloca(x)
#define LOCAL_FREE(x)
extern pointer alloca PROTOTYPE((unsigned));
#else
#if defined(__HIGHC__) /* Barf! */
pragma on(alloca);
#define LOCAL_ALLOC(x) alloca(x)
#define LOCAL_FREE(x)
extern pointer alloca PROTOTYPE((unsigned));
#else
/* no alloca? */
#define LOCAL_ALLOC(x) malloc(x)
#define LOCAL_FREE(x) free(x)
#endif
#endif
#endif /* LOCAL_ALLOC stuff */
typedef char BOOL;
typedef struct _ss_abbrev_entry {
char *name; /* abbrev name */
char **abbrev; /* new tokens to insert */
char beginning_of_line : 1;
} ss_abbrev_entry;
typedef struct _ss_abbrev_list {
int n_abbrevs;
ss_abbrev_entry *first_abbrev;
} ss_abbrev_list;
typedef struct {
/* char *path; */
ss_abbrev_list abbrevs[127];
} ss_abbrev_info;
typedef struct _ss_data { /* init values */
/* this subsystem */
char *subsystem_name;
char *subsystem_version;
/* current request info */
int argc;
char **argv; /* arg list */
char const *current_request; /* primary name */
/* info directory for 'help' */
char **info_dirs;
/* to be extracted by subroutines */
pointer info_ptr; /* (void *) NULL */
/* for ss_listen processing */
char *prompt;
ss_request_table **rqt_tables;
ss_abbrev_info *abbrev_info;
struct {
unsigned char escape_disabled : 1,
abbrevs_disabled : 1;
} flags;
/* to get out */
int abort; /* exit subsystem */
int exit_status;
} ss_data;
#define CURRENT_SS_VERSION 1
#define ss_info(sci_idx) (_ss_table[sci_idx])
#define ss_current_request(sci_idx,code_ptr) \
(*code_ptr=0,ss_info(sci_idx)->current_request)
void ss_unknown_function();
void ss_delete_info_dir();
int ss_execute_line();
char **ss_parse();
ss_abbrev_info *ss_abbrev_initialize PROTOTYPE((char *, int *));
void ss_page_stdin();
extern ss_data **_ss_table;
extern char *ss_et_msgs[];
extern pointer malloc PROTOTYPE((unsigned));
extern pointer realloc PROTOTYPE((pointer, unsigned));
extern pointer calloc PROTOTYPE((unsigned, unsigned));
extern int exit PROTOTYPE((int));
#endif /* _ss_internal_h */

46
lib/libss/std_rqs.ct Normal file
View File

@ -0,0 +1,46 @@
command_table ss_std_requests;
request ss_self_identify, "Identify the subsystem.",
".",
(dont_list, dont_summarize);
request ss_help, "Display info on command or topic.",
help;
unimplemented
ss_list_help,
"List topics for which help is available.",
list_help, lh;
request ss_list_requests, "List available commands.",
list_requests, lr, "?";
request ss_quit, "Leave the subsystem.",
quit, q;
unimplemented
ss_abbrev,
"Enable/disable abbreviation processing of request lines.",
abbrev, ab;
unimplemented
ss_execute,
"Execute a UNIX command line.",
execute, e;
unimplemented
ss_summarize_requests,
"Produce a list of the most commonly used requests.",
"?";
request ss_subsystem_name,
"Return the name of this subsystem.",
subsystem_name,
(dont_list);
request ss_subsystem_version,
"Return the version of this subsystem.",
subsystem_version,
(dont_list);
end;