From e2a9f170a10bb160933054f3e1f25e35b2a78f56 Mon Sep 17 00:00:00 2001 From: pjwilliams <pjwilliams@4ea69e1a-61f1-4043-bf83-b5c94c648137> Date: Tue, 7 Jan 2003 00:27:16 +0000 Subject: [PATCH] Print valid arguments if user omits a required option argument in smartctl git-svn-id: https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/trunk@437 4ea69e1a-61f1-4043-bf83-b5c94c648137 --- sm5/smartctl.c | 84 +++++++++++++++++++++++++----------------------- sm5/smartctl.cpp | 84 +++++++++++++++++++++++++----------------------- 2 files changed, 88 insertions(+), 80 deletions(-) diff --git a/sm5/smartctl.c b/sm5/smartctl.c index 66bdb47b5..338e50002 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.43 2003/01/05 20:05:32 pjwilliams Exp $" +const char* CVSid5="$Id: smartctl.c,v 1.44 2003/01/07 00:27:16 pjwilliams Exp $" CVSID1 CVSID2 CVSID3 CVSID4 CVSID5 CVSID6; // This is a block containing all the "control variables". We declare @@ -198,46 +198,42 @@ void Usage (void){ #endif } -/* Print an appropriate error message for option opt when given an invalid argument, optarg */ -void printbadargmessage(int opt, const char *optarg) { +/* Returns a pointer to a static string containing a formatted list of the valid + arguments to the option opt or NULL on failure. */ +const char *getvalidarglist(char opt) { + static char *v_list = NULL; char *s; - pout("=======> INVALID ARGUMENT TO -%c: %s <======= \n", opt, optarg); - pout("=======> VALID ARGUMENTS ARE: "); switch (opt) { case 'q': - pout("errorsonly, silent"); - break; + return "errorsonly, silent"; case 'd': - pout("ata, scsi"); - break; + return "ata, scsi"; case 'T': - pout("normal, conservative, permissive"); - break; + return "normal, conservative, permissive"; case 'b': - pout("warn, exit, ignore"); - break; + return "warn, exit, ignore"; case 's': case 'o': case 'S': - pout("on, off"); - break; + return "on, off"; case 'l': - pout("error, selftest"); - break; + return "error, selftest"; case 'v': - if (!(s = create_vendor_attribute_arg_list())) { - pout("\nInsufficient memory to construct argument list\n"); - break; - } - pout("\"help\", %s", s); + if (v_list) + return v_list; + if (!(s = create_vendor_attribute_arg_list())) + return NULL; + // Allocate space for "\"help\", " + s + terminating 0 + v_list = (char *)malloc(9+strlen(s)); + sprintf(v_list, "\"help\", %s", s); free(s); - break; + return v_list; case 't': - pout("offline, short, long"); - break; + return "offline, short, long"; + default: + return NULL; } - pout(" <======= \n\n"); } unsigned char tryata=0,tryscsi=0; @@ -249,9 +245,11 @@ void ParseOpts (int argc, char** argv){ int captive; extern char *optarg; extern int optopt, optind, opterr; + // Please update getvalidarglist() if you edit shortopts const char *shortopts = "h?Vq:d:T:b:s:o:S:HcAl:iav:t:CX"; #ifdef HAVE_GETOPT_LONG char *arg; + // Please update getvalidarglist() if you edit longopts struct option longopts[] = { { "help", no_argument, 0, 'h' }, { "usage", no_argument, 0, 'h' }, @@ -460,37 +458,43 @@ void ParseOpts (int argc, char** argv){ // 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",arg+2); - else + if (optopt && (strchr(shortopts, optopt) != NULL)) { + pout("=======> ARGUMENT REQUIRED FOR OPTION: %s <=======\n", arg+2); + pout("=======> VALID ARGUMENTS ARE: %s <=======\n", getvalidarglist(optopt)); + } else pout("=======> UNRECOGNIZED OPTION: %s <=======\n",arg+2); - pout("Use smartctl --help to get a usage summary\n\n"); + pout("\nUse smartctl --help to get a usage summary\n\n"); exit(FAILCMD); } #endif if (optopt) { // Iff optopt holds a valid option then argument must be missing. - if (strchr(shortopts, optopt) != NULL) - pout("=======> ARGUMENT REQUIRED FOR OPTION: %c <=======\n\n",optopt); - else - pout("=======> UNRECOGNIZED OPTION: %c <=======\n\n",optopt); - pout("Use smartctl -h to get a usage summary\n\n"); + if (strchr(shortopts, optopt) != NULL) { + pout("=======> ARGUMENT REQUIRED FOR OPTION: %c <=======\n", optopt); + pout("=======> VALID ARGUMENTS ARE: %s <=======\n", getvalidarglist(optopt)); + } else + pout("=======> UNRECOGNIZED OPTION: %c <=======\n",optopt); + pout("\nUse smartctl -h to get a usage summary\n\n"); exit(FAILCMD); } Usage(); exit(0); } // closes switch statement to process command-line options - // At this point we have processed all command-line options. Now - // check to see if any of those options had unrecognized or - // incorrect arguments. + // Check to see if option had an unrecognized or incorrect argument. if (badarg) { printslogan(); - printbadargmessage(optchar, optarg); - pout("Use smartctl -h to get a usage summary\n\n"); + // It would be nice to print the actual option name given by the user + // here, but we just print the short form. Please fix this if you know + // a clean way to do it. + pout("=======> INVALID ARGUMENT TO -%c: %s <======= \n", optchar, optarg); + pout("=======> VALID ARGUMENTS ARE: %s <=======\n", getvalidarglist(optchar)); + pout("\nUse smartctl -h to get a usage summary\n\n"); exit(FAILCMD); } } + // At this point we have processed all command-line options. + // Do this here, so results are independent of argument order if (con->quietmode) con->veryquietmode=TRUE; diff --git a/sm5/smartctl.cpp b/sm5/smartctl.cpp index c38e5a4f0..3107fade3 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.43 2003/01/05 20:05:32 pjwilliams Exp $" +const char* CVSid5="$Id: smartctl.cpp,v 1.44 2003/01/07 00:27:16 pjwilliams Exp $" CVSID1 CVSID2 CVSID3 CVSID4 CVSID5 CVSID6; // This is a block containing all the "control variables". We declare @@ -198,46 +198,42 @@ void Usage (void){ #endif } -/* Print an appropriate error message for option opt when given an invalid argument, optarg */ -void printbadargmessage(int opt, const char *optarg) { +/* Returns a pointer to a static string containing a formatted list of the valid + arguments to the option opt or NULL on failure. */ +const char *getvalidarglist(char opt) { + static char *v_list = NULL; char *s; - pout("=======> INVALID ARGUMENT TO -%c: %s <======= \n", opt, optarg); - pout("=======> VALID ARGUMENTS ARE: "); switch (opt) { case 'q': - pout("errorsonly, silent"); - break; + return "errorsonly, silent"; case 'd': - pout("ata, scsi"); - break; + return "ata, scsi"; case 'T': - pout("normal, conservative, permissive"); - break; + return "normal, conservative, permissive"; case 'b': - pout("warn, exit, ignore"); - break; + return "warn, exit, ignore"; case 's': case 'o': case 'S': - pout("on, off"); - break; + return "on, off"; case 'l': - pout("error, selftest"); - break; + return "error, selftest"; case 'v': - if (!(s = create_vendor_attribute_arg_list())) { - pout("\nInsufficient memory to construct argument list\n"); - break; - } - pout("\"help\", %s", s); + if (v_list) + return v_list; + if (!(s = create_vendor_attribute_arg_list())) + return NULL; + // Allocate space for "\"help\", " + s + terminating 0 + v_list = (char *)malloc(9+strlen(s)); + sprintf(v_list, "\"help\", %s", s); free(s); - break; + return v_list; case 't': - pout("offline, short, long"); - break; + return "offline, short, long"; + default: + return NULL; } - pout(" <======= \n\n"); } unsigned char tryata=0,tryscsi=0; @@ -249,9 +245,11 @@ void ParseOpts (int argc, char** argv){ int captive; extern char *optarg; extern int optopt, optind, opterr; + // Please update getvalidarglist() if you edit shortopts const char *shortopts = "h?Vq:d:T:b:s:o:S:HcAl:iav:t:CX"; #ifdef HAVE_GETOPT_LONG char *arg; + // Please update getvalidarglist() if you edit longopts struct option longopts[] = { { "help", no_argument, 0, 'h' }, { "usage", no_argument, 0, 'h' }, @@ -460,37 +458,43 @@ void ParseOpts (int argc, char** argv){ // 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",arg+2); - else + if (optopt && (strchr(shortopts, optopt) != NULL)) { + pout("=======> ARGUMENT REQUIRED FOR OPTION: %s <=======\n", arg+2); + pout("=======> VALID ARGUMENTS ARE: %s <=======\n", getvalidarglist(optopt)); + } else pout("=======> UNRECOGNIZED OPTION: %s <=======\n",arg+2); - pout("Use smartctl --help to get a usage summary\n\n"); + pout("\nUse smartctl --help to get a usage summary\n\n"); exit(FAILCMD); } #endif if (optopt) { // Iff optopt holds a valid option then argument must be missing. - if (strchr(shortopts, optopt) != NULL) - pout("=======> ARGUMENT REQUIRED FOR OPTION: %c <=======\n\n",optopt); - else - pout("=======> UNRECOGNIZED OPTION: %c <=======\n\n",optopt); - pout("Use smartctl -h to get a usage summary\n\n"); + if (strchr(shortopts, optopt) != NULL) { + pout("=======> ARGUMENT REQUIRED FOR OPTION: %c <=======\n", optopt); + pout("=======> VALID ARGUMENTS ARE: %s <=======\n", getvalidarglist(optopt)); + } else + pout("=======> UNRECOGNIZED OPTION: %c <=======\n",optopt); + pout("\nUse smartctl -h to get a usage summary\n\n"); exit(FAILCMD); } Usage(); exit(0); } // closes switch statement to process command-line options - // At this point we have processed all command-line options. Now - // check to see if any of those options had unrecognized or - // incorrect arguments. + // Check to see if option had an unrecognized or incorrect argument. if (badarg) { printslogan(); - printbadargmessage(optchar, optarg); - pout("Use smartctl -h to get a usage summary\n\n"); + // It would be nice to print the actual option name given by the user + // here, but we just print the short form. Please fix this if you know + // a clean way to do it. + pout("=======> INVALID ARGUMENT TO -%c: %s <======= \n", optchar, optarg); + pout("=======> VALID ARGUMENTS ARE: %s <=======\n", getvalidarglist(optchar)); + pout("\nUse smartctl -h to get a usage summary\n\n"); exit(FAILCMD); } } + // At this point we have processed all command-line options. + // Do this here, so results are independent of argument order if (con->quietmode) con->veryquietmode=TRUE; -- GitLab