pennmush/game/
pennmush/game/data/
pennmush/game/log/
pennmush/game/save/
pennmush/game/txt/evt/
pennmush/game/txt/nws/
pennmush/os2/
/* privtab.c */
/* Functions to work with privilege tables */

#include "copyrite.h"
#include "config.h"
#include <ctype.h>
#ifdef I_STDLIB
#include <stdlib.h>
#endif
#ifdef I_STRING
#include <string.h>
#else
#include <strings.h>
#endif
#include "privtab.h"
#include "externs.h"
#include "confmagic.h"


/* Given a privs table, a string, and an original set of privileges,
 * return a modified set of privileges by applying the privs in the
 * string to the original set of privileges
 */
int
string_to_privs(table, str, origprivs)
    PRIV *table;
    const char *str;
    long int origprivs;
{
  PRIV *c;
  long int yes = 0;
  long int no = 0;
  char *p, *r;
  char tbuf1[BUFFER_LEN];
  int not;
  int words = 0;

  if (!str || !*str)
    return origprivs;
  strcpy(tbuf1, str);
  r = trim_space_sep(tbuf1, ' ');
  while ((p = split_token(&r, ' '))) {
    words++;
    not = 0;
    if (*p == '!') {
      not = 1;
      if (!*++p)
	continue;
    }
    for (c = table; c->name; c++) {
      if (string_prefix(c->name, p)) {
	if (not)
	  no |= c->bits_to_set;
	else
	  yes |= c->bits_to_set;
	break;
      }
    }
  }
  /* If we made no changes, and were given one word, 
   * we probably were given letters instead */
  if (!no && !yes && (words == 1))
    return letter_to_privs(table, str, origprivs);
  return ((origprivs | yes) & ~no);
}

/* Given a privs table, a string of letters, and an original set of privileges,
 * return a modified set of privileges by applying the privs in the
 * letters to the original set of privileges
 */
int
letter_to_privs(table, str, origprivs)
    PRIV *table;
    const char *str;
    long int origprivs;
{
  PRIV *c;
  long int yes = 0, no = 0;
  const char *p;
  int not;

  if (!str || !*str)
    return origprivs;
  p = str;
  for (c = table; c->name && *p; c++) {
    not = 0;
    if (*p == '!') {
      not = 1;
      if (!*++p)
	break;
    }
    if (c->letter == *p) {
      if (not)
	no = c->bits_to_set;
      else
	yes = c->bits_to_set;
    }
    p++;
  }
  return ((origprivs | yes) & ~no);
}

/* Given a table and a bitmask, return a privs string (static allocation) */
const char *
privs_to_string(table, privs)
    PRIV *table;
    int privs;
{
  PRIV *c;
  static char buf[BUFFER_LEN];
  char *bp;

  bp = buf;
  for (c = table; c->name; c++) {
    if (privs & c->bits_to_show) {
      if (bp != buf)
	safe_chr(' ', buf, &bp);
      safe_str(c->name, buf, &bp);
      privs &= ~c->bits_to_set;
    }
  }
  *bp = '\0';
  return buf;
}


/* Given a table and a bitmask, return a privs letter string 
 * (static allocation) */
const char *
privs_to_letters(table, privs)
    PRIV *table;
    int privs;
{
  PRIV *c;
  static char buf[BUFFER_LEN];
  char *bp;

  bp = buf;
  for (c = table; c->name; c++) {
    if (privs & c->bits_to_show) {
      safe_chr(c->letter, buf, &bp);
      privs &= ~c->bits_to_set;
    }
  }
  *bp = '\0';
  return buf;
}