tmi2_fluffos_v2/
tmi2_fluffos_v2/bin/
tmi2_fluffos_v2/etc/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/ChangeLog.old/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/Win32/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/compat/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/compat/simuls/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/include/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/clone/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/command/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/data/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/etc/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/include/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/inherit/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/inherit/master/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/log/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/compiler/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/efuns/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/operators/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/u/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/tmp/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/windows/
tmi2_fluffos_v2/lib/
tmi2_fluffos_v2/lib/adm/
tmi2_fluffos_v2/lib/adm/daemons/languages/
tmi2_fluffos_v2/lib/adm/daemons/network/I3/
tmi2_fluffos_v2/lib/adm/daemons/virtual/
tmi2_fluffos_v2/lib/adm/daemons/virtual/template/
tmi2_fluffos_v2/lib/adm/news/
tmi2_fluffos_v2/lib/adm/obj/
tmi2_fluffos_v2/lib/adm/obj/master/
tmi2_fluffos_v2/lib/adm/priv/
tmi2_fluffos_v2/lib/adm/shell/
tmi2_fluffos_v2/lib/adm/tmp/
tmi2_fluffos_v2/lib/cmds/
tmi2_fluffos_v2/lib/d/
tmi2_fluffos_v2/lib/d/Conf/
tmi2_fluffos_v2/lib/d/Conf/adm/
tmi2_fluffos_v2/lib/d/Conf/boards/
tmi2_fluffos_v2/lib/d/Conf/cmds/
tmi2_fluffos_v2/lib/d/Conf/data/
tmi2_fluffos_v2/lib/d/Conf/logs/
tmi2_fluffos_v2/lib/d/Conf/obj/
tmi2_fluffos_v2/lib/d/Conf/text/help/
tmi2_fluffos_v2/lib/d/Fooland/adm/
tmi2_fluffos_v2/lib/d/Fooland/data/
tmi2_fluffos_v2/lib/d/Fooland/data/attic/
tmi2_fluffos_v2/lib/d/Fooland/items/
tmi2_fluffos_v2/lib/d/TMI/
tmi2_fluffos_v2/lib/d/TMI/adm/
tmi2_fluffos_v2/lib/d/TMI/boards/
tmi2_fluffos_v2/lib/d/TMI/data/
tmi2_fluffos_v2/lib/d/TMI/rooms/
tmi2_fluffos_v2/lib/d/grid/
tmi2_fluffos_v2/lib/d/grid/adm/
tmi2_fluffos_v2/lib/d/grid/data/
tmi2_fluffos_v2/lib/d/std/
tmi2_fluffos_v2/lib/d/std/adm/
tmi2_fluffos_v2/lib/data/adm/
tmi2_fluffos_v2/lib/data/adm/daemons/
tmi2_fluffos_v2/lib/data/adm/daemons/doc_d/
tmi2_fluffos_v2/lib/data/adm/daemons/emoted/
tmi2_fluffos_v2/lib/data/adm/daemons/network/http/
tmi2_fluffos_v2/lib/data/adm/daemons/network/services/mail_q/
tmi2_fluffos_v2/lib/data/adm/daemons/network/smtp/
tmi2_fluffos_v2/lib/data/adm/daemons/news/archives/
tmi2_fluffos_v2/lib/data/attic/connection/
tmi2_fluffos_v2/lib/data/attic/user/
tmi2_fluffos_v2/lib/data/std/connection/b/
tmi2_fluffos_v2/lib/data/std/connection/l/
tmi2_fluffos_v2/lib/data/std/user/a/
tmi2_fluffos_v2/lib/data/std/user/b/
tmi2_fluffos_v2/lib/data/std/user/d/
tmi2_fluffos_v2/lib/data/std/user/f/
tmi2_fluffos_v2/lib/data/std/user/l/
tmi2_fluffos_v2/lib/data/std/user/x/
tmi2_fluffos_v2/lib/data/u/d/dm/working/doc_d/
tmi2_fluffos_v2/lib/data/u/l/leto/doc_d/
tmi2_fluffos_v2/lib/data/u/l/leto/smtp/
tmi2_fluffos_v2/lib/doc/
tmi2_fluffos_v2/lib/doc/driverdoc/applies/
tmi2_fluffos_v2/lib/doc/driverdoc/applies/interactive/
tmi2_fluffos_v2/lib/doc/driverdoc/concepts/
tmi2_fluffos_v2/lib/doc/driverdoc/driver/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/arrays/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/buffers/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/compile/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/ed/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/filesystem/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/floats/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/functions/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/general/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/mappings/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/numbers/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/parsing/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/constructs/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/preprocessor/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/types/
tmi2_fluffos_v2/lib/doc/driverdoc/platforms/
tmi2_fluffos_v2/lib/doc/mudlib/
tmi2_fluffos_v2/lib/ftp/
tmi2_fluffos_v2/lib/include/driver/
tmi2_fluffos_v2/lib/log/
tmi2_fluffos_v2/lib/log/driver/
tmi2_fluffos_v2/lib/obj/net/
tmi2_fluffos_v2/lib/obj/shells/
tmi2_fluffos_v2/lib/obj/tools/
tmi2_fluffos_v2/lib/std/adt/
tmi2_fluffos_v2/lib/std/board/
tmi2_fluffos_v2/lib/std/body/
tmi2_fluffos_v2/lib/std/fun/
tmi2_fluffos_v2/lib/std/living/
tmi2_fluffos_v2/lib/std/object/
tmi2_fluffos_v2/lib/std/shop/
tmi2_fluffos_v2/lib/std/socket/
tmi2_fluffos_v2/lib/std/user/
tmi2_fluffos_v2/lib/std/virtual/
tmi2_fluffos_v2/lib/student/
tmi2_fluffos_v2/lib/student/kalypso/
tmi2_fluffos_v2/lib/student/kalypso/armor/
tmi2_fluffos_v2/lib/student/kalypso/rooms/
tmi2_fluffos_v2/lib/student/kalypso/weapons/
tmi2_fluffos_v2/lib/u/l/leto/
tmi2_fluffos_v2/lib/u/l/leto/cmds/
tmi2_fluffos_v2/lib/www/errors/
tmi2_fluffos_v2/lib/www/gateways/
tmi2_fluffos_v2/lib/www/images/
tmi2_fluffos_v2/old/
tmi2_fluffos_v2/win32/
//  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;
    }
}