dbm/
misc/
old-docs/
/* misc.c */

#include "copyright.h"
#include "config.h"

#include <stdio.h>
#include <sys/types.h>
#include <ctype.h>
#include <sys/time.h>
#ifdef STRING_H
#include <string.h>
#else
#include <strings.h>
#endif				/* STRING_H */

#include "teeny.h"
#include "io.h"
#include "case.h"
#include "rwho.h"

/* The WHO list. Surprise. */
Iob            *wholist = (Iob *) 0;

/* Time last time timers() was called. */

static struct timeval last;

/* Last time we did a dump */
static long     lastdump;

/* The time that the mud went up. */
static long     startingtimeofmud;

#define DOING_MAX	40	/* max length of a doing string */

static char    *poll_str;	/* the poll */

#ifdef PDX
static long     lastmaxdaemon;
extern int      max_logins;
#endif
#ifdef SUPPORT_RWHO
static long     lastrwho;
#endif

static void     set_output_str();
static void     log_create();
static void     log_badconnect();

extern void     check_last();
extern void     check_news();

void            do_where();

void            init_timers()
{
  (void) gettimeofday(&last, (struct timezone *) 0);
  lastdump = last.tv_sec;
  startingtimeofmud = last.tv_sec;
#ifdef PDX
  max_daemon();
  lastmaxdaemon = last.tv_sec;
#endif
#ifdef SUPPORT_RWHO
  if (rwho_enabled)
    rwhocli_setup(rwho_server, rwho_pword, RWHO_NAME, RWHO_COMMENT);
  lastrwho = last.tv_sec;
#endif
}

/*
 * This checks the current time and resets quotas if the current timeslice
 * has elapsed, and does a dump if the current dump interval has elapsed.
 * 
 */

void            timers()
{
  struct timeval  now;
  int             delta;
  Iob            *curr;

  (void) gettimeofday(&now, (struct timezone *) 0);

  /* How many tenths of seconds have elapsed since last time */

  delta = (now.tv_sec - last.tv_sec) * 10
    + (now.tv_usec - last.tv_usec) / 100000;

  if (delta >= TIME_SLICE) {
    /* timeout idle connects */
    timeout_daemon();

    /* Update all the quotas */

    curr = wholist;
    if (curr != (Iob *) 0) {
      do {
	curr->quota = SLICE_QUOTA;
	curr = curr->whofwd;
      } while (curr != wholist);
    }
    last.tv_sec = now.tv_sec;
    last.tv_usec = now.tv_usec;
  }
  if (now.tv_sec - lastdump > DUMP_INTERVAL) {
    lastdump = now.tv_sec;

    /* Dump the DB */

    dump_db();
  }
#ifdef PDX
  if (now.tv_sec - lastmaxdaemon > 1750) {
    lastmaxdaemon = now.tv_sec;
    max_daemon();
  }
#endif
#ifdef SUPPORT_RWHO
  if (now.tv_sec - lastrwho > RWHO_INTERVAL) {
    lastrwho = now.tv_sec;
    if (rwho_enabled)
      rwho_daemon();
  }
#endif
}


/*
 * The network code calls this with Iob's with pending goo to process.
 * Process it.
 * 
 */

void            dispatch(bp)
  Iob            *bp;

{
  char           *buff, *cmd, *p;
  int             count;
  int             player;
  int             fullbuff;
  int             z;

  bp->lastcmd = last.tv_sec;

  if (bp->quota < 0) {
    bp->inputcnt = 0;
    if (bp->typ != INPUT_PLAY) {
      iobflush(bp);
      iobdrop(bp);
      log_disconnect(bp);
    }
    return;
  }
  buff = bp->inputbuf;
  count = bp->inputcnt;

  /* Slide along, chopping it up into commands. */

  fullbuff = (count == (MUDBUFSIZ - 1));	/* One for terminating \0 */
  while (1) {
    cmd = buff;
    while (*buff != '\n' && count > 0 && *buff != '\r') {
      buff++;
      count--;
    }
    if (count <= 0 && !fullbuff)
      break;

    if ((bp->typ == INPUT_PLAY && !isrobot(bp->player)) ||
	bp->typ != INPUT_PLAY)
      (bp->quota)--;
    if (bp->quota < 0) {	/* Fuck this guy */
      (bp->blown)++;
      buff = cmd;		/* Fake an empty buffer */
      break;
    }
    fullbuff = 0;
    *buff++ = '\0';
    count--;

    /* change all non-printing characters to whitespace */

    for (z = 0; cmd[z]; z++) {
      if (!isprint(cmd[z]))
	cmd[z] = ' ';
    }

    /* strip leading and trailing whitespace */

    for (z--; isspace(cmd[z]); z--);
    cmd[z + 1] = '\0';
    for (; isspace(cmd[0]); cmd++);

    if (!cmd[0])
      continue;

    /* Check special commands. */
#ifdef WHO_CI
    if (!strncasecmp(cmd, WHO_COMMAND, strlen(WHO_COMMAND))) {
#else
    if (!strncmp(cmd, WHO_COMMAND, strlen(WHO_COMMAND))) {
#endif				/* WHO_CI */
      if ((bp->typ == INPUT_PLAY) && bp->outputprefix) {
	iobput(bp, bp->outputprefix);
	iobput(bp, "\r\n");
      }
      do_wholist(bp, cmd + strlen(WHO_COMMAND));
      if ((bp->typ == INPUT_PLAY) && bp->outputsuffix) {
	iobput(bp, bp->outputsuffix);
	iobput(bp, "\r\n");
      }
      continue;
    } else
#ifdef WHERE_CI
    if (!strncasecmp(cmd, WHERE_COMMAND, strlen(WHERE_COMMAND))) {
#else
    if (!strncmp(cmd, WHERE_COMMAND, strlen(WHERE_COMMAND))) {
#endif
      if ((bp->typ == INPUT_PLAY) && bp->outputprefix) {
	iobput(bp, bp->outputprefix);
	iobput(bp, "\r\n");
      }
      do_where(bp, cmd + strlen(WHERE_COMMAND));
      if ((bp->typ == INPUT_PLAY) && bp->outputsuffix) {
	iobput(bp, bp->outputsuffix);
	iobput(bp, "\r\n");
      }
      continue;
#ifdef QUIT_CI
    } else if (!strcasecmp(cmd, QUIT_COMMAND)) {
#else
    } else if (!strcmp(cmd, QUIT_COMMAND)) {
#endif				/* QUIT_CI */
      if ((bp->typ == INPUT_PLAY) && bp->outputprefix) {
	iobput(bp, bp->outputprefix);
	iobput(bp, "\r\n");
      }
      if (bp->typ == INPUT_PLAY)
	iobput(bp, GOODBYE_MSG);
      if ((bp->typ == INPUT_PLAY) && bp->outputsuffix) {
	iobput(bp, bp->outputsuffix);
	iobput(bp, "\r\n");
      }
      iobflush(bp);
      iobdrop(bp);
      if (bp->typ == INPUT_PLAY) {
	disconnect_player(bp->player);
      }
      log_disconnect(bp);
      continue;
    }
    switch (bp->typ) {
    case INPUT_NEWCONN:

      if (!strncmp(cmd, PREFIX_COMMAND, strlen(PREFIX_COMMAND))) {
#ifndef RESTRICT_BOT
	set_output_str(bp, cmd + strlen(PREFIX_COMMAND), PREFIX_CODE);
#else
	iobput(bp, RESTRICT_BOT_MSG);
#endif
	break;
      }
      if (!strncmp(cmd, SUFFIX_COMMAND, strlen(SUFFIX_COMMAND))) {
#ifndef RESTRICT_BOT
	set_output_str(bp, cmd + strlen(SUFFIX_COMMAND), SUFFIX_CODE);
#else
	iobput(bp, RESTRICT_BOT_MSG);
#endif
	break;
      }
      /* We grok two commands, create and connect. */

      for (p = cmd; !isspace(*p) && *p; p++);
      if (*p == '\0') {
	greet(bp);
	break;
      }
      *p++ = '\0';

      if (stringprefix(cmd, "connect")) {
	player = connect_player(p);
	if (player == -1) {
	  iobput(bp, BAD_CONNECT);
	  log_badconnect(p, bp);
	} else {
#ifdef PDX
	  if (mud_fullPDX(player)) {
	    iobput(bp, "Sorry, ThreadWay is currently full.  Do try again later.\r\n");
	  } else {
#endif				/* PDX */
	    connect_player2(player);	/* announce and such */
	    bp->typ = INPUT_PLAY;
	    bp->player = player;
	    newwho(bp);

	    log_connect(bp);

#ifdef SUPPORT_RWHO
	    if (rwho_enabled)
	      rwho_login(player, bp->connect);
#endif

	    iob_spit_file(bp, MOTD_FILE);
	    if (iswiz(player))
	      iob_spit_file(bp, WIZN_FILE);
	    check_last(player);
	    check_news(player);
	    if (set_str_elt(player, SITE, bp->hostname) == -1) {
	      warning("dispatch", "couldn't set SITE.");
	    }
	    stamp(player);
#ifdef RESTRICT_BOT
	    if (!isrobot(player) && (bp->outputprefix || bp->outputsuffix)) {
	      iobput(bp, "Your OUTPUTPREFIX and OUTPUTSUFFIX strings have been cleared.\r\n");
	      if (bp->outputprefix) {
		ty_free(bp->outputprefix);
		bp->outputprefix = (char *) 0;
	      }
	      if (bp->outputsuffix) {
		ty_free(bp->outputsuffix);
		bp->outputsuffix = (char *) 0;
	      }
	    }
#endif				/* RESTRICT_BOT */
	    do_look(player, (char *) 0);
#ifdef PDX
	  }
#endif				/* PDX */
	}
      } else if (stringprefix(cmd, "create")) {
#ifdef PDX
	if (mud_fullPDX(-1)) {
	  iobput(bp, "Sorry, ThreadWay is currently full.  Do try again later.\r\n");
	} else {
#endif				/* PDX */
#ifndef REGISTRATION
#ifdef SUPPORT_LOCKOUT
	  {
	    char           *msg;

	    if (check_lockout_list(bp->site, LOCK_REGISTER, &msg)) {
	      if (msg && *msg) {
		iobput(bp, msg);
	      } else {
		if (iob_spit_file(bp, REGISTER_FILE) == -1)
		  iobput(bp, REGISTER_MSG);
	      }
	      iobflush(bp);
	      break;
	    }
	  }
#endif
	  player = create_player(p, -1);
	  if (player == -1) {
	    iobput(bp, BAD_CREATE);
	  } else {
	    bp->typ = INPUT_PLAY;
	    bp->player = player;
	    newwho(bp);

	    log_create(bp);

#ifdef SUPPORT_RWHO
	    if (rwho_enabled)
	      rwho_login(player, bp->connect);
#endif

	    iob_spit_file(bp, MOTD_FILE);
	    iob_spit_file(bp, NEWP_FILE);
	    check_news(player);
	    if (set_str_elt(player, SITE, bp->hostname) == -1) {
	      warning("dispatch", "couldn't set SITE.");
	    }
	    stamp(player);
#ifdef RESTRICT_BOT
	    if (!isrobot(player) && (bp->outputprefix || bp->outputsuffix)) {
	      iobput(bp, "Your OUTPUTPREFIX and OUTPUTSUFFIX strings have been cleared.\r\n");
	      if (bp->outputprefix) {
		ty_free(bp->outputprefix);
		bp->outputprefix = (char *) 0;
	      }
	      if (bp->outputsuffix) {
		ty_free(bp->outputsuffix);
		bp->outputsuffix = (char *) 0;
	      }
	    }
#endif				/* RESTRICT_BOT */
	    do_look(player, (char *) 0);
	  }
#else				/* REGISTRATION */
	  if (iob_spit_file(bp, REGISTER_FILE) == -1) {
	    iobput(bp, REGISTER_MSG);
	  }
#endif				/* REGISTRATION */
#ifdef PDX
	}
#endif				/* PDX */
      } else {
	/* Re-greet this idiot.  */
	greet(bp);
      }
      break;
    case INPUT_PLAY:
      /* check for OUTPUT*X commands first */
      if (!strncmp(cmd, PREFIX_COMMAND, strlen(PREFIX_COMMAND))) {
#ifdef RESTRICT_BOT
	if (!isrobot(bp->player))
	  iobput(bp, RESTRICT_BOT_MSG);
	else
	  set_output_str(bp, cmd + strlen(PREFIX_COMMAND), PREFIX_CODE);
#else
	set_output_str(bp, cmd + strlen(PREFIX_COMMAND), PREFIX_CODE);
#endif
	break;
      }
      if (!strncmp(cmd, SUFFIX_COMMAND, strlen(SUFFIX_COMMAND))) {
#ifdef RESTRICT_BOT
	if (!isrobot(bp->player))
	  iobput(bp, RESTRICT_BOT_MSG);
	else
	  set_output_str(bp, cmd + strlen(SUFFIX_COMMAND), SUFFIX_CODE);
#else
	set_output_str(bp, cmd + strlen(SUFFIX_COMMAND), SUFFIX_CODE);
#endif
	break;
      }
      if (bp->outputprefix) {
	iobput(bp, bp->outputprefix);
	iobput(bp, "\r\n");
      }
      handle_cmd(bp->player, cmd);
      if (bp->outputsuffix) {
	iobput(bp, bp->outputsuffix);
	iobput(bp, "\r\n");
      }
      break;
    }
  }
  /* OK We banged into the end of the buffer. */


  if (cmd != buff) {		/* Is there anything left in the buffer? */
    bp->inputcnt = buff - cmd;
    bcopy(cmd, bp->inputbuf, bp->inputcnt);
  } else {
    bp->inputcnt = 0;
  }
}

static void     set_output_str(bp, string, code)
  Iob            *bp;
  char           *string;
  int             code;
{

  while (*string && isspace(*string) && isascii(*string))
    string++;

  if (code == PREFIX_CODE) {
    if (!string || !*string) {
      ty_free(bp->outputprefix);
      bp->outputprefix = 0;
    } else {
      ty_free(bp->outputprefix);
      bp->outputprefix = (char *) ty_malloc(strlen(string) + 1, "set_output_str");
      if (bp->outputprefix)
	strcpy(bp->outputprefix, string);
    }
  }
  if (code == SUFFIX_CODE) {
    if (!string || !*string) {
      ty_free(bp->outputsuffix);
      bp->outputsuffix = 0;
    } else {
      ty_free(bp->outputsuffix);
      bp->outputsuffix = (char *) ty_malloc(strlen(string) + 1, "set_output_str");
      if (bp->outputsuffix)
	strcpy(bp->outputsuffix, string);
    }
  }
}

void            newwho(bp)
  Iob            *bp;
{
  if (wholist == (Iob *) 0) {
    wholist = bp->whofwd = bp->whoback = bp;
  } else {
    bp->whoback = wholist;
    bp->whofwd = wholist->whofwd;
    (wholist->whofwd)->whoback = bp;
    wholist->whofwd = bp;
  }
}

void            dropwho(bp)
  Iob            *bp;
{
  if (bp->whofwd == bp) {
    wholist = (Iob *) 0;
  } else {
    if (wholist == bp) {
      wholist = bp->whoback;
    }
    (bp->whoback)->whofwd = bp->whofwd;
    (bp->whofwd)->whoback = bp->whoback;
  }
}

void            greet(bp)
  Iob            *bp;
{
  if (bp->typ == INPUT_NEWCONN) {
    if (iob_spit_file(bp, GREET_FILE) == -1) {
      iobput(bp, DEFAULT_GREET);
    }
  }
}

int             iob_spit_file(bp, filename)
  Iob            *bp;
  char           *filename;
{
  FILE           *in;
  char            filebuff[128];

  if ((in = fopen(filename, "r")) == NULL) {
    return (-1);
  }
  while (fgets(filebuff, 127, in) != NULL) {
    fix_newline(filebuff);
    iobput(bp, filebuff);
  }

  (void) fclose(in);

  return (1);
}

/*
 * Matches against the list of active players.
 * 
 * returns -1 if no match, -2 if ambiguous, or the object number.
 * 
 * This lives here, 'cause it needs to screw around with the network's notion of
 * the who list.
 * 
 */

int             match_who(name)
  char           *name;

{
  Iob            *curr;
  char           *player_name;

  curr = wholist;

  do {
    if (get_str_elt(curr->player, NAME, &player_name) == -1) {
      warning("match_who", "bad name reference on WHO list");
      return (-1);
    }
    if (player_name == (char *) 0) {
      warning("match_who", "active player with NULL name");
      curr = curr->whofwd;
      continue;
    }
    if (!strcasecmp(name, player_name))
      return (curr->player);
    curr = curr->whofwd;
  } while (curr != wholist);

  return (-1);
}

/*
 * Display the WHO list to a bp.
 */

void            do_wholist(bp, arg)
  Iob            *bp;
  char           *arg;
{
  Iob            *who;
  char           *whonm, idletype;
  char            work2[82];
  char            work3[14];
  char            line[82];
  int             g, h, i, j, k, total = 0;
  int             wizard = 0;

#ifdef REVERSED_WHO
  Iob            *first;
#endif				/* REVERSED_WHO */

  while (arg[0] == ' ')
    arg++;

#ifdef WIZWHOALL
  if (bp->typ == INPUT_PLAY)
    wizard = 1;
#else				/* WIZWHOALL */
  if ((bp->typ == INPUT_PLAY) && iswiz(bp->player))
    wizard = 1;
#endif				/* WIZWHOALL */
  (void) sprintf(line,
       "Player Name           On For   Idle %s\r\n", (poll_str && *poll_str)
		 ? poll_str : "Doing");
  iobput(bp, line);

  if ((who = wholist) == (Iob *) 0)
    goto uptime;
#ifdef REVERSED_WHO
  first = who = who->whofwd;
#endif				/* REVERSED_WHO */

  do {
    if (isdark(who->player) && !wizard)
      goto skipthisline;
    total++;
    if (get_str_elt(who->player, NAME, &whonm) != -1) {
      (void) strcpy(work2, whonm);
    } else
      (void) strcpy(work2, "???");
    if (strlen(arg) && !stringprefix(arg, work2))
      goto skipthisline;
    if (wizard) {
      sprintf(work3, "(#%d%s%s%s%s)", who->player, (iswiz(who->player)) ?
       "W" : "", (isdark(who->player)) ? "D" : "", (issticky(who->player)) ?
	      "S" : "", (isguest(who->player)) ? "G" : "");
      strcat(work2, work3);
    }
    g = (int) (last.tv_sec - who->connect);
    h = g / 86400;
    g %= 86400;
    i = g / 3600;
    j = g / 60 % 60;
    k = (int) (last.tv_sec - who->lastcmd);
    idletype = 's';
    if (k > 59) {
      idletype = 'm';
      k /= 60;
      if (k > 59) {
	idletype = 'h';
	k /= 60;
	if (k > 23) {
	  idletype = 'd';
	  k /= 24;
	}
      }
    }
    if (h)
      sprintf(line,
	      "%-19s %dd %02d:%02d    %2d%c", work2, h, i, j, k,
	      idletype);
    else
      sprintf(line,
	      "%-22s %02d:%02d    %2d%c", work2, i, j, k, idletype);
    if (who->doing) {
      strcat(line, " ");
      strcat(line, who->doing);
    }
    strcat(line, "\r\n");
    iobput(bp, line);
skipthisline:
#ifdef REVERSED_WHO
    who = who->whofwd;
  } while (who != first);
#else				/* REVERSED_WHO */
    who = who->whoback;
  } while (who != wholist);
#endif				/* REVERSED_WHO */

uptime:

  if (total) {
#ifdef PDX
    sprintf(line, "%d (of %d) user%s %s connected.  ", total, max_logins,
#else
    sprintf(line, "%d user%s %s connected.  ", total,
#endif				/* PDX */
	    (total == 1) ? "" : "s", (total == 1) ? "is" : "are");
    iobput(bp, line);
  } else
    iobput(bp, "No users are connected.  ");
  h = last.tv_sec - startingtimeofmud;
  j = h / 3600 % 24;
  k = h / 60 % 60;
  i = h / 86400;
  if (i)
    sprintf(line, "Uptime: %dd, %02d:%02d.\r\n", i, j, k);
  else
    sprintf(line, "Uptime: %02d:%02d.\r\n", j, k);
  iobput(bp, line);
}

void            do_where(bp, arg)
  Iob            *bp;
  char           *arg;
{
  Iob            *who;
  char           *whonm, *p;
  char            work2[82];
  char            work3[82];
  char            line[82];
  int             where, wizard = 0;

#ifdef REVERSED_WHO
  Iob            *first;
#endif				/* REVERSED_WHO */

  if (strlen(arg))
    while (arg[0] == ' ')
      arg++;

#ifdef WIZWHOALL
  wizard = 1;
#else				/* WIZWHOALL */
  if (bp->typ == INPUT_PLAY && iswiz(bp->player) && arg[0] != '-')
    wizard = 1;
#endif				/* WIZWHOALL */
  if (arg[0] == '-')
    arg++;

  iobput(bp, "Player Name         Location");
  iobput(bp, wizard ? "  Site\r\n" : "\r\n");
  if ((who = wholist) == (Iob *) 0) {
    iobput(bp, "No users are connected.\r\n");
    return;
  }
#ifdef REVERSED_WHO
  first = who = who->whofwd;
#endif				/* REVERSED_WHO */

  do {
    if (!wizard && isdark(who->player))
      goto skipthisline2;
    if (get_str_elt(who->player, NAME, &whonm) != -1) {
      (void) strcpy(work2, whonm);
    } else
      (void) strcpy(work2, "???");
    if (strlen(arg) && !stringprefix(arg, work2))
      goto skipthisline2;
    if (wizard) {
      sprintf(work3, "(#%d%s%s%s)", who->player, (iswiz(who->player)) ?
	      "W" : "", (isdark(who->player)) ? "D" : "",
	      (issticky(who->player)) ? "S" : "");
      strcat(work2, work3);
    }
    if (!wizard) {
      if (!issticky(who->player)) {
	if (get_int_elt(who->player, LOC, &where) == -1)
	  where = -1;
	if (where != -1) {
	  if (get_str_elt(where, NAME, &p) != -1) {
	    if (p == NULL)
	      p = "???";
	    if (strlen(p) > 50) {
	      strncpy(work3, p, 50);
	      work3[49] = 0;
	    } else
	      strcpy(work3, p);
	    if ((isjumpok(where) || (bp->typ == INPUT_PLAY &&
		      controls(bp->player, where))) && strlen(work3) < 45) {
	      sprintf(work3 + strlen(work3), "(#%d)", where);
	    }
	  }
	} else
	  strcpy(work3, "???");
      } else
	work3[0] = 0;
      sprintf(line, "%-19s %s", work2, work3);
    } else {
      if (get_int_elt(who->player, LOC, &where) == -1)
	where = -1;
      sprintf(work3, "(#%d)", where);
      sprintf(line, "%-19s %8s  %s", work2, work3, who->hostname);
    }
    strcat(line, "\r\n");
    iobput(bp, line);
skipthisline2:
#ifdef REVERSED_WHO
    who = who->whofwd;
  } while (who != first);
#else				/* REVERSED_WHO */
    who = who->whoback;
  } while (who != wholist);
#endif				/* REVERSED_WHO */
}

void            log_disconnect(bp)
  Iob            *bp;
{
  char           *name;

  if (bp->typ == INPUT_PLAY) {
    if (get_str_elt(bp->player, NAME, &name) != -1) {
      log_status("DISCONNECT: %s(#%d) on fd %d.\n", name, bp->player, bp->fd);
    } else
      log_status("DISCONNECT: ???(#%d) on fd %d.\n", bp->player, bp->fd);
  } else
    log_status("DISCONNECT: fd %d never connected.\n", bp->fd);
}
void            log_connect(bp)
  Iob            *bp;
{
  char           *name;

  if (bp->typ == INPUT_PLAY) {
    if (get_str_elt(bp->player, NAME, &name) != -1) {
      log_status("CONNECTED: %s(#%d) on fd %d.\n", name, bp->player, bp->fd);
    } else
      log_status("CONNECTED: ???(#%d) on fd %d.\n", bp->player, bp->fd);
  } else
    log_status("CONNECTION: fd %d connected from [%s].\n",
	       bp->fd, bp->hostname);
}
static void     log_create(bp)
  Iob            *bp;
{
  char           *name;

  if (get_str_elt(bp->player, NAME, &name) != -1) {
    log_status("CREATED: %s(#%d) on fd %d.\n", name, bp->player, bp->fd);
  } else
    log_status("CREATED: ???(#%d) on fd %d.\n", bp->player, bp->fd);
}
static void     log_badconnect(s, bp)
  char           *s;
  Iob            *bp;
{
  char            buf[65];
  char           *p, *q;

  for (p = s, q = buf; p && *p && *p != ' ' && (q - buf) < 64; *q++ = *p++);
  *q = '\0';

  log_status("FAILED CONNECT: fd %d failed connection to \"%s\".\n",
	     bp->fd, buf);
}

#ifdef SUPPORT_RWHO
void            rwho_daemon()
{
  Iob            *cur = wholist;

  rwhocli_pingalive();
  if (wholist != (Iob *) 0) {
    do {
      rwho_login(cur->player, cur->connect);
      cur = cur->whoback;
    } while (cur != wholist);
  }
}
#endif

#ifdef PDX
int             mud_fullPDX(player)
  int             player;
{
  Iob            *cur = wholist;
  int             total = 0;
  extern int      max_logins;

  if (player != -1 && iswiz(player))
    return (0);

  if (wholist != (Iob *) 0) {
    do {
#ifndef HOSTNAMES
      if (strncmp(cur->hostname, "131.252", 7) && strcmp(cur->hostname,
		       "127.0.0.1") && strncmp(cur->hostname, "128.193", 7))
#else
      if ((domaincmp(cur->hostname, "pdx.edu", 2) || domaincmp(cur->hostname,
	       "cs.pdx.edu", 1)) && (domaincmp(cur->hostname, "CS.ORST.EDU",
			   1) || domaincmp(cur->hostname, "ORST.EDU", 1)) &&
	  strncmp(cur->hostname, "localhost", 9))
#endif
	total++;
      cur = cur->whofwd;
    } while (cur != wholist);
  }
  return (total >= max_logins);
}
#endif

int             match_active_player(arg)
  char           *arg;
{
  Iob            *who;
  Iob            *first;
  int             number = 0;
  int             player;
  char           *name;

  who = wholist;
  first = who = who->whofwd;
  do {
    if (get_str_elt(who->player, NAME, &name) == -1) {
      warning("match_active_player", "bad player name");
      return (-1);
    }
    if (strlen(arg) && stringprefix(arg, name)) {
      if (strlen(arg) == strlen(name))
	return (who->player);
      number++;
      if (number == 1) {
	player = who->player;
      } else {
	if (who->player != player)
	  return (-2);
	else
	  number = 1;
      }
    }
    who = who->whofwd;
  } while (who != first);
  if (number)
    return (player);
  else
    return (-1);
}

#ifdef SUPPORT_LOCKOUT
int             check_lockout_list(site, flag, msg)
  long            site;
  int             flag;
  char          **msg;
{
  FILE           *file;
  int             a, b, c, d;
  long            lockedsite;
  int             lockedout = FALSE;
  register int    lockflag;
  char            buf[512];
  char           *p;

  if ((file = fopen(LOCKOUT_FILE, "r")) == NULL) {
    log_error("check_lockout_list: %s does not exist", LOCKOUT_FILE);
    return (lockedout);
  }
  while (!lockedout && fgets(buf, 511, file) != NULL) {
    a = b = c = d = 0;
    p = buf;
    lockflag = LOCK_REGISTER;

    switch (buf[0]) {
    case 'R':
      lockflag = LOCK_REGISTER;
      for (p++; *p && isspace(*p); p++);
      break;
    case 'L':
      lockflag = LOCK_DISCONNECT;
      for (p++; *p && isspace(*p); p++);
      break;
    }
    if (*p && *p != '#') {
      a = atoi(p);
      while (*p != '.')
	p++;
      p++;
      b = atoi(p);
      while (*p != '.')
	p++;
      p++;
      c = atoi(p);
      while (*p != '.')
	p++;
      p++;
      d = atoi(p);

      lockedsite = ((a & 0xff) << 24) + ((b & 0xff) << 16)
	+ ((c & 0xff) << 8) + (d & 0xff);
      if ((lockedsite == site) && (flag == lockflag)) {
	lockedout = TRUE;
	for (; *p && !isspace(*p); p++);
	for (; *p && isspace(*p); p++);
	fix_newline(p);
	*msg = p;
      }
    }
  }
  fclose(file);
  return (lockedout);
}
#endif

voidfunc        do_doing(player, who, str)
  int             player;
  char           *who, *str;
{
  Iob            *curr;
  int             person;

  if (str && *str) {
    if ((person = resolve_player(player, who, iswiz(player))) == -1 ||
	person == -2) {
      notify_player(player, "No such player.\r\n");
      return;
    }
    if (!iswiz(player) && person != player) {
      notify_player(player, "You can't do that.\r\n");
      return;
    }
  } else {
    person = player;
    str = who;
  }

  if (!isalive(person)) {	/* @forse won't crash me */
    notify_player(player, "That person is not connected.\r\n");
    return;
  }
  if (str && *str && strlen(str) > DOING_MAX)
    str[DOING_MAX - 1] = 0;
  curr = wholist;
  do {
    if (curr->player != person)
      goto nextone;
    if (curr->doing) {
      ty_free(curr->doing);
      curr->doing = 0;
    }
    if (str && *str) {
      curr->doing = ty_malloc(strlen(str) + 1, "do_doing");
      (void) strcpy(curr->doing, str);
    }
nextone:
    curr = curr->whofwd;
  } while (curr != wholist);
  notify_player(player, (person == player) ? "Set.  Have fun doing it.\r\n"
		: "Set.\r\n");
}

voidfunc        do_poll(player, str)
  int             player;
  char           *str;
{
  extern char     cmdwork[];
  char           *name;

  if (!iswiz(player)) {
    notify_player(player, "Having delusions of grandeur, are we?\r\n");
    return;
  }
  if (!str || !*str)
    str = "Doing";

  if (strlen(str) > DOING_MAX)
    str[DOING_MAX - 1] = 0;
  if (poll_str)
    ty_free(poll_str);
  poll_str = ty_malloc(strlen(str) + 1, "do_poll");
  (void) strcpy(poll_str, str);
  notify_player(player, "Poll set.\r\n");

  if (get_str_elt(player, NAME, &name) != -1) {
    (void) sprintf(cmdwork, "* %s has added a new poll. *\r\n", name);
    notify_wall(cmdwork);
  }
}