Diff for /embedaddon/smartmontools/smartctl.cpp between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2012/02/21 16:32:16 version 1.1.1.2, 2012/10/09 09:36:45
Line 4 Line 4
  * Home page of code is: http://smartmontools.sourceforge.net   * Home page of code is: http://smartmontools.sourceforge.net
  *   *
  * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>   * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
 * Copyright (C) 2008-11 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2008-12 Christian Franke <smartmontools-support@lists.sourceforge.net>
  * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>   * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
  *   *
  * This program is free software; you can redistribute it and/or modify   * This program is free software; you can redistribute it and/or modify
Line 73  static void UsageSummary() Line 73  static void UsageSummary()
   return;    return;
 }  }
   
static std::string getvalidarglist(char opt);static std::string getvalidarglist(int opt);
   
 /*  void prints help information for command syntax */  /*  void prints help information for command syntax */
 static void Usage()  static void Usage()
Line 85  static void Usage() Line 85  static void Usage()
 "         Display this help and exit\n\n"  "         Display this help and exit\n\n"
 "  -V, --version, --copyright, --license\n"  "  -V, --version, --copyright, --license\n"
 "         Print license, copyright, and version information and exit\n\n"  "         Print license, copyright, and version information and exit\n\n"
"  -i, --info                                                       \n""  -i, --info\n"
 "         Show identity information for device\n\n"  "         Show identity information for device\n\n"
"  -a, --all                                                        \n""  -g NAME, --get=NAME\n"
 "        Get device setting: all, aam, apm, lookahead, security, wcache\n\n"
 "  -a, --all\n"
 "         Show all SMART information for device\n\n"  "         Show all SMART information for device\n\n"
 "  -x, --xall\n"  "  -x, --xall\n"
 "         Show all information for device\n\n"  "         Show all information for device\n\n"
Line 119  static void Usage() Line 121  static void Usage()
 "        Enable/disable automatic offline testing on device (on/off)\n\n"  "        Enable/disable automatic offline testing on device (on/off)\n\n"
 "  -S VALUE, --saveauto=VALUE                                          (ATA)\n"  "  -S VALUE, --saveauto=VALUE                                          (ATA)\n"
 "        Enable/disable Attribute autosave on device (on/off)\n\n"  "        Enable/disable Attribute autosave on device (on/off)\n\n"
   "  -s NAME[,VALUE], --set=NAME[,VALUE]\n"
   "        Enable/disable/change device setting: aam,[N|off], apm,[N|off],\n"
   "        lookahead,[on|off], security-freeze, standby,[N|off|now],\n"
   "        wcache,[on|off]\n\n"
   );    );
   printf(    printf(
 "======================================= READ AND DISPLAY DATA OPTIONS =====\n\n"  "======================================= READ AND DISPLAY DATA OPTIONS =====\n\n"
Line 129  static void Usage() Line 135  static void Usage()
 "  -A, --attributes\n"  "  -A, --attributes\n"
 "        Show device SMART vendor-specific Attributes and values\n\n"  "        Show device SMART vendor-specific Attributes and values\n\n"
 "  -f FORMAT, --format=FORMAT                                          (ATA)\n"  "  -f FORMAT, --format=FORMAT                                          (ATA)\n"
"        Set output format for attributes to one of: old, brief\n\n""        Set output format for attributes: old, brief, hex[,id|val]\n\n"
 "  -l TYPE, --log=TYPE\n"  "  -l TYPE, --log=TYPE\n"
 "        Show device log. TYPE: error, selftest, selective, directory[,g|s],\n"  "        Show device log. TYPE: error, selftest, selective, directory[,g|s],\n"
 "                               xerror[,N][,error], xselftest[,N][,selftest],\n"  "                               xerror[,N][,error], xselftest[,N][,selftest],\n"
Line 160  static void Usage() Line 166  static void Usage()
          "]\n\n"           "]\n\n"
 "============================================ DEVICE SELF-TEST OPTIONS =====\n\n"  "============================================ DEVICE SELF-TEST OPTIONS =====\n\n"
 "  -t TEST, --test=TEST\n"  "  -t TEST, --test=TEST\n"
"        Run test. TEST: offline, short, long, conveyance, vendor,N,\n""        Run test. TEST: offline, short, long, conveyance, force, vendor,N,\n"
 "                        select,M-N, pending,N, afterselect,[on|off]\n\n"  "                        select,M-N, pending,N, afterselect,[on|off]\n\n"
 "  -C, --captive\n"  "  -C, --captive\n"
 "        Do test in captive mode (along with -t)\n\n"  "        Do test in captive mode (along with -t)\n\n"
Line 172  static void Usage() Line 178  static void Usage()
     printf("%s\n", examples.c_str());      printf("%s\n", examples.c_str());
 }  }
   
   // Values for  --long only options, see parse_options()
   enum { opt_scan = 1000, opt_scan_open, opt_set, opt_smart };
   
 /* Returns a string containing a formatted list of the valid arguments  /* Returns a string containing a formatted list of the valid arguments
    to the option opt or empty on failure. Note 'v' case different */     to the option opt or empty on failure. Note 'v' case different */
