|
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]; |
| |
|