]> git.proxmox.com Git - mirror_smartmontools-debian.git/blobdiff - smartctl.cpp
Refreshed patches
[mirror_smartmontools-debian.git] / smartctl.cpp
index 549dd957c9f06168f266f63096aa5cc7695db9d6..65b6d3b9bc31cf4f5565817a6c761a4fd3210793 100644 (file)
@@ -56,7 +56,7 @@
 #include "smartctl.h"
 #include "utility.h"
 
-const char * smartctl_cpp_cvsid = "$Id: smartctl.cpp 2854 2009-07-21 19:23:20Z chrfranke $"
+const char * smartctl_cpp_cvsid = "$Id: smartctl.cpp 2975 2009-10-29 22:52:38Z chrfranke $"
                                   CONFIG_H_CVSID EXTERN_H_CVSID SMARTCTL_H_CVSID;
 
 // This is a block containing all the "control variables".  We declare
@@ -73,7 +73,7 @@ void UsageSummary(){
   return;
 }
 
-static const char *getvalidarglist(char opt);
+static std::string getvalidarglist(char opt);
 
 /*  void prints help information for command syntax */
 void Usage (void){
@@ -105,7 +105,7 @@ void Usage (void){
 "         Report transactions (see man page)\n\n"
 "  -n MODE, --nocheck=MODE                                             (ATA)\n"
 "         No check if: never, sleep, standby, idle (see man page)\n\n",
-  getvalidarglist('d')); // TODO: Use this function also for other options ?
+  getvalidarglist('d').c_str()); // TODO: Use this function also for other options ?
   printf(
 "============================== DEVICE FEATURE ENABLE/DISABLE COMMANDS =====\n\n"
 "  -s VALUE, --smart=VALUE\n"
@@ -153,24 +153,20 @@ void Usage (void){
 "  -X, --abort\n"
 "        Abort any non-captive test on device\n\n"
 );
-  const char * examples = smi()->get_app_examples("smartctl");
-  if (examples)
-    printf("%s\n", examples);
+  std::string examples = smi()->get_app_examples("smartctl");
+  if (!examples.empty())
+    printf("%s\n", examples.c_str());
 }
 
-/* Returns a pointer to a static string containing a formatted list of the valid
-   arguments to the option opt or NULL on failure. Note 'v' case different */
-static const char *getvalidarglist(char opt)
+/* Returns a string containing a formatted list of the valid arguments
+   to the option opt or empty on failure. Note 'v' case different */
+static std::string getvalidarglist(char opt)
 {
   switch (opt) {
   case 'q':
     return "errorsonly, silent, noserial";
   case 'd':
-    { // TODO: let this function return std::string ?
-      static std::string buf = smi()->get_valid_dev_types_str();
-      buf += ", test";
-      return buf.c_str();
-    }
+    return smi()->get_valid_dev_types_str() + ", test";
   case 'T':
     return "normal, conservative, permissive, verypermissive";
   case 'b':
@@ -195,7 +191,7 @@ static const char *getvalidarglist(char opt)
     return "never, sleep, standby, idle";
   case 'v':
   default:
-    return NULL;
+    return "";
   }
 }
 
@@ -210,9 +206,9 @@ void printvalidarglistmessage(char opt) {
   else {
   // getvalidarglist() might produce a multiline or single line string.  We
   // need to figure out which to get the formatting right.
-    const char * s = getvalidarglist(opt);
-    char separator = strchr(s, '\n') ? '\n' : ' ';
-    pout("=======> VALID ARGUMENTS ARE:%c%s%c<=======\n", separator, s, separator);
+    std::string s = getvalidarglist(opt);
+    char separator = strchr(s.c_str(), '\n') ? '\n' : ' ';
+    pout("=======> VALID ARGUMENTS ARE:%c%s%c<=======\n", separator, s.c_str(), separator);
   }
 
   return;
@@ -543,7 +539,7 @@ const char * parse_options(int argc, char** argv,
              create_vendor_attribute_arg_list().c_str());
         EXIT(0);
       }
-      if (parse_attribute_def(optarg, ataopts.attributedefs))
+      if (!parse_attribute_def(optarg, ataopts.attribute_defs, PRIOR_USER))
         badarg = true;
       break;    
     case 'P':
@@ -881,92 +877,83 @@ int main_worker(int argc, char **argv)
   if (!smi())
     return 1;
 
-  int retval = 0;
+  // define control block for external functions
+  smartmonctrl control;
+  con=&control;
 
