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/
#define DEBUG_C
#include <unistd.h>
#include <sys/file.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include "kernel.h" 
#include "global.h"
#include "mudmacros.h"
#include "colors.h"
#include "debugger.h"
#include "admin.h"
#include "mud.h"
#include "bprintf.h"
#include "main.h"
#include "mobile.h"
#include "cmd_handlers.h"
#include "mail.h"
#include "sflags.h"
#include "log.h"
#include "special.h"
#include "pflags.h"
#include "parse.h"
#include "uaf.h"

#define MAX_DEBUG_CMD 7

static char *debug_cmds[] = {
	"help",		"sockets",	"globals",	"slots",
        "handlers",	"clear",	"verbs",	"fddump",
        TABLE_END
	};

IHMAPPING(i_handlers) = {
  { "get command (default handler)",		get_command},
  { "debugger (online debug system)",		debugger},
  { "get_email (login: getting email)",		get_email},
  { "get_pname1 (login: Getting name)",		get_pname1},
  { "get_pname2 (login: Name confirmation)",	get_pname2},
  { "get_new_pass1 (Setting password)",		get_new_pass1},
  { "get_new_pass2 (Checking new password)",	get_new_pass2},
  { "get_passwd1 (login: getting password)",	get_passwd1},
  { "file_pager (viewing paged file)",		file_pager},
  { "enter_vis (login: setting vis level)",	enter_vis},
  { "do_motd (login: show message of the day)",	do_motd},
  { "klockcom (keyboard locked AFK)",		klockcom},
  { "unveilcom (unveil attempt)",		unveilcom},
  { "frobcom (promotion command)",		frobcom},
  { "mail_menu (mail: selection menu)",		mail_menu},
  { "write_mail (mail: adressing Message)",	write_mail},
  { "input_mail (mail: writing message body)",	input_mail},
  { "give_options (login: Main menu)",		give_options},
  { "configure_player (login: Configure menu)",	configure_player},
  { "get_gender (login of new player)",		get_gender}
};
	
void socket_stat();
void globals_stat();
void player_slots();
void handlers();
void clearstuff();
void verbcommands();
void dump_fd_descs(void);

A_COMMAND(debugstart)
{  if (ptstflg(mynum,PFL_DEBUG))
      debugger(NULL);
   else
      erreval();
}

void debugger(char *str)
{  int num = 0;
   char temp[MAX_COM_LEN];

   if (!str)  /* Initialise for use */
   {   strcpy(cur_player->cprompt,cur_player->prompt);
       strcpy(cur_player->prompt,"&+wDEBUG>&*");
       bprintf("&+wMarty's Debugger - V1.0\n&+w%s\n&*",DASHLINE);
       bprintf("%s",cur_player->prompt);
       push_input_handler(debugger);
   } else
   {  while (!EQ(str,"quit"))
      { 
          sscanf(str," %s ",temp);
          num = tlookup(temp,debug_cmds);
          switch (num) {
          case 0 : bprintf("debug [help|sockets|globals|slots|handlers|quit]\n"
                           "\n"
                           "&+whelp     &*: This message\n"
                           "&+wsockets  &*: The sockets that are occupied\n"
                           "&+wglobals  &*: Internal globals (other thans global command)\n"
                           "&+wslots    &*: View players slots\n"
                           "&+whandlers &*: View the command handlers of the players\n"
                           "&+wquit     &*: End debug session\n");
                   break;
          case 1 : socket_stat();
                   break;
          case 2 : globals_stat();
                   break;
          case 3 : player_slots();  
                   break;
          case 4 : handlers();
                   break;
          case 5 : clearstuff(str);
                   break;
          case 6 : verbcommands();
                   break;
	  case 7:  dump_fd_descs();
		   break;
          default: bprintf("Unknown option\n");
                   break;
          }
          bprintf("%s",cur_player->prompt);
          return;
      }
      strcpy(cur_player->prompt,cur_player->cprompt);
      pop_input_handler();
      bprintf("Ended debug session\n%s",cur_player->prompt);
      sclrflg(mynum,SFL_DISTRACTED);
      return;
   }
}

void socket_stat()
{  socinfo();
}

void globals_stat()
{  
   bprintf("\n&+w=======&+w[Driver variables]&+w=====================================================&*\n");
   bprintf("Program Name  = %s\n",progname);
   bprintf("Data directory= %s\n",data_dir);
   bprintf("Hostname      = %s\n",my_hostname);
   bprintf("Environment   = %s\n",*envp);
   bprintf("Process ID    = %d    Environment pointer = %p\n",getpid(),envp);
   bprintf("Max_players   = %d\n",max_players);
   bprintf("&+w%s&*\n",DASHLINE);
   bprintf("&+wDyrt global variables&*\n");
   bprintf("STRBUF = %-70s\n",strbuf);
   bprintf("WORDBUF= %-70s\n",wordbuf);
   bprintf("RAWBUF = %-70s\n",rawbuf);
   bprintf("ITEM1  = %-70s\n",item1);
   bprintf("ITEM2  = %-70s\n",item2);
   bprintf("&+w%s&*\n",DASHLINE);
   bprintf("Mynum    : %3d              Real mynum: %3d\n",mynum,real_mynum);
   bprintf("Quit list: %d\n",quit_list);   
   bprintf("Numchars : %4d          char_array_len: %4d    num_const_chars: %4d\n",
            numchars,char_array_len,num_const_chars);
   bprintf("Numobs   : %4d          obj_array_len : %4d    num_const_obs  : %4d\n",
            numobs,obj_array_len,num_const_obs);
   bprintf("Numzon   : %4d          zon_array_len : %4d    num_const_zon  : %4d\n",
            numzon,zon_array_len,num_const_zon);
   bprintf("verbnum  : %3d      ob1: %4d      ob2: %4d     pl1: %4d      pl2: %4d\n",
            verbnum,ob1,ob2,pl1,pl2);
   bprintf("&+w%s&*\n",DASHLINE);
}  

