summaryrefslogtreecommitdiffstats
path: root/plugins/check_ide_smart.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_ide_smart.c')
-rw-r--r--plugins/check_ide_smart.c580
1 files changed, 253 insertions, 327 deletions
diff --git a/plugins/check_ide_smart.c b/plugins/check_ide_smart.c
index 3872e341..16fe3d01 100644
--- a/plugins/check_ide_smart.c
+++ b/plugins/check_ide_smart.c
@@ -1,240 +1,211 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2 *
3* Monitoring check_ide_smart plugin 3 * Monitoring check_ide_smart plugin
4* ide-smart 1.3 - IDE S.M.A.R.T. checking tool 4 * ide-smart 1.3 - IDE S.M.A.R.T. checking tool
5* 5 *
6* License: GPL 6 * License: GPL
7* Copyright (C) 1998-1999 Ragnar Hojland Espinosa <ragnar@lightside.dhis.org> 7 * Copyright (C) 1998-1999 Ragnar Hojland Espinosa <ragnar@lightside.dhis.org>
8* 1998 Gadi Oxman <gadio@netvision.net.il> 8 * 1998 Gadi Oxman <gadio@netvision.net.il>
9* Copyright (c) 2000 Robert Dale <rdale@digital-mission.com> 9 * Copyright (c) 2000 Robert Dale <rdale@digital-mission.com>
10* Copyright (c) 2000-2007 Monitoring Plugins Development Team 10 * Copyright (c) 2000-2024 Monitoring Plugins Development Team
11* 11 *
12* Description: 12 * Description:
13* 13 *
14* This file contains the check_ide_smart plugin 14 * This file contains the check_ide_smart plugin
15* 15 *
16* This plugin checks a local hard drive with the (Linux specific) SMART 16 * This plugin checks a local hard drive with the (Linux specific) SMART
17* interface 17 * interface
18* 18 *
19* 19 *
20* This program is free software: you can redistribute it and/or modify 20 * This program is free software: you can redistribute it and/or modify
21* it under the terms of the GNU General Public License as published by 21 * it under the terms of the GNU General Public License as published by
22* the Free Software Foundation, either version 3 of the License, or 22 * the Free Software Foundation, either version 3 of the License, or
23* (at your option) any later version. 23 * (at your option) any later version.
24* 24 *
25* This program is distributed in the hope that it will be useful, 25 * This program is distributed in the hope that it will be useful,
26* but WITHOUT ANY WARRANTY; without even the implied warranty of 26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28* GNU General Public License for more details. 28 * GNU General Public License for more details.
29* 29 *
30* You should have received a copy of the GNU General Public License 30 * You should have received a copy of the GNU General Public License
31* along with this program. If not, see <http://www.gnu.org/licenses/>. 31 * along with this program. If not, see <http://www.gnu.org/licenses/>.
32* 32 *
33* 33 *
34*****************************************************************************/ 34 *****************************************************************************/
35 35
36const char *progname = "check_ide_smart"; 36const char *progname = "check_ide_smart";
37const char *copyright = "1998-2007"; 37const char *copyright = "1998-2024";
38const char *email = "devel@monitoring-plugins.org"; 38const char *email = "devel@monitoring-plugins.org";
39 39
40#include "common.h" 40#include "common.h"
41#include "utils.h" 41#include "utils.h"
42 42
43void print_help (void); 43static void print_help(void);
44void print_usage (void); 44void print_usage(void);
45 45
46#include <sys/stat.h> 46#include <sys/stat.h>
47#include <sys/ioctl.h> 47#include <sys/ioctl.h>
48#include <fcntl.h> 48#include <fcntl.h>
49#ifdef __linux__ 49#ifdef __linux__
50#include <linux/hdreg.h> 50# include <linux/hdreg.h>
51#include <linux/types.h> 51# include <linux/types.h>
52 52
53#define OPEN_MODE O_RDONLY 53# define OPEN_MODE O_RDONLY
54#endif /* __linux__ */ 54#endif /* __linux__ */
55#ifdef __NetBSD__ 55#ifdef __NetBSD__
56#include <sys/device.h> 56# include <sys/device.h>
57#include <sys/param.h> 57# include <sys/param.h>
58#include <sys/sysctl.h> 58# include <sys/sysctl.h>
59#include <sys/videoio.h> /* for __u8 and friends */ 59# include <sys/scsiio.h>
60#include <sys/scsiio.h> 60# include <sys/ataio.h>
61#include <sys/ataio.h> 61# include <dev/ata/atareg.h>
62#include <dev/ata/atareg.h> 62# include <dev/ic/wdcreg.h>
63#include <dev/ic/wdcreg.h> 63
64 64# define SMART_ENABLE WDSM_ENABLE_OPS
65#define SMART_ENABLE WDSM_ENABLE_OPS 65# define SMART_DISABLE WDSM_DISABLE_OPS
66#define SMART_DISABLE WDSM_DISABLE_OPS 66# define SMART_IMMEDIATE_OFFLINE WDSM_EXEC_OFFL_IMM
67#define SMART_IMMEDIATE_OFFLINE WDSM_EXEC_OFFL_IMM 67# define SMART_AUTO_OFFLINE 0xdb /* undefined in NetBSD headers */
68#define SMART_AUTO_OFFLINE 0xdb /* undefined in NetBSD headers */ 68
69 69# define OPEN_MODE O_RDWR
70#define OPEN_MODE O_RDWR
71#endif /* __NetBSD__ */ 70#endif /* __NetBSD__ */
72#include <errno.h> 71#include <errno.h>
73 72
74#define NR_ATTRIBUTES 30 73#define NR_ATTRIBUTES 30
75 74
76#define PREFAILURE 2 75#define PREFAILURE 2
77#define ADVISORY 1 76#define ADVISORY 1
78#define OPERATIONAL 0 77#define OPERATIONAL 0
79#define UNKNOWN -1 78#define UNKNOWN -1
80 79
81typedef struct threshold_s 80typedef struct threshold_s {
82{ 81 uint8_t id;
83 __u8 id; 82 uint8_t threshold;
84 __u8 threshold; 83 uint8_t reserved[10];
85 __u8 reserved[10]; 84} __attribute__((packed)) threshold_t;
86}
87__attribute__ ((packed)) threshold_t;
88 85
89typedef struct thresholds_s 86typedef struct thresholds_s {
90{ 87 uint16_t revision;
91 __u16 revision;
92 threshold_t thresholds[NR_ATTRIBUTES]; 88 threshold_t thresholds[NR_ATTRIBUTES];
93 __u8 reserved[18]; 89 uint8_t reserved[18];
94 __u8 vendor[131]; 90 uint8_t vendor[131];
95 __u8 checksum; 91 uint8_t checksum;
96} 92} __attribute__((packed)) thresholds_t;
97__attribute__ ((packed)) thresholds_t; 93
98 94typedef struct value_s {
99typedef struct value_s 95 uint8_t id;
100{ 96 uint16_t status;
101 __u8 id; 97 uint8_t value;
102 __u16 status; 98 uint8_t vendor[8];
103 __u8 value; 99} __attribute__((packed)) value_t;
104 __u8 vendor[8]; 100
105} 101typedef struct values_s {
106__attribute__ ((packed)) value_t; 102 uint16_t revision;
107
108typedef struct values_s
109{
110 __u16 revision;
111 value_t values[NR_ATTRIBUTES]; 103 value_t values[NR_ATTRIBUTES];
112 __u8 offline_status; 104 uint8_t offline_status;
113 __u8 vendor1; 105 uint8_t vendor1;
114 __u16 offline_timeout; 106 uint16_t offline_timeout;
115 __u8 vendor2; 107 uint8_t vendor2;
116 __u8 offline_capability; 108 uint8_t offline_capability;
117 __u16 smart_capability; 109 uint16_t smart_capability;
118 __u8 reserved[16]; 110 uint8_t reserved[16];
119 __u8 vendor[125]; 111 uint8_t vendor[125];
120 __u8 checksum; 112 uint8_t checksum;
121} 113} __attribute__((packed)) values_t;
122__attribute__ ((packed)) values_t; 114
123 115static struct {
124struct 116 uint8_t value;
125{
126 __u8 value;
127 char *text; 117 char *text;
128} 118} offline_status_text[] = {{0x00, "NeverStarted"}, {0x02, "Completed"}, {0x04, "Suspended"}, {0x05, "Aborted"}, {0x06, "Failed"}, {0, 0}};
129 119
130offline_status_text[] = 120static struct {
131 { 121 uint8_t value;
132 {0x00, "NeverStarted"},
133 {0x02, "Completed"},
134 {0x04, "Suspended"},
135 {0x05, "Aborted"},
136 {0x06, "Failed"},
137 {0, 0}
138 };
139
140struct
141{
142 __u8 value;
143 char *text; 122 char *text;
144} 123} smart_command[] = {{SMART_ENABLE, "SMART_ENABLE"},
145 124 {SMART_DISABLE, "SMART_DISABLE"},
146smart_command[] = 125 {SMART_IMMEDIATE_OFFLINE, "SMART_IMMEDIATE_OFFLINE"},
147 { 126 {SMART_AUTO_OFFLINE, "SMART_AUTO_OFFLINE"}};
148 {SMART_ENABLE, "SMART_ENABLE"}, 127
149 {SMART_DISABLE, "SMART_DISABLE"}, 128/* Index to smart_command table, keep in order */
150 {SMART_IMMEDIATE_OFFLINE, "SMART_IMMEDIATE_OFFLINE"}, 129enum SmartCommand {
151 {SMART_AUTO_OFFLINE, "SMART_AUTO_OFFLINE"} 130 SMART_CMD_ENABLE,
152 }; 131 SMART_CMD_DISABLE,
153 132 SMART_CMD_IMMEDIATE_OFFLINE,
154 133 SMART_CMD_AUTO_OFFLINE
155/* Index to smart_command table, keep in order */ 134};
156enum SmartCommand 135
157 { SMART_CMD_ENABLE, 136static char *get_offline_text(int);
158 SMART_CMD_DISABLE, 137static int smart_read_values(int, values_t *);
159 SMART_CMD_IMMEDIATE_OFFLINE, 138static int nagios(values_t *, thresholds_t *);
160 SMART_CMD_AUTO_OFFLINE 139static void print_value(value_t *, threshold_t *);
161 }; 140static void print_values(values_t *, thresholds_t *);
162 141static int smart_cmd_simple(int, enum SmartCommand, uint8_t, bool);
163char *get_offline_text (int); 142static int smart_read_thresholds(int, thresholds_t *);
164int smart_read_values (int, values_t *); 143static bool verbose = false;
165int nagios (values_t *, thresholds_t *); 144
166void print_value (value_t *, threshold_t *); 145int main(int argc, char *argv[]) {
167void print_values (values_t *, thresholds_t *);
168int smart_cmd_simple (int, enum SmartCommand, __u8, bool);
169int smart_read_thresholds (int, thresholds_t *);
170bool verbose = false;
171
172int
173main (int argc, char *argv[])
174{
175 char *device = NULL; 146 char *device = NULL;
176 int o, longindex; 147 int o;
148 int longindex;
177 int retval = 0; 149 int retval = 0;
178 150
179 thresholds_t thresholds; 151 thresholds_t thresholds;
180 values_t values; 152 values_t values;
181 int fd; 153 int fd;
182 154
183 static struct option longopts[] = { 155 static struct option longopts[] = {{"device", required_argument, 0, 'd'},
184 {"device", required_argument, 0, 'd'}, 156 {"immediate", no_argument, 0, 'i'},
185 {"immediate", no_argument, 0, 'i'}, 157 {"quiet-check", no_argument, 0, 'q'},
186 {"quiet-check", no_argument, 0, 'q'}, 158 {"auto-on", no_argument, 0, '1'},
187 {"auto-on", no_argument, 0, '1'}, 159 {"auto-off", no_argument, 0, '0'},
188 {"auto-off", no_argument, 0, '0'}, 160 {"nagios", no_argument, 0, 'n'}, /* DEPRECATED, but we still accept it */
189 {"nagios", no_argument, 0, 'n'}, /* DEPRECATED, but we still accept it */ 161 {"help", no_argument, 0, 'h'},
190 {"help", no_argument, 0, 'h'}, 162 {"version", no_argument, 0, 'V'},
191 {"version", no_argument, 0, 'V'}, 163 {0, 0, 0, 0}};
192 {0, 0, 0, 0}
193 };
194 164
195 /* Parse extra opts if any */ 165 /* Parse extra opts if any */
196 argv=np_extra_opts (&argc, argv, progname); 166 argv = np_extra_opts(&argc, argv, progname);
197 167
198 setlocale (LC_ALL, ""); 168 setlocale(LC_ALL, "");
199 bindtextdomain (PACKAGE, LOCALEDIR); 169 bindtextdomain(PACKAGE, LOCALEDIR);
200 textdomain (PACKAGE); 170 textdomain(PACKAGE);
201 171
202 while (true) { 172 while (true) {
203
204 o = getopt_long (argc, argv, "+d:iq10nhVv", longopts, &longindex);
205 173
206 if (o == -1 || o == EOF || o == 1) 174 o = getopt_long(argc, argv, "+d:iq10nhVv", longopts, &longindex);
175
176 if (o == -1 || o == EOF || o == 1) {
207 break; 177 break;
178 }
208 179
209 switch (o) { 180 switch (o) {
210 case 'd': 181 case 'd':
211 device = optarg; 182 device = optarg;
212 break; 183 break;
213 case 'q': 184 case 'q':
214 fprintf (stderr, "%s\n", _("DEPRECATION WARNING: the -q switch (quiet output) is no longer \"quiet\".")); 185 fprintf(stderr, "%s\n", _("DEPRECATION WARNING: the -q switch (quiet output) is no longer \"quiet\"."));
215 fprintf (stderr, "%s\n", _("Nagios-compatible output is now always returned.")); 186 fprintf(stderr, "%s\n", _("Nagios-compatible output is now always returned."));
216 break; 187 break;
217 case 'i': 188 case 'i':
218 case '1': 189 case '1':
219 case '0': 190 case '0':
220 printf ("%s\n", _("SMART commands are broken and have been disabled (See Notes in --help).")); 191 printf("%s\n", _("SMART commands are broken and have been disabled (See Notes in --help)."));
221 return STATE_CRITICAL; 192 return STATE_CRITICAL;
222 break; 193 break;
223 case 'n': 194 case 'n':
224 fprintf (stderr, "%s\n", _("DEPRECATION WARNING: the -n switch (Nagios-compatible output) is now the")); 195 fprintf(stderr, "%s\n", _("DEPRECATION WARNING: the -n switch (Nagios-compatible output) is now the"));
225 fprintf (stderr, "%s\n", _("default and will be removed from future releases.")); 196 fprintf(stderr, "%s\n", _("default and will be removed from future releases."));
226 break; 197 break;
227 case 'v': /* verbose */ 198 case 'v': /* verbose */
228 verbose = true; 199 verbose = true;
229 break; 200 break;
230 case 'h': 201 case 'h':
231 print_help (); 202 print_help();
232 return STATE_UNKNOWN; 203 return STATE_UNKNOWN;
233 case 'V': 204 case 'V':
234 print_revision (progname, NP_VERSION); 205 print_revision(progname, NP_VERSION);
235 return STATE_UNKNOWN; 206 return STATE_UNKNOWN;
236 default: 207 default:
237 usage5 (); 208 usage5();
238 } 209 }
239 } 210 }
240 211
@@ -243,36 +214,34 @@ main (int argc, char *argv[])
243 } 214 }
244 215
245 if (!device) { 216 if (!device) {
246 print_help (); 217 print_help();
247 return STATE_UNKNOWN; 218 return STATE_UNKNOWN;
248 } 219 }
249 220
250 fd = open (device, OPEN_MODE); 221 fd = open(device, OPEN_MODE);
251 222
252 if (fd < 0) { 223 if (fd < 0) {
253 printf (_("CRITICAL - Couldn't open device %s: %s\n"), device, strerror (errno)); 224 printf(_("CRITICAL - Couldn't open device %s: %s\n"), device, strerror(errno));
254 return STATE_CRITICAL; 225 return STATE_CRITICAL;
255 } 226 }
256 227
257 if (smart_cmd_simple (fd, SMART_CMD_ENABLE, 0, false)) { 228 if (smart_cmd_simple(fd, SMART_CMD_ENABLE, 0, false)) {
258 printf (_("CRITICAL - SMART_CMD_ENABLE\n")); 229 printf(_("CRITICAL - SMART_CMD_ENABLE\n"));
259 return STATE_CRITICAL; 230 return STATE_CRITICAL;
260 } 231 }
261 232
262 smart_read_values (fd, &values); 233 smart_read_values(fd, &values);
263 smart_read_thresholds (fd, &thresholds); 234 smart_read_thresholds(fd, &thresholds);
264 retval = nagios (&values, &thresholds); 235 retval = nagios(&values, &thresholds);
265 if (verbose) print_values (&values, &thresholds); 236 if (verbose) {
237 print_values(&values, &thresholds);
238 }
266 239
267 close (fd); 240 close(fd);
268 return retval; 241 return retval;
269} 242}
270 243
271 244char *get_offline_text(int status) {
272
273char *
274get_offline_text (int status)
275{
276 int i; 245 int i;
277 for (i = 0; offline_status_text[i].text; i++) { 246 for (i = 0; offline_status_text[i].text; i++) {
278 if (offline_status_text[i].value == status) { 247 if (offline_status_text[i].value == status) {
@@ -282,24 +251,20 @@ get_offline_text (int status)
282 return "UNKNOWN"; 251 return "UNKNOWN";
283} 252}
284 253
285 254int smart_read_values(int fd, values_t *values) {
286
287int
288smart_read_values (int fd, values_t * values)
289{
290#ifdef __linux__ 255#ifdef __linux__
291 int e; 256 int e;
292 __u8 args[4 + 512]; 257 uint8_t args[4 + 512];
293 args[0] = WIN_SMART; 258 args[0] = WIN_SMART;
294 args[1] = 0; 259 args[1] = 0;
295 args[2] = SMART_READ_VALUES; 260 args[2] = SMART_READ_VALUES;
296 args[3] = 1; 261 args[3] = 1;
297 if (ioctl (fd, HDIO_DRIVE_CMD, &args)) { 262 if (ioctl(fd, HDIO_DRIVE_CMD, &args)) {
298 e = errno; 263 e = errno;
299 printf (_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror (errno)); 264 printf(_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror(errno));
300 return e; 265 return e;
301 } 266 }
302 memcpy (values, args + 4, 512); 267 memcpy(values, args + 4, 512);
303#endif /* __linux__ */ 268#endif /* __linux__ */
304#ifdef __NetBSD__ 269#ifdef __NetBSD__
305 struct atareq req; 270 struct atareq req;
@@ -317,13 +282,14 @@ smart_read_values (int fd, values_t * values)
317 req.cylinder = WDSMART_CYL; 282 req.cylinder = WDSMART_CYL;
318 283
319 if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { 284 if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) {
320 if (req.retsts != ATACMD_OK) 285 if (req.retsts != ATACMD_OK) {
321 errno = ENODEV; 286 errno = ENODEV;
287 }
322 } 288 }
323 289
324 if (errno != 0) { 290 if (errno != 0) {
325 int e = errno; 291 int e = errno;
326 printf (_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror (errno)); 292 printf(_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror(errno));
327 return e; 293 return e;
328 } 294 }
329 295
@@ -332,13 +298,9 @@ smart_read_values (int fd, values_t * values)
332 return 0; 298 return 0;
333} 299}
334 300
335 301int nagios(values_t *p, thresholds_t *t) {
336 302 value_t *value = p->values;
337int 303 threshold_t *threshold = t->thresholds;
338nagios (values_t * p, thresholds_t * t)
339{
340 value_t * value = p->values;
341 threshold_t * threshold = t->thresholds;
342 int status = OPERATIONAL; 304 int status = OPERATIONAL;
343 int prefailure = 0; 305 int prefailure = 0;
344 int advisory = 0; 306 int advisory = 0;
@@ -353,13 +315,11 @@ nagios (values_t * p, thresholds_t * t)
353 if (value->status & 1) { 315 if (value->status & 1) {
354 status = PREFAILURE; 316 status = PREFAILURE;
355 ++prefailure; 317 ++prefailure;
356 } 318 } else {
357 else {
358 status = ADVISORY; 319 status = ADVISORY;
359 ++advisory; 320 ++advisory;
360 } 321 }
361 } 322 } else {
362 else {
363 ++passed; 323 ++passed;
364 } 324 }
365 ++total; 325 ++total;
@@ -369,96 +329,66 @@ nagios (values_t * p, thresholds_t * t)
369 } 329 }
370 switch (status) { 330 switch (status) {
371 case PREFAILURE: 331 case PREFAILURE:
372 printf (_("CRITICAL - %d Harddrive PreFailure%cDetected! %d/%d tests failed.\n"), 332 printf(_("CRITICAL - %d Harddrive PreFailure%cDetected! %d/%d tests failed.\n"), prefailure, prefailure > 1 ? 's' : ' ', failed,
373 prefailure, 333 total);
374 prefailure > 1 ? 's' : ' ', 334 status = STATE_CRITICAL;
375 failed,
376 total);
377 status=STATE_CRITICAL;
378 break; 335 break;
379 case ADVISORY: 336 case ADVISORY:
380 printf (_("WARNING - %d Harddrive Advisor%s Detected. %d/%d tests failed.\n"), 337 printf(_("WARNING - %d Harddrive Advisor%s Detected. %d/%d tests failed.\n"), advisory, advisory > 1 ? "ies" : "y", failed, total);
381 advisory, 338 status = STATE_WARNING;
382 advisory > 1 ? "ies" : "y",
383 failed,
384 total);
385 status=STATE_WARNING;
386 break; 339 break;
387 case OPERATIONAL: 340 case OPERATIONAL:
388 printf (_("OK - Operational (%d/%d tests passed)\n"), passed, total); 341 printf(_("OK - Operational (%d/%d tests passed)\n"), passed, total);
389 status=STATE_OK; 342 status = STATE_OK;
390 break; 343 break;
391 default: 344 default:
392 printf (_("ERROR - Status '%d' unknown. %d/%d tests passed\n"), status, 345 printf(_("ERROR - Status '%d' unknown. %d/%d tests passed\n"), status, passed, total);
393 passed, total);
394 status = STATE_UNKNOWN; 346 status = STATE_UNKNOWN;
395 break; 347 break;
396 } 348 }
397 return status; 349 return status;
398} 350}
399 351
400 352void print_value(value_t *p, threshold_t *t) {
401 353 printf("Id=%3d, Status=%2d {%s , %s}, Value=%3d, Threshold=%3d, %s\n", p->id, p->status, p->status & 1 ? "PreFailure" : "Advisory ",
402void 354 p->status & 2 ? "OnLine " : "OffLine", p->value, t->threshold, p->value >= t->threshold ? "Passed" : "Failed");
403print_value (value_t * p, threshold_t * t)
404{
405 printf ("Id=%3d, Status=%2d {%s , %s}, Value=%3d, Threshold=%3d, %s\n",
406 p->id, p->status, p->status & 1 ? "PreFailure" : "Advisory ",
407 p->status & 2 ? "OnLine " : "OffLine", p->value, t->threshold,
408 p->value >= t->threshold ? "Passed" : "Failed");
409} 355}
410 356
411 357void print_values(values_t *p, thresholds_t *t) {
412 358 value_t *value = p->values;
413void 359 threshold_t *threshold = t->thresholds;
414print_values (values_t * p, thresholds_t * t)
415{
416 value_t * value = p->values;
417 threshold_t * threshold = t->thresholds;
418 int i; 360 int i;
419 for (i = 0; i < NR_ATTRIBUTES; i++) { 361 for (i = 0; i < NR_ATTRIBUTES; i++) {
420 if (value->id && threshold->id && value->id == threshold->id) { 362 if (value->id && threshold->id && value->id == threshold->id) {
421 print_value (value++, threshold++); 363 print_value(value++, threshold++);
422 } 364 }
423 } 365 }
424 printf 366 printf(_("OffLineStatus=%d {%s}, AutoOffLine=%s, OffLineTimeout=%d minutes\n"), p->offline_status,
425 (_("OffLineStatus=%d {%s}, AutoOffLine=%s, OffLineTimeout=%d minutes\n"), 367 get_offline_text(p->offline_status & 0x7f), (p->offline_status & 0x80 ? "Yes" : "No"), p->offline_timeout / 60);
426 p->offline_status, 368 printf(_("OffLineCapability=%d {%s %s %s}\n"), p->offline_capability, p->offline_capability & 1 ? "Immediate" : "",
427 get_offline_text (p->offline_status & 0x7f), 369 p->offline_capability & 2 ? "Auto" : "", p->offline_capability & 4 ? "AbortOnCmd" : "SuspendOnCmd");
428 (p->offline_status & 0x80 ? "Yes" : "No"), 370 printf(_("SmartRevision=%d, CheckSum=%d, SmartCapability=%d {%s %s}\n"), p->revision, p->checksum, p->smart_capability,
429 p->offline_timeout / 60); 371 p->smart_capability & 1 ? "SaveOnStandBy" : "", p->smart_capability & 2 ? "AutoSave" : "");
430 printf
431 (_("OffLineCapability=%d {%s %s %s}\n"),
432 p->offline_capability,
433 p->offline_capability & 1 ? "Immediate" : "",
434 p->offline_capability & 2 ? "Auto" : "",
435 p->offline_capability & 4 ? "AbortOnCmd" : "SuspendOnCmd");
436 printf
437 (_("SmartRevision=%d, CheckSum=%d, SmartCapability=%d {%s %s}\n"),
438 p->revision,
439 p->checksum,
440 p->smart_capability,
441 p->smart_capability & 1 ? "SaveOnStandBy" : "",
442 p->smart_capability & 2 ? "AutoSave" : "");
443} 372}
444 373
445 374int smart_cmd_simple(int fd, enum SmartCommand command, uint8_t val0, bool show_error) {
446int smart_cmd_simple (int fd, enum SmartCommand command, __u8 val0, bool show_error) {
447 int e = STATE_UNKNOWN; 375 int e = STATE_UNKNOWN;
448#ifdef __linux__ 376#ifdef __linux__
449 __u8 args[4]; 377 uint8_t args[4];
450 args[0] = WIN_SMART; 378 args[0] = WIN_SMART;
451 args[1] = val0; 379 args[1] = val0;
452 args[2] = smart_command[command].value; 380 args[2] = smart_command[command].value;
453 args[3] = 0; 381 args[3] = 0;
454 if (ioctl (fd, HDIO_DRIVE_CMD, &args)) { 382 if (ioctl(fd, HDIO_DRIVE_CMD, &args)) {
455 e = STATE_CRITICAL; 383 e = STATE_CRITICAL;
456 if (show_error) 384 if (show_error) {
457 printf (_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror (errno)); 385 printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno));
386 }
458 } else { 387 } else {
459 e = STATE_OK; 388 e = STATE_OK;
460 if (show_error) 389 if (show_error) {
461 printf (_("OK - Command sent (%s)\n"), smart_command[command].text); 390 printf(_("OK - Command sent (%s)\n"), smart_command[command].text);
391 }
462 } 392 }
463 393
464#endif /* __linux__ */ 394#endif /* __linux__ */
@@ -474,44 +404,44 @@ int smart_cmd_simple (int fd, enum SmartCommand command, __u8 val0, bool show_er
474 req.sec_count = val0; 404 req.sec_count = val0;
475 405
476 if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { 406 if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) {
477 if (req.retsts != ATACMD_OK) 407 if (req.retsts != ATACMD_OK) {
478 errno = ENODEV; 408 errno = ENODEV;
479 if (req.cylinder != WDSMART_CYL) 409 }
410 if (req.cylinder != WDSMART_CYL) {
480 errno = ENODEV; 411 errno = ENODEV;
412 }
481 } 413 }
482 414
483 if (errno != 0) { 415 if (errno != 0) {
484 e = STATE_CRITICAL; 416 e = STATE_CRITICAL;
485 if (show_error) 417 if (show_error) {
486 printf (_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror (errno)); 418 printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno));
419 }
487 } else { 420 } else {
488 e = STATE_OK; 421 e = STATE_OK;
489 if (show_error) 422 if (show_error) {
490 printf (_("OK - Command sent (%s)\n"), smart_command[command].text); 423 printf(_("OK - Command sent (%s)\n"), smart_command[command].text);
424 }
491 } 425 }
492 426
493#endif /* __NetBSD__ */ 427#endif /* __NetBSD__ */
494 return e; 428 return e;
495} 429}
496 430
497 431int smart_read_thresholds(int fd, thresholds_t *thresholds) {
498
499int
500smart_read_thresholds (int fd, thresholds_t * thresholds)
501{
502#ifdef __linux__ 432#ifdef __linux__
503 int e; 433 int e;
504 __u8 args[4 + 512]; 434 uint8_t args[4 + 512];
505 args[0] = WIN_SMART; 435 args[0] = WIN_SMART;
506 args[1] = 0; 436 args[1] = 0;
507 args[2] = SMART_READ_THRESHOLDS; 437 args[2] = SMART_READ_THRESHOLDS;
508 args[3] = 1; 438 args[3] = 1;
509 if (ioctl (fd, HDIO_DRIVE_CMD, &args)) { 439 if (ioctl(fd, HDIO_DRIVE_CMD, &args)) {
510 e = errno; 440 e = errno;
511 printf (_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror (errno)); 441 printf(_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror(errno));
512 return e; 442 return e;
513 } 443 }
514 memcpy (thresholds, args + 4, 512); 444 memcpy(thresholds, args + 4, 512);
515#endif /* __linux__ */ 445#endif /* __linux__ */
516#ifdef __NetBSD__ 446#ifdef __NetBSD__
517 struct atareq req; 447 struct atareq req;
@@ -529,13 +459,14 @@ smart_read_thresholds (int fd, thresholds_t * thresholds)
529 req.cylinder = WDSMART_CYL; 459 req.cylinder = WDSMART_CYL;
530 460
531 if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { 461 if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) {
532 if (req.retsts != ATACMD_OK) 462 if (req.retsts != ATACMD_OK) {
533 errno = ENODEV; 463 errno = ENODEV;
464 }
534 } 465 }
535 466
536 if (errno != 0) { 467 if (errno != 0) {
537 int e = errno; 468 int e = errno;
538 printf (_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror (errno)); 469 printf(_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror(errno));
539 return e; 470 return e;
540 } 471 }
541 472
@@ -544,45 +475,43 @@ smart_read_thresholds (int fd, thresholds_t * thresholds)
544 return 0; 475 return 0;
545} 476}
546 477
478void print_help(void) {
479 print_revision(progname, NP_VERSION);
547 480
548void 481 printf("(C) 1999 Ragnar Hojland Espinosa <ragnar@lightside.dhis.org>\n");
549print_help (void) 482 printf("Plugin implementation - 1999 Robert Dale <rdale@digital-mission.com>\n");
550{ 483 printf(COPYRIGHT, copyright, email);
551 print_revision (progname, NP_VERSION);
552
553 printf ("(C) 1999 Ragnar Hojland Espinosa <ragnar@lightside.dhis.org>\n");
554 printf ("Plugin implementation - 1999 Robert Dale <rdale@digital-mission.com>\n");
555 printf (COPYRIGHT, copyright, email);
556 484
557 printf (_("This plugin checks a local hard drive with the (Linux specific) SMART interface [http://smartlinux.sourceforge.net/smart/index.php].")); 485 printf(_("This plugin checks a local hard drive with the (Linux specific) SMART interface "
486 "[http://smartlinux.sourceforge.net/smart/index.php]."));
558 487
559 printf ("\n\n"); 488 printf("\n\n");
560 489
561 print_usage (); 490 print_usage();
562 491
563 printf (UT_HELP_VRSN); 492 printf(UT_HELP_VRSN);
564 printf (UT_EXTRA_OPTS); 493 printf(UT_EXTRA_OPTS);
565 494
566 printf (" %s\n", "-d, --device=DEVICE"); 495 printf(" %s\n", "-d, --device=DEVICE");
567 printf (" %s\n", _("Select device DEVICE")); 496 printf(" %s\n", _("Select device DEVICE"));
568 printf (" %s\n", _("Note: if the device is specified without this option, any further option will")); 497 printf(" %s\n", _("Note: if the device is specified without this option, any further option will"));
569 printf (" %s\n", _("be ignored.")); 498 printf(" %s\n", _("be ignored."));
570 499
571 printf (UT_VERBOSE); 500 printf(UT_VERBOSE);
572 501
573 printf ("\n"); 502 printf("\n");
574 printf ("%s\n", _("Notes:")); 503 printf("%s\n", _("Notes:"));
575 printf (" %s\n", _("The SMART command modes (-i/--immediate, -0/--auto-off and -1/--auto-on) were")); 504 printf(" %s\n", _("The SMART command modes (-i/--immediate, -0/--auto-off and -1/--auto-on) were"));
576 printf (" %s\n", _("broken in an underhand manner and have been disabled. You can use smartctl")); 505 printf(" %s\n", _("broken in an underhand manner and have been disabled. You can use smartctl"));
577 printf (" %s\n", _("instead:")); 506 printf(" %s\n", _("instead:"));
578 printf (" %s\n", _("-0/--auto-off: use \"smartctl --offlineauto=off\"")); 507 printf(" %s\n", _("-0/--auto-off: use \"smartctl --offlineauto=off\""));
579 printf (" %s\n", _("-1/--auto-on: use \"smartctl --offlineauto=on\"")); 508 printf(" %s\n", _("-1/--auto-on: use \"smartctl --offlineauto=on\""));
580 printf (" %s\n", _("-i/--immediate: use \"smartctl --test=offline\"")); 509 printf(" %s\n", _("-i/--immediate: use \"smartctl --test=offline\""));
581 510
582 printf (UT_SUPPORT); 511 printf(UT_SUPPORT);
583} 512}
584 513
585 /* todo : add to the long nanual as example 514/* todo : add to the long nanual as example
586 * 515 *
587 * Run with: check_ide-smart --nagios [-d] <DRIVE> 516 * Run with: check_ide-smart --nagios [-d] <DRIVE>
588 * Where DRIVE is an IDE drive, ie. /dev/hda, /dev/hdb, /dev/hdc 517 * Where DRIVE is an IDE drive, ie. /dev/hda, /dev/hdb, /dev/hdc
@@ -593,10 +522,7 @@ print_help (void)
593 * - Returns -1 not too often 522 * - Returns -1 not too often
594 */ 523 */
595 524
596 525void print_usage(void) {
597void 526 printf("%s\n", _("Usage:"));
598print_usage (void) 527 printf("%s [-d <device>] [-v]", progname);
599{
600 printf ("%s\n", _("Usage:"));
601 printf ("%s [-d <device>] [-v]", progname);
602} 528}