TinyMAZE/
TinyMAZE/config/
TinyMAZE/doc/
TinyMAZE/run/msgs/
TinyMAZE/src/
TinyMAZE/src/db/
TinyMAZE/src/ident/
TinyMAZE/src/io/
TinyMAZE/src/prog/
TinyMAZE/src/softcode/
TinyMAZE/src/util/
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <ctype.h>
#include "config.h"
#include "externs.h"
#include "db.h"
#include "mail.h"
#include "commands.h"
#include "plugins.h"

static void info_msgs P((OBJ *));
static void info_cpu P((OBJ *));
static void info_mail P((OBJ *));
static void info_pid P((OBJ *));
static void info_memory P((OBJ *));

void do_info(OBJ *player, char *arg1)
{
  int i;
  struct
  {
    char *name;
    void (*func)();
  } list[] = { {"db",     info_db},
               {"funcs",  info_funcs},
               {"msgs",   info_msgs},
               {"cpu",    info_cpu},
               {"io",     info_io},
               {"mail",   info_mail},
               {"memory", info_memory},
               {"pid",    info_pid},
               {"stack",  info_stack},
               {NULL,     NULL}
             };

  if(!*arg1)
  {
    notify(player, "|+W|Valid Categories:");
    for(i = 0;list[i].name;i++)
      notify(player, tprintf("|+B|  %s", list[i].name));
    return;
  }

  for(i = 0;list[i].name;i++)
  {
    if(string_prefix(list[i].name, arg1))
    {
      list[i].func(player);
      return;
    }
  }

  notify(player, "|+W|Valid Categories:");
  for(i = 0;list[i].name;i++)
    notify(player, tprintf("|+B|  %s", list[i].name));
}

static void info_msgs(OBJ *player)
{
  extern int num_bad_cmd_msgs;
  extern char *bad_cmd_msgs[];
  extern int num_perm_denied;
  extern char *perm_messages[];
  int i;

  notify(player, "|+W|Huh? Messages:");
  for(i = 0;i < num_bad_cmd_msgs;++i)
    notify(player, tprintf("  |+B|%s", bad_cmd_msgs[i]));

  notify(player, "|+W|Permission Denied Messages:");
  for(i = 0;i < num_perm_denied;i++)
    notify(player, tprintf("  |+R|%s", perm_messages[i]));
}

void info_cpu(OBJ *player)
{
  FILE *fp;
  char buf[80];

  if((fp = fopen("/proc/cpuinfo", "r")) == NULL)
    return;

  while(!feof(fp))
  {
    fgets(buf, sizeof(buf), fp);
    if(feof(fp))
      break;
    buf[strlen(buf)-1] = '\0';
    notify(player, buf);
  }
  fclose(fp);
}

void do_whois(OBJ *player, char *arg)
{
  OBJ *who;

  if(!*arg)
  {
    notify(player, "Who is who?");
    return;
  }

  who = match_player(NULL, arg);
  if(!who)
  {
    notify(player, no_match(arg));
    return;
  }

  notify(player, tprintf("Who is %s?", unparse_object(player, who)));

  if(atoi(atr_get(who, "CONNECTS")))
    notify(player, tprintf("%s has connected %d times.", name(who),
      atoi(atr_get(who, "CONNECTS"))));
  else
    notify(player, tprintf("%s has never connected.", name(who)));

  if(*atr_get(who, "RNAME"))
    notify(player, tprintf("%s real name is %s.", poss(who),
      atr_get(who, "RNAME")));

  if(*atr_get(who, "ALIAS"))
    notify(player, tprintf("Alias: %s", atr_get(who, "ALIAS")));

  if(*atr_get(who, "WHOIS"))
    notify(player, tprintf("Whois: %s", atr_get(who, "WHOIS")));
}

static char *unparse_mail_flags(MAIL *msg)
{
  char buf[4096];

  if(msg->flags & MF_NEW)
    strcpy(buf, "NEW ");
  else if(msg->flags & MF_READ)
    strcpy(buf, "READ ");
  if(msg->flags & MF_MAILLIST)
    strcpy(buf+strlen(buf), "MAILLIST ");
  if(msg->flags & MF_PROTECTED)
    strcpy(buf+strlen(buf), "PROTECTED ");

  *(buf+strlen(buf)-1) = '\0';
  return(stack_string_alloc(buf, 0));
}

void info_mail(OBJ *player)
{
  MAIL *m;
  OBJ *o;
  int new, read, unread, mlist, protected;
  int total;
  MAIL *oldest = NULL, *newest = NULL;
  OBJ *oldest_obj = NULL, *newest_obj = NULL;
  char *msg;

  new = read = unread = mlist = total = protected = 0;

  for(o = player_list;o;o = o->next)
  {
    for(m = o->mail;m;m = m->next)
    {
      if(m->flags & MF_READ)
        read++;
      else if(m->flags & MF_NEW)
        new++;
      else
        unread++;

      if(m->flags & MF_MAILLIST)
        mlist++;
      if(m->flags & MF_PROTECTED)
        protected++;

      if(!oldest || m->date < oldest->date)
      {
        oldest = m;
        oldest_obj = o;
      }
      if(!newest || m->date > newest->date)
      {
        newest = m;
        newest_obj = o;
      }

      total++;
    }
  }

  notify(player, tprintf("|+B|maildb size  |+W|: |+C|%s",
    comma(tprintf("%ld", file_size(config.maildb_name)))));
  notify(player, tprintf("|+B|max_mail_age |+W|: |+C|%s",
    (!config.max_mail_age)?
    "Feature Disabled":format_time(config.max_mail_age)));
  if(config.max_mail_age)
    notify(player, tprintf("|+B|Mail Clear In|+W|: |+C|%s",
      time_format(next_mail_clear-now, 1)));

  if(oldest || newest)  /* If one is set, the other one is */
  {
    msg = unparse_mail_flags(oldest);
    notify(player,
      tprintf("\n|+B|Oldest MSG|+W|: |+C|%s |+W|(|+Y|%s|+W|)",
      mktm(oldest->date, "D", player), format_time(now-oldest->date)));
    notify(player, tprintf("  |+B|Who  |+W|: %s",
      unparse_object(player, oldest_obj)));
    notify(player, tprintf("  |+B|Flags|+W|: |+C|%s", msg));

    msg = unparse_mail_flags(newest);
    notify(player,
      tprintf("\n|+B|Newest MSG|+W|: |+C|%s |+W|(|+Y|%s|+W|)",
      mktm(newest->date, "D", player), format_time(now-newest->date)));
    notify(player, tprintf("  |+B|Who  |+W|: %s",
      unparse_object(player, newest_obj)));
    notify(player, tprintf("  |+B|Flags|+W|: |+C|%s", msg));
  }

  notify(player, tprintf("\n|+B|Total Messages       |+W|: |+C|%s",
    comma(tprintf("%d", total))));
  notify(player, tprintf("|+B|Read Messages        |+W|: |+C|%s",
    comma(tprintf("%d", read))));
  notify(player, tprintf("|+B|Unread Messages      |+W|: |+C|%s",
    comma(tprintf("%d", unread))));
  notify(player, tprintf("|+B|New Messages         |+W|: |+C|%s",
    comma(tprintf("%d", new))));
  notify(player, tprintf("|+B|Mailing List Messages|+W|: |+C|%s",
    comma(tprintf("%d", mlist))));
  notify(player, tprintf("|+B|Protected Messages   |+W|: |+C|%s",
    comma(tprintf("%d", protected))));
}

void info_pid(OBJ *player)
{
  char buf[1024];
  FILE *fp;
  char *p;

  if((fp = fopen("/proc/self/status", "r")) == NULL)
  {
    notify(player,
      "'@info pid' will not work on this server because it doesn't support the /proc filesystem.");
    return;
  }

  while(!feof(fp))
  {
    fgets(buf, sizeof(buf), fp);
    if(!strncmp(buf, "VmSize", 6))
      break;
  }

  if(feof(fp))
  {
    fclose(fp);
    notify(player, "Error reading from /proc filesystem!");
    return;
  }

  fclose(fp);

  *(buf+strlen(buf)-1) = '\0';

  for(p = buf;*p && !isspace(*p);p++);
  while(isspace(*p))
    p++;

  notify(player, "|+Y|NetMAZE Process ID info:");
  notify(player, tprintf("  |+B|PID |+W|: |+C|%d", getpid()));
  notify(player, tprintf("  |+B|Size|+W|: |+C|%s", p));
}

static void info_memory(OBJ *player)
{
  struct mallinfo meminfo;

  meminfo = mallinfo();

  notify(player, tprintf("|+B|Total size of allocated memory|+W|: |+C|%s",
    comma(tprintf("%d", meminfo.uordblks))));
}

void do_commands(OBJ *player)
{
  CS *c;
  char buf[256];
  int ctr = 0;
  int i;

  notify(player, tprintf("|+G|%s ARGUMENTS", my_ljust("NAME", 20)));

  for(c = command_set;c->name;c++)
  {
    if(Guest(player))
    {
      for(i = 0;guest_command_set[i];++i)
        if(guest_command_set[i] == c->func)
          break;
      if(!guest_command_set[i])
        continue;           /* They can't use this command */
    }

    ctr++;

    if(c->flags & ARG1)
      strcpy(buf, "arg1 ");
    else if(c->flags & PURE)
      strcpy(buf, "pure ");
    else
      *buf = '\0';
    if(c->flags & ARG2)
      strcat(buf, "arg2");
    else if(c->flags & PURE2)
      strcat(buf, "pure2");

    if(!*buf)
      strcpy(buf, "none");

    notify(player, tprintf("|+B|%s |+Y|%s", my_ljust(c->name, 20), buf));
  }

  if(!ctr)
    notify(player, "No commands available.");
  else
    notify(player, tprintf("|+C|%d |+B|command%s available.",
    ctr, check_plural(ctr, "", "s")));

  notify(player,
    "Use the '+plugins' command to get a list of additional commands.");
}