/*~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- ~ 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. ~ ~ ~ ~ Ack 2.2 improvements copyright (C) 1994 by Stephen Dooley ~ ~ ACK!MUD is modified Merc2.0/2.1/2.2 code (c)Stephen Zepp 1998 Ver: 4.3 ~ ~ ~ ~ In order to use any part of this PA Diku Mud, you must comply with ~ ~ both the original Diku license in 'license.doc' as well the Merc ~ ~ license in 'license.txt', and the Ack!Mud license in 'ack_license.txt'.~ ~ In particular, you may not remove any of these copyright notices. ~ ~ ~ ~ _______ _____ ~ ~ / __ /\ / ___ \ 222222 PA_MUD by Amnon Kruvi ~ ~ /______/ / / /___\ \ 2 PA_MUD is modified ~ ~ / _______/ / _______ \ 2 Ack!Mud, v4.3 ~ ~ /_/ /_/ \_\ 2 ~ ~ 2 ~ ~ 2222222 ~ ~ ~ ~ ~ ~ Years of work have been invested to create DIKU, Merc, Ack and PA. ~ ~ Please show your respect by following the licenses, and issuing ~ ~ credits where due. ~ ~ ~ ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-*/ #include <sys/types.h> #include <sys/time.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #include "ack.h" #include "tables.h" #include "ssm.h" /* String checker, Spectrum 11/96 * * Basic idea is to walk through all the strings we know about, and mark them * as referenced. Then we check for strings that have a reference count thats * different from ptr->usage and log them */ /* * Things which are walked (anything else must be touched from these): * * o char_list * o descriptor_list * o object_list * o obj_index hash table * o socials table * o helps * o areas * o notes/ideas/etc */ extern char * quote_table[MAX_QUOTE]; /* From ban.c: */ extern BAN_DATA *first_ban; extern OBJ_INDEX_DATA * obj_index_hash [MAX_KEY_HASH]; /* Main code */ static void touch(char *str) { BufEntry *p; if (!str) return; if (str < string_space || str > top_string) return; /* not in string space */ p = (BufEntry *) (str - HEADER_SIZE); p->ref++; } static void clear(void) { /* Set all reference counts to 0 */ BufEntry *p; for (p = ssm_buf_head; p; p = p->next) p->ref = 0; } static BufEntry *dump_ptr[2]; static long dump(void) { /* Dump strings that have ref!=usage */ FILE *dumpf; BufEntry *p; long count = 0; fclose(fpReserve); dumpf = fopen("../reports/leaks.dmp", "w"); for (p = ssm_buf_head; p; p = p->next) { if (p->usage > 0 && p->usage != p->ref) { /* things to ignore: * the common <%hhp %mm %vmv> prompt string * a '$' (from socials) */ if (!str_cmp(p->buf, "<%hhp %mm %vmv> ") || !str_cmp(p->buf, "$")) continue; fprintf(dumpf, "usage %2d/%2d, caller %s, string %s\n", p->ref, p->usage, p->caller, p->buf); count += abs(p->usage - p->ref); } dump_ptr[0]=dump_ptr[1]; dump_ptr[1]=p; } fclose(dumpf); fpReserve = fopen(NULL_FILE, "r"); return count; } static void walk_web () { touch(history1); touch(history2); touch(history3); touch(history4); touch(history5); touch(history6); touch(history7); touch(history8); touch(history9); touch(history10); touch(web_data.last_killed_in_pit); touch(web_data.last_kills_in_pit); touch(web_data.highest_ranking_player); touch(web_data.newest_player); return; } static void walk_queue_data(QUEUE_DATA * q) { if (!q) return; touch(q->command); walk_queue_data(q->next); } static void walk_pcdata(PC_DATA * p) { int i; if (!p) return; touch(p->pwd); touch(p->bamfin); touch(p->bamfout); touch(p->title); touch(p->room_enter); touch(p->room_exit); touch(p->host); touch(p->who_name); touch(p->header); touch(p->message ); touch(p->lastlogin); touch(p->load_msg); for ( i = 0; i < MAX_IGNORES; i++ ) touch( p->ignore_list[i]); for ( i = 0; i < 5 ; i++ ) { touch( p->pedit_string[i] ); } touch( p->pedit_state ); touch( p->email_address ); walk_queue_data(p->queue); } static void walk_brand_data(BRAND_DATA * brand) { if (!brand) return; touch(brand->branded); touch(brand->branded_by); touch(brand->dt_stamp); touch(brand->message); touch(brand->priority); } static void walk_brands( void ) { BRAND_DATA * this_brand; DL_LIST * brands; for (brands = first_brand ; brands; brands = brands->next) { this_brand = brands->this_one; walk_brand_data(this_brand); } } static void walk_char_data(CHAR_DATA * ch) { int i; if (!ch) return; walk_pcdata(ch->pcdata); touch(ch->name); touch(ch->prompt); touch(ch->old_prompt); touch(ch->last_tell); for ( i = 0;i < 5;i++ ) { touch( ch->alias[i]); touch( ch->alias_command[i]); } } static void walk_obj_index_data(OBJ_INDEX_DATA * o) { if (!o) return; touch(o->name); touch(o->short_descr); touch(o->description); touch(o->owner); touch(o->image); } static void walk_obj_data(OBJ_DATA * o) { if (!o) return; touch(o->owner); touch(o->name); touch(o->short_descr); touch(o->description); } static void walk_area_data(AREA_DATA * ad) { if (!ad) return; touch(ad->filename); touch(ad->name); touch(ad->owner); touch(ad->can_read); touch(ad->can_write); touch(ad->keyword); /* spec- missed strings */ } static void walk_social_type(struct social_type *s) { if (!s) return; touch( s->name ); touch(s->char_no_arg); touch(s->others_no_arg); touch(s->char_found); touch(s->others_found); touch(s->vict_found); touch(s->char_auto); touch(s->others_auto); } static void walk_help_data(HELP_DATA * h) { if (!h) return; touch(h->keyword); touch(h->text); } static void walk_descriptor_data(DESCRIPTOR_DATA * d) { if (!d) return; touch(d->host); if ( d->connected != CON_PLAYING ) walk_char_data (d->character); } static void walk_ban_data(BAN_DATA * b) { touch(b->name); touch( b->banned_by); touch( b->note); } static void walk_socials(void) { extern int maxSocial; int i; for (i = 0; i < maxSocial; i++) walk_social_type(&social_table[i]); } static void walk_helps(void) { HELP_DATA *h; for (h = first_help; h; h = h->next) walk_help_data(h); } static void walk_chars(void) { CHAR_DATA *ch; for (ch = first_char; ch; ch = ch->next) walk_char_data(ch); } static void walk_descriptors(void) { DESCRIPTOR_DATA *d; for (d = first_desc; d; d = d->next) walk_descriptor_data(d); } static void walk_objects(void) { OBJ_DATA *o; for (o = first_obj; o; o = o->next) walk_obj_data(o); walk_obj_data(vehicle_weapon); } static void walk_areas(void) { AREA_DATA *ad; for (ad = first_area; ad; ad = ad->next) walk_area_data(ad); } static void walk_obj_indexes(void) { OBJ_INDEX_DATA *o; int i; for (i = 0; i < MAX_KEY_HASH; i++) for (o = obj_index_hash[i]; o; o = o->next) walk_obj_index_data(o); } static void walk_bans(void) { BAN_DATA *b; for (b = first_ban; b; b = b->next) walk_ban_data(b); } static void walk_message_data(MESSAGE_DATA * m) { if (!m) return; touch(m->message); touch(m->author); touch(m->title ); } void walk_messages( MESSAGE_DATA * m ) { for( ; m ; m = m->next ) walk_message_data( m ); } void walk_boards( void ) { BOARD_DATA *board; extern BOARD_DATA *first_board; for (board = first_board; board; board = board->next) walk_messages(board->first_message); } void walk_sysdata( void ) { sh_int looper; touch( sysdata.playtesters ); for ( looper = 0; looper < 5; looper++ ) touch( sysdata.imms[looper].this_string); } void walk_quotes( void ) { sh_int looper; for ( looper = 0; looper < MAX_QUOTE; looper++ ) touch( quote_table[looper] ); } static void walk_disable_data(DISABLED_DATA * disable) { if (!disable) return; touch(disable->disabled_by); } void walk_disablelist(void) { DISABLED_DATA *disable; for (disable = disabled_first; disable; disable = disable->next) { walk_disable_data(disable); } } void walk_alliances(void) { int i; for ( i=0;i<MAX_ALLIANCE;i++ ) { if ( alliance_table[i].name == NULL ) break; touch( alliance_table[i].name ); touch( alliance_table[i].leader ); touch( alliance_table[i].history ); } } void walk_scores(void) { int i; for ( i=0;i<100;i++ ) { touch( score_table[i].name ); touch( score_table[i].killedby ); } for ( i=0;i<30;i++ ) touch( rank_table[i].name ); } void walk_multiplay(void) { int i; for ( i=0;i<30;i++ ) { touch(multiplay_table[i].name); touch(multiplay_table[i].host); } } void walk_build_table(void) { int i; for ( i=0;i<MAX_BUILDING;i++ ) { touch(build_table[i].name); touch(build_table[i].desc); touch(build_table[i].symbol); touch(build_help_table[i].help); } } void walk_buildings(void) { BUILDING_DATA *bld; for ( bld = first_building;bld;bld = bld->next ) { touch( bld->owned ); touch( bld->name ); touch( bld->attacker ); } } void walk_vehicles(void) { VEHICLE_DATA *vhc; for ( vhc = first_vehicle;vhc;vhc = vhc->next ) { touch( vhc->name ); touch( vhc->desc ); } } void do_scheck(CHAR_DATA * ch, char *argument) { char buf[MAX_STRING_LENGTH]; extern bool disable_timer_abort; disable_timer_abort = TRUE; clear(); walk_socials(); walk_helps(); walk_chars(); walk_descriptors(); walk_objects(); walk_areas(); walk_bans(); walk_obj_indexes(); walk_boards(); walk_brands( ); walk_sysdata( ); walk_quotes( ); walk_disablelist( ); walk_buildings( ); walk_vehicles( ); walk_scores( ); walk_multiplay( ); walk_build_table( ); walk_alliances( ); walk_web (); sprintf(buf, "%ld leaks dumped to leaks.dmp\n\r", dump()); send_to_char(buf, ch); disable_timer_abort = FALSE; }