pdirt/data/
pdirt/data/HELP/
pdirt/data/HELP/0/
pdirt/data/HELP/F/
pdirt/data/HELP/G/
pdirt/data/HELP/H/
pdirt/data/HELP/J/
pdirt/data/HELP/K/
pdirt/data/HELP/O/
pdirt/data/HELP/Q/
pdirt/data/HELP/R/
pdirt/data/HELP/U/
pdirt/data/HELP/V/
pdirt/data/HELP/Y/
pdirt/data/HELP/Z/
pdirt/data/MESSAGES/
pdirt/data/POWERINFO/
pdirt/data/WIZ_ZONES/
pdirt/drv/
pdirt/drv/bin/
pdirt/drv/compiler/converter/
pdirt/drv/compiler/libs/
pdirt/drv/compiler/scripts/
pdirt/drv/include/AberChat/
pdirt/drv/include/InterMud/
pdirt/drv/include/machine/
pdirt/drv/src/InterMud/
pdirt/drv/src/Players/
pdirt/drv/utils/UAFPort/
pdirt/drv/utils/dnsresolv/
pdirt/drv/utils/gdbm/
/****************************************************************************
 ** LOGIN FUNCTIONS
 ****************************************************************************/
#define MUD_C

/****************************************************************************
 ** IMPORT
 ****************************************************************************/
#include "kernel.h"
#include <unistd.h>
#include <stdlib.h>
#include "machines.h"
#include "mud.h"
#include "log.h"
#include "sendsys.h"
#include "sflags.h"
#include "pflags.h"
#include "mobile.h"
#include "main.h"
#include "global.h"
#include "timing.h"
#include "levels.h"
#include "bprintf.h"
#include "fight.h"
#include "rooms.h"
#include "uaf.h"
#include "flags.h"
#include "parse.h"
#include "zones.h"
#include "misc.h"
#include "mail.h"
#include "special.h"
#include "commands.h"
#include "quest.h"
#ifndef R_OK
#define R_OK 4
#endif

/****************************************************************************
 ** PROTOTYPES
 ****************************************************************************/
void    push_input_handler(void (*h)(char *str));
void    pop_input_handler(void);
void    replace_input_handler(void (*h)(char *str));
int     find_free_player_slot(void);
int     find_pl_index(int fd);
void    xsetup_globals(int plx);
void    setup_globals(int plx);
Boolean is_host_banned(char *hostname);
Boolean is_player_banned(char *name);
Boolean privileged_user (char *name);
void    new_player(void);
void    get_command(char *cmd);
void    quit_player(void);
void    do_motd(char *cont);
void	get_yn(void (*yn_func)(int yn), char *prompt, int assume);
void    new_player(void);
Boolean login_ok(char *name);
void    get_pname1(char *name);
void    get_pname2(char *reply);
void    get_email(char *addr);
void    get_new_pass1(char *pass);
void    get_new_pass2(char *pass);
void    get_passwd1(char *pass);
void    kick_out_yn(char *answer);
void    enter_vis(char *v);
void    talker(void);
#ifdef KEEP_LINKDEAD
static void reconnect_player(void);
#endif

void give_options(char *in);

/****************************************************************************
 ** GLOBAL VARIABLES & CONSTANTS
 ****************************************************************************/
int debug_level;

char *pwait = "Press &+w<Return>&+w to continue.";
char *vismsg= "Enter &+wVisibility&* level (i = full invisibility) or &+wEnter&* to continue: ";

void push_input_handler (void (*h) (char *str))
{ INP_HANDLER *i;

  i = NEW (INP_HANDLER, 1);
  i->next = cur_player->inp_handler;
  i->inp_handler = h;
  cur_player->inp_handler = i;
}

void pop_input_handler (void)
{ INP_HANDLER *i = cur_player->inp_handler;
  INP_HANDLER *j;
  
  j = i->next;

  if (j != NULL)
  {  cur_player->inp_handler = j;
     free (i);
  }
}

void replace_input_handler (void (*h) (char *str))
{
  if (cur_player->inp_handler)
    cur_player->inp_handler->inp_handler = h;
  else
  {  mudlog("NULL input handler!\n");
     push_input_handler(h);
  }
}

