logRotate.c 2.99 KB
#include <sys/select.h> /* for select system call and related */
#include <time.h>
#include <unistd.h>     /* for fork and exec */
#include <sys/types.h>
#include <sys/wait.h>   /* for wait */
#include <stdio.h>      /* fopen and stuff */
#include <stdlib.h>     /* exit */
#include <string.h>     /* strncpy, memcpy, etc. */
#include <syslog.h>
#include <errno.h>

#include "include/appConfig.h"
#include "include/monitor.h"
#include "include/server.h"


void
_gzip(tVirtualItemServer * server, const char * logName)
{
    pid_t gzipPid = fork();

    switch(gzipPid) {
        pid_t tmpPid;

        case 0:
            /* first close everything in child */
            serverClose(server);

            // We don't care about finishing of child, so decouple it
            // by using a second child that stop immediatly
            tmpPid = fork();
            if (0 == tmpPid) {
                syslog(LOG_INFO, "gzip: %s", logName);
                // if (-1 == execl("/bin/gzip", "/bin/gzip", "-9", logName, (char *) 0)) {
                if (-1 == execl("/bin/gzip", "/bin/gzip", logName, (char *) 0)) {
                    syslogMonitor(LOG_ERR, MON_WARNING, "logrotate.gzip",
                            "execl failed for gzip %s: %s", logName, strerror(errno));
                }
            }
            exit(EXIT_SUCCESS);

        case -1:
            syslogMonitor(LOG_ERR, MON_WARNING, "logrotate.fork",
                    "fork failed for gzip %s: %s", logName, strerror(errno));
            break;

        default:
            wait(NULL);
            break;
    }
}


void
logRotate(tVirtualItemServer * server)
{
    static char logName[1024]     = "";

    char        strftimeName[128] = "";
    char        newLogName[1024]  = "";

    time_t      t;
    struct tm   *tmp;

    t   = time(NULL);
    tmp = localtime(&t);
    if (tmp == NULL) {
        syslogMonitor(LOG_ERR, MON_WARNING, "logrotate.localtime",
                "can't get localtime for new logname. continue with old one");
        return;
    }

    if (strftime(
                strftimeName,
                sizeof(strftimeName)-1,
                server->namePat,
                tmp) == 0)
    {
        syslogMonitor(LOG_ERR, MON_WARNING, "logrotate.strftime", 
                "strftime returned 0 for new logname. continue with old one");
        return;
    }

    snprintf(
            newLogName,
            sizeof(newLogName)-1,
            "%s/%s",
            server->logPath,
            strftimeName);

    if (0 != strncmp(logName, newLogName, sizeof(logName)-1)) {
        if (0 != verbose) {
            syslog(LOG_INFO, "actual logfile name: %s", logName);
            syslog(LOG_INFO, "new logfile name: %s", newLogName);
        }

        if (NULL != server->wHandle) {
            fclose(server->wHandle);
            server->wHandle = NULL;

            if (doGzip) {
                _gzip(server, logName);
            }
        }

        strncpy(logName, newLogName, sizeof(logName)-1);
        server->wHandle = fopen(logName, "w");
    }
}