Ok.. I have a function that seems to have (definately has) a memory leak.
This function was based on a 'plist snippet' that I had found and I
have 'tweaked' it substantially to get to do what I needed it to do.
But...Everytime I run it I lose 2mb of memory. For the life of me I can not
find this leak. I would be incredibily grateful if someone can point me in
the right direction. I am attaching the function below (something I have
never done on this list, so forgive me for taking up some space here please).
Thanks again for any help anyone can provide.
-Mike
void do_plist( CHAR_DATA *ch, char *argument )
{
DIR *dp;
FILE *fp;
CHAR_DATA *victim = NULL;
struct dirent *ep;
char buf[80];
char buf2[MSL];
char buf3[MSL];
char buffer[MAX_STRING_LENGTH*4];
bool fOld;
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
int days;
int type = 0;
int clan = -1;
int god = -1;
int race = -1;
buffer[0] = '\0';
smash_tilde( argument );
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
if ( arg1[0] == '\0' && IS_IMMORTAL(ch))
{
send_to_char( "Syntax: plist clan (name)\n\r", ch );
send_to_char( " plist god (name)\n\r", ch );
send_to_char( " plist race (name)\n\r", ch );
send_to_char( " plist tier1\n\r", ch );
send_to_char( " plist tier2\n\r", ch );
send_to_char( " plist immortals\n\r", ch );
return;
}
if ( arg1[0] == '\0' && !IS_IMMORTAL(ch))
{
send_to_char( "Syntax: plist clan\n\r", ch );
send_to_char( " plist god\n\r", ch );
send_to_char( " plist race\n\r", ch );
return;
}
if (!str_prefix (arg1, "clan"))
{
if (arg2[0] == '\0' && IS_IMMORTAL(ch))
{
send_to_char( "Which clan?{x\n\r",ch);
return;
}
if (IS_IMMORTAL(ch))
{
if ((clan = clan_lookup (arg2)) == 0)
{
send_to_char ("No such clan exists.\n\r", ch);
return;
}
}
else if (is_clan(ch))
clan = ch->clan;
else
{
send_to_char("You are not in a clan.{x\n\r",ch);
return;
}
type = 1;
}
if (!str_prefix (arg1, "god"))
{
if (arg2[0] == '\0' && IS_IMMORTAL(ch))
{
send_to_char( "Which god?{x\n\r",ch);
return;
}
if (IS_IMMORTAL(ch))
{
if ((god = god_lookup (arg2)) == 0)
{
send_to_char ("No such god exists.\n\r", ch);
return;
}
}
else if (is_godfol(ch))
god = ch->god;
else
{
send_to_char("You are not in a church.{x\n\r",ch);
return;
}
type = 2;
}
if (!str_prefix (arg1, "race"))
{
if (arg2[0] == '\0' && IS_IMMORTAL(ch))
{
send_to_char( "Which race?{x\n\r",ch);
return;
}
if (IS_IMMORTAL(ch))
{
if ((race = race_lookup (arg2)) == 0)
{
send_to_char ("No such race exists.\n\r", ch);
return;
}
}
else
race = ch->race;
type = 3;
}
if (!str_prefix (arg1, "tier1") && IS_IMMORTAL(ch))
{
type = 4;
}
if (!str_prefix (arg1, "tier2") && IS_IMMORTAL(ch))
{
type = 5;
}
if (IS_IMMORTAL(ch) && !str_prefix (arg1, "immortals"))
{
type = 6;
}
if (type < 1 && IS_IMMORTAL(ch))
{
send_to_char( "Syntax: plist clan (name)\n\r", ch );
send_to_char( " plist god (name)\n\r", ch );
send_to_char( " plist race (name)\n\r", ch );
send_to_char( " plist tier1\n\r", ch );
send_to_char( " plist tier2\n\r", ch );
send_to_char( " plist immortals\n\r", ch );
return;
}
if (type < 1 && !IS_IMMORTAL(ch))
{
send_to_char( "Syntax: plist clan\n\r", ch );
send_to_char( " plist god\n\r", ch );
send_to_char( " plist race\n\r", ch );
return;
}
if (type == 1)
{
sprintf(buf3, "Last Login Report for %s{x\n\r\n\r",clan_table
[clan].who_name);
send_to_char (buf3, ch);
}
if (type == 2)
{
sprintf(buf3, "Last Login Report for %s{x\n\r\n\r",god_table
[god].who_name);
send_to_char (buf3, ch);
}
if (type == 3)
{
sprintf(buf3, "Last Login Report for %s{x\n\r\n\r",race_table
[race].who_name);
send_to_char (buf3, ch);
}
if (type == 4)
{
sprintf(buf3, "Last Login Report for Tier 1 Players{x\n\r\n\r");
send_to_char (buf3, ch);
}
if (type == 5)
{
sprintf(buf3, "Last Login Report for Tier 2 Players{x\n\r\n\r");
send_to_char (buf3, ch);
}
if (type == 6 && IS_IMMORTAL(ch))
{
sprintf(buf3, "Last Login Report for Immortals{x\n\r\n\r");
send_to_char (buf3, ch);
}
dp = opendir ("../player");
if (dp != NULL)
{
while ( (ep = readdir (dp)) )
{
if ( ep->d_name[0] == '.' )
continue;
victim = new_char();
victim->pcdata = new_pcdata();
fOld = FALSE;
sprintf( buf2, "%s%s", PLAYER_DIR, capitalize( ep->d_name ) );
if ( ( fp = fopen( buf2, "r" ) ) != NULL )
{
int iNest;
for ( iNest = 0; iNest < MAX_NEST; iNest++ )
rgObjNest[iNest] = NULL;
fOld = TRUE;
for ( ; ; )
{
char letter;
char *word;
letter = fread_letter( fp );
if ( letter == '*' )
{
fread_to_eol( fp );
continue;
}
if ( letter != '#' )
{
bug( "Load_char_obj: # not found.", 0 );
break;
}
word = fread_word( fp );
if ( !str_cmp( word, "PLAYER" ) ) fread_char( victim, fp );
else if ( !str_cmp( word, "OBJECT" ) ) break;
else if ( !str_cmp( word, "O" ) ) break;
else if ( !str_cmp( word, "PET" ) ) break;
else if ( !str_cmp( word, "END" ) ) break;
else
{
bug( "Load_char_obj: bad section.", 0 );
break;
}
}
fclose( fp );
}
if (!fOld)
continue;
if (type == 1 && (victim->clan != clan || IS_IMMORTAL(victim)))
continue;
if (type == 2 && (victim->god != god || IS_IMMORTAL(victim)))
continue;
if (type == 3 && (victim->race != race || IS_IMMORTAL(victim)))
continue;
if (type == 4 && (victim->tier > 1 || IS_IMMORTAL(victim)))
continue;
if (type == 5 && (victim->tier != 2 || IS_IMMORTAL(victim)))
continue;
if (type == 6 && (!IS_IMMORTAL(victim) || victim->level > ch->level))
continue;
sprintf( buf, "%s%s", "../player/", ep->d_name );
days = days_since_last_file_mod( buf );
sprintf( buf, "%-15s %s%-3d{x days\n\r",
ep->d_name, days >= 30 ? "{r" : days >= 15 ? "{Y" : days >=
10 ? "{g" : "{G", days);
strcat( buffer, buf );
}
closedir (dp);
free_pcdata(victim->pcdata);
free_char(victim);
}
else
perror ("Couldn't open the directory");
page_to_char( buffer, ch );
free_string(buffer);
free_string(buf);
free_string(buf2);
free_string(buf3);
return;
}