rpms/logrotate/devel logrotate-3.7.1-dateext.patch, NONE, 1.1 logrotate-3.7.1-maxage.patch, NONE, 1.1

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Wed Jun 22 13:47:32 UTC 2005


Author: pvrabec

Update of /cvs/dist/rpms/logrotate/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv15215

Added Files:
	logrotate-3.7.1-dateext.patch logrotate-3.7.1-maxage.patch 
Log Message:
- enhance logrotate with "dateext", "maxage"


logrotate-3.7.1-dateext.patch:
 config.c    |    8 ++
 logrotate.8 |    5 +
 logrotate.c |  177 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 logrotate.h |    1 
 4 files changed, 173 insertions(+), 18 deletions(-)

--- NEW FILE logrotate-3.7.1-dateext.patch ---
--- logrotate-3.7.1/logrotate.h.dateext	2003-08-07 13:13:14.000000000 +0200
+++ logrotate-3.7.1/logrotate.h	2005-05-03 14:17:28.732914132 +0200
@@ -15,6 +15,7 @@
 #define LOG_FLAG_MAILFIRST	(1 << 6)
 #define LOG_FLAG_SHAREDSCRIPTS	(1 << 7)
 #define LOG_FLAG_COPY		(1 << 8)
+#define LOG_FLAG_DATEEXT	(1 << 9)
 
 #define NO_FORCE_ROTATE 0
 #define FORCE_ROTATE    1
--- logrotate-3.7.1/logrotate.c.dateext	2005-05-03 14:17:28.730914415 +0200
+++ logrotate-3.7.1/logrotate.c	2005-05-03 14:31:29.916899912 +0200
@@ -11,6 +11,7 @@
 #include <sys/wait.h>
 #include <time.h>
 #include <unistd.h>
+#include <glob.h>
 
 #ifdef WITH_SELINUX
 #include <selinux/selinux.h>
@@ -23,6 +24,10 @@
 #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! */
@@ -43,6 +48,14 @@
 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;
@@ -93,6 +106,17 @@
     return rc;
 }
 
+static int removeLogFile(char * name) {
+    message(MESS_DEBUG, "removing old log %s\n", name);
+
+    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) {
     char * compressedName;
     const char ** fullCommand;
@@ -237,6 +261,25 @@
     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;
@@ -456,6 +499,9 @@
     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;
@@ -486,7 +532,7 @@
 
     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);
