/***************************************************************************   
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
 *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
 *                                                                         *
 *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
 *  Chastain, Michael Quan, and Mitchell Tse.                              *
 *                                                                         *
 *  In order to use any part of this Merc Diku Mud, you must comply with   *
 *  both the original Diku license in 'license.doc' as well the Merc       *
 *  license in 'license.txt'.  In particular, you may not remove either of *
 *  these copyright notices.                                               *
 *                                                                         *
 *  Much time and thought has gone into this software and you are          *
 *  benefitting.  We hope that you share your changes too.  What goes      *
 *  around, comes around.                                                  *
 ***************************************************************************/

/***************************************************************************
*	ROM 2.4 is copyright 1993-1998 Russ Taylor			   *
*	ROM has been brought to you by the ROM consortium		   *
*	    Russ Taylor (rtaylor@hypercube.org)				   *
*	    Gabrielle Taylor (gtaylor@hypercube.org)			   *
*	    Brian Moore (zump@rom.org)					   *
*	By using this code, you have agreed to follow the terms of the	   *
*	ROM license, in the file Rom24/doc/rom.license			   *
***************************************************************************/

#if defined(macintosh)
#include <types.h>
#include <time.h>
#else
#include <sys/types.h>
#include <sys/time.h>
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "merc.h"
#include "recycle.h"

BAN_DATA *ban_list;

void
save_bans (void)
{
  BAN_DATA *pban;
  FILE *fp;
  bool found = FALSE;

  fclose (fpReserve);
  if ((fp = fopen (BAN_FILE, "w")) == NULL)
    {
      perror (BAN_FILE);
    }

  for (pban = ban_list; pban != NULL; pban = pban->next)
    {
      if (IS_SET (pban->ban_flags, BAN_PERMANENT))
	{
	  found = TRUE;
	  fprintf (fp, "%-20s %-2d %s\n", pban->name, pban->level,
		   print_flags (pban->ban_flags));
	}
    }

  fclose (fp);
  fpReserve = fopen (NULL_FILE, "r");
  if (!found)
    unlink (BAN_FILE);
}

void
load_bans (void)
{
  FILE *fp;
  BAN_DATA *ban_last;

  if ((fp = fopen (BAN_FILE, "r")) == NULL)
    return;

  ban_last = NULL;
  for (;;)
    {
      BAN_DATA *pban;
      if (feof (fp))
	{
	  fclose (fp);
	  return;
	}

      pban = new_ban ();

      pban->name = str_dup (fread_word (fp));
      pban->level = fread_number (fp);
      pban->ban_flags = fread_flag (fp);
      fread_to_eol (fp);

      if (ban_list == NULL)
	ban_list = pban;
      else
	ban_last->next = pban;
      ban_last = pban;
    }
}

bool
check_ban (char *site, int type)
{
  BAN_DATA *pban;
  char host[MAX_STRING_LENGTH];

  strcpy (host, capitalize (site));
  host[0] = LOWER (host[0]);

  for (pban = ban_list; pban != NULL; pban = pban->next)
    {
      if (!IS_SET (pban->ban_flags, type))
	continue;

      if (IS_SET (pban->ban_flags, BAN_PREFIX)
	  && IS_SET (pban->ban_flags, BAN_SUFFIX)
	  && strstr (pban->name, host) != NULL)
	return TRUE;

      if (IS_SET (pban->ban_flags, BAN_PREFIX)
	  && !str_suffix (pban->name, host))
	return TRUE;

      if (IS_SET (pban->ban_flags, BAN_SUFFIX)
	  && !str_prefix (pban->name, host))
	return TRUE;
    }

  return FALSE;
}


