diff options
| author | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2025-09-15 12:59:37 +0200 |
|---|---|---|
| committer | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2025-09-15 12:59:37 +0200 |
| commit | 802e46f8ea36c344f112d7e1dd8d64d17a4cc939 (patch) | |
| tree | cabf480269113686430053d66df3dadcd4d137a7 /lib/utils_cmd.c | |
| parent | a3cf9041af810770daf5d9b83f1906fa9bb0dd11 (diff) | |
| download | monitoring-plugins-802e46f8ea36c344f112d7e1dd8d64d17a4cc939.tar.gz | |
Run clang-format again
Diffstat (limited to 'lib/utils_cmd.c')
| -rw-r--r-- | lib/utils_cmd.c | 95 |
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 | ||
| 349 | int cmd_file_read(const char *filename, output *out, int flags) { | 374 | int 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 | ||
| 367 | void timeout_alarm_handler(int signo) { | 395 | void 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 | } |