@@ -508,25 +554,106 @@
     /* 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)) {
+			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 {
+
     sprintf(oldName, "%s/%s.%d%s%s", dirName, baseName,
             logStart + rotateCount, fileext, compext);
     strcpy(newName, oldName);
     
     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);
@@ -582,12 +709,27 @@
                 hasErrors = 1;
 	    }
 	}
-    }
-    
+    } 
+    } /* !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)) {
@@ -596,9 +738,6 @@
         disposeName = NULL;
     } 
     
-    free(dirName);
-    free(baseName);
-    
     if (!hasErrors) {
         if (log->pre && !(log->flags & LOG_FLAG_SHAREDSCRIPTS)) {
             message(MESS_DEBUG, "running prerotate script\n");
@@ -744,6 +883,8 @@
 		}
 	}
 #endif
+    free(dirName);
+    free(baseName);
     return hasErrors;
 }
 
--- logrotate-3.7.1/config.c.dateext	2003-08-07 13:13:14.000000000 +0200
+++ logrotate-3.7.1/config.c	2005-05-03 14:17:28.734913850 +0200
@@ -511,6 +511,14 @@
 		newlog->flags &= ~LOG_FLAG_IFEMPTY;
 
 		*endtag = oldchar, start = endtag;
+	    } else if (!strcmp(start, "dateext")) {
+		newlog->flags |= LOG_FLAG_DATEEXT;
+
+		*endtag = oldchar, start = endtag;
+	    } else if (!strcmp(start, "nodateext")) {
+		newlog->flags &= ~LOG_FLAG_DATEEXT;
+
+		*endtag = oldchar, start = endtag;
 	    } else if (!strcmp(start, "noolddir")) {
 		newlog->oldDir = NULL;
 
--- logrotate-3.7.1/logrotate.8.dateext	2005-05-03 14:17:28.722915545 +0200
+++ logrotate-3.7.1/logrotate.8	2005-05-03 14:17:28.735913708 +0200
@@ -205,6 +205,11 @@
 Log files are rotated every day.
 
 .TP
+\fBdateext\fR
+Archive old versions of log files adding a daily extension like YYYYMMDD
+instead of simply adding a number.
+
+.TP
 \fBdelaycompress\fR
 Postpone compression of the previous log file to the next rotation cycle.
 This has only effect when used in combination with \fBcompress\fR.

logrotate-3.7.1-maxage.patch:
 config.c    |   15 +++++++++++++++
 logrotate.8 |    6 ++++++
 logrotate.c |   25 +++++++++++++++++++++++--
 logrotate.h |    1 +
 4 files changed, 45 insertions(+), 2 deletions(-)

--- NEW FILE logrotate-3.7.1-maxage.patch ---
--- logrotate-3.7.1/logrotate.c.maxage	2005-05-03 14:46:08.154599467 +0200
+++ logrotate-3.7.1/logrotate.c	2005-05-03 14:50:43.707983574 +0200
@@ -617,7 +617,10 @@
 	     * 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)) {
+		    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];
@@ -647,6 +650,22 @@
 	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);
@@ -1171,7 +1190,9 @@
 
 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,
--- logrotate-3.7.1/logrotate.h.maxage	2005-05-03 14:51:33.207865757 +0200
+++ logrotate-3.7.1/logrotate.h	2005-05-03 14:51:58.732195346 +0200
@@ -35,6 +35,7 @@
     enum { ROT_DAYS, ROT_WEEKLY, ROT_MONTHLY, ROT_SIZE, ROT_FORCE } criterium;
     unsigned int threshhold;
     int rotateCount;
+    int rotateAge;
     int logStart;
     char * pre, * post, * first, * last;
     char * logAddress;
--- logrotate-3.7.1/config.c.maxage	2005-05-03 14:39:35.690020183 +0200
+++ logrotate-3.7.1/config.c	2005-05-03 14:40:33.429711948 +0200
@@ -678,6 +678,21 @@
 		    }
 		    *endtag = oldchar, start = endtag;
 		}
+	    } else if (!strcmp(start, "maxage")) {
+		*endtag = oldchar, start = endtag;
+
+		if (!isolateValue(configFile, lineNum, "maxage count", &start,
+				  &endtag)) {
+		    oldchar = *endtag, *endtag = '\0';
+
+		    newlog->rotateAge = strtoul(start, &chptr, 0);
+		    if (*chptr || newlog->rotateAge < 0) {
+			message(MESS_ERROR, "%s:%d bad maximum age '%s'\n",
+				configFile, lineNum, start);
+			return 1;
+		    }
+		    *endtag = oldchar, start = endtag;
+		}
 	    } else if (!strcmp(start, "errors")) {
 		message(MESS_DEBUG, "%s: %d: the errors directive is deprecated and no longer used.\n",
 			configFile, lineNum);
--- logrotate-3.7.1/logrotate.8.maxage	2005-05-03 14:41:55.736877916 +0200
+++ logrotate-3.7.1/logrotate.8	2005-05-03 14:45:33.464585908 +0200
@@ -256,6 +256,12 @@
 instead of the just-rotated file (this is the default).
 
 .TP
+\fBmaxage\fR \fIcount\fR
+Remove rotated logs older than <count> days. The age is only checked
+if the logfile is to be rotated. The files are mailed to the
+configured address if \fBmaillast\fR and \fBmail\fR are configured.
+
+.TP
 \fBmissingok\fR
 If the log file is missing, go on to the next one without issuing an error
 message. See also \fBnomissingok\fR.




More information about the fedora-cvs-commits mailing list