summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2026-01-09 15:07:48 +0100
committerGitHub <noreply@github.com>2026-01-09 15:07:48 +0100
commit6d1edb3df2feb7fca636226b520e76b0366a7ddd (patch)
treed20769e0a61ac2ba76920190050d3e0a3e7c85b7
parentf694f4cd4dfead0da6feab04d92335d9bbe185b6 (diff)
parentda4fb28fca51b180d50608b0c847b1c0927cd8c5 (diff)
downloadmonitoring-plugins-6d1edb3df2feb7fca636226b520e76b0366a7ddd.tar.gz
Merge pull request #2111 from RincewindsHat/refactor/check_ide_smart
Refactor check_ide_smart
-rw-r--r--plugins/Makefile.am1
-rw-r--r--plugins/check_ide_smart.c259
-rw-r--r--plugins/check_ide_smart.d/config.h15
3 files changed, 157 insertions, 118 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index fa159f4a..a35f273e 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -66,6 +66,7 @@ EXTRA_DIST = t \
66 check_hpjd.d \ 66 check_hpjd.d \
67 check_game.d \ 67 check_game.d \
68 check_radius.d \ 68 check_radius.d \
69 check_ide_smart.d \
69 check_curl.d \ 70 check_curl.d \
70 check_disk.d \ 71 check_disk.d \
71 check_time.d \ 72 check_time.d \
diff --git a/plugins/check_ide_smart.c b/plugins/check_ide_smart.c
index 16fe3d01..c1325cf9 100644
--- a/plugins/check_ide_smart.c
+++ b/plugins/check_ide_smart.c
@@ -39,6 +39,8 @@ const 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#include "check_ide_smart.d/config.h"
43#include "states.h"
42 44
43static void print_help(void); 45static void print_help(void);
44void print_usage(void); 46void print_usage(void);
@@ -46,6 +48,7 @@ void print_usage(void);
46#include <sys/stat.h> 48#include <sys/stat.h>
47#include <sys/ioctl.h> 49#include <sys/ioctl.h>
48#include <fcntl.h> 50#include <fcntl.h>
51
49#ifdef __linux__ 52#ifdef __linux__
50# include <linux/hdreg.h> 53# include <linux/hdreg.h>
51# include <linux/types.h> 54# include <linux/types.h>
@@ -77,30 +80,30 @@ void print_usage(void);
77#define OPERATIONAL 0 80#define OPERATIONAL 0
78#define UNKNOWN -1 81#define UNKNOWN -1
79 82
80typedef struct threshold_s { 83typedef struct {
81 uint8_t id; 84 uint8_t id;
82 uint8_t threshold; 85 uint8_t threshold;
83 uint8_t reserved[10]; 86 uint8_t reserved[10];
84} __attribute__((packed)) threshold_t; 87} __attribute__((packed)) smart_threshold;
85 88
86typedef struct thresholds_s { 89typedef struct {
87 uint16_t revision; 90 uint16_t revision;
88 threshold_t thresholds[NR_ATTRIBUTES]; 91 smart_threshold thresholds[NR_ATTRIBUTES];
89 uint8_t reserved[18]; 92 uint8_t reserved[18];
90 uint8_t vendor[131]; 93 uint8_t vendor[131];
91 uint8_t checksum; 94 uint8_t checksum;
92} __attribute__((packed)) thresholds_t; 95} __attribute__((packed)) smart_thresholds;
93 96
94typedef struct value_s { 97typedef struct {
95 uint8_t id; 98 uint8_t id;
96 uint16_t status; 99 uint16_t status;
97 uint8_t value; 100 uint8_t value;
98 uint8_t vendor[8]; 101 uint8_t vendor[8];
99} __attribute__((packed)) value_t; 102} __attribute__((packed)) smart_value;
100 103
101typedef struct values_s { 104typedef struct {
102 uint16_t revision; 105 uint16_t revision;
103 value_t values[NR_ATTRIBUTES]; 106 smart_value values[NR_ATTRIBUTES];
104 uint8_t offline_status; 107 uint8_t offline_status;
105 uint8_t vendor1; 108 uint8_t vendor1;
106 uint16_t offline_timeout; 109 uint16_t offline_timeout;
@@ -110,7 +113,7 @@ typedef struct values_s {
110 uint8_t reserved[16]; 113 uint8_t reserved[16];
111 uint8_t vendor[125]; 114 uint8_t vendor[125];
112 uint8_t checksum; 115 uint8_t checksum;
113} __attribute__((packed)) values_t; 116} __attribute__((packed)) smart_values;
114 117
115static struct { 118static struct {
116 uint8_t value; 119 uint8_t value;
@@ -133,25 +136,20 @@ enum SmartCommand {
133 SMART_CMD_AUTO_OFFLINE 136 SMART_CMD_AUTO_OFFLINE
134}; 137};
135 138
136static char *get_offline_text(int); 139static char *get_offline_text(int /*status*/);
137static int smart_read_values(int, values_t *); 140static int smart_read_values(int /*fd*/, smart_values * /*values*/);
138static int nagios(values_t *, thresholds_t *); 141static mp_state_enum compare_values_and_thresholds(smart_values * /*p*/, smart_thresholds * /*t*/);
139static void print_value(value_t *, threshold_t *); 142static void print_value(smart_value * /*p*/, smart_threshold * /*t*/);
140static void print_values(values_t *, thresholds_t *); 143static void print_values(smart_values * /*p*/, smart_thresholds * /*t*/);
141static int smart_cmd_simple(int, enum SmartCommand, uint8_t, bool); 144static mp_state_enum smart_cmd_simple(int /*fd*/, enum SmartCommand /*command*/, uint8_t /*val0*/, bool /*show_error*/);
142static int smart_read_thresholds(int, thresholds_t *); 145static int smart_read_thresholds(int /*fd*/, smart_thresholds * /*thresholds*/);
143static bool verbose = false; 146static int verbose = 0;
144 147
145int main(int argc, char *argv[]) { 148typedef struct {
146 char *device = NULL; 149 int errorcode;
147 int o; 150 check_ide_smart_config config;
148 int longindex; 151} check_ide_smart_config_wrapper;
149 int retval = 0; 152static check_ide_smart_config_wrapper process_arguments(int argc, char **argv) {
150
151 thresholds_t thresholds;
152 values_t values;
153 int fd;
154
155 static struct option longopts[] = {{"device", required_argument, 0, 'd'}, 153 static struct option longopts[] = {{"device", required_argument, 0, 'd'},
156 {"immediate", no_argument, 0, 'i'}, 154 {"immediate", no_argument, 0, 'i'},
157 {"quiet-check", no_argument, 0, 'q'}, 155 {"quiet-check", no_argument, 0, 'q'},
@@ -162,24 +160,22 @@ int main(int argc, char *argv[]) {
162 {"version", no_argument, 0, 'V'}, 160 {"version", no_argument, 0, 'V'},
163 {0, 0, 0, 0}}; 161 {0, 0, 0, 0}};
164 162
165 /* Parse extra opts if any */ 163 check_ide_smart_config_wrapper result = {
166 argv = np_extra_opts(&argc, argv, progname); 164 .errorcode = OK,
167 165 .config = check_ide_smart_init(),
168 setlocale(LC_ALL, ""); 166 };
169 bindtextdomain(PACKAGE, LOCALEDIR);
170 textdomain(PACKAGE);
171 167
172 while (true) { 168 while (true) {
169 int longindex = 0;
170 int option_index = getopt_long(argc, argv, "+d:iq10nhVv", longopts, &longindex);
173 171
174 o = getopt_long(argc, argv, "+d:iq10nhVv", longopts, &longindex); 172 if (option_index == -1 || option_index == EOF || option_index == 1) {
175
176 if (o == -1 || o == EOF || o == 1) {
177 break; 173 break;
178 } 174 }
179 175
180 switch (o) { 176 switch (option_index) {
181 case 'd': 177 case 'd':
182 device = optarg; 178 result.config.device = optarg;
183 break; 179 break;
184 case 'q': 180 case 'q':
185 fprintf(stderr, "%s\n", _("DEPRECATION WARNING: the -q switch (quiet output) is no longer \"quiet\".")); 181 fprintf(stderr, "%s\n", _("DEPRECATION WARNING: the -q switch (quiet output) is no longer \"quiet\"."));
@@ -189,84 +185,103 @@ int main(int argc, char *argv[]) {
189 case '1': 185 case '1':
190 case '0': 186 case '0':
191 printf("%s\n", _("SMART commands are broken and have been disabled (See Notes in --help).")); 187 printf("%s\n", _("SMART commands are broken and have been disabled (See Notes in --help)."));
192 return STATE_CRITICAL; 188 result.errorcode = ERROR;
189 return result;
193 break; 190 break;
194 case 'n': 191 case 'n':
195 fprintf(stderr, "%s\n", _("DEPRECATION WARNING: the -n switch (Nagios-compatible output) is now the")); 192 fprintf(stderr, "%s\n", _("DEPRECATION WARNING: the -n switch (Nagios-compatible output) is now the"));
196 fprintf(stderr, "%s\n", _("default and will be removed from future releases.")); 193 fprintf(stderr, "%s\n", _("default and will be removed from future releases."));
197 break; 194 break;
198 case 'v': /* verbose */ 195 case 'v': /* verbose */
199 verbose = true; 196 verbose++;
200 break; 197 break;
201 case 'h': 198 case 'h':
202 print_help(); 199 print_help();
203 return STATE_UNKNOWN; 200 exit(STATE_UNKNOWN);
204 case 'V': 201 case 'V':
205 print_revision(progname, NP_VERSION); 202 print_revision(progname, NP_VERSION);
206 return STATE_UNKNOWN; 203 exit(STATE_UNKNOWN);
207 default: 204 default:
208 usage5(); 205 usage5();
209 } 206 }
210 } 207 }
211 208
212 if (optind < argc) { 209 if (optind < argc) {
213 device = argv[optind]; 210 result.config.device = argv[optind];
214 } 211 }
215 212
216 if (!device) { 213 if (result.config.device == NULL) {
217 print_help(); 214 print_help();
218 return STATE_UNKNOWN; 215 exit(STATE_UNKNOWN);
216 }
217
218 return result;
219}
220
221int main(int argc, char *argv[]) {
222 setlocale(LC_ALL, "");
223 bindtextdomain(PACKAGE, LOCALEDIR);
224 textdomain(PACKAGE);
225
226 /* Parse extra opts if any */
227 argv = np_extra_opts(&argc, argv, progname);
228
229 check_ide_smart_config_wrapper tmp_config = process_arguments(argc, argv);
230
231 if (tmp_config.errorcode != OK) {
232 die(STATE_UNKNOWN, _("Failed to parse commandline"));
219 } 233 }
220 234
221 fd = open(device, OPEN_MODE); 235 check_ide_smart_config config = tmp_config.config;
222 236
223 if (fd < 0) { 237 int device_file_descriptor = open(config.device, OPEN_MODE);
224 printf(_("CRITICAL - Couldn't open device %s: %s\n"), device, strerror(errno)); 238
239 if (device_file_descriptor < 0) {
240 printf(_("CRITICAL - Couldn't open device %s: %s\n"), config.device, strerror(errno));
225 return STATE_CRITICAL; 241 return STATE_CRITICAL;
226 } 242 }
227 243
228 if (smart_cmd_simple(fd, SMART_CMD_ENABLE, 0, false)) { 244 if (smart_cmd_simple(device_file_descriptor, SMART_CMD_ENABLE, 0, false)) {
229 printf(_("CRITICAL - SMART_CMD_ENABLE\n")); 245 printf(_("CRITICAL - SMART_CMD_ENABLE\n"));
230 return STATE_CRITICAL; 246 return STATE_CRITICAL;
231 } 247 }
232 248
233 smart_read_values(fd, &values); 249 smart_values values;
234 smart_read_thresholds(fd, &thresholds); 250 smart_read_values(device_file_descriptor, &values);
235 retval = nagios(&values, &thresholds); 251 smart_thresholds thresholds;
252 smart_read_thresholds(device_file_descriptor, &thresholds);
253 mp_state_enum retval = compare_values_and_thresholds(&values, &thresholds);
236 if (verbose) { 254 if (verbose) {
237 print_values(&values, &thresholds); 255 print_values(&values, &thresholds);
238 } 256 }
239 257
240 close(fd); 258 close(device_file_descriptor);
241 return retval; 259 return retval;
242} 260}
243 261
244char *get_offline_text(int status) { 262char *get_offline_text(int status) {
245 int i; 263 for (int index = 0; offline_status_text[index].text; index++) {
246 for (i = 0; offline_status_text[i].text; i++) { 264 if (offline_status_text[index].value == status) {
247 if (offline_status_text[i].value == status) { 265 return offline_status_text[index].text;
248 return offline_status_text[i].text;
249 } 266 }
250 } 267 }
251 return "UNKNOWN"; 268 return "UNKNOWN";
252} 269}
253 270
254int smart_read_values(int fd, values_t *values) { 271int smart_read_values(int file_descriptor, smart_values *values) {
255#ifdef __linux__ 272#ifdef __linux__
256 int e;
257 uint8_t args[4 + 512]; 273 uint8_t args[4 + 512];
258 args[0] = WIN_SMART; 274 args[0] = WIN_SMART;
259 args[1] = 0; 275 args[1] = 0;
260 args[2] = SMART_READ_VALUES; 276 args[2] = SMART_READ_VALUES;
261 args[3] = 1; 277 args[3] = 1;
262 if (ioctl(fd, HDIO_DRIVE_CMD, &args)) { 278 if (ioctl(file_descriptor, HDIO_DRIVE_CMD, &args)) {
263 e = errno; 279 int errno_storage = errno;
264 printf(_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror(errno)); 280 printf(_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror(errno));
265 return e; 281 return errno_storage;
266 } 282 }
267 memcpy(values, args + 4, 512); 283 memcpy(values, args + 4, 512);
268#endif /* __linux__ */ 284#elif defined __NetBSD__
269#ifdef __NetBSD__
270 struct atareq req; 285 struct atareq req;
271 unsigned char inbuf[DEV_BSIZE]; 286 unsigned char inbuf[DEV_BSIZE];
272 287
@@ -281,34 +296,37 @@ int smart_read_values(int fd, values_t *values) {
281 req.datalen = sizeof(inbuf); 296 req.datalen = sizeof(inbuf);
282 req.cylinder = WDSMART_CYL; 297 req.cylinder = WDSMART_CYL;
283 298
284 if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { 299 if (ioctl(file_descriptor, ATAIOCCOMMAND, &req) == 0) {
285 if (req.retsts != ATACMD_OK) { 300 if (req.retsts != ATACMD_OK) {
286 errno = ENODEV; 301 errno = ENODEV;
287 } 302 }
288 } 303 }
289 304
290 if (errno != 0) { 305 if (errno != 0) {
291 int e = errno; 306 int errno_storage = errno;
292 printf(_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror(errno)); 307 printf(_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror(errno));
293 return e; 308 return errno_storage;
294 } 309 }
295 310
296 (void)memcpy(values, inbuf, 512); 311 (void)memcpy(values, inbuf, 512);
297#endif /* __NetBSD__ */ 312#else // __linux__ || __NetBSD__
313# error Not implemented for this OS
314#endif
315
298 return 0; 316 return 0;
299} 317}
300 318
301int nagios(values_t *p, thresholds_t *t) { 319mp_state_enum compare_values_and_thresholds(smart_values *values, smart_thresholds *thresholds) {
302 value_t *value = p->values; 320 smart_value *value = values->values;
303 threshold_t *threshold = t->thresholds; 321 smart_threshold *threshold = thresholds->thresholds;
322
304 int status = OPERATIONAL; 323 int status = OPERATIONAL;
305 int prefailure = 0; 324 int prefailure = 0;
306 int advisory = 0; 325 int advisory = 0;
307 int failed = 0; 326 int failed = 0;
308 int passed = 0; 327 int passed = 0;
309 int total = 0; 328 int total = 0;
310 int i; 329 for (int i = 0; i < NR_ATTRIBUTES; i++) {
311 for (i = 0; i < NR_ATTRIBUTES; i++) {
312 if (value->id && threshold->id && value->id == threshold->id) { 330 if (value->id && threshold->id && value->id == threshold->id) {
313 if (value->value < threshold->threshold) { 331 if (value->value < threshold->threshold) {
314 ++failed; 332 ++failed;
@@ -327,6 +345,7 @@ int nagios(values_t *p, thresholds_t *t) {
327 ++value; 345 ++value;
328 ++threshold; 346 ++threshold;
329 } 347 }
348
330 switch (status) { 349 switch (status) {
331 case PREFAILURE: 350 case PREFAILURE:
332 printf(_("CRITICAL - %d Harddrive PreFailure%cDetected! %d/%d tests failed.\n"), prefailure, prefailure > 1 ? 's' : ' ', failed, 351 printf(_("CRITICAL - %d Harddrive PreFailure%cDetected! %d/%d tests failed.\n"), prefailure, prefailure > 1 ? 's' : ' ', failed,
@@ -349,50 +368,51 @@ int nagios(values_t *p, thresholds_t *t) {
349 return status; 368 return status;
350} 369}
351 370
352void print_value(value_t *p, threshold_t *t) { 371void print_value(smart_value *value_pointer, smart_threshold *threshold_pointer) {
353 printf("Id=%3d, Status=%2d {%s , %s}, Value=%3d, Threshold=%3d, %s\n", p->id, p->status, p->status & 1 ? "PreFailure" : "Advisory ", 372 printf("Id=%3d, Status=%2d {%s , %s}, Value=%3d, Threshold=%3d, %s\n", value_pointer->id, value_pointer->status,
354 p->status & 2 ? "OnLine " : "OffLine", p->value, t->threshold, p->value >= t->threshold ? "Passed" : "Failed"); 373 value_pointer->status & 1 ? "PreFailure" : "Advisory ", value_pointer->status & 2 ? "OnLine " : "OffLine",
374 value_pointer->value, threshold_pointer->threshold, value_pointer->value >= threshold_pointer->threshold ? "Passed" : "Failed");
355} 375}
356 376
357void print_values(values_t *p, thresholds_t *t) { 377void print_values(smart_values *values, smart_thresholds *thresholds) {
358 value_t *value = p->values; 378 smart_value *value = values->values;
359 threshold_t *threshold = t->thresholds; 379 smart_threshold *threshold = thresholds->thresholds;
360 int i; 380 for (int i = 0; i < NR_ATTRIBUTES; i++) {
361 for (i = 0; i < NR_ATTRIBUTES; i++) {
362 if (value->id && threshold->id && value->id == threshold->id) { 381 if (value->id && threshold->id && value->id == threshold->id) {
363 print_value(value++, threshold++); 382 print_value(value++, threshold++);
364 } 383 }
365 } 384 }
366 printf(_("OffLineStatus=%d {%s}, AutoOffLine=%s, OffLineTimeout=%d minutes\n"), p->offline_status, 385 printf(_("OffLineStatus=%d {%s}, AutoOffLine=%s, OffLineTimeout=%d minutes\n"), values->offline_status,
367 get_offline_text(p->offline_status & 0x7f), (p->offline_status & 0x80 ? "Yes" : "No"), p->offline_timeout / 60); 386 get_offline_text(values->offline_status & 0x7f), (values->offline_status & 0x80 ? "Yes" : "No"), values->offline_timeout / 60);
368 printf(_("OffLineCapability=%d {%s %s %s}\n"), p->offline_capability, p->offline_capability & 1 ? "Immediate" : "", 387 printf(_("OffLineCapability=%d {%s %s %s}\n"), values->offline_capability, values->offline_capability & 1 ? "Immediate" : "",
369 p->offline_capability & 2 ? "Auto" : "", p->offline_capability & 4 ? "AbortOnCmd" : "SuspendOnCmd"); 388 values->offline_capability & 2 ? "Auto" : "", values->offline_capability & 4 ? "AbortOnCmd" : "SuspendOnCmd");
370 printf(_("SmartRevision=%d, CheckSum=%d, SmartCapability=%d {%s %s}\n"), p->revision, p->checksum, p->smart_capability, 389 printf(_("SmartRevision=%d, CheckSum=%d, SmartCapability=%d {%s %s}\n"), values->revision, values->checksum, values->smart_capability,
371 p->smart_capability & 1 ? "SaveOnStandBy" : "", p->smart_capability & 2 ? "AutoSave" : ""); 390 values->smart_capability & 1 ? "SaveOnStandBy" : "", values->smart_capability & 2 ? "AutoSave" : "");
372} 391}
373 392
374int smart_cmd_simple(int fd, enum SmartCommand command, uint8_t val0, bool show_error) { 393mp_state_enum smart_cmd_simple(int file_descriptor, enum SmartCommand command, uint8_t val0, bool show_error) {
375 int e = STATE_UNKNOWN; 394 mp_state_enum result = STATE_UNKNOWN;
376#ifdef __linux__ 395#ifdef __linux__
377 uint8_t args[4]; 396 uint8_t args[4] = {
378 args[0] = WIN_SMART; 397 WIN_SMART,
379 args[1] = val0; 398 val0,
380 args[2] = smart_command[command].value; 399 smart_command[command].value,
381 args[3] = 0; 400 0,
382 if (ioctl(fd, HDIO_DRIVE_CMD, &args)) { 401 };
383 e = STATE_CRITICAL; 402
403 if (ioctl(file_descriptor, HDIO_DRIVE_CMD, &args)) {
404 result = STATE_CRITICAL;
384 if (show_error) { 405 if (show_error) {
385 printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno)); 406 printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno));
386 } 407 }
387 } else { 408 } else {
388 e = STATE_OK; 409 result = STATE_OK;
389 if (show_error) { 410 if (show_error) {
390 printf(_("OK - Command sent (%s)\n"), smart_command[command].text); 411 printf(_("OK - Command sent (%s)\n"), smart_command[command].text);
391 } 412 }
392 } 413 }
393 414
394#endif /* __linux__ */ 415#elif defined __NetBSD__
395#ifdef __NetBSD__
396 struct atareq req; 416 struct atareq req;
397 417
398 memset(&req, 0, sizeof(req)); 418 memset(&req, 0, sizeof(req));
@@ -403,7 +423,7 @@ int smart_cmd_simple(int fd, enum SmartCommand command, uint8_t val0, bool show_
403 req.cylinder = WDSMART_CYL; 423 req.cylinder = WDSMART_CYL;
404 req.sec_count = val0; 424 req.sec_count = val0;
405 425
406 if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { 426 if (ioctl(file_descriptor, ATAIOCCOMMAND, &req) == 0) {
407 if (req.retsts != ATACMD_OK) { 427 if (req.retsts != ATACMD_OK) {
408 errno = ENODEV; 428 errno = ENODEV;
409 } 429 }
@@ -413,42 +433,42 @@ int smart_cmd_simple(int fd, enum SmartCommand command, uint8_t val0, bool show_
413 } 433 }
414 434
415 if (errno != 0) { 435 if (errno != 0) {
416 e = STATE_CRITICAL; 436 result = STATE_CRITICAL;
417 if (show_error) { 437 if (show_error) {
418 printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno)); 438 printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno));
419 } 439 }
420 } else { 440 } else {
421 e = STATE_OK; 441 result = STATE_OK;
422 if (show_error) { 442 if (show_error) {
423 printf(_("OK - Command sent (%s)\n"), smart_command[command].text); 443 printf(_("OK - Command sent (%s)\n"), smart_command[command].text);
424 } 444 }
425 } 445 }
426 446#else
447# error Not implemented for this OS
427#endif /* __NetBSD__ */ 448#endif /* __NetBSD__ */
428 return e; 449
450 return result;
429} 451}
430 452
431int smart_read_thresholds(int fd, thresholds_t *thresholds) { 453int smart_read_thresholds(int file_descriptor, smart_thresholds *thresholds) {
432#ifdef __linux__ 454#ifdef __linux__
433 int e;
434 uint8_t args[4 + 512]; 455 uint8_t args[4 + 512];
435 args[0] = WIN_SMART; 456 args[0] = WIN_SMART;
436 args[1] = 0; 457 args[1] = 0;
437 args[2] = SMART_READ_THRESHOLDS; 458 args[2] = SMART_READ_THRESHOLDS;
438 args[3] = 1; 459 args[3] = 1;
439 if (ioctl(fd, HDIO_DRIVE_CMD, &args)) { 460 if (ioctl(file_descriptor, HDIO_DRIVE_CMD, &args)) {
440 e = errno; 461 int errno_storage = errno;
441 printf(_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror(errno)); 462 printf(_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror(errno));
442 return e; 463 return errno_storage;
443 } 464 }
444 memcpy(thresholds, args + 4, 512); 465 memcpy(thresholds, args + 4, 512);
445#endif /* __linux__ */ 466#elif defined __NetBSD__
446#ifdef __NetBSD__
447 struct atareq req; 467 struct atareq req;
448 unsigned char inbuf[DEV_BSIZE];
449
450 memset(&req, 0, sizeof(req)); 468 memset(&req, 0, sizeof(req));
451 req.timeout = 1000; 469 req.timeout = 1000;
470
471 unsigned char inbuf[DEV_BSIZE];
452 memset(&inbuf, 0, sizeof(inbuf)); 472 memset(&inbuf, 0, sizeof(inbuf));
453 473
454 req.flags = ATACMD_READ; 474 req.flags = ATACMD_READ;
@@ -458,20 +478,23 @@ int smart_read_thresholds(int fd, thresholds_t *thresholds) {
458 req.datalen = sizeof(inbuf); 478 req.datalen = sizeof(inbuf);
459 req.cylinder = WDSMART_CYL; 479 req.cylinder = WDSMART_CYL;
460 480
461 if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { 481 if (ioctl(file_descriptor, ATAIOCCOMMAND, &req) == 0) {
462 if (req.retsts != ATACMD_OK) { 482 if (req.retsts != ATACMD_OK) {
463 errno = ENODEV; 483 errno = ENODEV;
464 } 484 }
465 } 485 }
466 486
467 if (errno != 0) { 487 if (errno != 0) {
468 int e = errno; 488 int errno_storage = errno;
469 printf(_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror(errno)); 489 printf(_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror(errno));
470 return e; 490 return errno_storage;
471 } 491 }
472 492
473 (void)memcpy(thresholds, inbuf, 512); 493 (void)memcpy(thresholds, inbuf, 512);
494#else
495# error Not implemented for this OS
474#endif /* __NetBSD__ */ 496#endif /* __NetBSD__ */
497
475 return 0; 498 return 0;
476} 499}
477 500
diff --git a/plugins/check_ide_smart.d/config.h b/plugins/check_ide_smart.d/config.h
new file mode 100644
index 00000000..36899abe
--- /dev/null
+++ b/plugins/check_ide_smart.d/config.h
@@ -0,0 +1,15 @@
1#pragma once
2
3#include "../../config.h"
4#include <stddef.h>
5
6typedef struct {
7 char *device;
8} check_ide_smart_config;
9
10check_ide_smart_config check_ide_smart_init() {
11 check_ide_smart_config tmp = {
12 .device = NULL,
13 };
14 return tmp;
15}