Net2/usr/src/contrib/isode/quipu/dish/dishlib.c

Compare this file to the similar file:
Show the results in this format:

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