From: Colin Patrick McCabe Date: Fri, 13 May 2011 19:04:23 +0000 (-0700) Subject: Implement send_mail X-Git-Url: http://club.cc.cmu.edu/~cmccabe/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=686b7cb4e5894d56f6e23b8aeab9af610c90eeed;p=handle_core Implement send_mail Signed-off-by: Colin McCabe --- diff --git a/handle_core.c b/handle_core.c index 93d03cc..ce81772 100644 --- a/handle_core.c +++ b/handle_core.c @@ -1,10 +1,11 @@ #include -#include #include +#include #include #include #include #include +#include #include #include #include @@ -21,8 +22,9 @@ * Core file handler * * Example usage: - * echo "|/usr/bin/handle_core -e %e -d /home/core -m 10" > \ - * /proc/sys/kernel/core_pattern + * echo "|/sbin/handle_core -e %e -d /var/core -m 10 \ + * -s '/usr/sbin/sendmail -t sysadmin@example.com'" > \ + * /proc/sys/kernel/core_pattern */ /* Count the number of core files we have. */ @@ -92,17 +94,20 @@ static void usage(void) -h This help message\n\ -m This maximum number of core files to allow\n\ before deleting older core files.\n\ +-s Send email using email_command.\n\ + Example: -s '/usr/sbin/sendmail -t sysadmin@example.com'\n\ "); } static int parse_options(int argc, char **argv, int *max_cores, - char **exe_name, char **core_dir) + char **exe_name, char **core_dir, char **email) { int c; *max_cores = 10; *exe_name = NULL; *core_dir = "/var/core"; - while ((c = getopt(argc, argv, "d:e:hm:")) != -1) { + *email = NULL; + while ((c = getopt(argc, argv, "d:e:hm:s:")) != -1) { switch (c) { case 'd': *core_dir = optarg; @@ -123,6 +128,9 @@ static int parse_options(int argc, char **argv, int *max_cores, return 1; } break; + case 's': + *email = optarg; + break; default: fprintf(stderr, "handle_core: invalid usage\n\n"); return 1; @@ -137,17 +145,61 @@ static int parse_options(int argc, char **argv, int *max_cores, return 0; } +int send_mail(const char *exe_name, const char *core_dir, + const char *core_name, const char *email) +{ + char hostname[255]; + struct hostent *fqdn; + const char *fqdn_name; + FILE *fp; + + if (!email) + return 0; + fp = popen(email, "w"); + if (!fp) { + int err = errno; + syslog(LOG_USER | LOG_ERR, "popen(%s) error: %d (%s)", + email, err, strerror(err)); + return err; + } + if (gethostname(hostname, sizeof(hostname))) { + int err = errno; + syslog(LOG_USER | LOG_ERR, "gethostname error: %d (%s)", + err, strerror(err)); + snprintf(hostname, sizeof(hostname), "(unknown-host)"); + } + fqdn = gethostbyname(hostname); + if (!fqdn) { + int err = h_errno; + syslog(LOG_USER | LOG_ERR, "gethostbyname(%s) error: %d", + hostname, err); + fqdn_name = hostname; + } + else { + fqdn_name = fqdn->h_name; + } + fprintf(fp, "\ +Subject: [core_dump] %s crashed on %s\r\n\r\n\ +!!!!! Crash encountered on %s !!!!!!!!!\r\n\ +executable name: %s\r\n\ +core file name: %s/%s\r\n\ +", exe_name, hostname, fqdn_name, exe_name, core_dir, core_name); + fclose(fp); + return 0; +} + int main(int argc, char **argv) { int ret, done = 0; - char *exe_name, *core_dir; + char *exe_name, *core_dir, *email; char core_name[PATH_MAX]; FILE *fp; int num_coref, num_deleted; int max_cores; /* Write the core to a file */ - ret = parse_options(argc, argv, &max_cores, &exe_name, &core_dir); + ret = parse_options(argc, argv, &max_cores, &exe_name, &core_dir, + &email); if (ret) { syslog(LOG_USER | LOG_ERR, "parse_options error\n"); return 1; @@ -205,6 +257,12 @@ int main(int argc, char **argv) num_deleted++; } + ret = send_mail(exe_name, core_dir, core_name, email); + if (ret) { + syslog(LOG_USER | LOG_ERR, "send_mail failed with error " + "code %d\n", ret); + } + syslog(LOG_USER | LOG_ERR, "wrote core %s. Deleted %d extra core%s\n", core_name, num_deleted, ((num_deleted == 1) ? "" : "s")); return 0;