/* $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;
}