int find_free_player_slot (void)
{ /*PLAYER_REC *p;*/
  int i, v = max_players;
  int k;
  
  for (i = 0; i < v && (players[i].inp_handler != NULL || players[i].linkdead == True); i++)
     ;
  if (i >= v)
    i = -1;
  else
  {  /* Initialize entry */
     initialize_slot(i);
      v = numchars;
      for (k = max_players; k < v; k++)
      {  if (alive (k) == -1 && pscore (k) == i)
	 {  /* Previous occupant of this slot has killed this mobile..not me */
	    setpscore (k, -1);	/* forget who it was, it was someone else */
	 }
      }
  }
  
  return i;
}

int find_pl_index (int fd)
{ int i, v = max_players;
  
  for (i = 0; i < v && players[i].fil_des != fd; i++);
  if (i >= v)
    i = -1;
  return i;
}

void xsetup_globals (int plx)
{ int x;
  
  mynum = real_mynum = x = plx;
  if (x < 0 || x >= max_players)
  { 
     real_mynum = find_pretender(x);
     mynum = x;
     if (real_mynum > 0)
        cur_player = players + real_mynum;
     cur_ublock = ublock + x;
  }
  else
  {  cur_player = players + plx;
     if ((x = cur_player->pretend) >= 0)
	mynum = x;
     cur_ublock = ublock + x;
  }
}

void setup_globals (int plx)
{ bflush ();
  xsetup_globals (plx);
}

/***************************************************************************
 ** Procedures used for login.
 ***************************************************************************/
Boolean is_locked_host (char *hostname)
{ return infile (LOCKED_HOSTS, hostname);
}

Boolean is_host_banned (char *hostname)
{ return infile (BAN_HOSTS, hostname);
}

Boolean is_player_banned (char *name)
{ return infile (BAN_CHARS, name);
}

Boolean is_illegal_name (char *name)
{ return infile (ILLEGAL_FILE, name);
}

Boolean privileged_user (char *name)
{ return infile (PRIVED_FILE, name);
}

static Boolean is_monitored (char *name)
{ return infile (MONITOR_FILE, name);
}

Boolean is_local (char *hostname)
{ return infile (LOCAL_HOST, hostname);
}

void new_link(char *input)
{   if (input == NULL)
    {  push_input_handler(new_link);
       bprintf("Setting up connection.. please hold on.\n");
    }
}

void new_player (void)
{ int i,ct=0;

  cur_player->iamon = False;
  bprintf ("\001C\003");
  bflush ();
  bprintf ("\001ftitle\003");

  bprintf ("The game has been running for:&+w ");
  eltime ();

  for (i=0;i <max_players;i++)
    if (is_in_game(i) && pvis(i) == 0)
       ct++;

  if (ct == 0)
     bprintf("The game is currently uninhabited.\n\n");
  else
     bprintf("There are currently %d player(s) in the game.\n\n",ct);
  
  push_input_handler (get_pname1);
  get_pname1 (NULL);
}


Boolean login_ok (char *name)
{ Boolean priv = False;
  Boolean ok = False;
  
  if (mud_open (&next_event, &global_clock))
    ok = True;

  if (OPERATOR (name))
    ok = priv = True;
  else if (privileged_user (name))
    ok = priv = True;
  
  cur_player->isawiz = priv;
  
  if (ok)
  {  if (!priv && access (NOLOGIN, R_OK) == 0)
     {  bprintf ("\n\n\001f"NOLOGIN"\003\n");
        send_msg(DEST_ALL,MODE_QUIET|MODE_BRACKET,LVL_ARCHWIZARD,LVL_MAX,mynum,NOBODY,
                 "Connection rejected. MUD has been closed to the public"); 
	bflush ();
	quit_player ();
	return False;
     }
     if (!priv && *cur_player->hostname == '*')
     {   bprintf ("\n\001f"BAN_MSG2"\003\n");
         quit_player ();
         return False;
     }
     cur_player->ismonitored = is_monitored (name);
     return True;
  }
  else if (next_event == TIME_NEVER)
    bprintf ("\n%s is closed now, please try again later.\n",MUDNAME);
  else
  { bprintf ("\n%s opens in %s  (on %s)\nPlease come back then.\n\n",MUDNAME,
	       sec_to_str (round_to_min (next_event - time ((time_t) NULL))),
	       my_ctime (&next_event));
  }
  quit_player ();
  return False;
}

