#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#include "merc.h"
#include "leader.h"
/* Local functions */
void fread_ban args ( ( FILE *fp, int type ) );
bool check_expire args ( ( BAN_DATA *ban ) );
void dispose_ban args ( ( BAN_DATA *ban, int type ) );
void free_ban args ( ( BAN_DATA *pban ) );
/* Global Variables */
BAN_DATA *first_ban;
BAN_DATA *last_ban;
BAN_DATA *first_ban_class;
BAN_DATA *last_ban_class;
BAN_DATA *first_ban_race;
BAN_DATA *last_ban_race;
/*
* Load all those nasty bans up :)
*
*/
void load_bans ( )
{
char buf[MAX_STRING_LENGTH];
char *word;
FILE *fp;
bool fMatch = FALSE;
if (!(fp = fopen(DATA_DIR BAN_LIST, "r")))
{
bug ("load_banlist: Cannot open " BAN_LIST, 0);
perror (BAN_LIST);
return;
}
for ( ; ; )
{
word = feof (fp) ? "END" : fread_word ( fp );
fMatch = FALSE;
switch ( UPPER ( word[0] ) )
{
case 'C':
if ( !str_cmp ( word, "CLASS" ) )
{
fread_ban ( fp, BAN_CLASS );
fMatch = TRUE;
}
break;
case 'E':
if ( !str_cmp ( word, "END"))/*File should always contain END*/
{
fclose ( fp );
log_string ( "Done." );
return;
}
case 'S':
if ( !str_cmp ( word, "SITE" ) )
{
fread_ban ( fp, BAN_SITE );
fMatch = TRUE;
}
break;
}
if ( !fMatch )
{
sprintf ( buf, "Load_banlist: no match: %s", word );
bug ( buf, 0 );
fread_to_eol(fp);
} /* End of switch statement */
} /* End of for loop */
}
/*
* Load up one class or one race ban structure.
*/
void fread_ban ( FILE *fp, int type )
{
BAN_DATA *pban;
int i = 0;
bool fMatch = FALSE;
pban = alloc_mem(sizeof( BAN_DATA ) );
pban->name = fread_string ( fp );
pban->level = fread_number( fp );
pban->duration = fread_number( fp );
pban->unban_date = fread_number( fp );
if ( type == BAN_SITE )
{
pban->prefix = fread_number( fp );
pban->suffix = fread_number( fp );
}
pban->warn = fread_number( fp );
pban->ban_by = fread_string( fp );
pban->ban_time = fread_string( fp );
pban->note = fread_string( fp );
/* Need to lookup the class or race number if it is of that type */
if ( type == BAN_CLASS )
for ( i = 0; class_table[i].class_name[0] != '\0'; i++ )
{
if ( !str_cmp( class_table[i].class_name, pban->name ) )
{
fMatch = TRUE;
break;
}
}
else if ( type == BAN_SITE )
for ( i = 0; i < strlen( pban->name); i ++ )
{
if ( pban->name[i] == '@' )
{
char *temp;
char *temp2;
temp = str_dup( pban->name );
temp[i] = '\0';
temp2 = &pban->name[i+1];
free_string( pban->name );
pban->name = str_dup( temp2 );
break;
}
}
if ( type == BAN_CLASS )
{
if ( fMatch )
pban->flag = i;
else /* The file is corupted throw out this ban structure */
{
bug("Bad class structure %d.\n\r", i );
free_ban( pban );
return;
}
}
if ( type == BAN_CLASS )
LINK( pban, first_ban_class, last_ban_class, next, prev );
else if ( type == BAN_SITE )
LINK( pban, first_ban, last_ban, next, prev );
else /* Bad type throw out the ban structure */
{
bug("Fread_ban: Bad type %d", type );
free_ban( pban );
}
return;
}
/*
* Saves all bans, for sites, classes
*/
void save_banlist ( void )
{
BAN_DATA *pban;
FILE *fp;
fclose (fpReserve);
if (!(fp = fopen (DATA_DIR BAN_LIST, "w")))
{
bug ("Save_banlist: Cannot open " BAN_LIST, 0);
perror (BAN_LIST);
fpReserve = fopen (NULL_FILE, "r");
return;
}
/* Print out all the site bans */
for (pban = first_ban; pban; pban = pban->next)
{
fprintf (fp, "SITE\n" );
fprintf (fp, "%s~\n", pban->name );
fprintf (fp, "%d %d %d %d %d %d\n", pban->level, pban->duration,
pban->unban_date, pban->prefix, pban->suffix, pban->warn );
fprintf (fp, "%s~\n%s~\n%s~\n", pban->ban_by, pban->ban_time,
pban->note );
}
/* Print out all the class bans */
for (pban = first_ban_class; pban; pban = pban->next )
{
fprintf (fp, "CLASS\n" );
fprintf (fp, "%s~\n", pban->name );
fprintf (fp, "%d %d %d %d\n", pban->level, pban->duration,
pban->unban_date, pban->warn );
fprintf (fp, "%s~\n%s~\n%s~\n", pban->ban_by, pban->ban_time,
pban->note );
}
fprintf (fp, "END\n"); /* File must have an END even if empty */
fclose (fp);
fpReserve = fopen (NULL_FILE, "r");
return;
}
/*
* The main command for ban, lots of arguments so be carefull what you
* change here.
*/
void do_ban ( CHAR_DATA *ch, char *argument )
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
char arg3[MAX_INPUT_LENGTH];
char arg4[MAX_INPUT_LENGTH];
char *temp;
BAN_DATA *pban;
int value = 0, time;
if (IS_NPC (ch)) /* Don't want mobs banning sites ;) */
{
send_to_char ("Monsters are too dumb to do that!\n\r", ch);
return;
}
if (!ch->desc) /* No desc means no go :) */
{
bug ("do_ban: no descriptor", 0);
return;
}
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
argument = one_argument( argument, arg3 );
argument = one_argument( argument, arg4 );
/* Do we have a time duration for the ban? */
if ( arg4[0] != '\0' && is_number( arg4 ) )
time = atoi( arg4 );
else
time = -1;
/* -1 is default, but no reason the time should be greater than 1000
* or less than 1, after all if it is greater than 1000 you are talking
* around 3 years.
*/
if ( time != -1 && ( time < 1 || time > 1000 ) )
{
send_to_char("Time value is -1 (forever) or from 1 to 1000.\n\r", ch);
return;
}
if ( arg1[0] == '\0' )
{
send_to_char("Syntax: ban site <address> <type> <duration>\n\r", ch );
send_to_char("Syntax: ban class <class> <type> <duration>\n\r", ch );
send_to_char("Syntax: ban show <field> <number>\n\r", ch );
send_to_char("Ban site lists current bans.\n\r", ch );
send_to_char("Duration is the length of the ban in days.\n\r", ch );
send_to_char("Type can be: newbie, mortal, all, warn or level.\n\r", ch );
send_to_char("In ban show, the <field> is site, race or class,", ch);
send_to_char(" and the <number> is the ban number.\n\r", ch );
return;
}
if ( !str_cmp ( arg1, "site" ) )
{
if ( arg2[0] == '\0' )
{
show_bans( ch, BAN_SITE );
return;
}
if ( get_trust(ch) < sysdata.ban_site_level )
{
ch_printf(ch,"You must be %d level to add bans.\n\r",
sysdata.ban_site_level);
return;
}
if ( arg3[0] == '\0' )
{
do_ban(ch,"");
return;
}
if ( !add_ban ( ch, arg2, arg3, time, BAN_SITE ) )
return;
}
else if ( !str_cmp ( arg1, "class" ) )
{
if ( arg2[0] == '\0' )
{
show_bans( ch, BAN_CLASS );
return;
}
/* Are they high enough to ban classes? */
if ( get_trust(ch) < sysdata.ban_class_level )
{
ch_printf(ch,"You must be %d level to add bans.\n\r",sysdata.ban_class_level);
return;
}
if ( arg3[0] == '\0' )
{
do_ban(ch,"");
return;
}
if ( !add_ban(ch, arg2, arg3, time, BAN_CLASS ) )
return;
}
else if ( !str_cmp ( arg1, "show" ) )
{
if ( arg2[0] == '\0' || arg3[0] == '\0' )
{
do_ban(ch,"");
return;
}
temp = arg3;
if ( arg3[0] == '#' ) /* Use #1 to show the first ban*/
{
temp = arg3;
temp++;
if ( !is_number( temp ) )
{
send_to_char("Which ban # to show?\n\r", ch);
return;
}
value = atoi(temp);
if ( value < 1 )
{
send_to_char ("You must specify a number greater than 0.\n\r",ch);
return;
}
}
if ( !str_cmp ( arg2, "site" ) )
{
pban = first_ban;
if ( temp[0] == '*' )
temp++;
if ( temp[strlen(temp)-1] == '*' )
temp[strlen(temp)-1] = '\0';
}
else if ( !str_cmp ( arg2, "class" ) )
pban = first_ban_class;
else
{
do_ban(ch,"");
return;
}
for ( ; pban; pban = pban->next )
if ( value == 1 || !str_cmp ( pban->name, temp ) )
break;
else if ( value > 1 )
value--;
if ( !pban )
{
send_to_char ("No such ban.\n\r", ch);
return;
}
ch_printf(ch, "Banned by: %s\n\r", pban->ban_by );
send_to_char ( pban->note, ch );
return;
}
do_ban(ch,"");
return;
}
/*
* Allow a already banned site/class
*/
void do_allow ( CHAR_DATA *ch, char * argument )
{
BAN_DATA *pban;
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
char *temp = NULL;
bool fMatch = FALSE;
int value = 0;
if (IS_NPC (ch)) /* No mobs allowing sites */
{
send_to_char ("Monsters are too dumb to do that!\n\r", ch);
return;
}
if (!ch->desc) /* No desc is a bad thing */
{
bug ("do_allow: no descriptor", 0);
return;
}
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
if ( arg1[0] == '\0' || arg2[0] == '\0')
{
send_to_char ("Syntax: allow site <address>\n\r", ch );
send_to_char ("Syntax: allow class <class>\n\r", ch );
return;
}
if ( arg2[0] == '#' ) /* Use #1 to ban the first ban in the list specified */
{
temp = arg2;
temp++;
if ( !is_number( temp ) )
{
send_to_char("Which ban # to allow?\n\r", ch);
return;
}
value = atoi(temp);
}
if ( !str_cmp( arg1, "site" ) ) {
if ( !value ) {
if ( strlen(arg2) < 2 )
{
send_to_char("You have to have at least 2 chars for a ban\n\r", ch);
send_to_char("If you are trying to allow by number use #\n\r",ch);
return;
}
temp = arg2;
if ( arg2[0] == '*' )
temp++;
if ( temp[strlen(temp) - 1] == '*' )
temp[ strlen(temp) -1] = '\0';
}
for ( pban = first_ban; pban; pban = pban->next )
{
if ( value == 1 || !str_cmp ( pban->name, temp ) )
{
fMatch = TRUE;
wiznetf( ch, WIZ_MISC, get_trust( ch ),
"%s allowing site %s.",
ch->name, pban->name );
dispose_ban( pban, BAN_SITE );
break;
}
if ( value > 1 )
value--;
}
}
else if ( !str_cmp( arg1, "class" ) )
{
arg2[0] = toupper( arg2[0] );
for ( pban = first_ban_class; pban; pban = pban->next )
{
if ( value == 1 || !str_cmp ( pban->name, arg2 ) )
{
fMatch = TRUE;
wiznetf( ch, WIZ_MISC, get_trust( ch ),
"%s allowing class %s.",
ch->name, pban->name );
dispose_ban( pban, BAN_CLASS );
break;
}
if ( value > 1 )
value--;
}
}
else
{
do_allow(ch,"");
return;
}
if ( fMatch )
{
save_banlist();
ch_printf(ch, "%s is now allowed.\n\r", arg2 );
}
else
ch_printf(ch, "%s was not banned.\n\r", arg2 );
return;
}
/*
* Sets the warn flag on bans.
*/
void do_warn ( CHAR_DATA *ch, char *argument )
{
char arg1[MAX_STRING_LENGTH];
char arg2[MAX_STRING_LENGTH];
char *name;
int count = -1, type;
BAN_DATA *pban, *start, *end;
if (IS_NPC (ch))
{
send_to_char ("Monsters are too dumb to do that!\n\r", ch);
return;
}
if (!ch->desc)
{
bug ("do_warn: no descriptor", 0);
return;
}
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
if ( arg1[0] == '\0' || arg2[0] == '\0' )
{
send_to_char ("Syntax: warn class <field>\n\r", ch );
send_to_char ("Syntax: warn site <field>\n\r", ch );
send_to_char ("Field is either #(ban_number) or the site/class/race.\n\r", ch);
send_to_char ("Example: warn class #1\n\r", ch );
return;
}
if ( arg2[0] == '#' )
{
name = arg2;
name++;
if ( !is_number( name ) )
{
do_warn(ch,"");
return;
}
count = atoi( name );
if ( count < 1 )
{
send_to_char("The number has to be above 0.\n\r", ch );
return;
}
}
if ( !str_cmp( arg1, "class") )
type = BAN_CLASS;
else if ( !str_cmp( arg1, "site" ) )
type = BAN_SITE;
else
type = -1;
if ( type == BAN_CLASS )
{
pban = first_ban_class;
start = first_ban_class;
end = last_ban_class;
arg2[0] = toupper( arg2[0] );
}
else if ( type == BAN_SITE )
{
pban = first_ban;
start = first_ban;
end = last_ban;
}
else
{
do_warn(ch,"");
return;
}
for ( ; pban && count != 0; count--, pban = pban->next )
if ( count == -1 && !str_cmp(pban->name, arg2 ) )
break;
if ( pban )
{
if ( pban->warn )
{
if ( pban->level == BAN_WARN )
{
dispose_ban( pban, type );
send_to_char("Warn has been deleted.\n\r", ch );
}
else
{
pban->warn = FALSE;
send_to_char("Warn turned off.\n\r", ch);
}
}
else
{
pban->warn = TRUE;
send_to_char("Warn turned on.\n\r", ch );
}
save_banlist( );
}
else
{
ch_printf(ch, "%s was not found in the ban list.\n\r", arg2 );
return;
}
return;
}
/*
* This actually puts the new ban into the proper linked list and
* initializes its data.
*/
int add_ban( CHAR_DATA *ch, char *arg1, char *arg2, int time, int type )
{
char arg[MAX_STRING_LENGTH];
char buf[MAX_STRING_LENGTH];
BAN_DATA *pban, *temp;
struct tm *tms;
char *name;
int level, value;
/* Should we check to see if they have dropped link sometime in between
* writing the note and now? Not sure but for right now we won't since
* do_ban checks for that.
*/
one_argument( arg1, arg );
smash_tilde ( arg ); /* Make sure the immortals don't put a ~ in it. */
if ( arg[0] == '\0' || arg2[0] == '\0')
return 0;
if ( is_number( arg2 ) )
{
level = atoi ( arg2 );
if ( level < 0 || level > LEVEL_IMPLEMENTOR )
{
ch_printf(ch,"Level range is from 0 to %d.\n\r", LEVEL_IMPLEMENTOR );
return 0;
}
}
else if ( !str_cmp( arg2, "all" ) )
level = LEVEL_IMPLEMENTOR;
else if ( !str_cmp( arg2, "newbie" ) )
level = 1;
else if ( !str_cmp( arg2, "mortal" ) )
level = LEVEL_AVATAR;
else if ( !str_cmp( arg2, "warn" ) )
level = BAN_WARN;
else
{
bug("Bad string for flag in add_ban.", 0 );
return 0;
}
switch ( type )
{
case BAN_CLASS:
if ( arg[0] == '\0' )
return 0;
if ( is_number( arg ) )
value = atoi( arg );
else
value = class_lookupn(arg);
if (value < 0 || value >= MAX_CLASS)
{
send_to_char("Unknown class.\n\r", ch );
return 0;
}
for( temp = first_ban_class; temp; temp = temp->next )
{
if ( temp->flag == value )
{
if ( temp->level == level )
{
send_to_char ("That entry already exists.\n\r",ch);
return 0;
}
else
{
temp->level = level;
if ( temp->level == BAN_WARN )
temp->warn = TRUE;
sprintf (buf, "%24.24s", ctime (¤t_time));
temp->ban_time = str_dup (buf);
if ( temp->ban_by )
free_string( temp->ban_by );
temp->ban_by = str_dup ( ch->name );
send_to_char("Updated entry.\n\r", ch);
return 1;
}
}
}
pban = alloc_mem( sizeof( BAN_DATA) );
pban->name = str_dup ( class_table[value].class_name );
pban->flag = value;
pban->level = level;
pban->ban_by = str_dup ( ch->name );
LINK( pban, first_ban_class, last_ban_class, next, prev );
wiznetf( ch, WIZ_MISC,
get_trust( ch ), "%s setting class ban on %s",
ch->name, pban->name );
break;
case BAN_SITE:
{
bool prefix = FALSE, suffix = FALSE;
name = arg;
if ( name[0] == '*' )
{
prefix = TRUE;
name++;
}
if ( name[strlen(name) - 1] == '*' )
{
suffix = TRUE;
name[strlen(name) - 1] = '\0';
}
for( temp = first_ban; temp; temp = temp->next )
{
if ( !str_cmp ( temp->name, name ) )
{
if ( temp->level == level && (prefix && temp->prefix)
&& ( suffix && temp->suffix ) )
{
send_to_char ("That entry already exists.\n\r",ch);
return 0;
}
else
{
temp->suffix = suffix;
temp->prefix = prefix;
if ( temp->level == BAN_WARN )
temp->warn = TRUE;
temp->level = level;
sprintf (buf, "%24.24s", ctime (¤t_time));
temp->ban_time = str_dup (buf);
if ( temp->ban_by )
free_string( temp->ban_by );
temp->ban_by = str_dup ( ch->name );
send_to_char("Updated entry.\n\r", ch);
return 1;
}
}
}
pban = alloc_mem( sizeof( BAN_DATA ) );
pban->ban_by = str_dup ( ch->name );
pban->suffix = suffix;
pban->prefix = prefix;
pban->name = str_dup( name );
pban->level = level;
LINK( pban, first_ban, last_ban, next, prev );
wiznetf( ch, WIZ_MISC,
get_trust( ch ), "%s setting class ban on %s",
ch->name, pban->name );
break;
}
default:
bug("Bad type in add_ban: %d.", type );
return 0;
}
sprintf (buf, "%24.24s", ctime (¤t_time));
pban->ban_time = str_dup (buf);
if ( time > 0 ) {
pban->duration = time;
tms = localtime(¤t_time);
tms->tm_mday += time;
pban->unban_date = mktime(tms);
}
else {
pban->duration = -1;
pban->unban_date = -1;
}
if ( pban->level == BAN_WARN )
pban->warn = TRUE;
string_append( ch, &pban->note );
save_banlist( );
if ( pban->duration > 0 )
{
ch_printf (ch, "%s banned for %d days.\n\r", pban->name, pban->duration );
}
else
{
ch_printf (ch, "%s banned forever.\n\r", pban->name );
}
return 1;
}
/*
* Print the bans out to the screen
*/
void show_bans ( CHAR_DATA *ch, int type )
{
BAN_DATA *pban;
int bnum;
switch ( type )
{
case BAN_SITE:
page_to_char("Banned sites:\n\r", ch);
page_to_char("[ ##] Warn (Lv) Time By For Site\n\r",ch);
page_to_char("---- ---- ---- ------------------------ --------------- ---- ---------------\n\r", ch);
pban = first_ban;
for ( bnum=1; pban; pban=pban->next, bnum++)
{
pager_printf (ch, "[%2d] %-4s (%2d) %-24s %-15s %4d %c%s%c\n\r",
bnum, (pban->warn)?"YES":"no", pban->level,
pban->ban_time, pban->ban_by, pban->duration,
(pban->prefix)?'*':' ',
pban->name, (pban->suffix)?'*':' ');
}
return;
case BAN_CLASS:
page_to_char("Banned classes:\n\r", ch);
page_to_char("[ #] Warn (Lv) Time By For Class\n\r",ch);
pban = first_ban_class;
break;
default:
bug ("Bad type in show_bans: %d", type );
return;
}
page_to_char("---- ---- ---- ------------------------ --------------- ---- ---------------\n\r", ch);
for ( bnum=1; pban; pban=pban->next, bnum++)
pager_printf (ch, "[%2d] %-4s (%2d) %-24s %-15s %4d %s\n\r", bnum,
(pban->warn)?"YES":"no", pban->level, pban->ban_time, pban->ban_by,
pban->duration, pban->name);
return;
}
/*
* Check for totally banned sites. Need this because we don't have a
* char struct yet
*/
bool check_total_bans ( DESCRIPTOR_DATA *d )
{
BAN_DATA *pban;
char new_host[MAX_STRING_LENGTH];
int i;
for ( i = 0; i < (int) strlen( d->host ) ; i++ )
new_host[i] = LOWER( d->host[i] );
new_host[i] = '\0';
for ( pban = first_ban; pban; pban = pban->next ) {
if ( pban->level != LEVEL_IMPLEMENTOR )
continue;
if ( pban->prefix && pban->suffix &&
strstr( pban->name, new_host ) )
{
if ( check_expire( pban ) )
{
dispose_ban( pban, BAN_SITE );
save_banlist( );
return FALSE;
}
else
return TRUE;
}
/*
* Bug of switched checks noticed by Cronel
*/
if ( pban->suffix && !str_prefix( pban->name, new_host ) )
{
if ( check_expire( pban ) )
{
dispose_ban( pban, BAN_SITE );
save_banlist( );
return FALSE;
}
else
return TRUE;
}
if ( pban->prefix && !str_suffix( pban->name, new_host ) )
{
if ( check_expire( pban ) )
{
dispose_ban( pban, BAN_SITE );
save_banlist( );
return FALSE;
}
else
return TRUE;
}
if ( !str_cmp( pban->name, new_host ) )
{
if ( check_expire( pban ) )
{
dispose_ban( pban, BAN_SITE );
save_banlist( );
return FALSE;
}
else
return TRUE;
}
}
return FALSE;
}
/*
* The workhose, checks for bans on sites/classes
*/
bool check_bans( CHAR_DATA *ch, int type )
{
char buf[MAX_STRING_LENGTH];
BAN_DATA *pban;
char new_host[MAX_STRING_LENGTH];
int i;
bool fMatch = FALSE;
switch ( type )
{
case BAN_CLASS:
pban = first_ban_class;
break;
case BAN_SITE:
pban = first_ban;
for ( i = 0; i < (int) ( strlen( ch->desc->host ) ); i++ )
new_host[i] = LOWER( ch->desc->host[i] );
new_host[i] = '\0';
break;
default:
bug ( "Ban type in check_bans: %d.", type );
return FALSE;
}
for ( ; pban; pban = pban->next ) {
if ( type == BAN_CLASS && pban->flag == ch->class )
{
if ( check_expire( pban ) )
{
dispose_ban( pban, BAN_CLASS );
save_banlist( );
return FALSE;
}
if ( ch->level > pban->level )
{
if ( pban->warn ) {
sprintf( buf, "%s class logging in from %s.",
pban->name, ch->desc->host );
log_string( buf );
}
return FALSE;
}
else
return TRUE;
}
if ( type == BAN_SITE )
{
if ( pban->prefix && pban->suffix &&
strstr( pban->name, new_host ) )
fMatch = TRUE;
else if ( pban->prefix && !str_suffix( pban->name, new_host ) )
fMatch = TRUE;
else if ( pban->suffix && !str_prefix( pban->name, new_host ) )
fMatch = TRUE;
else if ( !str_cmp( pban->name, new_host ) )
fMatch = TRUE;
if ( fMatch )
{
if ( check_expire( pban ) )
{
dispose_ban( pban, BAN_SITE );
save_banlist( );
return FALSE;
}
if ( ch->level > pban->level )
{
if ( pban->warn ) {
sprintf( buf, "%s logging in from site %s.",
ch->name, ch->desc->host );
log_string( buf );
}
return FALSE;
}
else
return TRUE;
}
}
}
return FALSE;
}
bool check_expire( BAN_DATA *pban )
{
char buf[MAX_STRING_LENGTH];
if ( pban->unban_date < 0 )
return FALSE;
if ( pban->unban_date <= current_time )
{
sprintf( buf, "%s ban has expired.", pban->name );
log_string( buf );
return TRUE;
}
return FALSE;
}
void dispose_ban ( BAN_DATA *pban , int type)
{
if ( !pban )
return;
if ( type != BAN_SITE && type != BAN_CLASS )
{
bug("Dispose_ban: Unknown Ban Type %d.", type );
return;
}
switch ( type )
{
case BAN_SITE: UNLINK(pban, first_ban, last_ban, next, prev); break;
case BAN_CLASS: UNLINK(pban, first_ban_class, last_ban_class, next,
prev ); break;
}
free_ban( pban );
return;
}
void free_ban( BAN_DATA *pban )
{
if ( pban->name )
free_string( pban->name );
if ( pban->ban_time )
free_string( pban->ban_time );
if ( pban->note )
free_string( pban->note );
if ( pban->ban_by )
free_string( pban->ban_by );
if ( pban->ban_time )
free_string( pban->ban_time );
free_mem( pban, sizeof( *pban ) );
}