#include /* for select system call and related */ #include #include /* for fork and exec */ #include #include #include /* fopen and stuff */ #include /* exit */ #include /* strncpy, memcpy, etc. */ #include #include #include "../include/monitor.h" extern int verbose; void logRotate(FILE ** handle, char * path, char * pattern) { 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_INFO, "logrotate.localtime", "can't get localtime for new logname. continue with old one"); return; } if (strftime(strftimeName, sizeof(strftimeName)-1, pattern, tmp) == 0) { syslogMonitor(LOG_ERR, MON_INFO, "logrotate.strftime", "strftime returned 0 for new logname. continue with old one"); return; } snprintf(newLogName, sizeof(newLogName)-1, "%s/%s", path, 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 != *handle) { fclose(*handle); pid_t gzipPid = fork(); switch(gzipPid) { pid_t tmpPid; case 0: // 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)) { syslogMonitor(LOG_ERR, MON_INFO, "logrotate.gzip", "execl failed for gzip %s: %s", logName, strerror(errno)); } } exit(EXIT_SUCCESS); case -1: syslogMonitor(LOG_ERR, MON_INFO, "logrotate.fork", "fork failed for gzip %s: %s", logName, strerror(errno)); break; default: wait(NULL); break; } } strncpy(logName, newLogName, sizeof(logName)-1); *handle = fopen(logName, "w"); } }