From 2373bc36e2c23e5ccc2b40d75e7bb32b7c85802e Mon Sep 17 00:00:00 2001 From: Jeff Squyres Date: Fri, 6 Mar 2009 21:59:19 +0000 Subject: [PATCH] Add the "smtp" notifier component. It uses libesmtp (http://www.stafford.uklinux.net/libesmtp/) via the --with-esmtp(=DIR) configure option. Several MCA parameters must be set in order to use this component: * notifier_smtp_server: SMTP server IP address or name; must be supplied * notifier_smtp_port: port to talk to on the server; defaults to 25 * notifier_smtp_to: comma-delimited list of email addresses to send the mail to; must be supplied * notifier_smtp_from_name: free-form "name" who the mail is from; defaults to "Open MPI Notifier" * notifier_smtp_from_addr: email address from the mail is from; must be supplied * notifier_smtp_subject: subject of the mail; defaults to "Open MPI notifier" * notifier_smtp_body_prefix: prefix of the body of the mail; defaults to a sensible value * notifier_smtp_body_suffix: suffix of the body of the mail; defaults to a sensible value Also libesmtp supports SMTP AUTH protocols, this component does not. If people want/need those kinds of features, they're relatively easy to add -- I just didn't bother [yet] before I knew if anyone cared. This commit was SVN r20749. --- NEWS | 8 + orte/mca/notifier/smtp/Makefile.am | 51 +++ orte/mca/notifier/smtp/configure.m4 | 35 ++ orte/mca/notifier/smtp/configure.params | 13 + .../notifier/smtp/help-orte-notifier-smtp.txt | 33 ++ orte/mca/notifier/smtp/notifier_smtp.h | 65 +++ .../notifier/smtp/notifier_smtp_component.c | 236 +++++++++++ orte/mca/notifier/smtp/notifier_smtp_module.c | 389 ++++++++++++++++++ 8 files changed, 830 insertions(+) create mode 100644 orte/mca/notifier/smtp/Makefile.am create mode 100644 orte/mca/notifier/smtp/configure.m4 create mode 100644 orte/mca/notifier/smtp/configure.params create mode 100644 orte/mca/notifier/smtp/help-orte-notifier-smtp.txt create mode 100644 orte/mca/notifier/smtp/notifier_smtp.h create mode 100644 orte/mca/notifier/smtp/notifier_smtp_component.c create mode 100644 orte/mca/notifier/smtp/notifier_smtp_module.c diff --git a/NEWS b/NEWS index acff979b6d..d6c573aab1 100644 --- a/NEWS +++ b/NEWS @@ -35,6 +35,14 @@ Trunk (not on release branches yet) details. --> Expected: ??? +1.4 +--- + +- Added smtp notifier component (requires libesmtp). See "ompi_info + --param notifier smtp" for a list of the relevant MCA parameters that + are necessary. + + 1.3.1 ----- diff --git a/orte/mca/notifier/smtp/Makefile.am b/orte/mca/notifier/smtp/Makefile.am new file mode 100644 index 0000000000..d5b9328b2e --- /dev/null +++ b/orte/mca/notifier/smtp/Makefile.am @@ -0,0 +1,51 @@ +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +AM_CPPFLAGS = $(notifier_smtp_CPPFLAGS) + +dist_pkgdata_DATA = \ + help-orte-notifier-smtp.txt + +sources = \ + notifier_smtp.h \ + notifier_smtp_module.c \ + notifier_smtp_component.c + +# Make the output library in this directory, and name it either +# mca__.la (for DSO builds) or libmca__.la +# (for static builds). + +if OMPI_BUILD_notifier_smtp_DSO +component_noinst = +component_install = mca_notifier_smtp.la +else +component_noinst = libmca_notifier_smtp.la +component_install = +endif + +mcacomponentdir = $(pkglibdir) +mcacomponent_LTLIBRARIES = $(component_install) +mca_notifier_smtp_la_SOURCES = $(sources) +mca_notifier_smtp_la_LDFLAGS = -module -avoid-version $(notifier_smtp_LDFLAGS) +mca_notifier_smtp_la_LIBADD = $(notifier_smtp_LIBS) + +noinst_LTLIBRARIES = $(component_noinst) +libmca_notifier_smtp_la_SOURCES =$(sources) +libmca_notifier_smtp_la_LDFLAGS = -module -avoid-version $(notifier_smtp_LDFLAGS) +libmca_notifier_smtp_la_LIBADD = $(notifier_smtp_LIBS) diff --git a/orte/mca/notifier/smtp/configure.m4 b/orte/mca/notifier/smtp/configure.m4 new file mode 100644 index 0000000000..d73f7b22fe --- /dev/null +++ b/orte/mca/notifier/smtp/configure.m4 @@ -0,0 +1,35 @@ +# -*- shell-script -*- +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# MCA_notifier_smtp_CONFIG([action-if-found], [action-if-not-found]) +# ----------------------------------------------------------- +AC_DEFUN([MCA_notifier_smtp_CONFIG], [ + OPAL_SETUP_COMPONENT_PACKAGE([notifier], + [smtp], + [esmtp], + [include/libesmtp.h], + [libesmtp*], + [libesmtp.h], + [esmtp], + [smtp_create_session], + [], + [$1], + [$2]) +])dnl diff --git a/orte/mca/notifier/smtp/configure.params b/orte/mca/notifier/smtp/configure.params new file mode 100644 index 0000000000..a58b171f7b --- /dev/null +++ b/orte/mca/notifier/smtp/configure.params @@ -0,0 +1,13 @@ +# -*- shell-script -*- +# +# Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# Specific to this module + +PARAM_CONFIG_FILES="Makefile" diff --git a/orte/mca/notifier/smtp/help-orte-notifier-smtp.txt b/orte/mca/notifier/smtp/help-orte-notifier-smtp.txt new file mode 100644 index 0000000000..b03438387c --- /dev/null +++ b/orte/mca/notifier/smtp/help-orte-notifier-smtp.txt @@ -0,0 +1,33 @@ +# -*- text -*- +# +# Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# +# This is the US/English help file for Open MPI's SMTP notifier support +# +[to/from not specified] +Error: the Open MPI SMTP notifier component had no "to" and/or "from" +email addresses specified. +# +[server not specified] +Error: the Open MPI SMTP notifier component had no SMTP server name or +IP address specified. +# +[unable to resolve server] +Sorry, Open MPI's SMTP notifier component was unable to resolve the IP +address of the server provided. + + Server: %s +# +[send_email failed] +Oops! Open MPI's SMTP notifier failed to send an email. + + Reason: %s + libESMTP function: %s + libESMTP message: %s + Message: %s +# diff --git a/orte/mca/notifier/smtp/notifier_smtp.h b/orte/mca/notifier/smtp/notifier_smtp.h new file mode 100644 index 0000000000..7cfd9acc2d --- /dev/null +++ b/orte/mca/notifier/smtp/notifier_smtp.h @@ -0,0 +1,65 @@ +/* -*- C -*- + * + * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2006 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + * + */ +#ifndef NOTIFIER_SMTP_H +#define NOTIFIER_SMTP_H + +#include "orte_config.h" + +#include + +#include "libesmtp.h" + +#include "orte/types.h" +#include "orte/mca/notifier/notifier.h" + +BEGIN_C_DECLS + +typedef struct { + orte_notifier_base_component_t super; + + /* SMTP server name and port */ + char *server; + int port; + + /* To, From, Subject */ + char *to, **to_argv, *from_name, *from_addr, *subject; + + /* Mail body prefix and suffix */ + char *body_prefix, *body_suffix; + + /* struct hostent from resolved SMTP server name */ + struct hostent *server_hostent; + + /* Priority of this component */ + int priority; +} orte_notifier_smtp_component_t; + + +/* + * Notifier interfaces + */ +ORTE_MODULE_DECLSPEC extern orte_notifier_smtp_component_t + mca_notifier_smtp_component; +extern orte_notifier_base_module_t orte_notifier_smtp_module; + +END_C_DECLS + +#endif diff --git a/orte/mca/notifier/smtp/notifier_smtp_component.c b/orte/mca/notifier/smtp/notifier_smtp_component.c new file mode 100644 index 0000000000..1992920acd --- /dev/null +++ b/orte/mca/notifier/smtp/notifier_smtp_component.c @@ -0,0 +1,236 @@ +/* -*- C -*- +* +* Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana +* University Research and Technology +* Corporation. All rights reserved. +* Copyright (c) 2004-2005 The University of Tennessee and The University +* of Tennessee Research Foundation. All rights +* reserved. +* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +* University of Stuttgart. All rights reserved. +* Copyright (c) 2004-2005 The Regents of the University of California. +* All rights reserved. + * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. +* $COPYRIGHT$ +* +* Additional copyrights may follow +* +* $HEADER$ +*/ + +/* + * Because we can. :-) + */ + +#include "orte_config.h" + +#include "opal/mca/base/mca_base_param.h" + +#include "orte/constants.h" +#include "orte/util/show_help.h" + +#include "notifier_smtp.h" + +static int smtp_open(void); +static int smtp_component_query(mca_base_module_t **module, int *priority); +static int smtp_close(void); +static int smtp_register(void); + +/* + * Struct of function pointers that need to be initialized + */ +orte_notifier_smtp_component_t mca_notifier_smtp_component = { + { + { + ORTE_NOTIFIER_BASE_VERSION_1_0_0, + + "smtp", + + ORTE_MAJOR_VERSION, + ORTE_MINOR_VERSION, + ORTE_RELEASE_VERSION, + + smtp_open, + smtp_close, + smtp_component_query, + smtp_register, + }, + { + /* The component is checkpoint ready */ + MCA_BASE_METADATA_PARAM_CHECKPOINT + } + }, + + /* SMTP server and port */ + "localhost", + 25, + + /* To, from, subject */ + NULL, + NULL, + "Open MPI Notifier", + NULL, + "Open MPI notifier", + + /* Mail body prefix, suffix */ + "The Open MPI SMTP notifier wishes to inform you of the following message:\n\n", + "\n\nSincerely,\nOscar the Open MPI Owl", + + /* Struct hostent */ + NULL, + + /* Priority */ + 10, +}; + +static int smtp_register(void) +{ + char version[256]; + + /* Server stuff */ + mca_base_param_reg_string(&mca_notifier_smtp_component.super.base_version, + "server", + "SMTP server name or IP address", + false, false, + mca_notifier_smtp_component.server, + &mca_notifier_smtp_component.server); + mca_base_param_reg_int(&mca_notifier_smtp_component.super.base_version, + "port", + "SMTP server port", + false, false, + mca_notifier_smtp_component.port, + &mca_notifier_smtp_component.port); + + /* Email stuff */ + mca_base_param_reg_string(&mca_notifier_smtp_component.super.base_version, + "to", + "Comma-delimited list of email addresses to send to", + false, false, + mca_notifier_smtp_component.to, + &mca_notifier_smtp_component.to); + mca_base_param_reg_string(&mca_notifier_smtp_component.super.base_version, + "from_addr", + "Email address that messages will be from", + false, false, + mca_notifier_smtp_component.from_addr, + &mca_notifier_smtp_component.from_addr); + mca_base_param_reg_string(&mca_notifier_smtp_component.super.base_version, + "from_name", + "Email name that messages will be from", + false, false, + mca_notifier_smtp_component.from_name, + &mca_notifier_smtp_component.from_name); + mca_base_param_reg_string(&mca_notifier_smtp_component.super.base_version, + "subject", + "Email subject", + false, false, + mca_notifier_smtp_component.subject, + &mca_notifier_smtp_component.subject); + + /* Mail body prefix and suffix */ + mca_base_param_reg_string(&mca_notifier_smtp_component.super.base_version, + "body_prefix", + "Text to put at the beginning of the mail message", + false, false, + mca_notifier_smtp_component.body_prefix, + &mca_notifier_smtp_component.body_prefix); + mca_base_param_reg_string(&mca_notifier_smtp_component.super.base_version, + "body_suffix", + "Text to put at the beginning of the mail message", + false, false, + mca_notifier_smtp_component.body_suffix, + &mca_notifier_smtp_component.body_suffix); + + /* Priority */ + mca_base_param_reg_int(&mca_notifier_smtp_component.super.base_version, + "priority", + "Priority of this component", + false, false, + mca_notifier_smtp_component.priority, + &mca_notifier_smtp_component.priority); + + /* Libesmtp version */ + smtp_version(version, sizeof(version), 0); + version[sizeof(version) - 1] = '\0'; + mca_base_param_reg_string(&mca_notifier_smtp_component.super.base_version, + "libesmtp_version", + "Version of libesmtp that this component is linked against", + false, true, version, NULL); + + return ORTE_SUCCESS; +} + +static int smtp_open(void) +{ + /* Nothing to do */ + return ORTE_SUCCESS; +} + +static int smtp_close(void) +{ + if (NULL != mca_notifier_smtp_component.server) { + free(mca_notifier_smtp_component.server); + } + + if (NULL != mca_notifier_smtp_component.to) { + free(mca_notifier_smtp_component.to); + } + if (NULL != mca_notifier_smtp_component.from_name) { + free(mca_notifier_smtp_component.from_name); + } + if (NULL != mca_notifier_smtp_component.from_addr) { + free(mca_notifier_smtp_component.from_addr); + } + if (NULL != mca_notifier_smtp_component.subject) { + free(mca_notifier_smtp_component.subject); + } + if (NULL != mca_notifier_smtp_component.body_prefix) { + free(mca_notifier_smtp_component.body_prefix); + } + if (NULL != mca_notifier_smtp_component.body_suffix) { + free(mca_notifier_smtp_component.body_suffix); + } + + return ORTE_SUCCESS; +} + +static int smtp_component_query(mca_base_module_t **module, + int *priority) +{ + *priority = 0; + *module = NULL; + + /* If there's no to or from, there's no love */ + if (NULL == mca_notifier_smtp_component.to || + '\0' == mca_notifier_smtp_component.to[0] || + NULL == mca_notifier_smtp_component.from_addr || + '\0' == mca_notifier_smtp_component.from_addr[0]) { + orte_show_help("help-orte-notifier-smtp.txt", + "to/from not specified", true); + return ORTE_ERR_NOT_FOUND; + } + + /* Sanity checks */ + if (NULL == mca_notifier_smtp_component.server || + '\0' == mca_notifier_smtp_component.server[0]) { + orte_show_help("help-orte-notifier-smtp.txt", + "server not specified", true); + return ORTE_ERR_NOT_FOUND; + } + + /* Since we have to open a socket later, try to resolve the IP + address of the server now. Save the result, or abort if we + can't resolve it. */ + mca_notifier_smtp_component.server_hostent = + gethostbyname(mca_notifier_smtp_component.server); + if (NULL == mca_notifier_smtp_component.server_hostent) { + orte_show_help("help-orte-notifier-smtp.txt", + "unable to resolve server", + true, mca_notifier_smtp_component.server); + return ORTE_ERR_NOT_FOUND; + } + + *priority = 10; + *module = (mca_base_module_t *)&orte_notifier_smtp_module; + return ORTE_SUCCESS; +} diff --git a/orte/mca/notifier/smtp/notifier_smtp_module.c b/orte/mca/notifier/smtp/notifier_smtp_module.c new file mode 100644 index 0000000000..39ae4b587c --- /dev/null +++ b/orte/mca/notifier/smtp/notifier_smtp_module.c @@ -0,0 +1,389 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +/* + * Send an email upon notifier events. + */ + +#include "orte_config.h" + +#include +#include +#ifdef HAVE_STDARG_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_SIGNAL_H +#include +#endif + +#include "opal/util/show_help.h" +#include "opal/util/output.h" +#include "opal/util/argv.h" + +#include "orte/constants.h" +#include "orte/mca/ess/ess.h" +#include "orte/util/name_fns.h" +#include "orte/util/show_help.h" +#include "orte/runtime/orte_globals.h" +#include "orte/mca/notifier/base/base.h" + +#include "notifier_smtp.h" + + +/* Static API's */ +static void mylog(int severity, int errcode, const char *msg, ...); +static void myhelplog(int severity, int errcode, const char *filename, + const char *topic, ...); +static void mypeerlog(int severity, int errcode, orte_process_name_t *peer_proc, + const char *msg, ...); + +/* Module */ +orte_notifier_base_module_t orte_notifier_smtp_module = { + NULL, + NULL, + mylog, + myhelplog, + mypeerlog +}; + +typedef enum { + SENT_NONE, + SENT_HEADER, + SENT_BODY_PREFIX, + SENT_BODY, + SENT_BODY_SUFFIX, + SENT_ALL +} sent_flag_t; + +typedef struct { + sent_flag_t sent_flag; + char *msg; + char *prev_string; +} message_status_t; + +/* + * Convert lone \n's to \r\n + */ +static char *crnl(char *orig) +{ + int i, j, max, count; + char *str; + return strdup(orig); + + /* Count how much space we need */ + count = max = strlen(orig); + for (i = 0; i < max; ++i) { + if (orig[i] == '\n' && i > 0 && orig[i - 1] != '\r') { + ++count; + } + } + + /* Copy, changing \n to \r\n */ + str = malloc(count + 1); + for (j = i = 0; i < max; ++i) { + if (orig[i] == '\n' && i > 0 && orig[i - 1] != '\r') { + str[j++] = '\n'; + } + str[j++] = orig[i]; + } + str[j] = '\0'; + return str; +} + +/* + * Callback function invoked via smtp_start_session() + */ +static const char *message_cb(void **buf, int *len, void *arg) +{ + message_status_t *ms = (message_status_t*) arg; + + if (NULL == *buf) { + *buf = malloc(8192); + } + if (NULL == len) { + ms->sent_flag = SENT_NONE; + return NULL; + } + + /* Free the previous string */ + if (NULL != ms->prev_string) { + free(ms->prev_string); + ms->prev_string = NULL; + } + + switch (ms->sent_flag) { + case SENT_NONE: + /* Send a blank line to signify the end of the header */ + ms->sent_flag = SENT_HEADER; + ms->prev_string = NULL; + *len = 2; + return "\r\n"; + + case SENT_HEADER: + if (NULL != mca_notifier_smtp_component.body_prefix) { + ms->sent_flag = SENT_BODY_PREFIX; + ms->prev_string = crnl(mca_notifier_smtp_component.body_prefix); + *len = strlen(ms->prev_string); + return ms->prev_string; + } + + case SENT_BODY_PREFIX: + ms->sent_flag = SENT_BODY; + ms->prev_string = crnl(ms->msg); + *len = strlen(ms->prev_string); + return ms->prev_string; + + case SENT_BODY: + if (NULL != mca_notifier_smtp_component.body_suffix) { + ms->sent_flag = SENT_BODY_SUFFIX; + ms->prev_string = crnl(mca_notifier_smtp_component.body_suffix); + *len = strlen(ms->prev_string); + return ms->prev_string; + } + + case SENT_BODY_SUFFIX: + case SENT_ALL: + default: + ms->sent_flag = SENT_ALL; + *len = 0; + return NULL; + } +} + +/* + * Back-end function to actually send the email + */ +static int send_email(char *msg) +{ + int i, err = ORTE_SUCCESS; + char *str = NULL; + char *errmsg = NULL; + struct sigaction sig, oldsig; + bool set_oldsig = false; + smtp_session_t session = NULL; + smtp_message_t message = NULL; + message_status_t ms; + orte_notifier_smtp_component_t *c = &mca_notifier_smtp_component; + + if (NULL == c->to_argv) { + c->to_argv = opal_argv_split(c->to, ','); + if (NULL == c->to_argv || + NULL == c->to_argv[0]) { + return ORTE_ERR_OUT_OF_RESOURCE; + } + } + + ms.sent_flag = SENT_NONE; + ms.prev_string = NULL; + ms.msg = msg; + + /* Temporarily disable SIGPIPE so that if remote servers timeout + or hang up on us, it doesn't kill this application. We'll + restore the original SIGPIPE handler when we're done. */ + sig.sa_handler = SIG_IGN; + sigemptyset(&sig.sa_mask); + sig.sa_flags = 0; + sigaction(SIGPIPE, &sig, &oldsig); + set_oldsig = true; + + /* Try to get a libesmtp session. If so, assume that libesmtp is + happy and proceeed */ + session = smtp_create_session(); + if (NULL == session) { + err = ORTE_ERR_NOT_SUPPORTED; + errmsg = "stmp_create_session"; + goto error; + } + + /* Create the message */ + message = smtp_add_message(session); + if (NULL == message) { + err = ORTE_ERROR; + errmsg = "stmp_add_message"; + goto error; + } + + /* Set the SMTP server (yes, it's a weird return status!) */ + asprintf(&str, "%s:%d", c->server, c->port); + if (0 == smtp_set_server(session, str)) { + err = ORTE_ERROR; + errmsg = "stmp_set_server"; + goto error; + } + free(str); + str = NULL; + + /* Add the sender */ + if (0 == smtp_set_reverse_path(message, c->from_addr)) { + err = ORTE_ERROR; + errmsg = "stmp_set_reverse_path"; + goto error; + } + + /* Set the subject and some headers */ + asprintf(&str, "Open MPI SMTP Notifier v%d.%d.%d", + c->super.base_version.mca_component_major_version, + c->super.base_version.mca_component_minor_version, + c->super.base_version.mca_component_release_version); + if (0 == smtp_set_header(message, "Subject", c->subject) || + 0 == smtp_set_header_option(message, "Subject", Hdr_OVERRIDE, 1) || + 0 == smtp_set_header(message, "To", NULL, NULL) || + 0 == smtp_set_header(message, "From", + (NULL != c->from_name ? + c->from_name : c->from_addr), + c->from_addr) || + 0 == smtp_set_header(message, "X-Mailer", str) || + 0 == smtp_set_header_option(message, "Subject", Hdr_OVERRIDE, 1)) { + err = ORTE_ERROR; + errmsg = "smtp_set_header"; + goto error; + } + free(str); + str = NULL; + + /* Add the recipients */ + for (i = 0; NULL != c->to_argv[i]; ++i) { + if (NULL == smtp_add_recipient(message, c->to_argv[i])) { + err = ORTE_ERR_OUT_OF_RESOURCE; + errmsg = "stmp_add_recipient"; + goto error; + } + } + + /* Set the callback to get the message */ + if (0 == smtp_set_messagecb(message, message_cb, &ms)) { + err = ORTE_ERROR; + errmsg = "smtp_set_messagecb"; + goto error; + } + + /* Send it! */ + if (0 == smtp_start_session(session)) { + err = ORTE_ERROR; + errmsg = "smtp_start_session"; + goto error; + } + + /* Fall through */ + + error: + if (NULL != str) { + free(str); + } + if (NULL != session) { + smtp_destroy_session(session); + } + /* Restore the SIGPIPE handler */ + if (set_oldsig) { + sigaction(SIGPIPE, &oldsig, NULL); + } + if (ORTE_SUCCESS != err) { + int e; + char em[256]; + + e = smtp_errno(); + smtp_strerror(e, em, sizeof(em)); + orte_show_help("help-orte-notifier-smtp.txt", + "send_email failed", + true, "libesmtp library call failed", + errmsg, em, e, msg); + } + return err; +} + +static void mylog(int severity, int errcode, const char *msg, ...) +{ + char *output; + va_list arglist; + + /* If there was a message, output it */ + va_start(arglist, msg); + vasprintf(&output, msg, arglist); + va_end(arglist); + + if (NULL != output) { + send_email(output); + free(output); + } +} + +static void myhelplog(int severity, int errcode, const char *filename, + const char *topic, ...) +{ + va_list arglist; + char *output; + + va_start(arglist, topic); + output = opal_show_help_vstring(filename, topic, false, arglist); + va_end(arglist); + + if (NULL != output) { + send_email(output); + free(output); + } +} + +static void mypeerlog(int severity, int errcode, + orte_process_name_t *peer_proc, const char *msg, ...) +{ + va_list arglist; + char buf[ORTE_NOTIFIER_MAX_BUF + 1]; + char *peer_host = NULL, *peer_name = NULL; + char *pos = buf; + char *errstr = (char*)orte_err2str(errcode); + int len, space = ORTE_NOTIFIER_MAX_BUF; + + if (peer_proc) { + peer_host = orte_ess.proc_get_hostname(peer_proc); + peer_name = ORTE_NAME_PRINT(peer_proc); + } + + len = snprintf(pos, space, + "While communicating to proc %s on node %s," + " proc %s on node %s encountered an error ", + peer_name ? peer_name : "UNKNOWN", + peer_host ? peer_host : "UNKNOWN", + ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), + orte_process_info.nodename); + space -= len; + pos += len; + + if (0 < space) { + if (errstr) { + len = snprintf(pos, space, "'%s':", errstr); + } else { + len = snprintf(pos, space, "(%d):", errcode); + } + space -= len; + pos += len; + } + + if (0 < space) { + va_start(arglist, msg); + vsnprintf(pos, space, msg, arglist); + va_end(arglist); + } + + buf[ORTE_NOTIFIER_MAX_BUF] = '\0'; + send_email(buf); +}