{GPL, other}: Relicense to MIT license.
[collectd.git] / src / exec.c
index 9e3a20e..d56c07f 100644 (file)
@@ -18,7 +18,7 @@
  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  *
  * Authors:
- *   Florian octo Forster <octo at verplant.org>
+ *   Florian octo Forster <octo at collectd.org>
  *   Sebastian Harl <sh at tokkee.org>
  *   Peter Holik <peter at holik.at>
  **/
@@ -270,13 +270,15 @@ static void set_environment (void) /* {{{ */
   char buffer[1024];
 
 #ifdef HAVE_SETENV
-  ssnprintf (buffer, sizeof (buffer), "%i", interval_g);
+  ssnprintf (buffer, sizeof (buffer), "%.3f",
+      CDTIME_T_TO_DOUBLE (plugin_get_interval ()));
   setenv ("COLLECTD_INTERVAL", buffer, /* overwrite = */ 1);
 
   ssnprintf (buffer, sizeof (buffer), "%s", hostname_g);
   setenv ("COLLECTD_HOSTNAME", buffer, /* overwrite = */ 1);
 #else
-  ssnprintf (buffer, sizeof (buffer), "COLLECTD_INTERVAL=%i", interval_g);
+  ssnprintf (buffer, sizeof (buffer), "COLLECTD_INTERVAL=%.3f",
+      CDTIME_T_TO_DOUBLE (plugin_get_interval ()));
   putenv (buffer);
 
   ssnprintf (buffer, sizeof (buffer), "COLLECTD_HOSTNAME=%s", hostname_g);
@@ -285,71 +287,11 @@ static void set_environment (void) /* {{{ */
 } /* }}} void set_environment */
 
 __attribute__((noreturn))
