X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fnotify_email.c;h=08f865fc2c57805866ce3475a3ec9b3a77ed0e9a;hb=61a1fa91ba73e4fe3a34949f77c5f017056f2b7a;hp=3d35f870f7c9d724b36e16f38855fe8578b2c45a;hpb=1266e5222769187a1dfddd323b690e1b2b2d131d;p=collectd.git diff --git a/src/notify_email.c b/src/notify_email.c index 3d35f870..08f865fc 100644 --- a/src/notify_email.c +++ b/src/notify_email.c @@ -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 + * Florian Forster **/ #include "collectd.h" @@ -26,25 +28,27 @@ #include #include +#include #define MAXSTRING 256 static const char *config_keys[] = { - "SMTPHost", + "SMTPServer", "SMTPPort", "SMTPUser", "SMTPPassword", - "SMTPFrom", - "SMTPSubject", - "EmailTo" + "From", + "Recipient", + "Subject" }; static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); -static char **emails; -static int emails_len = 0; +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; @@ -52,16 +56,16 @@ static int smtp_port = 25; static char *smtp_host = NULL; static char *smtp_user = NULL; static char *smtp_password = NULL; -static char *smtp_from = NULL; -static char *smtp_subject = NULL; +static char *email_from = NULL; +static char *email_subject = NULL; #define DEFAULT_SMTP_HOST "localhost" #define DEFAULT_SMTP_FROM "root@localhost" #define DEFAULT_SMTP_SUBJECT "Collectd notify: %s@%s" - /* Callback to get username and password */ -static int authinteract (auth_client_request_t request, char **result, int fields, void *arg) +static int authinteract (auth_client_request_t request, char **result, + int fields, void __attribute__((unused)) *arg) { int i; for (i = 0; i < fields; i++) @@ -74,21 +78,24 @@ static int authinteract (auth_client_request_t request, char **result, int field return 0; } return 1; -} +} /* int authinteract */ /* Callback to print the recipient status */ -static void print_recipient_status (smtp_recipient_t recipient, const char *mailbox, void *arg) +static void print_recipient_status (smtp_recipient_t recipient, + const char *mailbox, void __attribute__((unused)) *arg) { const smtp_status_t *status; status = smtp_recipient_status (recipient); if (status->text[strlen(status->text) - 2] == '\r') status->text[strlen(status->text) - 2] = 0; - INFO ("notify_email: notify sent to %s: %d %s", mailbox, status->code, status->text); -} + INFO ("notify_email: notify sent to %s: %d %s", mailbox, status->code, + status->text); +} /* void print_recipient_status */ /* Callback to monitor SMTP activity */ -static void monitor_cb (const char *buf, int buflen, int writing, void *arg) +static void monitor_cb (const char *buf, int buflen, int writing, + void __attribute__((unused)) *arg) { char log_str[MAXSTRING]; @@ -97,27 +104,36 @@ static void monitor_cb (const char *buf, int buflen, int writing, void *arg) log_str[buflen - 2] = 0; /* replace \n with \0 */ if (writing == SMTP_CB_HEADERS) { - DEBUG ("SMTP --- H: %s", log_str); + DEBUG ("notify_email plugin: SMTP --- H: %s", log_str); return; } - DEBUG (writing ? "SMTP >>> C: %s" : "SMTP <<< S: %s", log_str); -} + DEBUG (writing + ? "notify_email plugin: SMTP >>> C: %s" + : "notify_email plugin: SMTP <<< S: %s", + log_str); +} /* void monitor_cb */ -static int notify_email_init() +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) { @@ -127,44 +143,54 @@ static int notify_email_init() } 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() +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(); - return (0); -} + pthread_mutex_unlock (&session_lock); + return (0); +} /* int notify_email_shutdown */ static int notify_email_config (const char *key, const char *value) { - if (strcasecmp (key, "EmailTo") == 0) + if (strcasecmp (key, "Recipient") == 0) { char **tmp; - tmp = (char **) realloc ((void *) emails, (emails_len + 1) * sizeof (char *)); + tmp = (char **) realloc ((void *) recipients, (recipients_len + 1) * sizeof (char *)); if (tmp == NULL) { ERROR ("notify_email: realloc failed."); return (-1); } - emails = tmp; - emails[emails_len] = strdup (value); - if (emails[emails_len] == NULL) { + recipients = tmp; + recipients[recipients_len] = strdup (value); + if (recipients[recipients_len] == NULL) { ERROR ("notify_email: strdup failed."); return (-1); } - emails_len++; + recipients_len++; } - else if (0 == strcasecmp (key, "SMTPHost")) { + else if (0 == strcasecmp (key, "SMTPServer")) { sfree (smtp_host); smtp_host = strdup (value); } @@ -185,13 +211,13 @@ static int notify_email_config (const char *key, const char *value) sfree (smtp_password); smtp_password = strdup (value); } - else if (0 == strcasecmp (key, "SMTPFrom")) { - sfree (smtp_from); - smtp_from = strdup (value); + else if (0 == strcasecmp (key, "From")) { + sfree (email_from); + email_from = strdup (value); } - else if (0 == strcasecmp (key, "SMTPSubject")) { - sfree (smtp_subject); - smtp_subject = strdup (value); + else if (0 == strcasecmp (key, "Subject")) { + sfree (email_subject); + email_subject = strdup (value); } else { return -1; @@ -199,10 +225,9 @@ static int notify_email_config (const char *key, const char *value) return 0; } /* int notify_email_config (const char *, const char *) */ - -static int notify_email_notification (const notification_t *n) +static int notify_email_notification (const notification_t *n, + user_data_t __attribute__((unused)) *user_data) { - smtp_recipient_t recipient; struct tm timestamp_tm; char timestamp_str[64]; @@ -220,11 +245,12 @@ static int notify_email_notification (const notification_t *n) : ((n->severity == NOTIF_OKAY) ? "OKAY" : "UNKNOWN"))); ssnprintf (subject, sizeof (subject), - (smtp_subject == NULL) ? DEFAULT_SMTP_SUBJECT : smtp_subject, + (email_subject == NULL) ? DEFAULT_SMTP_SUBJECT : email_subject, severity, n->host); localtime_r (&n->time, ×tamp_tm); - strftime (timestamp_str, sizeof (timestamp_str), "%Y-%m-%d %H:%M:%S", ×tamp_tm); + strftime (timestamp_str, sizeof (timestamp_str), "%Y-%m-%d %H:%M:%S", + ×tamp_tm); timestamp_str[sizeof (timestamp_str) - 1] = '\0'; /* Let's make RFC822 message text with \r\n EOLs */ @@ -243,30 +269,48 @@ static int notify_email_notification (const notification_t *n) n->host, n->message); - if ( !(message = smtp_add_message (session))) { + 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); } - smtp_set_reverse_path (message, smtp_from); + smtp_set_reverse_path (message, email_from); smtp_set_header (message, "To", NULL, NULL); smtp_set_message_str (message, buf); - for (i = 0; i < emails_len; i++) - recipient = smtp_add_recipient (message, emails[i]); + for (i = 0; i < recipients_len; i++) + smtp_add_recipient (message, recipients[i]); /* Initiate a connection to the SMTP server and transfer the message. */ if (!smtp_start_session (session)) { char buf[MAXSTRING]; - ERROR ("SMTP server problem: %s", smtp_strerror (smtp_errno (), buf, sizeof buf)); + 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; - /* Report on the success or otherwise of the mail transfer. */ - status = smtp_message_transfer_status (message); - DEBUG ("SMTP server report: %d %s", status->code, (status->text != NULL) ? status->text : "\n"); + #if COLLECT_DEBUG + const smtp_status_t *status; + /* Report on the success or otherwise of the mail transfer. */ + status = smtp_message_transfer_status (message); + DEBUG ("notify_email plugin: SMTP server report: %d %s", + status->code, (status->text != NULL) ? status->text : "\n"); + #else + //I don't know if the function below has side affects so i'm calling it to be on the safe side. + smtp_message_transfer_status (message); + #endif smtp_enumerate_recipients (message, print_recipient_status, NULL); } + pthread_mutex_unlock (&session_lock); return (0); } /* int notify_email_notification */ @@ -276,5 +320,8 @@ void module_register (void) plugin_register_shutdown ("notify_email", notify_email_shutdown); plugin_register_config ("notify_email", notify_email_config, config_keys, config_keys_num); - plugin_register_notification ("notify_email", notify_email_notification); + plugin_register_notification ("notify_email", notify_email_notification, + /* user_data = */ NULL); } /* void module_register (void) */ + +/* vim: set sw=2 sts=2 ts=8 et : */