void player_slots()
{  int x;

   bprintf("&+w===========&+w[Name]&+w====&+w[Ploc]&+w====&+w[ FD ]&+w====&+w[Stream                 ]&+w==&*\n");
   for (x=0; x < max_players; x++)
   {  bprintf("SLOT %2d: %-7s      %4d    %2d    \n",
       x,(EMPTY(pname(x))? "  <EMPTY>" : pname(x)),ploc(x),players[x].fil_des
       /*,players[x].inp_buffer_p*/); 
   }
   bprintf("&+=====================================================================&*\n");
}

void verbcommands()
{  
   Print_CmdTable();
}

void handlers()
{  int plx=0;
   int i;
   Boolean found=False;
 
   bprintf("&+w[Player]&+w==&+w[Handler]&+w==============================================\n");
   for (plx=0; plx <max_players;plx++)
   {  if (players[plx].inp_handler)
      {  bprintf("%-10s",(EMPTY(pname(plx)) ? "*tcp*" : pname(plx)));
         
         found = False;
         for (i=0;i < IHSIZE(i_handlers); i++)
         {  if (phandler(plx) == i_handlers[i].func)
            {   bprintf("%s\n",i_handlers[i].hand_desc);
                found = True;
                continue;
            }
         }
         if (!found)
            bprintf("Unknown input handler\n");
      }
   }
   bprintf("&+w=================================================================\n");
}


void clearstuff(char *str)
{  
   int   identify;

   if (sscanf(str,"clear slot %d",&identify)!=2)
   {  bprintf("Clear what slot?\n");
      return;
   }
   if (identify >= max_players || identify < 0)
   {  bprintf("Slot number must be between 0 and %d.\n",max_players);
      return;
   }
   if (players[identify].iamon)
   {  bprintf("Slot is currently in use. Please use killsoc or disconnect.\n");
      return;
   }
   strcpy(pname(identify),"\0\0\0\0"); /* make it REALLY clear */
   if (players[identify].fil_des > 0)
   {   /* Uh oh .. some kind of open file error.\n */
       quit_player();
       if (players[identify].fil_des > 0)
          bprintf("Unable to close file descriptor.\n");
   }
   setploc(identify,0);
   if (players[identify].stream == NULL)
      fclose(players[identify].stream);
   players[identify].stream = NULL;
}

char *get_fd_type(int fd)
{   extern int main_socket;
    extern int dnsfd;
    extern int aberfd;
    extern fd_set sockets_fds;

    int i;

    if (fd == main_socket)
       return "Listen Socket";
    else if (fd == dnsfd || fd == aberfd)
       return "Static socket";

    for (i = 0; i < max_players; i++)
      if (fd == players[i].fil_des)
         return "User Socket";
  
    if (FD_ISSET(i,&sockets_fds))
       return "Socket";
 
    if (fd == 2)
       return "File"; 
    if (fd == 4)
       return "GDBM-File";

    return "Unknown";
}

char *get_fd_name(int fd)
{  extern int main_socket;
   extern int dnsfd;
   extern int aberfd;
   extern int syslogfd;
   static char m[20];
   int i;


    if (fd == main_socket)
       return "Main Port";
    else if (fd == dnsfd)
       return "DNS Resolver";
    else if (fd == aberfd)
       return "AberChat";
    else if (fd == syslogfd)
       return "Syslog";
 
    switch (fd) {
    case 0: if (main_socket == 0)
               return "Main Port";
            else
               return "StdIn";
    /*case 1: return "StdOut";*/
    case 2: return "LogFile";
    case 4: return "PlayerFile";
    default:
    }

    for (i=0; i < max_players; i++)
    {   if (players[i].fil_des == fd)
        {   if (*pname(i) == '\0')
            {  sprintf(m,"TCP[%d]",i);
               return m;
            }
            else
                return pname(i); 
        }
    }
 
    return "Unknown";
}  

void dump_fd_descs(void)
{   extern int width;
    int    i;
    struct stat s;
    char *sa,*sm,*sc;

    
    bprintf("&+w FD  Description  Last Access   Last Mod  Last Change\n&+w%s&*\n",DOUBLELINE);
    for (i = 0; i < width; i++)
    {   if (fstat(i,&s) == 0)
        {   sa = sec_to_hhmmss(global_clock - s.st_atime);
            sm = sec_to_hhmmss(global_clock - s.st_mtime);
            sc = sec_to_hhmmss(global_clock - s.st_ctime);
            bprintf("&+w[&+w%.2d&+w] %-10.10s     &+w%-8.8s    &+w%-8.8s    &+w%-8.8s &+w%s\n",i,get_fd_name(i),sa,sm,sc,get_fd_type(i));
        }
    }
    bprintf("&+w%s&*\n",DOUBLELINE);
}