pennmush/game/data/
pennmush/game/log/
pennmush/game/save/
pennmush/game/txt/evt/
pennmush/game/txt/nws/
pennmush/os2/
pennmush/po/
pennmush/win32/msvc.net/
pennmush/win32/msvc6/
/**
 * \file privtab.c
 *
 * \brief Privilege tables for PennMUSH.
 *
 * A privilege table is a respresentation of different privilege
 * flags with associated names, characters, and bitmasks.
 *
 */

#include "copyrite.h"
#include "config.h"
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "conf.h"
#include "privtab.h"
#include "externs.h"
#include "confmagic.h"


/** Convert a string to a set of privilege bits, masked by an original set.
 * 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.
 * \param table pointer to a privtab.
 * \param str a space-separated string of privilege names to apply.
 * \param origprivs the original privileges.
 * \return a privilege bitmask.
 */
int
string_to_privs(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);
}

/** Convert a letter string to a set of privilege bits, masked by an original set.
 * Given a privs table, a letter 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.
 * \param table pointer to a privtab.
 * \param str a string of privilege letters to apply.
 * \param origprivs the original privileges.
 * \return a privilege bitmask.
 */
int
letter_to_privs(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;

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

/** Given a table and a bitmask, return a privs string (static allocation).
 * \param table pointer to a privtab.
 * \param privs bitmask of privileges.
 * \return statically allocated space-separated string of priv names.
 */
const char *
privs_to_string(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).
 * \param table pointer to a privtab.
 * \param privs bitmask of privileges.
 * \return statically allocated string of priv letters.
 */
const char *
privs_to_letters(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) && c->letter) {
      safe_chr(c->letter, buf, &bp);
      privs &= ~c->bits_to_set;
    }
  }
  *bp = '\0';
  return buf;
}