diff options
author | wbx <wbx@hydrogenium.(none)> | 2009-05-17 14:41:34 +0200 |
---|---|---|
committer | wbx <wbx@hydrogenium.(none)> | 2009-05-17 14:41:34 +0200 |
commit | 219a6dab8995aad9ac4860cc1a84d6f3509a03a4 (patch) | |
tree | b9c0f3c43aebba2fcfef777592d0add39f2072f4 /package/logrotate/patches/patch-logrotate_c |
Initial import
Diffstat (limited to 'package/logrotate/patches/patch-logrotate_c')
-rw-r--r-- | package/logrotate/patches/patch-logrotate_c | 429 |
1 files changed, 429 insertions, 0 deletions
diff --git a/package/logrotate/patches/patch-logrotate_c b/package/logrotate/patches/patch-logrotate_c new file mode 100644 index 000000000..0222b1e5c --- /dev/null +++ b/package/logrotate/patches/patch-logrotate_c @@ -0,0 +1,429 @@ +$Id$ +--- logrotate-3.7.1.orig/logrotate.c Tue Oct 19 23:41:24 2004 ++++ logrotate-3.7.1/logrotate.c Sat Jan 20 18:56:30 2007 +@@ -11,6 +11,7 @@ + #include <sys/wait.h> + #include <time.h> + #include <unistd.h> ++#include <glob.h> + + #ifdef WITH_SELINUX + #include <selinux/selinux.h> +@@ -22,6 +23,10 @@ int selinux_enabled=0; + #include "log.h" + #include "logrotate.h" + ++#if !defined(GLOB_ABORTED) && defined(GLOB_ABEND) ++#define GLOB_ABORTED GLOB_ABEND ++#endif ++ + typedef struct { + char * fn; + struct tm lastRotated; /* only tm.mon, tm_mday, tm_year are good! */ +@@ -42,6 +47,14 @@ int debug = 0; + char * mailCommand = DEFAULT_MAIL_COMMAND; + time_t nowSecs = 0; + ++static int globerr(const char * pathname, int theerr) { ++ message(MESS_ERROR, "error accessing %s: %s\n", pathname, ++ strerror(theerr)); ++ ++ /* We want the glob operation to continue, so return 0 */ ++ return 1; ++} ++ + static logState * findState(const char * fn, struct stateSet * sip) { + int i; + logState * states = sip->states; +@@ -49,9 +62,11 @@ static logState * findState(const char * + struct tm now = *localtime(&nowSecs); + time_t lr_time; + ++ /* find the filename fn in the statesPtr list */ + for (i = 0; i < numStates; i++) + if (!strcmp(fn, states[i].fn)) break; + ++ /* not in statesPtr list, so add new entry */ + if (i == numStates) { + i = numStates++; + states = realloc(states, sizeof(*states) * numStates); +@@ -75,10 +90,7 @@ static logState * findState(const char * + } + + static int runScript(char * logfn, char * script) { +- int fd; +- char *filespec; + int rc; +- char buf[256]; + + if (debug) { + message(MESS_DEBUG, "running script with arg %s: \"%s\"\n", +@@ -86,39 +98,24 @@ static int runScript(char * logfn, char + return 0; + } + +- filespec = buf; +- snprintf(buf, sizeof(buf), "%s/logrotate.XXXXXX", getenv("TMPDIR") ?: "/tmp"); +- fd = -1; +- if (!filespec || (fd = mkstemp(filespec)) < 0 || fchmod(fd, 0700)) { +- message(MESS_DEBUG, "error creating %s: %s\n", filespec, +- strerror(errno)); +- if (fd >= 0) { +- close(fd); +- unlink(filespec); +- } +- return -1; +- } +- +- if (write(fd, "#!/bin/sh\n\n", 11) != 11 || +- write(fd, script, strlen(script)) != strlen(script)) { +- message(MESS_DEBUG, "error writing %s\n", filespec); +- close(fd); +- unlink(filespec); +- return -1; +- } +- +- close(fd); +- + if (!fork()) { +- execlp(filespec, filespec, logfn, NULL); ++ execl("/bin/sh", "sh", "-c", script, NULL); + exit(1); + } + + wait(&rc); ++ return rc; ++} + +- unlink(filespec); ++static int removeLogFile(char * name) { ++ message(MESS_DEBUG, "removing old log %s\n", name); + +- return rc; ++ if (!debug && unlink(name)) { ++ message(MESS_ERROR, "Failed to remove old log %s: %s\n", ++ name, strerror(errno)); ++ return 1; ++ } ++ return 0; + } + + static int compressLogFile(char * name, logInfo * log, struct stat *sb) { +@@ -265,6 +262,25 @@ static int mailLog(char * logFile, char + return rc; + } + ++static int mailLogWrapper (char * mailFilename, char * mailCommand, int logNum, logInfo * log) { ++ /* if the log is compressed (and we're not mailing a ++ * file whose compression has been delayed), we need ++ * to uncompress it */ ++ if ((log->flags & LOG_FLAG_COMPRESS) && ++ !((log->flags & LOG_FLAG_DELAYCOMPRESS) && ++ (log->flags & LOG_FLAG_MAILFIRST))) { ++ if (mailLog(mailFilename, mailCommand, ++ log->uncompress_prog, log->logAddress, ++ log->files[logNum])) ++ return 1; ++ } else { ++ if (mailLog(mailFilename, mailCommand, NULL, ++ log->logAddress, mailFilename)) ++ return 1; ++ } ++ return 0; ++} ++ + static int copyTruncate(char * currLog, char * saveLog, struct stat * sb, int flags) { + char buf[BUFSIZ]; + int fdcurr = -1, fdsave = -1; +@@ -424,12 +440,15 @@ int findNeedRotating(logInfo * log, int + switch (log->criterium) { + case ROT_WEEKLY: + /* rotate if: +- 1) the current weekday is before the weekday of the +- last rotation ++ 1) the day of the week is the same as the day of the week of ++ the previous rotation but not the same day of the year ++ this will rotate it on the same day every week, but not ++ twice a day. + 2) more then a week has passed since the last + rotation */ +- state->doRotate = ((now.tm_wday < state->lastRotated.tm_wday) || +- ((mktime(&now) - mktime(&state->lastRotated)) > ++ state->doRotate = ((now.tm_wday == state->lastRotated.tm_wday && ++ now.tm_yday != state->lastRotated.tm_yday) || ++ ((mktime(&now) - mktime(&state->lastRotated)) > + (7 * 24 * 3600))); + break; + case ROT_MONTHLY: +@@ -479,6 +498,9 @@ int rotateSingleLog(logInfo * log, int l + char * baseName; + char * dirName; + char * firstRotated; ++ char * glob_pattern; ++ glob_t globResult; ++ int rc; + size_t alloc_size; + int rotateCount = log->rotateCount ? log->rotateCount : 1; + int logStart = (log->logStart == -1) ? 1 : log->logStart; +@@ -509,7 +531,7 @@ int rotateSingleLog(logInfo * log, int l + + alloc_size = strlen(dirName) + strlen(baseName) + + strlen(log->files[logNum]) + strlen(fileext) + +- strlen(compext) + 10; ++ strlen(compext) + 18; + + oldName = alloca(alloc_size); + newName = alloca(alloc_size); +@@ -531,16 +553,116 @@ int rotateSingleLog(logInfo * log, int l + /* First compress the previous log when necessary */ + if (log->flags & LOG_FLAG_COMPRESS && + log->flags & LOG_FLAG_DELAYCOMPRESS) { +- struct stat sbprev; +- +- sprintf(oldName, "%s/%s.%d%s", dirName, baseName, logStart, fileext); +- if (stat(oldName, &sbprev)) { +- message(MESS_DEBUG, "previous log %s does not exist\n", +- oldName); +- } else { +- hasErrors = compressLogFile(oldName, log, &sbprev); ++ if (log->flags & LOG_FLAG_DATEEXT) { ++ /* glob for uncompressed files with our pattern */ ++ glob_pattern = malloc(strlen(dirName) + strlen(baseName) ++ + strlen(fileext) + 44 ); ++ sprintf(glob_pattern, ++ "%s/%s-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%s", ++ dirName, baseName, fileext); ++ rc = glob(glob_pattern, 0, globerr, &globResult); ++ if (!rc && globResult.gl_pathc > 0) { ++ for (i = 0; i < globResult.gl_pathc && !hasErrors; i++) { ++ struct stat sbprev; ++ sprintf(oldName,"%s",(globResult.gl_pathv)[i]); ++ if (stat(oldName, &sbprev)) { ++ message(MESS_DEBUG, "previous log %s does not exist\n", oldName); ++ } else { ++ hasErrors = compressLogFile(oldName, log, &sbprev); ++ } ++ } ++ } else { ++ message (MESS_DEBUG, "glob finding logs to compress failed\n"); ++ /* fallback to old behaviour */ ++ sprintf(oldName, "%s/%s.%d%s", dirName, baseName, logStart, fileext); ++ } ++ globfree(&globResult); ++ free(glob_pattern); ++ } else { ++ struct stat sbprev; ++ ++ sprintf(oldName, "%s/%s.%d%s", dirName, baseName, logStart, fileext); ++ if (stat(oldName, &sbprev)) { ++ message(MESS_DEBUG, "previous log %s does not exist\n", ++ oldName); ++ } else { ++ hasErrors = compressLogFile(oldName, log, &sbprev); ++ } + } + } ++ ++ firstRotated = alloca(strlen(dirName) + strlen(baseName) + ++ strlen(fileext) + strlen(compext) + 30); ++ ++ if(log->flags & LOG_FLAG_DATEEXT) { ++ /* glob for compressed files with our pattern ++ * and compress ext */ ++ glob_pattern = malloc(strlen(dirName)+strlen(baseName) ++ +strlen(fileext)+strlen(compext)+44); ++ sprintf(glob_pattern, ++ "%s/%s-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%s%s", ++ dirName, baseName, fileext, compext); ++ rc = glob(glob_pattern, 0, globerr, &globResult); ++ if (!rc) { ++ /* search for files to drop, if we find one remember it, ++ * if we find another one mail and remove the first and ++ * remember the second and so on */ ++ struct stat fst_buf; ++ int mail_out = -1; ++ /* remove the first (n - rotateCount) matches ++ * no real rotation needed, since the files have ++ * the date in their name */ ++ for (i = 0; i < globResult.gl_pathc; i++) { ++ if( !stat((globResult.gl_pathv)[i],&fst_buf) ) { ++ if ((i <= ((int)globResult.gl_pathc - rotateCount)) ++ || ((log->rotateAge > 0) ++ && (((nowSecs - fst_buf.st_mtime)/60/60/24) ++ > log->rotateAge))) { ++ if ( mail_out != -1 ) { ++ if (!hasErrors && log->logAddress) { ++ char * mailFilename = (globResult.gl_pathv)[mail_out]; ++ hasErrors = mailLogWrapper(mailFilename, mailCommand, logNum, log); ++ if (!hasErrors) ++ hasErrors = removeLogFile(mailFilename); ++ } ++ } ++ mail_out = i; ++ } ++ } ++ } ++ if ( mail_out != -1 ) { ++ /* oldName is oldest Backup found (for unlink later) */ ++ sprintf(oldName, "%s", (globResult.gl_pathv)[mail_out]); ++ strcpy(disposeName, oldName); ++ } else ++ disposeName = NULL; ++ } else { ++ message (MESS_DEBUG, "glob finding old rotated logs failed\n"); ++ disposeName = NULL; ++ } ++ /* firstRotated is most recently created/compressed rotated log */ ++ sprintf(firstRotated, "%s/%s-%04d%02d%02d%s%s", ++ dirName, baseName, now.tm_year+1900, ++ now.tm_mon+1, now.tm_mday, fileext, compext); ++ globfree(&globResult); ++ free(glob_pattern); ++ } else { ++ if ( log->rotateAge ) { ++ struct stat fst_buf; ++ for (i=1; i <= rotateCount; i++) { ++ sprintf(oldName, "%s/%s.%d%s%s", dirName, baseName, ++ rotateCount + 1, fileext, compext); ++ if(!stat(oldName,&fst_buf) ++ && (((nowSecs - fst_buf.st_mtime)/60/60/24) ++ > log->rotateAge)) { ++ char * mailFilename = (globResult.gl_pathv)[i]; ++ if (!hasErrors && log->logAddress) ++ hasErrors = mailLogWrapper(mailFilename, mailCommand, logNum, log); ++ if (!hasErrors) ++ hasErrors = removeLogFile(mailFilename); ++ } ++ } ++ } + + sprintf(oldName, "%s/%s.%d%s%s", dirName, baseName, + logStart + rotateCount, fileext, compext); +@@ -548,8 +670,6 @@ int rotateSingleLog(logInfo * log, int l + + strcpy(disposeName, oldName); + +- firstRotated = alloca(strlen(dirName) + strlen(baseName) + +- strlen(fileext) + strlen(compext) + 30); + sprintf(firstRotated, "%s/%s.%d%s%s", dirName, baseName, + logStart, fileext, + (log->flags & LOG_FLAG_DELAYCOMPRESS) ? "" : compext); +@@ -600,12 +720,27 @@ int rotateSingleLog(logInfo * log, int l + } + } + } +- ++ } /* !LOG_FLAG_DATEEXT */ ++ + finalName = oldName; +- +- /* note: the gzip extension is *not* used here! */ +- sprintf(finalName, "%s/%s.%d%s", dirName, baseName, logStart, fileext); +- ++ ++ if(log->flags & LOG_FLAG_DATEEXT) { ++ char * destFile = alloca(strlen(dirName) + strlen(baseName) + ++ strlen(fileext) + strlen(compext) + 30); ++ struct stat fst_buf; ++ sprintf(finalName, "%s/%s-%04d%02d%02d%s", ++ dirName, baseName, now.tm_year+1900, ++ now.tm_mon+1, now.tm_mday, fileext); ++ sprintf(destFile, "%s%s", finalName, compext); ++ if(!stat(destFile,&fst_buf)) { ++ message (MESS_DEBUG, "destination %s already exists, skipping rotation\n", firstRotated); ++ hasErrors = 1; ++ } ++ } else { ++ /* note: the gzip extension is *not* used here! */ ++ sprintf(finalName, "%s/%s.%d%s", dirName, baseName, logStart, fileext); ++ } ++ + /* if the last rotation doesn't exist, that's okay */ + if (!debug && access(disposeName, F_OK)) { + message(MESS_DEBUG, "log %s doesn't exist -- won't try to " +@@ -613,9 +748,6 @@ int rotateSingleLog(logInfo * log, int l + disposeName = NULL; + } + +- free(dirName); +- free(baseName); +- + if (!hasErrors) { + if (log->pre && !(log->flags & LOG_FLAG_SHAREDSCRIPTS)) { + message(MESS_DEBUG, "running prerotate script\n"); +@@ -722,33 +854,12 @@ int rotateSingleLog(logInfo * log, int l + else + mailFilename = disposeName; + +- if (mailFilename) { +- /* if the log is compressed (and we're not mailing a +- file whose compression has been delayed), we need +- to uncompress it */ +- if ((log->flags & LOG_FLAG_COMPRESS) && +- !((log->flags & LOG_FLAG_DELAYCOMPRESS) && +- (log->flags & LOG_FLAG_MAILFIRST))) { +- if (mailLog(mailFilename, mailCommand, +- log->uncompress_prog, log->logAddress, +- log->files[logNum])) +- hasErrors = 1; +- } else { +- if (mailLog(mailFilename, mailCommand, NULL, +- log->logAddress, mailFilename)) +- hasErrors = 1; +- } +- } ++ if (mailFilename) ++ hasErrors = mailLogWrapper(mailFilename, mailCommand, logNum, log); + } + + if (!hasErrors && disposeName) { +- message(MESS_DEBUG, "removing old log %s\n", disposeName); +- +- if (!debug && unlink(disposeName)) { +- message(MESS_ERROR, "Failed to remove old log %s: %s\n", +- disposeName, strerror(errno)); +- hasErrors = 1; +- } ++ hasErrors = removeLogFile(disposeName); + } + } + +@@ -761,6 +872,8 @@ int rotateSingleLog(logInfo * log, int l + } + } + #endif ++ free(dirName); ++ free(baseName); + return hasErrors; + } + +@@ -1002,7 +1115,7 @@ static int readState(char * stateFilenam + } + + /* Hack to hide earlier bug */ +- if ((year != 1900) && (year < 1996 || year > 2100)) { ++ if ((year != 1900) && (year < 1970 || year > 2100)) { + message(MESS_ERROR, "bad year %d for file %s in state file %s\n", + year, argv[0], stateFilename); + fclose(f); +@@ -1047,7 +1160,9 @@ static int readState(char * stateFilenam + + int main(int argc, const char ** argv) { + logInfo defConfig = { NULL, NULL, 0, NULL, ROT_SIZE, +- /* threshHold */ 1024 * 1024, 0, ++ /* threshHold */ 1024 * 1024, ++ /* rotateCount */ 0, ++ /* rotateAge */ 0, + /* log start */ -1, + /* pre, post */ NULL, NULL, + /* first, last */ NULL, NULL, +@@ -1108,8 +1223,7 @@ int main(int argc, const char ** argv) { + + files = poptGetArgs((poptContext) optCon); + if (!files) { +- fprintf(stderr, "logrotate " VERSION +- " - Copyright (C) 1995-2001 Red Hat, Inc.\n"); ++ fprintf(stderr, "logrotate - Copyright (C) 1995-2001 Red Hat, Inc.\n"); + fprintf(stderr, "This may be freely redistributed under the terms of " + "the GNU Public License\n\n"); + poptPrintUsage(optCon, stderr, 0); |