Index: newsyslog.8
===================================================================
RCS file: /cvsroot/src/usr.bin/newsyslog/newsyslog.8,v
retrieving revision 1.39
diff -u -p -r1.39 newsyslog.8
--- newsyslog.8	20 Dec 2013 17:01:39 -0000	1.39
+++ newsyslog.8	28 Sep 2015 00:13:37 -0000
@@ -40,7 +40,7 @@
 .\"
 .\" from FreeBSD: newsyslog.8,v 1.14.2.1 1999/02/25 18:38:33 wollman Exp
 .\"
-.Dd June 16, 2012
+.Dd September 27, 2015
 .Dt NEWSYSLOG 8
 .Os
 .Sh NAME
@@ -313,6 +313,13 @@ flags and their meanings:
 .Bl -tag -width indent
 .It Sy -
 This flag means nothing - it is used as a spacer when no flags are set.
+.It Sy 0
+This flag makes the generation numbers of the historical log files
+zero-padded so they sort correctly.
+By default the field width is 2, for log generations 00-99.
+Adding more
+.Sy 0
+flags makes the field wider.
 .It Sy b
 The file is a binary file or is not in
 .Xr syslogd 8
Index: newsyslog.c
===================================================================
RCS file: /cvsroot/src/usr.bin/newsyslog/newsyslog.c,v
retrieving revision 1.61
diff -u -p -r1.61 newsyslog.c
--- newsyslog.c	5 Sep 2013 11:34:40 -0000	1.61
+++ newsyslog.c	28 Sep 2015 00:13:38 -0000
@@ -104,6 +104,7 @@ struct conf_entry {
 	int	maxage;			/* Hours between log trimming */
 	time_t	trimat;			/* Specific trim time */
 	int	flags;			/* Flags (CE_*) */
+	int	genwidth;		/* Width of generation number */
 	int	signum;			/* Signal to send */
 	char	pidfile[MAXPATHLEN];	/* File containing PID to signal */
 	char	logfile[MAXPATHLEN];	/* Path to log file */
@@ -142,6 +143,8 @@ static time_t	parse_dwm(char *);
 static int	parse_userspec(const char *, struct passwd **, struct group **);
 static pid_t	readpidfile(const char *);
 static void	usage(void) __dead;
+static void	makelogname(char *buf, size_t max,
+		    struct conf_entry *log, unsigned gen, const char *suffix);
 
 static void	log_compress(struct conf_entry *, const char *);
 static void	log_create(struct conf_entry *);
@@ -362,10 +365,17 @@ parse_cfgline(struct conf_entry *log, FI
 	
 	/* flags */
 	log->flags = (nosignal ? CE_NOSIGNAL : 0);
+	log->genwidth = 0;
 
 	for (q = *ap++; q != NULL && *q != '\0'; q++) {
 		char qq = toupper((unsigned char)*q);
 		switch (qq) {
+		case '0':
+			if (log->genwidth == 0)
+				log->genwidth = 2;
+			else
+				log->genwidth++;
+			break;
 		case 'B':
 			log->flags |= CE_BINARY;
 			break;
@@ -528,10 +538,8 @@ log_trim(struct conf_entry *log)
 	if (log->numhist != 0) {
 		/* Remove oldest historical log. */
 		for (j = 0; j < (int)__arraycount(compress); j++) {
-			(void)snprintf(file1, sizeof(file1), "%s.%d",
-			    log->logfile, log->numhist - 1);
-			(void)strlcat(file1, compress[j].suffix,
-			    sizeof(file1));
+			makelogname(file1, sizeof(file1),
+			    log, log->numhist - 1, compress[j].suffix);
 			PRINFO(("rm -f %s\n", file1));
 			if (!noaction)
 				(void)unlink(file1);
@@ -546,11 +554,11 @@ log_trim(struct conf_entry *log)
 	 */
 	if (ziptype) {
 		for (i = 0; i < log->numhist; i++) {
-			snprintf(file1, sizeof(file1), "%s.%d", log->logfile, i);
+			makelogname(file1, sizeof(file1), log, i, NULL);
 			if (lstat(file1, &st) != 0)
 				continue;
-			snprintf(file2, sizeof(file2), "%s%s", file1,
-			    compress[ziptype].suffix);
+			makelogname(file2, sizeof(file2), log, i,
+				    compress[ziptype].suffix);
 			if (lstat(file2, &st) == 0)
 				continue;
 			log_compress(log, file1);
@@ -560,10 +568,10 @@ log_trim(struct conf_entry *log)
 	/* Move down log files. */
 	for (i = log->numhist - 1; i > 0; i--) {
 		for (j = 0; j < (int)__arraycount(compress); j++) {
-			snprintf(file1, sizeof(file1), "%s.%d%s", log->logfile,
-			    i - 1, compress[j].suffix);
-			snprintf(file2, sizeof(file2), "%s.%d%s", log->logfile,
-			    i, compress[j].suffix);
+			makelogname(file1, sizeof(file1), log, i - 1,
+			    compress[j].suffix);
+			makelogname(file2, sizeof(file2), log, i,
+			    compress[j].suffix);
 			k = lstat(file1, &st);
 			if (!k) break;
 		}
@@ -594,7 +602,7 @@ log_trim(struct conf_entry *log)
 			if (unlink(log->logfile))
 				err(EXIT_FAILURE, "%s", log->logfile);
 	} else {
-		(void)snprintf(file1, sizeof(file1), "%s.0", log->logfile);
+		makelogname(file1, sizeof(file1), log, 0, NULL);
 		PRINFO(("mv %s %s\n", log->logfile, file1));
 		if (!noaction)
 			if (rename(log->logfile, file1))
@@ -629,7 +637,7 @@ log_trim(struct conf_entry *log)
 
 	/* If the newest historical log is to be compressed, do it here. */
 	if (ziptype && !(log->flags & CE_PLAIN0) && log->numhist != 0) {
-		snprintf(file1, sizeof(file1), "%s.0", log->logfile);
+		makelogname(file1, sizeof(file1), log, 0, NULL);
 		if ((log->flags & CE_NOSIGNAL) == 0) {
 			PRINFO(("sleep for 10 seconds before compressing...\n"));
 			(void)sleep(10);
@@ -789,6 +797,24 @@ log_compress(struct conf_entry *log, con
 }
 
 /*
+ * Build an archived log name.
+ */
+static void
+makelogname(char *buf, size_t max,
+	    struct conf_entry *log, unsigned gen, const char *suffix)
+{
+	if (suffix == NULL)
+		suffix = "";
+	if (log->genwidth > 0) {
+		(void)snprintf(buf, max, "%s.%0*u%s",
+			       log->logfile, log->genwidth, gen, suffix);
+	} else {
+		(void)snprintf(buf, max, "%s.%u%s",
+			       log->logfile, gen, suffix);
+	}
+}
+
+/*
  * Display program usage information.
  */
 static void