Code

Merge branch 'collectd-4.2' into collectd-4.3
[collectd.git] / src / exec.c
index df912a6c49782884247541b1ba46cda027f767f0..b25e76979ebb2322db79a5acdd746d28ecf73335 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * collectd - src/exec.c
- * Copyright (C) 2007  Florian octo Forster
+ * Copyright (C) 2007,2008  Florian octo Forster
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -22,7 +22,9 @@
 #include "collectd.h"
 #include "common.h"
 #include "plugin.h"
+
 #include "utils_cmd_putval.h"
+#include "utils_cmd_putnotif.h"
 
 #include <sys/types.h>
 #include <pwd.h>
@@ -33,7 +35,6 @@
 
 #define PL_NORMAL        0x01
 #define PL_NOTIF_ACTION  0x02
-#define PL_NAGIOS_PLUGIN 0x04
 
 #define PL_RUNNING       0x10
 
@@ -126,9 +127,7 @@ static int exec_config_exec (oconfig_item_t *ci) /* {{{ */
   }
   memset (pl, '\0', sizeof (program_list_t));
 
-  if (strcasecmp ("NagiosExec", ci->key) == 0)
-    pl->flags |= PL_NAGIOS_PLUGIN;
-  else if (strcasecmp ("NotificationExec", ci->key) == 0)
+  if (strcasecmp ("NotificationExec", ci->key) == 0)
     pl->flags |= PL_NOTIF_ACTION;
   else
     pl->flags |= PL_NORMAL;
@@ -251,7 +250,6 @@ static int exec_config (oconfig_item_t *ci) /* {{{ */
   {
     oconfig_item_t *child = ci->children + i;
     if ((strcasecmp ("Exec", child->key) == 0)
-       || (strcasecmp ("NagiosExec", child->key) == 0)
        || (strcasecmp ("NotificationExec", child->key) == 0))
       exec_config_exec (child);
     else
@@ -327,6 +325,25 @@ static void exec_child (program_list_t *pl) /* {{{ */
     }
   } /* if (pl->group == NULL) */
 
+#if HAVE_SETGROUPS
+  if (getuid () == 0)
+  {
+    gid_t  glist[2];
+    size_t glist_len;
+
+    glist[0] = gid;
+    glist_len = 1;
+
+    if (gid != egid)
+    {
+      glist[1] = egid;
+      glist_len = 2;
+    }
+
+    setgroups (glist_len, glist);
+  }
+#endif /* HAVE_SETGROUPS */
+
   status = setgid (gid);
   if (status != 0)
   {
@@ -469,10 +486,15 @@ static int parse_line (char *buffer) /* {{{ */
   int fields_num;
 
   fields[0] = "PUTVAL";
-  fields_num = strsplit (buffer, &fields[1], STATIC_ARRAY_SIZE(fields) - 1);
+  fields_num = strsplit (buffer, fields + 1, STATIC_ARRAY_SIZE(fields) - 1);
 
-  handle_putval (stdout, fields, fields_num + 1);
-  return (0);
+  if (strcasecmp (fields[1], "putval") == 0)
+    return (handle_putval (stdout, fields + 1, fields_num));
+  else if (strcasecmp (fields[1], "putnotif") == 0)
+    return (handle_putnotif (stdout, fields + 1, fields_num));
+
+  /* compatibility code */
+  return (handle_putval (stdout, fields, fields_num + 1));
 } /* int parse_line }}} */
 
 static void *exec_read_one (void *arg) /* {{{ */
@@ -516,9 +538,6 @@ static void *exec_read_one (void *arg) /* {{{ */
 
     DEBUG ("exec plugin: exec_read_one: buffer = %s", buffer);
 
-    if (pl->flags & PL_NAGIOS_PLUGIN)
-      break;
-
     parse_line (buffer);
   } /* while (fgets) */
 
@@ -530,29 +549,6 @@ static void *exec_read_one (void *arg) /* {{{ */
   DEBUG ("exec plugin: Child %i exited with status %i.",
       (int) pl->pid, pl->status);
 
-  if (pl->flags & PL_NAGIOS_PLUGIN)
-  {
-    notification_t n;
-
-    memset (&n, '\0', sizeof (n));
-    
-    n.severity = NOTIF_FAILURE;
-    if (pl->status == 0)
-      n.severity = NOTIF_OKAY;
-    else if (pl->status == 1)
-      n.severity = NOTIF_WARNING;
-
-    strncpy (n.message, buffer, sizeof (n.message));
-    n.message[sizeof (n.message) - 1] = '\0';
-
-    n.time = time (NULL);
-
-    strncpy (n.host, hostname_g, sizeof (n.host));
-    n.host[sizeof (n.host) - 1] = '\0';
-
-    plugin_dispatch_notification (&n);
-  }
-
   pl->pid = 0;
 
   pthread_mutex_lock (&pl_lock);
@@ -574,8 +570,10 @@ static void *exec_notification_one (void *arg) /* {{{ */
   const char *severity;
 
   pid = fork_child (pl, &fd, NULL);
-  if (pid < 0)
+  if (pid < 0) {
+    sfree (arg);
     pthread_exit ((void *) 1);
+  }
 
   fh = fdopen (fd, "w");
   if (fh == NULL)
@@ -586,6 +584,7 @@ static void *exec_notification_one (void *arg) /* {{{ */
     kill (pl->pid, SIGTERM);
     pl->pid = 0;
     close (fd);
+    sfree (arg);
     pthread_exit ((void *) 1);
   }
 
@@ -595,12 +594,25 @@ static void *exec_notification_one (void *arg) /* {{{ */
   else if (n->severity == NOTIF_OKAY)
     severity = "OKAY";
 
-  fprintf (fh, "Severity: %s\n"
-      "Time: %u\n"
-      "Host: %s\n"
-      "Message: %s\n"
-      "\n",
-      severity, (unsigned int) n->time, n->host, n->message);
+  fprintf (fh,
+      "Severity: %s\n"
+      "Time: %u\n",
+      severity, (unsigned int) n->time);
+
+  /* Print the optional fields */
+  if (strlen (n->host) > 0)
+    fprintf (fh, "Host: %s\n", n->host);
+  if (strlen (n->plugin) > 0)
+    fprintf (fh, "Plugin: %s\n", n->plugin);
+  if (strlen (n->plugin_instance) > 0)
+    fprintf (fh, "PluginInstance: %s\n", n->plugin_instance);
+  if (strlen (n->type) > 0)
+    fprintf (fh, "Type: %s\n", n->type);
+  if (strlen (n->type_instance) > 0)
+    fprintf (fh, "TypeInstance: %s\n", n->type_instance);
+
+  fprintf (fh, "\n%s\n", n->message);
+
   fflush (fh);
   fclose (fh);
 
@@ -634,8 +646,8 @@ static int exec_read (void) /* {{{ */
     pthread_t t;
     pthread_attr_t attr;
 
-    /* Only execute `normal' and `nagios' style executables here. */
-    if ((pl->flags & (PL_NAGIOS_PLUGIN | PL_NORMAL)) == 0)
+    /* Only execute `normal' style executables here. */
+    if ((pl->flags & PL_NORMAL) == 0)
       continue;
 
     pthread_mutex_lock (&pl_lock);