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