From toddwagn@yahoo.com  Tue Sep 18 15:09:41 2001
Return-Path: <toddwagn@yahoo.com>
Received: from web10903.mail.yahoo.com (web10903.mail.yahoo.com [216.136.131.39])
	by hub.freebsd.org (Postfix) with SMTP id 8B30D37B408
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 18 Sep 2001 15:09:41 -0700 (PDT)
Received: from [64.70.59.93] by web10903.mail.yahoo.com via HTTP; Tue, 18 Sep 2001 15:09:40 PDT
Message-Id: <20010918220940.59020.qmail@web10903.mail.yahoo.com>
Date: Tue, 18 Sep 2001 15:09:40 -0700 (PDT)
From: Todd Wagner <toddwagn@yahoo.com>
To: FreeBSD-gnats-submit@freebsd.org
Subject: Added ability for newsyslog to archive logs with a timestamp.

>Number:         30654
>Category:       bin
>Synopsis:       [patch] Added ability for newsyslog(8) to archive logs
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    gad
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          update
>Submitter-Id:   current-users
>Arrival-Date:   Tue Sep 18 15:10:00 PDT 2001
>Closed-Date:    
>Last-Modified:  Fri Jul 18 13:10:44 UTC 2008
>Originator:     Todd Wagner
>Release:        FreeBSD 4.4-RELEASE i386
>Organization:
self
>Environment:
System: FreeBSD cims-la1-01.catt.exodus.net
4.4-RELEASE FreeBSD 
4.4-RELEASE #0: Mon Sep 17 23:25:16 GMT 2001 
root@cims-la1-01.catt.exodus.net:/usr/obj/usr/src/sys/CIMS-SMP
i386


	
>Description:
	Added the ability for newsyslog to archive logs with
a timestamp, in 
addition to the normal log rotation.  
	In addition, the number of log files to maintain
(numlogs) was not 
checked and caused newsyslog to hang when it was set
to a negative value 
in /etc/newsyslog.conf.  The included patch now checks
this value.
	The man page was also updated to describe the new
functionality.
>How-To-Repeat:
	Set the number of log files to maintain to a negative
value in 
/etc/newsyslog.conf and run newsyslog.  It will not
complete.
>Fix:


*** newsyslog.c.orig	Mon Sep 17 22:20:06 2001
--- newsyslog.c	Tue Sep 18 20:26:53 2001
***************
*** 351,357 ****
  		if (!*parse)
  			errx(1, "malformed line (missing fields):\n%s",
errline);
  		*parse = '\0';
! 		if (!sscanf(q, "%d", &working->numlogs))
  			errx(1, "error in config file; bad number:\n%s",
  			    errline);
  
--- 351,357 ----
  		if (!*parse)
  			errx(1, "malformed line (missing fields):\n%s",
errline);
  		*parse = '\0';
! 		if (!sscanf(q, "%d", &working->numlogs) ||
working->numlogs < -1)
  			errx(1, "error in config file; bad number:\n%s",
  			    errline);
  
***************
*** 480,488 ****
--- 480,491 ----
  	char dirpart[MAXPATHLEN], namepart[MAXPATHLEN];
  	char file1[MAXPATHLEN], file2[MAXPATHLEN];
  	char zfile1[MAXPATHLEN], zfile2[MAXPATHLEN];
+ 	char tmp[MAXPATHLEN];
+ 	char logdate[BUFSIZ];
  	int notified, need_notification, fd, _numdays;
  	struct stat st;
  	pid_t pid;
