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