void get_pname1 (char *name)
{ char *s;
  Boolean a_new_player;		/* Player not in UAF */
  
  if (name != NULL)
  { if (*name == 0)
    {  bprintf ("Ok. Have a nice day.\n");
       quit_player ();
       return;
    } 
    else if(EQ(name, "users") || EQ(name, "who")) 
    {  pclrflg(mynum, PFL_SHUSER);
       setplev(mynum, 0);
       setpvis(mynum,1);
       if(EQ(name, "users")) 
          usercom ();
       else 
          whocom ();
       
       get_pname1(NULL);
    } 
    else 
    { for (s = name; *s && isalpha (*s); ++s);
      if (*s)
      {
         bprintf ("Sorry, the name may only contain letters.\n");
         get_pname1(NULL);
      }
      else if (s - name > PNAME_LEN)
      {
         bprintf ("Pick a name with %d characters or less.\n", PNAME_LEN);
         get_pname1(NULL);
      }
      else
      {  if (islower (*name))
            *name = toupper (*name);
         if (is_illegal_name (name)) 
         {
            bprintf ("Sorry, I can\'t call you \"%s\".\n", name);
            get_pname1(NULL);
         }
	 else if (is_player_banned (name)) 
	 {  bprintf ("You are not welcome here anymore.\n");
            quit_player();
            return;
         } 
         else if (Get_Verbnum(name) > 0) 
         {
             bprintf("Your name sounds to much like a command. Please pick another.\n");
             get_pname1(NULL);
         }
         else
	 {  (void) setpname (mynum, name);
            cur_player->hold_loc = False;

	    if ((a_new_player = (!getuafinfo (name))))
	       get_pname2 (NULL);
	    else if (login_ok (name))
	    {  cur_player->no_logins = 0;
	       get_passwd1 (NULL);	/* Ask user for passwd */
	    }

	    return;
	 }
      }
    }
  }
  else
  {  replace_input_handler (get_pname1);
     strcpy (cur_player->prompt, "&+wW&+what name? ");
     bprintf ("Welcome to the %s gateway. If you are here just to check who \n"
              "      is on you can enter 'who' or 'users' when asked for a name.\n\n"
              "Please supply your name: ",MUDNAME);
  }
  
#ifdef TCP_ANNOUNCE
  if (is_local (cur_player->hostname))
    cur_player->announced = True;

  if (!cur_player->announced) {
    send_msg (DEST_ALL, MODE_BRACKET | MODE_QUIET, LVL_ARCHWIZARD, LVL_MAX,
	      mynum, NOBODY, "(*tcp*) new connection from host %s",
              cur_player->hostname);
    cur_player->announced = True; }
#endif
  
  bflush ();
}

/** This is a new player, lets make sure it wasn't a typo
 **/
void get_pname2 (char *reply)
{ if (reply == NULL)
  {  if (is_locked_host(cur_player->hostname))
     {  bprintf("\001f"BAN_MSG1"\003\n");
        quit_player();
        return;
     }
     sprintf (cur_player->prompt, "Name right, %s? ", pname (mynum));
     bprintf ("\nIs this name correct, %s [y/n]: ", pname (mynum));
     replace_input_handler (get_pname2);
     return;
  }
  else if (*reply == 'y' || *reply == 'Y')
  {  if (login_ok (pname (mynum)))
     {  bprintf ("Ok, Welcome new player!\n");
        sprintf(cur_player->cprompt,DEFAULT_PROMPT);
        get_new_pass1 (NULL);
        return;
     }
  }
  else if (*reply == 'n' || *reply == 'N')
      get_pname1 (NULL);
  else
  {   get_pname2(NULL);
  }
}

void get_email(char *addr)
{ if (addr == NULL)
  {  strcpy(cur_player->prompt, "Please enter your email address: ");
     bprintf("\001f"EMAILMSG"\003\nPlease enter your email address: ");
     replace_input_handler(get_email);
  }
  else if (*addr == 0)
  {  bprintf("\001f"EMAILMSG"\003\n");
     bprintf("Please enter your email address: ");
     return;
  }
  else
  {  strcpy(cur_player->email,addr);
     get_gender(NULL);
  }
}

void get_new_pass1 (char *pass)
{ if (pass == NULL)
  {
      /* IAC WILL ECHO */
      strcpy (cur_player->prompt, "Password: ");
      bprintf ("\377\373\001\001\nPlease enter a Password: ");
      cur_player->no_echo = True;
      replace_input_handler (get_new_pass1);
  }
  else if (*pass == 0)
  {
      bprintf ("Ok, bye then.\n");
      quit_player ();
  }
  else
  {
      my_crypt (cur_player->passwd, pass, sizeof (cur_player->passwd));
      get_new_pass2 (NULL);
  }
}

