BSD 4_3_Net_2 release
[unix-history] / usr / src / contrib / isode / quipu / dish / dishlib.c
/* dish.c - */
#ifndef lint
static char *rcsid = "$Header: /f/osi/quipu/dish/RCS/dishlib.c,v 7.5 91/03/09 11:56:17 mrose Exp $";
#endif
/*
* $Header: /f/osi/quipu/dish/RCS/dishlib.c,v 7.5 91/03/09 11:56:17 mrose Exp $
*
*
* $Log: dishlib.c,v $
* Revision 7.5 91/03/09 11:56:17 mrose
* update
*
* Revision 7.4 91/02/22 09:40:29 mrose
* Interim 6.8
*
* Revision 7.3 90/07/09 14:47:06 mrose
* sync
*
* Revision 7.2 90/04/18 08:49:37 mrose
* 6.2
*
* Revision 7.1 90/03/15 11:18:23 mrose
* quipu-sync
*
* Revision 7.1 89/12/19 16:21:01 mrose
* sync
*
* Revision 7.0 89/11/23 22:20:01 mrose
* Release 6.0
*
*/
/*
* NOTICE
*
* Acquisition, use, and distribution of this module and related
* materials are subject to the restrictions of a license agreement.
* Consult the Preface in the User's Manual for the full terms of
* this agreement.
*
*/
#include <stdio.h>
#include <signal.h>
#include "quipu/util.h"
#include "quipu/name.h"
#include <varargs.h>
#ifdef SOCKETS
#include "internet.h"
extern int sd_current;
#endif
#define MAXARGS 50
extern LLog *log_dsap;
DN dn = NULLDN; /* This actually stores the current position. */
#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps)
#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt)
char frompipe;
PS opt, rps;
DN savename;
SFD dish_quit ();
SFD dish_intr ();
char dad_flag = FALSE;
unsigned cache_time = 3600; /* time to keep process alive */
unsigned connect_time = 120; /* time to keep connection open */
char inbuf[LINESIZE];
char bound = FALSE;
char remote_prob;
char doneget;
char *TidyString();
char search_result; /* another horrid global ! */
extern int call_list (), call_compare (), call_search (),
call_add (), call_delete (), call_showentry (), call_showname (),
call_showattribute (), call_unbind (), call_help (), call_ds (),
unknown_cmd (), dsa_control (), call_modify (), call_modifyrdn (),
call_quit (), call_bind (), call_moveto (), call_fred ();
static struct {
char *command;
int (*handler) ();
int unique;
char defaults [LINESIZE];
} Commands[MAXARGS];
static int num_cmd = 0;
add_dish_command (name,func,len)
char * name;
IFP func;
int len;
{
Commands[num_cmd].command = name;
Commands[num_cmd].handler = func;
Commands[num_cmd].unique = (len == 0 ? strlen(name) : len);
bzero (Commands[num_cmd].defaults,LINESIZE);
num_cmd++;
}
dish_cmd_init ()
{
add_dish_command ("list", call_list, 1);
add_dish_command ("compare", call_compare, 1);
add_dish_command ("search", call_search, 2);
add_dish_command ("add", call_add, 1);
add_dish_command ("delete", call_delete, 2);
add_dish_command ("modify", call_modify, 3);
add_dish_command ("modifyrdn", call_modifyrdn, 7);
add_dish_command ("showentry", call_showentry, 2);
add_dish_command ("showname", call_showname, 5);
add_dish_command ("bind", call_bind, 1);
add_dish_command ("unbind", call_unbind, 1);
add_dish_command ("moveto", call_moveto, 3);
add_dish_command ("dsacontrol", dsa_control, 2);
add_dish_command ("quit", call_quit, 1); /* quick way out for interactive program */
add_dish_command ("squid", call_ds, 2);
add_dish_command ("?", call_help, 1);
add_dish_command ("help", call_help, 1);
add_dish_command ("fred", call_fred, 4);
dish_help_init ();
};
jmp_buf dish_env;
#ifndef IDLE
#define IDLE 0
#endif
#ifndef BUSY
#define BUSY 1
#endif
static char dish_state;
#ifndef NO_STATS
extern LLog *log_stat;
#endif
extern LLog *log_dsap;
#ifndef NO_STATS
static LLog _dad_log = {
"dad.log", NULLCP, NULLCP, LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE,
LLOG_NONE, -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK
};
LLog *dad_log = &_dad_log;
#endif
char no_rcfile;
dish_init (argc, argv)
int argc;
char **argv;
{
int i;
char *ttyname (), *getenv();
char *vec [1];
char **vecptr;
extern char * tailfile;
dish_cmd_init ();
(void) signal (SIGHUP, dish_quit);
(void) signal (SIGQUIT, dish_quit);
(void) signal (SIGILL, dish_quit);
(void) signal (SIGBUS, dish_quit);
(void) signal (SIGSEGV, dish_quit);
(void) signal (SIGSYS, dish_quit);
(void) signal (SIGTERM, dish_quit);
no_rcfile = FALSE;
for (i=1; i<argc; i++) {
if (test_arg (argv[i],"-dad",1)) {
cache_time = 15 * 60;
connect_time = 5 * 60;
dad_flag = TRUE;
#ifndef NO_STATS
ll_hdinit (dad_log, argv[0]);
#endif
shuffle_up (argc--, argv, i);
continue;
}
if (test_arg (argv[i],"-fast",1)) {
no_rcfile = TRUE;
shuffle_up (argc--, argv, i);
continue;
}
if (test_arg (argv[i],"-help",1)) {
if ((opt = ps_alloc (std_open)) == NULLPS)
fatal (-62, "ps_alloc failed");
if (std_setup (opt, stderr) == NOTOK)
fatal (-63, "std_setup failed");
if ((rps = ps_alloc (std_open)) == NULLPS)
fatal (-64, "ps_alloc 2 failed");
if (std_setup (rps, stdout) == NOTOK)
fatal (-65, "std_setup 2 failed");
help_arg ("dish");
exit (0);
}
if (test_arg(argv[i],"-tailor",1)) {
shuffle_up (argc--, argv, i);
if (i == argc)
fatal (-66,"Tailor file name missing");
tailfile = argv[i];
shuffle_up (argc--, argv, i);
}
}
if ( (argc >1) && (test_arg (argv[1], "-pipe",3))) {
if (init_pipe () != OK)
exit (-61);
frompipe = TRUE;
opt = rps = NULLPS;
} else {
frompipe = FALSE;
if ((opt = ps_alloc (std_open)) == NULLPS)
fatal (-62, "ps_alloc failed");
if (std_setup (opt, stderr) == NOTOK)
fatal (-63, "std_setup failed");
if ((rps = ps_alloc (std_open)) == NULLPS)
fatal (-64, "ps_alloc 2 failed");
if (std_setup (rps, stdout) == NOTOK)
fatal (-65, "std_setup 2 failed");
(void) printf ("Welcome to Dish (DIrectory SHell)\n");
(void) fflush (stdout);
}
i = 1;
vec[0] = argv[0];
vecptr = vec;
want_oc_hierarchy (); /* for add/modify ! */
#ifndef NO_STATS
log_stat -> ll_file = "dish.log";
log_stat -> ll_stat &= ~LLOGCRT;
#endif
log_dsap -> ll_stat &= ~LLOGCRT;
dsap_init (&i, &vecptr);
#ifndef NO_STATS
ll_hdinit (log_stat,vec[0]);
#endif
check_known_oids();
if (user_tailor () != OK) {
(void) fprintf (stderr, "Tailoring failed\n");
if (frompipe)
exit_pipe ();
exit (-66);
}
if (! frompipe) {
#ifndef NO_STATS
char buf [LINESIZE];
*buf = 0;
for (i=0; i<argc; i++) {
(void) strcat (buf,argv[i]);
(void) strcat (buf," ");
if (test_arg (argv[i], "-password",2) && ++i < argc)
(void) strcat (buf, "????");
}
LLOG (log_stat,LLOG_NOTICE,("%s",buf));
#endif
if (setjmp (dish_env))
exit (-66);
if (call_bind (argc,argv) != OK)
exit (-67);
}
}
unknown_cmd ()
{
if (frompipe)
ps_print (opt,"Serious dish error\n");
else {
if (print_arg_error (opt) != OK)
ps_print (opt,"Unknown command --- type '?' for help\n");
}
}
#ifdef GNUREADLINE
void gnu_gets_setup ()
{
extern int rl_bind_key ();
extern int *rl_insert ();
rl_bind_key ( '\t', rl_insert );
}
static char *gnu_gets ( buf, len )
char *buf;
int len;
{
extern char *readline ();
static char *gets_line;
gets_line = readline ( "Dish -> " );
if ( gets_line && *gets_line )
add_history ( gets_line );
if ( gets_line )
{
strncpy ( buf, gets_line, strlen(gets_line) + 1 );
free ( gets_line );
return buf;
}
else
return (char *) NULL;
}
#endif
do_dish ()
{
char *brkset;
char *command;
char cmd_buf [LINESIZE];
char *ptr;
char *vector[MAXARGS];
int no_of_args;
int x;
char noarg;
extern int parse_line;
extern int dsa_dead;
extern int errno;
Commands[num_cmd].command = NULLCP;
Commands[num_cmd].handler = unknown_cmd;
Commands[num_cmd].unique = 0;
#ifdef GNUREADLINE
gnu_gets_setup ();
#endif
(void) signal (SIGINT, dish_intr);
if (setjmp (dish_env) == 1)
goto tidy_up;
while (1) {
dish_state = IDLE;
if (dsa_dead) {
(void) ds_unbind ();
bound = FALSE;
dsa_dead = FALSE;
}
parse_line = 0;
reset_arg ();
set_current_pos();
remote_prob = FALSE;
doneget = FALSE;
if (frompipe) {
set_alarm ();
if (read_pipe (inbuf,sizeof inbuf) == -1)
continue;
(void) signal (SIGALRM, SIG_IGN);
/* unset alarm */
if (dad_flag)
cache_time = 15 * 60;
#ifdef SOCKETS
command = inbuf;
#else
command = index (inbuf, ':');
*command++ = 0;
#endif
#ifdef SOCKETS
if ((opt = ps_alloc (fdx_open)) == NULLPS) {
exit_pipe ();
fatal (-68, "ps_alloc failed");
}
if (fdx_setup (opt, sd_current) == NOTOK) {
exit_pipe ();
fatal (-69, "fdx_setup failed");
}
(void) (*opt -> ps_writeP) (opt, "2", 1, 0);
if ((rps = ps_alloc (fdx_open)) == NULLPS) {
exit_pipe ();
fatal (-70, "ps_alloc 2 failed");
}
if (fdx_setup (rps, sd_current) == NOTOK) {
exit_pipe ();
fatal (-71, "fdx_setup 2 failed");
}
(void) (*rps -> ps_writeP) (rps, "1", 1, 0);
#else
if ((opt = ps_alloc (str_open)) == NULLPS) {
exit_pipe ();
fatal (-68, "ps_alloc failed");
}
if (str_setup (opt, NULLCP, BUFSIZ, 0) == NOTOK) {
exit_pipe ();
fatal (-69, "str_setup failed");
}
opt->ps_ptr++, opt->ps_cnt--;
if ((rps = ps_alloc (str_open)) == NULLPS) {
exit_pipe ();
fatal (-70, "ps_alloc 2 failed");
}
if (str_setup (rps, NULLCP , BUFSIZ, 0) == NOTOK) {
exit_pipe ();
fatal (-71, "str_setup 2 failed");
}
rps->ps_ptr++, rps->ps_cnt--;
#endif
if (!no_rcfile)
test_rc_file (opt);
} else {
do {
set_alarm ();
#ifdef GNUREADLINE
if (gnu_gets ( inbuf, sizeof inbuf ) == 0)
#else
(void) printf ("Dish -> ");
(void) fflush (stdout);
if (fgets (inbuf, sizeof inbuf, stdin) == 0)
#endif
call_quit();
for (ptr = inbuf; isspace (*ptr); ptr++)
continue;
} while (*ptr == 0);
(void) signal (SIGALRM, SIG_IGN); /* unset alarm */
command = TidyString(inbuf);
}
savename = dn_cpy (dn);
hide_picture();
dish_state = BUSY;
ptr = command;
while (*ptr)
if (isspace (*ptr))
break;
else
ptr++;
if (*ptr == 0) {
noarg = TRUE;
} else {
*ptr = 0;
noarg = FALSE;
}
for (x = 0; Commands[x].command != 0; x++)
if (test_arg (command, Commands[x].command, Commands[x].unique))
break;
if (! noarg)
*ptr++ = ' ';
if (* Commands[x].defaults != 0) {
if (noarg) {
(void) sprintf (cmd_buf,"%s %s",Commands[x].command,Commands[x].defaults);
} else {
(void) sprintf (cmd_buf,"%s %s %s",Commands[x].command,Commands[x].defaults,ptr);
}
command = cmd_buf;
}
if (strncmp (command, "fred -ufn ",
sizeof "fred -ufn " - 1) == 0) {
command[4] = command[9] = ',';
brkset = ",";
}
else
brkset = " \t";
if ((no_of_args = sstr2arg (command, MAXARGS, vector, brkset)) == NOTOK)
ps_printf (OPT, "Too many arguments... Can't cope.\n");
else {
char help_flag = FALSE;
int y;
#ifndef NO_STATS
char buf [LINESIZE];
buf[0] = NULL;
#endif
vector[0] = Commands[x].command;
#ifndef NO_STATS
if (vector[0] != NULLCP) {
(void) strcpy (buf,vector[0]);
(void) strcat (buf," ");
}
#endif
for (y=1; y<no_of_args; y++) {
#ifndef NO_STATS
(void) strcat (buf,vector[y]);
(void) strcat (buf," ");
if (test_arg (vector[y], "-password",2) && y+1 < no_of_args) {
(void) strcat (buf, "????");
y++;
continue;
}
#endif
if (test_arg (vector[y],"-help",1)) {
if (vector[0] != NULLCP)
help_arg (vector[0]);
else
unknown_cmd();
help_flag = TRUE;
}
}
#ifndef NO_STATS
LLOG (log_stat,LLOG_NOTICE,("%s",buf));
if (dad_flag
&& buf[0]
&& strncmp (buf, "moveto ",
sizeof "moveto " -1))
(void) ll_log (dad_log, LLOG_NOTICE, NULLCP,
"%s", buf);
#endif
if ( ! help_flag)
(*Commands[x].handler) (no_of_args, vector);
}
/* if from pipe, return results */
tidy_up:;
if (frompipe && !remote_prob) {
#ifdef SOCKETS
if (rps -> ps_byteno > 0) {
(void) ps_flush (rps);
} else
if (opt -> ps_byteno > 0)
(void) ps_flush (opt);
#else
if (opt->ps_byteno == 0) {
*rps->ps_ptr = 0;
send_pipe (rps->ps_base);
} else {
*opt->ps_ptr = 0;
if (search_result == OK)
*opt->ps_base = '2';
else
*opt->ps_base = '3'; /* Signal search ok but >1 hit, with -hitone option */
send_pipe (opt->ps_base);
}
#endif
ps_free (opt);
ps_free (rps);
#ifdef SOCKETS
(void) close_tcp_socket (sd_current);
sd_current = NOTOK;
#endif
} else {
(void) fflush (stdout);
(void) ps_flush (opt);
(void) ps_flush (rps);
}
}
}
call_quit ()
{
/* can only get called if run interactively - dont worry about pipe */
(void) signal (SIGINT, SIG_DFL);
DLOG (log_dsap, LLOG_DEBUG, ("Dish:- Exiting Dish successfully..."));
if (bound)
(void) ds_unbind ();
bound = FALSE;
ps_free (opt);
ps_free (rps);
hide_picture();
exit (0);
}
set_cmd_default (cmd, dflt)
char * cmd;
char * dflt;
{
int x;
for (x = 0; Commands[x].command != 0; x++)
if (strcmp (cmd, Commands[x].command) == 0) {
if (* Commands[x].defaults != 0)
(void) strcat (Commands[x].defaults, " ");
(void) strcat (Commands[x].defaults, dflt);
return (OK);
}
return (NOTOK);
}
SFD dish_intr ()
{
#ifndef BSDSIGS
(void) signal (SIGINT, dish_intr);
#endif
if (dish_state == IDLE)
ps_printf (OPT, "\n");
else {
ps_printf (OPT, "(Interrupted)\n");
dish_state = IDLE;
}
longjmp (dish_env,2);
}
void advise (va_alist)
va_dcl
{
int code;
va_list ap;
extern LLog *log_dsap;
va_start (ap);
code = va_arg (ap, int);
(void) _ll_log (log_dsap, code, ap);
va_end (ap);
}