/**************************************************************************** * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | \\._.// * * -----------------------------------------------------------| (0...0) * * SMAUG 1.4 (C) 1994, 1995, 1996, 1998 by Derek Snider | ).:.( * * -----------------------------------------------------------| {o o} * * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, | / ' ' \ * * Scryn, Rennard, Swordbearer, Gorog, Grishnakh, Nivek, |~'~.VxvxV.~'~* * Tricops and Fireblade | * * ------------------------------------------------------------------------ * * Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * ------------------------------------------------------------------------ * * Ban module by Shaddai * ****************************************************************************/ #include <string.h> #include <ctype.h> #include <stdio.h> #include <time.h> #include "h/mud.h" #include "h/ban.h" #include "h/files.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 :) * Shaddai */ void load_banlist(void) { const char *word; FILE *fp; bool fMatch = FALSE; if(!(fp = FileOpen(SYSTEM_DIR BAN_LIST, "r"))) { bug("load_banlist: Cannot open %s", BAN_LIST); 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 */ FileClose(fp); log_string("Done."); return; } case 'R': if(!str_cmp(word, "RACE")) { fread_ban(fp, BAN_RACE); fMatch = TRUE; } break; case 'S': if(!str_cmp(word, "SITE")) { fread_ban(fp, BAN_SITE); fMatch = TRUE; } break; } if(!fMatch) { bug("Load_banlist: no match: %s", word); 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; unsigned int i = 0; bool fMatch = FALSE; CREATE(pban, BAN_DATA, 1); 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) { /* Sites have 2 extra numbers written out */ 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; i < MAX_CLASS; i++) { if(!str_cmp(class_table[i]->who_name, pban->name)) { fMatch = TRUE; break; } } else if(type == BAN_RACE) for(i = 0; i < MAX_RACE; i++) { if(!str_cmp(race_table[i]->race_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 = STRALLOC(pban->name); temp[i] = '\0'; temp2 = &pban->name[i + 1]; STRFREE(pban->name); pban->name = STRALLOC(temp2); DISPOSE(temp); break; } } if(type == BAN_RACE || type == BAN_CLASS) { if(fMatch) pban->flag = i; else { /* The file is corupted throw out * * * * this ban structure */ bug("Bad class structure %d.\r\n", i); free_ban(pban); return; } } if(type == BAN_CLASS) LINK(pban, first_ban_class, last_ban_class, next, prev); else if(type == BAN_RACE) LINK(pban, first_ban_race, last_ban_race, 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 and races. * Shaddai */ void save_banlist(void) { BAN_DATA *pban; FILE *fp; if(!(fp = FileOpen(SYSTEM_DIR BAN_LIST, "w"))) { bug("Save_banlist: Cannot open %s", BAN_LIST); perror(BAN_LIST); 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 race bans */ for(pban = first_ban_race; pban; pban = pban->next) { fprintf(fp, "RACE\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); } /* * 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 */ FileClose(fp); return; } /* * The main command for ban, lots of arguments so be carefull what you * change here. Shaddai */ 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, btime; if(IS_NPC(ch)) { /* Don't want mobs banning sites * ;) */ send_to_char("Monsters are too dumb to do that!\r\n", ch); return; } if(!ch->desc) { /* No desc means no go :) */ bug("%s", "do_ban: no descriptor"); return; } set_char_color(AT_IMMORT, ch); 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)) btime = atoi(arg4); else btime = -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(btime != -1 && (btime < 1 || btime > 1000)) { send_to_char("Time value is -1 (forever) or from 1 to 1000.\r\n", ch); return; } /* * Need to be carefull with sub-states or everything will get messed up. */ switch (ch->substate) { default: bug("%s", "do_ban: illegal substate"); return; case SUB_RESTRICTED: send_to_char("You cannot use this command from within another command.\r\n", ch); return; case SUB_NONE: ch->tempnum = SUB_NONE; break; /* * Returning to end the editing of the note */ case SUB_BAN_DESC: add_ban(ch, (char *)"", (char *)"", 0, 0); return; } if(arg1[0] == '\0') goto syntax_message; /* * If no args are sent after the class/site/race, show the current banned * * items. Shaddai */ if(!str_cmp(arg1, "site")) { if(arg2[0] == '\0') { show_bans(ch, BAN_SITE); return; } /* * Are they high enough to ban sites? */ if(get_trust(ch) < sysdata.ban_site_level) { ch_printf(ch, "You must be %d level to add bans.\r\n", sysdata.ban_site_level); return; } if(arg3[0] == '\0') goto syntax_message; if(!add_ban(ch, arg2, arg3, btime, BAN_SITE)) return; } else if(!str_cmp(arg1, "race")) { if(arg2[0] == '\0') { show_bans(ch, BAN_RACE); return; } /* * Are they high enough level to ban races? */ if(get_trust(ch) < sysdata.ban_race_level) { ch_printf(ch, "You must be %d level to add bans.\r\n", sysdata.ban_race_level); return; } if(arg3[0] == '\0') goto syntax_message; if(!add_ban(ch, arg2, arg3, btime, BAN_RACE)) 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.\r\n", sysdata.ban_class_level); return; } if(arg3[0] == '\0') goto syntax_message; if(!add_ban(ch, arg2, arg3, btime, BAN_CLASS)) return; } else if(!str_cmp(arg1, "show")) { /* * This will show the note attached to a ban */ if(arg2[0] == '\0' || arg3[0] == '\0') goto syntax_message; 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?\r\n", ch); return; } value = atoi(temp); if(value < 1) { send_to_char("You must specify a number greater than 0.\r\n", 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 if(!str_cmp(arg2, "race")) pban = first_ban_race; else goto syntax_message; 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.\r\n", ch); return; } ch_printf(ch, "Banned by: %s\r\n", pban->ban_by); send_to_char(pban->note, ch); return; } else goto syntax_message; return; /* Catch all syntax message, make sure that return stays above this or you * will get the syntax message everytime you issue the command even if it * is a valid one. Shaddai */ syntax_message: send_to_char("Syntax: ban site <address> <type> <duration>\r\n", ch); send_to_char("Syntax: ban race <race> <type> <duration>\r\n", ch); send_to_char("Syntax: ban class <class> <type> <duration>\r\n", ch); send_to_char("Syntax: ban show <field> <number>\r\n", ch); send_to_char("Ban site lists current bans.\r\n", ch); send_to_char("Duration is the length of the ban in days.\r\n", ch); send_to_char("Type can be: newbie, mortal, all, warn or level.\r\n", 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.\r\n", ch); return; } /* * Allow a already banned site/class or race. Shaddai */ 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!\r\n", ch); return; } if(!ch->desc) { /* No desc is a bad thing */ bug("%s", "do_allow: no descriptor"); return; } argument = one_argument(argument, arg1); argument = one_argument(argument, arg2); set_char_color(AT_IMMORT, ch); if(arg1[0] == '\0' || arg2[0] == '\0') goto syntax_message; 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?\r\n", 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\r\n", ch); send_to_char("If you are trying to allow by number use #\r\n", 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) { /* * Need to make sure we dispose properly of the ban_data * * Or memory problems will be created. * * Shaddai */ if(value == 1 || !str_cmp(pban->name, temp)) { fMatch = TRUE; dispose_ban(pban, BAN_SITE); break; } if(value > 1) value--; } } else if(!str_cmp(arg1, "race")) { arg2[0] = toupper(arg2[0]); for(pban = first_ban_race; pban; pban = pban->next) { /* * Need to make sure we dispose properly of the ban_data * * Or memory problems will be created. * * Shaddai */ if(value == 1 || !str_cmp(pban->name, arg2)) { fMatch = TRUE; dispose_ban(pban, BAN_RACE); 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) { /* * Need to make sure we dispose properly of the ban_data * * Or memory problems will be created. * * Shaddai */ if(value == 1 || !str_cmp(pban->name, arg2)) { fMatch = TRUE; dispose_ban(pban, BAN_CLASS); break; } if(value > 1) value--; } } else goto syntax_message; if(fMatch) { save_banlist(); ch_printf(ch, "%s is now allowed.\r\n", arg2); } else ch_printf(ch, "%s was not banned.\r\n", arg2); return; /* * Make sure that return above stays in! */ syntax_message: send_to_char("Syntax: allow site <address>\r\n", ch); send_to_char("Syntax: allow race <race>\r\n", ch); send_to_char("Syntax: allow class <class>\r\n", ch); 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; /* * Don't want mobs or link-deads doing this. */ if(IS_NPC(ch)) { send_to_char("Monsters are too dumb to do that!\r\n", ch); return; } if(!ch->desc) { bug("%s", "do_warn: no descriptor"); return; } argument = one_argument(argument, arg1); argument = one_argument(argument, arg2); if(arg1[0] == '\0' || arg2[0] == '\0') goto syntax_message; if(arg2[0] == '#') { name = arg2; name++; if(!is_number(name)) goto syntax_message; count = atoi(name); if(count < 1) { send_to_char("The number has to be above 0.\r\n", ch); return; } } /* * We simply set up which ban list we will be looking at here. */ if(!str_cmp(arg1, "class")) type = BAN_CLASS; else if(!str_cmp(arg1, "race")) type = BAN_RACE; 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_RACE) { pban = first_ban_race; start = first_ban_race; end = last_ban_race; arg2[0] = toupper(arg2[0]); } else if(type == BAN_SITE) { pban = first_ban; start = first_ban; end = last_ban; } else goto syntax_message; for(; pban && count != 0; count--, pban = pban->next) if(count == -1 && !str_cmp(pban->name, arg2)) break; if(pban) { /* * If it is just a warn delete it, otherwise remove the warn flag. */ if(pban->warn) { if(pban->level == BAN_WARN) { dispose_ban(pban, type); send_to_char("Warn has been deleted.\r\n", ch); } else { pban->warn = FALSE; send_to_char("Warn turned off.\r\n", ch); } } else { pban->warn = TRUE; send_to_char("Warn turned on.\r\n", ch); } save_banlist(); } else { ch_printf(ch, "%s was not found in the ban list.\r\n", arg2); return; } return; /* * The above return has to stay in! */ syntax_message: send_to_char("Syntax: warn class <field>\r\n", ch); send_to_char("Syntax: warn race <field>\r\n", ch); send_to_char("Syntax: warn site <field>\r\n", ch); send_to_char("Field is either #(ban_number) or the site/class/race.\r\n", ch); send_to_char("Example: warn class #1\r\n", ch); return; } /* * This actually puts the new ban into the proper linked list and * initializes its data. Shaddai */ int add_ban(CHAR_DATA *ch, char *arg1, char *arg2, int btime, int type) { char arg[MAX_STRING_LENGTH]; char buf[MAX_STRING_LENGTH]; BAN_DATA *pban, *temp; struct tm *tms; char *name; int level, i, 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. Shaddai */ switch (ch->substate) { default: bug("%s", "add_ban: illegal substate"); return 0; case SUB_RESTRICTED: send_to_char("You cannot use this command from within another command.\r\n", ch); return 0; case SUB_NONE: { 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_AJ_GENERAL) { ch_printf(ch, "Level range is from 0 to %d.\r\n", LEVEL_AJ_GENERAL); return 0; } } else if(!str_cmp(arg2, "all")) level = LEVEL_AJ_GENERAL; 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("%s", "Bad string for flag in add_ban."); return 0; } switch (type) { case BAN_CLASS: if(arg[0] == '\0') return 0; if(is_number(arg)) value = atoi(arg); else { for(i = 0; i < MAX_CLASS; i++) if(!str_cmp(class_table[i]->who_name, arg)) break; value = i; } if(value < 0 || value >= MAX_CLASS) { send_to_char("Unknown class.\r\n", 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.\r\n", 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 = STRALLOC(buf); if(btime > 0) { temp->duration = btime; tms = localtime(¤t_time); tms->tm_mday += btime; temp->unban_date = mktime(tms); } else { temp->duration = -1; temp->unban_date = -1; } if(temp->ban_by) STRFREE(temp->ban_by); temp->ban_by = STRALLOC(ch->name); send_to_char("Updated entry.\r\n", ch); return 1; } } } CREATE(pban, BAN_DATA, 1); pban->name = STRALLOC(class_table[value]->who_name); pban->flag = value; pban->level = level; pban->ban_by = STRALLOC(ch->name); LINK(pban, first_ban_class, last_ban_class, next, prev); break; case BAN_RACE: if(is_number(arg)) value = atoi(arg); else { for(i = 0; i < MAX_RACE; i++) if(!str_cmp(race_table[i]->race_name, arg)) break; value = i; } if(value < 0 || value >= MAX_RACE) { send_to_char("Unknown race.\r\n", ch); return 0; } for(temp = first_ban_race; temp; temp = temp->next) { if(temp->flag == value) { if(temp->level == level) { send_to_char("That entry already exists.\r\n", 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 = STRALLOC(buf); if(btime > 0) { temp->duration = btime; tms = localtime(¤t_time); tms->tm_mday += btime; temp->unban_date = mktime(tms); } else { temp->duration = -1; temp->unban_date = -1; } if(temp->ban_by) STRFREE(temp->ban_by); temp->ban_by = STRALLOC(ch->name); send_to_char("Updated entry.\r\n", ch); return 1; } } } CREATE(pban, BAN_DATA, 1); pban->name = STRALLOC(race_table[value]->race_name); pban->flag = value; pban->level = level; pban->ban_by = STRALLOC(ch->name); LINK(pban, first_ban_race, last_ban_race, next, prev); break; case BAN_SITE: { bool prefix = FALSE, suffix = FALSE, user_name = FALSE; char *temp_host = NULL, *temp_user = NULL; int x; for(x = 0; x < strlen(arg); x++) { if(arg[x] == '@') { user_name = TRUE; temp_host = STRALLOC(&arg[x + 1]); arg[x] = '\0'; temp_user = STRALLOC(arg); break; } } if(!user_name) name = arg; else name = temp_host; if(!name) { /* Double check to make sure name * isnt null */ /* * Free this stuff if its there */ if(user_name) { STRFREE(temp_host); STRFREE(temp_user); } send_to_char("Name was null.\r\n", ch); return 0; } 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)) { /* * Free this stuff if its there */ if(user_name) { STRFREE(temp_host); STRFREE(temp_user); } send_to_char("That entry already exists.\r\n", 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 = STRALLOC(buf); if(btime > 0) { temp->duration = btime; tms = localtime(¤t_time); tms->tm_mday += btime; temp->unban_date = mktime(tms); } else { temp->duration = -1; temp->unban_date = -1; } if(temp->ban_by) STRFREE(temp->ban_by); if(user_name) { STRFREE(temp_host); STRFREE(temp_user); } temp->ban_by = STRALLOC(ch->name); send_to_char("Updated entry.\r\n", ch); return 1; } } } CREATE(pban, BAN_DATA, 1); pban->ban_by = STRALLOC(ch->name); pban->suffix = suffix; pban->prefix = prefix; pban->name = STRALLOC(name); pban->level = level; LINK(pban, first_ban, last_ban, next, prev); if(user_name) { STRFREE(temp_host); STRFREE(temp_user); } break; } default: bug("Bad type in add_ban: %d.", type); return 0; } sprintf(buf, "%24.24s", ctime(¤t_time)); pban->ban_time = STRALLOC(buf); if(btime > 0) { pban->duration = btime; tms = localtime(¤t_time); tms->tm_mday += btime; pban->unban_date = mktime(tms); } else { pban->duration = -1; pban->unban_date = -1; } if(pban->level == BAN_WARN) pban->warn = TRUE; ch->substate = SUB_BAN_DESC; ch->dest_buf = pban; if(!pban->note) pban->note = STRALLOC("");; start_editing(ch, pban->note); return 1; } case SUB_BAN_DESC: pban = (BAN_DATA *)ch->dest_buf; if(!pban) { bug("%s", "do_ban: sub_ban_desc: NULL ch->dest_buf"); ch->substate = SUB_NONE; return 0; } if(pban->note) STRFREE(pban->note); pban->note = copy_buffer(ch); stop_editing(ch); ch->substate = ch->tempnum; save_banlist(); if(pban->duration > 0) { ch_printf(ch, "%s banned for %d days.\r\n", pban->name, pban->duration); } else { ch_printf(ch, "%s banned forever.\r\n", pban->name); } return 1; } return 1; } /* * Print the bans out to the screen. Shaddai */ void show_bans(CHAR_DATA *ch, int type) { BAN_DATA *pban; int bnum; set_pager_color(AT_IMMORT, ch); switch (type) { case BAN_SITE: send_to_pager("Banned sites:\r\n", ch); send_to_pager("[ #] Warn (Lv) Time By For Site\r\n", ch); send_to_pager("---- ---- ---- ------------------------ --------------- ---- ---------------\r\n", ch); pban = first_ban; set_pager_color(AT_PLAIN, ch); for(bnum = 1; pban; pban = pban->next, bnum++) { pager_printf(ch, "[%2d] %-4s (%2d) %-24s %-15s %4d %c%s%c\r\n", bnum, (pban->warn) ? "YES" : "no", pban->level, pban->ban_time, pban->ban_by, pban->duration, (pban->prefix) ? '*' : ' ', pban->name, (pban->suffix) ? '*' : ' '); } return; case BAN_RACE: send_to_pager("Banned races:\r\n", ch); send_to_pager("[ #] Warn (Lv) Time By For Race\r\n", ch); pban = first_ban_race; break; case BAN_CLASS: send_to_pager("Banned classes:\r\n", ch); send_to_pager("[ #] Warn (Lv) Time By For Class\r\n", ch); pban = first_ban_class; break; default: bug("Bad type in show_bans: %d", type); return; } send_to_pager("---- ---- ---- ------------------------ --------------- ---- ---------------\r\n", ch); set_pager_color(AT_PLAIN, ch); for(bnum = 1; pban; pban = pban->next, bnum++) pager_printf(ch, "[%2d] %-4s (%2d) %-24s %-15s %4d %s\r\n", 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. Shaddai */ 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_AJ_GENERAL) continue; if(pban->prefix && pban->suffix && strstr(new_host, pban->name)) { 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 and races. Shaddai */ bool check_bans(CHAR_DATA *ch, int type) { BAN_DATA *pban; char new_host[MAX_STRING_LENGTH]; int i; bool fMatch = FALSE; char buf[MSL]; switch (type) { case BAN_RACE: pban = first_ban_race; break; 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) { snprintf(buf, MSL, "%s class logging in from %s.", pban->name, ch->desc->host); log_string_plus(buf, LOG_WARN, sysdata.log_level); } return FALSE; } else return TRUE; } if(type == BAN_RACE && pban->flag == ch->race) { if(check_expire(pban)) { dispose_ban(pban, BAN_RACE); save_banlist(); return FALSE; } if(ch->level > pban->level) { if(pban->warn) { snprintf(buf, MSL, "%s race logging in from %s.", pban->name, ch->desc->host); log_string_plus(buf, LOG_WARN, sysdata.log_level); } return FALSE; } else return TRUE; } if(type == BAN_SITE) { if(pban->prefix && pban->suffix && strstr(new_host, pban->name)) 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) { snprintf(buf, MSL, "%s logging in from site %s.", ch->name, ch->desc->host); log_string_plus(buf, LOG_WARN, sysdata.log_level); } return FALSE; } else return TRUE; } } } return FALSE; } bool check_expire(BAN_DATA *pban) { char buf[MSL]; if(pban->unban_date < 0) return FALSE; if(pban->unban_date <= current_time) { snprintf(buf, MSL, "%s ban has expired.", pban->name); log_string_plus(buf, LOG_WARN, sysdata.log_level); return TRUE; } return FALSE; } void dispose_ban(BAN_DATA *pban, int type) { if(!pban) return; if(type != BAN_SITE && type != BAN_CLASS && type != BAN_RACE) { 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; case BAN_RACE: UNLINK(pban, first_ban_race, last_ban_race, next, prev); break; } free_ban(pban); } void free_ban(BAN_DATA *pban) { STRFREE(pban->name); STRFREE(pban->ban_time); STRFREE(pban->note); STRFREE(pban->ban_by); DISPOSE(pban); } void free_bans(void) { BAN_DATA *ban, *ban_next; for(ban = first_ban; ban; ban = ban_next) { ban_next = ban->next; dispose_ban(ban, BAN_SITE); } for(ban = first_ban_race; ban; ban = ban_next) { ban_next = ban->next; dispose_ban(ban, BAN_RACE); } for(ban = first_ban_class; ban; ban = ban_next) { ban_next = ban->next; dispose_ban(ban, BAN_CLASS); } return; }