Merge branch 'ff/highres'
[collectd.git] / src / notify_email.c
index a13b1f9..da6894a 100644 (file)
@@ -1,6 +1,7 @@
 /**
  * collectd - src/notify_email.c
  * Copyright (C) 2008  Oleg King
+ * Copyright (C) 2010  Florian 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
@@ -18,6 +19,7 @@
  *
  * Authors:
  *   Oleg King <king2 at kaluga.ru>
+ *   Florian Forster <octo at collectd.org>
  **/
 
 #include "collectd.h"
@@ -26,6 +28,7 @@
 
 #include <auth-client.h>
 #include <libesmtp.h>
+#include <pthread.h>
 
 #define MAXSTRING               256
 
@@ -45,6 +48,7 @@ static char **recipients;
 static int recipients_len = 0;
 
 static smtp_session_t session;
+static pthread_mutex_t session_lock = PTHREAD_MUTEX_INITIALIZER;
 static smtp_message_t message;
 static auth_context_t authctx = NULL;
 
@@ -113,17 +117,23 @@ static int notify_email_init (void)
 {
   char server[MAXSTRING];
 
+  ssnprintf(server, sizeof (server), "%s:%i",
+      (smtp_host == NULL) ? DEFAULT_SMTP_HOST : smtp_host,
+      smtp_port);
+
+  pthread_mutex_lock (&session_lock);
+
   auth_client_init();
-  if (!(session = smtp_create_session ())) {
+
+  session = smtp_create_session ();
+  if (session == NULL) {
+    pthread_mutex_unlock (&session_lock);
     ERROR ("notify_email plugin: cannot create SMTP session");
     return (-1);
   }
 
   smtp_set_monitorcb (session, monitor_cb, NULL, 1);
   smtp_set_hostname (session, hostname_g);
-  ssnprintf(server, sizeof (server), "%s:%i",
-      (smtp_host == NULL) ? DEFAULT_SMTP_HOST : smtp_host,
-      smtp_port);
   smtp_set_server (session, server);
 
   if (smtp_user && smtp_password) {
@@ -133,18 +143,30 @@ static int notify_email_init (void)
   }
 
   if ( !smtp_auth_set_context (session, authctx)) {
+    pthread_mutex_unlock (&session_lock);
     ERROR ("notify_email plugin: cannot set SMTP auth context");
     return (-1);   
   }
 
+  pthread_mutex_unlock (&session_lock);
   return (0);
 } /* int notify_email_init */
 
 static int notify_email_shutdown (void)
 {
-  smtp_destroy_session (session);
-  auth_destroy_context (authctx);
+  pthread_mutex_lock (&session_lock);
+
+  if (session != NULL)
+    smtp_destroy_session (session);
+  session = NULL;
+
+  if (authctx != NULL)
+    auth_destroy_context (authctx);
+  authctx = NULL;
+
   auth_client_exit();
+
+  pthread_mutex_unlock (&session_lock);
   return (0);
 } /* int notify_email_shutdown */
 
@@ -250,7 +272,16 @@ static int notify_email_notification (const notification_t *n,
       n->host,
       n->message);
 
+  pthread_mutex_lock (&session_lock);
+
+  if (session == NULL) {
+    /* Initialization failed or we're in the process of shutting down. */
+    pthread_mutex_unlock (&session_lock);
+    return (-1);
+  }
+
   if (!(message = smtp_add_message (session))) {
+    pthread_mutex_unlock (&session_lock);
     ERROR ("notify_email plugin: cannot set SMTP message");
     return (-1);   
   }
@@ -266,6 +297,7 @@ static int notify_email_notification (const notification_t *n,
     char buf[MAXSTRING];
     ERROR ("notify_email plugin: SMTP server problem: %s",
         smtp_strerror (smtp_errno (), buf, sizeof buf));
+    pthread_mutex_unlock (&session_lock);
     return (-1);
   } else {
     const smtp_status_t *status;
@@ -276,6 +308,7 @@ static int notify_email_notification (const notification_t *n,
     smtp_enumerate_recipients (message, print_recipient_status, NULL);
   }
 
+  pthread_mutex_unlock (&session_lock);
   return (0);
 } /* int notify_email_notification */