// File : /adm/daemons/prune_logdir.c // Creator : Robocoder@TMI // // This daemon prunes the files in the /log directory. // At the moment it ignores the contents of subdirectories, // such as /log/harass. // // This file loosely modelled after Watcher's clean_dir.c #include <config.h> #include <mudlib.h> #include <daemons.h> #include <uid.h> inherit DAEMON; #ifndef MAX_BYTE_TRANSFER #define MAX_BYTE_TRANSFER 10000 #endif #ifndef MAX_LOG_FILE_SIZE // Set threshhold for maximum log file size (at 100K) // Should be smaller than "maximum log size" (specified in config file) #define MAX_LOG_FILE_SIZE (100 * 1024) #endif #ifndef MAX_LOG_DAYS // Set maximum number of days to keep daily backups of "log" & "debug.log" // A week of logs is fairly sufficient. Feel free to adjust it according // to disk space available (more or less). #define MAX_LOG_DAYS 7 #endif void backup_debug_log(); void what_log_days(); #define SECS_IN_DAY (60*60*24) string *log_days; #define PROTECT ({ \ /* \ * Special get_dir() stuff \ */ \ ".", "..", \ \ /* \ * Don't trim these text files \ */ \ "README", "ChangeLog", \ "BUGS", "IDEAS", "PRAISES", "TYPOS", "QUERIES", \ \ /* \ * Redirected output \ * (check your startmud/stopmud scripts) \ */ \ "driver.log", "driver.err", \ "aserver.log", "aserver.err", \ }) int prune_logdir() { mixed *dir; int i, j, s; int l, max; string what, oldwhat; string blk; // Check euid of initiator to confirm correct permissions if (geteuid( previous_object() ) != ROOT_UID && !adminp(geteuid( previous_object() ))) return 0; // Get directory contents array dir = get_dir( LOG_DIR "*" ); if (!dir || !sizeof( dir )) return -1; // Ignore protected files dir -= PROTECT; s = sizeof(dir); for (i = 0; i < s; i++) { what = LOG_DIR + dir[i]; // Skip directories if (file_size( what ) == -2) continue; // Ignore ".old" and ".bak" files l = strlen( what ); if (l >= 4 && (what[l-4 .. l-1] == ".old" || what[l-4 .. l-1] == ".bak")) continue; // Archive "big" files if (file_size( what ) >= MAX_LOG_FILE_SIZE) { oldwhat = what + ".old"; if (file_size( oldwhat ) >= 0) rm( oldwhat ); if (file_size( oldwhat ) != -2) rename( what, oldwhat ); } } // Special handling for ChangeLog // Create backups in the form: // ChangeLog.1, ChangeLog.2, ChangeLog.3, ... if (file_size( LOG_DIR "ChangeLog" ) >= MAX_LOG_FILE_SIZE) { dir = get_dir( LOG_DIR "ChangeLog*" ); dir -= ({ "ChangeLog" }); s = sizeof( dir ); for (max = 0, i = 0; i < s; i++) { l = strlen( dir[i] ); if (l > 10 && sscanf( dir[i][10..l-1], ".%d", l ) && l > max) max = l; } max++; rename( LOG_DIR "ChangeLog", LOG_DIR "ChangeLog." + max ); } #if 0 // Special handling for "debug.log" // Create backups in /log/DEBUGS/ of the form: // feb27, feb28, mar01, mar02, ... if (file_size( LOG_DIR "DEBUGS" ) == -1) mkdir( LOG_DIR "DEBUGS" ); if (file_size( LOG_DIR "DEBUGS" ) == -2) { what_log_days(); dir = get_dir( LOG_DIR "DEBUGS/*" ); dir -= ({ ".", ".." }); i = sizeof(dir); // back it up only if today's log doesn't already exist; // for example, rescheduled prune_logdir for later that same day if (!i || (i && file_size( LOG_DIR "DEBUGS/" + log_days[0]) == -1)) { l = 0; // back up the difference from yesterday's log if ( uptime() > SECS_IN_DAY ) { s = file_size( LOG_DIR "DEBUGS/" + log_days[1]); if (s >= 0 && s < (max = file_size( LOG_DIR "debug.log" ))) { j = 0; while (s < max) { l = max - s; if (l > MAX_BYTE_TRANSFER) l = MAX_BYTE_TRANSFER; blk = read_bytes( LOG_DIR "debug.log", s, l ); if (blk) { write_bytes( LOG_DIR "DEBUGS/" + log_days[0], j, blk ); j += l; s += l; } else { l = 0; break; } } } } // just copy the file if (!l) cp(LOG_DIR "debug.log", LOG_DIR "DEBUGS/" + log_days[0]); } // remove "older" logs while (i--) { if (strlen(dir[i]) < 5 || member_array(dir[i][0..4], log_days) == -1) rm( LOG_DIR "DEBUGS/" + dir[i] ); } } #endif return 1; } // For shutdown calls; // Create backups in /log/DEBUGS/ of the form: // feb27.010033, feb27.024523, ... void backup_debug_log() { string s; #if 0 if (file_name(previous_object()) != SHUTDOWN_D) return; what_log_days(); s = ctime(time()); cp(LOG_DIR "debug.log", sprintf( LOG_DIR "DEBUGS/%s.%s%s%s", log_days[0], s[11..12], s[14..15], s[17..18])); #endif } void what_log_days() { string s; int i, t; if (log_days) return; if (MAX_LOG_DAYS <= 0) { log_days = ({ }); return; } log_days = allocate(MAX_LOG_DAYS); t = time(); for (i = 0; i < MAX_LOG_DAYS; i++) { s = ctime(t); log_days[i] = lower_case(sprintf("%s%c%c", s[4 .. 6 ], s[8] == ' ' ? '0' : s[8], s[9])); t -= SECS_IN_DAY; } }