/
umud/DOC/
umud/DOC/U/
umud/DOC/U/U-examples/
umud/DOC/internals/
umud/DOC/wizard/
umud/MISC/
umud/MISC/dbchk/
umud/RWHO/rwhod/
/*
	Copyright (C) 1991, Marcus J. Ranum. All rights reserved.
*/

#ifndef	lint
static	char	RCSid[] = "$Header: /home/mjr/hacks/umud/RCS/sym.c,v 1.2 92/02/29 14:49:41 mjr Exp $";
#endif

/* configure all options BEFORE including system stuff. */
#include	"config.h"
#include	"mud.h"
#include	"sym.h"


SysSym	*systable[SYSSYMWIDTH];
static	int	sym_initted = 0;


void
syminit()
{
	int	x;

	if(sym_initted)
		return;
	for(x = 0; x < SYSSYMWIDTH; x++)
		systable[x] = (SysSym *)0;
	sym_initted = 1;
}




static	unsigned
symhash(nam,hw)
register char	*nam;
int		hw;
{
	register unsigned int	n = 0;
 
	while(*nam != '\0')
		n = *nam++ + 65599 * n;
	return(n % hw);
}




static	SysSym	*
symget(nam)
char	*nam;
{
	SysSym	*sp;
	sp = systable[symhash(nam,SYSSYMWIDTH)];
	while(sp != (SysSym *)0) {
		if(sp->nam != (char *)0 && !strcmp(nam,sp->nam))
			return(sp);
		sp = sp->next;
	}
	return((SysSym *)0);
}




char	*
symlook(nam,t)
char	*nam;
int	*t;
{
	SysSym	*sp;

	if(!sym_initted)
		return((char *)0);
	if((sp = symget(nam)) == (SysSym *)0)
		return((char *)0);
	*t = sp->typ;
	return(sp->def);
}



static	void
printsym(who,sp)
char	*who;
SysSym	*sp;
{
	if(sp != (SysSym *)0 && sp->nam != (char *)0 && sp->def != (char *)0) {
		say(who,sp->nam," ",(char *)0);
		if(sp->typ & SFLG_SUID)
			say(who,"*setuid* ",(char *)0);
		if(sp->typ & SFLG_UCMD)
			say(who,"U-code ",(char *)0);
		if(sp->owner != (char *)0)
			say(who,"(",sp->owner,") ",(char *)0);
		say(who,sp->def,"\n",(char *)0);
	}
}




/* spew symbols at 'who' */
void
symlist(who,nam)
char	*who;
char	*nam;
{
	SysSym	*sp;
	int	x;

	if(!sym_initted)
		return;

	if(nam != (char *)0) {
		if((sp = symget(nam)) == (SysSym *)0)
			say(who,"no such symbol: ",nam,"\n",(char *)0);
		else
			printsym(who,sp);
		return;
	}

	/* default - list all */
	for(x = 0; x < SYSSYMWIDTH; x++)
		for(sp = systable[x]; sp != (SysSym *)0; sp = sp->next)
			printsym(who,sp);
}





symdef(nam,def,typ)
char	*nam;
char	*def;
int	typ;
{
	SysSym	*sp;

	if(!sym_initted)
		return(1);

	if((sp = symget(nam)) != (SysSym *)0) {
		char	*op;

		op = (char *)malloc((unsigned)strlen(def) + 1);
		if(op == (char *)0)
			return(1);
		(void)free((mall_t)sp->def);
		sp->def = op;
		(void)strcpy(op,def);
		return(0);
	}

	if((sp = (SysSym *)malloc(sizeof(SysSym))) == (SysSym *)0)
		return(1);
	sp->nam = (char *)malloc((unsigned)strlen(nam) + 1);
	if(sp->nam == (char *)0)
		return(1);
	sp->def = (char *)malloc((unsigned)strlen(def) + 1);
	if(sp->def == (char *)0)
		return(1);
	(void)strcpy(sp->nam,nam);
	(void)strcpy(sp->def,def);
	sp->typ = typ;
	sp->owner = (char *)0;

	/* link in */
	sp->next = systable[symhash(nam,SYSSYMWIDTH)];
	systable[symhash(nam,SYSSYMWIDTH)] = sp;
	return(0);
}




symundef(nam)
char	*nam;
{
	SysSym	*sp;
	SysSym	*psp;
	int	hval;

	if(!sym_initted)
		return(1);

	psp = sp = systable[(hval = symhash(nam,SYSSYMWIDTH))];
	while(sp != (SysSym *)0) {
		if(sp->nam != (char *)0 && !strcmp(nam,sp->nam)) {
			if(sp == systable[hval])
				systable[hval] = sp->next;
			else
				psp->next = sp->next;
			break;
		}
		psp = sp;
		sp = sp->next;
	}

	if(sp != (SysSym *)0) {
		free((mall_t)sp->nam);
		free((mall_t)sp->def);
		if(sp->owner != (char *)0)
			free((mall_t)sp->owner);
		free((mall_t)sp);
		return(0);
	}
	return(1);
}



sympriv(nam,owner)
char	*nam;
char	*owner;
{
	SysSym	*sp;

	if(!sym_initted)
		return(1);

	if((sp = symget(nam)) != (SysSym *)0) {
		sp->typ |= SFLG_SUID;
		sp->owner = (char *)malloc((unsigned)strlen(owner) + 1);
		if(sp->owner == (char *)0)
			return(1);
		(void)strcpy(sp->owner,owner);
		return(0);
	}
	return(1);
}




char	*
symowner(nam)
char	*nam;
{
	SysSym	*sp;

	if(!sym_initted)
		return((char *)0);
	if((sp = symget(nam)) == (SysSym *)0)
		return((char *)0);
	return(sp->owner);
}