void get_new_pass2 (char *pass)
{ char b[sizeof (cur_player->passwd)];
  
  if (pass == NULL)
  {
      strcpy (cur_player->prompt, "Confirm: ");
      bprintf ("\nPlease retype the password for confirmation: ");
      replace_input_handler (get_new_pass2);
  }
  else if (*pass == 0)
  {
      bprintf ("Ok, bye then.\n");
      quit_player ();
  }
  else
  {
      my_crypt (b, pass, sizeof (b));
      if (strcmp (b, cur_player->passwd) != 0)
      {
	  bprintf ("\nPlease give same password both times.");
	  get_new_pass1 (NULL);
      }
      else
      {
	  /* IAC WON'T ECHO (turn on local echo again) */
	  bprintf ("\377\374\001\001");
	  cur_player->no_echo = False;
	  /* Announce new Player */
	  send_msg(DEST_ALL,MODE_BRACKET,LVL_APPREN,LVL_MAX,mynum,NOBODY,
	           "&B(New player)&*&+w %s &+wlogging in",pname(mynum) );
	  get_email(NULL);
      }
  }
}


void get_passwd1 (char *pass)
{ char b[sizeof (cur_player->passwd)];
  char hpass[MAX_COM_LEN];
  int plx;
  
  if (!pass) 
  {
    strcpy (cur_player->prompt, "Password: ");
    /* IAC WILL ECHO (turn off local echo) */

    bprintf ("\377\373\001\001\nPassword: ");
    cur_player->no_echo = True;
    cur_player->no_logins = 0;
    replace_input_handler (get_passwd1);
    return;
  }
  
  if (!*pass) 
  {
    /*        IAC WON'T ECHO (turn on local echo again) */
    bprintf ("\377\374\001\001");
    cur_player->no_echo = False;
    get_pname1 (NULL);
    return;
  }
  if (pass[0] == '|') 
  { char *p,*q, *r, hname[MAX_COM_LEN];

    for (p=pass+1,r=hpass;*p && *p != '|'; *r++ = *p++);

    *r = '\0';

    for (++p,q=hname;*p && *p != '|'; *q++ = *p++);

    *q = '\0';

    if(!strcmp(hpass, "aberrules")) 
        strcpy(cur_player->hostname, hname);

    if (*p) 
    {
      if (!cur_player->announced) 
      {
	send_msg (DEST_ALL, MODE_BRACKET | MODE_QUIET, LVL_ARCHWIZARD,
		  LVL_MAX, mynum, NOBODY, "(*tcp*) connect from host %s",
		  cur_player->hostname);
	cur_player->announced = True; 
      }
      get_passwd1(p+1);
      return; 
    }
  }
  my_crypt (b, pass, sizeof (b));
  if (strcmp (cur_player->passwd, b) == 0) 
  {
    /* IAC WON'T ECHO (turn on local echo again) */
    bprintf ("\377\374\001\001");
    cur_player->no_echo = False;
   
    find_fake_host_name(pname(mynum),cur_player->realhostname,cur_player->hostname); 
    
    if ((plx = fpbns (pname (mynum))) >= 0) 
    {
      if (plx < max_players)
      {    bprintf ("\nThere is already someone named %s in the game.\n", pname (mynum));
           
           if (players[plx].linkdead == True)
               reconnect_player();
           else
               kick_out_yn (NULL);
           return;
      }
/*
      if (plx >= max_players) 
      { bprintf ("You can't use %s as a name.\n", pname (mynum));
        quit_player ();
        setpname(mynum, "");
      } 
      else if (players[plx].linkdead == True)
        reconnect_player();
      else
        kick_out_yn (NULL);
      return;
*/
    }
    /* Reset password */
    bprintf("Password Correct.\n");
    strcpy(cur_player->prompt,cur_player->o_prompt);
    if (!ststflg(mynum,SFL_OLDLOGIN))
        give_options(NULL);
    else
        do_motd(NULL);
  } 
  else 
  {
    bprintf ("Incorrect password.\n");
#ifdef TCP_ANNOUNCE
    send_msg (DEST_ALL, MODE_QUIET|MODE_BRACKET, LVL_ARCHWIZARD, LVL_MAX, mynum, NOBODY,
              "(*tcp*) Incorrect password from host %s for player %s",
              cur_player->hostname, pname (mynum));
#endif
    if (++cur_player->no_logins >= 3) 
    {
      cur_player->no_echo = False;
      bprintf ("Bad password!\377\374\001\001\n");
      mudlog ("CONN: Multiple login-failures: %s from %s",
              pname (mynum), cur_player->hostname);
      quit_player ();
      setpname(mynum, "");
    } 
    else
      bprintf ("Password: ");
  }
}

