Fix #66: Rotate /var/log/wtmp log max:2, size:100k

This patch adds a simple log-rotate function to the UTMP, WTMP, BTMP,
and lastlog files.  Enabled by default, disable with:

    configure --disable-logrotate

Even though it can rotate /run/utmp it is unlikely this file will grow
that much during a system's uptime.

The hard-coded defaults are to keep up to two (2) previous versions
of the files and rotate on file size >= 100k.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson
2017-01-25 19:40:06 +01:00
parent a0e17c8f47
commit 9974d65756
2 changed files with 75 additions and 0 deletions
+6
View File
@@ -56,6 +56,9 @@ AC_ARG_ENABLE(watchdog,
AC_ARG_ENABLE(inetd,
AS_HELP_STRING([--disable-inetd], [Disable built-in inetd super server, default enabled]))
AC_ARG_ENABLE(logrotate,
AS_HELP_STRING([--disable-logrotate], [Disable built-in rotation of /var/log/wtmp, default enabled]))
AC_ARG_ENABLE(quiet,
AS_HELP_STRING([--disable-quiet], [Default Finit obeys the kernel quiet option]))
@@ -145,6 +148,9 @@ AS_IF([test "x$enable_inetd" != "xno"], [
enable_inetd="yes"
AC_DEFINE(INETD_ENABLED, 1, [Enable built-in inetd])])
AS_IF([test "x$enable_logrotate" != "xno"], [
AC_DEFINE(LOGROTATE_ENABLED, 1, [Enable built-in rotation of /var/log/wtmp et al.])])
AS_IF([test "x$enable_quiet" != "xno"], [
AC_DEFINE(QUIET_MODE, 1, [Silent, after initial boot, no stopping/starting messages. Default: 1])
], [
+69
View File
@@ -21,6 +21,9 @@
* THE SOFTWARE.
*/
#include "config.h"
#include <paths.h>
#include <stdio.h>
#include <time.h>
#include <utmp.h>
@@ -28,6 +31,14 @@
#include <sys/utsname.h>
#include <lite/lite.h>
#include "helpers.h"
#ifndef _PATH_BTMP
#define _PATH_BTMP "/var/log/btmp"
#endif
#define MAX_NO 2
#define MAX_SZ 100 * 1024
static void utmp_strncpy(char *dst, const char *src, size_t dlen)
{
@@ -40,6 +51,62 @@ static void utmp_strncpy(char *dst, const char *src, size_t dlen)
dst[i] = 0;
}
#ifdef LOGROTATE_ENABLED
static int logrotate(char *file, int num, off_t sz)
{
struct stat st;
if (stat(file, &st))
return 1;
if (sz > 0 && S_ISREG(st.st_mode) && st.st_size > sz) {
if (num > 0) {
size_t len = strlen(file) + 3 + 1;
char ofile[len];
char nfile[len];
while (num) {
snprintf(ofile, len, "%s.%d", file, num - 1);
snprintf(nfile, len, "%s.%d", file, num--);
/* May fail because ofile doesn't exist yet, ignore. */
(void)rename(ofile, nfile);
}
rename(file, nfile);
create(file, st.st_mode, st.st_uid, st.st_gid);
} else {
truncate(file, 0);
}
}
return 0;
}
#endif /* LOGROTATE_ENABLED */
/*
* Rotate /var/log/wtmp (+ btmp?) and /run/utmp
*
* Useful on systems with no logrotate daemon, e.g. BusyBox based
* systems where syslogd rotates its own log files only.
*/
void utmp_logrotate(void)
{
#ifdef LOGROTATE_ENABLED
int i;
char *files[] = {
_PATH_UTMP,
_PATH_WTMP,
_PATH_BTMP,
_PATH_LASTLOG,
NULL
};
for (i = 0; files[i]; i++)
logrotate(files[i], MAX_NO, MAX_SZ);
#endif /* LOGROTATE_ENABLED */
}
int utmp_set(int type, int pid, char *line, char *id, char *user)
{
int result = 0;
@@ -75,6 +142,8 @@ int utmp_set(int type, int pid, char *line, char *id, char *user)
result += pututline(&ut) ? 0 : 1;
endutent();
}
utmp_logrotate();
updwtmp(_PATH_WTMP, &ut);
return result;