summaryrefslogtreecommitdiffstats
path: root/lib/utils_cmd.c
diff options
context:
space:
mode:
authorLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2025-09-15 13:18:17 +0200
committerGitHub <noreply@github.com>2025-09-15 13:18:17 +0200
commit8ef825d85fb4d09c32ca44c545d6eb8d995ddea4 (patch)
tree5ab7b18797dfd5849dec7827c87ca3bb5fcb0993 /lib/utils_cmd.c
parenta3cf9041af810770daf5d9b83f1906fa9bb0dd11 (diff)
parent204cf956f0b3db90d079321ee957b3860da7e33f (diff)
downloadmonitoring-plugins-8ef825d85fb4d09c32ca44c545d6eb8d995ddea4.tar.gz
Merge pull request #2149 from RincewindsHat/clang-format
Clang format
Diffstat (limited to 'lib/utils_cmd.c')
-rw-r--r--lib/utils_cmd.c95
1 files changed, 63 insertions, 32 deletions
diff --git a/lib/utils_cmd.c b/lib/utils_cmd.c
index 9b222409..d1feaa33 100644
--- a/lib/utils_cmd.c
+++ b/lib/utils_cmd.c
@@ -71,7 +71,7 @@ extern char **environ;
71#endif 71#endif
72 72
73#ifndef WIFEXITED 73#ifndef WIFEXITED
74# define WIFEXITED(stat_val) (((stat_val)&255) == 0) 74# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
75#endif 75#endif
76 76
77/* 4.3BSD Reno <signal.h> doesn't define SIG_ERR */ 77/* 4.3BSD Reno <signal.h> doesn't define SIG_ERR */
@@ -103,8 +103,9 @@ void cmd_init(void) {
103 maxfd = MAXFD_LIMIT; 103 maxfd = MAXFD_LIMIT;
104 } 104 }
105 105
106 if (!_cmd_pids) 106 if (!_cmd_pids) {
107 _cmd_pids = calloc(maxfd, sizeof(pid_t)); 107 _cmd_pids = calloc(maxfd, sizeof(pid_t));
108 }
108} 109}
109 110
110/* Start running a command, array style */ 111/* Start running a command, array style */
@@ -116,13 +117,15 @@ static int _cmd_open(char *const *argv, int *pfd, int *pfderr) {
116 117
117 int i = 0; 118 int i = 0;
118 119
119 if (!_cmd_pids) 120 if (!_cmd_pids) {
120 CMD_INIT; 121 CMD_INIT;
122 }
121 123
122 setenv("LC_ALL", "C", 1); 124 setenv("LC_ALL", "C", 1);
123 125
124 if (pipe(pfd) < 0 || pipe(pfderr) < 0 || (pid = fork()) < 0) 126 if (pipe(pfd) < 0 || pipe(pfderr) < 0 || (pid = fork()) < 0) {
125 return -1; /* errno set by the failing function */ 127 return -1; /* errno set by the failing function */
128 }
126 129
127 /* child runs exceve() and _exit. */ 130 /* child runs exceve() and _exit. */
128 if (pid == 0) { 131 if (pid == 0) {
@@ -147,9 +150,11 @@ static int _cmd_open(char *const *argv, int *pfd, int *pfderr) {
147 * This is executed in a separate address space (pure child), 150 * This is executed in a separate address space (pure child),
148 * so we don't have to worry about async safety */ 151 * so we don't have to worry about async safety */
149 long maxfd = mp_open_max(); 152 long maxfd = mp_open_max();
150 for (i = 0; i < maxfd; i++) 153 for (i = 0; i < maxfd; i++) {
151 if (_cmd_pids[i] > 0) 154 if (_cmd_pids[i] > 0) {
152 close(i); 155 close(i);
156 }
157 }
153 158
154 execve(argv[0], argv, environ); 159 execve(argv[0], argv, environ);
155 _exit(STATE_UNKNOWN); 160 _exit(STATE_UNKNOWN);
@@ -172,17 +177,21 @@ static int _cmd_close(int fd) {
172 177
173 /* make sure the provided fd was opened */ 178 /* make sure the provided fd was opened */
174 long maxfd = mp_open_max(); 179 long maxfd = mp_open_max();
175 if (fd < 0 || fd > maxfd || !_cmd_pids || (pid = _cmd_pids[fd]) == 0) 180 if (fd < 0 || fd > maxfd || !_cmd_pids || (pid = _cmd_pids[fd]) == 0) {
176 return -1; 181 return -1;
182 }
177 183
178 _cmd_pids[fd] = 0; 184 _cmd_pids[fd] = 0;
179 if (close(fd) == -1) 185 if (close(fd) == -1) {
180 return -1; 186 return -1;
187 }
181 188
182 /* EINTR is ok (sort of), everything else is bad */ 189 /* EINTR is ok (sort of), everything else is bad */
183 while (waitpid(pid, &status, 0) < 0) 190 while (waitpid(pid, &status, 0) < 0) {
184 if (errno != EINTR) 191 if (errno != EINTR) {
185 return -1; 192 return -1;
193 }
194 }
186 195
187 /* return child's termination status */ 196 /* return child's termination status */
188 return (WIFEXITED(status)) ? WEXITSTATUS(status) : -1; 197 return (WIFEXITED(status)) ? WEXITSTATUS(status) : -1;
@@ -212,15 +221,17 @@ static int _cmd_fetch_output(int fd, output *op, int flags) {
212 221
213 /* some plugins may want to keep output unbroken, and some commands 222 /* some plugins may want to keep output unbroken, and some commands
214 * will yield no output, so return here for those */ 223 * will yield no output, so return here for those */
215 if (flags & CMD_NO_ARRAYS || !op->buf || !op->buflen) 224 if (flags & CMD_NO_ARRAYS || !op->buf || !op->buflen) {
216 return op->buflen; 225 return op->buflen;
226 }
217 227
218 /* and some may want both */ 228 /* and some may want both */
219 if (flags & CMD_NO_ASSOC) { 229 if (flags & CMD_NO_ASSOC) {
220 buf = malloc(op->buflen); 230 buf = malloc(op->buflen);
221 memcpy(buf, op->buf, op->buflen); 231 memcpy(buf, op->buf, op->buflen);
222 } else 232 } else {
223 buf = op->buf; 233 buf = op->buf;
234 }
224 235
225 op->line = NULL; 236 op->line = NULL;
226 op->lens = NULL; 237 op->lens = NULL;
@@ -241,8 +252,9 @@ static int _cmd_fetch_output(int fd, output *op, int flags) {
241 op->line[lineno] = &buf[i]; 252 op->line[lineno] = &buf[i];
242 253
243 /* hop to next newline or end of buffer */ 254 /* hop to next newline or end of buffer */
244 while (buf[i] != '\n' && i < op->buflen) 255 while (buf[i] != '\n' && i < op->buflen) {
245 i++; 256 i++;
257 }
246 buf[i] = '\0'; 258 buf[i] = '\0';
247 259
248 /* calculate the string length using pointer difference */ 260 /* calculate the string length using pointer difference */
@@ -262,30 +274,36 @@ int cmd_run(const char *cmdstring, output *out, output *err, int flags) {
262 char *cmd = NULL; 274 char *cmd = NULL;
263 char *str = NULL; 275 char *str = NULL;
264 276
265 if (cmdstring == NULL) 277 if (cmdstring == NULL) {
266 return -1; 278 return -1;
279 }
267 280
268 /* initialize the structs */ 281 /* initialize the structs */
269 if (out) 282 if (out) {
270 memset(out, 0, sizeof(output)); 283 memset(out, 0, sizeof(output));
271 if (err) 284 }
285 if (err) {
272 memset(err, 0, sizeof(output)); 286 memset(err, 0, sizeof(output));
287 }
273 288
274 /* make copy of command string so strtok() doesn't silently modify it */ 289 /* make copy of command string so strtok() doesn't silently modify it */
275 /* (the calling program may want to access it later) */ 290 /* (the calling program may want to access it later) */
276 cmdlen = strlen(cmdstring); 291 cmdlen = strlen(cmdstring);
277 if ((cmd = malloc(cmdlen + 1)) == NULL) 292 if ((cmd = malloc(cmdlen + 1)) == NULL) {
278 return -1; 293 return -1;
294 }
279 memcpy(cmd, cmdstring, cmdlen); 295 memcpy(cmd, cmdstring, cmdlen);
280 cmd[cmdlen] = '\0'; 296 cmd[cmdlen] = '\0';
281 297
282 /* This is not a shell, so we don't handle "???" */ 298 /* This is not a shell, so we don't handle "???" */
283 if (strstr(cmdstring, "\"")) 299 if (strstr(cmdstring, "\"")) {
284 return -1; 300 return -1;
301 }
285 302
286 /* allow single quotes, but only if non-whitesapce doesn't occur on both sides */ 303 /* allow single quotes, but only if non-whitesapce doesn't occur on both sides */
287 if (strstr(cmdstring, " ' ") || strstr(cmdstring, "'''")) 304 if (strstr(cmdstring, " ' ") || strstr(cmdstring, "'''")) {
288 return -1; 305 return -1;
306 }
289 307
290 /* each arg must be whitespace-separated, so args can be a maximum 308 /* each arg must be whitespace-separated, so args can be a maximum
291 * of (len / 2) + 1. We add 1 extra to the mix for NULL termination */ 309 * of (len / 2) + 1. We add 1 extra to the mix for NULL termination */
@@ -304,8 +322,9 @@ int cmd_run(const char *cmdstring, output *out, output *err, int flags) {
304 322
305 if (strstr(str, "'") == str) { /* handle SIMPLE quoted strings */ 323 if (strstr(str, "'") == str) { /* handle SIMPLE quoted strings */
306 str++; 324 str++;
307 if (!strstr(str, "'")) 325 if (!strstr(str, "'")) {
308 return -1; /* balanced? */ 326 return -1; /* balanced? */
327 }
309 cmd = 1 + strstr(str, "'"); 328 cmd = 1 + strstr(str, "'");
310 str[strcspn(str, "'")] = 0; 329 str[strcspn(str, "'")] = 0;
311 } else { 330 } else {
@@ -317,8 +336,9 @@ int cmd_run(const char *cmdstring, output *out, output *err, int flags) {
317 } 336 }
318 } 337 }
319 338
320 if (cmd && strlen(cmd) == strspn(cmd, " \t\r\n")) 339 if (cmd && strlen(cmd) == strspn(cmd, " \t\r\n")) {
321 cmd = NULL; 340 cmd = NULL;
341 }
322 342
323 argv[i++] = str; 343 argv[i++] = str;
324 } 344 }
@@ -330,50 +350,61 @@ int cmd_run_array(char *const *argv, output *out, output *err, int flags) {
330 int fd, pfd_out[2], pfd_err[2]; 350 int fd, pfd_out[2], pfd_err[2];
331 351
332 /* initialize the structs */ 352 /* initialize the structs */
333 if (out) 353 if (out) {
334 memset(out, 0, sizeof(output)); 354 memset(out, 0, sizeof(output));
335 if (err) 355 }
356 if (err) {
336 memset(err, 0, sizeof(output)); 357 memset(err, 0, sizeof(output));
358 }
337 359
338 if ((fd = _cmd_open(argv, pfd_out, pfd_err)) == -1) 360 if ((fd = _cmd_open(argv, pfd_out, pfd_err)) == -1) {
339 die(STATE_UNKNOWN, _("Could not open pipe: %s\n"), argv[0]); 361 die(STATE_UNKNOWN, _("Could not open pipe: %s\n"), argv[0]);
362 }
340 363
341 if (out) 364 if (out) {
342 out->lines = _cmd_fetch_output(pfd_out[0], out, flags); 365 out->lines = _cmd_fetch_output(pfd_out[0], out, flags);
343 if (err) 366 }
367 if (err) {
344 err->lines = _cmd_fetch_output(pfd_err[0], err, flags); 368 err->lines = _cmd_fetch_output(pfd_err[0], err, flags);
369 }
345 370
346 return _cmd_close(fd); 371 return _cmd_close(fd);
347} 372}
348 373
349int cmd_file_read(const char *filename, output *out, int flags) { 374int cmd_file_read(const char *filename, output *out, int flags) {
350 int fd; 375 int fd;
351 if (out) 376 if (out) {
352 memset(out, 0, sizeof(output)); 377 memset(out, 0, sizeof(output));
378 }
353 379
354 if ((fd = open(filename, O_RDONLY)) == -1) { 380 if ((fd = open(filename, O_RDONLY)) == -1) {
355 die(STATE_UNKNOWN, _("Error opening %s: %s"), filename, strerror(errno)); 381 die(STATE_UNKNOWN, _("Error opening %s: %s"), filename, strerror(errno));
356 } 382 }
357 383
358 if (out) 384 if (out) {
359 out->lines = _cmd_fetch_output(fd, out, flags); 385 out->lines = _cmd_fetch_output(fd, out, flags);
386 }
360 387
361 if (close(fd) == -1) 388 if (close(fd) == -1) {
362 die(STATE_UNKNOWN, _("Error closing %s: %s"), filename, strerror(errno)); 389 die(STATE_UNKNOWN, _("Error closing %s: %s"), filename, strerror(errno));
390 }
363 391
364 return 0; 392 return 0;
365} 393}
366 394
367void timeout_alarm_handler(int signo) { 395void timeout_alarm_handler(int signo) {
368 if (signo == SIGALRM) { 396 if (signo == SIGALRM) {
369 printf(_("%s - Plugin timed out after %d seconds\n"), state_text(timeout_state), timeout_interval); 397 printf(_("%s - Plugin timed out after %d seconds\n"), state_text(timeout_state),
398 timeout_interval);
370 399
371 long maxfd = mp_open_max(); 400 long maxfd = mp_open_max();
372 if (_cmd_pids) 401 if (_cmd_pids) {
373 for (long int i = 0; i < maxfd; i++) { 402 for (long int i = 0; i < maxfd; i++) {
374 if (_cmd_pids[i] != 0) 403 if (_cmd_pids[i] != 0) {
375 kill(_cmd_pids[i], SIGKILL); 404 kill(_cmd_pids[i], SIGKILL);
405 }
376 } 406 }
407 }
377 408
378 exit(timeout_state); 409 exit(timeout_state);
379 } 410 }