[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[bug-inetutils] syslog - circular log extension
From: |
Daniel Lehne |
Subject: |
[bug-inetutils] syslog - circular log extension |
Date: |
Thu, 01 Mar 2012 11:43:00 +0200 |
User-agent: |
Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20120216 Thunderbird/10.0.2 |
Hello,
in my last mail i reported to port the circular log feature clog from
BSD to our version of inetutils. The response was, such a feature is
welcome but the source is too old (1991) for a port.
After some bad circumstance, which i will report specially, i changed
and reduced the logic and the additional source hardly. Once syslog
comes with GPL, i also grant GPL. This patch is untested and the use it
on your own risk! The base idea comes from Jeff Weelhouse with his clog
program.
I fixed some bugs especially for allocation, once strdup (kernel.org
strdup )is used. There are still code parts confusing me, but i let them
untouched. Like this:
> static void dbg_printf (const char *fmt, ...)
> ...
> #if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
> va_start (ap, fmt);
> #else
> va_start (ap);
> #endif
>
> va_start (ap, fmt);
> vfprintf (stdout, fmt, ap);
The timestamps aren't important to me(missing fractional seconds), so i
mask them out with IOV_OFFSET, change it to 0 and they will be back.
Known Bugs:
The maximum file size could be exceeded once the incoming message is
greater than the maximum file size.
Non cosmetic warp cut old lines.
Syntax in syslog.conf for a circular log:
<facility>.<priority/level>{SPACES}%<file>{SPACE}<maximum
size>{SPACE}<offset>
<> must replaced by the user for his needs, all fields must filled
{} essential syntax characters must used by the user
Best regards!
Daniel Lehne
Here the patch based on inetutils-1.6:
Index: inetutils-1.6/syslogd/syslogd.c
===================================================================
--- inetutils-1.6.orig/syslogd/syslogd.c 2012-03-01
11:05:11.588949808 +0200
+++ inetutils-1.6/syslogd/syslogd.c 2012-03-01 12:11:53.860948399 +0200
@@ -146,6 +146,8 @@
*/
int facilities_seen;
+const char clog_wrap[] = "\n\n"; /* empty line, indicates wrap
of ringbuffer */
+
const char *ConfFile = PATH_LOGCONF; /* Default Configuration file. */
const char *PidFile = PATH_LOGPID; /* Default path to tuck pid. */
char ctty[] = PATH_CONSOLE; /* Default console to send message
info. */
@@ -193,6 +195,12 @@
char *f_hname;
struct sockaddr_in f_addr;
} f_forw; /* Forwarding address. */
+ struct {
+ char *f_fname;
+ long int cf_offset;
+ long int cf_next;
+ long int cf_max;
+ } f_clog; /* circular log file */
char *f_fname; /* Name use for Files|Pipes|TTYs. */
} f_un;
char f_prevline[MAXSVLINE]; /* Last message logged. */
@@ -219,6 +227,7 @@
#define F_FORW_SUSP 7 /* Suspended host forwarding. */
#define F_FORW_UNKN 8 /* Unknown host forwarding. */
#define F_PIPE 9 /* Named pipe. */
+#define F_CLOG 10 /* Circular log) */
const char *TypeNames[] = {
"UNUSED",
@@ -230,7 +239,8 @@
"WALL",
"FORW(SUSPENDED)",
"FORW(UNKNOWN)",
- "PIPE"
+ "PIPE",
+ "CLOG"
};
/* Flags in filed.f_flags. */
@@ -255,6 +265,10 @@
/* Delimiter in arguments to command line options `-s' and `-l'. */
#define LIST_DELIMITER ':'
+/* Constants for the F_CLOG footer and wrap */
+#define WRAP_CHARS_SIZE sizeof(clog_wrap) /* size of space print on
wraping the log */
+#define IOV_OFFSET 2 /* ignore n first elements of
iov - DATE, SPACE */
+
extern int waitdaemon (int nochdir, int noclose, int maxwait);
void cfline (const char *, struct filed *);
@@ -278,6 +292,7 @@
static void add_funix (const char *path);
static int create_unix_socket (const char *path);
static int create_inet_socket (void);
+ssize_t clogwritev (struct filed *, struct iovec *, int);
char *LocalHostName; /* Our hostname. */
char *LocalDomain; /* Our local domain name. */
@@ -1319,6 +1334,7 @@
{
f->f_type = F_UNUSED;
logerror (f->f_un.f_fname);
+ free(f->f_un.f_fname);
}
else
goto again;
@@ -1328,12 +1344,28 @@
f->f_type = F_UNUSED;
errno = e;
logerror (f->f_un.f_fname);
+ free(f->f_un.f_fname);
}
}
else if ((flags & SYNC_FILE) && !(f->f_flags & OMIT_SYNC))
fsync (f->f_file);
break;
+ case F_CLOG:
+ f->f_time = now;
+ dbg_printf(" %s\n", f->f_un.f_fname);
+ v->iov_base = "\n";
+ v->iov_len = 1;
+ if (clogwritev(f, iov, IOVCNT) < 0) {
+ int e = errno;
+ close(f->f_file);
+ f->f_type = F_UNUSED;
+ errno = e;
+ logerror(f->f_un.f_fname);
+ free(f->f_un.f_fname);
+ }
+ break;
+
case F_USERS:
case F_WALL:
f->f_time = now;
@@ -1593,7 +1625,9 @@
case F_TTY:
case F_CONSOLE:
case F_PIPE:
- close (f->f_file);
+ case F_CLOG:
+ free(f->f_un.f_fname);
+ close (f->f_file);
break;
}
next = f->f_next;
@@ -1734,6 +1768,7 @@
case F_TTY:
case F_CONSOLE:
case F_PIPE:
+ case F_CLOG:
dbg_printf ("%s", f->f_un.f_fname);
break;
@@ -1926,6 +1961,7 @@
if ((f->f_file = open (++p, O_RDWR | O_NONBLOCK)) < 0)
{
f->f_type = F_UNUSED;
+ free(f->f_un.f_fname);
logerror (p);
break;
}
@@ -1942,6 +1978,7 @@
if ((f->f_file = open (p, O_WRONLY | O_APPEND | O_CREAT, 0644)) < 0)
{
f->f_type = F_UNUSED;
+ free(f->f_un.f_fname);
logerror (p);
break;
}
@@ -1953,6 +1990,45 @@
f->f_type = F_FILE;
break;
+ /* circular log file */
+ case '%':
+ f->f_type = F_UNUSED;
+ memset(&f->f_un.f_clog, 0, sizeof(f->f_un.f_clog));
+ f->f_un.f_clog.f_fname = strdup(p+1);
+ errno = 0;
+ q = strtok(f->f_un.f_clog.f_fname, " ");
+ if ((errno) || ((f->f_file = open(q, O_WRONLY | O_TRUNC |
O_CREAT, 0644)) < 0))
+ {
+ free(f->f_un.f_fname);
+ logerror(p);
+ break;
+ }
+ /* parse size */
+ errno = 0;
+ q = strtok(NULL, " ");
+ f->f_un.f_clog.cf_max = strtol(q, NULL ,10);
+ if(errno) {
+ close(f->f_file);
+ free(f->f_un.f_fname);
+ logerror(p);
+ break;
+ }
+ /* parse offset */
+ q = strtok(NULL, " ");
+ errno = 0;
+ f->f_un.f_clog.cf_offset = strtol(q, NULL ,10);
+ if(errno) {
+ close(f->f_file);
+ free(f->f_un.f_fname);
+ logerror(p);
+ break;
+ }
+ /* prohibit invalid offsets */
+ if (f->f_un.f_clog.cf_offset > (f->f_un.f_clog.cf_max -
WRAP_CHARS_SIZE) )
+ f->f_un.f_clog.cf_offset = 0;
+ f->f_type = F_CLOG;
+ break;
+
case '*':
f->f_type = F_WALL;
break;
@@ -1983,6 +2059,40 @@
}
}
+/* The following function handles the circular log file access */
+ssize_t clogwritev(struct filed *f, struct iovec *iov, int iovcnt) {
+ int i;
+ ssize_t out = 0;
+ ssize_t err = 0;
+ long int diff = 0;
+
+ /* wrap file when data not fit maximum size */
+ for(i=IOV_OFFSET; i<iovcnt; i++)
+ out += iov[i].iov_len;
+ diff = (f->f_un.f_clog.cf_max - f->f_un.f_clog.cf_next);
+ if((diff < 0) || (out >= diff))
+ {
+ /* hard wrap to offset and set mark */
+ f->f_un.f_clog.cf_next = f->f_un.f_clog.cf_offset;
+ err = pwrite(f->f_file, clog_wrap, strlen(clog_wrap),
f->f_un.f_clog.cf_next);
+ if (err == -1)
+ return -1;
+ fsync(f->f_file);
+ f->f_un.f_clog.cf_next += err;
+ }
+ out = 0;
+
+ /* write out to circular log file */
+ err = pwritev(f->f_file,&iov[IOV_OFFSET],iovcnt -
IOV_OFFSET,f->f_un.f_clog.cf_next);
+ if (err==-1)
+ return -1;
+ fsync(f->f_file);
+ f->f_un.f_clog.cf_next += err;
+ out += err;
+
+ return out;
+}
+
/* Decode a symbolic name to a numeric value. */
int
decode (const char *name, CODE * codetab)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [bug-inetutils] syslog - circular log extension,
Daniel Lehne <=