#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; }