diff --git a/sm5/atacmds.c b/sm5/atacmds.c index 2f4110459b89e2f8fdf5c1cd6c5ef44b2b4b6034..cc6f4df5d5f477362e52e302294e54de16a17b8f 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.46 2002/12/12 13:55:54 ballen4705 Exp $" CVSID1; +const char *CVSid1="$Id: atacmds.c,v 1.47 2002/12/19 00:05:19 pjwilliams 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,6 +116,13 @@ 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[] = { + "9,minutes", + NULL +}; + // A replacement for perror() that sends output to our choice of // printing. void syserror(const char *message){ diff --git a/sm5/atacmds.cpp b/sm5/atacmds.cpp index 48e5b6de00543e6b0de09550a76ca51f47652b94..c0c8cc92704ff1564158970195d4321d7859c9ce 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.46 2002/12/12 13:55:54 ballen4705 Exp $" CVSID1; +const char *CVSid1="$Id: atacmds.cpp,v 1.47 2002/12/19 00:05:19 pjwilliams 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,6 +116,13 @@ 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[] = { + "9,minutes", + NULL +}; + // A replacement for perror() that sends output to our choice of // printing. void syserror(const char *message){ diff --git a/sm5/atacmds.h b/sm5/atacmds.h index 267d567216e99ea58745ab0fbaa08fa5caa9103d..1cce29df38ee200bd9cc89cd79ad67929ad41046 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.26 2002/11/25 08:40:48 ballen4705 Exp $\n" +#define CVSID1 "$Id: atacmds.h,v 1.27 2002/12/19 00:05:19 pjwilliams Exp $\n" #endif // These are the major and minor versions for smartd and smartctl @@ -267,7 +267,9 @@ 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 *); diff --git a/sm5/ataprint.c b/sm5/ataprint.c index 25c5eadb48bb37947bb9540dadbf6e768a64e575..f27d915d3eaa99605084b2ecfff9f27c88df5441 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.48 2002/12/11 23:15:43 pjwilliams Exp $" +const char *CVSid2="$Id: ataprint.c,v 1.49 2002/12/19 00:05:19 pjwilliams Exp $" CVSID1 CVSID2 CVSID3 CVSID6; // for passing global control variables @@ -722,8 +722,7 @@ void failuretest(int type, int returnvalue){ // If this is an error in an "optional" SMART command if (type==OPTIONAL_CMD){ if (con->conservative){ - pout("An optional SMART command has failed: exiting. To continue, turn off the -%c option\n", - ULTRACONSERVATIVE); + pout("An optional SMART command has failed: exiting. To continue, set the tolerance level to something other than 'conservative'\n"); exit(returnvalue); } return; @@ -733,8 +732,7 @@ void failuretest(int type, int returnvalue){ if (type==MANDATORY_CMD){ if (con->permissive) return; - pout("A mandatory SMART command has failed: exiting. To continue, turn on the -%c option\n", - PERMISSIVE); + pout("A mandatory SMART command has failed: exiting. To continue, use the -T option to set the tolerance level to 'permissive'\n"); exit(returnvalue); } @@ -824,7 +822,7 @@ int ataPrintMain (int fd){ // From here on, every command requires that SMART be enabled... if (!ataDoesSmartWork(fd)) { - pout("SMART Disabled. Use option -%c to enable it.\n", (int)SMARTENABLE ); + pout("SMART Disabled. Use option -s with argument 'on' to enable it.\n"); return returnval; } @@ -834,7 +832,7 @@ int ataPrintMain (int fd){ pout( "Smartctl: SMART Disable Failed.\n\n"); failuretest(MANDATORY_CMD,returnval|=FAILSMART); } - pout("SMART Disabled. Use option -%c to enable it.\n",(int)SMARTENABLE); + pout("SMART Disabled. Use option -s with argument 'on' to enable it.\n"); return returnval; } @@ -1035,7 +1033,7 @@ int ataPrintMain (int fd){ (int)timewait, con->testcase==OFFLINE_FULL_SCAN?"seconds":"minutes"); if (con->testcase!=SHORT_CAPTIVE_SELF_TEST && con->testcase!=EXTEND_CAPTIVE_SELF_TEST) - pout("Use smartctl -%c to abort test.\n", (int)SMARTSELFTESTABORT); + pout("Use smartctl -X to abort test.\n"); } return returnval; } diff --git a/sm5/ataprint.cpp b/sm5/ataprint.cpp index 8b9e4a8cf00b0fa93886499f9b6394155d077ed5..af04d054c78a198027f0e8acefba9aa2c472d89e 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.48 2002/12/11 23:15:43 pjwilliams Exp $" +const char *CVSid2="$Id: ataprint.cpp,v 1.49 2002/12/19 00:05:19 pjwilliams Exp $" CVSID1 CVSID2 CVSID3 CVSID6; // for passing global control variables @@ -722,8 +722,7 @@ void failuretest(int type, int returnvalue){ // If this is an error in an "optional" SMART command if (type==OPTIONAL_CMD){ if (con->conservative){ - pout("An optional SMART command has failed: exiting. To continue, turn off the -%c option\n", - ULTRACONSERVATIVE); + pout("An optional SMART command has failed: exiting. To continue, set the tolerance level to something other than 'conservative'\n"); exit(returnvalue); } return; @@ -733,8 +732,7 @@ void failuretest(int type, int returnvalue){ if (type==MANDATORY_CMD){ if (con->permissive) return; - pout("A mandatory SMART command has failed: exiting. To continue, turn on the -%c option\n", - PERMISSIVE); + pout("A mandatory SMART command has failed: exiting. To continue, use the -T option to set the tolerance level to 'permissive'\n"); exit(returnvalue); } @@ -824,7 +822,7 @@ int ataPrintMain (int fd){ // From here on, every command requires that SMART be enabled... if (!ataDoesSmartWork(fd)) { - pout("SMART Disabled. Use option -%c to enable it.\n", (int)SMARTENABLE ); + pout("SMART Disabled. Use option -s with argument 'on' to enable it.\n"); return returnval; } @@ -834,7 +832,7 @@ int ataPrintMain (int fd){ pout( "Smartctl: SMART Disable Failed.\n\n"); failuretest(MANDATORY_CMD,returnval|=FAILSMART); } - pout("SMART Disabled. Use option -%c to enable it.\n",(int)SMARTENABLE); + pout("SMART Disabled. Use option -s with argument 'on' to enable it.\n"); return returnval; } @@ -1035,7 +1033,7 @@ int ataPrintMain (int fd){ (int)timewait, con->testcase==OFFLINE_FULL_SCAN?"seconds":"minutes"); if (con->testcase!=SHORT_CAPTIVE_SELF_TEST && con->testcase!=EXTEND_CAPTIVE_SELF_TEST) - pout("Use smartctl -%c to abort test.\n", (int)SMARTSELFTESTABORT); + pout("Use smartctl -X to abort test.\n"); } return returnval; } diff --git a/sm5/scsiprint.c b/sm5/scsiprint.c index f33e727d470c3c475107fd916413c8dc115efe54..3d6fec3ab9245448fcb82c8da95d89016e0104d2 100644 --- a/sm5/scsiprint.c +++ b/sm5/scsiprint.c @@ -36,7 +36,7 @@ #define GBUF_SIZE 65535 -const char* CVSid4="$Id: scsiprint.c,v 1.11 2002/11/17 05:57:32 ballen4705 Exp $" +const char* CVSid4="$Id: scsiprint.c,v 1.12 2002/12/19 00:05:19 pjwilliams Exp $" CVSID3 CVSID4 CVSID5 CVSID6; // control block which points to external global control variables @@ -340,7 +340,7 @@ void scsiPrintMain (char *device, int fd) } printf ("Drive Command Successful offline test has begun\n"); - printf ("Use smartctl -%c to abort test\n", SMARTSELFTESTABORT); + printf ("Use smartctl -X to abort test\n"); } @@ -353,7 +353,7 @@ void scsiPrintMain (char *device, int fd) exit(-1); } printf ("Drive Command Successful Short Self test has begun\n"); - printf ("Use smartctl -%c to abort test\n", SMARTSELFTESTABORT); + printf ("Use smartctl -X to abort test\n"); } if ( con->smartshortselftest ) @@ -365,7 +365,7 @@ void scsiPrintMain (char *device, int fd) exit(-1); } printf ("Drive Command Successful Short Self test has begun\n"); - printf ("Use smartctl -%c to abort test\n", SMARTSELFTESTABORT); + printf ("Use smartctl -X to abort test\n"); } if ( con->smartextendselftest ) @@ -377,7 +377,7 @@ void scsiPrintMain (char *device, int fd) } printf ("Drive Command Successful Extended Self test has begun\n"); - printf ("Use smartctl -%c to abort test\n", SMARTSELFTESTABORT); + printf ("Use smartctl -X to abort test\n"); } if ( con->smartextendcapselftest ) @@ -390,7 +390,7 @@ void scsiPrintMain (char *device, int fd) } printf ("Drive Command Successful Extended Self test has begun\n"); - printf ("Use smartctl -%c to abort test\n", SMARTSELFTESTABORT); + printf ("Use smartctl -X to abort test\n"); } if ( con->smartselftestabort ) diff --git a/sm5/scsiprint.cpp b/sm5/scsiprint.cpp index 7a6b239ac839be3c9f5244d8b3a94fafcd123974..040692aa798b0badccd8af0757b745f3c46ec649 100644 --- a/sm5/scsiprint.cpp +++ b/sm5/scsiprint.cpp @@ -36,7 +36,7 @@ #define GBUF_SIZE 65535 -const char* CVSid4="$Id: scsiprint.cpp,v 1.11 2002/11/17 05:57:32 ballen4705 Exp $" +const char* CVSid4="$Id: scsiprint.cpp,v 1.12 2002/12/19 00:05:19 pjwilliams Exp $" CVSID3 CVSID4 CVSID5 CVSID6; // control block which points to external global control variables @@ -340,7 +340,7 @@ void scsiPrintMain (char *device, int fd) } printf ("Drive Command Successful offline test has begun\n"); - printf ("Use smartctl -%c to abort test\n", SMARTSELFTESTABORT); + printf ("Use smartctl -X to abort test\n"); } @@ -353,7 +353,7 @@ void scsiPrintMain (char *device, int fd) exit(-1); } printf ("Drive Command Successful Short Self test has begun\n"); - printf ("Use smartctl -%c to abort test\n", SMARTSELFTESTABORT); + printf ("Use smartctl -X to abort test\n"); } if ( con->smartshortselftest ) @@ -365,7 +365,7 @@ void scsiPrintMain (char *device, int fd) exit(-1); } printf ("Drive Command Successful Short Self test has begun\n"); - printf ("Use smartctl -%c to abort test\n", SMARTSELFTESTABORT); + printf ("Use smartctl -X to abort test\n"); } if ( con->smartextendselftest ) @@ -377,7 +377,7 @@ void scsiPrintMain (char *device, int fd) } printf ("Drive Command Successful Extended Self test has begun\n"); - printf ("Use smartctl -%c to abort test\n", SMARTSELFTESTABORT); + printf ("Use smartctl -X to abort test\n"); } if ( con->smartextendcapselftest ) @@ -390,7 +390,7 @@ void scsiPrintMain (char *device, int fd) } printf ("Drive Command Successful Extended Self test has begun\n"); - printf ("Use smartctl -%c to abort test\n", SMARTSELFTESTABORT); + printf ("Use smartctl -X to abort test\n"); } if ( con->smartselftestabort ) diff --git a/sm5/smartctl.c b/sm5/smartctl.c index 77442a8cccc681b7c81811c86da1e989f714abf2..23f4db07edd70cc94aa6cad6d98d1555afaa0a69 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.30 2002/12/11 00:11:31 pjwilliams Exp $" +const char* CVSid5="$Id: smartctl.c,v 1.31 2002/12/19 00:05:19 pjwilliams Exp $" CVSID1 CVSID2 CVSID3 CVSID4 CVSID5 CVSID6; // This is a block containing all the "control variables". We declare @@ -78,82 +78,179 @@ void printcopy(){ } /* void prints help information for command syntax */ -void Usage ( void){ - printf("Usage: smartctl -[options] [device]\n"); +void Usage (void){ + printf("Usage: smartctl [options] [device]\n"); printf("\nShow Information Options:\n"); - printf(" %c Show Version, Copyright and License info\n", PRINTCOPYLEFT); - printf(" %c Show SMART Drive Info (ATA/SCSI)\n",DRIVEINFO); - printf(" %c Show all SMART Information (ATA/SCSI)\n",SMARTVERBOSEALL); - printf("\nRun-time Behavior Options:\n"); - printf(" %c Quiet: only show SMART Drive Errors (ATA Only)\n", QUIETMODE); - printf(" %c Very Quiet: no display, use Exit Status (ATA Only)\n", VERYQUIETMODE); - printf(" %c Device is an ATA Device (ATA Only)\n", NOTSCSIDEVICE); - printf(" %c Device is a SCSI Device (SCSI Only)\n", NOTATADEVICE); - printf(" %c Permissive: continue on Mandatory fails (ATA Only)\n", PERMISSIVE); - printf(" %c Conservative: exit if Optional Cmd fail (ATA Only)\n", ULTRACONSERVATIVE); - printf(" %c Warning: exit if Struct Checksum bad (ATA Only)\n", EXITCHECKSUMERROR); - printf("\nSMART Feature Enable/Disable Commands:\n"); - printf(" %c Enable SMART data collection (ATA/SCSI)\n", SMARTENABLE); - printf(" %c Disable SMART data collection (ATA/SCSI)\n", SMARTDISABLE); - printf(" %c Enable SMART Automatic Offline Test (ATA Only)\n", SMARTAUTOOFFLINEENABLE); - printf(" %c Disable SMART Automatic Offline Test (ATA Only)\n", SMARTAUTOOFFLINEDISABLE); - printf(" %c Enable SMART Attribute Autosave (ATA Only)\n", SMARTAUTOSAVEENABLE); - printf(" %c Disable SMART Attribute Autosave (ATA Only)\n", SMARTAUTOSAVEDISABLE); - printf("\nRead and Display Data Options:\n"); - printf(" %c Show SMART Status (ATA/SCSI)\n", CHECKSMART); - printf(" %c Show SMART General Attributes (ATA Only)\n", GENERALSMARTVALUES); - printf(" %c Show SMART Vendor Attributes (ATA Only)\n", SMARTVENDORATTRIB); - printf(" %c Show SMART Drive Error Log (ATA Only\n", SMARTERRORLOG); - printf(" %c Show SMART Drive Self Test Log (ATA Only)\n", SMARTSELFTESTLOG); - printf("\nVendor-specific Attribute Display Options:\n"); - printf(" %c Raw Attribute id=009 stored in minutes (ATA Only)\n", SMART009MINUTES); - printf("\nSelf-Test Options (no more than one):\n"); - printf(" %c Execute Off-line data collection (ATA/SCSI)\n", SMARTEXEOFFIMMEDIATE); - printf(" %c Execute Short Self Test (ATA/SCSI)\n", SMARTSHORTSELFTEST ); - printf(" %c Execute Short Self Test (Captive Mode) (ATA/SCSI)\n", SMARTSHORTCAPSELFTEST ); - printf(" %c Execute Extended Self Test (ATA/SCSI)\n", SMARTEXTENDSELFTEST ); - printf(" %c Execute Extended Self Test (Captive) (ATA/SCSI)\n", SMARTEXTENDCAPSELFTEST ); - printf(" %c Execute Self Test Abort (ATA/SCSI)\n", SMARTSELFTESTABORT ); - printf("\nExamples:\n"); - printf(" smartctl -etf /dev/hda (Enables SMART on first disk)\n"); - printf(" smartctl -a /dev/hda (Prints all SMART information)\n"); - printf(" smartctl -X /dev/hda (Executes extended disk self-test)\n"); - printf(" smartctl -qvL /dev/hda (Prints Self-Test & Attribute errors.)\n"); +#ifdef HAVE_GETOPT_LONG + printf("\ + -h, --help, --usage\n\ + Display this help and exit\n\ + -?\n\ + Same as -h\n\ + -V, --version, --copyright, --license\n\ + Print license, copyright, and version information\n\ + -i, --info (ATA/SCSI)\n\ + Show drive information\n\ + -a, --all (ATA/SCSI)\n\ + Show all SMART information for device\n\ +"); +#else + printf("\ + -h Display this help and exit\n\ + -? Same as -h\n\ + -V Print license, copyright, and version information\n\ + -i Show drive information (ATA/SCSI)\n\ + -a Show all SMART information for device (ATA/SCSI)\n\ +"); +#endif + printf("\n"); + printf("Run-time Behavior Options:\n"); +#ifdef HAVE_GETOPT_LONG + printf("\ + -q TYPE, --quietmode=TYPE (ATA)\n\ + Set the quiet mode to one of: errorsonly, silent\n\ + -d TYPE, --device=TYPE\n\ + Set the device type to one of: ata, scsi\n\ + -T TYPE, --tolerance=TYPE (ATA)\n\ + Set tolerance to one of: normal, conservative, permissive\n\ + -b TYPE, --badsum=TYPE (ATA)\n\ + Set action on bad checksum to one of: warn, exit, ignore\n\ +"); +#else + printf("\ + -q TYPE Set the quiet mode to one of: errorsonly, silent (ATA)\n\ + -d TYPE Set the device type to one of: ata, scsi\n\ + -T TYPE Set tolerance to one of: normal, conservative, permissive (ATA)\n\ + -b TYPE Set action on bad checksum to one of: warn, exit, ignore (ATA)\n\ +"); +#endif + printf("\n"); + printf("SMART Feature Enable/Disable Commands:\n"); +#ifdef HAVE_GETOPT_LONG + printf("\ + -s VALUE, --smart=VALUE (ATA/SCSI)\n\ + Enable/disable SMART (on/off)\n\ + -o VALUE, --offlineauto=VALUE (ATA)\n\ + Enable/disable automatic offline testing (on/off)\n\ + -S VALUE, --saveauto=VALUE (ATA)\n\ + Enable/disable attribute autosave (on/off)\n\ +"); +#else + printf("\ + -s VALUE Enable/disable SMART (on/off) (ATA/SCSI)\n\ + -o VALUE Enable/disable automatic offline testing (on/off) (ATA)\n\ + -S VALUE Enable/disable attribute autosave (on/off) (ATA)\n\ +"); +#endif + printf("\n"); + printf("Read and Display Data Options:\n"); +#ifdef HAVE_GETOPT_LONG + printf("\ + -H, --health (ATA/SCSI)\n\ + Show SMART health status\n\ + -c, --capabilities (ATA)\n\ + Show SMART capabilities\n\ + -A, --attributes (ATA)\n\ + Show SMART vendor-specific attributes and values\n\ + -l TYPE, --log=TYPE (ATA)\n\ + Show device log. Type is one of: error, selftest\n\ + -v N,OPTION , --vendorattribute=N,OPTION (ATA)\n\ + Set vendor specific OPTION for attribute N (see man page)\n\ +"); +#else + printf("\ + -H Show SMART health status (ATA/SCSI)\n\ + -c Show SMART capabilities (ATA)\n\ + -A Show SMART vendor-specific attributes and values (ATA)\n\ + -l TYPE Show device log. Type is one of: error, selftest (ATA)\n\ + -v N,OPT Set vendor specific OPTion for attribute N (see man page) (ATA)\n\ +"); +#endif + printf("\n"); + printf("Self-Test Options:\n"); +#ifdef HAVE_GETOPT_LONG + printf("\ + -t TEST, --test=TEST (ATA/SCSI)\n\ + Test immediately. TEST is one of: offline, short, long\n\ + -C, --captive (ATA/SCSI)\n\ + With -t, performs test in captive mode (short/long only)\n\ + -X, --abort (ATA/SCSI)\n\ + Abort any non-captive test\n\ +"); +#else + printf("\ + -t TEST Test immediately. TEST is one of: offline, short, long (ATA/SCSI)\n\ + -C With -t, performs test in captive mode (short/long only) (ATA/SCSI)\n\ + -X Abort any non-captive test (ATA/SCSI)\n\ +"); +#endif + printf("\n"); + printf("Examples:\n"); +#ifdef HAVE_GETOPT_LONG + printf("\ + smartctl -a /dev/hda\n\ + (Prints all SMART information)\n\ + smartctl --smart=on --offlineauto=on --saveauto=on /dev/hda\n\ + (Enables SMART on first disk)\n\ + smartctl -t long /dev/hda\n\ + (Executes extended disk self-test)\n\ + smartctl --attributes --log=selftest --quietmode=errorsonly /dev/hda\n\ + (Prints Self-Test & Attribute errors)\n\ +"); +#else + printf("\ + smartctl -a /dev/hda\n\ + (Prints all SMART information)\n\ + smartctl -s on -o on -S on /dev/hda\n\ + (Enables SMART on first disk)\n\ + smartctl -t long /dev/hda\n\ + (Executes extended disk self-test)\n\ + smartctl -A -l selftest -q errorsonly /dev/hda\n\ + (Prints Self-Test & Attribute errors)\n\ +"); +#endif } -const char shortopts[] = { - S_OPT_HELP, - S_OPT_ALT_HELP, - S_OPT_VERSION, - S_OPT_QUIETMODE, - ':', - S_OPT_DEVICE, - ':', - S_OPT_TOLERANCE, - ':', - S_OPT_BADSUM, - ':', - S_OPT_SMART, - ':', - S_OPT_OFFLINEAUTO, - ':', - S_OPT_SAVEAUTO, - ':', - S_OPT_HEALTH, - S_OPT_CAPABILITIES, - S_OPT_ATTRIBUTES, - S_OPT_LOG, - ':', - S_OPT_INFO, - S_OPT_ALL, - S_OPT_VENDORATTRIBUTE, - ':', - S_OPT_TEST, - ':', - S_OPT_CAPTIVE, - S_OPT_ABORT, - '\0' -}; +/* Print an appropriate error message for option opt when given an invalid argument, optarg */ +void printbadargmessage(int opt, const char *optarg) { + const char **ps; + + pout("=======> INVALID ARGUMENT: %s <======= \n", optarg); + pout("=======> VALID ARGUMENTS ARE: "); + switch (opt) { + case 'q': + pout("errorsonly, silent"); + break; + case 'd': + pout("ata, scsi"); + break; + case 'T': + pout("normal, conservative, permissive"); + break; + case 'b': + pout("warn, exit, ignore"); + break; + case 's': + case 'o': + case 'S': + pout("on, off"); + break; + case 'l': + pout("error, selftest"); + break; + case 'v': + // Print all strings in vendorattributeargs separated by commas. The + // strings themselves contain commas, so surrounding double quotes are used + // for clarity. + for (ps = vendorattributeargs; *ps != NULL; ps++) + pout("\"%s\"%s", *ps, *(ps+1) ? ", " : ""); + break; + case 't': + pout("offline, short, long"); + break; + } + pout(" <======= \n\n"); +} unsigned char printcopyleft=0,tryata=0,tryscsi=0; @@ -162,38 +259,36 @@ void ParseOpts (int argc, char** argv){ int optchar; int badarg; int captive; - struct { - int n; - char *option; - } vendorattribute; + 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"; #ifdef HAVE_GETOPT_LONG char *arg; struct option longopts[] = { - { L_OPT_HELP, no_argument, 0, S_OPT_HELP }, - { L_OPT_USAGE, no_argument, 0, S_OPT_HELP }, - { L_OPT_VERSION, no_argument, 0, S_OPT_VERSION }, - { L_OPT_COPYRIGHT, no_argument, 0, S_OPT_VERSION }, - { L_OPT_LICENSE, no_argument, 0, S_OPT_VERSION }, - { L_OPT_QUIETMODE, required_argument, 0, S_OPT_QUIETMODE }, - { L_OPT_DEVICE, required_argument, 0, S_OPT_DEVICE }, - { L_OPT_TOLERANCE, required_argument, 0, S_OPT_TOLERANCE }, - { L_OPT_BADSUM, required_argument, 0, S_OPT_BADSUM }, - { L_OPT_SMART, required_argument, 0, S_OPT_SMART }, - { L_OPT_OFFLINEAUTO, required_argument, 0, S_OPT_OFFLINEAUTO }, - { L_OPT_SAVEAUTO, required_argument, 0, S_OPT_SAVEAUTO }, - { L_OPT_HEALTH, no_argument, 0, S_OPT_HEALTH }, - { L_OPT_CAPABILITIES, no_argument, 0, S_OPT_CAPABILITIES }, - { L_OPT_ATTRIBUTES, no_argument, 0, S_OPT_ATTRIBUTES }, - { L_OPT_LOG, required_argument, 0, S_OPT_LOG }, - { L_OPT_INFO, no_argument, 0, S_OPT_INFO }, - { L_OPT_ALL, no_argument, 0, S_OPT_ALL }, - { L_OPT_VENDORATTRIBUTE, required_argument, 0, S_OPT_VENDORATTRIBUTE }, - { L_OPT_TEST, required_argument, 0, S_OPT_TEST }, - { L_OPT_CAPTIVE, no_argument, 0, S_OPT_CAPTIVE }, - { L_OPT_ABORT, no_argument, 0, S_OPT_ABORT }, - { 0, 0, 0, 0 } + { "help", no_argument, 0, 'h' }, + { "usage", no_argument, 0, 'h' }, + { "version", no_argument, 0, 'V' }, + { "copyright", no_argument, 0, 'V' }, + { "license", no_argument, 0, 'V' }, + { "quietmode", required_argument, 0, 'q' }, + { "device", required_argument, 0, 'd' }, + { "tolerance", required_argument, 0, 'T' }, + { "badsum", required_argument, 0, 'b' }, + { "smart", required_argument, 0, 's' }, + { "offlineauto", required_argument, 0, 'o' }, + { "saveauto", required_argument, 0, 'S' }, + { "health", no_argument, 0, 'H' }, + { "capabilities", no_argument, 0, 'c' }, + { "attributes", no_argument, 0, 'A' }, + { "log", required_argument, 0, 'l' }, + { "info", no_argument, 0, 'i' }, + { "all", no_argument, 0, 'a' }, + { "vendorattribute", required_argument, 0, 'v' }, + { "test", required_argument, 0, 't' }, + { "captive", no_argument, 0, 'C' }, + { "abort", no_argument, 0, 'X' }, + { 0, 0, 0, 0 } }; #endif @@ -207,10 +302,10 @@ void ParseOpts (int argc, char** argv){ while (-1 != (optchar = getopt(argc, argv, shortopts))) { #endif switch (optchar){ - case S_OPT_VERSION: + case 'V': printcopyleft=TRUE; break; - case S_OPT_QUIETMODE: + case 'q': if (!strcmp(optarg,"errorsonly")) { con->quietmode = TRUE; con->veryquietmode = FALSE; @@ -221,7 +316,7 @@ void ParseOpts (int argc, char** argv){ badarg = TRUE; } break; - case S_OPT_DEVICE: + case 'd': if (!strcmp(optarg,"ata")) { tryata = TRUE; tryscsi = FALSE; @@ -232,7 +327,7 @@ void ParseOpts (int argc, char** argv){ badarg = TRUE; } break; - case S_OPT_TOLERANCE: + case 'T': if (!strcmp(optarg,"normal")) { con->conservative = FALSE; con->permissive = FALSE; @@ -246,7 +341,7 @@ void ParseOpts (int argc, char** argv){ badarg = TRUE; } break; - case S_OPT_BADSUM: + case 'b': if (!strcmp(optarg,"warn")) { con->checksumfail = FALSE; con->checksumignore = FALSE; @@ -260,7 +355,7 @@ void ParseOpts (int argc, char** argv){ badarg = TRUE; } break; - case S_OPT_SMART: + case 's': if (!strcmp(optarg,"on")) { con->smartenable = TRUE; con->smartdisable = FALSE; @@ -271,7 +366,7 @@ void ParseOpts (int argc, char** argv){ badarg = TRUE; } break; - case S_OPT_OFFLINEAUTO: + case 'o': if (!strcmp(optarg,"on")) { con->smartautoofflineenable = TRUE; con->smartautoofflinedisable = FALSE; @@ -282,7 +377,7 @@ void ParseOpts (int argc, char** argv){ badarg = TRUE; } break; - case S_OPT_SAVEAUTO: + case 'S': if (!strcmp(optarg,"on")) { con->smartautosaveenable = TRUE; con->smartautosavedisable = FALSE; @@ -293,16 +388,16 @@ void ParseOpts (int argc, char** argv){ badarg = TRUE; } break; - case S_OPT_HEALTH: + case 'H': con->checksmart = TRUE; break; - case S_OPT_CAPABILITIES: + case 'c': con->generalsmartvalues = TRUE; break; - case S_OPT_ATTRIBUTES: + case 'A': con->smartvendorattrib = TRUE; break; - case S_OPT_LOG: + case 'l': if (!strcmp(optarg,"error")) { con->smarterrorlog = TRUE; } else if (!strcmp(optarg,"selftest")) { @@ -311,10 +406,10 @@ void ParseOpts (int argc, char** argv){ badarg = TRUE; } break; - case S_OPT_INFO: + case 'i': con->driveinfo = TRUE; break; - case S_OPT_ALL: + case 'a': con->driveinfo = TRUE; con->checksmart = TRUE; con->generalsmartvalues = TRUE; @@ -322,20 +417,19 @@ void ParseOpts (int argc, char** argv){ con->smarterrorlog = TRUE; con->smartselftestlog = TRUE; break; - case S_OPT_VENDORATTRIBUTE: - vendorattribute.option = (char *)malloc(strlen(optarg)+1); - if (sscanf(optarg,"%u,%s",&(vendorattribute.n),vendorattribute.option) != 2) { - badarg = TRUE; - } - if (vendorattribute.n == 9 && !strcmp(vendorattribute.option,"minutes")) { - con->smart009minutes=TRUE; - } else { - // Should handle this better + case 'v': + for (i=0; vendorattributeargs[i] && strcmp(optarg,vendorattributeargs[i]); i++) + ; + switch (i) { + case 0: + con->smart009minutes = TRUE; + break; + default: badarg = TRUE; + break; } - free(vendorattribute.option); break; - case S_OPT_TEST: + case 't': if (!strcmp(optarg,"offline")) { con->smartexeoffimmediate = TRUE; con->testcase = OFFLINE_FULL_SCAN; @@ -349,23 +443,23 @@ void ParseOpts (int argc, char** argv){ badarg = TRUE; } break; - case S_OPT_CAPTIVE: + case 'C': captive = TRUE; break; - case S_OPT_ABORT: + case 'X': con->smartselftestabort = TRUE; con->testcase = ABORT_SELF_TEST; break; - case S_OPT_HELP: - case S_OPT_ALT_HELP: + case 'h': + case '?': default: con->veryquietmode=FALSE; printslogan(); #ifdef HAVE_GETOPT_LONG // Point arg to the argument in which this option was found. arg = argv[optind-1]; - // Check whether the option is a long option and options that map to -h. - if (arg[1] == '-' && optchar != S_OPT_HELP) { + // Check whether the option is a long option that doesn't map to -h. + if (arg[1] == '-' && optchar != 'h') { // Iff optopt holds a valid option then argument must be missing. if (optopt && (strchr(shortopts, optopt) != NULL)) { pout("=======> ARGUMENT REQUIRED FOR OPTION: %s <=======\n\n",arg+2); @@ -390,7 +484,7 @@ void ParseOpts (int argc, char** argv){ exit(0); } if (badarg) { - pout("=======> INVALID ARGUMENT: %s <======= \n\n",optarg); + printbadargmessage(optchar, optarg); Usage(); exit(FAILCMD); } @@ -502,8 +596,7 @@ int main (int argc, char **argv){ else if (tryscsi) scsiPrintMain (device, fd); else { - pout("Smartctl: specify if this is an ATA or SCSI device with the -%c or -%c options respectively.\n", - NOTSCSIDEVICE, NOTATADEVICE); + pout("Smartctl: specify if this is an ATA or SCSI device with the -d option.\n"); Usage(); return FAILCMD; } diff --git a/sm5/smartctl.cpp b/sm5/smartctl.cpp index c214dc0a1777ac0f29f9ea61728dad2546a81f42..43fe2c87dc10e65a208c33d9bf90140a6d8a8b41 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.30 2002/12/11 00:11:31 pjwilliams Exp $" +const char* CVSid5="$Id: smartctl.cpp,v 1.31 2002/12/19 00:05:19 pjwilliams Exp $" CVSID1 CVSID2 CVSID3 CVSID4 CVSID5 CVSID6; // This is a block containing all the "control variables". We declare @@ -78,82 +78,179 @@ void printcopy(){ } /* void prints help information for command syntax */ -void Usage ( void){ - printf("Usage: smartctl -[options] [device]\n"); +void Usage (void){ + printf("Usage: smartctl [options] [device]\n"); printf("\nShow Information Options:\n"); - printf(" %c Show Version, Copyright and License info\n", PRINTCOPYLEFT); - printf(" %c Show SMART Drive Info (ATA/SCSI)\n",DRIVEINFO); - printf(" %c Show all SMART Information (ATA/SCSI)\n",SMARTVERBOSEALL); - printf("\nRun-time Behavior Options:\n"); - printf(" %c Quiet: only show SMART Drive Errors (ATA Only)\n", QUIETMODE); - printf(" %c Very Quiet: no display, use Exit Status (ATA Only)\n", VERYQUIETMODE); - printf(" %c Device is an ATA Device (ATA Only)\n", NOTSCSIDEVICE); - printf(" %c Device is a SCSI Device (SCSI Only)\n", NOTATADEVICE); - printf(" %c Permissive: continue on Mandatory fails (ATA Only)\n", PERMISSIVE); - printf(" %c Conservative: exit if Optional Cmd fail (ATA Only)\n", ULTRACONSERVATIVE); - printf(" %c Warning: exit if Struct Checksum bad (ATA Only)\n", EXITCHECKSUMERROR); - printf("\nSMART Feature Enable/Disable Commands:\n"); - printf(" %c Enable SMART data collection (ATA/SCSI)\n", SMARTENABLE); - printf(" %c Disable SMART data collection (ATA/SCSI)\n", SMARTDISABLE); - printf(" %c Enable SMART Automatic Offline Test (ATA Only)\n", SMARTAUTOOFFLINEENABLE); - printf(" %c Disable SMART Automatic Offline Test (ATA Only)\n", SMARTAUTOOFFLINEDISABLE); - printf(" %c Enable SMART Attribute Autosave (ATA Only)\n", SMARTAUTOSAVEENABLE); - printf(" %c Disable SMART Attribute Autosave (ATA Only)\n", SMARTAUTOSAVEDISABLE); - printf("\nRead and Display Data Options:\n"); - printf(" %c Show SMART Status (ATA/SCSI)\n", CHECKSMART); - printf(" %c Show SMART General Attributes (ATA Only)\n", GENERALSMARTVALUES); - printf(" %c Show SMART Vendor Attributes (ATA Only)\n", SMARTVENDORATTRIB); - printf(" %c Show SMART Drive Error Log (ATA Only\n", SMARTERRORLOG); - printf(" %c Show SMART Drive Self Test Log (ATA Only)\n", SMARTSELFTESTLOG); - printf("\nVendor-specific Attribute Display Options:\n"); - printf(" %c Raw Attribute id=009 stored in minutes (ATA Only)\n", SMART009MINUTES); - printf("\nSelf-Test Options (no more than one):\n"); - printf(" %c Execute Off-line data collection (ATA/SCSI)\n", SMARTEXEOFFIMMEDIATE); - printf(" %c Execute Short Self Test (ATA/SCSI)\n", SMARTSHORTSELFTEST ); - printf(" %c Execute Short Self Test (Captive Mode) (ATA/SCSI)\n", SMARTSHORTCAPSELFTEST ); - printf(" %c Execute Extended Self Test (ATA/SCSI)\n", SMARTEXTENDSELFTEST ); - printf(" %c Execute Extended Self Test (Captive) (ATA/SCSI)\n", SMARTEXTENDCAPSELFTEST ); - printf(" %c Execute Self Test Abort (ATA/SCSI)\n", SMARTSELFTESTABORT ); - printf("\nExamples:\n"); - printf(" smartctl -etf /dev/hda (Enables SMART on first disk)\n"); - printf(" smartctl -a /dev/hda (Prints all SMART information)\n"); - printf(" smartctl -X /dev/hda (Executes extended disk self-test)\n"); - printf(" smartctl -qvL /dev/hda (Prints Self-Test & Attribute errors.)\n"); +#ifdef HAVE_GETOPT_LONG + printf("\ + -h, --help, --usage\n\ + Display this help and exit\n\ + -?\n\ + Same as -h\n\ + -V, --version, --copyright, --license\n\ + Print license, copyright, and version information\n\ + -i, --info (ATA/SCSI)\n\ + Show drive information\n\ + -a, --all (ATA/SCSI)\n\ + Show all SMART information for device\n\ +"); +#else + printf("\ + -h Display this help and exit\n\ + -? Same as -h\n\ + -V Print license, copyright, and version information\n\ + -i Show drive information (ATA/SCSI)\n\ + -a Show all SMART information for device (ATA/SCSI)\n\ +"); +#endif + printf("\n"); + printf("Run-time Behavior Options:\n"); +#ifdef HAVE_GETOPT_LONG + printf("\ + -q TYPE, --quietmode=TYPE (ATA)\n\ + Set the quiet mode to one of: errorsonly, silent\n\ + -d TYPE, --device=TYPE\n\ + Set the device type to one of: ata, scsi\n\ + -T TYPE, --tolerance=TYPE (ATA)\n\ + Set tolerance to one of: normal, conservative, permissive\n\ + -b TYPE, --badsum=TYPE (ATA)\n\ + Set action on bad checksum to one of: warn, exit, ignore\n\ +"); +#else + printf("\ + -q TYPE Set the quiet mode to one of: errorsonly, silent (ATA)\n\ + -d TYPE Set the device type to one of: ata, scsi\n\ + -T TYPE Set tolerance to one of: normal, conservative, permissive (ATA)\n\ + -b TYPE Set action on bad checksum to one of: warn, exit, ignore (ATA)\n\ +"); +#endif + printf("\n"); + printf("SMART Feature Enable/Disable Commands:\n"); +#ifdef HAVE_GETOPT_LONG + printf("\ + -s VALUE, --smart=VALUE (ATA/SCSI)\n\ + Enable/disable SMART (on/off)\n\ + -o VALUE, --offlineauto=VALUE (ATA)\n\ + Enable/disable automatic offline testing (on/off)\n\ + -S VALUE, --saveauto=VALUE (ATA)\n\ + Enable/disable attribute autosave (on/off)\n\ +"); +#else + printf("\ + -s VALUE Enable/disable SMART (on/off) (ATA/SCSI)\n\ + -o VALUE Enable/disable automatic offline testing (on/off) (ATA)\n\ + -S VALUE Enable/disable attribute autosave (on/off) (ATA)\n\ +"); +#endif + printf("\n"); + printf("Read and Display Data Options:\n"); +#ifdef HAVE_GETOPT_LONG + printf("\ + -H, --health (ATA/SCSI)\n\ + Show SMART health status\n\ + -c, --capabilities (ATA)\n\ + Show SMART capabilities\n\ + -A, --attributes (ATA)\n\ + Show SMART vendor-specific attributes and values\n\ + -l TYPE, --log=TYPE (ATA)\n\ + Show device log. Type is one of: error, selftest\n\ + -v N,OPTION , --vendorattribute=N,OPTION (ATA)\n\ + Set vendor specific OPTION for attribute N (see man page)\n\ +"); +#else + printf("\ + -H Show SMART health status (ATA/SCSI)\n\ + -c Show SMART capabilities (ATA)\n\ + -A Show SMART vendor-specific attributes and values (ATA)\n\ + -l TYPE Show device log. Type is one of: error, selftest (ATA)\n\ + -v N,OPT Set vendor specific OPTion for attribute N (see man page) (ATA)\n\ +"); +#endif + printf("\n"); + printf("Self-Test Options:\n"); +#ifdef HAVE_GETOPT_LONG + printf("\ + -t TEST, --test=TEST (ATA/SCSI)\n\ + Test immediately. TEST is one of: offline, short, long\n\ + -C, --captive (ATA/SCSI)\n\ + With -t, performs test in captive mode (short/long only)\n\ + -X, --abort (ATA/SCSI)\n\ + Abort any non-captive test\n\ +"); +#else + printf("\ + -t TEST Test immediately. TEST is one of: offline, short, long (ATA/SCSI)\n\ + -C With -t, performs test in captive mode (short/long only) (ATA/SCSI)\n\ + -X Abort any non-captive test (ATA/SCSI)\n\ +"); +#endif + printf("\n"); + printf("Examples:\n"); +#ifdef HAVE_GETOPT_LONG + printf("\ + smartctl -a /dev/hda\n\ + (Prints all SMART information)\n\ + smartctl --smart=on --offlineauto=on --saveauto=on /dev/hda\n\ + (Enables SMART on first disk)\n\ + smartctl -t long /dev/hda\n\ + (Executes extended disk self-test)\n\ + smartctl --attributes --log=selftest --quietmode=errorsonly /dev/hda\n\ + (Prints Self-Test & Attribute errors)\n\ +"); +#else + printf("\ + smartctl -a /dev/hda\n\ + (Prints all SMART information)\n\ + smartctl -s on -o on -S on /dev/hda\n\ + (Enables SMART on first disk)\n\ + smartctl -t long /dev/hda\n\ + (Executes extended disk self-test)\n\ + smartctl -A -l selftest -q errorsonly /dev/hda\n\ + (Prints Self-Test & Attribute errors)\n\ +"); +#endif } -const char shortopts[] = { - S_OPT_HELP, - S_OPT_ALT_HELP, - S_OPT_VERSION, - S_OPT_QUIETMODE, - ':', - S_OPT_DEVICE, - ':', - S_OPT_TOLERANCE, - ':', - S_OPT_BADSUM, - ':', - S_OPT_SMART, - ':', - S_OPT_OFFLINEAUTO, - ':', - S_OPT_SAVEAUTO, - ':', - S_OPT_HEALTH, - S_OPT_CAPABILITIES, - S_OPT_ATTRIBUTES, - S_OPT_LOG, - ':', - S_OPT_INFO, - S_OPT_ALL, - S_OPT_VENDORATTRIBUTE, - ':', - S_OPT_TEST, - ':', - S_OPT_CAPTIVE, - S_OPT_ABORT, - '\0' -}; +/* Print an appropriate error message for option opt when given an invalid argument, optarg */ +void printbadargmessage(int opt, const char *optarg) { + const char **ps; + + pout("=======> INVALID ARGUMENT: %s <======= \n", optarg); + pout("=======> VALID ARGUMENTS ARE: "); + switch (opt) { + case 'q': + pout("errorsonly, silent"); + break; + case 'd': + pout("ata, scsi"); + break; + case 'T': + pout("normal, conservative, permissive"); + break; + case 'b': + pout("warn, exit, ignore"); + break; + case 's': + case 'o': + case 'S': + pout("on, off"); + break; + case 'l': + pout("error, selftest"); + break; + case 'v': + // Print all strings in vendorattributeargs separated by commas. The + // strings themselves contain commas, so surrounding double quotes are used + // for clarity. + for (ps = vendorattributeargs; *ps != NULL; ps++) + pout("\"%s\"%s", *ps, *(ps+1) ? ", " : ""); + break; + case 't': + pout("offline, short, long"); + break; + } + pout(" <======= \n\n"); +} unsigned char printcopyleft=0,tryata=0,tryscsi=0; @@ -162,38 +259,36 @@ void ParseOpts (int argc, char** argv){ int optchar; int badarg; int captive; - struct { - int n; - char *option; - } vendorattribute; + 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"; #ifdef HAVE_GETOPT_LONG char *arg; struct option longopts[] = { - { L_OPT_HELP, no_argument, 0, S_OPT_HELP }, - { L_OPT_USAGE, no_argument, 0, S_OPT_HELP }, - { L_OPT_VERSION, no_argument, 0, S_OPT_VERSION }, - { L_OPT_COPYRIGHT, no_argument, 0, S_OPT_VERSION }, - { L_OPT_LICENSE, no_argument, 0, S_OPT_VERSION }, - { L_OPT_QUIETMODE, required_argument, 0, S_OPT_QUIETMODE }, - { L_OPT_DEVICE, required_argument, 0, S_OPT_DEVICE }, - { L_OPT_TOLERANCE, required_argument, 0, S_OPT_TOLERANCE }, - { L_OPT_BADSUM, required_argument, 0, S_OPT_BADSUM }, - { L_OPT_SMART, required_argument, 0, S_OPT_SMART }, - { L_OPT_OFFLINEAUTO, required_argument, 0, S_OPT_OFFLINEAUTO }, - { L_OPT_SAVEAUTO, required_argument, 0, S_OPT_SAVEAUTO }, - { L_OPT_HEALTH, no_argument, 0, S_OPT_HEALTH }, - { L_OPT_CAPABILITIES, no_argument, 0, S_OPT_CAPABILITIES }, - { L_OPT_ATTRIBUTES, no_argument, 0, S_OPT_ATTRIBUTES }, - { L_OPT_LOG, required_argument, 0, S_OPT_LOG }, - { L_OPT_INFO, no_argument, 0, S_OPT_INFO }, - { L_OPT_ALL, no_argument, 0, S_OPT_ALL }, - { L_OPT_VENDORATTRIBUTE, required_argument, 0, S_OPT_VENDORATTRIBUTE }, - { L_OPT_TEST, required_argument, 0, S_OPT_TEST }, - { L_OPT_CAPTIVE, no_argument, 0, S_OPT_CAPTIVE }, - { L_OPT_ABORT, no_argument, 0, S_OPT_ABORT }, - { 0, 0, 0, 0 } + { "help", no_argument, 0, 'h' }, + { "usage", no_argument, 0, 'h' }, + { "version", no_argument, 0, 'V' }, + { "copyright", no_argument, 0, 'V' }, + { "license", no_argument, 0, 'V' }, + { "quietmode", required_argument, 0, 'q' }, + { "device", required_argument, 0, 'd' }, + { "tolerance", required_argument, 0, 'T' }, + { "badsum", required_argument, 0, 'b' }, + { "smart", required_argument, 0, 's' }, + { "offlineauto", required_argument, 0, 'o' }, + { "saveauto", required_argument, 0, 'S' }, + { "health", no_argument, 0, 'H' }, + { "capabilities", no_argument, 0, 'c' }, + { "attributes", no_argument, 0, 'A' }, + { "log", required_argument, 0, 'l' }, + { "info", no_argument, 0, 'i' }, + { "all", no_argument, 0, 'a' }, + { "vendorattribute", required_argument, 0, 'v' }, + { "test", required_argument, 0, 't' }, + { "captive", no_argument, 0, 'C' }, + { "abort", no_argument, 0, 'X' }, + { 0, 0, 0, 0 } }; #endif @@ -207,10 +302,10 @@ void ParseOpts (int argc, char** argv){ while (-1 != (optchar = getopt(argc, argv, shortopts))) { #endif switch (optchar){ - case S_OPT_VERSION: + case 'V': printcopyleft=TRUE; break; - case S_OPT_QUIETMODE: + case 'q': if (!strcmp(optarg,"errorsonly")) { con->quietmode = TRUE; con->veryquietmode = FALSE; @@ -221,7 +316,7 @@ void ParseOpts (int argc, char** argv){ badarg = TRUE; } break; - case S_OPT_DEVICE: + case 'd': if (!strcmp(optarg,"ata")) { tryata = TRUE; tryscsi = FALSE; @@ -232,7 +327,7 @@ void ParseOpts (int argc, char** argv){ badarg = TRUE; } break; - case S_OPT_TOLERANCE: + case 'T': if (!strcmp(optarg,"normal")) { con->conservative = FALSE; con->permissive = FALSE; @@ -246,7 +341,7 @@ void ParseOpts (int argc, char** argv){ badarg = TRUE; } break; - case S_OPT_BADSUM: + case 'b': if (!strcmp(optarg,"warn")) { con->checksumfail = FALSE; con->checksumignore = FALSE; @@ -260,7 +355,7 @@ void ParseOpts (int argc, char** argv){ badarg = TRUE; } break; - case S_OPT_SMART: + case 's': if (!strcmp(optarg,"on")) { con->smartenable = TRUE; con->smartdisable = FALSE; @@ -271,7 +366,7 @@ void ParseOpts (int argc, char** argv){ badarg = TRUE; } break; - case S_OPT_OFFLINEAUTO: + case 'o': if (!strcmp(optarg,"on")) { con->smartautoofflineenable = TRUE; con->smartautoofflinedisable = FALSE; @@ -282,7 +377,7 @@ void ParseOpts (int argc, char** argv){ badarg = TRUE; } break; - case S_OPT_SAVEAUTO: + case 'S': if (!strcmp(optarg,"on")) { con->smartautosaveenable = TRUE; con->smartautosavedisable = FALSE; @@ -293,16 +388,16 @@ void ParseOpts (int argc, char** argv){ badarg = TRUE; } break; - case S_OPT_HEALTH: + case 'H': con->checksmart = TRUE; break; - case S_OPT_CAPABILITIES: + case 'c': con->generalsmartvalues = TRUE; break; - case S_OPT_ATTRIBUTES: + case 'A': con->smartvendorattrib = TRUE; break; - case S_OPT_LOG: + case 'l': if (!strcmp(optarg,"error")) { con->smarterrorlog = TRUE; } else if (!strcmp(optarg,"selftest")) { @@ -311,10 +406,10 @@ void ParseOpts (int argc, char** argv){ badarg = TRUE; } break; - case S_OPT_INFO: + case 'i': con->driveinfo = TRUE; break; - case S_OPT_ALL: + case 'a': con->driveinfo = TRUE; con->checksmart = TRUE; con->generalsmartvalues = TRUE; @@ -322,20 +417,19 @@ void ParseOpts (int argc, char** argv){ con->smarterrorlog = TRUE; con->smartselftestlog = TRUE; break; - case S_OPT_VENDORATTRIBUTE: - vendorattribute.option = (char *)malloc(strlen(optarg)+1); - if (sscanf(optarg,"%u,%s",&(vendorattribute.n),vendorattribute.option) != 2) { - badarg = TRUE; - } - if (vendorattribute.n == 9 && !strcmp(vendorattribute.option,"minutes")) { - con->smart009minutes=TRUE; - } else { - // Should handle this better + case 'v': + for (i=0; vendorattributeargs[i] && strcmp(optarg,vendorattributeargs[i]); i++) + ; + switch (i) { + case 0: + con->smart009minutes = TRUE; + break; + default: badarg = TRUE; + break; } - free(vendorattribute.option); break; - case S_OPT_TEST: + case 't': if (!strcmp(optarg,"offline")) { con->smartexeoffimmediate = TRUE; con->testcase = OFFLINE_FULL_SCAN; @@ -349,23 +443,23 @@ void ParseOpts (int argc, char** argv){ badarg = TRUE; } break; - case S_OPT_CAPTIVE: + case 'C': captive = TRUE; break; - case S_OPT_ABORT: + case 'X': con->smartselftestabort = TRUE; con->testcase = ABORT_SELF_TEST; break; - case S_OPT_HELP: - case S_OPT_ALT_HELP: + case 'h': + case '?': default: con->veryquietmode=FALSE; printslogan(); #ifdef HAVE_GETOPT_LONG // Point arg to the argument in which this option was found. arg = argv[optind-1]; - // Check whether the option is a long option and options that map to -h. - if (arg[1] == '-' && optchar != S_OPT_HELP) { + // Check whether the option is a long option that doesn't map to -h. + if (arg[1] == '-' && optchar != 'h') { // Iff optopt holds a valid option then argument must be missing. if (optopt && (strchr(shortopts, optopt) != NULL)) { pout("=======> ARGUMENT REQUIRED FOR OPTION: %s <=======\n\n",arg+2); @@ -390,7 +484,7 @@ void ParseOpts (int argc, char** argv){ exit(0); } if (badarg) { - pout("=======> INVALID ARGUMENT: %s <======= \n\n",optarg); + printbadargmessage(optchar, optarg); Usage(); exit(FAILCMD); } @@ -502,8 +596,7 @@ int main (int argc, char **argv){ else if (tryscsi) scsiPrintMain (device, fd); else { - pout("Smartctl: specify if this is an ATA or SCSI device with the -%c or -%c options respectively.\n", - NOTSCSIDEVICE, NOTATADEVICE); + pout("Smartctl: specify if this is an ATA or SCSI device with the -d option.\n"); Usage(); return FAILCMD; } diff --git a/sm5/smartctl.h b/sm5/smartctl.h index 79e3eec7d3109fd27ea8e01df68b7567728f58bc..7305c91032a5938d7723ff776def623e4f6cd73c 100644 --- a/sm5/smartctl.h +++ b/sm5/smartctl.h @@ -26,85 +26,9 @@ #define __SMARTCTL_H_ #ifndef CVSID6 -#define CVSID6 "$Id: smartctl.h,v 1.14 2002/12/11 00:11:31 pjwilliams Exp $\n" +#define CVSID6 "$Id: smartctl.h,v 1.15 2002/12/19 00:05:19 pjwilliams Exp $\n" #endif -/* Defines for command line options */ -#define DRIVEINFO 'i' -#define CHECKSMART 'c' -#define SMARTVERBOSEALL 'a' -#define SMARTVENDORATTRIB 'v' -#define GENERALSMARTVALUES 'g' -#define SMARTERRORLOG 'l' -#define SMARTSELFTESTLOG 'L' -#define SMARTDISABLE 'd' -#define SMARTENABLE 'e' -#define SMARTEXEOFFIMMEDIATE 'O' -#define SMARTSHORTSELFTEST 'S' -#define SMARTEXTENDSELFTEST 'X' -#define SMARTSHORTCAPSELFTEST 's' -#define SMARTEXTENDCAPSELFTEST 'x' -#define SMARTSELFTESTABORT 'A' -#define SMARTAUTOOFFLINEENABLE 't' -#define SMARTAUTOOFFLINEDISABLE 'T' -#define SMARTAUTOSAVEENABLE 'f' -#define SMARTAUTOSAVEDISABLE 'F' -#define PRINTCOPYLEFT 'V' -#define SMART009MINUTES 'm' -#define QUIETMODE 'q' -#define VERYQUIETMODE 'Q' -#define NOTATADEVICE 'N' -#define NOTSCSIDEVICE 'n' -#define EXITCHECKSUMERROR 'W' -#define ULTRACONSERVATIVE 'U' -#define PERMISSIVE 'P' - -#define S_OPT_HELP 'h' -#define S_OPT_ALT_HELP '?' -#define S_OPT_VERSION 'V' -#define S_OPT_QUIETMODE 'q' -#define S_OPT_DEVICE 'd' -#define S_OPT_TOLERANCE 'T' -#define S_OPT_BADSUM 'b' -#define S_OPT_SMART 's' -#define S_OPT_OFFLINEAUTO 'o' -#define S_OPT_SAVEAUTO 'S' -#define S_OPT_HEALTH 'H' -#define S_OPT_CAPABILITIES 'c' -#define S_OPT_ATTRIBUTES 'A' -#define S_OPT_LOG 'l' -#define S_OPT_INFO 'i' -#define S_OPT_ALL 'a' -#define S_OPT_VENDORATTRIBUTE 'v' -#define S_OPT_TEST 't' -#define S_OPT_CAPTIVE 'C' -#define S_OPT_ABORT 'X' -#ifdef HAVE_GETOPT_LONG -#define L_OPT_HELP "help" -#define L_OPT_USAGE "usage" -#define L_OPT_VERSION "version" -#define L_OPT_COPYRIGHT "copyright" -#define L_OPT_LICENSE "license" -#define L_OPT_QUIETMODE "quietmode" -#define L_OPT_DEVICE "device" -#define L_OPT_TOLERANCE "tolerance" -#define L_OPT_BADSUM "badsum" -#define L_OPT_SMART "smart" -#define L_OPT_OFFLINEAUTO "offlineauto" -#define L_OPT_SAVEAUTO "saveauto" -#define L_OPT_HEALTH "health" -#define L_OPT_CAPABILITIES "capabilities" -#define L_OPT_ATTRIBUTES "attributes" -#define L_OPT_LOG "log" -#define L_OPT_INFO "info" -#define L_OPT_ALL "all" -#define L_OPT_VENDORATTRIBUTE "vendorattribute" -#define L_OPT_TEST "test" -#define L_OPT_CAPTIVE "captive" -#define L_OPT_ABORT "abort" -#endif - - /* Boolean Values */ #define TRUE 0x01 #define FALSE 0x00