Hello community,
here is the log from the commit of package logrotate for openSUSE:Factory checked in at 2015-07-05 17:57:32
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/logrotate (Old)
and /work/SRC/openSUSE:Factory/.logrotate.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "logrotate"
Changes:
--------
--- /work/SRC/openSUSE:Factory/logrotate/logrotate.changes 2015-05-22 16:32:31.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.logrotate.new/logrotate.changes 2015-07-05 17:57:33.000000000 +0200
@@ -1,0 +2,22 @@
+Mon Jun 22 12:53:44 UTC 2015 - kstreitova@suse.com
+
+- update to 3.9.1
+ * 3.9.1
+ - Fix off-by-one error which can lead to crash when copytruncate
+ is used.
+ * 3.9.0
+ - Fix crash when using long dateformat. [nmerdan]
+ - Add support for %H dateformat. [czchen]
+ - Fix regression introduced in 3.8.9 when when rotating multiple
+ logs when one of them is missing.
+ - In the debug mode, do not skip the code-path which handles the
+ case when the last rotation does not exist. [Sergey Vidishev]
+ - Show more precise description when "log does not need rotating".
+ - Add new -l option to log verbose output to file. The file is
+ overwritten on every logrotate execution.
+ - Allow rotation of sparse files with copytruncate.
+ * update logrotate-addextension.patch
+- use spec-cleaner
+- remove unused PreReq tags
+
+-------------------------------------------------------------------
Old:
----
logrotate-3.8.9.tar.gz
New:
----
logrotate-3.9.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ logrotate.spec ++++++
--- /var/tmp/diff_new_pack.MQlKxd/_old 2015-07-05 17:57:34.000000000 +0200
+++ /var/tmp/diff_new_pack.MQlKxd/_new 2015-07-05 17:57:34.000000000 +0200
@@ -16,14 +16,13 @@
#
-Url: https://fedorahosted.org/releases/l/o/logrotate
-
Name: logrotate
-Version: 3.8.9
+Version: 3.9.1
Release: 0
Summary: Rotate, compress, remove, and mail system log files
License: GPL-2.0+
Group: System/Base
+Url: https://fedorahosted.org/releases/l/o/logrotate
Source: https://fedorahosted.org/releases/l/o/%{name}/%{name}-%{version}.tar.gz
Source100: %{name}-rpmlintrc
Source101: %{name}.service
@@ -39,9 +38,6 @@
BuildRequires: libselinux-devel
BuildRequires: popt-devel
BuildRequires: pkgconfig(systemd) >= 197
-PreReq: %fillup_prereq
-PreReq: /bin/mv
-PreReq: /bin/rm
Requires: xz
BuildRoot: %{_tmppath}/%{name}-%{version}-build
%{?systemd_requires}
@@ -64,12 +60,12 @@
%patch5 -p1
%build
-make %{?_smp_mflags} CC="%__cc" RPM_OPT_FLAGS="%{optflags}" \
+make %{?_smp_mflags} CC="gcc" RPM_OPT_FLAGS="%{optflags}" \
WITH_SELINUX=yes \
WITH_ACL=yes
%check
-make test
+make %{?_smp_mflags} test
%install
make PREFIX=%{buildroot} install
@@ -77,8 +73,8 @@
mkdir -p %{buildroot}%{_prefix}/sbin
install -m 644 examples/logrotate-default %{buildroot}%{_sysconfdir}/logrotate.conf
install -m 644 examples/logrotate.wtmp %{buildroot}%{_sysconfdir}/logrotate.d/wtmp
-install -D -m 0644 %{S:101} %{buildroot}%{_unitdir}/%{name}.service
-install -D -m 0644 %{S:102} %{buildroot}%{_unitdir}/%{name}.timer
+install -D -m 0644 %{SOURCE101} %{buildroot}%{_unitdir}/%{name}.service
+install -D -m 0644 %{SOURCE102} %{buildroot}%{_unitdir}/%{name}.timer
%pre
#only the timer can be enabled/disabled/masked !
@@ -86,9 +82,9 @@
%post
%{remove_and_set MAX_DAYS_FOR_LOG_FILES}
-if [ -f /etc/logrotate.d/aaa_base ] ; then
+if [ -f %{_sysconfdir}/logrotate.d/aaa_base ] ; then
echo "Saving old logrotate system configuration"
- mv -v /etc/logrotate.d/aaa_base /etc/logrotate.d.aaa_base.save
+ mv -v %{_sysconfdir}/logrotate.d/aaa_base %{_sysconfdir}/logrotate.d.aaa_base.save
fi
%service_add_post %{name}.service %{name}.timer
@@ -106,7 +102,7 @@
%{_mandir}/man8/logrotate.8*
%{_mandir}/man5/logrotate.conf.5*
%config %{_sysconfdir}/logrotate.conf
-%config(noreplace)/etc/logrotate.d/wtmp
+%config(noreplace)%{_sysconfdir}/logrotate.d/wtmp
%{_unitdir}/%{name}.service
%{_unitdir}/%{name}.timer
++++++ logrotate-3.8.9.tar.gz -> logrotate-3.9.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/logrotate-3.8.9/CHANGES new/logrotate-3.9.1/CHANGES
--- old/logrotate-3.8.9/CHANGES 2015-02-13 07:11:21.000000000 +0100
+++ new/logrotate-3.9.1/CHANGES 2015-04-03 09:39:35.000000000 +0200
@@ -1,3 +1,17 @@
+3.9.0 -> 3.9.1
+ - Fix off-by-one error which can lead to crash when copytruncate is used.
+3.8.9 -> 3.9.0
+ - Fix crash when using long dateformat. [nmerdan]
+ - Add support for %H dateformat. [czchen]
+ - Fix regression introduced in 3.8.9 when when rotating multiple
+ logs when one of them is missing.
+ - In the debug mode, do not skip the code-path which handles the case when
+ the last rotation does not exist. [Sergey Vidishev]
+ - Show more precise description when "log does not need rotating".\
+ - Add new -l option to log verbose output to file. The file is overwritten
+ on every logrotate execution.
+ - Allow rotation of sparse files with copytruncate.
+
3.8.8 -> 3.8.9
- Add new directive "createolddir" and "nocreateolddir". These directives
can be used to create the directory specified by olddir with particular
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/logrotate-3.8.9/Makefile new/logrotate-3.9.1/Makefile
--- old/logrotate-3.8.9/Makefile 2015-02-13 07:11:21.000000000 +0100
+++ new/logrotate-3.9.1/Makefile 2015-04-03 09:39:35.000000000 +0200
@@ -1,7 +1,7 @@
VERSION = $(shell awk '/Version:/ { print $$2 }' logrotate.spec)
OS_NAME = $(shell uname -s)
LFS = $(shell echo `getconf LFS_CFLAGS 2>/dev/null`)
-CFLAGS = -Wall -D_GNU_SOURCE -D$(OS_NAME) -DVERSION=\"$(VERSION)\" -DHAVE_STRPTIME=1 -DHAVE_QSORT $(RPM_OPT_FLAGS) $(LFS)
+CFLAGS = -Wall -D_GNU_SOURCE -D$(OS_NAME) -DVERSION=\"$(VERSION)\" -DHAVE_STRPTIME=1 -DHAVE_QSORT -DHAVE_STRUCT_STAT_ST_BLOCKS -DHAVE_STRUCT_STAT_ST_BLKSIZE $(RPM_OPT_FLAGS) $(LFS)
PROG = logrotate
MAN = logrotate.8
MAN5 = logrotate.conf.5
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/logrotate-3.8.9/configure.ac new/logrotate-3.9.1/configure.ac
--- old/logrotate-3.8.9/configure.ac 2015-02-13 07:11:21.000000000 +0100
+++ new/logrotate-3.9.1/configure.ac 2015-04-03 09:39:35.000000000 +0200
@@ -1,4 +1,4 @@
-AC_INIT([logrotate],[3.8.9])
+AC_INIT([logrotate],[3.9.1])
AM_INIT_AUTOMAKE
AC_DEFINE(_GNU_SOURCE)
@@ -7,6 +7,8 @@
AC_PROG_CC
AC_PROG_CC_STDC
+AC_STRUCT_ST_BLKSIZE
+AC_STRUCT_ST_BLOCKS
AC_CHECK_LIB([popt],[poptParseArgvString],,
AC_MSG_ERROR([libpopt required but not found]))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/logrotate-3.8.9/log.c new/logrotate-3.9.1/log.c
--- old/logrotate-3.8.9/log.c 2015-02-13 07:11:21.000000000 +0100
+++ new/logrotate-3.9.1/log.c 2015-04-03 09:39:35.000000000 +0200
@@ -37,75 +37,48 @@
flags &= ~newFlags;
}
-#if 0
-void log(int fd, char *format, ...)
+static void log_once(FILE *where, int level, char *format, va_list args)
{
- int i = 0;
- char *buf = NULL;
- va_list args;
- int size;
-
- va_start(args, format);
-
- do {
- i += 1000;
- if (buf)
- free(buf);
- buf = malloc(i);
- size = vsnprintf(buf, i, format, args);
- } while (size >= i);
-
- write(fd, buf, size);
-
- free(buf);
-
- va_end(args);
-}
-#endif
-
-void message(int level, char *format, ...)
-{
- va_list args;
- FILE *where = NULL;
- int showTime = 0;
-
- if (errorFile == NULL)
- errorFile = stderr;
- if (messageFile == NULL)
- messageFile = stderr;
- where = errorFile;
-
- if (level >= logLevel) {
- va_start(args, format);
+ int showTime = 0;
switch (level) {
case MESS_DEBUG:
- where = messageFile;
- showTime = 1;
- break;
-
+ showTime = 1;
+ break;
case MESS_NORMAL:
case MESS_VERBOSE:
- where = messageFile;
- break;
-
+ break;
default:
- if (flags & LOG_TIMES)
+ if (flags & LOG_TIMES)
fprintf(where, "%ld: ", (long) time(NULL));
- fprintf(errorFile, "error: ");
- break;
+ fprintf(where, "error: ");
+ break;
}
if (showTime && (flags & LOG_TIMES)) {
- fprintf(where, "%ld:", (long) time(NULL));
+ fprintf(where, "%ld:", (long) time(NULL));
}
vfprintf(where, format, args);
fflush(where);
- va_end(args);
-
if (level == MESS_FATAL)
- exit(1);
+ exit(1);
+}
+
+void message(int level, char *format, ...)
+{
+ va_list args;
+
+ if (level >= logLevel) {
+ va_start(args, format);
+ log_once(stderr, level, format, args);
+ va_end(args);
+ }
+
+ if (messageFile != NULL) {
+ va_start(args, format);
+ log_once(messageFile, level, format, args);
+ va_end(args);
}
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/logrotate-3.8.9/log.h new/logrotate-3.9.1/log.h
--- old/logrotate-3.8.9/log.h 2015-02-13 07:11:21.000000000 +0100
+++ new/logrotate-3.9.1/log.h 2015-04-03 09:39:35.000000000 +0200
@@ -18,9 +18,6 @@
#else
;
#endif
-#if 0
-void log(int fd, char *format, ...);
-#endif
void logSetErrorFile(FILE * f);
void logSetMessageFile(FILE * f);
void logSetFlags(int flags);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/logrotate-3.8.9/logrotate.8 new/logrotate-3.9.1/logrotate.8
--- old/logrotate-3.8.9/logrotate.8 2015-02-13 07:11:21.000000000 +0100
+++ new/logrotate-3.9.1/logrotate.8 2015-04-03 09:39:35.000000000 +0200
@@ -48,6 +48,12 @@
correctly.
.TP
+\fB\-l \fR
+Tells \fBlogrotate\fR to log verbose output into the log_file. The verbose
+output logged to that file is the same as when running \fBlogrotate\fR with
+\fB-v\fR switch. The log file is overwritten on every logrotate execution.
+
+.TP
\fB\-m\fR, \fB\-\-mail <command>\fR
Tells \fBlogrotate\fR which command to use when mailing logs. This
command should accept two arguments: 1) the subject of the message, and
@@ -239,10 +245,11 @@
.TP
\fBdateformat\fR \fIformat_string\fR
Specify the extension for \fBdateext\fR using the notation similar to
-\fBstrftime\fR(3) function. Only %Y %m %d and %s specifiers are allowed.
-The default value is \-%Y%m%d. Note that also the character separating log
-name from the extension is part of the dateformat string. The system clock
-must be set past Sep 9th 2001 for %s to work correctly.
+\fBstrftime\fR(3) function. Only %Y %m %d %H and %s specifiers are allowed.
+The default value is \-%Y%m%d except hourly, which uses \-%Y%m%d%H as default
+value. Note that also the character separating log name from the extension is
+part of the dateformat string. The system clock must be set past Sep 9th 2001
+for %s to work correctly.
Note that the datestamps generated by this format must be lexically sortable
(i.e., first the year, then the month then the day. e.g., 2001/12/01 is ok,
but 01/12/2001 is not, since 01/11/2002 would sort lower while it is later).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/logrotate-3.8.9/logrotate.c new/logrotate-3.9.1/logrotate.c
--- old/logrotate-3.8.9/logrotate.c 2015-02-13 07:11:21.000000000 +0100
+++ new/logrotate-3.9.1/logrotate.c 2015-04-03 09:39:35.000000000 +0200
@@ -20,6 +20,7 @@
#include
#include
#include
+#include
#if defined(SunOS)
#include
@@ -72,8 +73,6 @@
#define DOEXIT exit
#endif
-#define ERROR_STOP_ROTATION 1
-#define ERROR_CONTINUE_ROTATION 2
struct logState {
char *fn;
@@ -740,12 +739,133 @@
return 0;
}
+/* Use a heuristic to determine whether stat buffer SB comes from a file
+ with sparse blocks. If the file has fewer blocks than would normally
+ be needed for a file of its size, then at least one of the blocks in
+ the file is a hole. In that case, return true. */
+static int is_probably_sparse(struct stat const *sb)
+{
+#if defined(HAVE_STRUCT_STAT_ST_BLOCKS) && defined(HAVE_STRUCT_STAT_ST_BLKSIZE)
+ return (S_ISREG (sb->st_mode)
+ && sb->st_blocks < sb->st_size / sb->st_blksize);
+#else
+ return 0;
+#endif
+}
+
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+/* Return whether the buffer consists entirely of NULs.
+ Note the word after the buffer must be non NUL. */
+
+static inline int is_nul (void const *buf, size_t bufsize)
+{
+ char const *cbuf = buf;
+ char const *cp = buf;
+
+ /* Find the first nonzero *byte*, or the sentinel. */
+ while (*cp++ == 0)
+ continue;
+
+ return cbuf + bufsize < cp;
+}
+
+static size_t full_write(int fd, const void *buf, size_t count)
+{
+ size_t total = 0;
+ const char *ptr = (const char *) buf;
+
+ while (count > 0)
+ {
+ size_t n_rw;
+ for (;;)
+ {
+ n_rw = write (fd, buf, count);
+ if (errno == EINTR)
+ continue;
+ else
+ break;
+ }
+ if (n_rw == (size_t) -1)
+ break;
+ if (n_rw == 0)
+ break;
+ total += n_rw;
+ ptr += n_rw;
+ count -= n_rw;
+ }
+
+ return total;
+}
+
+static int sparse_copy(int src_fd, int dest_fd, struct stat *sb,
+ const char *saveLog, const char *currLog)
+{
+ int make_holes = is_probably_sparse(sb);
+ size_t max_n_read = SIZE_MAX;
+ int last_write_made_hole = 0;
+ off_t total_n_read = 0;
+ char buf[BUFSIZ + 1];
+
+ while (max_n_read) {
+ int make_hole = 0;
+
+ ssize_t n_read = read (src_fd, buf, MIN (max_n_read, BUFSIZ));
+ if (n_read < 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+ message(MESS_ERROR, "error reading %s: %s\n",
+ currLog, strerror(errno));
+ return 0;
+ }
+
+ if (n_read == 0)
+ break;
+
+ max_n_read -= n_read;
+ total_n_read += n_read;
+
+ if (make_holes) {
+ /* Sentinel required by is_nul(). */
+ buf[n_read] = '\1';
+
+ if ((make_hole = is_nul(buf, n_read))) {
+ if (lseek (dest_fd, n_read, SEEK_CUR) < 0) {
+ message(MESS_ERROR, "error seeking %s: %s\n",
+ saveLog, strerror(errno));
+ return 0;
+ }
+ }
+ }
+
+ if (!make_hole) {
+ size_t n = n_read;
+ if (full_write (dest_fd, buf, n) != n) {
+ message(MESS_ERROR, "error writing to %s: %s\n",
+ saveLog, strerror(errno));
+ return 0;
+ }
+ }
+
+ last_write_made_hole = make_hole;
+ }
+
+ if (last_write_made_hole) {
+ if (ftruncate(dest_fd, total_n_read) < 0) {
+ message(MESS_ERROR, "error ftruncate %s: %s\n",
+ saveLog, strerror(errno));
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
static int copyTruncate(char *currLog, char *saveLog, struct stat *sb,
int flags)
{
- char buf[BUFSIZ];
int fdcurr = -1, fdsave = -1;
- ssize_t cnt;
message(MESS_DEBUG, "copying %s to %s\n", currLog, saveLog);
@@ -753,7 +873,7 @@
if ((fdcurr = open(currLog, ((flags & LOG_FLAG_COPY) ? O_RDONLY : O_RDWR) | O_NOFOLLOW)) < 0) {
message(MESS_ERROR, "error opening %s: %s\n", currLog,
strerror(errno));
- return ERROR_CONTINUE_ROTATION;
+ return 1;
}
#ifdef WITH_SELINUX
if (selinux_enabled) {
@@ -822,21 +942,10 @@
return 1;
}
- while ((cnt = read(fdcurr, buf, sizeof(buf))) > 0) {
- if (write(fdsave, buf, cnt) != cnt) {
- message(MESS_ERROR, "error writing to %s: %s\n",
- saveLog, strerror(errno));
+ if (sparse_copy(fdcurr, fdsave, sb, saveLog, currLog) != 1) {
close(fdcurr);
close(fdsave);
return 1;
- }
- }
- if (cnt != 0) {
- message(MESS_ERROR, "error reading %s: %s\n",
- currLog, strerror(errno));
- close(fdcurr);
- close(fdsave);
- return 1;
}
}
@@ -928,8 +1037,15 @@
/* user forced rotation of logs from command line */
state->doRotate = 1;
}
+ else if (log->maxsize && sb.st_size > log->maxsize) {
+ state->doRotate = 1;
+ }
else if (log->criterium == ROT_SIZE) {
state->doRotate = (sb.st_size >= log->threshhold);
+ if (!state->doRotate) {
+ message(MESS_DEBUG, " log does not need rotating "
+ "(log size is below the 'size' threshold)\n");
+ }
} else if (mktime(&state->lastRotated) - mktime(&now) > (25 * 3600)) {
/* 25 hours allows for DST changes as well as geographical moves */
message(MESS_ERROR,
@@ -952,49 +1068,90 @@
((mktime(&now) -
mktime(&state->lastRotated)) >
(7 * 24 * 3600)));
+ if (!state->doRotate) {
+ message(MESS_DEBUG, " log does not need rotating "
+ "(log has been rotated at %d-%d-%d %d:%d, "
+ "that is not week ago yet)\n", state->lastRotated.tm_year,
+ state->lastRotated.tm_mon, state->lastRotated.tm_mday,
+ state->lastRotated.tm_hour, state->lastRotated.tm_min);
+ }
break;
case ROT_HOURLY:
state->doRotate = ((now.tm_hour != state->lastRotated.tm_hour) ||
(now.tm_mday != state->lastRotated.tm_mday) ||
(now.tm_mon != state->lastRotated.tm_mon) ||
(now.tm_year != state->lastRotated.tm_year));
+ if (!state->doRotate) {
+ message(MESS_DEBUG, " log does not need rotating "
+ "(log has been rotated at %d-%d-%d %d:%d, "
+ "that is not hour ago yet)\n", state->lastRotated.tm_year,
+ state->lastRotated.tm_mon, state->lastRotated.tm_mday,
+ state->lastRotated.tm_hour, state->lastRotated.tm_min);
+ }
break;
case ROT_DAYS:
/* FIXME: only days=1 is implemented!! */
state->doRotate = ((now.tm_mday != state->lastRotated.tm_mday) ||
(now.tm_mon != state->lastRotated.tm_mon) ||
(now.tm_year != state->lastRotated.tm_year));
+ if (!state->doRotate) {
+ message(MESS_DEBUG, " log does not need rotating "
+ "(log has been rotated at %d-%d-%d %d:%d, "
+ "that is not day ago yet)\n", state->lastRotated.tm_year,
+ state->lastRotated.tm_mon, state->lastRotated.tm_mday,
+ state->lastRotated.tm_hour, state->lastRotated.tm_min);
+ }
break;
case ROT_MONTHLY:
/* rotate if the logs haven't been rotated this month or
this year */
state->doRotate = ((now.tm_mon != state->lastRotated.tm_mon) ||
(now.tm_year != state->lastRotated.tm_year));
+ if (!state->doRotate) {
+ message(MESS_DEBUG, " log does not need rotating "
+ "(log has been rotated at %d-%d-%d %d:%d, "
+ "that is not month ago yet)\n", state->lastRotated.tm_year,
+ state->lastRotated.tm_mon, state->lastRotated.tm_mday,
+ state->lastRotated.tm_hour, state->lastRotated.tm_min);
+ }
break;
case ROT_YEARLY:
/* rotate if the logs haven't been rotated this year */
state->doRotate = (now.tm_year != state->lastRotated.tm_year);
+ if (!state->doRotate) {
+ message(MESS_DEBUG, " log does not need rotating "
+ "(log has been rotated at %d-%d-%d %d:%d, "
+ "that is not year ago yet)\n", state->lastRotated.tm_year,
+ state->lastRotated.tm_mon, state->lastRotated.tm_mday,
+ state->lastRotated.tm_hour, state->lastRotated.tm_min);
+ }
break;
default:
/* ack! */
state->doRotate = 0;
break;
}
- if (log->minsize && sb.st_size < log->minsize)
+ if (log->minsize && sb.st_size < log->minsize) {
state->doRotate = 0;
+ message(MESS_DEBUG, " log does not need rotating "
+ "('misinze' directive is used and the log "
+ "size is smaller than the minsize value");
+ }
+ }
+ else if (!state->doRotate) {
+ message(MESS_DEBUG, " log does not need rotating "
+ "(log has been already rotated)");
}
-
- if (log->maxsize && sb.st_size > log->maxsize)
- state->doRotate = 1;
/* The notifempty flag overrides the normal criteria */
- if (!(log->flags & LOG_FLAG_IFEMPTY) && !sb.st_size)
+ if (state->doRotate && !(log->flags & LOG_FLAG_IFEMPTY) && !sb.st_size) {
state->doRotate = 0;
+ message(MESS_DEBUG, " log does not need rotating "
+ "(log is empty)");
+ }
if (state->doRotate) {
message(MESS_DEBUG, " log needs rotating\n");
- } else {
- message(MESS_DEBUG, " log does not need rotating\n");
}
return 0;
@@ -1099,6 +1256,7 @@
j += 10; /* strlen("[0-9][0-9]") */
case 'm':
case 'd':
+ case 'H':
strncat(dext_pattern, "[0-9][0-9]",
sizeof(dext_pattern) - strlen(dext_pattern) - 1);
j += 10;
@@ -1250,9 +1408,10 @@
}
}
+ /* adding 2 due to / and \0 being added by snprintf */
rotNames->firstRotated =
malloc(strlen(rotNames->dirName) + strlen(rotNames->baseName) +
- strlen(fileext) + strlen(compext) + 30);
+ strlen(fileext) + strlen(compext) + DATEEXT_LEN + 2 );
if (log->flags & LOG_FLAG_DATEEXT) {
/* glob for compressed files with our pattern
@@ -1411,10 +1570,9 @@
}
/* if the last rotation doesn't exist, that's okay */
- if (!debug && rotNames->disposeName
- && access(rotNames->disposeName, F_OK)) {
+ if (rotNames->disposeName && access(rotNames->disposeName, F_OK)) {
message(MESS_DEBUG,
- "log %s doesn't exist -- won't try to " "dispose of it\n",
+ "log %s doesn't exist -- won't try to dispose of it\n",
rotNames->disposeName);
free(rotNames->disposeName);
rotNames->disposeName = NULL;
@@ -1501,7 +1659,7 @@
if (!ACL_NOT_WELL_SUPPORTED(errno)) {
message(MESS_ERROR, "getting file ACL %s: %s\n",
log->files[logNum], strerror(errno));
- hasErrors |= 1;
+ hasErrors = 1;
}
}
#endif /* WITH_ACL */
@@ -1517,12 +1675,7 @@
message(MESS_ERROR, "failed to rename %s to %s: %s\n",
log->files[logNum], tmpFilename,
strerror(errno));
- if (errno == ENOENT) {
- hasErrors |= ERROR_CONTINUE_ROTATION;
- }
- else {
- hasErrors |= 1;
- }
+ hasErrors = 1;
}
}
else {
@@ -1533,7 +1686,7 @@
message(MESS_ERROR, "failed to rename %s to %s: %s\n",
log->files[logNum], tmpFilename,
strerror(errno));
- hasErrors |= 1;
+ hasErrors = 1;
}
}
@@ -1587,7 +1740,7 @@
}
#endif
if (fd < 0)
- hasErrors |= 1;
+ hasErrors = 1;
else {
close(fd);
}
@@ -1605,7 +1758,7 @@
if (!hasErrors
&& log->flags & (LOG_FLAG_COPYTRUNCATE | LOG_FLAG_COPY)
&& !(log->flags & LOG_FLAG_TMPFILENAME)) {
- hasErrors |=
+ hasErrors =
copyTruncate(log->files[logNum], rotNames->finalName,
&state->sb, log->flags);
}
@@ -1680,7 +1833,6 @@
int i, j;
int hasErrors = 0;
int logHasErrors[log->numFiles];
- int logHasScriptErrors[log->numFiles];
int numRotated = 0;
struct logState **state;
struct logNames **rotNames;
@@ -1752,7 +1904,6 @@
for (i = 0; i < log->numFiles; i++) {
logHasErrors[i] = findNeedRotating(log, i, force);
hasErrors |= logHasErrors[i];
- logHasScriptErrors[i] = 0;
/* sure is a lot of findStating going on .. */
if ((findState(log->files[i]))->doRotate)
@@ -1821,8 +1972,7 @@
"error running non-shared prerotate script "
"for %s of '%s'\n", log->files[j], log->pattern);
}
- logHasScriptErrors[j] = 1;
- logHasErrors[j] = 1;
+ logHasErrors[j] = 1;
hasErrors = 1;
}
}
@@ -1831,7 +1981,8 @@
for (i = j;
((log->flags & LOG_FLAG_SHAREDSCRIPTS) && i < log->numFiles)
|| (!(log->flags & LOG_FLAG_SHAREDSCRIPTS) && i == j); i++) {
- if (!logHasScriptErrors[i] && !(logHasErrors[i] & ERROR_STOP_ROTATION)) {
+ if (! ( (logHasErrors[i] && !(log->flags & LOG_FLAG_SHAREDSCRIPTS))
+ || (hasErrors && (log->flags & LOG_FLAG_SHAREDSCRIPTS)) ) ) {
logHasErrors[i] |=
rotateSingleLog(log, i, state[i], rotNames[i]);
hasErrors |= logHasErrors[i];
@@ -1840,7 +1991,7 @@
if (log->post
&& (!(
- (((logHasErrors[j] & ERROR_STOP_ROTATION) || !state[j]->doRotate) && !(log->flags & LOG_FLAG_SHAREDSCRIPTS))
+ ((logHasErrors[j] || !state[j]->doRotate) && !(log->flags & LOG_FLAG_SHAREDSCRIPTS))
|| (hasErrors && (log->flags & LOG_FLAG_SHAREDSCRIPTS))
))
) {
@@ -1859,8 +2010,7 @@
"error running non-shared postrotate script "
"for %s of '%s'\n", log->files[j], log->pattern);
}
- logHasScriptErrors[j] = 1;
- logHasErrors[j] = 1;
+ logHasErrors[j] = 1;
hasErrors = 1;
}
}
@@ -1869,7 +2019,8 @@
for (i = j;
((log->flags & LOG_FLAG_SHAREDSCRIPTS) && i < log->numFiles)
|| (!(log->flags & LOG_FLAG_SHAREDSCRIPTS) && i == j); i++) {
- if (!logHasScriptErrors[i] && !(logHasErrors[i] & ERROR_STOP_ROTATION)) {
+ if (! ( (logHasErrors[i] && !(log->flags & LOG_FLAG_SHAREDSCRIPTS))
+ || (hasErrors && (log->flags & LOG_FLAG_SHAREDSCRIPTS)) ) ) {
logHasErrors[i] |=
postrotateSingleLog(log, i, state[i], rotNames[i]);
hasErrors |= logHasErrors[i];
@@ -2273,6 +2424,8 @@
{
int force = 0;
char *stateFile = STATEFILE;
+ char *logFile = NULL;
+ FILE *logFd = 0;
int rc = 0;
int arg;
const char **files;
@@ -2290,6 +2443,7 @@
"Path of state file",
"statefile"},
{"verbose", 'v', 0, 0, 'v', "Display messages during rotation"},
+ {"log", 'l', POPT_ARG_STRING, &logFile, 'l', "Log file"},
{"version", '\0', POPT_ARG_NONE, NULL, 'V', "Display version information"},
POPT_AUTOHELP {0, 0, 0, 0, 0}
};
@@ -2309,6 +2463,15 @@
case 'v':
logSetLevel(MESS_DEBUG);
break;
+ case 'l':
+ logFd = fopen(logFile, "w");
+ if (!logFd) {
+ message(MESS_ERROR, "error opening log file %s: %s\n",
+ logFile, strerror(errno));
+ break;
+ }
+ logSetMessageFile(logFd);
+ break;
case 'V':
fprintf(stderr, "logrotate %s\n", VERSION);
poptFreeContext(optCon);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/logrotate-3.8.9/logrotate.spec new/logrotate-3.9.1/logrotate.spec
--- old/logrotate-3.8.9/logrotate.spec 2015-02-13 07:11:21.000000000 +0100
+++ new/logrotate-3.9.1/logrotate.spec 2015-04-03 09:39:35.000000000 +0200
@@ -1,6 +1,6 @@
Summary: Rotates, compresses, removes and mails system log files
Name: logrotate
-Version: 3.8.9
+Version: 3.9.1
Release: 1
License: GPL+
Group: System Environment/Base
@@ -52,6 +52,12 @@
%attr(0644, root, root) %verify(not size md5 mtime) %config(noreplace) %{_localstatedir}/lib/logrotate.status
%changelog
+* Fri Apr 03 2015 Jan Kaluza 3.9.1-1
+- new upstream version
+
+* Fri Apr 03 2015 Jan Kaluza 3.9.0-1
+- new upstream version
+
* Fri Feb 13 2015 Jan Kaluza 3.8.9-1
- new upstream version
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/logrotate-3.8.9/test/test new/logrotate-3.9.1/test/test
--- old/logrotate-3.8.9/test/test 2015-02-13 07:11:20.000000000 +0100
+++ new/logrotate-3.9.1/test/test 2015-04-03 09:39:35.000000000 +0200
@@ -539,7 +539,7 @@
# ------------------------------- Test 17 ------------------------------------
preptest test.log 17 1 0
# log with 1 byte should not be rotated
-$RLR test-config.17 2>error.log
+$RLR test-config.17 -l logrotate.log 2>error.log
grep "unexpected } (missing previous '{')" error.log >/dev/null
if [ $? != 0 ]; then
@@ -549,6 +549,14 @@
rm error.log
+grep "reading config file test-config.17" logrotate.log >/dev/null
+if [ $? != 0 ]; then
+ echo "There is no log output in logrotate.log"
+ exit 3
+fi
+
+rm -f logrotate.log
+
checkoutput </dev/null
if [ $? != 0 ]; then
echo "test.log must have user:nobody:rwx ACL"
+ getfacl test.log
exit 3
fi
getfacl test.log|grep "group::---" >/dev/null
if [ $? != 0 ]; then
echo "test.log must have group::--- ACL"
+ getfacl test.log
exit 3
fi
getfacl test.log.1|grep "user:nobody:rwx" >/dev/null
if [ $? != 0 ]; then
echo "test.log.1 must have user:nobody:rwx ACL"
+ getfacl test.log.1
exit 3
fi
getfacl test.log.1|grep "group::---" >/dev/null
if [ $? != 0 ]; then
echo "test.log.1 must have group::--- ACL"
+ getfacl test.log.1
exit 3
fi
@@ -1124,7 +1136,7 @@
# ------------------------------- Test 45 ------------------------------------
# Test that prerotate and postrotate scripts are not called when sharedscripts
-# is defined and one rotation fails. File test.log should still be rotated.
+# is defined and one rotation fails
preptest test.log 45 1
touch scriptout
@@ -1139,8 +1151,7 @@
rm -f error.log
checkoutput < test2.log
+# Test we log debug output using -l option when passed.
+preptest test.log 61 1 0
+
+$RLR test-config.61 --force -l ./logrotate.log
-$RLR test-config.60 2>error.log
+DATESTRING=$(/bin/date +%Y-%m-%d-%H)
-grep "error opening" error.log >/dev/null
+grep "reading config file test-config.61" logrotate.log >/dev/null
if [ $? != 0 ]; then
- echo "No error printed, but there should be one."
+ echo "There is no log output in logrotate.log"
exit 3
fi
+rm -f logrotate.log
+
checkoutput < test.log
+truncate -s 10M test.log
+echo x >> test.log
+
+cp test.log test.example
+
+SIZE_SPARSE_OLD=$(du test.log|awk '{print $1}')
+SIZE_OLD=$(du --apparent-size test.log|awk '{print $1}')
+$RLR test-config.24 --force
+SIZE_NEW=$(du --apparent-size test.log.1|awk '{print $1}')
+SIZE_SPARSE_NEW=$(du test.log.1|awk '{print $1}')
+
+if [ $SIZE_OLD != $SIZE_NEW ]; then
+ echo "Bad apparent size of sparse logs"
+ echo "test.log: $SIZE_OLD"
+ echo "test.log.1: $SIZE_NEW"
+ exit 3
+fi
+
+if [ $SIZE_SPARSE_OLD -gt 100 ] || [ $SIZE_SPARSE_NEW -gt 100 ]; then
+ echo "Bad size of sparse logs"
+ echo "test.log: $SIZE_SPARSE_OLD"
+ echo "test.log.1: $SIZE_SPARSE_NEW"
+ exit 3
+fi
+
+checkoutput < test.log
+truncate -s 10M test.log
+
+cp test.log test.example
+
+SIZE_SPARSE_OLD=$(du test.log|awk '{print $1}')
+SIZE_OLD=$(du --apparent-size test.log|awk '{print $1}')
+$RLR test-config.24 --force
+SIZE_NEW=$(du --apparent-size test.log.1|awk '{print $1}')
+SIZE_SPARSE_NEW=$(du test.log.1|awk '{print $1}')
+
+if [ $SIZE_OLD != $SIZE_NEW ]; then
+ echo "Bad apparent size of sparse logs"
+ echo "test.log: $SIZE_OLD"
+ echo "test.log.1: $SIZE_NEW"
+ exit 3
+fi
+
+if [ $SIZE_SPARSE_OLD -gt 100 ] || [ $SIZE_SPARSE_NEW -gt 100 ]; then
+ echo "Bad size of sparse logs"
+ echo "test.log: $SIZE_SPARSE_OLD"
+ echo "test.log.1: $SIZE_SPARSE_NEW"
+ exit 3
+fi
+
+checkoutput <extension);
@@ -64,9 +64,9 @@
Index: logrotate.8
===================================================================
---- logrotate.8.orig 2013-07-25 14:13:02.780567373 +0200
-+++ logrotate.8 2013-07-25 14:13:04.196582364 +0200
-@@ -265,6 +265,15 @@ configured to be run by cron daily. You
+--- logrotate.8.orig
++++ logrotate.8
+@@ -283,6 +283,15 @@ configured to be run by cron daily. You
and run \fIlogrotate\fR hourly to be able to really rotate logs hourly.
.TP
@@ -84,9 +84,9 @@
option (\fBifempty\fR is the default).
Index: logrotate.c
===================================================================
---- logrotate.c.orig 2013-07-25 14:13:02.781567384 +0200
-+++ logrotate.c 2013-07-25 14:13:04.196582364 +0200
-@@ -964,6 +964,24 @@ int prerotateSingleLog(struct logInfo *l
+--- logrotate.c.orig
++++ logrotate.c
+@@ -1216,6 +1216,24 @@ int prerotateSingleLog(struct logInfo *l
rotNames->baseName = strdup(ourBaseName(log->files[logNum]));
@@ -113,9 +113,9 @@
(rotNames->
Index: logrotate.h
===================================================================
---- logrotate.h.orig 2013-07-25 14:13:02.781567384 +0200
-+++ logrotate.h 2013-07-25 14:13:04.196582364 +0200
-@@ -44,6 +44,7 @@ struct logInfo {
+--- logrotate.h.orig
++++ logrotate.h
+@@ -54,6 +54,7 @@ struct logInfo {
char *pre, *post, *first, *last, *preremove;
char *logAddress;
char *extension;
@@ -125,8 +125,8 @@
char *compress_ext;
Index: test/test-config.100.in
===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ test/test-config.100.in 2013-07-25 14:13:04.196582364 +0200
+--- /dev/null
++++ test/test-config.100.in
@@ -0,0 +1,7 @@
+create
+
@@ -137,8 +137,8 @@
+}
Index: test/test-config.101.in
===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ test/test-config.101.in 2013-07-25 14:13:04.196582364 +0200
+--- /dev/null
++++ test/test-config.101.in
@@ -0,0 +1,7 @@
+create
+