-  smart_device * dev = 0;
-  try {
-    // define control block for external functions
-    smartmonctrl control;
-    con=&control;
-
-    // Parse input arguments
-    ata_print_options ataopts;
-    scsi_print_options scsiopts;
-    const char * type = parse_options(argc, argv, ataopts, scsiopts);
-
-    // '-d test' -> Report result of autodetection
-    bool print_type_only = (type && !strcmp(type, "test"));
-    if (print_type_only)
-      type = 0;
-
-    const char * name = argv[argc-1];
-
-    if (!strcmp(name,"-")) {
-      // Parse "smartctl -r ataioctl,2 ..." output from stdin
-      if (type || print_type_only) {
-        pout("Smartctl: -d option is not allowed in conjunction with device name \"-\".\n");
-        UsageSummary();
-        return FAILCMD;
-      }
-      dev = get_parsed_ata_device(smi(), name);
-    }
-    else
-      // get device of appropriate type
-      dev = smi()->get_smart_device(name, type);
+  // Parse input arguments
+  ata_print_options ataopts;
+  scsi_print_options scsiopts;
+  const char * type = parse_options(argc, argv, ataopts, scsiopts);
 
-    if (!dev) {
-      pout("%s: %s\n", name, smi()->get_errmsg());
-      if (type)
-        printvalidarglistmessage('d');
-      else
-        pout("Smartctl: please specify device type with the -d option.\n");
+  // '-d test' -> Report result of autodetection
+  bool print_type_only = (type && !strcmp(type, "test"));
+  if (print_type_only)
+    type = 0;
+
+  const char * name = argv[argc-1];
+
+  smart_device_auto_ptr dev;
+  if (!strcmp(name,"-")) {
+    // Parse "smartctl -r ataioctl,2 ..." output from stdin
+    if (type || print_type_only) {
+      pout("Smartctl: -d option is not allowed in conjunction with device name \"-\".\n");
       UsageSummary();
       return FAILCMD;
     }
+    dev = get_parsed_ata_device(smi(), name);
+  }
+  else
+    // get device of appropriate type
+    dev = smi()->get_smart_device(name, type);
+
+  if (!dev) {
+    pout("%s: %s\n", name, smi()->get_errmsg());
+    if (type)
+      printvalidarglistmessage('d');
+    else
+      pout("Smartctl: please specify device type with the -d option.\n");
+    UsageSummary();
+    return FAILCMD;
+  }
 
-    if (print_type_only)
-      // Report result of first autodetection
-      pout("%s: Device of type '%s' [%s] detected\n",
-           dev->get_info_name(), dev->get_dev_type(), get_protocol_info(dev));
-
-    // Open device
-    {
-      // Save old info
-      smart_device::device_info oldinfo = dev->get_info();
-
-      // Open with autodetect support, may return 'better' device
-      dev = dev->autodetect_open();
+  if (print_type_only)
+    // Report result of first autodetection
+    pout("%s: Device of type '%s' [%s] detected\n",
+         dev->get_info_name(), dev->get_dev_type(), get_protocol_info(dev.get()));
 
-      // Report if type has changed
-      if ((type || print_type_only) && oldinfo.dev_type != dev->get_dev_type())
-        pout("%s: Device open changed type from '%s' to '%s'\n",
-          dev->get_info_name(), oldinfo.dev_type.c_str(), dev->get_dev_type());
-    }
-    if (!dev->is_open()) {
-      pout("Smartctl open device: %s failed: %s\n", dev->get_info_name(), dev->get_errmsg());
-      delete dev;
-      return FAILDEV;
-    }
+  // Open device
+  {
+    // Save old info
+    smart_device::device_info oldinfo = dev->get_info();
 
-    // now call appropriate ATA or SCSI routine
-    if (print_type_only)
-      pout("%s: Device of type '%s' [%s] opened\n",
-           dev->get_info_name(), dev->get_dev_type(), get_protocol_info(dev));
-    else if (dev->is_ata())
-      retval = ataPrintMain(dev->to_ata(), ataopts);
-    else if (dev->is_scsi())
-      retval = scsiPrintMain(dev->to_scsi(), scsiopts);
-    else
-      // we should never fall into this branch!
-      pout("%s: Neither ATA nor SCSI device\n", dev->get_info_name());
+    // Open with autodetect support, may return 'better' device
+    dev.replace( dev->autodetect_open() );
 
-    dev->close();
-    delete dev;
+    // Report if type has changed
+    if ((type || print_type_only) && oldinfo.dev_type != dev->get_dev_type())
+      pout("%s: Device open changed type from '%s' to '%s'\n",
+        dev->get_info_name(), oldinfo.dev_type.c_str(), dev->get_dev_type());
   }
-  catch (...) {
-    delete dev;
-    throw;
+  if (!dev->is_open()) {
+    pout("Smartctl open device: %s failed: %s\n", dev->get_info_name(), dev->get_errmsg());
+    return FAILDEV;
   }
+
+  // now call appropriate ATA or SCSI routine
+  int retval = 0;
+  if (print_type_only)
+    pout("%s: Device of type '%s' [%s] opened\n",
+         dev->get_info_name(), dev->get_dev_type(), get_protocol_info(dev.get()));
+  else if (dev->is_ata())
+    retval = ataPrintMain(dev->to_ata(), ataopts);
+  else if (dev->is_scsi())
+    retval = scsiPrintMain(dev->to_scsi(), scsiopts);
+  else
+    // we should never fall into this branch!
+    pout("%s: Neither ATA nor SCSI device\n", dev->get_info_name());
+
+  dev->close();
   return retval;
 }
 
@@ -985,12 +972,12 @@ int main(int argc, char **argv)
   }
   catch (const std::bad_alloc & /*ex*/) {
     // Memory allocation failed (also thrown by std::operator new)
-    pout("Smartctl: Out of memory\n");
+    printf("Smartctl: Out of memory\n");
     status = FAILCMD;
   }
   catch (const std::exception & ex) {
     // Other fatal errors
-    pout("Smartctl: Exception: %s\n", ex.what());
+    printf("Smartctl: Exception: %s\n", ex.what());
     status = FAILCMD;
   }
   return status;