+ 	time_t logtime;
  
  #ifdef _IBMR2
  	/*
***************
*** 493,498 ****
--- 496,504 ----
  	if (owner_uid == -1)
  		owner_uid = geteuid();
  #endif
+ 	/* build date extension */
+ 	logtime = time(NULL);
+ 	(void) strftime(logdate, BUFSIZ-1, "%Y%m%d%H%M%S", 
localtime(&logtime));
  
  	if (archtodir) {
  		char *p;
***************
*** 520,534 ****
  		else
  			strlcpy(namepart, p + 1, sizeof(namepart));
  
! 		/* name of oldest log */
! 		(void) snprintf(file1, sizeof(file1), "%s/%s.%d",
dirpart, 
namepart, numdays);
  		(void) snprintf(zfile1, sizeof(zfile1), "%s%s",
file1,
  		    COMPRESS_POSTFIX);
  	} else {
! 		/* name of oldest log */
! 		(void) snprintf(file1, sizeof(file1), "%s.%d",
log, numdays);
  		(void) snprintf(zfile1, sizeof(zfile1), "%s%s",
file1,
  		    COMPRESS_POSTFIX);
  	}
  
  	if (noaction) {
--- 526,553 ----
  		else
  			strlcpy(namepart, p + 1, sizeof(namepart));
  
! 		if (numdays > -1) {
! 			/* name of oldest log */
! 			(void) snprintf(file1, sizeof(file1), "%s/%s.%d",
dirpart, 
namepart, numdays);
! 		} else {
! 			/* name of dated log */
! 			(void) snprintf(file1, sizeof(file1), "%s/%s.%s",
dirpart, 
namepart, logdate);
! 		}
! 		/* name of compressed log */
  		(void) snprintf(zfile1, sizeof(zfile1), "%s%s",
file1,
  		    COMPRESS_POSTFIX);
+ 
  	} else {
! 		if (numdays > -1) {
! 			/* name of oldest log */
! 			(void) snprintf(file1, sizeof(file1), "%s/%s.%d",
dirpart, 
namepart, numdays);
! 		} else {
! 			/* name of dated log */
! 			(void) snprintf(file1, sizeof(file1), "%s.%s",
log, logdate);
! 		}
  		(void) snprintf(zfile1, sizeof(zfile1), "%s%s",
file1,
  		    COMPRESS_POSTFIX);
+ 
  	}
  
  	if (noaction) {
***************
*** 541,547 ****
  
  	/* Move down log files */
  	_numdays = numdays;	/* preserve */
! 	while (numdays--) {
  
  		(void) strlcpy(file2, file1, sizeof(file2));
  
--- 560,566 ----
  
  	/* Move down log files */
  	_numdays = numdays;	/* preserve */
! 	while (--numdays > 0) {
  
  		(void) strlcpy(file2, file1, sizeof(file2));
  
***************
*** 628,634 ****
  		if (need_notification && !notified)
  			warnx("log %s not compressed because daemon not
notified", log);
  		else if (noaction)
! 			printf("Compress %s.0\n", log);
  		else {
  			if (notified) {
  				if (verbose)
--- 647,656 ----
  		if (need_notification && !notified)
  			warnx("log %s not compressed because daemon not
notified", log);
  		else if (noaction)
! 			if (numdays > -1)
! 				printf("Compress %s.0\n", log);
! 			else
! 				printf("Compress %s.%s\n", log, logdate);
  		else {
  			if (notified) {
  				if (verbose)
***************
*** 636,645 ****
  				sleep(10);
  			}
  			if (archtodir) {
! 				(void) snprintf(file1, sizeof(file1), "%s/%s",
dirpart, 
namepart);
  				compress_log(file1);
  			} else {
! 				compress_log(log);
  			}
  		}
  	}
--- 658,671 ----
  				sleep(10);
  			}
  			if (archtodir) {
! 				/* (void) snprintf(file1, sizeof(file1),
"%s/%s", dirpart, 
namepart); */
  				compress_log(file1);
  			} else {
! 				if (numdays > 0)
! 					(void) snprintf(tmp, sizeof(tmp), "%s.0", log);
! 				else
! 					(void) snprintf(tmp, sizeof(tmp), "%s.%s", log,
logdate);
! 				compress_log(tmp);
  			}
  		}
  	}
***************
*** 665,678 ****
  compress_log(char *log)
  {
  	pid_t pid;
- 	char tmp[MAXPATHLEN];
  
- 	(void) snprintf(tmp, sizeof(tmp), "%s.0", log);
  	pid = fork();
  	if (pid < 0)
  		err(1, "fork");
  	else if (!pid) {
! 		(void) execl(_PATH_GZIP, _PATH_GZIP, "-f", tmp,
0);
  		err(1, _PATH_GZIP);
  	}
  }
--- 691,702 ----
  compress_log(char *log)
  {
  	pid_t pid;
  
  	pid = fork();
  	if (pid < 0)
  		err(1, "fork");
  	else if (!pid) {
! 		(void) execl(_PATH_GZIP, _PATH_GZIP, "-f", log,
0);
  		err(1, _PATH_GZIP);
  	}
  }


*** newsyslog.8.orig	Mon Sep 17 22:20:06 2001
--- newsyslog.8	Tue Sep 18 21:29:42 2001
***************
*** 99,105 ****
  Specify the mode of the log file and archives.
  .It Ar count
  Specify the number of archive files to be kept
! besides the log file itself.
  .It Ar size
  When the size of the log file reaches
  .Ar size
--- 99,105 ----
  Specify the mode of the log file and archives.
  .It Ar count
  Specify the number of archive files to be kept
! besides the log file itself.  If '-1' is specified,
then the file 
will be archived with a timestamp appended, instead of
the rotation 
number, and all archived files will be retained.  For
example, 'my.log' would 
be archived as 'my.log.YYYYMMDDHHMMSS'.
  .It Ar size
  When the size of the log file reaches
  .Ar size

__________________________________________________
Terrorist Attacks on U.S. - How can you help?
Donate cash, emergency relief information
http://dailynews.yahoo.com/fc/US/Emergency_Information/
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->gad-bugs 
Responsible-Changed-By: gad 
Responsible-Changed-When: Fri Feb 21 12:09:51 PST 2003 
Responsible-Changed-Why:  
I'll look into this, as long as I'm working on some other 
changes to newsyslog. 


http://www.freebsd.org/cgi/query-pr.cgi?pr=30654 
Responsible-Changed-From-To: gad-bugs->gad 
Responsible-Changed-By: gad 
Responsible-Changed-When: Fri Feb 21 12:53:40 PST 2003 
Responsible-Changed-Why:  
I don't know how I keep changing 'responsible' to 'gad-bugs' 
when I *meant* to change it to just plain 'gad'... 

http://www.freebsd.org/cgi/query-pr.cgi?pr=30654 

From: Garance A Drosehn <gad@FreeBSD.org>
To: freebsd-gnats-submit@FreeBSD.org, toddwagn@yahoo.com
Cc:  
Subject: Re: bin/30654: Added ability for newsyslog to archive logs
Date: Sun, 23 Feb 2003 21:57:19 -0500

 .      I have committed a change to -current which fixes the
 serious-bug part of this PR, so I have changed the severity
 to non-critical.  I will MFC that to stable.  Later on I'll
 look into the new feature of archiving logs by timestamp.
 
 -- 
 Garance Alistair Drosehn     =                drosih@rpi.edu
 Senior Systems Programmer               or   gad@FreeBSD.org
 Rensselaer Polytechnic Institute;             Troy, NY;  USA
 

From: Garance A Drosehn <gad@FreeBSD.org>
To: freebsd-gnats-submit@FreeBSD.org, toddwagn@yahoo.com
Cc:  
Subject: Re: bin/30654: Added ability for newsyslog to archive logs
Date: Sun, 27 Apr 2003 19:57:40 -0400

 The bug-fix part of this PR has been MFC'ed to -stable.
 It may be a few more weeks before I implement some kind of
 timestamp-logfile ability.
 
 -- 
 Garance Alistair Drosehn     =               gad@FreeBSD.org
 

From: Sergey Svishchev <svs@ropnet.ru>
To: freebsd-gnats-submit@FreeBSD.org, toddwagn@yahoo.com
Cc:  
Subject: Re: bin/30654: Added ability for newsyslog to archive logs
Date: Fri, 01 Apr 2005 14:48:39 +0400

 This is a multi-part message in MIME format.
 --------------030705060200080608040506
 Content-Type: text/plain; charset=KOI8-R; format=flowed
 Content-Transfer-Encoding: 7bit
 
 I've "ported" the patch to FreeBSD 5.2.1, here it is:
 
 -- 
 Sergey Svishchev
 
 
 --------------030705060200080608040506
 Content-Type: text/plain;
  name="freebsd-5.2.1-pr30654.txt"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="freebsd-5.2.1-pr30654.txt"
 
 --- newsyslog.c.orig	Tue Sep 23 04:00:26 2003
 +++ newsyslog.c	Wed Feb  9 17:23:09 2005
 @@ -1046,7 +1046,7 @@
  			errx(1, "malformed line (missing fields):\n%s",
  			    errline);
  		*parse = '\0';
 -		if (!sscanf(q, "%d", &working->numlogs) || working->numlogs < 0)
 +		if (!sscanf(q, "%d", &working->numlogs))
  			errx(1, "error in config file; bad value for count of logs to save:\n%s",
  			    errline);
  
 @@ -1286,11 +1286,18 @@
  	char zfile1[MAXPATHLEN], zfile2[MAXPATHLEN];
  	char jfile1[MAXPATHLEN];
  	char tfile[MAXPATHLEN];
 +	char tmp[MAXPATHLEN];
 +	char logdate[BUFSIZ];
  	int flags, notified, need_notification, fd, numlogs_c;
  	struct stat st;
 +	time_t logtime;
  
  	flags = ent->flags;
  
 +	/* build date extension */
 +	logtime = time(NULL);
 +	(void) strftime(logdate, BUFSIZ-1, "%Y%m%d%H%M%S", localtime(&logtime));
 +
  	if (archtodir) {
  		char *p;
  
 @@ -1318,8 +1325,16 @@
  			strlcpy(namepart, p + 1, sizeof(namepart));
  
  		/* name of oldest log */
 -		(void) snprintf(file1, sizeof(file1), "%s/%s.%d", dirpart,
 -		    namepart, ent->numlogs);
 +		if (ent->numlogs > -1) {
 +			/* name of oldest log */
 +			(void) snprintf(file1, sizeof(file1), "%s/%s.%d", 
 +			    dirpart, namepart, ent->numlogs);
 +		} else {
 +			/* name of dated log */
 +			(void) snprintf(file1, sizeof(file1), "%s/%s.%s", 
 +			    dirpart, namepart, logdate);
 +		}
 +		/* name of compressed log */
  		(void) snprintf(zfile1, sizeof(zfile1), "%s%s", file1,
  		    COMPRESS_POSTFIX);
  		snprintf(jfile1, sizeof(jfile1), "%s%s", file1,
 @@ -1328,6 +1343,15 @@
  		/* name of oldest log */
  		(void) snprintf(file1, sizeof(file1), "%s.%d", ent->log,
  		    ent->numlogs);
 +		if (ent->numlogs > -1) {
 +			/* name of oldest log */
 +			(void) snprintf(file1, sizeof(file1), "%s/%s.%d", 
 +			    dirpart, namepart, ent->numlogs);
 +		} else {
 +			/* name of dated log */
 +			(void) snprintf(file1, sizeof(file1), "%s.%s", 
 +			    ent->log, logdate);
 +		}
  		(void) snprintf(zfile1, sizeof(zfile1), "%s%s", file1,
  		    COMPRESS_POSTFIX);
  		snprintf(jfile1, sizeof(jfile1), "%s%s", file1,
 @@ -1346,7 +1370,7 @@
  
  	/* Move down log files */
  	numlogs_c = ent->numlogs;		/* copy for countdown */
 -	while (numlogs_c--) {
 +	while (--numlogs_c > 0) {
  
  		(void) strlcpy(file2, file1, sizeof(file2));
  
 @@ -1473,32 +1497,31 @@
  			    ent->log);
  		else if (noaction)
  			if (flags & CE_COMPACT)
 -				printf("\tgzip %s.0\n", ent->log);
 +				printf("\tgzip %s.%s\n", ent->log,
 +				   ent->numlogs > -1 ? "0" : logdate);
  			else
 -				printf("\tbzip2 %s.0\n", ent->log);
 +				printf("\tbzip2 %s.%s\n", ent->log,
 +				   ent->numlogs > -1 ? "0" : logdate);
  		else {
  			if (notified) {
  				if (verbose)
  					printf("small pause to allow daemon(s) to close log\n");
  				sleep(10);
  			}
 -			if (archtodir) {
 -				(void) snprintf(file1, sizeof(file1), "%s/%s",
 -				    dirpart, namepart);
 -				if (flags & CE_COMPACT)
 -					compress_log(file1,
 -					    flags & CE_COMPACTWAIT);
 -				else if (flags & CE_BZCOMPACT)
 -					bzcompress_log(file1,
 -					    flags & CE_COMPACTWAIT);
 -			} else {
 -				if (flags & CE_COMPACT)
 -					compress_log(ent->log,
 -					    flags & CE_COMPACTWAIT);
 -				else if (flags & CE_BZCOMPACT)
 -					bzcompress_log(ent->log,
 -					    flags & CE_COMPACTWAIT);
 +			if (!archtodir) {
 +				if (ent->numlogs > 0)
 +					(void) snprintf(file1, sizeof(tmp), 
 +					   "%s.0", ent->log);
 +				else
 +					(void) snprintf(file1, sizeof(tmp), 
 +					   "%s.%s", ent->log, logdate);
  			}
 +			if (flags & CE_COMPACT)
 +				compress_log(file1,
 +				    flags & CE_COMPACTWAIT);
 +			else if (flags & CE_BZCOMPACT)
 +				bzcompress_log(file1,
 +				    flags & CE_COMPACTWAIT);
  		}
  	}
  }
 @@ -1534,16 +1557,14 @@
  compress_log(char *logname, int dowait)
  {
  	pid_t pid;
 -	char tmp[MAXPATHLEN];
  
  	while (dowait && (wait(NULL) > 0 || errno == EINTR))
  		;
 -	(void) snprintf(tmp, sizeof(tmp), "%s.0", logname);
  	pid = fork();
  	if (pid < 0)
  		err(1, "gzip fork");
  	else if (!pid) {
 -		(void) execl(_PATH_GZIP, _PATH_GZIP, "-f", tmp, (char *)0);
 +		(void) execl(_PATH_GZIP, _PATH_GZIP, "-f", logname, (char *)0);
  		err(1, _PATH_GZIP);
  	}
  }
 @@ -1553,16 +1574,14 @@
  bzcompress_log(char *logname, int dowait)
  {
  	pid_t pid;
 -	char tmp[MAXPATHLEN];
  
  	while (dowait && (wait(NULL) > 0 || errno == EINTR))
  		;
 -	snprintf(tmp, sizeof(tmp), "%s.0", logname);
  	pid = fork();
  	if (pid < 0)
  		err(1, "bzip2 fork");
  	else if (!pid) {
 -		execl(_PATH_BZIP2, _PATH_BZIP2, "-f", tmp, (char *)0);
 +		execl(_PATH_BZIP2, _PATH_BZIP2, "-f", logname, (char *)0);
  		err(1, _PATH_BZIP2);
  	}
  }
 --- newsyslog.8.orig	Mon Apr 28 03:37:31 2003
 +++ newsyslog.8	Wed Feb  9 15:50:39 2005
 @@ -111,7 +111,10 @@
  Specify the mode of the log file and archives.
  .It Ar count
  Specify the number of archive files to be kept
 -besides the log file itself.
 +besides the log file itself.  If '-1' is specified, then the file will be
 +archived with a timestamp appended, instead of the rotation number, and all
 +archived files will be retained.  For example, 'my.log' would be archived
 +as 'my.log.YYYYMMDDHHMMSS'.
  .It Ar size
  When the size of the log file reaches
  .Ar size
 
 --------------030705060200080608040506--
>Unformatted:
 with a 
 timestamp.
