untermud/DOC/
untermud/DOC/U/
untermud/DOC/U/U-examples/
untermud/DOC/internals/
untermud/DOC/wizard/
untermud/MISC/
untermud/MISC/dbchk/
untermud/RWHO/
untermud/RWHO/rwhod/
/*
    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);
}