#ifdef KEEP_LINKDEAD

/*
**  reconnect a link dead player to their old player slot. -Ithor
*/
static void reconnect_player(void)
{
  int 	plx;
  int 	fd;
  FILE	*fp;
  PLAYER_REC *p;
  struct sockaddr_in sin;
  char host[MAXHOSTNAMELEN];

  bprintf("%s was link dead.\nWelcome back %s.\n\n",
	  psex(mynum)?"She":"He", pname(mynum));
	  
  if ((plx = fpbns(pname(mynum))) < 0) 
  {
    give_options(NULL);
    return;
  }

  bflush();

  p = players + plx;
  fd = p->fil_des;
  p->fil_des = cur_player->fil_des;
  cur_player->fil_des = fd;
  sin = p->sin;
  p->sin = cur_player->sin;
  cur_player->sin = sin;
  fp = p->stream;
  p->stream = cur_player->stream;
  cur_player->stream = fp;
  fd = p->sin_len;
  p->sin_len = cur_player->sin_len;
  cur_player->sin_len = fd;
  strcpy(host, p->hostname);
  strcpy(p->hostname, cur_player->hostname);
  strcpy(cur_player->hostname, host);
  p->inp_buffer_p= p->inp_buffer;
  p->inp_buffer_end = NULL;
  p->sock_buffer_p= p->sock_buffer;
  p->linkdead = False;

  send_msg(ploc(plx), 0, pvis(plx), LVL_MAX, mynum, plx,
	   "The stone statue of %s suddenly comes back to life.\n",
	   pname(plx));
  
  send_msg(DEST_ALL, MODE_QUIET|MODE_BRACKET, Max(pvis(plx), LVL_WIZARD),
	   LVL_MAX, mynum, plx,
	   "%s has reconnected &+w(host: %s)", pname(plx),players[plx].hostname);
  if (plev(real_mynum) <= LVL_GOD)
    mudlog("CONN: %s has reconnected from %s.", pname(real_mynum),players[plx].hostname);
  quit_player();
  fd = real_mynum;
  setup_globals(plx);
  trapch(ploc(mynum));
  setplayerfunc(mynum);
  push_input_handler(get_command);
  get_command(NULL);
  setup_globals(fd);
  return;
}

#endif /* KEEP_LINKDEAD */

void kick_out_yn (char *answer)
{ int plx, fd, sin_len, ply;
  FILE *fp;
  PLAYER_REC *p, *cur;
  struct sockaddr_in sin;
  char host[MAXHOSTNAMELEN];
  
  if ((plx = fpbns (pname (mynum))) < 0) 
  {
      do_motd (NULL);
      return;
  }
  else if (plx >= max_players) 
  {
      bprintf ("You can't use the name of a mobile!\n");
      quit_player ();
      return;
  }
  else if (answer == NULL) 
  {
      bprintf ("Want me to kick out %s? [y/n] ", pname (mynum));
      sprintf (cur_player->prompt, "Kick out %s? ", pname (mynum));
      replace_input_handler (kick_out_yn);
      return;
  }
  else
  {
      while (*answer == ' ' || *answer == '\t')
	++answer;
      if (*answer == '\0')
      {
	  bprintf ("%s", cur_player->prompt);
	  return;
      }
      else if (*answer != 'y' && *answer != 'Y')
      {
	  bprintf ("Ok, bye then.\n");
	  quit_player ();
	  return;
      }
      else
      {   
	  p = players + plx;
	  cur = cur_player;
	  fd = cur->fil_des;
	  fp = cur->stream;
	  sin = cur->sin;
	  sin_len = cur->sin_len;
	  strcpy (host, cur->hostname);
	  cur->fil_des = p->fil_des;
	  cur->stream = p->stream;
	  cur->sin = p->sin;
	  cur->sin_len = p->sin_len;
	  strcpy (cur->hostname, p->hostname);
	  p->fil_des = fd;
	  p->stream = fp;
	  p->sin = sin;
	  p->sin_len = sin_len;
          p->linkdead = False;
          /* keep the same location as the old one */
          cur->hold_loc = True;
          p->hold_loc = True;
	  strcpy (p->hostname, host);
/*	  cur_player->iamon = False;*/
          strcpy(pname(mynum),"");
	  quit_player ();
	  ply = real_mynum;
	  setup_globals (plx);
	  do_motd (NULL);
	  setup_globals (ply);
	}
    }
}

void toggle_option(int option)
{   if (ststflg(mynum,option))
	sclrflg(mynum,option);
    else
	ssetflg(mynum,option);
}

