diff --git a/sm5/atacmds.c b/sm5/atacmds.c index 6d3583c136677152d415ab96b0b74d31b803e4df..1deb312ee368724b4faa53b6fc336fa43d9f71f4 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.48 2003/01/03 17:25:12 ballen4705 Exp $" CVSID1; +const char *CVSid1="$Id: atacmds.c,v 1.49 2003/01/04 17:34:16 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 @@ -156,6 +156,43 @@ int parse_attribute_def(char *pair, unsigned char *defs){ } } +// Function to return a string containing a list of the arguments in +// vendorattributeargs[] separated by commas. The strings themselves +// contain commas, so surrounding double quotes are added for clarity. +// This function allocates the required memory for the string and the +// caller must use free() to free it. Returns NULL if the required +// memory can't be allocated. +char *create_vendor_attribute_arg_list(void){ + const char **ps; + char *s; + int len; + + // Calculate the required number of characters + len = 1; // At least one char ('\0') + for (ps = vendorattributeargs; *ps != NULL; ps++) { + len += strlen(*ps); // For the actual argument string + len += 2; // For the surrounding double quotes + if (*(ps+1)) + len += 2; // For the ", " delimiter if required + } + + // Attempt to allocate memory for the string + if (!(s = (char *)malloc(len))) + return NULL; + + // Construct the string + *s = '\0'; + for (ps = vendorattributeargs; *ps != NULL; ps++) { + strcat(s, "\""); + strcat(s, *ps); + strcat(s, "\""); + if (*(ps+1)) + strcat(s, ", "); + } + + // Return a pointer to the string + return s; +} // A replacement for perror() that sends output to our choice of // printing. diff --git a/sm5/atacmds.cpp b/sm5/atacmds.cpp index f7c0e57eee1759c740118a7717c6d99246d35def..6ee100e920a0a36fadbb6768ca5249d340bc1fbf 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.48 2003/01/03 17:25:12 ballen4705 Exp $" CVSID1; +const char *CVSid1="$Id: atacmds.cpp,v 1.49 2003/01/04 17:34:16 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 @@ -156,6 +156,43 @@ int parse_attribute_def(char *pair, unsigned char *defs){ } } +// Function to return a string containing a list of the arguments in +// vendorattributeargs[] separated by commas. The strings themselves +// contain commas, so surrounding double quotes are added for clarity. +// This function allocates the required memory for the string and the +// caller must use free() to free it. Returns NULL if the required +// memory can't be allocated. +char *create_vendor_attribute_arg_list(void){ + const char **ps; + char *s; + int len; + + // Calculate the required number of characters + len = 1; // At least one char ('\0') + for (ps = vendorattributeargs; *ps != NULL; ps++) { + len += strlen(*ps); // For the actual argument string + len += 2; // For the surrounding double quotes + if (*(ps+1)) + len += 2; // For the ", " delimiter if required + } + + // Attempt to allocate memory for the string + if (!(s = (char *)malloc(len))) + return NULL; + + // Construct the string + *s = '\0'; + for (ps = vendorattributeargs; *ps != NULL; ps++) { + strcat(s, "\""); + strcat(s, *ps); + strcat(s, "\""); + if (*(ps+1)) + strcat(s, ", "); + } + + // Return a pointer to the string + return s; +} // A replacement for perror() that sends output to our choice of // printing. diff --git a/sm5/atacmds.h b/sm5/atacmds.h index 89360a38fa84ebc5efa44a89f5fed9d1a92f8d51..c8d717b99aadecc61f8d203ce628834a86c64c5d 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.29 2003/01/03 17:25:12 ballen4705 Exp $\n" +#define CVSID1 "$Id: atacmds.h,v 1.30 2003/01/04 17:34:16 pjwilliams Exp $\n" #endif // These are the major and minor versions for smartd and smartctl @@ -383,4 +383,9 @@ extern const char *vendorattributeargs[]; // else 1 if there is a problem. int parse_attribute_def(char *pair, unsigned char *defs); +// Function to return a string containing a list of the arguments in +// vendorattributeargs[]. Returns NULL if the required memory can't +// be allocated. +char *create_vendor_attribute_arg_list(void); + #endif /* _ATACMDS_H_ */ diff --git a/sm5/smartctl.c b/sm5/smartctl.c index 8e8314e68fe40d69b0621ff1046817e0735a943b..f262f40df078afb5fcee5c76b82f53f2469fc343 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.33 2003/01/04 08:26:10 ballen4705 Exp $" +const char* CVSid5="$Id: smartctl.c,v 1.34 2003/01/04 17:34:16 pjwilliams Exp $" CVSID1 CVSID2 CVSID3 CVSID4 CVSID5 CVSID6; // This is a block containing all the "control variables". We declare @@ -213,9 +213,9 @@ void Usage (void){ /* Print an appropriate error message for option opt when given an invalid argument, optarg */ void printbadargmessage(int opt, const char *optarg) { - const char **ps; + char *s; - pout("=======> INVALID ARGUMENT OF -%c: %s <======= \n", opt, optarg); + pout("=======> INVALID ARGUMENT TO -%c: %s <======= \n", opt, optarg); pout("=======> VALID ARGUMENTS ARE: "); switch (opt) { case 'q': @@ -239,11 +239,12 @@ void printbadargmessage(int opt, const char *optarg) { 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) ? ", " : ""); + if (!(s = create_vendor_attribute_arg_list())) { + pout("\nInsufficient memory to construct argument list\n"); + break; + } + pout("%s", s); + free(s); break; case 't': pout("offline, short, long"); diff --git a/sm5/smartctl.cpp b/sm5/smartctl.cpp index 29eb97e13d4279e6bd45551efd86437f45a2b83c..8351ea67a561336e17582811ea987758398370b3 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.33 2003/01/04 08:26:10 ballen4705 Exp $" +const char* CVSid5="$Id: smartctl.cpp,v 1.34 2003/01/04 17:34:16 pjwilliams Exp $" CVSID1 CVSID2 CVSID3 CVSID4 CVSID5 CVSID6; // This is a block containing all the "control variables". We declare @@ -213,9 +213,9 @@ void Usage (void){ /* Print an appropriate error message for option opt when given an invalid argument, optarg */ void printbadargmessage(int opt, const char *optarg) { - const char **ps; + char *s; - pout("=======> INVALID ARGUMENT OF -%c: %s <======= \n", opt, optarg); + pout("=======> INVALID ARGUMENT TO -%c: %s <======= \n", opt, optarg); pout("=======> VALID ARGUMENTS ARE: "); switch (opt) { case 'q': @@ -239,11 +239,12 @@ void printbadargmessage(int opt, const char *optarg) { 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) ? ", " : ""); + if (!(s = create_vendor_attribute_arg_list())) { + pout("\nInsufficient memory to construct argument list\n"); + break; + } + pout("%s", s); + free(s); break; case 't': pout("offline, short, long"); diff --git a/sm5/smartd.c b/sm5/smartd.c index f0b3e4c19a5594d5266e9709a8a46beb62c47b4e..a8c7728b236b5aad43a36c22fb34aa1245c57d98 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.92 2003/01/03 17:25:12 ballen4705 Exp $" +const char *CVSid6="$Id: smartd.c,v 1.93 2003/01/04 17:34:16 pjwilliams Exp $" CVSID1 CVSID2 CVSID3 CVSID4 CVSID7; // global variable used for control of printing, passing arguments, etc. @@ -934,6 +934,8 @@ void CheckDevices(atadevices_t *atadevices, scsidevices_t *scsidevices){ // Print out a list of valid arguments for the Directive d void printoutvaliddirectiveargs(int priority, char d) { + char *s; + switch (d) { case 'd': printout(priority, "ata, scsi"); @@ -951,6 +953,14 @@ void printoutvaliddirectiveargs(int priority, char d) { case 'M': printout(priority, "\"once\", \"daily\", \"diminishing\", \"once,test\", \"daily,test\", \"diminishing,test\""); break; + case 'v': + if (!(s = create_vendor_attribute_arg_list())) { + printout(LOG_CRIT,"Insufficient memory to construct argument list\n"); + break; + } + printout(priority, "%s", s); + free(s); + break; } } @@ -1161,20 +1171,10 @@ int parsetoken(char *token,cfgfile *cfg){ 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); + if ((arg=strtok(NULL,delim)) == NULL) { + missingarg = 1; + } else if (parse_attribute_def(arg, cfg->attributedefs)){ + badarg = 1; } break; default: diff --git a/sm5/smartd.cpp b/sm5/smartd.cpp index 8215860cb88ed36c507dbfaf2f9610bfd727ff74..bc5e325361da72e244f70f18866d7e95842abc04 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.92 2003/01/03 17:25:12 ballen4705 Exp $" +const char *CVSid6="$Id: smartd.cpp,v 1.93 2003/01/04 17:34:16 pjwilliams Exp $" CVSID1 CVSID2 CVSID3 CVSID4 CVSID7; // global variable used for control of printing, passing arguments, etc. @@ -934,6 +934,8 @@ void CheckDevices(atadevices_t *atadevices, scsidevices_t *scsidevices){ // Print out a list of valid arguments for the Directive d void printoutvaliddirectiveargs(int priority, char d) { + char *s; + switch (d) { case 'd': printout(priority, "ata, scsi"); @@ -951,6 +953,14 @@ void printoutvaliddirectiveargs(int priority, char d) { case 'M': printout(priority, "\"once\", \"daily\", \"diminishing\", \"once,test\", \"daily,test\", \"diminishing,test\""); break; + case 'v': + if (!(s = create_vendor_attribute_arg_list())) { + printout(LOG_CRIT,"Insufficient memory to construct argument list\n"); + break; + } + printout(priority, "%s", s); + free(s); + break; } } @@ -1161,20 +1171,10 @@ int parsetoken(char *token,cfgfile *cfg){ 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); + if ((arg=strtok(NULL,delim)) == NULL) { + missingarg = 1; + } else if (parse_attribute_def(arg, cfg->attributedefs)){ + badarg = 1; } break; default: