diff --git a/sm5/CHANGELOG b/sm5/CHANGELOG index f6b127429f4604b997e8404e88d743af07d29281..61679143d55831a5f2ea6efbcd14aed187ba0216 100644 --- a/sm5/CHANGELOG +++ b/sm5/CHANGELOG @@ -1,6 +1,6 @@ CHANGELOG for smartmontools -$Id: CHANGELOG,v 1.77 2003/01/03 12:23:40 pjwilliams Exp $ +$Id: CHANGELOG,v 1.78 2003/01/03 17:25:12 ballen4705 Exp $ Copyright (C) 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net> @@ -38,6 +38,9 @@ CURRENT RELEASE (see VERSION file in this directory): smartmontools-5.1.1 + [BA] smartd,smartctl: added additional Attribute modification option + -v 220,temp and -9,temp. + [PW] Renamed smartd option -X to -d START OF SMARTMONTOOLS 5.1 series diff --git a/sm5/atacmds.c b/sm5/atacmds.c index cc6f4df5d5f477362e52e302294e54de16a17b8f..6d3583c136677152d415ab96b0b74d31b803e4df 100644 --- a/sm5/atacmds.c +++ b/sm5/atacmds.c @@ -29,7 +29,7 @@ #include <stdlib.h> #include "atacmds.h" -const char *CVSid1="$Id: atacmds.c,v 1.47 2002/12/19 00:05:19 pjwilliams Exp $" CVSID1; +const char *CVSid1="$Id: atacmds.c,v 1.48 2003/01/03 17:25:12 ballen4705 Exp $" CVSID1; // These Drive Identity tables are taken from hdparm 5.2, and are also // given in the ATA/ATAPI specs for the IDENTIFY DEVICE command. Note @@ -116,13 +116,47 @@ const int actual_ver[] = { 0 /* 0x001d-0xfffe */ }; -// Array of valid argument strings for the -v option. The order of elements is -// important! + const char *vendorattributeargs[] = { + // 0 "9,minutes", + // 1 + "220,temp", + // 2 + "9,temp", + // NULL should always terminate the array NULL }; +// This is a utility function for parsing pairs like "9,minutes" or +// "220,temp", and putting the correct flag into the attributedefs +// array. Returns 1 if problem, 0 if pair has been recongized. +int parse_attribute_def(char *pair, unsigned char *defs){ + int i; + + // look along list and see if we find the pair + for (i=0; vendorattributeargs[i] && strcmp(pair, vendorattributeargs[i]); i++); + + switch (i) { + case 0: + // power on time stored in minutes + defs[9]=1; + return 0; + case 1: + // attribute 220 is temperature in celsius + defs[220]=1; + return 0; + case 2: + // attribute 9 is temperature in celsius + defs[9]=2; + return 0; + default: + // pair not found + return 1; + } +} + + // A replacement for perror() that sends output to our choice of // printing. void syserror(const char *message){ @@ -724,8 +758,9 @@ int ataCheckAttribute(struct ata_smart_values *data, // Note some attribute names appear redundant because different // manufacturers use different attribute IDs for an attribute with the -// same name. -void ataPrintSmartAttribName(char *out, unsigned char id){ +// same name. The array defs[] contains non-zero values if particular +// attributes have non-default interpretations. +void ataPrintSmartAttribName(char *out, unsigned char id, unsigned char *defs){ char *name; switch (id){ @@ -754,7 +789,17 @@ void ataPrintSmartAttribName(char *out, unsigned char id){ name="Seek_Time_Performance"; break; case 9: - name="Power_On_Hours"; + switch (defs[id]) { + case 1: + name="Power_On_Minutes"; + break; + case 2: + name="Temperature_Celsius"; + break; + default: + name="Power_On_Hours"; + break; + } break; case 10: name="Spin_Retry_Count"; @@ -800,8 +845,14 @@ void ataPrintSmartAttribName(char *out, unsigned char id){ name="Multi_Zone_Error_Rate"; break; case 220: - // Note -- this is also apparently used for temperature. - name="Disk_Shift"; + switch (defs[id]) { + case 1: + name="Temperature_Celsius"; + break; + default: + name="Disk_Shift"; + break; + } break; case 221: name="G-Sense_Error_Rate"; diff --git a/sm5/atacmds.cpp b/sm5/atacmds.cpp index c0c8cc92704ff1564158970195d4321d7859c9ce..f7c0e57eee1759c740118a7717c6d99246d35def 100644 --- a/sm5/atacmds.cpp +++ b/sm5/atacmds.cpp @@ -29,7 +29,7 @@ #include <stdlib.h> #include "atacmds.h" -const char *CVSid1="$Id: atacmds.cpp,v 1.47 2002/12/19 00:05:19 pjwilliams Exp $" CVSID1; +const char *CVSid1="$Id: atacmds.cpp,v 1.48 2003/01/03 17:25:12 ballen4705 Exp $" CVSID1; // These Drive Identity tables are taken from hdparm 5.2, and are also // given in the ATA/ATAPI specs for the IDENTIFY DEVICE command. Note @@ -116,13 +116,47 @@ const int actual_ver[] = { 0 /* 0x001d-0xfffe */ }; -// Array of valid argument strings for the -v option. The order of elements is -// important! + const char *vendorattributeargs[] = { + // 0 "9,minutes", + // 1 + "220,temp", + // 2 + "9,temp", + // NULL should always terminate the array NULL }; +// This is a utility function for parsing pairs like "9,minutes" or +// "220,temp", and putting the correct flag into the attributedefs +// array. Returns 1 if problem, 0 if pair has been recongized. +int parse_attribute_def(char *pair, unsigned char *defs){ + int i; + + // look along list and see if we find the pair + for (i=0; vendorattributeargs[i] && strcmp(pair, vendorattributeargs[i]); i++); + + switch (i) { + case 0: + // power on time stored in minutes + defs[9]=1; + return 0; + case 1: + // attribute 220 is temperature in celsius + defs[220]=1; + return 0; + case 2: + // attribute 9 is temperature in celsius + defs[9]=2; + return 0; + default: + // pair not found + return 1; + } +} + + // A replacement for perror() that sends output to our choice of // printing. void syserror(const char *message){ @@ -724,8 +758,9 @@ int ataCheckAttribute(struct ata_smart_values *data, // Note some attribute names appear redundant because different // manufacturers use different attribute IDs for an attribute with the -// same name. -void ataPrintSmartAttribName(char *out, unsigned char id){ +// same name. The array defs[] contains non-zero values if particular +// attributes have non-default interpretations. +void ataPrintSmartAttribName(char *out, unsigned char id, unsigned char *defs){ char *name; switch (id){ @@ -754,7 +789,17 @@ void ataPrintSmartAttribName(char *out, unsigned char id){ name="Seek_Time_Performance"; break; case 9: - name="Power_On_Hours"; + switch (defs[id]) { + case 1: + name="Power_On_Minutes"; + break; + case 2: + name="Temperature_Celsius"; + break; + default: + name="Power_On_Hours"; + break; + } break; case 10: name="Spin_Retry_Count"; @@ -800,8 +845,14 @@ void ataPrintSmartAttribName(char *out, unsigned char id){ name="Multi_Zone_Error_Rate"; break; case 220: - // Note -- this is also apparently used for temperature. - name="Disk_Shift"; + switch (defs[id]) { + case 1: + name="Temperature_Celsius"; + break; + default: + name="Disk_Shift"; + break; + } break; case 221: name="G-Sense_Error_Rate"; diff --git a/sm5/atacmds.h b/sm5/atacmds.h index 259a26be3b983a9747250042b94fe949632e96bf..89360a38fa84ebc5efa44a89f5fed9d1a92f8d51 100644 --- a/sm5/atacmds.h +++ b/sm5/atacmds.h @@ -26,7 +26,7 @@ #define _ATACMDS_H_ #ifndef CVSID1 -#define CVSID1 "$Id: atacmds.h,v 1.28 2003/01/03 07:00:27 ballen4705 Exp $\n" +#define CVSID1 "$Id: atacmds.h,v 1.29 2003/01/03 17:25:12 ballen4705 Exp $\n" #endif // These are the major and minor versions for smartd and smartctl @@ -267,9 +267,6 @@ struct ata_smart_selftestlog { unsigned char chksum; } __attribute__ ((packed)); -// Array of valid argument strings to the -v option. Defined in atamain.c -extern const char *vendorattributeargs[]; - /* Read S.M.A.R.T information from drive */ int ataReadHDIdentity (int device, struct hd_driveid *buf); int ataReadSmartValues (int device,struct ata_smart_values *); @@ -346,7 +343,7 @@ int TestTime(struct ata_smart_values *data,int testtype); // Prints Attribute Name for standard SMART attributes. Writes a // 30 byte string with attribute name into output -void ataPrintSmartAttribName(char *output, unsigned char id); +void ataPrintSmartAttribName(char *output, unsigned char id, unsigned char *defs); // like printf() except that we can control it better.... void pout(char *fmt, ...) @@ -379,5 +376,11 @@ int ataCheckAttribute(struct ata_smart_values *data, // Structure with the incorrect checksum. void checksumwarning(const char *string); +extern const char *vendorattributeargs[]; + +// function to parse pairs like "9,minutes" or "220,temp". See end of +// extern.h for definition of defs[]. Returns 0 if pair recognized, +// else 1 if there is a problem. +int parse_attribute_def(char *pair, unsigned char *defs); #endif /* _ATACMDS_H_ */ diff --git a/sm5/ataprint.c b/sm5/ataprint.c index f27d915d3eaa99605084b2ecfff9f27c88df5441..6003437e4efe0e7e37f2203fa68e3f58d1ff058b 100644 --- a/sm5/ataprint.c +++ b/sm5/ataprint.c @@ -30,7 +30,7 @@ #include "smartctl.h" #include "extern.h" -const char *CVSid2="$Id: ataprint.c,v 1.49 2002/12/19 00:05:19 pjwilliams Exp $" +const char *CVSid2="$Id: ataprint.c,v 1.50 2003/01/03 17:25:12 ballen4705 Exp $" CVSID1 CVSID2 CVSID3 CVSID6; // for passing global control variables @@ -405,7 +405,7 @@ void PrintSmartAttribWithThres (struct ata_smart_values *data, status=" -"; // Print name of attribute - ataPrintSmartAttribName(attributename,disk->id); + ataPrintSmartAttribName(attributename,disk->id, con->attributedefs); pout("%-28s",attributename); // printing line for each valid attribute @@ -432,7 +432,7 @@ void PrintSmartAttribWithThres (struct ata_smart_values *data, switch (disk->id){ // Power on time case 9: - if (con->smart009minutes){ + if (con->attributedefs[9]==1){ // minutes long long tmp1=rawvalue/60; long long tmp2=rawvalue%60; @@ -460,8 +460,8 @@ void PrintSmartAttribWithThres (struct ata_smart_values *data, // print a warning if there is inconsistency here! if (disk->id != thre->id){ char atdat[64],atthr[64]; - ataPrintSmartAttribName(atdat,disk->id); - ataPrintSmartAttribName(atthr,thre->id); + ataPrintSmartAttribName(atdat, disk->id, con->attributedefs); + ataPrintSmartAttribName(atthr, thre->id, con->attributedefs); pout("%-28s<== Data Page | WARNING: PREVIOUS ATTRIBUTE HAS TWO\n",atdat); pout("%-28s<== Threshold Page | INCONSISTENT IDENTITIES IN THE DATA\n",atthr); } diff --git a/sm5/ataprint.cpp b/sm5/ataprint.cpp index af04d054c78a198027f0e8acefba9aa2c472d89e..64ed2db148c1e14ad8ca8540fd5a10a64c18ba4f 100644 --- a/sm5/ataprint.cpp +++ b/sm5/ataprint.cpp @@ -30,7 +30,7 @@ #include "smartctl.h" #include "extern.h" -const char *CVSid2="$Id: ataprint.cpp,v 1.49 2002/12/19 00:05:19 pjwilliams Exp $" +const char *CVSid2="$Id: ataprint.cpp,v 1.50 2003/01/03 17:25:12 ballen4705 Exp $" CVSID1 CVSID2 CVSID3 CVSID6; // for passing global control variables @@ -405,7 +405,7 @@ void PrintSmartAttribWithThres (struct ata_smart_values *data, status=" -"; // Print name of attribute - ataPrintSmartAttribName(attributename,disk->id); + ataPrintSmartAttribName(attributename,disk->id, con->attributedefs); pout("%-28s",attributename); // printing line for each valid attribute @@ -432,7 +432,7 @@ void PrintSmartAttribWithThres (struct ata_smart_values *data, switch (disk->id){ // Power on time case 9: - if (con->smart009minutes){ + if (con->attributedefs[9]==1){ // minutes long long tmp1=rawvalue/60; long long tmp2=rawvalue%60; @@ -460,8 +460,8 @@ void PrintSmartAttribWithThres (struct ata_smart_values *data, // print a warning if there is inconsistency here! if (disk->id != thre->id){ char atdat[64],atthr[64]; - ataPrintSmartAttribName(atdat,disk->id); - ataPrintSmartAttribName(atthr,thre->id); + ataPrintSmartAttribName(atdat, disk->id, con->attributedefs); + ataPrintSmartAttribName(atthr, thre->id, con->attributedefs); pout("%-28s<== Data Page | WARNING: PREVIOUS ATTRIBUTE HAS TWO\n",atdat); pout("%-28s<== Threshold Page | INCONSISTENT IDENTITIES IN THE DATA\n",atthr); } diff --git a/sm5/extern.h b/sm5/extern.h index 90b1d6f66705b4b94edcb1fc08d5119ee7be8d94..d8a934c19f6878a71586856df47189eefbe35380 100644 --- a/sm5/extern.h +++ b/sm5/extern.h @@ -27,7 +27,7 @@ #ifndef CVSID3 -#define CVSID3 "$Id: extern.h,v 1.11 2002/12/11 00:11:30 pjwilliams Exp $\n" +#define CVSID3 "$Id: extern.h,v 1.12 2003/01/03 17:25:12 ballen4705 Exp $\n" #endif // Block used for global control/communications. If you need more @@ -53,7 +53,6 @@ typedef struct ataprintmain_s { unsigned char smartautoofflinedisable; unsigned char smartautosaveenable; unsigned char smartautosavedisable; - unsigned char smart009minutes; int testcase; unsigned char quietmode; unsigned char veryquietmode; @@ -61,6 +60,23 @@ typedef struct ataprintmain_s { unsigned char conservative; unsigned char checksumfail; unsigned char checksumignore; + // The i'th entry in this array will modify the printed meaning of + // the i'th SMART attribute. The default definitions of the + // Attributes are obtained by having the array be all zeros. If + // attributedefs[i] is nonzero, it means that the i'th attribute has + // a non-default meaning. See the ataPrintSmartAttribName function, + // and list below. + unsigned char attributedefs[256]; } atamainctrl; #endif + +/* + +attributedefs[9]: + 1 -- time in minutes + 2 -- temperature in Celsius +attributedefs[220]: + 1 -- temperature in Celsius + +*/ diff --git a/sm5/smartctl.8 b/sm5/smartctl.8 index e9d760c480c7adcfc8c58a9961f9c608d98713db..1c67616c233aee270aeb9dea60a93271d0a599e5 100644 --- a/sm5/smartctl.8 +++ b/sm5/smartctl.8 @@ -1,6 +1,6 @@ \# Copyright (C) 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net> \# -\# $Id: smartctl.8,v 1.32 2003/01/03 06:19:55 ballen4705 Exp $ +\# $Id: smartctl.8,v 1.33 2003/01/03 17:25:12 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 SMARTCTL 8 "$Date: 2003/01/03 06:19:55 $" "smartmontools-5.0" +.TH SMARTCTL 8 "$Date: 2003/01/03 17:25:12 $" "smartmontools-5.0" .SH NAME smartctl \- S.M.A.R.T. control and monitor utility .SH SYNOPSIS @@ -402,13 +402,18 @@ in hexadecimal notation. .TP .B \-v N,OPTION, \-\-vendorattribute=N,OPTION -Sets a vendor-specific display OPTION for attribute N. There is currently only -one valid argument to this option: +Sets a vendor-specific display OPTION for Attribute N. Valid +arguments to this option are: .I 9,minutes -\- the disk stores Raw Attribute number 9 (power on time) in -minutes rather than hours, so display it in the form 'X h + Y m', -where X is hours and Y is minutes. +\- Raw Attribute number 9 is power-on time in minutes. It will be +displayed in the form 'X h + Y m', where X is hours and Y is minutes. + +.I 9,temp +\- Raw attribute number 220 is the disk temperature in Celsius. + +.I 220,temp +\- Raw attribute number 220 is the disk temperature in Celsius. .TP .B S.M.A.R.T. RUN/ABORT OFFLINE TEST AND SELF-TEST OPTIONS: @@ -648,4 +653,4 @@ Please let us know if there is an on\-line source for this document. .SH CVS ID OF THIS PAGE: -$Id: smartctl.8,v 1.32 2003/01/03 06:19:55 ballen4705 Exp $ +$Id: smartctl.8,v 1.33 2003/01/03 17:25:12 ballen4705 Exp $ diff --git a/sm5/smartctl.c b/sm5/smartctl.c index 23f4db07edd70cc94aa6cad6d98d1555afaa0a69..ac9678268e119dd827f77526a0046a3efc765e89 100644 --- a/sm5/smartctl.c +++ b/sm5/smartctl.c @@ -42,7 +42,7 @@ #include "extern.h" extern const char *CVSid1, *CVSid2, *CVSid3, *CVSid4; -const char* CVSid5="$Id: smartctl.c,v 1.31 2002/12/19 00:05:19 pjwilliams Exp $" +const char* CVSid5="$Id: smartctl.c,v 1.32 2003/01/03 17:25:12 ballen4705 Exp $" CVSID1 CVSID2 CVSID3 CVSID4 CVSID5 CVSID6; // This is a block containing all the "control variables". We declare @@ -215,7 +215,7 @@ void Usage (void){ void printbadargmessage(int opt, const char *optarg) { const char **ps; - pout("=======> INVALID ARGUMENT: %s <======= \n", optarg); + pout("=======> INVALID ARGUMENT OF -%c: %s <======= \n", opt, optarg); pout("=======> VALID ARGUMENTS ARE: "); switch (opt) { case 'q': @@ -259,7 +259,6 @@ void ParseOpts (int argc, char** argv){ int optchar; int badarg; int captive; - int i; extern char *optarg; extern int optopt, optind, opterr; const char *shortopts = "h?Vq:d:T:b:s:o:S:HcAl:iav:t:CX"; @@ -418,17 +417,10 @@ void ParseOpts (int argc, char** argv){ con->smartselftestlog = TRUE; break; case 'v': - for (i=0; vendorattributeargs[i] && strcmp(optarg,vendorattributeargs[i]); i++) - ; - switch (i) { - case 0: - con->smart009minutes = TRUE; - break; - default: - badarg = TRUE; - break; - } - break; + // parse vendor-specific definitions of attributes + if (parse_attribute_def(optarg, con->attributedefs)) + badarg = TRUE; + break; case 't': if (!strcmp(optarg,"offline")) { con->smartexeoffimmediate = TRUE; diff --git a/sm5/smartctl.cpp b/sm5/smartctl.cpp index 43fe2c87dc10e65a208c33d9bf90140a6d8a8b41..0ee00284597c8477629cc8b9b5f37f8477fd7711 100644 --- a/sm5/smartctl.cpp +++ b/sm5/smartctl.cpp @@ -42,7 +42,7 @@ #include "extern.h" extern const char *CVSid1, *CVSid2, *CVSid3, *CVSid4; -const char* CVSid5="$Id: smartctl.cpp,v 1.31 2002/12/19 00:05:19 pjwilliams Exp $" +const char* CVSid5="$Id: smartctl.cpp,v 1.32 2003/01/03 17:25:12 ballen4705 Exp $" CVSID1 CVSID2 CVSID3 CVSID4 CVSID5 CVSID6; // This is a block containing all the "control variables". We declare @@ -215,7 +215,7 @@ void Usage (void){ void printbadargmessage(int opt, const char *optarg) { const char **ps; - pout("=======> INVALID ARGUMENT: %s <======= \n", optarg); + pout("=======> INVALID ARGUMENT OF -%c: %s <======= \n", opt, optarg); pout("=======> VALID ARGUMENTS ARE: "); switch (opt) { case 'q': @@ -259,7 +259,6 @@ void ParseOpts (int argc, char** argv){ int optchar; int badarg; int captive; - int i; extern char *optarg; extern int optopt, optind, opterr; const char *shortopts = "h?Vq:d:T:b:s:o:S:HcAl:iav:t:CX"; @@ -418,17 +417,10 @@ void ParseOpts (int argc, char** argv){ con->smartselftestlog = TRUE; break; case 'v': - for (i=0; vendorattributeargs[i] && strcmp(optarg,vendorattributeargs[i]); i++) - ; - switch (i) { - case 0: - con->smart009minutes = TRUE; - break; - default: - badarg = TRUE; - break; - } - break; + // parse vendor-specific definitions of attributes + if (parse_attribute_def(optarg, con->attributedefs)) + badarg = TRUE; + break; case 't': if (!strcmp(optarg,"offline")) { con->smartexeoffimmediate = TRUE; diff --git a/sm5/smartd.8 b/sm5/smartd.8 index dfe7d1a068838122e7e8063934dd909c0123e824..0a40279e96d3a759cdd2bb90944ed6eb9a901557 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.46 2003/01/03 12:23:40 pjwilliams Exp $ +\# $Id: smartd.8,v 1.47 2003/01/03 17:25:12 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: 2003/01/03 12:23:40 $" "smartmontools-5.0" +.TH SMARTD 8 "$Date: 2003/01/03 17:25:12 $" "smartmontools-5.0" .SH NAME smartd \- S.M.A.R.T. Daemon .SH SYNOPSIS @@ -515,6 +515,20 @@ temperature (usually Attribute 194 or 231). It's annoying to get reports each time the temperature changes. This Directive may appear multiple times for a single device, if you want to ignore multiple Attributes. .TP +.B \-v N,OPTION +Modifies the labeling for Attribute N, for disks which use +non-standard Attribute definitions. Valid arguments to this Directive +are: + +.I 9,minutes +\- Raw Attribute number 9 is power-on time in minutes (not hours). + +.I 9,temp +\- Raw Attribute number 9 is the disk temperature in Celsius. + +.I 220,temp +\- Raw attribute number 220 is the disk temperature in Celsius. +.TP .B \-a Equivalent to turning on all of the following Directives: .B '\-H' @@ -666,4 +680,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.46 2003/01/03 12:23:40 pjwilliams Exp $ +$Id: smartd.8,v 1.47 2003/01/03 17:25:12 ballen4705 Exp $ diff --git a/sm5/smartd.c b/sm5/smartd.c index f22f38e7a6756e9b5f53cce0c22abed3516c1b5f..f0b3e4c19a5594d5266e9709a8a46beb62c47b4e 100644 --- a/sm5/smartd.c +++ b/sm5/smartd.c @@ -50,7 +50,7 @@ // CVS ID strings extern const char *CVSid1, *CVSid2; -const char *CVSid6="$Id: smartd.c,v 1.91 2003/01/03 12:23:41 pjwilliams Exp $" +const char *CVSid6="$Id: smartd.c,v 1.92 2003/01/03 17:25:12 ballen4705 Exp $" CVSID1 CVSID2 CVSID3 CVSID4 CVSID7; // global variable used for control of printing, passing arguments, etc. @@ -330,6 +330,7 @@ void Directives() { printout(LOG_INFO," -t Equivalent to -p and -u 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," -v N,ST Modifies labeling of Attribute N (see man page) \n"); printout(LOG_INFO," -a Equivalent to -H -f -t -l error -l selftest Directives\n"); printout(LOG_INFO," # Comment: text after a hash sign is ignored\n"); printout(LOG_INFO," \\ Line continuation character\n"); @@ -767,7 +768,7 @@ int ataCheckDevice(atadevices_t *drive){ char attname[64], *loc=attname; // get attribute name & skip white space - ataPrintSmartAttribName(loc, att); + ataPrintSmartAttribName(loc, att, con->attributedefs); while (*loc && *loc==' ') loc++; // warning message @@ -794,7 +795,7 @@ int ataCheckDevice(atadevices_t *drive){ if (!isattoff(id, cfg->trackatt, 0)){ // get attribute name, skip spaces - ataPrintSmartAttribName(loc, id); + ataPrintSmartAttribName(loc, id, con->attributedefs); while (*loc && *loc==' ') loc++; // prefailure attribute @@ -1147,18 +1148,37 @@ int parsetoken(char *token,cfgfile *cfg){ arg=strtok(NULL,delim); if (!arg) { printout(LOG_CRIT,"File %s line %d (drive %s): Directive: %s needs email address(es)\n", - CONFIGFILE, lineno, name, token); + CONFIGFILE, lineno, name, token); Directives(); exit(1); } if (!(cfg->address=strdup(arg))){ printout(LOG_CRIT,"File %s line %d (drive %s): Directive: %s: no free memory for email address(es) %s\n", - CONFIGFILE, lineno, name, token, arg); + CONFIGFILE, lineno, name, token, arg); + Directives(); + exit(1); + } + break; + case 'v': + // non-default vendor-specific attribute meaning + arg=strtok(NULL,delim); + if (!arg) { + // user forgot argument! + printout(LOG_CRIT,"File %s line %d (drive %s): Directive: %s needs attribute #,action pair\n", + CONFIGFILE, lineno, name, token); + Directives(); + exit(1); + } + if (parse_attribute_def(arg, cfg->attributedefs)){ + // user argument not recognized + printout(LOG_CRIT,"File %s line %d (drive %s): Directive: %s argument %s not recognized\n", + CONFIGFILE, lineno, name, token, arg); Directives(); exit(1); } break; default: + // Directive not recognized printout(LOG_CRIT,"File %s line %d (drive %s): unknown Directive: %s\n", CONFIGFILE, lineno, name, token); Directives(); @@ -1228,8 +1248,9 @@ int parseconfigline(int entry, int lineno,char *line){ cfg->name=strdup(name); cfg->failatt=(unsigned char *)calloc(32,1); cfg->trackatt=(unsigned char *)calloc(32,1); + cfg->attributedefs=(unsigned char *)calloc(256,1); - if (!cfg->name || !cfg->failatt || !cfg->trackatt) { + if (!cfg->name || !cfg->failatt || !cfg->trackatt || !cfg->attributedefs) { printout(LOG_INFO,"No memory to store file: %s line %d, %s\n", CONFIGFILE, lineno, strerror(errno)); exit(1); } @@ -1532,7 +1553,8 @@ int makeconfigentries(int num, char *name, int isata, int start){ cfg->name=strdup(name); cfg->failatt=(unsigned char *)calloc(32,1); cfg->trackatt=(unsigned char *)calloc(32,1); - if (!cfg->name || !cfg->failatt || !cfg->trackatt) { + cfg->attributedefs=(unsigned char *)calloc(256,1); + if (!cfg->name || !cfg->failatt || !cfg->trackatt || !cfg->attributedefs) { printout(LOG_INFO,"No memory for %d'th device after %s, %s\n", i, name, strerror(errno)); exit(1); } diff --git a/sm5/smartd.cpp b/sm5/smartd.cpp index bdb9a9f9f08056cfa5a6de82fac1ba69efb4a1de..8215860cb88ed36c507dbfaf2f9610bfd727ff74 100644 --- a/sm5/smartd.cpp +++ b/sm5/smartd.cpp @@ -50,7 +50,7 @@ // CVS ID strings extern const char *CVSid1, *CVSid2; -const char *CVSid6="$Id: smartd.cpp,v 1.91 2003/01/03 12:23:41 pjwilliams Exp $" +const char *CVSid6="$Id: smartd.cpp,v 1.92 2003/01/03 17:25:12 ballen4705 Exp $" CVSID1 CVSID2 CVSID3 CVSID4 CVSID7; // global variable used for control of printing, passing arguments, etc. @@ -330,6 +330,7 @@ void Directives() { printout(LOG_INFO," -t Equivalent to -p and -u 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," -v N,ST Modifies labeling of Attribute N (see man page) \n"); printout(LOG_INFO," -a Equivalent to -H -f -t -l error -l selftest Directives\n"); printout(LOG_INFO," # Comment: text after a hash sign is ignored\n"); printout(LOG_INFO," \\ Line continuation character\n"); @@ -767,7 +768,7 @@ int ataCheckDevice(atadevices_t *drive){ char attname[64], *loc=attname; // get attribute name & skip white space - ataPrintSmartAttribName(loc, att); + ataPrintSmartAttribName(loc, att, con->attributedefs); while (*loc && *loc==' ') loc++; // warning message @@ -794,7 +795,7 @@ int ataCheckDevice(atadevices_t *drive){ if (!isattoff(id, cfg->trackatt, 0)){ // get attribute name, skip spaces - ataPrintSmartAttribName(loc, id); + ataPrintSmartAttribName(loc, id, con->attributedefs); while (*loc && *loc==' ') loc++; // prefailure attribute @@ -1147,18 +1148,37 @@ int parsetoken(char *token,cfgfile *cfg){ arg=strtok(NULL,delim); if (!arg) { printout(LOG_CRIT,"File %s line %d (drive %s): Directive: %s needs email address(es)\n", - CONFIGFILE, lineno, name, token); + CONFIGFILE, lineno, name, token); Directives(); exit(1); } if (!(cfg->address=strdup(arg))){ printout(LOG_CRIT,"File %s line %d (drive %s): Directive: %s: no free memory for email address(es) %s\n", - CONFIGFILE, lineno, name, token, arg); + CONFIGFILE, lineno, name, token, arg); + Directives(); + exit(1); + } + break; + case 'v': + // non-default vendor-specific attribute meaning + arg=strtok(NULL,delim); + if (!arg) { + // user forgot argument! + printout(LOG_CRIT,"File %s line %d (drive %s): Directive: %s needs attribute #,action pair\n", + CONFIGFILE, lineno, name, token); + Directives(); + exit(1); + } + if (parse_attribute_def(arg, cfg->attributedefs)){ + // user argument not recognized + printout(LOG_CRIT,"File %s line %d (drive %s): Directive: %s argument %s not recognized\n", + CONFIGFILE, lineno, name, token, arg); Directives(); exit(1); } break; default: + // Directive not recognized printout(LOG_CRIT,"File %s line %d (drive %s): unknown Directive: %s\n", CONFIGFILE, lineno, name, token); Directives(); @@ -1228,8 +1248,9 @@ int parseconfigline(int entry, int lineno,char *line){ cfg->name=strdup(name); cfg->failatt=(unsigned char *)calloc(32,1); cfg->trackatt=(unsigned char *)calloc(32,1); + cfg->attributedefs=(unsigned char *)calloc(256,1); - if (!cfg->name || !cfg->failatt || !cfg->trackatt) { + if (!cfg->name || !cfg->failatt || !cfg->trackatt || !cfg->attributedefs) { printout(LOG_INFO,"No memory to store file: %s line %d, %s\n", CONFIGFILE, lineno, strerror(errno)); exit(1); } @@ -1532,7 +1553,8 @@ int makeconfigentries(int num, char *name, int isata, int start){ cfg->name=strdup(name); cfg->failatt=(unsigned char *)calloc(32,1); cfg->trackatt=(unsigned char *)calloc(32,1); - if (!cfg->name || !cfg->failatt || !cfg->trackatt) { + cfg->attributedefs=(unsigned char *)calloc(256,1); + if (!cfg->name || !cfg->failatt || !cfg->trackatt || !cfg->attributedefs) { printout(LOG_INFO,"No memory for %d'th device after %s, %s\n", i, name, strerror(errno)); exit(1); } diff --git a/sm5/smartd.h b/sm5/smartd.h index be899539b9fa30b75ecb8ecb3887daf6e022d7ac..bbb4c1c48655e83026bdb052d4018eb4aeb5318d 100644 --- a/sm5/smartd.h +++ b/sm5/smartd.h @@ -23,7 +23,7 @@ */ #ifndef CVSID7 -#define CVSID7 "$Id: smartd.h,v 1.24 2002/11/23 17:06:45 pjwilliams Exp $\n" +#define CVSID7 "$Id: smartd.h,v 1.25 2003/01/03 17:25:13 ballen4705 Exp $\n" #endif // Configuration file @@ -102,6 +102,9 @@ typedef struct configfile_s { // valid attribute values are from 1 <= x <= 254 unsigned char *failatt; unsigned char *trackatt; + // See the end of extern.h for a definition of the array of 256 + // bytes that this points to. + unsigned char *attributedefs; } cfgfile;