/*
Copyright (C) 1991, Marcus J. Ranum. All rights reserved.
*/
/* configure all options BEFORE including system stuff. */
#include "config.h"
#include "mud.h"
#include "sym.h"
SysSym *systable[SYSSYMWIDTH];
static int sym_initted = 0;
static unsigned symhash(register char *nam, int hw);
static SysSym *symget(char *nam);
static void printsym(char *who, SysSym *sp);
void syminit (void)
{
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);
}
int symdef (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);
}
int symundef (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);
}
int sympriv (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);
}