-static void exec_child (program_list_t *pl) /* {{{ */
+static void exec_child (program_list_t *pl, int uid, int gid, int egid) /* {{{ */
 {
   int status;
-  int uid;
-  int gid;
-  int egid;
-
-  struct passwd *sp_ptr;
-  struct passwd sp;
-  char nambuf[2048];
   char errbuf[1024];
 
-  sp_ptr = NULL;
-  status = getpwnam_r (pl->user, &sp, nambuf, sizeof (nambuf), &sp_ptr);
-  if (status != 0)
-  {
-    ERROR ("exec plugin: Failed to get user information for user ``%s'': %s",
-        pl->user, sstrerror (errno, errbuf, sizeof (errbuf)));
-    exit (-1);
-  }
-  if (sp_ptr == NULL)
-  {
-    ERROR ("exec plugin: No such user: `%s'", pl->user);
-    exit (-1);
-  }
-
-  uid = sp.pw_uid;
-  gid = sp.pw_gid;
-  if (uid == 0)
-  {
-    ERROR ("exec plugin: Cowardly refusing to exec program as root.");
-    exit (-1);
-  }
-
-  /* The group configured in the configfile is set as effective group, because
-   * this way the forked process can (re-)gain the user's primary group. */
-  egid = -1;
-  if (NULL != pl->group)
-  {
-    if ('\0' != *pl->group) {
-      struct group *gr_ptr = NULL;
-      struct group gr;
-
-      status = getgrnam_r (pl->group, &gr, nambuf, sizeof (nambuf), &gr_ptr);
-      if (0 != status)
-      {
-        ERROR ("exec plugin: Failed to get group information "
-            "for group ``%s'': %s", pl->group,
-            sstrerror (errno, errbuf, sizeof (errbuf)));
-        exit (-1);
-      }
-      if (NULL == gr_ptr)
-      {
-        ERROR ("exec plugin: No such group: `%s'", pl->group);
-        exit (-1);
-      }
-
-      egid = gr.gr_gid;
-    }
-    else
-    {
-      egid = gid;
-    }
-  } /* if (pl->group == NULL) */
-
 #if HAVE_SETGROUPS
   if (getuid () == 0)
   {
@@ -427,6 +369,14 @@ static int fork_child (program_list_t *pl, int *fd_in, int *fd_out, int *fd_err)
   int status;
   int pid;
 
+  int uid;
+  int gid;
+  int egid;
+
+  struct passwd *sp_ptr;
+  struct passwd sp;
+  char nambuf[2048];
+
   if (pl->pid != 0)
     return (-1);
 
@@ -454,6 +404,59 @@ static int fork_child (program_list_t *pl, int *fd_in, int *fd_out, int *fd_err)
     return (-1);
   }
 
+  sp_ptr = NULL;
+  status = getpwnam_r (pl->user, &sp, nambuf, sizeof (nambuf), &sp_ptr);
+  if (status != 0)
+  {
+    ERROR ("exec plugin: Failed to get user information for user ``%s'': %s",
+        pl->user, sstrerror (errno, errbuf, sizeof (errbuf)));
+    return (-1);
+  }
+  if (sp_ptr == NULL)
+  {
+    ERROR ("exec plugin: No such user: `%s'", pl->user);
+    return (-1);
+  }
+
+  uid = sp.pw_uid;
+  gid = sp.pw_gid;
+  if (uid == 0)
+  {
+    ERROR ("exec plugin: Cowardly refusing to exec program as root.");
+    return (-1);
+  }
+
+  /* The group configured in the configfile is set as effective group, because
+   * this way the forked process can (re-)gain the user's primary group. */
+  egid = -1;
+  if (NULL != pl->group)
+  {
+    if ('\0' != *pl->group) {
+      struct group *gr_ptr = NULL;
+      struct group gr;
+
+      status = getgrnam_r (pl->group, &gr, nambuf, sizeof (nambuf), &gr_ptr);
+      if (0 != status)
+      {
+        ERROR ("exec plugin: Failed to get group information "
+            "for group ``%s'': %s", pl->group,
+            sstrerror (errno, errbuf, sizeof (errbuf)));
+        return (-1);
+      }
+      if (NULL == gr_ptr)
+      {
+        ERROR ("exec plugin: No such group: `%s'", pl->group);
+        return (-1);
+      }
+
+      egid = gr.gr_gid;
+    }
+    else
+    {
+      egid = gid;
+    }
+  } /* if (pl->group == NULL) */
+
   pid = fork ();
   if (pid < 0)
   {
@@ -503,7 +506,7 @@ static int fork_child (program_list_t *pl, int *fd_in, int *fd_out, int *fd_err)
     /* Unblock all signals */
     reset_signal_mask ();
 
-    exec_child (pl);
+    exec_child (pl, uid, gid, egid);
     /* does not return */
   }
 
@@ -537,12 +540,9 @@ static int parse_line (char *buffer) /* {{{ */
     return (handle_putnotif (stdout, buffer));
   else
   {
-    /* For backwards compatibility */
-    char tmp[1220];
-    /* Let's annoy the user a bit.. */
-    INFO ("exec plugin: Prepending `PUTVAL' to this line: %s", buffer);
-    ssnprintf (tmp, sizeof (tmp), "PUTVAL %s", buffer);
-    return (handle_putval (stdout, tmp));
+    ERROR ("exec plugin: Unable to parse command, ignoring line: \"%s\"",
+       buffer);
+    return (-1);
   }
 } /* int parse_line }}} */
 
@@ -744,8 +744,8 @@ static void *exec_notification_one (void *arg) /* {{{ */
 
   fprintf (fh,
       "Severity: %s\n"
-      "Time: %u\n",
-      severity, (unsigned int) n->time);
+      "Time: %.3f\n",
+      severity, CDTIME_T_TO_DOUBLE (n->time));
 
   /* Print the optional fields */
   if (strlen (n->host) > 0)
@@ -828,7 +828,7 @@ static int exec_read (void) /* {{{ */
 
     pthread_attr_init (&attr);
     pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
-    pthread_create (&t, &attr, exec_read_one, (void *) pl);
+    plugin_thread_create (&t, &attr, exec_read_one, (void *) pl);
     pthread_attr_destroy (&attr);
   } /* for (pl) */
 
@@ -872,7 +872,7 @@ static int exec_notification (const notification_t *n, /* {{{ */
 
     pthread_attr_init (&attr);
     pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
-    pthread_create (&t, &attr, exec_notification_one, (void *) pln);
+    plugin_thread_create (&t, &attr, exec_notification_one, (void *) pln);
     pthread_attr_destroy (&attr);
   } /* for (pl) */