bug-inetutils
[Top][All Lists]
Advanced

[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)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]