muddy/
muddy/CVS/
muddy/area/
muddy/area/CVS/
muddy/clans/CVS/
muddy/classes/CVS/
muddy/doc/
muddy/doc/CVS/
muddy/etc/CVS/
muddy/etc/i3/
muddy/etc/i3/CVS/
muddy/imc/CVS/
muddy/lang/CVS/
muddy/licenses/CVS/
muddy/msgdb/CVS/
muddy/new/CVS/
muddy/notes/
muddy/player/
muddy/races/CVS/
muddy/religions/CVS/
muddy/src/CVS/
muddy/src/comm/CVS/
muddy/src/db/CVS/
muddy/src/intermud/
muddy/src/intermud/CVS/
muddy/src/irc/CVS/
muddy/src/olc/CVS/
/* $Id: ban.c,v 1.666 2004/09/20 10:50:15 shrike Exp $  */

/************************************************************************************
 *    Copyright 2004 Astrum Metaphora consortium                                    *
 *                                                                                  *
 *    Licensed under the Apache License, Version 2.0 (the "License");               *
 *    you may not use this file except in compliance with the License.              *
 *    You may obtain a copy of the License at                                       *
 *                                                                                  *
 *    http://www.apache.org/licenses/LICENSE-2.0                                    *
 *                                                                                  *
 *    Unless required by applicable law or agreed to in writing, software           *
 *    distributed under the License is distributed on an "AS IS" BASIS,             *
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.      *
 *    See the License for the specific language governing permissions and           *
 *    limitations under the License.                                                *
 *                                                                                  *
 ************************************************************************************/
/************************************************************************************
 *     ANATOLIA 2.1 is copyright 1996-1997 Serdar BULUT, Ibrahim CANPUNAR           *
 *     ANATOLIA has been brought to you by ANATOLIA consortium                      *
 *       Serdar BULUT {Chronos}         bulut@rorqual.cc.metu.edu.tr                *
 *       Ibrahim Canpunar  {Asena}      canpunar@rorqual.cc.metu.edu.tr             *
 *       Murat BICER  {KIO}             mbicer@rorqual.cc.metu.edu.tr               *
 *       D.Baris ACAR {Powerman}        dbacar@rorqual.cc.metu.edu.tr               *
 *     By using this code, you have agreed to follow the terms of the               *
 *     ANATOLIA license, in the file Anatolia/anatolia.licence                      *
 ***********************************************************************************/

/************************************************************************************
 *  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-1995 Russ Taylor                                  *
*       ROM has been brought to you by the ROM consortium                           *
*           Russ Taylor (rtaylor@pacinfo.com)                                       *
*           Gabrielle Taylor (gtaylor@pacinfo.com)                                  *
*           Brian Moore (rom@rom.efn.org)                                           *
*       By using this code, you have agreed to follow the terms of the              *
*       ROM license, in the file Rom24/doc/rom.license                              *
*************************************************************************************/

/************************************************************************************
 * Copyright (c) 1998 fjoe <fjoe@iclub.nsu.ru>                                      *
 * All rights reserved.                                                             *
 *                                                                                  *
 * Redistribution and use in source and binary forms, with or without               *
 * modification, are permitted provided that the following conditions               *
 * are met:                                                                         *
 * 1. Redistributions of source code must retain the above copyright                *
 *    notice, this list of conditions and the following disclaimer.                 *
 * 2. Redistributions in binary form must reproduce the above copyright             *
 *    notice, this list of conditions and the following disclaimer in the           *
 *    documentation and/or other materials provided with the distribution.          *
 *                                                                                  *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND           *
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE            *
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE       *
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE          *
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL       *
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS          *
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)            *
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT       *
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY        *
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF           *
 * SUCH DAMAGE.                                                                     *
 ************************************************************************************/
 

#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#if        !defined (WIN32)
#include <unistd.h>
#endif
#include <stdio.h>
#include <ctype.h>

#include "merc.h"
#include "ban.h"
#include "db/db.h"

ban_t * new_ban        (void);
void    free_ban(ban_t *ban);

struct ban_t
{
     ban_t      * next;
     flag32_t     ban_flags;
     int          level;
     const char * name;
};

ban_t *ban_list;
ban_t *ban_free;

ban_t *new_ban(void)
{
     static ban_t ban_zero;
     ban_t *ban;
     
     if (ban_free == NULL)
          ban = alloc_perm(sizeof(*ban));
     else
     {
          ban = ban_free;
          ban_free = ban_free->next;
     }
     
     *ban = ban_zero;
     ban->name = str_empty;
     return ban;
}

void free_ban(ban_t *ban)
{
    if (!ban)
         return;

    free_string(ban->name);

    ban->next = ban_free;
    ban_free = ban;
}

void save_bans(void)
{
    ban_t *pban;
    FILE *fp;
    bool found = FALSE;
    char buf[160];

    fclose(fpReserve); 
    if ((fp = dfopen(ETC_PATH, 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;
               snprintf(buf, sizeof(buf), "%-20s %-2d %s\n", pban->name, pban->level,
                         format_flags(pban->ban_flags));
               dump_to_scr(buf);
               fprintf(fp,"%-20s %-2d %s\n", pban->name,pban->level,
                    format_flags(pban->ban_flags));
          }
     }

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

     if (fpReserve == NULL)
     bug("ban_save: can't open null file.", 0);
}

void load_bans(void)
{
    FILE *fp;
    ban_t *ban_last;
 
    if ((fp = dfopen(ETC_PATH, BAN_FILE, "r")) == NULL)
        return;
 
    ban_last = NULL;
    for (; ;)
    {
        ban_t *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_flags(fp);
        
        fread_to_eol(fp);

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

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

    strnzcpy(host, sizeof(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|BAN_SUFFIX) && !str_cmp(pban->name,host))
	       return TRUE;

          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, const char *argument, bool fPerm)
{
    char arg1[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH];
    char *name;
    BUFFER *buffer;
    ban_t *pban, *prev;
    bool prefix = FALSE,suffix = FALSE;
    int type;

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

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

               buffer = buf_new(-1);

               buf_add(buffer, "Banned sites  level  type     status\n");
               for (pban = ban_list;pban != NULL;pban = pban->next) 
               {
                    char buf2[MAX_STRING_LENGTH];

                    snprintf(buf2, sizeof(buf2), "%s%s%s",
                              IS_SET(pban->ban_flags,BAN_PREFIX) ? "*" : str_empty,
                              pban->name,
                              IS_SET(pban->ban_flags,BAN_SUFFIX) ? "*" : str_empty);

                    buf_printf(buffer,"%-12s    %-3d  %-7s  %s\n",
                              buf2, pban->level,
                              IS_SET(pban->ban_flags,BAN_NEWBIES) ?
                                        "newbies" :
                              IS_SET(pban->ban_flags,BAN_PLAYER)  ?
                                        "player" :
                              IS_SET(pban->ban_flags,BAN_PERMIT)  ?
                                        "permit" :
                              IS_SET(pban->ban_flags,BAN_ALL)     ?
                                        "all"        : str_empty,
                              IS_SET(pban->ban_flags,BAN_PERMANENT) ?
                                        "perm" : "temp");
               }

               page_to_char(buf_string(buffer), ch);
               buf_free(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,"player"))
          type = BAN_PLAYER;
     else if (!str_prefix(arg2,"permit"))
          type = BAN_PERMIT;
     else
     {
          char_act("Acceptable ban types are all, newbies, player, and permit.", 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)
     {
                    char_act("You have to ban SOMETHING!", ch);
                    return;
     }

     prev = NULL;

     for (pban = ban_list; pban != NULL; prev = pban, pban = pban->next)
     {
          if (!str_cmp(name,pban->name))
          {
               if (pban->level > ch->level)
               {
                    char_act("That ban was set by a higher power.", 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 = ch->level;
     
     /* 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();
     
     act_puts("$t has been banned.", ch, pban->name, NULL, TO_CHAR, POS_DEAD);
     
     return;
}

DO_FUN(do_ban)
{
    ban_site(ch,argument,FALSE);
}

DO_FUN(do_permban)
{
    ban_site(ch,argument,TRUE);
}

DO_FUN(do_allow)                        
{
    char arg[MAX_INPUT_LENGTH];
    ban_t *prev;
    ban_t *curr;

    one_argument(argument, arg, sizeof(arg));

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

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

            free_ban(curr);
            act_puts("Ban on $t lifted.", ch, arg, NULL, TO_CHAR, POS_DEAD);
            save_bans();
            return;
        }
    }

    char_act("Site is not banned.", ch);
    return;
}