wmud/old-codebase/src/ban.c
2012-03-07 16:24:50 +01:00

315 lines
8.3 KiB
C

/* ************************************************************************
* File: ban.c Part of CircleMUD *
* Usage: banning/unbanning/checking sites and player names *
* *
* All rights reserved. See license.doc for complete information. *
* *
* Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University *
* CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. *
************************************************************************ */
#include "conf.h"
#include "sysdep.h"
#include "structs.h"
#include "utils.h"
#include "comm.h"
#include "interpreter.h"
#include "handler.h"
#include "db.h"
/* local globals */
struct ban_list_element *ban_list = NULL;
/* local functions */
void load_banned(void);
int isbanned(char *hostname);
void _write_one_node(FILE *fp, struct ban_list_element *node);
void write_ban_list(void);
ACMD(do_ban);
ACMD(do_unban);
int Valid_Name(char *newname);
void Read_Invalid_List(void);
void Free_Invalid_List(void);
const char *ban_types[] = {
"no",
"new",
"select",
"all",
"ERROR"
};
void load_banned(void)
{
FILE *fl;
int i, date;
char site_name[BANNED_SITE_LENGTH + 1], ban_type[100];
char name[MAX_NAME_LENGTH + 1];
struct ban_list_element *next_node;
ban_list = 0;
if (!(fl = fopen(BAN_FILE, "r"))) {
if (errno != ENOENT) {
log("SYSERR: Unable to open banfile '%s': %s", BAN_FILE, strerror(errno));
} else
log(" Ban file '%s' doesn't exist.", BAN_FILE);
return;
}
while (fscanf(fl, " %s %s %d %s ", ban_type, site_name, &date, name) == 4) {
CREATE(next_node, struct ban_list_element, 1);
strncpy(next_node->site, site_name, BANNED_SITE_LENGTH); /* strncpy: OK (n_n->site:BANNED_SITE_LENGTH+1) */
next_node->site[BANNED_SITE_LENGTH] = '\0';
strncpy(next_node->name, name, MAX_NAME_LENGTH); /* strncpy: OK (n_n->name:MAX_NAME_LENGTH+1) */
next_node->name[MAX_NAME_LENGTH] = '\0';
next_node->date = date;
for (i = BAN_NOT; i <= BAN_ALL; i++)
if (!strcmp(ban_type, ban_types[i]))
next_node->type = i;
next_node->next = ban_list;
ban_list = next_node;
}
fclose(fl);
}
int isbanned(char *hostname)
{
int i;
struct ban_list_element *banned_node;
char *nextchar;
if (!hostname || !*hostname)
return (0);
i = 0;
for (nextchar = hostname; *nextchar; nextchar++)
*nextchar = LOWER(*nextchar);
for (banned_node = ban_list; banned_node; banned_node = banned_node->next)
if (strstr(hostname, banned_node->site)) /* if hostname is a substring */
i = MAX(i, banned_node->type);
return (i);
}
void _write_one_node(FILE *fp, struct ban_list_element *node)
{
if (node) {
_write_one_node(fp, node->next);
fprintf(fp, "%s %s %ld %s\n", ban_types[node->type],
node->site, (long) node->date, node->name);
}
}
void write_ban_list(void)
{
FILE *fl;
if (!(fl = fopen(BAN_FILE, "w"))) {
perror("SYSERR: Unable to open '" BAN_FILE "' for writing");
return;
}
_write_one_node(fl, ban_list);/* recursively write from end to start */
fclose(fl);
return;
}
#define BAN_LIST_FORMAT "%-25.25s %-8.8s %-10.10s %-16.16s\r\n"
ACMD(do_ban)
{
char flag[MAX_INPUT_LENGTH], site[MAX_INPUT_LENGTH], *nextchar;
char timestr[16];
int i;
struct ban_list_element *ban_node;
if (!*argument) {
if (!ban_list) {
send_to_char(ch, "No sites are banned.\r\n");
return;
}
send_to_char(ch, BAN_LIST_FORMAT,
"Banned Site Name",
"Ban Type",
"Banned On",
"Banned By");
send_to_char(ch, BAN_LIST_FORMAT,
"---------------------------------",
"---------------------------------",
"---------------------------------",
"---------------------------------");
for (ban_node = ban_list; ban_node; ban_node = ban_node->next) {
if (ban_node->date) {
strlcpy(timestr, asctime(localtime(&(ban_node->date))), 10);
timestr[10] = '\0';
} else
strcpy(timestr, "Unknown"); /* strcpy: OK (strlen("Unknown") < 16) */
send_to_char(ch, BAN_LIST_FORMAT, ban_node->site, ban_types[ban_node->type], timestr, ban_node->name);
}
return;
}
two_arguments(argument, flag, site);
if (!*site || !*flag) {
send_to_char(ch, "Usage: ban {all | select | new} site_name\r\n");
return;
}
if (!(!str_cmp(flag, "select") || !str_cmp(flag, "all") || !str_cmp(flag, "new"))) {
send_to_char(ch, "Flag must be ALL, SELECT, or NEW.\r\n");
return;
}
for (ban_node = ban_list; ban_node; ban_node = ban_node->next) {
if (!str_cmp(ban_node->site, site)) {
send_to_char(ch, "That site has already been banned -- unban it to change the ban type.\r\n");
return;
}
}
CREATE(ban_node, struct ban_list_element, 1);
strncpy(ban_node->site, site, BANNED_SITE_LENGTH); /* strncpy: OK (b_n->site:BANNED_SITE_LENGTH+1) */
for (nextchar = ban_node->site; *nextchar; nextchar++)
*nextchar = LOWER(*nextchar);
ban_node->site[BANNED_SITE_LENGTH] = '\0';
strncpy(ban_node->name, GET_NAME(ch), MAX_NAME_LENGTH); /* strncpy: OK (b_n->size:MAX_NAME_LENGTH+1) */
ban_node->name[MAX_NAME_LENGTH] = '\0';
ban_node->date = time(0);
for (i = BAN_NEW; i <= BAN_ALL; i++)
if (!str_cmp(flag, ban_types[i]))
ban_node->type = i;
ban_node->next = ban_list;
ban_list = ban_node;
mudlog(NRM, MAX(LVL_GOD, GET_INVIS_LEV(ch)), TRUE, "%s has banned %s for %s players.",
GET_NAME(ch), site, ban_types[ban_node->type]);
send_to_char(ch, "Site banned.\r\n");
write_ban_list();
}
#undef BAN_LIST_FORMAT
ACMD(do_unban)
{
char site[MAX_INPUT_LENGTH];
struct ban_list_element *ban_node, *temp;
int found = 0;
one_argument(argument, site);
if (!*site) {
send_to_char(ch, "A site to unban might help.\r\n");
return;
}
ban_node = ban_list;
while (ban_node && !found) {
if (!str_cmp(ban_node->site, site))
found = 1;
else
ban_node = ban_node->next;
}
if (!found) {
send_to_char(ch, "That site is not currently banned.\r\n");
return;
}
REMOVE_FROM_LIST(ban_node, ban_list, next);
send_to_char(ch, "Site unbanned.\r\n");
mudlog(NRM, MAX(LVL_GOD, GET_INVIS_LEV(ch)), TRUE, "%s removed the %s-player ban on %s.",
GET_NAME(ch), ban_types[ban_node->type], ban_node->site);
free(ban_node);
write_ban_list();
}
/**************************************************************************
* Code to check for invalid names (i.e., profanity, etc.) *
* Written by Sharon P. Goza *
**************************************************************************/
#define MAX_INVALID_NAMES 200
char *invalid_list[MAX_INVALID_NAMES];
int num_invalid = 0;
int Valid_Name(char *newname)
{
int i;
struct descriptor_data *dt;
char tempname[MAX_INPUT_LENGTH];
/*
* Make sure someone isn't trying to create this same name. We want to
* do a 'str_cmp' so people can't do 'Bob' and 'BoB'. The creating login
* will not have a character name yet and other people sitting at the
* prompt won't have characters yet.
*/
for (dt = descriptor_list; dt; dt = dt->next)
if (dt->character && GET_NAME(dt->character) && !str_cmp(GET_NAME(dt->character), newname))
return (STATE(dt) == CON_PLAYING);
/* return valid if list doesn't exist */
if (!invalid_list || num_invalid < 1)
return (1);
/* change to lowercase */
strlcpy(tempname, newname, sizeof(tempname));
for (i = 0; tempname[i]; i++)
tempname[i] = LOWER(tempname[i]);
/* Does the desired name contain a string in the invalid list? */
for (i = 0; i < num_invalid; i++)
if (strstr(tempname, invalid_list[i]))
return (0);
return (1);
}
/* What's with the wacky capitalization in here? */
void Free_Invalid_List(void)
{
int invl;
for (invl = 0; invl < num_invalid; invl++)
free(invalid_list[invl]);
num_invalid = 0;
}
void Read_Invalid_List(void)
{
FILE *fp;
char temp[256];
if (!(fp = fopen(XNAME_FILE, "r"))) {
perror("SYSERR: Unable to open '" XNAME_FILE "' for reading");
return;
}
num_invalid = 0;
while (get_line(fp, temp) && num_invalid < MAX_INVALID_NAMES)
invalid_list[num_invalid++] = strdup(temp);
if (num_invalid >= MAX_INVALID_NAMES) {
log("SYSERR: Too many invalid names; change MAX_INVALID_NAMES in ban.c");
exit(1);
}
fclose(fp);
}