diff --git a/sm5/VERSION b/sm5/VERSION index f5c89552bd3e62bfce023a230e90d141f7a46b2f..bb95160cb6e07358f54a28a208ae41e69889c97b 100644 --- a/sm5/VERSION +++ b/sm5/VERSION @@ -1 +1 @@ -32 +33 diff --git a/sm5/smartd.c b/sm5/smartd.c index f2f51191023152c1448660fdc99bd55f7ec101f2..cc0cadbb8e5f71a88cd5b06deae8c4fd1863d0ef 100644 --- a/sm5/smartd.c +++ b/sm5/smartd.c @@ -35,6 +35,7 @@ #include <stdlib.h> #include <errno.h> #include <string.h> +#include <time.h> #include "atacmds.h" #include "scsicmds.h" #include "smartd.h" @@ -44,7 +45,7 @@ // CVS ID strings extern const char *CVSid1, *CVSid2; -const char *CVSid6="$Id: smartd.c,v 1.52 2002/11/07 11:00:56 ballen4705 Exp $" +const char *CVSid6="$Id: smartd.c,v 1.53 2002/11/08 10:51:51 ballen4705 Exp $" CVSID1 CVSID2 CVSID3 CVSID4 CVSID7; // global variable used for control of printing, passing arguments, etc. @@ -86,6 +87,59 @@ void printout(int priority,char *fmt, ...){ return; } + +void printandmail(mailinfo *mail, int priority, char *fmt, ...){ + int pid; + va_list ap; + + // iitialize variable argument list, then log message to SYSLOG or + // stdout, then finish with argument list + va_start(ap,fmt); + printout(priority, fmt, ap); + va_end(ap); + + // See if user wants us to send mail + if (mail==NULL) + return; + + // Have we already sent a message about this? + if (mail->logged) + return; + + // Need to send a message -- fork and send + pid=fork(); + + if (pid<0){ + // We are parent, and were unable to fork to send email. Log + // warning then return. + if (errno<sys_nerr) + printout(LOG_CRIT,"Unable to send email, %s, fork() failed\n", sys_errlist[errno]); + else + printout(LOG_CRIT,"Unable to send email, fork() failed\n"); + return; + } + else if (pid) { + // we are the parent process, record the time of the mail message, + // and increment counter, then return. + mail->logged++; + mail->lastsent=time(NULL); + return; + } + else { + // We are the child process, send email + char command[1024], message[256]; + + // print warning string into message + va_start(ap, fmt); + vsnprintf(message, 256, fmt, ap); + va_end(ap); + + // now construct a command to send this as EMAIL, and issue it. + snprintf(command,1024, "echo '%s' | mail -s 'smartd warning: S.M.A.R.T. errors' %s > /dev/null 2> /dev/null", message, mail->address); + exit(system(command)); + } +} + // Printing function for watching ataprint commands, or losing them void pout(char *fmt, ...){ va_list ap; diff --git a/sm5/smartd.cpp b/sm5/smartd.cpp index c2f44fc916e5ec83703ee10049465502a5ec4d19..c16c05e9e95f88e0959b62e469d014c3155c91ff 100644 --- a/sm5/smartd.cpp +++ b/sm5/smartd.cpp @@ -35,6 +35,7 @@ #include <stdlib.h> #include <errno.h> #include <string.h> +#include <time.h> #include "atacmds.h" #include "scsicmds.h" #include "smartd.h" @@ -44,7 +45,7 @@ // CVS ID strings extern const char *CVSid1, *CVSid2; -const char *CVSid6="$Id: smartd.cpp,v 1.52 2002/11/07 11:00:56 ballen4705 Exp $" +const char *CVSid6="$Id: smartd.cpp,v 1.53 2002/11/08 10:51:51 ballen4705 Exp $" CVSID1 CVSID2 CVSID3 CVSID4 CVSID7; // global variable used for control of printing, passing arguments, etc. @@ -86,6 +87,59 @@ void printout(int priority,char *fmt, ...){ return; } + +void printandmail(mailinfo *mail, int priority, char *fmt, ...){ + int pid; + va_list ap; + + // iitialize variable argument list, then log message to SYSLOG or + // stdout, then finish with argument list + va_start(ap,fmt); + printout(priority, fmt, ap); + va_end(ap); + + // See if user wants us to send mail + if (mail==NULL) + return; + + // Have we already sent a message about this? + if (mail->logged) + return; + + // Need to send a message -- fork and send + pid=fork(); + + if (pid<0){ + // We are parent, and were unable to fork to send email. Log + // warning then return. + if (errno<sys_nerr) + printout(LOG_CRIT,"Unable to send email, %s, fork() failed\n", sys_errlist[errno]); + else + printout(LOG_CRIT,"Unable to send email, fork() failed\n"); + return; + } + else if (pid) { + // we are the parent process, record the time of the mail message, + // and increment counter, then return. + mail->logged++; + mail->lastsent=time(NULL); + return; + } + else { + // We are the child process, send email + char command[1024], message[256]; + + // print warning string into message + va_start(ap, fmt); + vsnprintf(message, 256, fmt, ap); + va_end(ap); + + // now construct a command to send this as EMAIL, and issue it. + snprintf(command,1024, "echo '%s' | mail -s 'smartd warning: S.M.A.R.T. errors' %s > /dev/null 2> /dev/null", message, mail->address); + exit(system(command)); + } +} + // Printing function for watching ataprint commands, or losing them void pout(char *fmt, ...){ va_list ap; diff --git a/sm5/smartd.h b/sm5/smartd.h index 00dd54ea098b0c5b92170ff9ce4ff3c5f56602fb..3577ec82304ea54c634870bf888c61a6f19cc4da 100644 --- a/sm5/smartd.h +++ b/sm5/smartd.h @@ -23,7 +23,7 @@ */ #ifndef CVSID7 -#define CVSID7 "$Id: smartd.h,v 1.17 2002/10/30 19:16:44 ballen4705 Exp $\n" +#define CVSID7 "$Id: smartd.h,v 1.18 2002/11/08 10:51:51 ballen4705 Exp $\n" #endif // Configuration file @@ -68,6 +68,17 @@ typedef struct scsidevices_s { } scsidevices_t; +// If user has requested email warning messages, then this structure +// stores the information about them. +typedef struct mailinfo { + // number of times an email has been sent + int logged; + // time last email was sent, as defined by man 2 time + time_t lastsent; + // address to send email to + char *address; +} mailinfo; + // Used to store a list of devices and options that were in the // configuration file. typedef struct configfile_s { @@ -83,6 +94,8 @@ typedef struct configfile_s { char usage; char selftest; char errorlog; + // mailing information for each of the previous error types + mailinfo *mailinfop[6]; // counts of ata and self-test errors. Perhaps ought to be in the // atadevices_t structure. unsigned char selflogcount;