Commit 03c92dcf authored by Tobias Frost's avatar Tobias Frost

Import Upstream version 3.8.5

parent 73923da4
3.8.4 -> 3.8.5
- Improved rotation during daylight saving time and between timezone
changes.
- Fixed ACL setting problem caused by ext3 erroneously reporting ENOSYS
instead of ENOSUP.
- Do not continue with rotation if state file is corrupted.
- Make logrotate.status creation atomic.
- Allow "hourly" rotation. See manpage for more information.
- Use "/bin/echo" in tests. Fixes tests execution in Dash.
- Do no try to parse config files bigger than 16MB.
- Improved manpage consistency and formatting.
- Fix race condition between acl_set_fd() and fchmod().
3.8.3 -> 3.8.4
- Added --version command line option
- Disable ACL tests if logrotate is not compiled WITH_ACL support or if
ACLs are not supported by the system running tests
- Disable SELinux tests if logrotate is not compiled WITH_SELINUX support
or if SELinux is not supported by the system running tests
- Fixed bug which prevented skipping particular log file config
if the config contained errors.
- Fixed skipping of configs containing firstaction/lastaction scripts
with '}' character in case of error before these scripts.
- Support also 'K' unit for *size directives.
- Added preremove option to let admin to do something with the old logs
before they are removed by logrotate.
- Fixed possible loop in tabooext parsing.
- Move code to set SELinux context before compressLogFile calls to create
compressed log files with the proper context.
- Call prerotate/postrotate script only for really rotated files in
nosharedscripts mode (as stated in man page).
3.8.2 -> 3.8.3
- Fixed setting "size" bigger than 4GB on 32bit architectures
- Do not overwrite mode set by "create" option when using ACL. "create"
......
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code
2. Type `make' to compile the package.
3. Optionally, type `make test' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'.
If you want to add the Access Control List (ACL) support to the program
use `make WITH_ACL=yes' at the point 2 and `make test WITH_ACL=yes' at
the point 3.
If you want to add the NSA Security-Enhanced Linux (SELinux) support to
the program use `make WITH_SELINUX=yes' at the point 2.
If you want to add both the ACL and SELinux supports to the program use
`make WITH_ACL=yes WITH_SELINUX=yes' at the point 2 and
`make test WITH_ACL=yes' at the point 3.
......@@ -13,11 +13,21 @@ SVNTAG = r$(subst .,-,$(VERSION))
ifeq ($(WITH_SELINUX),yes)
CFLAGS += -DWITH_SELINUX
LOADLIBES += -lselinux
# See pretest
TEST_SELINUX=1
else
# See pretest
TEST_SELINUX=0
endif
ifeq ($(WITH_ACL),yes)
CFLAGS += -DWITH_ACL
LOADLIBES += -lacl
# See pretest
TEST_ACL=1
else
# See pretest
TEST_ACL=0
endif
# HP-UX using GCC
......@@ -104,16 +114,25 @@ endif
RCSVERSION = $(subst .,-,$(VERSION))
all: $(TARGET)
all: $(TARGET) pretest
$(PROG): $(OBJS)
clean:
rm -f $(OBJS) $(PROG) core* .depend
rm -f ./test/test.ACL ./test/test.SELINUX ./test/error.log
depend:
$(CPP) $(CFLAGS) -M $(SOURCES) > .depend
# pretest create the file ./test/test.ACL with
# 0 or 1 according to the WITH_ACL=yes presence.
# The file will be used by ./test/test to decide
# if to do the ACL tests or not.
pretest:
echo "$(TEST_ACL)" > ./test/test.ACL ;
echo "$(TEST_SELINUX)" > ./test/test.SELINUX ;
.PHONY : test
test: $(TARGET)
(cd test; ./test)
......
......@@ -45,7 +45,7 @@
#include "asprintf.c"
#endif
#if !defined(asprintf)
#if !defined(asprintf) && !defined(_FORTIFY_SOURCE)
#include <stdarg.h>
int asprintf(char **string_ptr, const char *format, ...)
......@@ -260,7 +260,9 @@ static int checkFile(const char *fname)
/* Check if fname is ending in a taboo-extension; if so, return false */
for (i = 0; i < tabooCount; i++) {
asprintf(&pattern, "*%s", tabooExts[i]);
if (asprintf(&pattern, "*%s", tabooExts[i]) < 0) {
message(MESS_FATAL, "failed to allocate taboo pattern memory\n");
}
if (!fnmatch(pattern, fname, 0))
{
free(pattern);
......@@ -309,6 +311,8 @@ static void copyLogInfo(struct logInfo *to, struct logInfo *from)
to->first = strdup(from->first);
if (from->last)
to->last = strdup(from->last);
if (from->preremove)
to->preremove = strdup(from->preremove);
if (from->logAddress)
to->logAddress = strdup(from->logAddress);
if (from->extension)
......@@ -343,6 +347,7 @@ static void freeLogInfo(struct logInfo *log)
free(log->post);
free(log->first);
free(log->last);
free(log->preremove);
free(log->logAddress);
free(log->extension);
free(log->compress_prog);
......@@ -381,7 +386,8 @@ static void freeTailLogs(int num)
message(MESS_DEBUG, "removing last %d log configs\n", num);
while (num--)
removeLogInfo(*(logs.tqh_last));
removeLogInfo(TAILQ_LAST(&logs, logInfoHead));
}
static int readConfigPath(const char *path, struct logInfo *defConfig)
......@@ -521,6 +527,7 @@ int readAllConfigPaths(const char **paths)
.post = NULL,
.first = NULL,
.last = NULL,
.preremove = NULL,
.logAddress = NULL,
.extension = NULL,
.compress_prog = NULL,
......@@ -624,12 +631,14 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
if ((flags = fcntl(fd, F_GETFD)) == -1) {
message(MESS_ERROR, "Could not retrieve flags from file %s\n",
configFile);
close(fd);
return 1;
}
flags |= FD_CLOEXEC;
if (fcntl(fd, F_SETFD, flags) == -1) {
message(MESS_ERROR, "Could not set flags on file %s\n",
configFile);
close(fd);
return 1;
}
/* We don't want anybody to change the file while we parse it,
......@@ -654,6 +663,7 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
if (!(pw = getpwuid(getuid()))) {
message(MESS_ERROR, "Logrotate UID is not in passwd file.\n");
close(fd);
return 1;
}
......@@ -687,6 +697,13 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
length = sb.st_size;
if (length > 0xffffff) {
message(MESS_ERROR, "file %s too large, probably not a config file.\n",
configFile);
close(fd);
return 1;
}
/* We can't mmap empty file... */
if (length == 0) {
message(MESS_DEBUG,
......@@ -915,7 +932,7 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
if ((key = isolateValue(configFile, lineNum, opt, &start,
&buf, length)) != NULL) {
int l = strlen(key) - 1;
if (key[l] == 'k') {
if (key[l] == 'k' || key[l] == 'K') {
key[l] = '\0';
multiplier = 1024;
} else if (key[l] == 'M') {
......@@ -938,7 +955,7 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
multiplier = 1;
}
size = multiplier * strtoul(key, &chptr, 0);
size = multiplier * strtoull(key, &chptr, 0);
if (*chptr) {
message(MESS_ERROR, "%s:%d bad size '%s'\n",
configFile, lineNum, key);
......@@ -976,6 +993,8 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
}
}
else continue;
} else if (!strcmp(key, "hourly")) {
newlog->criterium = ROT_HOURLY;
} else if (!strcmp(key, "daily")) {
newlog->criterium = ROT_DAYS;
newlog->threshhold = 1;
......@@ -1084,6 +1103,11 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
scriptStart = start;
scriptDest = &newlog->last;
state = STATE_LOAD_SCRIPT;
} else if (!strcmp(key, "preremove")) {
freeLogItem (preremove);
scriptStart = start;
scriptDest = &newlog->preremove;
state = STATE_LOAD_SCRIPT;
} else if (!strcmp(key, "tabooext")) {
if (newlog != defConfig) {
message(MESS_ERROR,
......@@ -1123,8 +1147,8 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
endtag = chptr;
if (*endtag == ',')
start++;
while (isspace(*endtag) && *endtag)
endtag++;
while (*endtag && isspace(*endtag))
endtag++;
}
}
......@@ -1439,12 +1463,8 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
newlog->pattern = key;
// if (!logerror)
// message(MESS_DEBUG, "reading config info for %s\n", start);
free(argv);
// start = endtag + 1;
} else if (*start == '}') {
if (newlog == defConfig) {
message(MESS_ERROR, "%s:%d unexpected }\n", configFile,
......@@ -1463,7 +1483,7 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
free(globerr_msg);
globerr_msg = NULL;
if (!(newlog->flags & LOG_FLAG_MISSINGOK))
return 1;
goto error;
}
if (newlog->oldDir) {
......@@ -1588,13 +1608,30 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
if (
(strcmp(key, "postrotate") == 0) ||
(strcmp(key, "prerotate") == 0) ||
(strcmp(key, "firstrotate") == 0) ||
(strcmp(key, "lastrotate") == 0)
(strcmp(key, "firstaction") == 0) ||
(strcmp(key, "lastaction") == 0) ||
(strcmp(key, "preremove") == 0)
) {
state = STATE_LOAD_SCRIPT | STATE_SKIP_CONFIG;
}
else {
state = STATE_SKIP_LINE | STATE_SKIP_CONFIG;
/* isolateWord moves the "start" pointer.
* If we have a line like
* rotate 5
* after isolateWord "start" points to "5" and it
* is OK to skip the line, but if we have a line
* like the following
* nocompress
* after isolateWord "start" points to "\n". In
* this case if we skip a line, we skip the next
* line, not the current "nocompress" one,
* because in the for cycle the "start"
* pointer is increased by one and, after this,
* "start" points to the beginning of the next line.
*/
if (*start != '\n') {
state = STATE_SKIP_LINE | STATE_SKIP_CONFIG;
}
}
free(key);
key = NULL;
......@@ -1613,7 +1650,7 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
if (scriptStart) {
message(MESS_ERROR,
"%s:prerotate or postrotate without endscript\n",
"%s:prerotate, postrotate or preremove without endscript\n",
configFile);
goto error;
}
......
.TH LOGROTATE 8 "Wed Nov 5 2002" "Linux" "System Administrator's Manual"
.SH NAME
logrotate \- rotates, compresses, and mails system logs
logrotate \(hy rotates, compresses, and mails system logs
.SH SYNOPSIS
\fBlogrotate\fR [\fB-dv\fR] [\fB-f\fR|\fB--force\fR]
[\fB-s\fR|\fB--state \fIfile\fR] \fIconfig_file\fR ..
\fBlogrotate\fR [\fB\-dv\fR] [\fB\-f\fR|\fB\-\-force\fR]
[\fB\-s\fR|\fB\-\-state \fIfile\fR] \fIconfig_file\fR ..
.SH DESCRIPTION
\fBlogrotate\fR is designed to ease administration of systems that generate
large numbers of log files. It allows automatic rotation, compression,
......@@ -13,7 +13,7 @@ weekly, monthly, or when it grows too large.
Normally, \fBlogrotate\fR is run as a daily cron job. It will not modify
a log multiple times in one day unless the criterion for that log is
based on the log's size and \fBlogrotate\fR is being run multiple times
each day, or unless the \fB-f\fR or \fB--force\fR option is used.
each day, or unless the \fB\-f\fR or \fB\-\-force\fR option is used.
.P
Any number of config files may be given on the command line. Later config
files may override the options given in earlier files, so the order
......@@ -31,16 +31,16 @@ non-zero status.
.SH OPTIONS
.TP
\fB-?\fR, \fB-\-help\fR
\fB\-?\fR, \fB\-\-help\fR
Prints help message.
.TP
\fB-d\fR, \fB-\-debug\fR
\fB\-d\fR, \fB\-\-debug\fR
Turns on debug mode and implies \fB-v\fR. In debug mode, no changes will
be made to the logs or to the \fBlogrotate\fR state file.
.TP
\fB-f\fR, \fB-\-force\fR
\fB\-f\fR, \fB\-\-force\fR
Tells \fBlogrotate\fR to force the rotation, even if it doesn't think
this is necessary. Sometimes this is useful after adding new entries to
a \fBlogrotate\fR config file, or if old log files have been removed
......@@ -48,7 +48,7 @@ by hand, as the new files will be created, and logging will continue
correctly.
.TP
\fB-m\fR, \fB-\-mail <command>\fR
\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
2) the recipient. The command must then read a message on standard input
......@@ -56,17 +56,17 @@ and mail it to the recipient. The default mail command is \fB/bin/mail
-s\fR.
.TP
\fB-s, -\-state <statefile>\fR
\fB\-s\fR, \fB\-\-state <statefile>\fR
Tells \fBlogrotate\fR to use an alternate state file. This is useful
if logrotate is being run as a different user for various sets of
log files. The default state file is \fI/var/lib/logrotate.status\fR.
.TP
\fB-\-usage\fR
\fB\-\-usage\fR
Prints a short usage message.
.TP
\fB-v\fR, \fB-\-verbose\fR
+\fB\-v\fR, \fB\-\-verbose\fR
Turns on verbose mode.
.SH CONFIGURATION FILE
......@@ -86,7 +86,7 @@ compress
rotate 5
weekly
postrotate
/usr/bin/killall -HUP syslogd
/usr/bin/killall \-HUP syslogd
endscript
}
......@@ -96,7 +96,7 @@ compress
size 100k
sharedscripts
postrotate
/usr/bin/killall -HUP httpd
/usr/bin/killall \-HUP httpd
endscript
}
......@@ -106,7 +106,7 @@ compress
olddir /var/log/news/old
missingok
postrotate
kill -HUP `cat /var/run/inn.pid`
kill \-HUP `cat /var/run/inn.pid`
endscript
nocompress
}
......@@ -125,7 +125,7 @@ The next section of the config files defined how to handle the log file
\fI/var/log/messages\fR. The log will go through five weekly rotations before
being removed. After the log file has been rotated (but before the old
version of the log has been compressed), the command
\fI/sbin/killall -HUP syslogd\fR will be executed.
\fI/sbin/killall \-HUP syslogd\fR will be executed.
The next section defines the parameters for both
\fI/var/log/httpd/access.log\fR and \fI/var/log/httpd/error.log\fR.
......@@ -178,8 +178,11 @@ command.
.TP
\fBcompressoptions\fR
Command line options may be passed to the compression program, if one is
in use. The default, for \fBgzip\fR(1), is "-6" (biased towards high
in use. The default, for \fBgzip\fR(1), is "\-6" (biased towards high
compression at the expense of speed).
If you use a different compression command, you may need to change the
\fBcompressoptions\fR to match.
.TP
\fBcopy\fR
......@@ -226,7 +229,7 @@ the \fBdateformat\fR and \fBdateyesterday\fR options.
\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
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.
Note that the datestamps generated by this format must be lexically sortable
......@@ -255,6 +258,12 @@ If compression is used, the compression extension (normally \fB.gz\fR)
appears after \fIext\fR. For example you have a logfile named mylog.foo
and want to rotate it to mylog.1.foo.gz instead of mylog.foo.1.gz.
.TP
\fBhourly\fR
Log files are rotated every hour. Note that usually \fIlogrotate\fR is
configured to be run by cron daily. You have to change this configuration
and run \fIlogrotate\fR hourly to be able to really rotate logs hourly.
.TP
\fBifempty\fR
Rotate the log file even if it is empty, overriding the \fBnotifempty\fR
......@@ -431,6 +440,13 @@ passed to the script as first argument. If the script exits
with error, just an error message is shown (as this is the last
action). See also \fBfirstaction\fR.
.TP
\fBpreremove\fR/\fBendscript\fR
The lines between \fBpreremove\fR and \fBendscript\fR (both of which must
appear on lines by themselves) are executed (using \fB/bin/sh\fR) once just
before removal of a log file. The logrotate will pass
the name of file which is soon to be removed. See also \fBfirstaction\fR.
.TP
\fBrotate \fIcount\fR
Log files are rotated \fIcount\fR times before being removed or mailed to the
......@@ -461,7 +477,7 @@ actions will not be executed for any logs. This option overrides the
.TP
\fBshred\fR
Delete log files using \fBshred\fR -u instead of unlink(). This should
Delete log files using \fBshred\fR \-u instead of unlink(). This should
ensure that logs are not readable after their scheduled deletion; this is
off by default. See also \fBnoshred\fR.
......@@ -476,7 +492,7 @@ This is the number to use as the base for rotation. For example, if
you specify 0, the logs will be created with a .0 extension as they are
rotated from the original log files. If you specify 9, log files will
be created with a .9, skipping 0-8. Files will still be rotated the
number of times specified with the \fBcount\fR directive.
number of times specified with the \fBrotate\fR directive.
.TP
\fBsu \fIuser\fR \fIgroup\fR
......@@ -490,7 +506,7 @@ The current taboo extension list is changed (see the \fBinclude\fR directive
for information on the taboo extensions). If a + precedes the list of
extensions, the current taboo extension list is augmented, otherwise it
is replaced. At startup, the taboo extension list
contains .rpmsave, .rpmorig, ~, .disabled, .dpkg-old, .dpkg-dist, .dpkg-new, .cfsaved, .ucf-old, .ucf-dist, .ucf-new, .rpmnew, .swp, .cfsaved, .rhn-cfg-tmp-*
contains .rpmsave, .rpmorig, ~, .disabled, .dpkg\-old, .dpkg\-dist, .dpkg\-new, .cfsaved, .ucf\-old, .ucf\-dist, .ucf\-new, .rpmnew, .swp, .cfsaved, .rhn\-cfg\-tmp\-*
.TP
\fBweekly\fR
......
This diff is collapsed.
......@@ -33,15 +33,15 @@ struct logInfo {
char **files;
int numFiles;
char *oldDir;
enum { ROT_DAYS, ROT_WEEKLY, ROT_MONTHLY, ROT_YEARLY, ROT_SIZE,
ROT_FORCE } criterium;
enum { ROT_HOURLY, ROT_DAYS, ROT_WEEKLY, ROT_MONTHLY, ROT_YEARLY, ROT_SIZE
} criterium;
unsigned long long threshhold;
unsigned long long maxsize;
unsigned long long minsize;
int rotateCount;
int rotateAge;
int logStart;
char *pre, *post, *first, *last;
char *pre, *post, *first, *last, *preremove;
char *logAddress;
char *extension;
char *compress_prog;
......@@ -67,7 +67,7 @@ extern int numLogs;
extern int debug;
int readAllConfigPaths(const char **paths);
#if !defined(asprintf)
#if !defined(asprintf) && !defined(_FORTIFY_SOURCE)
int asprintf(char **string_ptr, const char *format, ...);
#endif
......
Summary: Rotates, compresses, removes and mails system log files
Name: logrotate
Version: 3.8.3
Version: 3.8.5
Release: 1
License: GPL+
Group: System Environment/Base
......@@ -52,6 +52,12 @@ rm -rf $RPM_BUILD_ROOT
%attr(0644, root, root) %verify(not size md5 mtime) %config(noreplace) %{_localstatedir}/lib/logrotate.status
%changelog
* Mon Jun 10 2013 Jan Kaluza <jkaluza@redhat.com> 3.8.5-1
- new upstream version
* Tue Apr 30 2013 Jan Kaluza <jkaluza@redhat.com> 3.8.4-1
- new upstream version
* Thu Oct 04 2012 Jan Kaluza <jkaluza@redhat.com> 3.8.3-1
- new upstream version
......
This diff is collapsed.
# bad unit 'x'
&DIR&/test.log {
daily
size 300x
rotate 1
}
&DIR&/test.log {
size 300x
daily
firstaction
touch scriptout
# put some } here, so we check if parser won't break on it.
}
echo $(cat scriptout) foo > foo }
mv foo scriptout
endscript
rotate 1
}
&DIR&/test.log {
create
daily
firstaction
touch scriptout
echo $(cat scriptout) second > foo
mv foo scriptout
endscript
rotate 1
}
create
&DIR&/test*.log {
monthly
rotate 0
mail user@myhost.org
maillast
sharedscripts
preremove
touch scriptout
echo -n $(basename $*) >> scriptout
endscript
}
create
&DIR&/test*.log {
monthly
rotate 0
mail user@myhost.org
maillast
sharedscripts
preremove
touch scriptout
echo -n $(basename $*) >> scriptout
this should trigger an error
endscript
}
create
tabooext .v,.sample,.unused,~
tabooext + .x, .y, .z
include &DIR&/testingdir
create
&DIR&/test*.log {
size 5
rotate 1
nosharedscripts
prerotate
touch scriptout
echo -n $(basename $1) >> scriptout
echo -n ";" >> scriptout
endscript
postrotate
touch scriptout
echo -n $(basename $1) >> scriptout
echo -n ";" >> scriptout
endscript
}
create
&DIR&/test*.log {
size 5
rotate 1
sharedscripts
prerotate
touch scriptout
IFS=$(/bin/echo -en "\n\b")
echo -n "\"" >> scriptout
for f in "$1"
do
echo -n $(basename $f) >> scriptout
echo -n ";" >> scriptout
done
endscript
postrotate
touch scriptout
IFS=$(/bin/echo -en "\n\b")
for f in "$1"
do
echo -n $(basename $f) >> scriptout
echo -n ";" >> scriptout
done
echo -n "\"" >> scriptout
endscript
}
create
&DIR&/test*.log {
size 5
rotate 1
nosharedscripts
prerotate
touch scriptout
echo -n $(basename $1) >> scriptout
echo -n ";" >> scriptout
endscript
postrotate
touch scriptout
echo -n $(basename $1) >> scriptout
echo -n ";" >> scriptout
endscript
}
create
&DIR&/test.log &DIR&/test2.log {
size 5
rotate 1
nosharedscripts
prerotate
touch scriptout
IFS=$(/bin/echo -en "\n\b")
echo -n "\"" >> scriptout
for f in "$1"
do
echo -n $(basename $f) >> scriptout
echo -n ";" >> scriptout
done
endscript
postrotate
touch scriptout
IFS=$(/bin/echo -en "\n\b")
for f in "$1"
do
echo -n $(basename $f) >> scriptout
echo -n ";" >> scriptout
done
echo -n "\"" >> scriptout
endscript
}
create
&DIR&/test.log &DIR&/test2.log {
size 5
rotate 1
sharedscripts
prerotate
touch scriptout
IFS=$(echo -en "\n\b")
echo -n "\"" >> scriptout
for f in "$1"
do
echo -n $(basename $f) >> scriptout
echo -n ";" >> scriptout
done
endscript
postrotate
touch scriptout
IFS=$(echo -en "\n\b")
for f in "$1"
do
echo -n $(basename $f) >> scriptout
echo -n ";" >> scriptout
done
echo -n "\"" >> scriptout
endscript
}
create
&DIR&/test.log {
daily
rotate 999
dateext
}
create
&DIR&/test.log {
daily
rotate 999
dateext
}
create
&DIR&/test.log {
daily
rotate 999
size 2
}
create
&DIR&/test.log {
daily
rotate 4
size 2
}
create
&DIR&/test.log {
hourly
dateext
rotate 4
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment