Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 28 Mar 2012 01:03:21 +0700 (NOVT)
From:      Eugene Grosbein <eugen@grosbein.pp.ru>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   bin/166448: [patch] newsyslog -t fails to find previous rotated log
Message-ID:  <201203271803.q2RI3LEH003025@grosbein.pp.ru>
Resent-Message-ID: <201203271810.q2RIABjJ081996@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         166448
>Category:       bin
>Synopsis:       [patch] newsyslog -t fails to find previous rotated log
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Mar 27 18:10:11 UTC 2012
>Closed-Date:
>Last-Modified:
>Originator:     Eugene Grosbein
>Release:        FreeBSD 8.3-PRERELEASE amd64
>Organization:
RDTC JSC
>Environment:
System: FreeBSD grosbein.pp.ru 8.3-PRERELEASE FreeBSD 8.3-PRERELEASE #19: Tue Mar 20 03:24:04 NOVT 2012 root@grosbein.pp.ru:/usr/local/obj/usr/local/src/sys/DADV amd64

>Description:

	newsyslog.conf(5) has "when" field instructing newsyslog to find
	previous rotated copy of log and look if it is older than "when" hours.

	newsyslog always looks for "file.0" and this is wrong when -t flag is used.

>How-To-Repeat:

	Use newsyslog -t and non-zero value in "when" field:

/var/log/cron 600 3 * 8@T C

	This should rotate log three times a day starting from midnight.

>Fix:

--- usr.sbin/newsyslog/newsyslog.c.orig	2012-03-27 22:43:06.000000000 +0700
+++ usr.sbin/newsyslog/newsyslog.c	2012-03-28 00:53:21.000000000 +0700
@@ -2206,6 +2206,77 @@
 	return (kbytes(dbtob(sb.st_blocks)));
 }
 
+/* Return the age of previous old log file, when using time based filenames. */
+static time_t
+find_oldest_timelog(const char *dir, const char *logfname)
+{
+	struct stat sb;
+	int c, valid;
+	size_t logfname_len;
+	struct tm tm;
+	time_t oldt;
+	struct dirent *dp;
+	DIR *dirp;
+	char *s;
+
+	if ((dirp = opendir(dir)) == NULL)
+		err(1, "Cannot open log directory '%s'", dir);
+
+	oldt = -1;
+	logfname_len = strlen(logfname);
+	while ((dp = readdir(dirp)) != NULL) {
+		if (dp->d_type != DT_REG)
+			continue;
+		/* Ignore everything but files with our logfile prefix */
+		if (strncmp(dp->d_name, logfname, logfname_len) != 0)
+			continue;
+		/* Ignore the actual non-rotated logfile */
+		if (dp->d_namlen == logfname_len)
+			continue;
+		/*
+		 * Make sure we have found a logfile, so the
+		 * postfix is valid, IE format is: '.<time>(.[bg]z)?'.
+		 */
+		if (dp->d_name[logfname_len] != '.') {
+			if (verbose)
+				printf("Ignoring %s which has unexpected "
+				    "extension '%s'\n", dp->d_name,
+				    &dp->d_name[logfname_len]);
+			continue;
+		}
+		if ((s = strptime(&dp->d_name[logfname_len + 1],
+			    timefnamefmt, &tm)) == NULL) {
+			if (verbose)
+				printf("Ignoring %s which does not "
+				    "match time format\n", dp->d_name);
+			continue;
+		}
+
+		valid = 0;
+		c = 0;
+		while (!valid && c < COMPRESS_TYPES)
+			if (strcmp(s, compress_type[c++].suffix) == 0)
+				valid = 1;
+
+		if (valid != 1) {
+			if (verbose)
+				printf("Ignoring %s which has unexpected "
+				    "extension '%s'\n", dp->d_name, s);
+			continue;
+		}
+		if (stat(dp->d_name, &sb) < 0)
+			err(1, "Cannot stat '%s'", dp->d_name);
+
+		/* We have found more recent old logfile */
+		if (oldt < sb.st_mtime)
+			oldt = sb.st_mtime;
+	}
+	closedir(dirp);
+
+	/* Return -1 if nothing found */
+	return oldt;
+}
+
 /* Return the age of old log file (file.0) */
 static int
 age_old_log(char *file)
@@ -2241,6 +2312,17 @@
 		(void) strlcpy(tmp, file, sizeof(tmp));
 	}
 
+	if (timefnamefmt != NULL) {
+                char *bd;
+                time_t t;
+
+	        if ((bd = dirname(tmp)) == NULL)
+                        err(1, "'%s'", tmp);
+                if ((t = find_oldest_timelog(bd, basename(tmp))) == -1)
+                        return (-1);
+                return ((int)(ptimeget_secs(timenow) - t + 1800) / 3600);
+	}
+
 	strlcat(tmp, ".0", sizeof(tmp));
 	logfile_suffix = get_logfile_suffix(tmp);
 	if (logfile_suffix == NULL)


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201203271803.q2RI3LEH003025>