diff options
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/check_procs.c | 247 | 
1 files changed, 113 insertions, 134 deletions
| diff --git a/plugins/check_procs.c b/plugins/check_procs.c index 69b424dc..da2198a7 100644 --- a/plugins/check_procs.c +++ b/plugins/check_procs.c | |||
| @@ -43,6 +43,7 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 43 | #include "utils.h" | 43 | #include "utils.h" | 
| 44 | #include "utils_cmd.h" | 44 | #include "utils_cmd.h" | 
| 45 | #include "regex.h" | 45 | #include "regex.h" | 
| 46 | #include "states.h" | ||
| 46 | 47 | ||
| 47 | #include <pwd.h> | 48 | #include <pwd.h> | 
| 48 | #include <errno.h> | 49 | #include <errno.h> | 
| @@ -91,7 +92,7 @@ enum metric { | |||
| 91 | enum metric metric = METRIC_PROCS; | 92 | enum metric metric = METRIC_PROCS; | 
| 92 | 93 | ||
| 93 | static int verbose = 0; | 94 | static int verbose = 0; | 
| 94 | static int uid; | 95 | static uid_t uid; | 
| 95 | static pid_t ppid; | 96 | static pid_t ppid; | 
| 96 | static int vsz; | 97 | static int vsz; | 
| 97 | static int rss; | 98 | static int rss; | 
| @@ -107,62 +108,22 @@ static regex_t re_args; | |||
| 107 | static char *fmt; | 108 | static char *fmt; | 
| 108 | static char *fails; | 109 | static char *fails; | 
| 109 | static char tmp[MAX_INPUT_BUFFER]; | 110 | static char tmp[MAX_INPUT_BUFFER]; | 
| 110 | static int kthread_filter = 0; | 111 | static bool kthread_filter = false; | 
| 111 | static int usepid = 0; /* whether to test for pid or /proc/pid/exe */ | 112 | static bool usepid = false; /* whether to test for pid or /proc/pid/exe */ | 
| 112 | 113 | ||
| 113 | static int stat_exe(const pid_t pid, struct stat *buf) { | 114 | static int stat_exe(const pid_t pid, struct stat *buf) { | 
| 114 | char *path; | 115 | char *path; | 
| 115 | int ret; | ||
| 116 | xasprintf(&path, "/proc/%d/exe", pid); | 116 | xasprintf(&path, "/proc/%d/exe", pid); | 
| 117 | ret = stat(path, buf); | 117 | int ret = stat(path, buf); | 
| 118 | free(path); | 118 | free(path); | 
| 119 | return ret; | 119 | return ret; | 
| 120 | } | 120 | } | 
| 121 | 121 | ||
| 122 | int main(int argc, char **argv) { | 122 | int main(int argc, char **argv) { | 
| 123 | char *input_buffer; | ||
| 124 | char *input_line; | ||
| 125 | char *procprog; | ||
| 126 | |||
| 127 | pid_t mypid = 0; | ||
| 128 | pid_t myppid = 0; | ||
| 129 | struct stat statbuf; | ||
| 130 | dev_t mydev = 0; | ||
| 131 | ino_t myino = 0; | ||
| 132 | int procuid = 0; | ||
| 133 | pid_t procpid = 0; | ||
| 134 | pid_t procppid = 0; | ||
| 135 | pid_t kthread_ppid = 0; | ||
| 136 | int procvsz = 0; | ||
| 137 | int procrss = 0; | ||
| 138 | int procseconds = 0; | ||
| 139 | float procpcpu = 0; | ||
| 140 | char procstat[8]; | ||
| 141 | char procetime[MAX_INPUT_BUFFER] = {'\0'}; | ||
| 142 | char *procargs; | ||
| 143 | |||
| 144 | const char *zombie = "Z"; | ||
| 145 | |||
| 146 | int resultsum = 0; /* bitmask of the filter criteria met by a process */ | ||
| 147 | int found = 0; /* counter for number of lines returned in `ps` output */ | ||
| 148 | int procs = 0; /* counter for number of processes meeting filter criteria */ | ||
| 149 | int pos; /* number of spaces before 'args' in `ps` output */ | ||
| 150 | int cols; /* number of columns in ps output */ | ||
| 151 | int expected_cols = PS_COLS - 1; | ||
| 152 | int warn = 0; /* number of processes in warn state */ | ||
| 153 | int crit = 0; /* number of processes in crit state */ | ||
| 154 | int i = 0; | ||
| 155 | int result = STATE_UNKNOWN; | ||
| 156 | int ret = 0; | ||
| 157 | output chld_out, chld_err; | ||
| 158 | |||
| 159 | setlocale(LC_ALL, ""); | 123 | setlocale(LC_ALL, ""); | 
| 124 | setlocale(LC_NUMERIC, "POSIX"); | ||
| 160 | bindtextdomain(PACKAGE, LOCALEDIR); | 125 | bindtextdomain(PACKAGE, LOCALEDIR); | 
| 161 | textdomain(PACKAGE); | 126 | textdomain(PACKAGE); | 
| 162 | setlocale(LC_NUMERIC, "POSIX"); | ||
| 163 | |||
| 164 | input_buffer = malloc(MAX_INPUT_BUFFER); | ||
| 165 | procprog = malloc(MAX_INPUT_BUFFER); | ||
| 166 | 127 | ||
| 167 | xasprintf(&metric_name, "PROCS"); | 128 | xasprintf(&metric_name, "PROCS"); | 
| 168 | metric = METRIC_PROCS; | 129 | metric = METRIC_PROCS; | 
| @@ -175,13 +136,16 @@ int main(int argc, char **argv) { | |||
| 175 | } | 136 | } | 
| 176 | 137 | ||
| 177 | /* find ourself */ | 138 | /* find ourself */ | 
| 178 | mypid = getpid(); | 139 | pid_t mypid = getpid(); | 
| 179 | myppid = getppid(); | 140 | pid_t myppid = getppid(); | 
| 141 | dev_t mydev = 0; | ||
| 142 | ino_t myino = 0; | ||
| 143 | struct stat statbuf; | ||
| 180 | if (usepid || stat_exe(mypid, &statbuf) == -1) { | 144 | if (usepid || stat_exe(mypid, &statbuf) == -1) { | 
| 181 | /* usepid might have been set by -T */ | 145 | /* usepid might have been set by -T */ | 
| 182 | usepid = 1; | 146 | usepid = true; | 
| 183 | } else { | 147 | } else { | 
| 184 | usepid = 0; | 148 | usepid = false; | 
| 185 | mydev = statbuf.st_dev; | 149 | mydev = statbuf.st_dev; | 
| 186 | myino = statbuf.st_ino; | 150 | myino = statbuf.st_ino; | 
| 187 | } | 151 | } | 
| @@ -190,12 +154,15 @@ int main(int argc, char **argv) { | |||
| 190 | if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { | 154 | if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { | 
| 191 | die(STATE_UNKNOWN, _("Cannot catch SIGALRM")); | 155 | die(STATE_UNKNOWN, _("Cannot catch SIGALRM")); | 
| 192 | } | 156 | } | 
| 193 | (void)alarm((unsigned)timeout_interval); | 157 | (void)alarm(timeout_interval); | 
| 194 | 158 | ||
| 195 | if (verbose >= 2) { | 159 | if (verbose >= 2) { | 
| 196 | printf(_("CMD: %s\n"), PS_COMMAND); | 160 | printf(_("CMD: %s\n"), PS_COMMAND); | 
| 197 | } | 161 | } | 
| 198 | 162 | ||
| 163 | output chld_out; | ||
| 164 | output chld_err; | ||
| 165 | mp_state_enum result = STATE_UNKNOWN; | ||
| 199 | if (input_filename == NULL) { | 166 | if (input_filename == NULL) { | 
| 200 | result = cmd_run(PS_COMMAND, &chld_out, &chld_err, 0); | 167 | result = cmd_run(PS_COMMAND, &chld_out, &chld_err, 0); | 
| 201 | if (chld_err.lines > 0) { | 168 | if (chld_err.lines > 0) { | 
| @@ -206,20 +173,43 @@ int main(int argc, char **argv) { | |||
| 206 | result = cmd_file_read(input_filename, &chld_out, 0); | 173 | result = cmd_file_read(input_filename, &chld_out, 0); | 
| 207 | } | 174 | } | 
| 208 | 175 | ||
| 176 | int pos; /* number of spaces before 'args' in `ps` output */ | ||
| 177 | uid_t procuid = 0; | ||
| 178 | pid_t procpid = 0; | ||
| 179 | pid_t procppid = 0; | ||
| 180 | pid_t kthread_ppid = 0; | ||
| 181 | int warn = 0; /* number of processes in warn state */ | ||
| 182 | int crit = 0; /* number of processes in crit state */ | ||
| 183 | int procvsz = 0; | ||
| 184 | int procrss = 0; | ||
| 185 | int procseconds = 0; | ||
| 186 | float procpcpu = 0; | ||
| 187 | char procstat[8]; | ||
| 188 | char procetime[MAX_INPUT_BUFFER] = {'\0'}; | ||
| 189 | int resultsum = 0; /* bitmask of the filter criteria met by a process */ | ||
| 190 | int found = 0; /* counter for number of lines returned in `ps` output */ | ||
| 191 | int procs = 0; /* counter for number of processes meeting filter criteria */ | ||
| 192 | char *input_buffer = malloc(MAX_INPUT_BUFFER); | ||
| 193 | char *procprog = malloc(MAX_INPUT_BUFFER); | ||
| 194 | const int expected_cols = PS_COLS - 1; | ||
| 195 | |||
| 209 | /* flush first line: j starts at 1 */ | 196 | /* flush first line: j starts at 1 */ | 
| 210 | for (size_t j = 1; j < chld_out.lines; j++) { | 197 | for (size_t j = 1; j < chld_out.lines; j++) { | 
| 211 | input_line = chld_out.line[j]; | 198 | char *input_line = chld_out.line[j]; | 
| 212 | 199 | ||
| 213 | if (verbose >= 3) { | 200 | if (verbose >= 3) { | 
| 214 | printf("%s", input_line); | 201 | printf("%s", input_line); | 
| 215 | } | 202 | } | 
| 216 | 203 | ||
| 217 | strcpy(procprog, ""); | 204 | strcpy(procprog, ""); | 
| 205 | char *procargs; | ||
| 218 | xasprintf(&procargs, "%s", ""); | 206 | xasprintf(&procargs, "%s", ""); | 
| 219 | 207 | ||
| 220 | cols = sscanf(input_line, PS_FORMAT, PS_VARLIST); | 208 | /* number of columns in ps output */ | 
| 209 | int cols = sscanf(input_line, PS_FORMAT, PS_VARLIST); | ||
| 221 | 210 | ||
| 222 | /* Zombie processes do not give a procprog command */ | 211 | /* Zombie processes do not give a procprog command */ | 
| 212 | const char *zombie = "Z"; | ||
| 223 | if (cols < expected_cols && strstr(procstat, zombie)) { | 213 | if (cols < expected_cols && strstr(procstat, zombie)) { | 
| 224 | cols = expected_cols; | 214 | cols = expected_cols; | 
| 225 | } | 215 | } | 
| @@ -240,6 +230,7 @@ int main(int argc, char **argv) { | |||
| 240 | } | 230 | } | 
| 241 | 231 | ||
| 242 | /* Ignore self */ | 232 | /* Ignore self */ | 
| 233 | int ret = 0; | ||
| 243 | if ((usepid && mypid == procpid) || | 234 | if ((usepid && mypid == procpid) || | 
| 244 | (((!usepid) && ((ret = stat_exe(procpid, &statbuf) != -1) && statbuf.st_dev == mydev && statbuf.st_ino == myino)) || | 235 | (((!usepid) && ((ret = stat_exe(procpid, &statbuf) != -1) && statbuf.st_dev == mydev && statbuf.st_ino == myino)) || | 
| 245 | (ret == -1 && errno == ENOENT))) { | 236 | (ret == -1 && errno == ENOENT))) { | 
| @@ -249,7 +240,7 @@ int main(int argc, char **argv) { | |||
| 249 | continue; | 240 | continue; | 
| 250 | } | 241 | } | 
| 251 | /* Ignore parent*/ | 242 | /* Ignore parent*/ | 
| 252 | else if (myppid == procpid) { | 243 | if (myppid == procpid) { | 
| 253 | if (verbose >= 3) { | 244 | if (verbose >= 3) { | 
| 254 | printf("not considering - is parent\n"); | 245 | printf("not considering - is parent\n"); | 
| 255 | } | 246 | } | 
| @@ -266,15 +257,13 @@ int main(int argc, char **argv) { | |||
| 266 | 257 | ||
| 267 | /* Ignore excluded processes by name */ | 258 | /* Ignore excluded processes by name */ | 
| 268 | if (options & EXCLUDE_PROGS) { | 259 | if (options & EXCLUDE_PROGS) { | 
| 269 | int found = 0; | 260 | bool found = false; | 
| 270 | int i = 0; | 261 | for (int i = 0; i < (exclude_progs_counter); i++) { | 
| 271 | |||
| 272 | for (i = 0; i < (exclude_progs_counter); i++) { | ||
| 273 | if (!strcmp(procprog, exclude_progs_arr[i])) { | 262 | if (!strcmp(procprog, exclude_progs_arr[i])) { | 
| 274 | found = 1; | 263 | found = true; | 
| 275 | } | 264 | } | 
| 276 | } | 265 | } | 
| 277 | if (found == 0) { | 266 | if (!found) { | 
| 278 | resultsum |= EXCLUDE_PROGS; | 267 | resultsum |= EXCLUDE_PROGS; | 
| 279 | } else { | 268 | } else { | 
| 280 | if (verbose >= 3) { | 269 | if (verbose >= 3) { | 
| @@ -286,7 +275,7 @@ int main(int argc, char **argv) { | |||
| 286 | /* filter kernel threads (children of KTHREAD_PARENT)*/ | 275 | /* filter kernel threads (children of KTHREAD_PARENT)*/ | 
| 287 | /* TODO adapt for other OSes than GNU/Linux | 276 | /* TODO adapt for other OSes than GNU/Linux | 
| 288 | sorry for not doing that, but I've no other OSes to test :-( */ | 277 | sorry for not doing that, but I've no other OSes to test :-( */ | 
| 289 | if (kthread_filter == 1) { | 278 | if (kthread_filter) { | 
| 290 | /* get pid KTHREAD_PARENT */ | 279 | /* get pid KTHREAD_PARENT */ | 
| 291 | if (kthread_ppid == 0 && !strcmp(procprog, KTHREAD_PARENT)) { | 280 | if (kthread_ppid == 0 && !strcmp(procprog, KTHREAD_PARENT)) { | 
| 292 | kthread_ppid = procpid; | 281 | kthread_ppid = procpid; | 
| @@ -341,28 +330,29 @@ int main(int argc, char **argv) { | |||
| 341 | procrss, procpid, procppid, procpcpu, procstat, procetime, procprog, procargs); | 330 | procrss, procpid, procppid, procpcpu, procstat, procetime, procprog, procargs); | 
| 342 | } | 331 | } | 
| 343 | 332 | ||
| 333 | mp_state_enum temporary_result = STATE_OK; | ||
| 344 | if (metric == METRIC_VSZ) { | 334 | if (metric == METRIC_VSZ) { | 
| 345 | i = get_status((double)procvsz, procs_thresholds); | 335 | temporary_result = get_status((double)procvsz, procs_thresholds); | 
| 346 | } else if (metric == METRIC_RSS) { | 336 | } else if (metric == METRIC_RSS) { | 
| 347 | i = get_status((double)procrss, procs_thresholds); | 337 | temporary_result = get_status((double)procrss, procs_thresholds); | 
| 348 | } | 338 | } | 
| 349 | /* TODO? float thresholds for --metric=CPU */ | 339 | /* TODO? float thresholds for --metric=CPU */ | 
| 350 | else if (metric == METRIC_CPU) { | 340 | else if (metric == METRIC_CPU) { | 
| 351 | i = get_status(procpcpu, procs_thresholds); | 341 | temporary_result = get_status(procpcpu, procs_thresholds); | 
| 352 | } else if (metric == METRIC_ELAPSED) { | 342 | } else if (metric == METRIC_ELAPSED) { | 
| 353 | i = get_status((double)procseconds, procs_thresholds); | 343 | temporary_result = get_status((double)procseconds, procs_thresholds); | 
| 354 | } | 344 | } | 
| 355 | 345 | ||
| 356 | if (metric != METRIC_PROCS) { | 346 | if (metric != METRIC_PROCS) { | 
| 357 | if (i == STATE_WARNING) { | 347 | if (temporary_result == STATE_WARNING) { | 
| 358 | warn++; | 348 | warn++; | 
| 359 | xasprintf(&fails, "%s%s%s", fails, (strcmp(fails, "") ? ", " : ""), procprog); | 349 | xasprintf(&fails, "%s%s%s", fails, (strcmp(fails, "") ? ", " : ""), procprog); | 
| 360 | result = max_state(result, i); | 350 | result = max_state(result, temporary_result); | 
| 361 | } | 351 | } | 
| 362 | if (i == STATE_CRITICAL) { | 352 | if (temporary_result == STATE_CRITICAL) { | 
| 363 | crit++; | 353 | crit++; | 
| 364 | xasprintf(&fails, "%s%s%s", fails, (strcmp(fails, "") ? ", " : ""), procprog); | 354 | xasprintf(&fails, "%s%s%s", fails, (strcmp(fails, "") ? ", " : ""), procprog); | 
| 365 | result = max_state(result, i); | 355 | result = max_state(result, temporary_result); | 
| 366 | } | 356 | } | 
| 367 | } | 357 | } | 
| 368 | } | 358 | } | 
| @@ -416,20 +406,11 @@ int main(int argc, char **argv) { | |||
| 416 | } | 406 | } | 
| 417 | 407 | ||
| 418 | printf("\n"); | 408 | printf("\n"); | 
| 419 | return result; | 409 | exit(result); | 
| 420 | } | 410 | } | 
| 421 | 411 | ||
| 422 | /* process command-line arguments */ | 412 | /* process command-line arguments */ | 
| 423 | int process_arguments(int argc, char **argv) { | 413 | int process_arguments(int argc, char **argv) { | 
| 424 | int c = 1; | ||
| 425 | char *user; | ||
| 426 | struct passwd *pw; | ||
| 427 | int option = 0; | ||
| 428 | int err; | ||
| 429 | int cflags = REG_NOSUB | REG_EXTENDED; | ||
| 430 | char errbuf[MAX_INPUT_BUFFER]; | ||
| 431 | char *temp_string; | ||
| 432 | int i = 0; | ||
| 433 | static struct option longopts[] = {{"warning", required_argument, 0, 'w'}, | 414 | static struct option longopts[] = {{"warning", required_argument, 0, 'w'}, | 
| 434 | {"critical", required_argument, 0, 'c'}, | 415 | {"critical", required_argument, 0, 'c'}, | 
| 435 | {"metric", required_argument, 0, 'm'}, | 416 | {"metric", required_argument, 0, 'm'}, | 
| @@ -453,20 +434,21 @@ int process_arguments(int argc, char **argv) { | |||
| 453 | {"exclude-process", required_argument, 0, 'X'}, | 434 | {"exclude-process", required_argument, 0, 'X'}, | 
| 454 | {0, 0, 0, 0}}; | 435 | {0, 0, 0, 0}}; | 
| 455 | 436 | ||
| 456 | for (c = 1; c < argc; c++) { | 437 | for (int index = 1; index < argc; index++) { | 
| 457 | if (strcmp("-to", argv[c]) == 0) { | 438 | if (strcmp("-to", argv[index]) == 0) { | 
| 458 | strcpy(argv[c], "-t"); | 439 | strcpy(argv[index], "-t"); | 
| 459 | } | 440 | } | 
| 460 | } | 441 | } | 
| 461 | 442 | ||
| 462 | while (1) { | 443 | while (true) { | 
| 463 | c = getopt_long(argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T:X:", longopts, &option); | 444 | int option = 0; | 
| 445 | int option_index = getopt_long(argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T:X:", longopts, &option); | ||
| 464 | 446 | ||
| 465 | if (c == -1 || c == EOF) { | 447 | if (option_index == -1 || option_index == EOF) { | 
| 466 | break; | 448 | break; | 
| 467 | } | 449 | } | 
| 468 | 450 | ||
| 469 | switch (c) { | 451 | switch (option_index) { | 
| 470 | case '?': /* help */ | 452 | case '?': /* help */ | 
| 471 | usage5(); | 453 | usage5(); | 
| 472 | case 'h': /* help */ | 454 | case 'h': /* help */ | 
| @@ -504,10 +486,11 @@ int process_arguments(int argc, char **argv) { | |||
| 504 | xasprintf(&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); | 486 | xasprintf(&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); | 
| 505 | options |= STAT; | 487 | options |= STAT; | 
| 506 | break; | 488 | break; | 
| 507 | case 'u': /* user or user id */ | 489 | case 'u': /* user or user id */ { | 
| 490 | struct passwd *pw; | ||
| 508 | if (is_integer(optarg)) { | 491 | if (is_integer(optarg)) { | 
| 509 | uid = atoi(optarg); | 492 | uid = atoi(optarg); | 
| 510 | pw = getpwuid((uid_t)uid); | 493 | pw = getpwuid(uid); | 
| 511 | /* check to be sure user exists */ | 494 | /* check to be sure user exists */ | 
| 512 | if (pw == NULL) { | 495 | if (pw == NULL) { | 
| 513 | usage2(_("UID was not found"), optarg); | 496 | usage2(_("UID was not found"), optarg); | 
| @@ -521,10 +504,11 @@ int process_arguments(int argc, char **argv) { | |||
| 521 | /* then get uid */ | 504 | /* then get uid */ | 
| 522 | uid = pw->pw_uid; | 505 | uid = pw->pw_uid; | 
| 523 | } | 506 | } | 
| 524 | user = pw->pw_name; | 507 | |
| 508 | char *user = pw->pw_name; | ||
| 525 | xasprintf(&fmt, "%s%sUID = %d (%s)", (fmt ? fmt : ""), (options ? ", " : ""), uid, user); | 509 | xasprintf(&fmt, "%s%sUID = %d (%s)", (fmt ? fmt : ""), (options ? ", " : ""), uid, user); | 
| 526 | options |= USER; | 510 | options |= USER; | 
| 527 | break; | 511 | } break; | 
| 528 | case 'C': /* command */ | 512 | case 'C': /* command */ | 
| 529 | /* TODO: allow this to be passed in with --metric */ | 513 | /* TODO: allow this to be passed in with --metric */ | 
| 530 | if (prog) { | 514 | if (prog) { | 
| @@ -542,12 +526,12 @@ int process_arguments(int argc, char **argv) { | |||
| 542 | exclude_progs = optarg; | 526 | exclude_progs = optarg; | 
| 543 | } | 527 | } | 
| 544 | xasprintf(&fmt, _("%s%sexclude progs '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), exclude_progs); | 528 | xasprintf(&fmt, _("%s%sexclude progs '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), exclude_progs); | 
| 545 | char *p = strtok(exclude_progs, ","); | 529 | char *tmp_pointer = strtok(exclude_progs, ","); | 
| 546 | 530 | ||
| 547 | while (p) { | 531 | while (tmp_pointer) { | 
| 548 | exclude_progs_arr = realloc(exclude_progs_arr, sizeof(char *) * ++exclude_progs_counter); | 532 | exclude_progs_arr = realloc(exclude_progs_arr, sizeof(char *) * ++exclude_progs_counter); | 
| 549 | exclude_progs_arr[exclude_progs_counter - 1] = p; | 533 | exclude_progs_arr[exclude_progs_counter - 1] = tmp_pointer; | 
| 550 | p = strtok(NULL, ","); | 534 | tmp_pointer = strtok(NULL, ","); | 
| 551 | } | 535 | } | 
| 552 | 536 | ||
| 553 | options |= EXCLUDE_PROGS; | 537 | options |= EXCLUDE_PROGS; | 
| @@ -562,23 +546,26 @@ int process_arguments(int argc, char **argv) { | |||
| 562 | xasprintf(&fmt, "%s%sargs '%s'", (fmt ? fmt : ""), (options ? ", " : ""), args); | 546 | xasprintf(&fmt, "%s%sargs '%s'", (fmt ? fmt : ""), (options ? ", " : ""), args); | 
| 563 | options |= ARGS; | 547 | options |= ARGS; | 
| 564 | break; | 548 | break; | 
| 565 | case CHAR_MAX + 1: | 549 | case CHAR_MAX + 1: { | 
| 566 | err = regcomp(&re_args, optarg, cflags); | 550 | int cflags = REG_NOSUB | REG_EXTENDED; | 
| 551 | int err = regcomp(&re_args, optarg, cflags); | ||
| 567 | if (err != 0) { | 552 | if (err != 0) { | 
| 553 | char errbuf[MAX_INPUT_BUFFER]; | ||
| 568 | regerror(err, &re_args, errbuf, MAX_INPUT_BUFFER); | 554 | regerror(err, &re_args, errbuf, MAX_INPUT_BUFFER); | 
| 569 | die(STATE_UNKNOWN, "PROCS %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); | 555 | die(STATE_UNKNOWN, "PROCS %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); | 
| 570 | } | 556 | } | 
| 571 | /* Strip off any | within the regex optarg */ | 557 | /* Strip off any | within the regex optarg */ | 
| 572 | temp_string = strdup(optarg); | 558 | char *temp_string = strdup(optarg); | 
| 573 | while (temp_string[i] != '\0') { | 559 | int index = 0; | 
| 574 | if (temp_string[i] == '|') { | 560 | while (temp_string[index] != '\0') { | 
| 575 | temp_string[i] = ','; | 561 | if (temp_string[index] == '|') { | 
| 562 | temp_string[index] = ','; | ||
| 576 | } | 563 | } | 
| 577 | i++; | 564 | index++; | 
| 578 | } | 565 | } | 
| 579 | xasprintf(&fmt, "%s%sregex args '%s'", (fmt ? fmt : ""), (options ? ", " : ""), temp_string); | 566 | xasprintf(&fmt, "%s%sregex args '%s'", (fmt ? fmt : ""), (options ? ", " : ""), temp_string); | 
| 580 | options |= EREG_ARGS; | 567 | options |= EREG_ARGS; | 
| 581 | break; | 568 | } break; | 
| 582 | case 'r': /* RSS */ | 569 | case 'r': /* RSS */ | 
| 583 | if (sscanf(optarg, "%d%[^0-9]", &rss, tmp) == 1) { | 570 | if (sscanf(optarg, "%d%[^0-9]", &rss, tmp) == 1) { | 
| 584 | xasprintf(&fmt, "%s%sRSS >= %d", (fmt ? fmt : ""), (options ? ", " : ""), rss); | 571 | xasprintf(&fmt, "%s%sRSS >= %d", (fmt ? fmt : ""), (options ? ", " : ""), rss); | 
| @@ -606,29 +593,33 @@ int process_arguments(int argc, char **argv) { | |||
| 606 | if (strcmp(optarg, "PROCS") == 0) { | 593 | if (strcmp(optarg, "PROCS") == 0) { | 
| 607 | metric = METRIC_PROCS; | 594 | metric = METRIC_PROCS; | 
| 608 | break; | 595 | break; | 
| 609 | } else if (strcmp(optarg, "VSZ") == 0) { | 596 | } | 
| 597 | if (strcmp(optarg, "VSZ") == 0) { | ||
| 610 | metric = METRIC_VSZ; | 598 | metric = METRIC_VSZ; | 
| 611 | break; | 599 | break; | 
| 612 | } else if (strcmp(optarg, "RSS") == 0) { | 600 | } | 
| 601 | if (strcmp(optarg, "RSS") == 0) { | ||
| 613 | metric = METRIC_RSS; | 602 | metric = METRIC_RSS; | 
| 614 | break; | 603 | break; | 
| 615 | } else if (strcmp(optarg, "CPU") == 0) { | 604 | } | 
| 605 | if (strcmp(optarg, "CPU") == 0) { | ||
| 616 | metric = METRIC_CPU; | 606 | metric = METRIC_CPU; | 
| 617 | break; | 607 | break; | 
| 618 | } else if (strcmp(optarg, "ELAPSED") == 0) { | 608 | } | 
| 609 | if (strcmp(optarg, "ELAPSED") == 0) { | ||
| 619 | metric = METRIC_ELAPSED; | 610 | metric = METRIC_ELAPSED; | 
| 620 | break; | 611 | break; | 
| 621 | } | 612 | } | 
| 622 | 613 | ||
| 623 | usage4(_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!")); | 614 | usage4(_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!")); | 
| 624 | case 'k': /* linux kernel thread filter */ | 615 | case 'k': /* linux kernel thread filter */ | 
| 625 | kthread_filter = 1; | 616 | kthread_filter = true; | 
| 626 | break; | 617 | break; | 
| 627 | case 'v': /* command */ | 618 | case 'v': /* command */ | 
| 628 | verbose++; | 619 | verbose++; | 
| 629 | break; | 620 | break; | 
| 630 | case 'T': | 621 | case 'T': | 
| 631 | usepid = 1; | 622 | usepid = true; | 
| 632 | break; | 623 | break; | 
| 633 | case CHAR_MAX + 2: | 624 | case CHAR_MAX + 2: | 
| 634 | input_filename = optarg; | 625 | input_filename = optarg; | 
| @@ -636,15 +627,15 @@ int process_arguments(int argc, char **argv) { | |||
| 636 | } | 627 | } | 
| 637 | } | 628 | } | 
| 638 | 629 | ||
| 639 | c = optind; | 630 | int index = optind; | 
| 640 | if ((!warning_range) && argv[c]) { | 631 | if ((!warning_range) && argv[index]) { | 
| 641 | warning_range = argv[c++]; | 632 | warning_range = argv[index++]; | 
| 642 | } | 633 | } | 
| 643 | if ((!critical_range) && argv[c]) { | 634 | if ((!critical_range) && argv[index]) { | 
| 644 | critical_range = argv[c++]; | 635 | critical_range = argv[index++]; | 
| 645 | } | 636 | } | 
| 646 | if (statopts == NULL && argv[c]) { | 637 | if (statopts == NULL && argv[index]) { | 
| 647 | xasprintf(&statopts, "%s", argv[c++]); | 638 | xasprintf(&statopts, "%s", argv[index++]); | 
| 648 | xasprintf(&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); | 639 | xasprintf(&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); | 
| 649 | options |= STAT; | 640 | options |= STAT; | 
| 650 | } | 641 | } | 
| @@ -685,25 +676,9 @@ int validate_arguments() { | |||
| 685 | 676 | ||
| 686 | /* convert the elapsed time to seconds */ | 677 | /* convert the elapsed time to seconds */ | 
| 687 | int convert_to_seconds(char *etime) { | 678 | int convert_to_seconds(char *etime) { | 
| 688 | 679 | int hyphcnt = 0; | |
| 689 | char *ptr; | 680 | int coloncnt = 0; | 
| 690 | int total; | 681 | for (char *ptr = etime; *ptr != '\0'; ptr++) { | 
| 691 | |||
| 692 | int hyphcnt; | ||
| 693 | int coloncnt; | ||
| 694 | int days; | ||
| 695 | int hours; | ||
| 696 | int minutes; | ||
| 697 | int seconds; | ||
| 698 | |||
| 699 | hyphcnt = 0; | ||
| 700 | coloncnt = 0; | ||
| 701 | days = 0; | ||
| 702 | hours = 0; | ||
| 703 | minutes = 0; | ||
| 704 | seconds = 0; | ||
| 705 | |||
| 706 | for (ptr = etime; *ptr != '\0'; ptr++) { | ||
| 707 | 682 | ||
| 708 | if (*ptr == '-') { | 683 | if (*ptr == '-') { | 
| 709 | hyphcnt++; | 684 | hyphcnt++; | 
| @@ -715,6 +690,10 @@ int convert_to_seconds(char *etime) { | |||
| 715 | } | 690 | } | 
| 716 | } | 691 | } | 
| 717 | 692 | ||
| 693 | int days = 0; | ||
| 694 | int hours = 0; | ||
| 695 | int minutes = 0; | ||
| 696 | int seconds = 0; | ||
| 718 | if (hyphcnt > 0) { | 697 | if (hyphcnt > 0) { | 
| 719 | sscanf(etime, "%d-%d:%d:%d", &days, &hours, &minutes, &seconds); | 698 | sscanf(etime, "%d-%d:%d:%d", &days, &hours, &minutes, &seconds); | 
| 720 | /* linux 2.6.5/2.6.6 reporting some processes with infinite | 699 | /* linux 2.6.5/2.6.6 reporting some processes with infinite | 
| @@ -730,7 +709,7 @@ int convert_to_seconds(char *etime) { | |||
| 730 | } | 709 | } | 
| 731 | } | 710 | } | 
| 732 | 711 | ||
| 733 | total = (days * 86400) + (hours * 3600) + (minutes * 60) + seconds; | 712 | int total = (days * 86400) + (hours * 3600) + (minutes * 60) + seconds; | 
| 734 | 713 | ||
| 735 | if (verbose >= 3 && metric == METRIC_ELAPSED) { | 714 | if (verbose >= 3 && metric == METRIC_ELAPSED) { | 
| 736 | printf("seconds: %d\n", total); | 715 | printf("seconds: %d\n", total); | 
