Hello,

I add script call features to newsyslog.  This adds a one field to
newsyslog.conf.  When newsyslog processed log file, this can execute
arbitrary program.

Situation to assume:
 * For the log file which cannot use signal.
 * Cases to do statistical application for log file.

A sample entry of newsylog.conf:
# logfilename  [owner:group] mode count size when [ZB] [/pid_file] [sig_num] [/program]
/var/log/foo.log  bar:baz    640  1     100  *     Z   -  -  /etc/foo.sh

'-' is usable as a filler of null field.

I used similar enhanced function from the past.  I think that you can
apply this patch for 5-current.  In addition, I can prepare a patch
for 4-stable if it is necessary.

I ask for testing and a review of the following patches.

Thanks.
--
Toshihiko ARAI


Index: newsyslog.8
===================================================================
RCS file: /home/ncvs/src/usr.sbin/newsyslog/newsyslog.8,v
retrieving revision 1.32
diff -u -r1.32 newsyslog.8
--- newsyslog.8 2001/07/30 15:17:17     1.32
+++ newsyslog.8 2001/09/30 08:54:07
@@ -76,7 +76,7 @@
 Each line of the file contains information about a particular log file
 that should be handled by
 .Nm .
-Each line has five mandatory fields and four optional fields, with
+Each line has five mandatory fields and five optional fields, with
 whitespace separating each field.  Blank lines or lines beginning with
 ``#'' are ignored.  The fields of the configuration file are as
 follows:
@@ -294,12 +294,28 @@
 .Ar signal_number
 is sent the process id contained in this
 file.  This field must start with "/" in order to be recognized
-properly.
+properly.  Same as
+.Ar flags
+field, you can use "-" for null field.
 .It Ar signal_number
 This optional field specifies
-the signal number will be sent to the daemon process.
+the signal number or signal name will be sent to the daemon process.
 By default
-a SIGHUP will be sent.
+a SIGHUP will be sent.  Same as
+.Ar flags
+field, you can use "-" for null field.
+.It Ar path_to_program
+This optional field specifies
+the path name of a script for postprocessing of log file. 
+This field must be specified with full path.
+And a file must be execute permission by specified
+.Ar owner
+and
+.Ar group .
+When
+.Ar path_to_program
+is called, new log file is given to the first argument, and old
+log file is given to the second argument.
 .El
 .Sh OPTIONS
 The following options can be used with
Index: newsyslog.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/newsyslog/newsyslog.c,v
retrieving revision 1.37
diff -u -r1.37 newsyslog.c
--- newsyslog.c 2001/07/31 16:25:55     1.37
+++ newsyslog.c 2001/10/08 14:09:19
@@ -38,6 +38,7 @@
 
 #include <ctype.h>
 #include <err.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <grp.h>
 #include <paths.h>
@@ -73,6 +74,7 @@
 struct conf_entry {
        char *log;              /* Name of the log */
        char *pid_file;         /* PID file */
+       char *prog;             /* Program for postprocessing */
        int uid;                /* Owner of log */
        int gid;                /* Group of log */
        int numlogs;            /* Number of logs to keep */
@@ -106,11 +108,13 @@
 static void do_entry(struct conf_entry * ent);
 static void PRS(int argc, char **argv);
 static void usage(void);
-static void dotrim(char *log, const char *pid_file, int numdays, int falgs,
-               int perm, int owner_uid, int group_gid, int sig);
+static void dotrim(char *log, const char *pid_file, const char *prog,
+               int numdays, int falgs, int perm, int owner_uid,
+               int group_gid, int sig);
 static int log_trim(char *log);
 static void compress_log(char *log);
 static void bzcompress_log(char *log);
+static int post_prog(const char *prog, char *log, int owner_uid, int group_gid);
 static int sizefile(char *file);
 static int age_old_log(char *file);
 static pid_t get_pid(const char *pid_file);
@@ -119,6 +123,7 @@
                int group_gid);
 static void createdir(char *dirpart);
 static time_t parseDWM(char *s);
+static int signame_to_signum(char *sig);
 
 int
 main(int argc, char **argv)
@@ -200,7 +205,7 @@
                                else
                                        pid_file = NULL;
                        }