void configure_player(char *in)
{
    if (in == NULL)
    {   /* Clear screen and print configuration */
	bprintf("\001C\003");
        bflush();
        bprintf("               &+wC&+w)  &+wC&*olored text            : %s\n"
		"               &+wB&+w)  &+wB&*linking text           : %s\n"
		"               &+wS&+w)  &+wS&*ounds                  : %s\n"
		"               &+wM&+w)  &*Compact &+wM&*ode            : %s\n",
		ststflg(mynum,SFL_COLOR) ?  "&+wOn&*" : "&+wOff&*",
		ststflg(mynum,SFL_NOBLINK)? "&+wOff&*": "&+wOn&*",
		ststflg(mynum,SFL_NOBEEP) ? "&+wOff&*": "&+wOn&*",
		ststflg(mynum,SFL_COMPACT) ? "&+wOn&*": "&+wOff&*");

	bprintf("               &+wA&+w)  &+wA&*utomatic Exits         : %s\n"
		"               &+wR&+w)  &+wR&*epeat messages         : %s\n"
		"               &+wE&+w)  &+wE&*mail lock              : %s\n"
		"               &+wO&+w)  &+wO&*ld Style Login         : %s\n",
		ststflg(mynum,SFL_AUTOEXIT) ? "&+wOn&*" : "&+wOff&*",
		ststflg(mynum,SFL_SAYBACK)  ? "&+wOn&*" : "&+wOff&*",
		ststflg(mynum,SFL_NOFINGER) ? "&+wOn&*" : "&+wOff&*",
		ststflg(mynum,SFL_OLDLOGIN) ? "&+wOn&*" : "&+wOff&*");

	bprintf("\n\n               &+wQ&+w)  &+wQ&*uit configuration.\n\nChoose option: ");
       
       replace_input_handler(configure_player);
    }
    else
    {   /* Read input */
        switch(*in) {
        /* Switch color on/off */
	case 'C':
	case 'c': toggle_option(SFL_COLOR); break;

        /* Switch blinking text on/off */
	case 'B':
	case 'b': toggle_option(SFL_NOBLINK); break;

        /* Switch beeps on/off */
	case 'S':
	case 's': toggle_option(SFL_NOBEEP); break;
        
        /* Switch autoexits function on/off */
	case 'A':
	case 'a': toggle_option(SFL_AUTOEXIT); break;

        /* Switch compact(newstyle) mode on/off */
	case 'M':
	case 'm': toggle_option(SFL_COMPACT); break;

        /* Switch sayback(hearback/tellback) function on/off */
	case 'R':
	case 'r': toggle_option(SFL_SAYBACK); break;

        /* Switch email protection on/off */
	case 'E':
	case 'e': toggle_option(SFL_NOFINGER); break;

  case 'O':
  case 'o': toggle_option(SFL_OLDLOGIN); break;
  
        /* Quit configuration menu. */
	case 'Q':
	case 'q': saveme();
                  give_options(NULL); 
                  return;
	default: /* Don nothing */
	}
	configure_player(NULL);
    }
}

void confirm_delete(char *yn)
{   if (yn == NULL)
    {   bprintf("&+wWarning:&* You have chosen to delete your character. this will mean you will"
                "      loose all your experience and quests and have to make a new character when"
                "      you want to log in again.\n");
        replace_input_handler(confirm_delete);
    }
    else if (tolower(*yn) == 'n')
    {   bprintf("Whew, that was close.\n");
        give_options(NULL);
        return;
    }  
    else if (tolower(*yn) == 'y')
    {   deluaf(pname(mynum));
        mudlog("UAF: %s deleted %s char",pname(mynum),his_or_her(mynum));
        crapup("Sorry to see you leave so soon.",CRAP_RETURN);
        return;
    }
    bprintf("Are you sure you want to delete your character [Y/N]: ");
}

void give_options(char *in)
{  if (in == NULL)
   {   bprintf("\001C\003");
       bflush();
       bprintf("\001f"LOGINMENU"\003");
       bprintf("&+wSelect an option &+w[&+wE&+L/&+wC&+L/&+wD&+L/&+wQ&+w]&+w: ");
       replace_input_handler(give_options);
       return;
   }
   else
   {   switch (*in) {
       case 'E':
       case 'e': 
		do_motd(NULL);
		break;
       case 'C':
       case 'c':
		configure_player(NULL);
		break;
       case 'D':
       case 'd':
		confirm_delete(NULL);
		break;
       case 'Q':
       case 'q': 
                strcpy(cur_player->prompt,cur_player->cprompt);
		saveme();
		crapup("Hope we will see you again in the near future.",CRAP_SAVE|CRAP_RETURN);
		break;
       case '\0':
		do_motd(NULL);
		break;
       default: bprintf("Invalid option\n");
		give_options(NULL);
		break;
       }
   }
}
		
void enter_vis(char *v)
{  int maxlev,lev;

   if (EMPTY (v) || v[0] =='\n') 
   {
      setpvis(mynum,0);
      talker();
   } 
   else
   {  maxlev = plev(mynum);
   
      if (v[0] == 'i' || v[0] == 'I')
      {   setpvis(mynum,maxlev);
          talker();
      } else
      {  lev = atoi(v);
         if (lev < 0)
         {  bprintf("Invalid level. Invis level must be between 0 and %d",
                    pvis(mynum));
            replace_input_handler(enter_vis);
         } 
         else if (lev > maxlev)
         {  bprintf ("Vis level too high, setting to %d\n",maxlev);
            lev = maxlev;
         }
         setpvis(mynum,lev);
         bprintf("Setting Visibility to %d.\n",lev);
         talker();
      }
   }
}

void do_news (char *cont)
{   if (cont == NULL)
    {   bprintf("\001f"NEWS"\003");
        if (plev(mynum) >= LVL_APPREN) 
        {
            bprintf(vismsg);
            replace_input_handler (enter_vis);
        } 
        else 
        {  bprintf(pwait);
           replace_input_handler (do_news);
        }
    }
    else 
      talker();    
}       

void do_motd (char *cont)
{ PERSONA p;
  
  if (getuaf (pname (mynum), &p))
  { setpname(mynum,p.p_name);
    cur_player->p_last_on = p.p_last_on;
    cur_player->last_cmd = cur_player->last_command = global_clock ;
  }
  if (cont == NULL)
    { bprintf("\001C\003");
      bflush();
      bprintf ("\001f" MOTD "\003");
      strcpy (cur_player->prompt, "Hit return: ");

#ifdef NO_NEWS
      if (plev(mynum) >= LVL_APPREN) 
      {
         bprintf(vismsg);
         replace_input_handler (enter_vis);
      } 
      else 
      {  bprintf(pwait);
         replace_input_handler (do_motd);
      }
    }
  else
  { 
      talker ();
  }
#else
       bprintf(pwait);
       replace_input_handler(do_motd);
  }
  else
     do_news(NULL);
#endif
}

