a8a7d5e8f5f155454f4400832ae650de166ed45f
1 /******************************************************************************
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 $Id$
19 ******************************************************************************/
21 const char *progname = "check_procs";
22 const char *revision = "$Revision$";
23 const char *copyright = "2000-2004";
24 const char *email = "nagiosplug-devel@lists.sourceforge.net";
26 #include "common.h"
27 #include "popen.h"
28 #include "utils.h"
30 #include <pwd.h>
32 int process_arguments (int, char **);
33 int validate_arguments (void);
34 int check_thresholds (int);
35 int convert_to_seconds (char *);
36 void print_help (void);
37 void print_usage (void);
39 int wmax = -1;
40 int cmax = -1;
41 int wmin = -1;
42 int cmin = -1;
44 int options = 0; /* bitmask of filter criteria to test against */
45 #define ALL 1
46 #define STAT 2
47 #define PPID 4
48 #define USER 8
49 #define PROG 16
50 #define ARGS 32
51 #define VSZ 64
52 #define RSS 128
53 #define PCPU 256
54 #define ELAPSED 512
55 /* Different metrics */
56 char *metric_name;
57 enum metric {
58 METRIC_PROCS,
59 METRIC_VSZ,
60 METRIC_RSS,
61 METRIC_CPU,
62 METRIC_ELAPSED
63 };
64 enum metric metric = METRIC_PROCS;
66 int verbose = 0;
67 int uid;
68 int ppid;
69 int vsz;
70 int rss;
71 float pcpu;
72 char *statopts;
73 char *prog;
74 char *args;
75 char *fmt;
76 char *fails;
77 char tmp[MAX_INPUT_BUFFER];
81 int
82 main (int argc, char **argv)
83 {
84 char *input_buffer;
85 char *input_line;
86 char *procprog;
88 int procuid = 0;
89 int procppid = 0;
90 int procvsz = 0;
91 int procrss = 0;
92 int procseconds = 0;
93 float procpcpu = 0;
94 char procstat[8];
95 char procetime[MAX_INPUT_BUFFER];
96 char *procargs;
97 char *temp_string;
99 const char *zombie = "Z";
101 int resultsum = 0; /* bitmask of the filter criteria met by a process */
102 int found = 0; /* counter for number of lines returned in `ps` output */
103 int procs = 0; /* counter for number of processes meeting filter criteria */
104 int pos; /* number of spaces before 'args' in `ps` output */
105 int cols; /* number of columns in ps output */
106 int expected_cols = PS_COLS - 1;
107 int warn = 0; /* number of processes in warn state */
108 int crit = 0; /* number of processes in crit state */
109 int i = 0;
111 int result = STATE_UNKNOWN;
113 setlocale (LC_ALL, "");
114 bindtextdomain (PACKAGE, LOCALEDIR);
115 textdomain (PACKAGE);
117 input_buffer = malloc (MAX_INPUT_BUFFER);
118 procprog = malloc (MAX_INPUT_BUFFER);
120 asprintf (&metric_name, "PROCS");
121 metric = METRIC_PROCS;
123 if (process_arguments (argc, argv) != TRUE)
124 usage4 (_("Could not parse arguments"));
126 /* Set signal handling and alarm timeout */
127 if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) {
128 usage4 (_("Cannot catch SIGALRM"));
129 }
130 alarm (timeout_interval);
132 if (verbose >= 2)
133 printf (_("CMD: %s\n"), PS_COMMAND);
135 child_process = spopen (PS_COMMAND);
136 if (child_process == NULL) {
137 printf (_("Could not open pipe: %s\n"), PS_COMMAND);
138 return STATE_UNKNOWN;
139 }
141 child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
142 if (child_stderr == NULL)
143 printf (_("Could not open stderr for %s\n"), PS_COMMAND);
145 /* flush first line */
146 fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process);
147 while ( input_buffer[strlen(input_buffer)-1] != '\n' )
148 fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process);
150 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
151 asprintf (&input_line, "%s", input_buffer);
152 while ( input_buffer[strlen(input_buffer)-1] != '\n' ) {
153 fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process);
154 asprintf (&input_line, "%s%s", input_line, input_buffer);
155 }
157 if (verbose >= 3)
158 printf ("%s", input_line);
160 strcpy (procprog, "");
161 asprintf (&procargs, "%s", "");
163 cols = sscanf (input_line, PS_FORMAT, PS_VARLIST);
165 /* Zombie processes do not give a procprog command */
166 if ( cols == (expected_cols - 1) && strstr(procstat, zombie) ) {
167 cols = expected_cols;
168 }
169 if ( cols >= expected_cols ) {
170 resultsum = 0;
171 asprintf (&procargs, "%s", input_line + pos);
172 strip (procargs);
174 /* Some ps return full pathname for command. This removes path */
175 temp_string = strtok ((char *)procprog, "/");
176 while (temp_string) {
177 strcpy(procprog, temp_string);
178 temp_string = strtok (NULL, "/");
179 }
181 /* we need to convert the elapsed time to seconds */
182 procseconds = convert_to_seconds(procetime);
184 if (verbose >= 3)
185 printf ("%d %d %d %d %d %.2f %s %s %s %s\n",
186 procs, procuid, procvsz, procrss,
187 procppid, procpcpu, procstat,
188 procetime, procprog, procargs);
190 /* Ignore self */
191 if (strcmp (procprog, progname) == 0) {
192 continue;
193 }
195 if ((options & STAT) && (strstr (statopts, procstat)))
196 resultsum |= STAT;
197 if ((options & ARGS) && procargs && (strstr (procargs, args) != NULL))
198 resultsum |= ARGS;
199 if ((options & PROG) && procprog && (strcmp (prog, procprog) == 0))
200 resultsum |= PROG;
201 if ((options & PPID) && (procppid == ppid))
202 resultsum |= PPID;
203 if ((options & USER) && (procuid == uid))
204 resultsum |= USER;
205 if ((options & VSZ) && (procvsz >= vsz))
206 resultsum |= VSZ;
207 if ((options & RSS) && (procrss >= rss))
208 resultsum |= RSS;
209 if ((options & PCPU) && (procpcpu >= pcpu))
210 resultsum |= PCPU;
212 found++;
214 /* Next line if filters not matched */
215 if (!(options == resultsum || options == ALL))
216 continue;
218 procs++;
220 if (metric == METRIC_VSZ)
221 i = check_thresholds (procvsz);
222 else if (metric == METRIC_RSS)
223 i = check_thresholds (procrss);
224 /* TODO? float thresholds for --metric=CPU */
225 else if (metric == METRIC_CPU)
226 i = check_thresholds ((int)procpcpu);
227 else if (metric == METRIC_ELAPSED)
228 i = check_thresholds (procseconds);
230 if (metric != METRIC_PROCS) {
231 if (i == STATE_WARNING) {
232 warn++;
233 asprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog);
234 result = max_state (result, i);
235 }
236 if (i == STATE_CRITICAL) {
237 crit++;
238 asprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog);
239 result = max_state (result, i);
240 }
241 }
242 }
243 /* This should not happen */
244 else if (verbose) {
245 printf(_("Not parseable: %s"), input_buffer);
246 }
247 }
249 /* If we get anything on STDERR, at least set warning */
250 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) {
251 if (verbose)
252 printf (_("STDERR: %s"), input_buffer);
253 result = max_state (result, STATE_WARNING);
254 printf (_("System call sent warnings to stderr\n"));
255 }
257 (void) fclose (child_stderr);
259 /* close the pipe */
260 if (spclose (child_process)) {
261 printf (_("System call returned nonzero status\n"));
262 result = max_state (result, STATE_WARNING);
263 }
265 if (found == 0) { /* no process lines parsed so return STATE_UNKNOWN */
266 printf (_("Unable to read output\n"));
267 return result;
268 }
270 if ( result == STATE_UNKNOWN )
271 result = STATE_OK;
273 /* Needed if procs found, but none match filter */
274 if ( metric == METRIC_PROCS ) {
275 result = max_state (result, check_thresholds (procs) );
276 }
278 if ( result == STATE_OK ) {
279 printf ("%s %s: ", metric_name, _("OK"));
280 } else if (result == STATE_WARNING) {
281 printf ("%s %s: ", metric_name, _("WARNING"));
282 if ( metric != METRIC_PROCS ) {
283 printf (_("%d warn out of "), warn);
284 }
285 } else if (result == STATE_CRITICAL) {
286 printf ("%s %s: ", metric_name, _("CRITICAL"));
287 if (metric != METRIC_PROCS) {
288 printf (_("%d crit, %d warn out of "), crit, warn);
289 }
290 }
291 printf ("%d %s", procs, procs == 1 ? _("process") : _("processes"));
293 if (strcmp(fmt,"") != 0) {
294 printf (_(" with %s"), fmt);
295 }
297 if ( verbose >= 1 && strcmp(fails,"") )
298 printf (" [%s]", fails);
300 printf ("\n");
301 return result;
302 }
306 /* process command-line arguments */
307 int
308 process_arguments (int argc, char **argv)
309 {
310 int c = 1;
311 char *user;
312 struct passwd *pw;
313 int option = 0;
314 static struct option longopts[] = {
315 {"warning", required_argument, 0, 'w'},
316 {"critical", required_argument, 0, 'c'},
317 {"metric", required_argument, 0, 'm'},
318 {"timeout", required_argument, 0, 't'},
319 {"status", required_argument, 0, 's'},
320 {"ppid", required_argument, 0, 'p'},
321 {"command", required_argument, 0, 'C'},
322 {"vsz", required_argument, 0, 'z'},
323 {"rss", required_argument, 0, 'r'},
324 {"pcpu", required_argument, 0, 'P'},
325 {"elapsed", required_argument, 0, 'e'},
326 {"argument-array", required_argument, 0, 'a'},
327 {"help", no_argument, 0, 'h'},
328 {"version", no_argument, 0, 'V'},
329 {"verbose", no_argument, 0, 'v'},
330 {0, 0, 0, 0}
331 };
333 for (c = 1; c < argc; c++)
334 if (strcmp ("-to", argv[c]) == 0)
335 strcpy (argv[c], "-t");
337 while (1) {
338 c = getopt_long (argc, argv, "Vvht:c:w:p:s:u:C:a:z:r:m:P:",
339 longopts, &option);
341 if (c == -1 || c == EOF)
342 break;
344 switch (c) {
345 case '?': /* help */
346 printf (_("%s: Unknown argument: %s\n\n"), progname, optarg);
347 print_usage ();
348 exit (STATE_UNKNOWN);
349 case 'h': /* help */
350 print_help ();
351 exit (STATE_OK);
352 case 'V': /* version */
353 print_revision (progname, revision);
354 exit (STATE_OK);
355 case 't': /* timeout period */
356 if (!is_integer (optarg))
357 usage2 (_("Timeout interval must be a positive integer"), optarg);
358 else
359 timeout_interval = atoi (optarg);
360 break;
361 case 'c': /* critical threshold */
362 if (is_integer (optarg))
363 cmax = atoi (optarg);
364 else if (sscanf (optarg, ":%d", &cmax) == 1)
365 break;
366 else if (sscanf (optarg, "%d:%d", &cmin, &cmax) == 2)
367 break;
368 else if (sscanf (optarg, "%d:", &cmin) == 1)
369 break;
370 else
371 usage (_("Critical Process Count must be an integer!\n\n"));
372 break;
373 case 'w': /* warning threshold */
374 if (is_integer (optarg))
375 wmax = atoi (optarg);
376 else if (sscanf (optarg, ":%d", &wmax) == 1)
377 break;
378 else if (sscanf (optarg, "%d:%d", &wmin, &wmax) == 2)
379 break;
380 else if (sscanf (optarg, "%d:", &wmin) == 1)
381 break;
382 else
383 usage (_("Warning Process Count must be an integer!\n\n"));
384 break;
385 case 'p': /* process id */
386 if (sscanf (optarg, "%d%[^0-9]", &ppid, tmp) == 1) {
387 asprintf (&fmt, "%s%sPPID = %d", (fmt ? fmt : "") , (options ? ", " : ""), ppid);
388 options |= PPID;
389 break;
390 }
391 usage2 (_("%s: Parent Process ID must be an integer!\n\n"), progname);
392 case 's': /* status */
393 if (statopts)
394 break;
395 else
396 statopts = optarg;
397 asprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts);
398 options |= STAT;
399 break;
400 case 'u': /* user or user id */
401 if (is_integer (optarg)) {
402 uid = atoi (optarg);
403 pw = getpwuid ((uid_t) uid);
404 /* check to be sure user exists */
405 if (pw == NULL)
406 usage2 (_("UID %s was not found\n"), optarg);
407 }
408 else {
409 pw = getpwnam (optarg);
410 /* check to be sure user exists */
411 if (pw == NULL)
412 usage2 (_("User name %s was not found\n"), optarg);
413 /* then get uid */
414 uid = pw->pw_uid;
415 }
416 user = pw->pw_name;
417 asprintf (&fmt, _("%s%sUID = %d (%s)"), (fmt ? fmt : ""), (options ? ", " : ""),
418 uid, user);
419 options |= USER;
420 break;
421 case 'C': /* command */
422 /* TODO: allow this to be passed in with --metric */
423 if (prog)
424 break;
425 else
426 prog = optarg;
427 asprintf (&fmt, _("%s%scommand name '%s'"), (fmt ? fmt : ""), (options ? ", " : ""),
428 prog);
429 options |= PROG;
430 break;
431 case 'a': /* args (full path name with args) */
432 /* TODO: allow this to be passed in with --metric */
433 if (args)
434 break;
435 else
436 args = optarg;
437 asprintf (&fmt, _("%s%sargs '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), args);
438 options |= ARGS;
439 break;
440 case 'r': /* RSS */
441 if (sscanf (optarg, "%d%[^0-9]", &rss, tmp) == 1) {
442 asprintf (&fmt, _("%s%sRSS >= %d"), (fmt ? fmt : ""), (options ? ", " : ""), rss);
443 options |= RSS;
444 break;
445 }
446 usage2 (_("%s: RSS must be an integer!\n\n"), progname);
447 case 'z': /* VSZ */
448 if (sscanf (optarg, "%d%[^0-9]", &vsz, tmp) == 1) {
449 asprintf (&fmt, _("%s%sVSZ >= %d"), (fmt ? fmt : ""), (options ? ", " : ""), vsz);
450 options |= VSZ;
451 break;
452 }
453 usage2 (_("%s: VSZ must be an integer!\n\n"), progname);
454 case 'P': /* PCPU */
455 /* TODO: -P 1.5.5 is accepted */
456 if (sscanf (optarg, "%f%[^0-9.]", &pcpu, tmp) == 1) {
457 asprintf (&fmt, _("%s%sPCPU >= %.2f"), (fmt ? fmt : ""), (options ? ", " : ""), pcpu);
458 options |= PCPU;
459 break;
460 }
461 usage2 (_("%s: PCPU must be a float!\n\n"), progname);
462 case 'm':
463 asprintf (&metric_name, "%s", optarg);
464 if ( strcmp(optarg, "PROCS") == 0) {
465 metric = METRIC_PROCS;
466 break;
467 }
468 else if ( strcmp(optarg, "VSZ") == 0) {
469 metric = METRIC_VSZ;
470 break;
471 }
472 else if ( strcmp(optarg, "RSS") == 0 ) {
473 metric = METRIC_RSS;
474 break;
475 }
476 else if ( strcmp(optarg, "CPU") == 0 ) {
477 metric = METRIC_CPU;
478 break;
479 }
480 else if ( strcmp(optarg, "ELAPSED") == 0) {
481 metric = METRIC_ELAPSED;
482 break;
483 }
485 printf (_("%s: metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!\n\n"),
486 progname);
487 print_usage ();
488 exit (STATE_UNKNOWN);
489 case 'v': /* command */
490 verbose++;
491 break;
492 }
493 }
495 c = optind;
496 if (wmax == -1 && argv[c])
497 wmax = atoi (argv[c++]);
498 if (cmax == -1 && argv[c])
499 cmax = atoi (argv[c++]);
500 if (statopts == NULL && argv[c]) {
501 asprintf (&statopts, "%s", argv[c++]);
502 asprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts);
503 options |= STAT;
504 }
506 return validate_arguments ();
507 }
511 int
512 validate_arguments ()
513 {
515 if (wmax >= 0 && wmin == -1)
516 wmin = 0;
517 if (cmax >= 0 && cmin == -1)
518 cmin = 0;
519 if (wmax >= wmin && cmax >= cmin) { /* standard ranges */
520 if (wmax > cmax && cmax != -1) {
521 printf (_("wmax (%d) cannot be greater than cmax (%d)\n"), wmax, cmax);
522 return ERROR;
523 }
524 if (cmin > wmin && wmin != -1) {
525 printf (_("wmin (%d) cannot be less than cmin (%d)\n"), wmin, cmin);
526 return ERROR;
527 }
528 }
530 /* if (wmax == -1 && cmax == -1 && wmin == -1 && cmin == -1) { */
531 /* printf ("At least one threshold must be set\n"); */
532 /* return ERROR; */
533 /* } */
535 if (options == 0)
536 options = ALL;
538 if (statopts==NULL)
539 statopts = strdup("");
541 if (prog==NULL)
542 prog = strdup("");
544 if (args==NULL)
545 args = strdup("");
547 if (fmt==NULL)
548 fmt = strdup("");
550 if (fails==NULL)
551 fails = strdup("");
553 return options;
554 }
558 /* Check thresholds against value */
559 int
560 check_thresholds (int value)
561 {
562 if (wmax == -1 && cmax == -1 && wmin == -1 && cmin == -1) {
563 return OK;
564 }
565 else if (cmax >= 0 && cmin >= 0 && cmax < cmin) {
566 if (value > cmax && value < cmin)
567 return STATE_CRITICAL;
568 }
569 else if (cmax >= 0 && value > cmax) {
570 return STATE_CRITICAL;
571 }
572 else if (cmin >= 0 && value < cmin) {
573 return STATE_CRITICAL;
574 }
576 if (wmax >= 0 && wmin >= 0 && wmax < wmin) {
577 if (value > wmax && value < wmin) {
578 return STATE_WARNING;
579 }
580 }
581 else if (wmax >= 0 && value > wmax) {
582 return STATE_WARNING;
583 }
584 else if (wmin >= 0 && value < wmin) {
585 return STATE_WARNING;
586 }
587 return STATE_OK;
588 }
592 void
593 print_help (void)
594 {
595 print_revision (progname, revision);
597 printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>");
598 printf (COPYRIGHT, copyright, email);
600 printf(_("\
601 Checks all processes and generates WARNING or CRITICAL states if the specified\n\
602 metric is outside the required threshold ranges. The metric defaults to number\n\
603 of processes. Search filters can be applied to limit the processes to check.\n\n"));
605 print_usage ();
607 printf(_("\n\
608 Required Arguments:\n\
609 -w, --warning=RANGE\n\
610 Generate warning state if metric is outside this range\n\
611 -c, --critical=RANGE\n\
612 Generate critical state if metric is outside this range\n"));
614 printf(_("\n\
615 Optional Arguments:\n\
616 -m, --metric=TYPE\n\
617 Check thresholds against metric. Valid types:\n\
618 PROCS - number of processes (default)\n\
619 VSZ - virtual memory size\n\
620 RSS - resident set memory size\n\
621 CPU - percentage cpu\n"));
622 /* only linux etime is support currently */
623 #if defined( __linux__ )
624 printf(_("\
625 ELAPSED - time elapsed in seconds\n"));
626 #endif /* defined(__linux__) */
627 printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
629 printf(_("\
630 -v, --verbose\n\
631 Extra information. Up to 3 verbosity levels\n"));
633 printf(_("\n\
634 Optional Filters:\n\
635 -s, --state=STATUSFLAGS\n\
636 Only scan for processes that have, in the output of `ps`, one or\n\
637 more of the status flags you specify (for example R, Z, S, RS,\n\
638 RSZDT, plus others based on the output of your 'ps' command).\n\
639 -p, --ppid=PPID\n\
640 Only scan for children of the parent process ID indicated.\n\
641 -z, --vsz=VSZ\n\
642 Only scan for processes with vsz higher than indicated.\n\
643 -r, --rss=RSS\n\
644 Only scan for processes with rss higher than indicated.\n"));
646 printf(_("\
647 -P, --pcpu=PCPU\n\
648 Only scan for processes with pcpu higher than indicated.\n\
649 -u, --user=USER\n\
650 Only scan for processes with user name or ID indicated.\n\
651 -a, --argument-array=STRING\n\
652 Only scan for processes with args that contain STRING.\n\
653 -C, --command=COMMAND\n\
654 Only scan for exact matches of COMMAND (without path).\n"));
656 printf(_("\n\
657 RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\
658 specified 'max:min', a warning status will be generated if the\n\
659 count is inside the specified range\n\n"));
661 printf(_("\
662 This plugin checks the number of currently running processes and\n\
663 generates WARNING or CRITICAL states if the process count is outside\n\
664 the specified threshold ranges. The process count can be filtered by\n\
665 process owner, parent process PID, current state (e.g., 'Z'), or may\n\
666 be the total number of running processes\n\n"));
668 printf(_("\
669 Examples:\n\
670 check_procs -w 2:2 -c 2:1024 -C portsentry\n\
671 Warning if not two processes with command name portsentry. Critical\n\
672 if < 2 or > 1024 processes\n\n\
673 check_procs -w 10 -a '/usr/local/bin/perl' -u root\n\
674 Warning alert if > 10 processes with command arguments containing \n\
675 '/usr/local/bin/perl' and owned by root\n\n\
676 check_procs -w 50000 -c 100000 --metric=VSZ\n\
677 Alert if vsz of any processes over 50K or 100K\n\
678 check_procs -w 10 -c 20 --metric=CPU\n\
679 Alert if cpu of any processes over 10%% or 20%%\n\n"));
681 printf (_(UT_SUPPORT));
682 }
686 /* convert the elapsed time to seconds */
687 int
688 convert_to_seconds(char *etime) {
690 char *ptr;
691 int total;
693 int hyphcnt;
694 int coloncnt;
695 int days;
696 int hours;
697 int minutes;
698 int seconds;
700 hyphcnt = 0;
701 coloncnt = 0;
702 days = 0;
703 hours = 0;
704 minutes = 0;
705 seconds = 0;
707 for (ptr = etime; *ptr != '\0'; ptr++) {
709 if (*ptr == '-') {
710 hyphcnt++;
711 continue;
712 }
713 if (*ptr == ':') {
714 coloncnt++;
715 continue;
716 }
717 }
719 if (hyphcnt > 0) {
720 sscanf(etime, "%d-%d:%d:%d",
721 &days, &hours, &minutes, &seconds);
722 /* linux 2.6.5/2.6.6 reporting some processes with infinite
723 * elapsed times for some reason */
724 if (days == 49710) {
725 return 0;
726 }
727 } else {
728 if (coloncnt == 2) {
729 sscanf(etime, "%d:%d:%d",
730 &hours, &minutes, &seconds);
731 } else if (coloncnt == 1) {
732 sscanf(etime, "%d:%d",
733 &minutes, &seconds);
734 }
735 }
737 total = (days * 86400) +
738 (hours * 3600) +
739 (minutes * 60) +
740 seconds;
742 if (verbose >= 3) {
743 printf("seconds: %d\n", total);
744 }
745 return total;
746 }
748 void
749 print_usage (void)
750 {
751 printf ("\
752 Usage: %s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n\
753 [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n\
754 [-C command] [-t timeout] [-v]\n", progname);
755 printf (_(UT_HLP_VRS), progname, progname);
756 }