-                       dotrim(ent->log, pid_file, ent->numlogs,
+                       dotrim(ent->log, pid_file, ent->prog, ent->numlogs,
                            ent->flags, ent->permissions, ent->uid, ent->gid,
                            ent->sig);
                } else {
@@ -460,34 +465,52 @@
                if (q && *q) {
                        if (*q == '/')
                                working->pid_file = strdup(q);
-                       else if (isdigit(*q))
+                       else if (isalnum(*q))
                                goto got_sig;
-                       else
-                               errx(1,
-                       "illegal pid file or signal number in config file:\n%s",
+                       else if (*q != '-')
+                               errx(1, "illegal pid file in config file:\n%s",
                                    errline);
                }
+
                if (eol)
                        q = NULL;
                else {
                        q = parse = sob(++parse);       /* Optional field */
-                       *(parse = son(parse)) = '\0';
+                       parse = son(parse);
+                       if (!*parse)
+                               eol = 1;
+                       *parse = '\0';
                }
 
+       got_sig:
                working->sig = SIGHUP;
                if (q && *q) {
-                       if (isdigit(*q)) {
-               got_sig:
+                       if (isdigit(*q))
                                working->sig = atoi(q);
-                       } else {
-               err_sig:
+                       else if (*q != '-')
+                               working->sig = signame_to_signum(q);
+                       if (working->sig < 1 || working->sig >= NSIG)
                                errx(1,
                                    "illegal signal number in config file:\n%s",
                                    errline);
-                       }
-                       if (working->sig < 1 || working->sig >= NSIG)
-                               goto err_sig;
                }
+
+               if (eol)
+                       q = NULL;
+               else {
+                       q = parse = sob(++parse);       /* Optional field */
+                       *(parse = son(parse)) = '\0';
+               }
+
+               working->prog = NULL;
+               if (q && *q) {
+                       if (*q == '/')
+                               working->prog = strdup(q);
+                       else if (*q != '-')
+                               errx(1,
+                                   "illegal program file in config file:\n%s",
+                                   errline);
+               }
                free(errline);
        }
        if (working)
@@ -506,14 +529,14 @@
 }
 
 static void
-dotrim(char *log, const char *pid_file, int numdays, int flags, int perm,
-    int owner_uid, int group_gid, int sig)
+dotrim(char *log, const char *pid_file, const char *prog, int numdays,
+    int flags, int perm, int owner_uid, int group_gid, int sig)
 {
        char dirpart[MAXPATHLEN], namepart[MAXPATHLEN];
        char file1[MAXPATHLEN], file2[MAXPATHLEN];
        char zfile1[MAXPATHLEN], zfile2[MAXPATHLEN];
        char jfile1[MAXPATHLEN];
-       int notified, need_notification, fd, _numdays;
+       int notified, need_notification, pstat, fd, _numdays;
        struct stat st;
        pid_t pid;
 
@@ -660,7 +683,7 @@
                (void) chmod(log, perm);
 
        pid = 0;
-       need_notification = notified = 0;
+       need_notification = notified = pstat = 0;
        if (pid_file != NULL) {
                need_notification = 1;
                pid = get_pid(pid_file);
@@ -677,11 +700,29 @@
                                printf("daemon pid %d notified\n", (int) pid);
                }
        }
+       if (prog != NULL) {
+               if (need_notification && !notified)
+                       warnx("don't run %s because signal is not notified",
+                             prog);
+               else if (noaction)
+                       printf("Exec %s %s %s.0\n", prog, log, log);
+               else {
+                       pstat = post_prog(prog, log, owner_uid, group_gid);
+                       if (pstat != 0)
+                               warnx("%s returned exit status %d",
+                                     prog, WEXITSTATUS(pstat));
+                       else if (verbose)
+                               printf("exec %s done\n", prog);
+               }
+       }
        if ((flags & CE_COMPACT) || (flags & CE_BZCOMPACT)) {
                if (need_notification && !notified)
                        warnx(
                            "log %s not compressed because daemon not notified",
                            log);
+               else if (pstat != 0)
+                       warnx("log %s is not compressed because %s failed",
+                             log, prog);
                else if (noaction)
                        printf("Compress %s.0\n", log);
                else {
@@ -756,6 +797,32 @@
        }
 }
 
+/* Program run for postprocessing of log file */
+static int
+post_prog(const char *prog, char *log, int owner_uid, int group_gid)
+{
+       pid_t pid;
+       int pstat;
+
+       pid = vfork();
+       if (pid < 0)
+               err(1, "can't vfork");
+       else if (pid == 0) {
+               char tmp[MAXPATHLEN];
+
+               (void) snprintf(tmp, sizeof(tmp), "%s.0", log);
+               if (group_gid != NONE)
+                       setgid(group_gid);
+               if (owner_uid != NONE)
+                       setuid(owner_uid);
+               (void) execl(prog, prog, log, tmp, NULL);
+               warn("can't exec %s", prog);
+               _exit(1);
+       }
+       while (waitpid(pid, &pstat, 0) == -1 && errno == EINTR);
+       return pstat;
+}
+
 /* Return size in kilobytes of a file */
 static int
 sizefile(char *file)
@@ -1100,3 +1167,19 @@
        }
        return mktime(&tm);
 }
+
+/* Convert a signal name into signal number */
+static int
+signame_to_signum(char *sig)
+{
+       int n;
+
+       if (!strncasecmp(sig, "sig", (size_t)3))
+               sig += 3;
+       for (n = 1; n < NSIG; n++) {
+               if (!strcasecmp(sys_signame[n], sig))
+                       return (n);
+       }
+       return (-1);
+}
+

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message

Reply via email to