void talker (void)
{ int k;
  char msg[80];
  char b[50];
  char buff1[200];
  char buff2[200];
  int  start;
  int  also_me;

  for (also_me = 0; also_me < max_players; also_me++)
  {   if (EQ(pname(also_me),pname(mynum)) && also_me != mynum)
      {    mudlog("CONN: Multiple entries for player %s",pname(mynum));
           p_crapup(also_me,"\t\tNo need to be on more than once.",CRAP_SAVE|CRAP_RETURN);
      }
  }
  
  setpwpn (mynum, -1);
  setphelping (mynum, -1);
  setpfighting (mynum, -1);
  setpsitting (mynum, 0);
  (void) strcpy(cur_player->prompt,cur_player->cprompt);
  sclrflg(mynum,SFL_DRUNK);
  sclrflg(mynum,SFL_AWAY);
  sclrflg(mynum,SFL_KLOCKED);
  sclrflg(mynum,SFL_DISTRACTED);
  psetmsk(mynum,PFL_QUICKWRITER);
  setpdrunk(mynum,0);

  bprintf ("\001C\003");
  bflush ();

  insert_entry (mob_id (mynum), mynum, &id_table);
  
  if (ptstflg (mynum, PFL_CLONE)
      && ((k = get_zone_by_name (pname (mynum))) < 0 || ztemporary (k)))
  {
     load_zone (pname (mynum), NULL, NULL, NULL, NULL, NULL, NULL);
  }

  if (!cur_player->hold_loc)
  {   start = get_rand_start();

      setploc(mynum,exists(phome(mynum)) ?  phome(mynum) : start);
  }

  cur_player->iamon = True;
  fetchprmpt (mynum);
  
  cur_player->last_cmd = cur_player->p_last_comm = cur_player->p_last_spell = time (0);
  cur_player->last_command = time(0);
  /* Clear the string buffer */
  strbuf[0] = '\0';
  stp = 0;
  debug_level = 1;

  if (plev(mynum) >= LVL_APPREN)
  {  if (pvis(mynum) < (LVL_GOD+1))
       mudlog("CONN: Entry %s [lev %d][fd: %d] from %s",pname(mynum),plev(mynum),
            cur_player->fil_des,cur_player->realhostname);
  }
  else
  {  mudlog ("CONN: Entry %s [lev %d, scr %d][fd: %d]",
             pname (mynum), plev (mynum), pscore (mynum),cur_player->fil_des);
     mudlog ("CONN: %s connected from %s",pname(mynum),cur_player->realhostname);
  }
  
  debug_level = 2;
 
  send_msg (DEST_ALL, MODE_BRACKET| MODE_QUIET | MP (PFL_SHUSER) | MODE_PFLAG,
	    Max(pvis (mynum), LVL_APPREN), LVL_ARCHWIZARD, mynum, NOBODY,
	    "%s &+w[%s]&+w has entered the game in %s&+w]&*\n&+w[&+w%s is level %d and has a visibility of %d",
	    pname (mynum), cur_player->hostname, xshowname (buff2, ploc (mynum)), pname(mynum), plev(mynum), pvis(mynum));
  
  send_msg (DEST_ALL, MODE_BRACKET| MODE_QUIET | MP (PFL_SHUSER) | MODE_PFLAG,
	    Max(pvis (mynum), LVL_ARCHWIZARD), LVL_MAX, mynum, NOBODY,
	    "%s &+w[%s]&+w has entered the game in %s&+w]&*\n&+w[&+w%s is level %d and has a visibility of %d",
	    pname (mynum), cur_player->realhostname, xshowname (buff2, ploc (mynum)), pname(mynum), plev(mynum), pvis(mynum));

  debug_level = 3;
  
  send_msg (DEST_ALL, MODE_BRACKET | MODE_QUIET | MP (PFL_SHUSER) | MODE_NPFLAG,
	    Max(pvis (mynum), LVL_APPREN), LVL_MAX, mynum, NOBODY,
	    "%s has entered the game in %s&+w]&*\n&+w[&+w%s is level %d and has a visibility of %d",
	    pname (mynum), xshowname (buff2, ploc (mynum)), pname(mynum), plev(mynum), pvis(mynum));


  debug_level = 4;
  trapch (ploc (mynum));
 
  debug_level = 5; 
  if ((k = the_world->w_lock) > plev (mynum))
  {
      sprintf (msg,"I'm sorry, the game is currently %slocked - please try later.",
	       lev2s (b, k, 0));
      crapup (msg, NO_SAVE);
      return;
  }
  else if (k != 0)
  {
      bprintf ("&+w= STATUS:&* The game is currently &+w%s&*locked.\n", lev2s (buff1, k, 0));
  }
  
  debug_level = 6;
  if (the_world->w_peace)
  {
      bprintf ("&+w= STATUS:&* Everything is peaceful.\n");
  }
  
  debug_level = 7;
  if (plev (mynum) >= LVL_APPREN && the_world->w_mob_stop != 0)
  {
      bprintf ("&+w= STATUS:&* Mobiles are STOPed.\n");
  }
  
  debug_level = 8;
  check_files ();		/* new mailer */
  
  debug_level = 9;
  
  send_msg (ploc (mynum), 0, pvis (mynum), LVL_MAX, mynum, NOBODY,
	    "%s\n", build_setin (mynum,buff1, cur_player->setqin, pname (mynum), NULL));
  
  debug_level = 10;

  setplayerfunc(mynum);
  calib_questpoints(mynum);
  get_command (NULL);
}


void get_command (char *cmd)
{ Boolean x;
  static char dbuffer[(MAX_COM_LEN * 2) + 5];
/*  static char str[32];*/
  
  if (cmd != NULL)
  {
      bzero (dbuffer, MAX_COM_LEN * 2);
      safe_strcpy (dbuffer, cmd);
      strcpy (rawbuf, cmd);
      
      Game_Com (dbuffer, True);
      
      /* Check if he is using same command input handler */
      
      x = (cur_player->inp_handler->inp_handler != get_command);
      if (x || cur_player->quit_next >= -1)
	return;
  }
  else  
  {
    x = (cur_player->inp_handler->inp_handler != get_command);
  }
  bprintf("\r%s&*",build_prompt(real_mynum));
  if (x)
    replace_input_handler (get_command);
}



void quit_player (void)
{
  if (cur_player->quit_next == -2)
    {
      cur_player->quit_next = quit_list;
      quit_list = real_mynum;
    }
}