atd/area/
atd/build/
atd/clans/
atd/log/
atd/player/store/
atd/site/
atd/src/bin/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include "merc.h"

/* Globals */
time_t		  pfile_time;
struct tm *         new_pfile_time;
struct tm           new_pfile_struct;
time_t new_pfile_time_t;
sh_int	num_pfiles; /* Count up number of pfiles */
time_t	now_time;
sh_int	deleted = 0;
sh_int   days = 0;

#if defined(KEY)
#undef KEY
#endif

#define KEY( literal, field, value )    \
    if ( !str_cmp( word, literal ) )    \
    {                                   \
        field  = value;                 \
        fMatch = TRUE;                  \
        break;                          \
    }

#ifdef SKEY
#undef SKEY
#endif

#define SKEY( string, field )           \
    if ( !str_cmp( word, string ) )     \
    {                                   \
        free_string( field );           \
        field = fread_string( fp );     \
        fMatch = TRUE;                  \
        break;                          \
    }


void fread_pfile( FILE *fp, time_t tdiff, char *fname, bool count )
{
    char *word;
    char *name = NULL;
    sh_int mob_kills = 0;
    sh_int status    = 0;
    sh_int file_ver  = 0;
    int    played    = 0;
    int    level     = 0;
    int    extra     = 0;
    bool fMatch;

    for ( ; ; )
    {
	word   = feof( fp ) ? "End" : fread_word( fp );
	fMatch = FALSE;

	switch ( UPPER(word[0]) )
	{
	case '*':
	    fMatch = TRUE;
	    fread_to_eol( fp );
	    break;
        case 'E':
            KEY( "Extra",       extra,      fread_number( fp ) );
            if ( !strcmp( word, "End" ) )
	        goto timecheck;
	    break;
	case 'L':
            KEY( "Level",       level,      fread_number( fp ) );
            break;
	case 'N':
            KEY( "Name",        name, 	    fread_string( fp ) );
	    break;
        case 'P':
            if( !str_cmp( word, "PkPdMkMd" ) )
            {
                fread_number( fp );
                fread_number( fp );
                mob_kills = fread_number( fp );
                fread_number( fp );
                break;
            }
            KEY( "Played",      played,     fread_number( fp ) );
            break;
        case 'V':
            KEY( "Version",	file_ver,   fread_number( fp ) );
	    break;
        case 'R':
            KEY( "Race",        status,     fread_number( fp ) );
            break;
        }

	if ( !fMatch )
	   fread_to_eol( fp );
    }

timecheck:

    if( ( status > 0
          || level >= LEVEL_BUILDER
          || IS_SET( extra, EXTRA_BORN ) 
          || ( played > 0 && played / 3600 >= 100 )  )
	&& tdiff < 93 )
        return;

    if( count == FALSE )
    {
        if( mob_kills < 1500 && (int) tdiff > sysdata.newbie_purge )
        {
            if ( unlink(fname) == -1 )
                perror( "Unlink" );
            else
            {
                days = sysdata.newbie_purge;
                sprintf( log_buf, "Player %s was deleted. Exceeded time limit of %d days.",
                         name, days );
                log_string( log_buf );
                deleted++;
                return;
            }
        }

        if ( (int )tdiff > sysdata.regular_purge )
        {
            if ( unlink(fname) == -1 )
                perror( "Unlink" );
            else
            {
                days = sysdata.regular_purge;
                sprintf( log_buf, "Player %s was deleted. Exceeded time limit of %d days.", name, days );
                log_string( log_buf );
                deleted++;
                return;
            }
        }
    }

    return;
}


void read_pfile( char *dirname, char *filename, bool count )
{
  FILE *fp;
  char fname[MAX_STRING_LENGTH];
  struct stat fst;
  time_t tdiff;

  now_time = time(0);

  sprintf( fname, "%s%s", dirname, filename );

  if ( stat( fname, &fst ) != -1 )
  {
      tdiff = (now_time - fst.st_mtime) / 86400;
      if ( ( fp = fopen ( fname, "r" ) ) != NULL )
      {
          for ( ; ; )
          {
              char letter;
              char *word;

              letter = fread_letter( fp );

              if ( letter != '#' )
                  continue;

              word = fread_word( fp );

              if ( !str_cmp( word, "End" ) )
                  break;

              if ( !str_cmp( word, "PLAYER" ) )
                  fread_pfile( fp, tdiff, fname, count );
              else
                  if ( !str_cmp( word, "END" ) )
                      break;
          }
          fclose( fp );
    }
  }
  return;
}

void pfile_scan( bool count )
{
  DIR *dp;
  struct dirent *dentry;
  sh_int cou = 0;
  deleted = 0;

  now_time = time(0);
  nice(20);

  dp = opendir( PLAYER_DIR );
  dentry = readdir( dp );
  while ( dentry )
  {
      if ( dentry->d_name[0] != '.'
           && str_cmp( dentry->d_name, "backup" )
           && str_cmp( dentry->d_name, "store" ) 
           && str_cmp( dentry->d_name, "deleted" )
	   && str_cmp( dentry->d_name, "pfiles.tar" ) )
      {
	      read_pfile( PLAYER_DIR,  dentry->d_name, count );
          cou++;

      }
      dentry = readdir( dp );
  }
  closedir( dp );

  if( !count )
      log_string( "Pfile cleanup completed." );
  else
      log_string( "Pfile count completed." );

  sprintf( log_buf, "Total pfiles scanned: %d", cou );
  log_string( log_buf );

  if( !count )
  {
      sprintf( log_buf, "Total pfiles deleted: %d", deleted );
      log_string( log_buf );

      sprintf( log_buf, "Total pfiles remaining: %d", cou - deleted );
      num_pfiles = cou - deleted;
      log_string( log_buf );
  }
  else
      num_pfiles = cou;

  return;
}

void do_pfiles( CHAR_DATA *ch, char *argument )
{
   if ( IS_NPC(ch) )
   {
       send_to_char( "Mobs cannot use this command!\n\r", ch );
       return;
   }

   if ( argument[0] == '\0' || !argument )
   {
#if 0
       strcpy( buf, "tar -cf " );
       strcat( buf, PLAYER_DIR );
       strcat( buf, "pfiles.tar " );
       strcat( buf, PLAYER_DIR );
       strcat( buf, "*/*" );

       system( buf );
#endif
       sprintf( log_buf, "Manual pfile cleanup started by %s.", ch->name );
       log_string( log_buf );
       pfile_scan( FALSE );
       return;
   }

   if ( !str_cmp( argument, "settime" ) )
   {
       new_pfile_time_t = current_time + 86400;
       save_sysdata( sysdata );
       send_to_char( "New cleanup time set for 24 hrs from now.\n\r", ch );
       return;
   }

   if ( !str_cmp( argument, "count" ) )
   {
       sprintf( log_buf, "Pfile count started by %s.", ch->name );
       log_string( log_buf );
       pfile_scan( TRUE );
       return;
   }

   send_to_char( "Invalid argument.\n\r", ch );
   return;
}

void check_pfiles( time_t reset )
{
    if ( new_pfile_time_t <= current_time )
    {
        if( sysdata.CLEANPFILES == TRUE )
        {
            char buf[MAX_STRING_LENGTH];

            strcpy( buf, "tar -cf " );
            strcat( buf, PLAYER_DIR );
            strcat( buf, "pfiles.tar " );
            strcat( buf, PLAYER_DIR );
            strcat( buf, "*/*" );

            system( buf );

            new_pfile_time_t = current_time + 86400;
            save_sysdata( sysdata );
            log_string( "Automated pfile cleanup beginning...." );
            pfile_scan( FALSE );
        }
        else
        {
            new_pfile_time_t = current_time + 86400;
            save_sysdata( sysdata );
            log_string( "Counting pfiles....." );
            pfile_scan( TRUE );
        }
    }
    return;
}