From 437046344bcced48cc281f96bf084bc69249acbd Mon Sep 17 00:00:00 2001 From: ballen4705 <ballen4705@4ea69e1a-61f1-4043-bf83-b5c94c648137> Date: Tue, 12 Nov 2002 21:16:25 +0000 Subject: [PATCH] Added feature to send email warnings when errors detected by smartd. But this is NOT YET TESTED! Be cautious in using this for now. git-svn-id: https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/trunk@246 4ea69e1a-61f1-4043-bf83-b5c94c648137 --- sm5/CHANGELOG | 8 +++-- sm5/VERSION | 2 +- sm5/smartd.8 | 34 +++++++++++++++++---- sm5/smartd.c | 75 +++++++++++++++++++++++++++++++---------------- sm5/smartd.conf.5 | 34 +++++++++++++++++---- sm5/smartd.cpp | 75 +++++++++++++++++++++++++++++++---------------- sm5/smartd.h | 15 +++++----- 7 files changed, 168 insertions(+), 75 deletions(-) diff --git a/sm5/CHANGELOG b/sm5/CHANGELOG index 7c862eb1c..bc0a26b1b 100644 --- a/sm5/CHANGELOG +++ b/sm5/CHANGELOG @@ -1,6 +1,6 @@ CHANGELOG for smartmontools -$Id: CHANGELOG,v 1.43 2002/11/11 10:55:42 ballen4705 Exp $ +$Id: CHANGELOG,v 1.44 2002/11/12 21:16:25 ballen4705 Exp $ Copyright (C) 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net> @@ -25,7 +25,11 @@ NOTES FOR FUTURE RELEASES: see TODO file. CURRENT RELEASE (see VERSION file in this directory): -smartmontools-5.0.37 + Added a new smartd configuration file Directive: -M ADDRESS. + This sends a single warning email to ADDRESS for failures or + errors detected with the -c, -L, -l, or -f Directives. + +smartmontools-5.0.38 Modified perror() statements in atacmds.c so that printout for SMART commands errors is properly suppressed or queued depending upon users diff --git a/sm5/VERSION b/sm5/VERSION index e522732c7..a2720097d 100644 --- a/sm5/VERSION +++ b/sm5/VERSION @@ -1 +1 @@ -38 +39 diff --git a/sm5/smartd.8 b/sm5/smartd.8 index 11cc7b7ec..ff8f6de74 100644 --- a/sm5/smartd.8 +++ b/sm5/smartd.8 @@ -1,6 +1,6 @@ \# Copyright (C) 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net> \# -\# $Id: smartd.8,v 1.25 2002/11/11 12:43:53 ballen4705 Exp $ +\# $Id: smartd.8,v 1.26 2002/11/12 21:16:25 ballen4705 Exp $ \# \# 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 Free @@ -16,7 +16,7 @@ \# Research Center), Jack Baskin School of Engineering, University of \# California, Santa Cruz. http://ssrc.soe.ucsc.edu/ \# -.TH SMARTD 8 "$Date: 2002/11/11 12:43:53 $" "smartmontools-5.0" +.TH SMARTD 8 "$Date: 2002/11/12 21:16:25 $" "smartmontools-5.0" .SH NAME smartd \- S.M.A.R.T. Daemon .SH SYNOPSIS @@ -250,9 +250,7 @@ name on any line of the configuration file. Note that .B these are NOT command-line options for .B smartd. -The command-line options for -.B smartd -are listed above. The Directives below may appear in any order, +The Directives below may appear in any order, following the device name. For the moment, apart from the '\-S' Directive, these Directives only apply to ATA disks. .B For ATA disks, if @@ -332,6 +330,30 @@ life period." .B smartctl \-v command-line option.] .TP +.B \-M <ADD> +Mail: Send a warning email to the email address <ADD> if the '\-c', '\-l', '\-L', or '\-f' +Directives detect a failure or a new error. This Directive only +works in conjunction with these other Directives (or with the equivalent '\-a' +Directive). To prevent your email in-box from getting filled up +with warning messages, only a single warning will be sent for each of +the enabled test types, '\-c', '\-l', '\-L', or '\-f', even if more +than one failure or error is detected. + +The email is sent using the system +.B mail +command. In order that +.B smartd +find the mail command (normally /bin/mail) the +.B mail +command must be in the path of the +shell or environment from which +.B smartd +was started. + +If you want to send email to more than one user, you can use the form +.B user1@add1,user2@add2,...,userN@addN +with no spaces for <ADD>. +.TP .B \-p Prefail: Report anytime that a Prefail Attribute has changed its value since the last check, 30 minutes ago. [Please see the @@ -518,4 +540,4 @@ Please let us know if there is an on\-line source for this document. .SH CVS ID OF THIS PAGE: -$Id: smartd.8,v 1.25 2002/11/11 12:43:53 ballen4705 Exp $ +$Id: smartd.8,v 1.26 2002/11/12 21:16:25 ballen4705 Exp $ diff --git a/sm5/smartd.c b/sm5/smartd.c index e0c9e1703..410c2f677 100644 --- a/sm5/smartd.c +++ b/sm5/smartd.c @@ -45,7 +45,7 @@ // CVS ID strings extern const char *CVSid1, *CVSid2; -const char *CVSid6="$Id: smartd.c,v 1.55 2002/11/11 10:50:08 ballen4705 Exp $" +const char *CVSid6="$Id: smartd.c,v 1.56 2002/11/12 21:16:25 ballen4705 Exp $" CVSID1 CVSID2 CVSID3 CVSID4 CVSID7; // global variable used for control of printing, passing arguments, etc. @@ -87,8 +87,9 @@ void printout(int priority,char *fmt, ...){ return; } - -void printandmail(mailinfo *mail, int priority, char *fmt, ...){ +// If address is null, this just prints a warning message. But if +// address is non-null then send and log a warning email. +void printandmail(char *address, mailinfo *mail, int priority, char *fmt, ...){ int pid; va_list ap; @@ -99,7 +100,7 @@ void printandmail(mailinfo *mail, int priority, char *fmt, ...){ va_end(ap); // See if user wants us to send mail - if (mail==NULL) + if (!address) return; // Have we already sent a message about this? @@ -127,7 +128,11 @@ void printandmail(mailinfo *mail, int priority, char *fmt, ...){ } else { // We are the child process, send email - char command[1024], message[256]; + char command[1024], message[256], hostname[256]; + + if (gethostname(hostname, 256)){ + sprintf(hostname,"hostname: unknown"); + } // print warning string into message va_start(ap, fmt); @@ -135,7 +140,8 @@ void printandmail(mailinfo *mail, int priority, char *fmt, ...){ 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); + snprintf(command,1024, "echo '%s' | mail -s '%s: smartd detected SMART errors' %s > /dev/null 2> /dev/null", + message, hostname, address); exit(system(command)); } } @@ -227,21 +233,22 @@ void printhead(){ // prints help info for configuration file directives void Directives() { printout(LOG_INFO,"Configuration file Directives (following device name):\n"); - printout(LOG_INFO," -A Device is an ATA device\n"); - printout(LOG_INFO," -S Device is a SCSI device\n"); - printout(LOG_INFO," -C N Check disks once every N seconds, where N>=10.\n"); - printout(LOG_INFO," -P Permissive, ignore apparent lack of SMART.\n"); - printout(LOG_INFO," -c Monitor SMART Health Status, report if failed\n"); - printout(LOG_INFO," -l Monitor SMART Error Log, report new errors\n"); - printout(LOG_INFO," -L Monitor SMART Self-Test Log, report new errors\n"); - printout(LOG_INFO," -f Monitor 'Usage' Attributes, report failures\n"); - printout(LOG_INFO," -p Report changes in 'Prefailure' Attributes\n"); - printout(LOG_INFO," -u Report changes in 'Usage' Attributes\n"); - printout(LOG_INFO," -t Equivalent to -p and -u Directives\n"); - printout(LOG_INFO," -a Equivalent to -c -l -L -f -t Directives\n"); - printout(LOG_INFO," -i ID Ignore Attribute ID for -f Directive\n"); - printout(LOG_INFO," -I ID Ignore Attribute ID for -p, -u or -t Directive\n"); - printout(LOG_INFO," # Comment: text after a hash sign is ignored\n"); + printout(LOG_INFO," -A Device is an ATA device\n"); + printout(LOG_INFO," -S Device is a SCSI device\n"); + printout(LOG_INFO," -C N Check disks once every N seconds, where N>=10.\n"); + printout(LOG_INFO," -P Permissive, ignore apparent lack of SMART.\n"); + printout(LOG_INFO," -c Monitor SMART Health Status, report if failed\n"); + printout(LOG_INFO," -l Monitor SMART Error Log, report new errors\n"); + printout(LOG_INFO," -L Monitor SMART Self-Test Log, report new errors\n"); + printout(LOG_INFO," -f Monitor 'Usage' Attributes, report failures\n"); + printout(LOG_INFO," -M ADD Send email warning to address ADD\n"); + printout(LOG_INFO," -p Report changes in 'Prefailure' Attributes\n"); + printout(LOG_INFO," -u Report changes in 'Usage' Attributes\n"); + printout(LOG_INFO," -t Equivalent to -p and -u Directives\n"); + printout(LOG_INFO," -a Equivalent to -c -l -L -f -t Directives\n"); + printout(LOG_INFO," -i ID Ignore Attribute ID for -f Directive\n"); + printout(LOG_INFO," -I ID Ignore Attribute ID for -p, -u or -t Directive\n"); + printout(LOG_INFO," # Comment: text after a hash sign is ignored\n"); printout(LOG_INFO," \\ Line continuation character\n"); printout(LOG_INFO,"Attribute ID is a decimal integer 1 <= ID <= 255\n"); printout(LOG_INFO,"All but -S Directive are only implemented for ATA devices\n"); @@ -594,7 +601,7 @@ int ataCheckDevice(atadevices_t *drive){ if (status==-1) printout(LOG_INFO,"Device: %s, not capable of SMART self-check\n",name); else if (status==1) - printout(LOG_CRIT,"Device: %s, FAILED SMART self-check. BACK UP DATA NOW!\n",name); + printandmail(cfg->address, cfg->maildata , LOG_CRIT, "Device: %s, FAILED SMART self-check. BACK UP DATA NOW!\n", name); } // Check everything that depends upon SMART Data (eg, Attribute values) @@ -607,7 +614,7 @@ int ataCheckDevice(atadevices_t *drive){ printout(LOG_CRIT, "Device: %s, failed to read SMART Attribute Data\n", name); else { // look for failed usage attributes, or track usage or prefail attributes - for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++) { + for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++){ int att; // This block looks for usage attributes that have failed. @@ -625,7 +632,7 @@ int ataCheckDevice(atadevices_t *drive){ while (*loc && *loc==' ') loc++; // warning message - printout(LOG_CRIT,"Device: %s, Failed SMART usage Attribute: %s.\n", name, loc); + printandmail(cfg->address, cfg->maildata+1, LOG_CRIT, "Device: %s, Failed SMART usage Attribute: %s.\n", name, loc); } } @@ -673,7 +680,7 @@ int ataCheckDevice(atadevices_t *drive){ unsigned char old=cfg->selflogcount; int new=selftesterrorcount(fd, name); if (new>old){ - printout(LOG_CRIT,"Device: %s, Self-Test Log error count increased from %d to %d\n", + printandmail(cfg->address, cfg->maildata+2, LOG_CRIT, "Device: %s, Self-Test Log error count increased from %d to %d\n", name, (int)old, new); } if (new>=0) @@ -687,7 +694,7 @@ int ataCheckDevice(atadevices_t *drive){ int old=cfg->ataerrorcount; int new=ataerrorcount(fd, name); if (new>old){ - printout(LOG_CRIT,"Device: %s, ATA error count increased from %d to %d\n", + printandmail(cfg->address, cfg->maildata+3, LOG_CRIT, "Device: %s, ATA error count increased from %d to %d\n", name, old, new); } // this last line is probably not needed, count always increases @@ -841,6 +848,22 @@ int parsetoken(char *token,cfgfile *cfg){ cfg->selftest=1; cfg->errorlog=1; break; + case 'M': + // send email to address that follows + arg=strtok(NULL,delim); + if (!arg) { + printout(LOG_CRIT,"Drive %s Directive: %s at line %d of file %s needs email address.\n", + name,token,lineno,CONFIGFILE); + Directives(); + exit(1); + } + if (!(cfg->address=strdup(arg))){ + printout(LOG_CRIT,"Drive %s Directive: %s at line %d of file %s: no free memory for address %s.\n", + name,token,lineno,CONFIGFILE,arg); + Directives(); + exit(1); + } + break; case 'i': // ignore case 'I': // ignore case 'C': // period (time interval) for checking diff --git a/sm5/smartd.conf.5 b/sm5/smartd.conf.5 index 82a1182e6..4c0da2962 100644 --- a/sm5/smartd.conf.5 +++ b/sm5/smartd.conf.5 @@ -1,6 +1,6 @@ \# Copyright (C) 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net> \# -\# $Id: smartd.conf.5,v 1.3 2002/11/11 12:43:53 ballen4705 Exp $ +\# $Id: smartd.conf.5,v 1.4 2002/11/12 21:16:25 ballen4705 Exp $ \# \# 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 Free @@ -16,7 +16,7 @@ \# Research Center), Jack Baskin School of Engineering, University of \# California, Santa Cruz. http://ssrc.soe.ucsc.edu/ \# -.TH SMARTD.CONF 5 "$Date: 2002/11/11 12:43:53 $" "smartmontools-5.0" +.TH SMARTD.CONF 5 "$Date: 2002/11/12 21:16:25 $" "smartmontools-5.0" .SH NAME /etc/smartd.conf \- S.M.A.R.T. Monitoring Daemon Configuration File @@ -147,9 +147,7 @@ name on any line of the configuration file. Note that .B these are NOT command-line options for .B smartd. -The command-line options for -.B smartd -are listed above. The Directives below may appear in any order, +The Directives below may appear in any order, following the device name. For the moment, apart from the '\-S' Directive, these Directives only apply to ATA disks. .B For ATA disks, if @@ -229,6 +227,30 @@ life period." .B smartctl \-v command-line option.] .TP +.B \-M <ADD> +Mail: Send a warning email to the email address <ADD> if the '\-c', '\-l', '\-L', or '\-f' +Directives detect a failure or a new error. This Directive only +works in conjunction with these other Directives (or with the equivalent '\-a' +Directive). To prevent your email in-box from getting filled up +with warning messages, only a single warning will be sent for each of +the enabled test types, '\-c', '\-l', '\-L', or '\-f', even if more +than one failure or error is detected. + +The email is sent using the system +.B mail +command. In order that +.B smartd +find the mail command (normally /bin/mail) the +.B mail +command must be in the path of the +shell or environment from which +.B smartd +was started. + +If you want to send email to more than one user, you can use the form +.B user1@add1,user2@add2,...,userN@addN +with no spaces for <ADD>. +.TP .B \-p Prefail: Report anytime that a Prefail Attribute has changed its value since the last check, 30 minutes ago. [Please see the @@ -345,4 +367,4 @@ SEE ALSO: .SH CVS ID OF THIS PAGE: -$Id: smartd.conf.5,v 1.3 2002/11/11 12:43:53 ballen4705 Exp $ +$Id: smartd.conf.5,v 1.4 2002/11/12 21:16:25 ballen4705 Exp $ diff --git a/sm5/smartd.cpp b/sm5/smartd.cpp index c5cb8c541..2b67f290d 100644 --- a/sm5/smartd.cpp +++ b/sm5/smartd.cpp @@ -45,7 +45,7 @@ // CVS ID strings extern const char *CVSid1, *CVSid2; -const char *CVSid6="$Id: smartd.cpp,v 1.55 2002/11/11 10:50:08 ballen4705 Exp $" +const char *CVSid6="$Id: smartd.cpp,v 1.56 2002/11/12 21:16:25 ballen4705 Exp $" CVSID1 CVSID2 CVSID3 CVSID4 CVSID7; // global variable used for control of printing, passing arguments, etc. @@ -87,8 +87,9 @@ void printout(int priority,char *fmt, ...){ return; } - -void printandmail(mailinfo *mail, int priority, char *fmt, ...){ +// If address is null, this just prints a warning message. But if +// address is non-null then send and log a warning email. +void printandmail(char *address, mailinfo *mail, int priority, char *fmt, ...){ int pid; va_list ap; @@ -99,7 +100,7 @@ void printandmail(mailinfo *mail, int priority, char *fmt, ...){ va_end(ap); // See if user wants us to send mail - if (mail==NULL) + if (!address) return; // Have we already sent a message about this? @@ -127,7 +128,11 @@ void printandmail(mailinfo *mail, int priority, char *fmt, ...){ } else { // We are the child process, send email - char command[1024], message[256]; + char command[1024], message[256], hostname[256]; + + if (gethostname(hostname, 256)){ + sprintf(hostname,"hostname: unknown"); + } // print warning string into message va_start(ap, fmt); @@ -135,7 +140,8 @@ void printandmail(mailinfo *mail, int priority, char *fmt, ...){ 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); + snprintf(command,1024, "echo '%s' | mail -s '%s: smartd detected SMART errors' %s > /dev/null 2> /dev/null", + message, hostname, address); exit(system(command)); } } @@ -227,21 +233,22 @@ void printhead(){ // prints help info for configuration file directives void Directives() { printout(LOG_INFO,"Configuration file Directives (following device name):\n"); - printout(LOG_INFO," -A Device is an ATA device\n"); - printout(LOG_INFO," -S Device is a SCSI device\n"); - printout(LOG_INFO," -C N Check disks once every N seconds, where N>=10.\n"); - printout(LOG_INFO," -P Permissive, ignore apparent lack of SMART.\n"); - printout(LOG_INFO," -c Monitor SMART Health Status, report if failed\n"); - printout(LOG_INFO," -l Monitor SMART Error Log, report new errors\n"); - printout(LOG_INFO," -L Monitor SMART Self-Test Log, report new errors\n"); - printout(LOG_INFO," -f Monitor 'Usage' Attributes, report failures\n"); - printout(LOG_INFO," -p Report changes in 'Prefailure' Attributes\n"); - printout(LOG_INFO," -u Report changes in 'Usage' Attributes\n"); - printout(LOG_INFO," -t Equivalent to -p and -u Directives\n"); - printout(LOG_INFO," -a Equivalent to -c -l -L -f -t Directives\n"); - printout(LOG_INFO," -i ID Ignore Attribute ID for -f Directive\n"); - printout(LOG_INFO," -I ID Ignore Attribute ID for -p, -u or -t Directive\n"); - printout(LOG_INFO," # Comment: text after a hash sign is ignored\n"); + printout(LOG_INFO," -A Device is an ATA device\n"); + printout(LOG_INFO," -S Device is a SCSI device\n"); + printout(LOG_INFO," -C N Check disks once every N seconds, where N>=10.\n"); + printout(LOG_INFO," -P Permissive, ignore apparent lack of SMART.\n"); + printout(LOG_INFO," -c Monitor SMART Health Status, report if failed\n"); + printout(LOG_INFO," -l Monitor SMART Error Log, report new errors\n"); + printout(LOG_INFO," -L Monitor SMART Self-Test Log, report new errors\n"); + printout(LOG_INFO," -f Monitor 'Usage' Attributes, report failures\n"); + printout(LOG_INFO," -M ADD Send email warning to address ADD\n"); + printout(LOG_INFO," -p Report changes in 'Prefailure' Attributes\n"); + printout(LOG_INFO," -u Report changes in 'Usage' Attributes\n"); + printout(LOG_INFO," -t Equivalent to -p and -u Directives\n"); + printout(LOG_INFO," -a Equivalent to -c -l -L -f -t Directives\n"); + printout(LOG_INFO," -i ID Ignore Attribute ID for -f Directive\n"); + printout(LOG_INFO," -I ID Ignore Attribute ID for -p, -u or -t Directive\n"); + printout(LOG_INFO," # Comment: text after a hash sign is ignored\n"); printout(LOG_INFO," \\ Line continuation character\n"); printout(LOG_INFO,"Attribute ID is a decimal integer 1 <= ID <= 255\n"); printout(LOG_INFO,"All but -S Directive are only implemented for ATA devices\n"); @@ -594,7 +601,7 @@ int ataCheckDevice(atadevices_t *drive){ if (status==-1) printout(LOG_INFO,"Device: %s, not capable of SMART self-check\n",name); else if (status==1) - printout(LOG_CRIT,"Device: %s, FAILED SMART self-check. BACK UP DATA NOW!\n",name); + printandmail(cfg->address, cfg->maildata , LOG_CRIT, "Device: %s, FAILED SMART self-check. BACK UP DATA NOW!\n", name); } // Check everything that depends upon SMART Data (eg, Attribute values) @@ -607,7 +614,7 @@ int ataCheckDevice(atadevices_t *drive){ printout(LOG_CRIT, "Device: %s, failed to read SMART Attribute Data\n", name); else { // look for failed usage attributes, or track usage or prefail attributes - for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++) { + for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++){ int att; // This block looks for usage attributes that have failed. @@ -625,7 +632,7 @@ int ataCheckDevice(atadevices_t *drive){ while (*loc && *loc==' ') loc++; // warning message - printout(LOG_CRIT,"Device: %s, Failed SMART usage Attribute: %s.\n", name, loc); + printandmail(cfg->address, cfg->maildata+1, LOG_CRIT, "Device: %s, Failed SMART usage Attribute: %s.\n", name, loc); } } @@ -673,7 +680,7 @@ int ataCheckDevice(atadevices_t *drive){ unsigned char old=cfg->selflogcount; int new=selftesterrorcount(fd, name); if (new>old){ - printout(LOG_CRIT,"Device: %s, Self-Test Log error count increased from %d to %d\n", + printandmail(cfg->address, cfg->maildata+2, LOG_CRIT, "Device: %s, Self-Test Log error count increased from %d to %d\n", name, (int)old, new); } if (new>=0) @@ -687,7 +694,7 @@ int ataCheckDevice(atadevices_t *drive){ int old=cfg->ataerrorcount; int new=ataerrorcount(fd, name); if (new>old){ - printout(LOG_CRIT,"Device: %s, ATA error count increased from %d to %d\n", + printandmail(cfg->address, cfg->maildata+3, LOG_CRIT, "Device: %s, ATA error count increased from %d to %d\n", name, old, new); } // this last line is probably not needed, count always increases @@ -841,6 +848,22 @@ int parsetoken(char *token,cfgfile *cfg){ cfg->selftest=1; cfg->errorlog=1; break; + case 'M': + // send email to address that follows + arg=strtok(NULL,delim); + if (!arg) { + printout(LOG_CRIT,"Drive %s Directive: %s at line %d of file %s needs email address.\n", + name,token,lineno,CONFIGFILE); + Directives(); + exit(1); + } + if (!(cfg->address=strdup(arg))){ + printout(LOG_CRIT,"Drive %s Directive: %s at line %d of file %s: no free memory for address %s.\n", + name,token,lineno,CONFIGFILE,arg); + Directives(); + exit(1); + } + break; case 'i': // ignore case 'I': // ignore case 'C': // period (time interval) for checking diff --git a/sm5/smartd.h b/sm5/smartd.h index 02ee37c08..c5e2677a6 100644 --- a/sm5/smartd.h +++ b/sm5/smartd.h @@ -23,7 +23,7 @@ */ #ifndef CVSID7 -#define CVSID7 "$Id: smartd.h,v 1.19 2002/11/10 21:54:19 ballen4705 Exp $\n" +#define CVSID7 "$Id: smartd.h,v 1.20 2002/11/12 21:16:25 ballen4705 Exp $\n" #endif // Configuration file @@ -75,8 +75,6 @@ typedef struct mailinfo { 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 @@ -97,7 +95,9 @@ typedef struct configfile_s { // Should we ignore missing capabilities/SMART errors char permissive; // mailing information for each of the previous error types - mailinfo *mailinfop[6]; + mailinfo maildata[4]; + // address to send email to + char *address; // counts of ata and self-test errors. Perhaps ought to be in the // atadevices_t structure. unsigned char selflogcount; @@ -120,9 +120,8 @@ typedef struct atadevices_s { } atadevices_t; -// Declare our own printing function... -void printout(int priority,char *fmt, ...) - __attribute__ ((format (printf, 2, 3))); - +// Declare our own printing functions... +void printout(int priority,char *fmt, ...) __attribute__ ((format(printf, 2, 3))); +void printandmail(char *address, mailinfo *mail, int priority, char *fmt, ...) __attribute__ ((format(printf, 4, 5))); int ataCheckDevice(atadevices_t *drive); -- GitLab