static std::string getvalidarglist(char opt)static std::string getvalidarglist(int opt)
 {  {
   switch (opt) {    switch (opt) {
   case 'q':    case 'q':
Line 187  static std::string getvalidarglist(char opt) Line 196  static std::string getvalidarglist(char opt)
     return "warn, exit, ignore";      return "warn, exit, ignore";
   case 'r':    case 'r':
     return "ioctl[,N], ataioctl[,N], scsiioctl[,N]";      return "ioctl[,N], ataioctl[,N], scsiioctl[,N]";
  case 's':  case opt_smart:
   case 'o':    case 'o':
   case 'S':    case 'S':
     return "on, off";      return "on, off";
Line 202  static std::string getvalidarglist(char opt) Line 211  static std::string getvalidarglist(char opt)
   case 'P':    case 'P':
     return "use, ignore, show, showall";      return "use, ignore, show, showall";
   case 't':    case 't':
    return "offline, short, long, conveyance, vendor,N, select,M-N, "    return "offline, short, long, conveyance, force, vendor,N, select,M-N, "
            "pending,N, afterselect,[on|off]";             "pending,N, afterselect,[on|off]";
   case 'F':    case 'F':
     return "none, samsung, samsung2, samsung3, swapid";      return "none, samsung, samsung2, samsung3, swapid";
   case 'n':    case 'n':
     return "never, sleep, standby, idle";      return "never, sleep, standby, idle";
   case 'f':    case 'f':
    return "old, brief";    return "old, brief, hex[,id|val]";
   case 'g':
     return "aam, apm, lookahead, security, wcache";
   case opt_set:
     return "aam,[N|off], apm,[N|off], lookahead,[on|off], security-freeze, "
            "standby,[N|off|now], wcache,[on|off]";
   case 's':
     return getvalidarglist(opt_smart)+", "+getvalidarglist(opt_set);
   case 'v':    case 'v':
   default:    default:
     return "";      return "";
Line 218  static std::string getvalidarglist(char opt) Line 234  static std::string getvalidarglist(char opt)
   
 /* Prints the message "=======> VALID ARGUMENTS ARE: <LIST> \n", where  /* Prints the message "=======> VALID ARGUMENTS ARE: <LIST> \n", where
    <LIST> is the list of valid arguments for option opt. */     <LIST> is the list of valid arguments for option opt. */
static void printvalidarglistmessage(char opt)static void printvalidarglistmessage(int opt)
 {  {
   if (opt=='v'){    if (opt=='v'){
     pout("=======> VALID ARGUMENTS ARE:\n\thelp\n%s\n<=======\n",      pout("=======> VALID ARGUMENTS ARE:\n\thelp\n%s\n<=======\n",
Line 244  static checksum_err_mode_t checksum_err_mode = CHECKSU Line 260  static checksum_err_mode_t checksum_err_mode = CHECKSU
   
 static void scan_devices(const char * type, bool with_open, char ** argv);  static void scan_devices(const char * type, bool with_open, char ** argv);
   
   
 /*      Takes command options and sets features to be run */      /*      Takes command options and sets features to be run */    
 static const char * parse_options(int argc, char** argv,  static const char * parse_options(int argc, char** argv,
                           ata_print_options & ataopts,  ata_print_options & ataopts, scsi_print_options & scsiopts,
                           scsi_print_options & scsiopts)  bool & print_type_only)
 {  {
   // Please update getvalidarglist() if you edit shortopts    // Please update getvalidarglist() if you edit shortopts
  const char *shortopts = "h?Vq:d:T:b:r:s:o:S:HcAl:iaxv:P:t:CXF:n:B:f:";  const char *shortopts = "h?Vq:d:T:b:r:s:o:S:HcAl:iaxv:P:t:CXF:n:B:f:g:";
   // Please update getvalidarglist() if you edit longopts    // Please update getvalidarglist() if you edit longopts
   enum { opt_scan = 1000, opt_scan_open = 1001 };  
   struct option longopts[] = {    struct option longopts[] = {
     { "help",            no_argument,       0, 'h' },      { "help",            no_argument,       0, 'h' },
     { "usage",           no_argument,       0, 'h' },      { "usage",           no_argument,       0, 'h' },
Line 264  static const char * parse_options(int argc, char** arg Line 280  static const char * parse_options(int argc, char** arg
     { "tolerance",       required_argument, 0, 'T' },      { "tolerance",       required_argument, 0, 'T' },
     { "badsum",          required_argument, 0, 'b' },      { "badsum",          required_argument, 0, 'b' },
     { "report",          required_argument, 0, 'r' },      { "report",          required_argument, 0, 'r' },
    { "smart",           required_argument, 0, 's' },    { "smart",           required_argument, 0, opt_smart },
     { "offlineauto",     required_argument, 0, 'o' },      { "offlineauto",     required_argument, 0, 'o' },
     { "saveauto",        required_argument, 0, 'S' },      { "saveauto",        required_argument, 0, 'S' },
     { "health",          no_argument,       0, 'H' },      { "health",          no_argument,       0, 'H' },
Line 283  static const char * parse_options(int argc, char** arg Line 299  static const char * parse_options(int argc, char** arg
     { "nocheck",         required_argument, 0, 'n' },      { "nocheck",         required_argument, 0, 'n' },
     { "drivedb",         required_argument, 0, 'B' },      { "drivedb",         required_argument, 0, 'B' },
     { "format",          required_argument, 0, 'f' },      { "format",          required_argument, 0, 'f' },
       { "get",             required_argument, 0, 'g' },
       { "set",             required_argument, 0, opt_set },
     { "scan",            no_argument,       0, opt_scan      },      { "scan",            no_argument,       0, opt_scan      },
     { "scan-open",       no_argument,       0, opt_scan_open },      { "scan-open",       no_argument,       0, opt_scan_open },
     { 0,                 0,                 0, 0   }      { 0,                 0,                 0, 0   }
Line 323  static const char * parse_options(int argc, char** arg Line 341  static const char * parse_options(int argc, char** arg
       }        }
       break;        break;
     case 'd':      case 'd':
      type = (strcmp(optarg, "auto") ? optarg : (char *)0);      if (!strcmp(optarg, "test"))
         print_type_only = true;
       else
         type = (strcmp(optarg, "auto") ? optarg : (char *)0);
       break;        break;
     case 'T':      case 'T':
       if (!strcmp(optarg,"normal")) {        if (!strcmp(optarg,"normal")) {
Line 375  static const char * parse_options(int argc, char** arg Line 396  static const char * parse_options(int argc, char** arg
         free(s);          free(s);
       }        }
       break;        break;
   
     case 's':      case 's':
       case opt_smart: // --smart
       if (!strcmp(optarg,"on")) {        if (!strcmp(optarg,"on")) {
         ataopts.smart_enable  = scsiopts.smart_enable  = true;          ataopts.smart_enable  = scsiopts.smart_enable  = true;
         ataopts.smart_disable = scsiopts.smart_disable = false;          ataopts.smart_disable = scsiopts.smart_disable = false;
       } else if (!strcmp(optarg,"off")) {        } else if (!strcmp(optarg,"off")) {
         ataopts.smart_disable = scsiopts.smart_disable = true;          ataopts.smart_disable = scsiopts.smart_disable = true;
         ataopts.smart_enable  = scsiopts.smart_enable  = false;          ataopts.smart_enable  = scsiopts.smart_enable  = false;
         } else if (optchar == 's') {
           goto case_s_continued; // --set, see below
       } else {        } else {
         badarg = true;          badarg = true;
       }        }
       break;        break;
   
     case 'o':      case 'o':
       if (!strcmp(optarg,"on")) {        if (!strcmp(optarg,"on")) {
         ataopts.smart_auto_offl_enable  = true;          ataopts.smart_auto_offl_enable  = true;
Line 593  static const char * parse_options(int argc, char** arg Line 619  static const char * parse_options(int argc, char** arg
       ataopts.sct_temp_sts = ataopts.sct_temp_hist = true;        ataopts.sct_temp_sts = ataopts.sct_temp_hist = true;
       ataopts.sct_erc_get = true;        ataopts.sct_erc_get = true;
       ataopts.sataphy = true;        ataopts.sataphy = true;
         ataopts.get_set_used = true;
         ataopts.get_aam = ataopts.get_apm = true;
         ataopts.get_security = true;
         ataopts.get_lookahead = ataopts.get_wcache = true;
       scsiopts.smart_background_log = true;        scsiopts.smart_background_log = true;
       scsiopts.smart_ss_media_log = true;        scsiopts.smart_ss_media_log = true;
       scsiopts.sasphy = true;        scsiopts.sasphy = true;
       if (!output_format_set)        if (!output_format_set)
        ataopts.output_format = 1; // '-f brief'        ataopts.output_format |= ata_print_options::FMT_BRIEF;
       break;        break;
     case 'v':      case 'v':
       // parse vendor-specific definitions of attributes        // parse vendor-specific definitions of attributes
Line 648  static const char * parse_options(int argc, char** arg Line 678  static const char * parse_options(int argc, char** arg
       } else if (!strcmp(optarg,"conveyance")) {        } else if (!strcmp(optarg,"conveyance")) {
         testcnt++;          testcnt++;
         ataopts.smart_selftest_type = CONVEYANCE_SELF_TEST;          ataopts.smart_selftest_type = CONVEYANCE_SELF_TEST;
         } else if (!strcmp(optarg,"force")) {
           ataopts.smart_selftest_force = true;
       } else if (!strcmp(optarg,"afterselect,on")) {        } else if (!strcmp(optarg,"afterselect,on")) {
         // scan remainder of disk after doing selected segment          // scan remainder of disk after doing selected segment
         ataopts.smart_selective_args.scan_after_select = 2;          ataopts.smart_selective_args.scan_after_select = 2;
Line 732  static const char * parse_options(int argc, char** arg Line 764  static const char * parse_options(int argc, char** arg
         badarg = true;          badarg = true;
       break;        break;
     case 'f':      case 'f':
      output_format_set = true;      if (!strcmp(optarg, "old")) {
      if (!strcmp(optarg,"old")) {        ataopts.output_format &= ~ata_print_options::FMT_BRIEF;
        ataopts.output_format = 0;        output_format_set = true;
      } else if (!strcmp(optarg,"brief")) { 
        ataopts.output_format = 1; 
      } else { 
        badarg = true; 
       }        }
         else if (!strcmp(optarg, "brief")) {
           ataopts.output_format |= ata_print_options::FMT_BRIEF;
           output_format_set = true;
         }
         else if (!strcmp(optarg, "hex"))
           ataopts.output_format |= ata_print_options::FMT_HEX_ID
                                 |  ata_print_options::FMT_HEX_VAL;
         else if (!strcmp(optarg, "hex,id"))
           ataopts.output_format |= ata_print_options::FMT_HEX_ID;
         else if (!strcmp(optarg, "hex,val"))
           ataopts.output_format |= ata_print_options::FMT_HEX_VAL;
         else
           badarg = true;
       break;        break;
     case 'B':      case 'B':
       {        {
Line 759  static const char * parse_options(int argc, char** arg Line 800  static const char * parse_options(int argc, char** arg
       EXIT(0);          EXIT(0);  
       break;        break;
   
       case 'g':
       case_s_continued: // -s, see above
       case opt_set: // --set
         {
           ataopts.get_set_used = true;
           bool get = (optchar == 'g');
           char name[16+1]; unsigned val;
           int n1 = -1, n2 = -1, n3 = -1, len = strlen(optarg);
           if (sscanf(optarg, "%16[^,=]%n%*[,=]%n%u%n", name, &n1, &n2, &val, &n3) >= 1
               && (n1 == len || (!get && n2 > 0))) {
             bool on  = (n2 > 0 && !strcmp(optarg+n2, "on"));
             bool off = (n2 > 0 && !strcmp(optarg+n2, "off"));
             if (n3 != len)
               val = ~0U;
   
             if (get && !strcmp(name, "all")) {
               ataopts.get_aam = ataopts.get_apm = true;
               ataopts.get_security = true;
               ataopts.get_lookahead = ataopts.get_wcache = true;
             }
             else if (!strcmp(name, "aam")) {
               if (get)
                 ataopts.get_aam = true;
               else if (off)
                 ataopts.set_aam = -1;
               else if (val <= 254)
                 ataopts.set_aam = val + 1;
               else {
                 sprintf(extraerror, "Option -s aam,N must have 0 <= N <= 254\n");
                 badarg = true;
               }
             }
             else if (!strcmp(name, "apm")) {
               if (get)
                 ataopts.get_apm = true;
               else if (off)
                 ataopts.set_apm = -1;
               else if (1 <= val && val <= 254)
                 ataopts.set_apm = val + 1;
               else {
                 sprintf(extraerror, "Option -s apm,N must have 1 <= N <= 254\n");
                 badarg = true;
               }
             }
             else if (!strcmp(name, "lookahead")) {
               if (get)
                 ataopts.get_lookahead = true;
               else if (off)
                 ataopts.set_lookahead = -1;
               else if (on)
                 ataopts.set_lookahead = 1;
               else
                 badarg = true;
             }
             else if (get && !strcmp(name, "security")) {
               ataopts.get_security = true;
             }
             else if (!get && !strcmp(optarg, "security-freeze")) {
               ataopts.set_security_freeze = true;
             }
             else if (!get && !strcmp(optarg, "standby,now")) {
                 ataopts.set_standby_now = true;
             }
             else if (!get && !strcmp(name, "standby")) {
               if (off)
                 ataopts.set_standby = 0 + 1;
               else if (val <= 255)
                 ataopts.set_standby = val + 1;
               else {
                 sprintf(extraerror, "Option -s standby,N must have 0 <= N <= 255\n");
                 badarg = true;
               }
             }
             else if (!strcmp(name, "wcache")) {
               if (get)
                 ataopts.get_wcache = true;
               else if (off)
                 ataopts.set_wcache = -1;
               else if (on)
                 ataopts.set_wcache = 1;
               else
                 badarg = true;
             }
             else
               badarg = true;
           }
           else
             badarg = true;
         }
         break;
   
     case opt_scan:      case opt_scan:
     case opt_scan_open:      case opt_scan_open:
       scan = optchar;        scan = optchar;
Line 773  static const char * parse_options(int argc, char** arg Line 905  static const char * parse_options(int argc, char** arg
       // Check whether the option is a long option that doesn't map to -h.        // Check whether the option is a long option that doesn't map to -h.
       if (arg[1] == '-' && optchar != 'h') {        if (arg[1] == '-' && optchar != 'h') {
         // Iff optopt holds a valid option then argument must be missing.          // Iff optopt holds a valid option then argument must be missing.
        if (optopt && (strchr(shortopts, optopt) != NULL)) {        if (optopt && (optopt >= opt_scan || strchr(shortopts, optopt))) {
           pout("=======> ARGUMENT REQUIRED FOR OPTION: %s\n", arg+2);            pout("=======> ARGUMENT REQUIRED FOR OPTION: %s\n", arg+2);
           printvalidarglistmessage(optopt);            printvalidarglistmessage(optopt);
         } else          } else
Line 783  static const char * parse_options(int argc, char** arg Line 915  static const char * parse_options(int argc, char** arg
         UsageSummary();          UsageSummary();
         EXIT(FAILCMD);          EXIT(FAILCMD);
       }        }
      if (optopt) {      if (0 < optopt && optopt < '~') {
         // Iff optopt holds a valid option then argument must be          // Iff optopt holds a valid option then argument must be
         // missing.  Note (BA) this logic seems to fail using Solaris          // missing.  Note (BA) this logic seems to fail using Solaris
         // getopt!          // getopt!
Line 807  static const char * parse_options(int argc, char** arg Line 939  static const char * parse_options(int argc, char** arg
       // It would be nice to print the actual option name given by the user        // 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        // here, but we just print the short form.  Please fix this if you know
       // a clean way to do it.        // a clean way to do it.
      pout("=======> INVALID ARGUMENT TO -%c: %s\n", optchar, optarg);      char optstr[] = { (char)optchar, 0 };
       pout("=======> INVALID ARGUMENT TO -%s: %s\n",
         (optchar == opt_set ? "-set" :
          optchar == opt_smart ? "-smart" : optstr), optarg);
       printvalidarglistmessage(optchar);        printvalidarglistmessage(optchar);
       if (extraerror[0])        if (extraerror[0])
         pout("=======> %s", extraerror);          pout("=======> %s", extraerror);
Line 1046  static int main_worker(int argc, char **argv) Line 1181  static int main_worker(int argc, char **argv)
   // Parse input arguments    // Parse input arguments
   ata_print_options ataopts;    ata_print_options ataopts;
   scsi_print_options scsiopts;    scsi_print_options scsiopts;
  const char * type = parse_options(argc, argv, ataopts, scsiopts);  bool print_type_only = false;
  const char * type = parse_options(argc, argv, ataopts, scsiopts, print_type_only);
  // '-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];    const char * name = argv[argc-1];
   

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>