void
ban_site (CHAR_DATA * ch, char *argument, bool fPerm)
{
  char buf[MAX_STRING_LENGTH], buf2[MAX_STRING_LENGTH];
  char arg1[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH];
  char *name;
  BUFFER *buffer;
  BAN_DATA *pban, *prev;
  bool prefix = FALSE, suffix = FALSE;
  int type;

  argument = one_argument (argument, arg1);
  argument = one_argument (argument, arg2);

  if (arg1[0] == '\0')
    {
      if (ban_list == NULL)
	{
	  send_to_char ("No sites banned at this time.\n\r", ch);
	  return;
	}
      buffer = new_buf ();

      add_buf (buffer, "Banned sites  level  type     status\n\r");
      for (pban = ban_list; pban != NULL; pban = pban->next)
	{
	  sprintf (buf2, "%s%s%s",
		   IS_SET (pban->ban_flags, BAN_PREFIX) ? "*" : "",
		   pban->name,
		   IS_SET (pban->ban_flags, BAN_SUFFIX) ? "*" : "");
	  sprintf (buf, "%-12s    %-3d  %-7s  %s\n\r",
		   buf2, pban->level,
		   IS_SET (pban->ban_flags, BAN_NEWBIES) ? "newbies" :
		   IS_SET (pban->ban_flags, BAN_PERMIT) ? "permit" :
		   IS_SET (pban->ban_flags, BAN_ALL) ? "all" : "",
		   IS_SET (pban->ban_flags, BAN_PERMANENT) ? "perm" : "temp");
	  add_buf (buffer, buf);
	}

      page_to_char (buf_string (buffer), ch);
      free_buf (buffer);
      return;
    }

  /* find out what type of ban */
  if (arg2[0] == '\0' || !str_prefix (arg2, "all"))
    type = BAN_ALL;
  else if (!str_prefix (arg2, "newbies"))
    type = BAN_NEWBIES;
  else if (!str_prefix (arg2, "permit"))
    type = BAN_PERMIT;
  else
    {
      send_to_char ("Acceptable ban types are all, newbies, and permit.\n\r",
		    ch);
      return;
    }

  name = arg1;

  if (name[0] == '*')
    {
      prefix = TRUE;
      name++;
    }

  if (name[strlen (name) - 1] == '*')
    {
      suffix = TRUE;
      name[strlen (name) - 1] = '\0';
    }

  if (strlen (name) == 0)
    {
      send_to_char ("You have to ban SOMETHING.\n\r", ch);
      return;
    }

  prev = NULL;
  for (pban = ban_list; pban != NULL; prev = pban, pban = pban->next)
    {
      if (!str_cmp (name, pban->name))
	{
	  if (pban->level > get_trust (ch))
	    {
	      send_to_char ("That ban was set by a higher power.\n\r", ch);
	      return;
	    }
	  else
	    {
	      if (prev == NULL)
		ban_list = pban->next;
	      else
		prev->next = pban->next;
	      free_ban (pban);
	    }
	}
    }

  pban = new_ban ();
  pban->name = str_dup (name);
  pban->level = get_trust (ch);

  /* set ban type */
  pban->ban_flags = type;

  if (prefix)
    SET_BIT (pban->ban_flags, BAN_PREFIX);
  if (suffix)
    SET_BIT (pban->ban_flags, BAN_SUFFIX);
  if (fPerm)
    SET_BIT (pban->ban_flags, BAN_PERMANENT);

  pban->next = ban_list;
  ban_list = pban;
  save_bans ();
  sprintf (buf, "%s has been banned.\n\r", pban->name);
  send_to_char (buf, ch);
  return;
}

void
do_ban (CHAR_DATA * ch, char *argument)
{
  ban_site (ch, argument, FALSE);
}

void
do_permban (CHAR_DATA * ch, char *argument)
{
  ban_site (ch, argument, TRUE);
}

void
do_allow (CHAR_DATA * ch, char *argument)
{
  char arg[MAX_INPUT_LENGTH];
  char buf[MAX_STRING_LENGTH];
  BAN_DATA *prev;
  BAN_DATA *curr;

  one_argument (argument, arg);

  if (arg[0] == '\0')
    {
      send_to_char ("Remove which site from the ban list?\n\r", ch);
      return;
    }

  prev = NULL;
  for (curr = ban_list; curr != NULL; prev = curr, curr = curr->next)
    {
      if (!str_cmp (arg, curr->name))
	{
	  if (curr->level > get_trust (ch))
	    {
	      send_to_char
		("You are not powerful enough to lift that ban.\n\r", ch);
	      return;
	    }
	  if (prev == NULL)
	    ban_list = ban_list->next;
	  else
	    prev->next = curr->next;

	  free_ban (curr);
	  sprintf (buf, "Ban on %s lifted.\n\r", arg);
	  send_to_char (buf, ch);
	  save_bans ();
	  return;
	}
    }

  send_to_char ("Site is not banned.\n\r", ch);
  return;
}