diff options
Diffstat (limited to 'plugins/check_procs.c')
-rw-r--r-- | plugins/check_procs.c | 1143 |
1 files changed, 560 insertions, 583 deletions
diff --git a/plugins/check_procs.c b/plugins/check_procs.c index 1fcbd981..83e6864e 100644 --- a/plugins/check_procs.c +++ b/plugins/check_procs.c | |||
@@ -1,357 +1,330 @@ | |||
1 | /***************************************************************************** | 1 | /***************************************************************************** |
2 | * | 2 | * |
3 | * Monitoring check_procs plugin | 3 | * Monitoring check_procs plugin |
4 | * | 4 | * |
5 | * License: GPL | 5 | * License: GPL |
6 | * Copyright (c) 2000-2008 Monitoring Plugins Development Team | 6 | * Copyright (c) 2000-2024 Monitoring Plugins Development Team |
7 | * | 7 | * |
8 | * Description: | 8 | * Description: |
9 | * | 9 | * |
10 | * This file contains the check_procs plugin | 10 | * This file contains the check_procs plugin |
11 | * | 11 | * |
12 | * Checks all processes and generates WARNING or CRITICAL states if the | 12 | * Checks all processes and generates WARNING or CRITICAL states if the |
13 | * specified metric is outside the required threshold ranges. The metric | 13 | * specified metric is outside the required threshold ranges. The metric |
14 | * defaults to number of processes. Search filters can be applied to limit | 14 | * defaults to number of processes. Search filters can be applied to limit |
15 | * the processes to check. | 15 | * the processes to check. |
16 | * | 16 | * |
17 | * The parent process, check_procs itself and any child process of | 17 | * The parent process, check_procs itself and any child process of |
18 | * check_procs (ps) are excluded from any checks to prevent false positives. | 18 | * check_procs (ps) are excluded from any checks to prevent false positives. |
19 | * | 19 | * |
20 | * | 20 | * |
21 | * This program is free software: you can redistribute it and/or modify | 21 | * This program is free software: you can redistribute it and/or modify |
22 | * it under the terms of the GNU General Public License as published by | 22 | * it under the terms of the GNU General Public License as published by |
23 | * the Free Software Foundation, either version 3 of the License, or | 23 | * the Free Software Foundation, either version 3 of the License, or |
24 | * (at your option) any later version. | 24 | * (at your option) any later version. |
25 | * | 25 | * |
26 | * This program is distributed in the hope that it will be useful, | 26 | * This program is distributed in the hope that it will be useful, |
27 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 27 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
28 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 28 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
29 | * GNU General Public License for more details. | 29 | * GNU General Public License for more details. |
30 | * | 30 | * |
31 | * You should have received a copy of the GNU General Public License | 31 | * You should have received a copy of the GNU General Public License |
32 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 32 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
33 | * | 33 | * |
34 | * | 34 | * |
35 | *****************************************************************************/ | 35 | *****************************************************************************/ |
36 | 36 | ||
37 | const char *progname = "check_procs"; | 37 | const char *progname = "check_procs"; |
38 | const char *program_name = "check_procs"; /* Required for coreutils libs */ | 38 | const char *program_name = "check_procs"; /* Required for coreutils libs */ |
39 | const char *copyright = "2000-2008"; | 39 | const char *copyright = "2000-2024"; |
40 | const char *email = "devel@monitoring-plugins.org"; | 40 | const char *email = "devel@monitoring-plugins.org"; |
41 | 41 | ||
42 | #include "common.h" | 42 | #include "common.h" |
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" | ||
47 | #include "check_procs.d/config.h" | ||
46 | 48 | ||
47 | #include <pwd.h> | 49 | #include <pwd.h> |
48 | #include <errno.h> | 50 | #include <errno.h> |
49 | 51 | ||
50 | #ifdef HAVE_SYS_STAT_H | 52 | #ifdef HAVE_SYS_STAT_H |
51 | #include <sys/stat.h> | 53 | # include <sys/stat.h> |
52 | #endif | 54 | #endif |
53 | 55 | ||
54 | int process_arguments (int, char **); | 56 | typedef struct { |
55 | int validate_arguments (void); | 57 | int errorcode; |
56 | int convert_to_seconds (char *); | 58 | check_procs_config config; |
57 | void print_help (void); | 59 | } check_procs_config_wrapper; |
58 | void print_usage (void); | 60 | static check_procs_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); |
59 | 61 | static check_procs_config_wrapper validate_arguments(check_procs_config_wrapper /*config_wrapper*/); | |
60 | char *warning_range = NULL; | 62 | |
61 | char *critical_range = NULL; | 63 | static int convert_to_seconds(char * /*etime*/, enum metric /*metric*/); |
62 | thresholds *procs_thresholds = NULL; | 64 | static void print_help(void); |
63 | 65 | void print_usage(void); | |
64 | int options = 0; /* bitmask of filter criteria to test against */ | 66 | |
65 | #define ALL 1 | 67 | #define ALL 1 |
66 | #define STAT 2 | 68 | #define STAT 2 |
67 | #define PPID 4 | 69 | #define PPID 4 |
68 | #define USER 8 | 70 | #define USER 8 |
69 | #define PROG 16 | 71 | #define PROG 16 |
70 | #define ARGS 32 | 72 | #define ARGS 32 |
71 | #define VSZ 64 | 73 | #define VSZ 64 |
72 | #define RSS 128 | 74 | #define RSS 128 |
73 | #define PCPU 256 | 75 | #define PCPU 256 |
74 | #define ELAPSED 512 | 76 | #define ELAPSED 512 |
75 | #define EREG_ARGS 1024 | 77 | #define EREG_ARGS 1024 |
76 | #define EXCLUDE_PROGS 2048 | 78 | #define EXCLUDE_PROGS 2048 |
77 | 79 | ||
78 | #define KTHREAD_PARENT "kthreadd" /* the parent process of kernel threads: | 80 | #define KTHREAD_PARENT \ |
79 | ppid of procs are compared to pid of this proc*/ | 81 | "kthreadd" /* the parent process of kernel threads: \ |
80 | 82 | ppid of procs are compared to pid of this proc*/ | |
81 | /* Different metrics */ | 83 | |
82 | char *metric_name; | 84 | static int verbose = 0; |
83 | enum metric { | 85 | |
84 | METRIC_PROCS, | 86 | static int stat_exe(const pid_t pid, struct stat *buf) { |
85 | METRIC_VSZ, | ||
86 | METRIC_RSS, | ||
87 | METRIC_CPU, | ||
88 | METRIC_ELAPSED | ||
89 | }; | ||
90 | enum metric metric = METRIC_PROCS; | ||
91 | |||
92 | int verbose = 0; | ||
93 | int uid; | ||
94 | pid_t ppid; | ||
95 | int vsz; | ||
96 | int rss; | ||
97 | float pcpu; | ||
98 | char *statopts; | ||
99 | char *prog; | ||
100 | char *exclude_progs; | ||
101 | char **exclude_progs_arr = NULL; | ||
102 | char exclude_progs_counter = 0; | ||
103 | char *args; | ||
104 | char *input_filename = NULL; | ||
105 | regex_t re_args; | ||
106 | char *fmt; | ||
107 | char *fails; | ||
108 | char tmp[MAX_INPUT_BUFFER]; | ||
109 | int kthread_filter = 0; | ||
110 | int usepid = 0; /* whether to test for pid or /proc/pid/exe */ | ||
111 | |||
112 | FILE *ps_input = NULL; | ||
113 | |||
114 | static int | ||
115 | stat_exe (const pid_t pid, struct stat *buf) { | ||
116 | char *path; | 87 | char *path; |
117 | int ret; | ||
118 | xasprintf(&path, "/proc/%d/exe", pid); | 88 | xasprintf(&path, "/proc/%d/exe", pid); |
119 | ret = stat(path, buf); | 89 | int ret = stat(path, buf); |
120 | free(path); | 90 | free(path); |
121 | return ret; | 91 | return ret; |
122 | } | 92 | } |
123 | 93 | ||
124 | 94 | int main(int argc, char **argv) { | |
125 | int | 95 | setlocale(LC_ALL, ""); |
126 | main (int argc, char **argv) | ||
127 | { | ||
128 | char *input_buffer; | ||
129 | char *input_line; | ||
130 | char *procprog; | ||
131 | |||
132 | pid_t mypid = 0; | ||
133 | pid_t myppid = 0; | ||
134 | struct stat statbuf; | ||
135 | dev_t mydev = 0; | ||
136 | ino_t myino = 0; | ||
137 | int procuid = 0; | ||
138 | pid_t procpid = 0; | ||
139 | pid_t procppid = 0; | ||
140 | pid_t kthread_ppid = 0; | ||
141 | int procvsz = 0; | ||
142 | int procrss = 0; | ||
143 | int procseconds = 0; | ||
144 | float procpcpu = 0; | ||
145 | char procstat[8]; | ||
146 | char procetime[MAX_INPUT_BUFFER] = { '\0' }; | ||
147 | char *procargs; | ||
148 | |||
149 | const char *zombie = "Z"; | ||
150 | |||
151 | int resultsum = 0; /* bitmask of the filter criteria met by a process */ | ||
152 | int found = 0; /* counter for number of lines returned in `ps` output */ | ||
153 | int procs = 0; /* counter for number of processes meeting filter criteria */ | ||
154 | int pos; /* number of spaces before 'args' in `ps` output */ | ||
155 | int cols; /* number of columns in ps output */ | ||
156 | int expected_cols = PS_COLS - 1; | ||
157 | int warn = 0; /* number of processes in warn state */ | ||
158 | int crit = 0; /* number of processes in crit state */ | ||
159 | int i = 0; | ||
160 | int result = STATE_UNKNOWN; | ||
161 | int ret = 0; | ||
162 | output chld_out, chld_err; | ||
163 | |||
164 | setlocale (LC_ALL, ""); | ||
165 | bindtextdomain (PACKAGE, LOCALEDIR); | ||
166 | textdomain (PACKAGE); | ||
167 | setlocale(LC_NUMERIC, "POSIX"); | 96 | setlocale(LC_NUMERIC, "POSIX"); |
168 | 97 | bindtextdomain(PACKAGE, LOCALEDIR); | |
169 | input_buffer = malloc (MAX_INPUT_BUFFER); | 98 | textdomain(PACKAGE); |
170 | procprog = malloc (MAX_INPUT_BUFFER); | ||
171 | |||
172 | xasprintf (&metric_name, "PROCS"); | ||
173 | metric = METRIC_PROCS; | ||
174 | 99 | ||
175 | /* Parse extra opts if any */ | 100 | /* Parse extra opts if any */ |
176 | argv=np_extra_opts (&argc, argv, progname); | 101 | argv = np_extra_opts(&argc, argv, progname); |
102 | |||
103 | check_procs_config_wrapper tmp_config = process_arguments(argc, argv); | ||
104 | if (tmp_config.errorcode == ERROR) { | ||
105 | usage4(_("Could not parse arguments")); | ||
106 | } | ||
177 | 107 | ||
178 | if (process_arguments (argc, argv) == ERROR) | 108 | check_procs_config config = tmp_config.config; |
179 | usage4 (_("Could not parse arguments")); | ||
180 | 109 | ||
181 | /* find ourself */ | 110 | /* find ourself */ |
182 | mypid = getpid(); | 111 | pid_t mypid = getpid(); |
183 | myppid = getppid(); | 112 | pid_t myppid = getppid(); |
184 | if (usepid || stat_exe(mypid, &statbuf) == -1) { | 113 | dev_t mydev = 0; |
114 | ino_t myino = 0; | ||
115 | struct stat statbuf; | ||
116 | if (config.usepid || stat_exe(mypid, &statbuf) == -1) { | ||
185 | /* usepid might have been set by -T */ | 117 | /* usepid might have been set by -T */ |
186 | usepid = 1; | 118 | config.usepid = true; |
187 | } else { | 119 | } else { |
188 | usepid = 0; | 120 | config.usepid = false; |
189 | mydev = statbuf.st_dev; | 121 | mydev = statbuf.st_dev; |
190 | myino = statbuf.st_ino; | 122 | myino = statbuf.st_ino; |
191 | } | 123 | } |
192 | 124 | ||
193 | /* Set signal handling and alarm timeout */ | 125 | /* Set signal handling and alarm timeout */ |
194 | if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) { | 126 | if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { |
195 | die (STATE_UNKNOWN, _("Cannot catch SIGALRM")); | 127 | die(STATE_UNKNOWN, _("Cannot catch SIGALRM")); |
196 | } | 128 | } |
197 | (void) alarm ((unsigned) timeout_interval); | 129 | (void)alarm(timeout_interval); |
198 | 130 | ||
199 | if (verbose >= 2) | 131 | if (verbose >= 2) { |
200 | printf (_("CMD: %s\n"), PS_COMMAND); | 132 | printf(_("CMD: %s\n"), PS_COMMAND); |
133 | } | ||
201 | 134 | ||
202 | if (input_filename == NULL) { | 135 | output chld_out; |
203 | result = cmd_run( PS_COMMAND, &chld_out, &chld_err, 0); | 136 | output chld_err; |
137 | mp_state_enum result = STATE_UNKNOWN; | ||
138 | if (config.input_filename == NULL) { | ||
139 | result = cmd_run(PS_COMMAND, &chld_out, &chld_err, 0); | ||
204 | if (chld_err.lines > 0) { | 140 | if (chld_err.lines > 0) { |
205 | printf ("%s: %s", _("System call sent warnings to stderr"), chld_err.line[0]); | 141 | printf("%s: %s", _("System call sent warnings to stderr"), chld_err.line[0]); |
206 | exit(STATE_WARNING); | 142 | exit(STATE_WARNING); |
207 | } | 143 | } |
208 | } else { | 144 | } else { |
209 | result = cmd_file_read( input_filename, &chld_out, 0); | 145 | result = cmd_file_read(config.input_filename, &chld_out, 0); |
210 | } | 146 | } |
211 | 147 | ||
148 | int pos; /* number of spaces before 'args' in `ps` output */ | ||
149 | uid_t procuid = 0; | ||
150 | pid_t procpid = 0; | ||
151 | pid_t procppid = 0; | ||
152 | pid_t kthread_ppid = 0; | ||
153 | int warn = 0; /* number of processes in warn state */ | ||
154 | int crit = 0; /* number of processes in crit state */ | ||
155 | int procvsz = 0; | ||
156 | int procrss = 0; | ||
157 | int procseconds = 0; | ||
158 | float procpcpu = 0; | ||
159 | char procstat[8]; | ||
160 | char procetime[MAX_INPUT_BUFFER] = {'\0'}; | ||
161 | int resultsum = 0; /* bitmask of the filter criteria met by a process */ | ||
162 | int found = 0; /* counter for number of lines returned in `ps` output */ | ||
163 | int procs = 0; /* counter for number of processes meeting filter criteria */ | ||
164 | char *input_buffer = malloc(MAX_INPUT_BUFFER); | ||
165 | char *procprog = malloc(MAX_INPUT_BUFFER); | ||
166 | const int expected_cols = PS_COLS - 1; | ||
167 | |||
212 | /* flush first line: j starts at 1 */ | 168 | /* flush first line: j starts at 1 */ |
213 | for (size_t j = 1; j < chld_out.lines; j++) { | 169 | for (size_t j = 1; j < chld_out.lines; j++) { |
214 | input_line = chld_out.line[j]; | 170 | char *input_line = chld_out.line[j]; |
215 | 171 | ||
216 | if (verbose >= 3) | 172 | if (verbose >= 3) { |
217 | printf ("%s", input_line); | 173 | printf("%s", input_line); |
174 | } | ||
218 | 175 | ||
219 | strcpy (procprog, ""); | 176 | strcpy(procprog, ""); |
220 | xasprintf (&procargs, "%s", ""); | 177 | char *procargs; |
178 | xasprintf(&procargs, "%s", ""); | ||
221 | 179 | ||
222 | cols = sscanf (input_line, PS_FORMAT, PS_VARLIST); | 180 | /* number of columns in ps output */ |
181 | int cols = sscanf(input_line, PS_FORMAT, PS_VARLIST); | ||
223 | 182 | ||
224 | /* Zombie processes do not give a procprog command */ | 183 | /* Zombie processes do not give a procprog command */ |
225 | if ( cols < expected_cols && strstr(procstat, zombie) ) { | 184 | const char *zombie = "Z"; |
185 | if (cols < expected_cols && strstr(procstat, zombie)) { | ||
226 | cols = expected_cols; | 186 | cols = expected_cols; |
227 | } | 187 | } |
228 | if ( cols >= expected_cols ) { | 188 | if (cols >= expected_cols) { |
229 | resultsum = 0; | 189 | resultsum = 0; |
230 | xasprintf (&procargs, "%s", input_line + pos); | 190 | xasprintf(&procargs, "%s", input_line + pos); |
231 | strip (procargs); | 191 | strip(procargs); |
232 | 192 | ||
233 | /* Some ps return full pathname for command. This removes path */ | 193 | /* Some ps return full pathname for command. This removes path */ |
234 | strcpy(procprog, base_name(procprog)); | 194 | strcpy(procprog, base_name(procprog)); |
235 | 195 | ||
236 | /* we need to convert the elapsed time to seconds */ | 196 | /* we need to convert the elapsed time to seconds */ |
237 | procseconds = convert_to_seconds(procetime); | 197 | procseconds = convert_to_seconds(procetime, config.metric); |
238 | 198 | ||
239 | if (verbose >= 3) | 199 | if (verbose >= 3) { |
240 | printf ("proc#=%d uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", | 200 | printf("proc#=%d uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", procs, procuid, procvsz, |
241 | procs, procuid, procvsz, procrss, | 201 | procrss, procpid, procppid, procpcpu, procstat, procetime, procprog, procargs); |
242 | procpid, procppid, procpcpu, procstat, | 202 | } |
243 | procetime, procprog, procargs); | ||
244 | 203 | ||
245 | /* Ignore self */ | 204 | /* Ignore self */ |
246 | if ((usepid && mypid == procpid) || | 205 | int ret = 0; |
247 | ( ((!usepid) && ((ret = stat_exe(procpid, &statbuf) != -1) && statbuf.st_dev == mydev && statbuf.st_ino == myino)) || | 206 | if ((config.usepid && mypid == procpid) || |
248 | (ret == -1 && errno == ENOENT)) | 207 | (((!config.usepid) && ((ret = stat_exe(procpid, &statbuf) != -1) && statbuf.st_dev == mydev && statbuf.st_ino == myino)) || |
249 | ) { | 208 | (ret == -1 && errno == ENOENT))) { |
250 | if (verbose >= 3) | 209 | if (verbose >= 3) { |
251 | printf("not considering - is myself or gone\n"); | 210 | printf("not considering - is myself or gone\n"); |
211 | } | ||
252 | continue; | 212 | continue; |
253 | } | 213 | } |
254 | /* Ignore parent*/ | 214 | /* Ignore parent*/ |
255 | else if (myppid == procpid) { | 215 | if (myppid == procpid) { |
256 | if (verbose >= 3) | 216 | if (verbose >= 3) { |
257 | printf("not considering - is parent\n"); | 217 | printf("not considering - is parent\n"); |
218 | } | ||
258 | continue; | 219 | continue; |
259 | } | 220 | } |
260 | 221 | ||
261 | /* Ignore our own children */ | 222 | /* Ignore our own children */ |
262 | if (procppid == mypid) { | 223 | if (procppid == mypid) { |
263 | if (verbose >= 3) | 224 | if (verbose >= 3) { |
264 | printf("not considering - is our child\n"); | 225 | printf("not considering - is our child\n"); |
226 | } | ||
265 | continue; | 227 | continue; |
266 | } | 228 | } |
267 | 229 | ||
268 | /* Ignore excluded processes by name */ | 230 | /* Ignore excluded processes by name */ |
269 | if(options & EXCLUDE_PROGS) { | 231 | if (config.options & EXCLUDE_PROGS) { |
270 | int found = 0; | 232 | bool found = false; |
271 | int i = 0; | 233 | for (int i = 0; i < (config.exclude_progs_counter); i++) { |
272 | 234 | if (!strcmp(procprog, config.exclude_progs_arr[i])) { | |
273 | for(i=0; i < (exclude_progs_counter); i++) { | 235 | found = true; |
274 | if(!strcmp(procprog, exclude_progs_arr[i])) { | 236 | } |
275 | found = 1; | 237 | } |
276 | } | 238 | if (!found) { |
277 | } | 239 | resultsum |= EXCLUDE_PROGS; |
278 | if(found == 0) { | 240 | } else { |
279 | resultsum |= EXCLUDE_PROGS; | 241 | if (verbose >= 3) { |
280 | } else | 242 | printf("excluding - by ignorelist\n"); |
281 | { | 243 | } |
282 | if(verbose >= 3) | 244 | } |
283 | printf("excluding - by ignorelist\n"); | ||
284 | } | ||
285 | } | 245 | } |
286 | 246 | ||
287 | /* filter kernel threads (children of KTHREAD_PARENT)*/ | 247 | /* filter kernel threads (children of KTHREAD_PARENT)*/ |
288 | /* TODO adapt for other OSes than GNU/Linux | 248 | /* TODO adapt for other OSes than GNU/Linux |
289 | sorry for not doing that, but I've no other OSes to test :-( */ | 249 | sorry for not doing that, but I've no other OSes to test :-( */ |
290 | if (kthread_filter == 1) { | 250 | if (config.kthread_filter) { |
291 | /* get pid KTHREAD_PARENT */ | 251 | /* get pid KTHREAD_PARENT */ |
292 | if (kthread_ppid == 0 && !strcmp(procprog, KTHREAD_PARENT) ) | 252 | if (kthread_ppid == 0 && !strcmp(procprog, KTHREAD_PARENT)) { |
293 | kthread_ppid = procpid; | 253 | kthread_ppid = procpid; |
254 | } | ||
294 | 255 | ||
295 | if (kthread_ppid == procppid) { | 256 | if (kthread_ppid == procppid) { |
296 | if (verbose >= 2) | 257 | if (verbose >= 2) { |
297 | printf ("Ignore kernel thread: pid=%d ppid=%d prog=%s args=%s\n", procpid, procppid, procprog, procargs); | 258 | printf("Ignore kernel thread: pid=%d ppid=%d prog=%s args=%s\n", procpid, procppid, procprog, procargs); |
259 | } | ||
298 | continue; | 260 | continue; |
299 | } | 261 | } |
300 | } | 262 | } |
301 | 263 | ||
302 | if ((options & STAT) && (strstr (procstat, statopts))) | 264 | if ((config.options & STAT) && (strstr(procstat, config.statopts))) { |
303 | resultsum |= STAT; | 265 | resultsum |= STAT; |
304 | if ((options & ARGS) && procargs && (strstr (procargs, args) != NULL)) | 266 | } |
267 | if ((config.options & ARGS) && procargs && (strstr(procargs, config.args) != NULL)) { | ||
305 | resultsum |= ARGS; | 268 | resultsum |= ARGS; |
306 | if ((options & EREG_ARGS) && procargs && (regexec(&re_args, procargs, (size_t) 0, NULL, 0) == 0)) | 269 | } |
270 | if ((config.options & EREG_ARGS) && procargs && (regexec(&config.re_args, procargs, (size_t)0, NULL, 0) == 0)) { | ||
307 | resultsum |= EREG_ARGS; | 271 | resultsum |= EREG_ARGS; |
308 | if ((options & PROG) && procprog && (strcmp (prog, procprog) == 0)) | 272 | } |
273 | if ((config.options & PROG) && procprog && (strcmp(config.prog, procprog) == 0)) { | ||
309 | resultsum |= PROG; | 274 | resultsum |= PROG; |
310 | if ((options & PPID) && (procppid == ppid)) | 275 | } |
276 | if ((config.options & PPID) && (procppid == config.ppid)) { | ||
311 | resultsum |= PPID; | 277 | resultsum |= PPID; |
312 | if ((options & USER) && (procuid == uid)) | 278 | } |
279 | if ((config.options & USER) && (procuid == config.uid)) { | ||
313 | resultsum |= USER; | 280 | resultsum |= USER; |
314 | if ((options & VSZ) && (procvsz >= vsz)) | 281 | } |
282 | if ((config.options & VSZ) && (procvsz >= config.vsz)) { | ||
315 | resultsum |= VSZ; | 283 | resultsum |= VSZ; |
316 | if ((options & RSS) && (procrss >= rss)) | 284 | } |
285 | if ((config.options & RSS) && (procrss >= config.rss)) { | ||
317 | resultsum |= RSS; | 286 | resultsum |= RSS; |
318 | if ((options & PCPU) && (procpcpu >= pcpu)) | 287 | } |
288 | if ((config.options & PCPU) && (procpcpu >= config.pcpu)) { | ||
319 | resultsum |= PCPU; | 289 | resultsum |= PCPU; |
290 | } | ||
320 | 291 | ||
321 | found++; | 292 | found++; |
322 | 293 | ||
323 | /* Next line if filters not matched */ | 294 | /* Next line if filters not matched */ |
324 | if (!(options == resultsum || options == ALL)) | 295 | if (!(config.options == resultsum || config.options == ALL)) { |
325 | continue; | 296 | continue; |
297 | } | ||
326 | 298 | ||
327 | procs++; | 299 | procs++; |
328 | if (verbose >= 2) { | 300 | if (verbose >= 2) { |
329 | printf ("Matched: uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", | 301 | printf("Matched: uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", procuid, procvsz, |
330 | procuid, procvsz, procrss, | 302 | procrss, procpid, procppid, procpcpu, procstat, procetime, procprog, procargs); |
331 | procpid, procppid, procpcpu, procstat, | ||
332 | procetime, procprog, procargs); | ||
333 | } | 303 | } |
334 | 304 | ||
335 | if (metric == METRIC_VSZ) | 305 | mp_state_enum temporary_result = STATE_OK; |
336 | i = get_status ((double)procvsz, procs_thresholds); | 306 | if (config.metric == METRIC_VSZ) { |
337 | else if (metric == METRIC_RSS) | 307 | temporary_result = get_status((double)procvsz, config.procs_thresholds); |
338 | i = get_status ((double)procrss, procs_thresholds); | 308 | } else if (config.metric == METRIC_RSS) { |
309 | temporary_result = get_status((double)procrss, config.procs_thresholds); | ||
310 | } | ||
339 | /* TODO? float thresholds for --metric=CPU */ | 311 | /* TODO? float thresholds for --metric=CPU */ |
340 | else if (metric == METRIC_CPU) | 312 | else if (config.metric == METRIC_CPU) { |
341 | i = get_status (procpcpu, procs_thresholds); | 313 | temporary_result = get_status(procpcpu, config.procs_thresholds); |
342 | else if (metric == METRIC_ELAPSED) | 314 | } else if (config.metric == METRIC_ELAPSED) { |
343 | i = get_status ((double)procseconds, procs_thresholds); | 315 | temporary_result = get_status((double)procseconds, config.procs_thresholds); |
316 | } | ||
344 | 317 | ||
345 | if (metric != METRIC_PROCS) { | 318 | if (config.metric != METRIC_PROCS) { |
346 | if (i == STATE_WARNING) { | 319 | if (temporary_result == STATE_WARNING) { |
347 | warn++; | 320 | warn++; |
348 | xasprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog); | 321 | xasprintf(&config.fails, "%s%s%s", config.fails, (strcmp(config.fails, "") ? ", " : ""), procprog); |
349 | result = max_state (result, i); | 322 | result = max_state(result, temporary_result); |
350 | } | 323 | } |
351 | if (i == STATE_CRITICAL) { | 324 | if (temporary_result == STATE_CRITICAL) { |
352 | crit++; | 325 | crit++; |
353 | xasprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog); | 326 | xasprintf(&config.fails, "%s%s%s", config.fails, (strcmp(config.fails, "") ? ", " : ""), procprog); |
354 | result = max_state (result, i); | 327 | result = max_state(result, temporary_result); |
355 | } | 328 | } |
356 | } | 329 | } |
357 | } | 330 | } |
@@ -361,339 +334,350 @@ main (int argc, char **argv) | |||
361 | } | 334 | } |
362 | } | 335 | } |
363 | 336 | ||
364 | if (found == 0) { /* no process lines parsed so return STATE_UNKNOWN */ | 337 | if (found == 0) { /* no process lines parsed so return STATE_UNKNOWN */ |
365 | printf (_("Unable to read output\n")); | 338 | printf(_("Unable to read output\n")); |
366 | return STATE_UNKNOWN; | 339 | return STATE_UNKNOWN; |
367 | } | 340 | } |
368 | 341 | ||
369 | if ( result == STATE_UNKNOWN ) | 342 | if (result == STATE_UNKNOWN) { |
370 | result = STATE_OK; | 343 | result = STATE_OK; |
344 | } | ||
371 | 345 | ||
372 | /* Needed if procs found, but none match filter */ | 346 | /* Needed if procs found, but none match filter */ |
373 | if ( metric == METRIC_PROCS ) { | 347 | if (config.metric == METRIC_PROCS) { |
374 | result = max_state (result, get_status ((double)procs, procs_thresholds) ); | 348 | result = max_state(result, get_status((double)procs, config.procs_thresholds)); |
375 | } | 349 | } |
376 | 350 | ||
377 | if ( result == STATE_OK ) { | 351 | if (result == STATE_OK) { |
378 | printf ("%s %s: ", metric_name, _("OK")); | 352 | printf("%s %s: ", config.metric_name, _("OK")); |
379 | } else if (result == STATE_WARNING) { | 353 | } else if (result == STATE_WARNING) { |
380 | printf ("%s %s: ", metric_name, _("WARNING")); | 354 | printf("%s %s: ", config.metric_name, _("WARNING")); |
381 | if ( metric != METRIC_PROCS ) { | 355 | if (config.metric != METRIC_PROCS) { |
382 | printf (_("%d warn out of "), warn); | 356 | printf(_("%d warn out of "), warn); |
383 | } | 357 | } |
384 | } else if (result == STATE_CRITICAL) { | 358 | } else if (result == STATE_CRITICAL) { |
385 | printf ("%s %s: ", metric_name, _("CRITICAL")); | 359 | printf("%s %s: ", config.metric_name, _("CRITICAL")); |
386 | if (metric != METRIC_PROCS) { | 360 | if (config.metric != METRIC_PROCS) { |
387 | printf (_("%d crit, %d warn out of "), crit, warn); | 361 | printf(_("%d crit, %d warn out of "), crit, warn); |
388 | } | 362 | } |
389 | } | 363 | } |
390 | printf (ngettext ("%d process", "%d processes", (unsigned long) procs), procs); | 364 | printf(ngettext("%d process", "%d processes", (unsigned long)procs), procs); |
391 | 365 | ||
392 | if (strcmp(fmt,"") != 0) { | 366 | if (strcmp(config.fmt, "") != 0) { |
393 | printf (_(" with %s"), fmt); | 367 | printf(_(" with %s"), config.fmt); |
394 | } | 368 | } |
395 | 369 | ||
396 | if ( verbose >= 1 && strcmp(fails,"") ) | 370 | if (verbose >= 1 && strcmp(config.fails, "")) { |
397 | printf (" [%s]", fails); | 371 | printf(" [%s]", config.fails); |
372 | } | ||
398 | 373 | ||
399 | if (metric == METRIC_PROCS) | 374 | if (config.metric == METRIC_PROCS) { |
400 | printf (" | procs=%d;%s;%s;0;", procs, | 375 | printf(" | procs=%d;%s;%s;0;", procs, config.warning_range ? config.warning_range : "", |
401 | warning_range ? warning_range : "", | 376 | config.critical_range ? config.critical_range : ""); |
402 | critical_range ? critical_range : ""); | 377 | } else { |
403 | else | 378 | printf(" | procs=%d;;;0; procs_warn=%d;;;0; procs_crit=%d;;;0;", procs, warn, crit); |
404 | printf (" | procs=%d;;;0; procs_warn=%d;;;0; procs_crit=%d;;;0;", procs, warn, crit); | 379 | } |
405 | 380 | ||
406 | printf ("\n"); | 381 | printf("\n"); |
407 | return result; | 382 | exit(result); |
408 | } | 383 | } |
409 | 384 | ||
410 | |||
411 | |||
412 | /* process command-line arguments */ | 385 | /* process command-line arguments */ |
413 | int | 386 | check_procs_config_wrapper process_arguments(int argc, char **argv) { |
414 | process_arguments (int argc, char **argv) | 387 | static struct option longopts[] = {{"warning", required_argument, 0, 'w'}, |
415 | { | 388 | {"critical", required_argument, 0, 'c'}, |
416 | int c = 1; | 389 | {"metric", required_argument, 0, 'm'}, |
417 | char *user; | 390 | {"timeout", required_argument, 0, 't'}, |
418 | struct passwd *pw; | 391 | {"status", required_argument, 0, 's'}, |
419 | int option = 0; | 392 | {"ppid", required_argument, 0, 'p'}, |
420 | int err; | 393 | {"user", required_argument, 0, 'u'}, |
421 | int cflags = REG_NOSUB | REG_EXTENDED; | 394 | {"command", required_argument, 0, 'C'}, |
422 | char errbuf[MAX_INPUT_BUFFER]; | 395 | {"vsz", required_argument, 0, 'z'}, |
423 | char *temp_string; | 396 | {"rss", required_argument, 0, 'r'}, |
424 | int i=0; | 397 | {"pcpu", required_argument, 0, 'P'}, |
425 | static struct option longopts[] = { | 398 | {"elapsed", required_argument, 0, 'e'}, |
426 | {"warning", required_argument, 0, 'w'}, | 399 | {"argument-array", required_argument, 0, 'a'}, |
427 | {"critical", required_argument, 0, 'c'}, | 400 | {"help", no_argument, 0, 'h'}, |
428 | {"metric", required_argument, 0, 'm'}, | 401 | {"version", no_argument, 0, 'V'}, |
429 | {"timeout", required_argument, 0, 't'}, | 402 | {"verbose", no_argument, 0, 'v'}, |
430 | {"status", required_argument, 0, 's'}, | 403 | {"ereg-argument-array", required_argument, 0, CHAR_MAX + 1}, |
431 | {"ppid", required_argument, 0, 'p'}, | 404 | {"input-file", required_argument, 0, CHAR_MAX + 2}, |
432 | {"user", required_argument, 0, 'u'}, | 405 | {"no-kthreads", required_argument, 0, 'k'}, |
433 | {"command", required_argument, 0, 'C'}, | 406 | {"traditional-filter", no_argument, 0, 'T'}, |
434 | {"vsz", required_argument, 0, 'z'}, | 407 | {"exclude-process", required_argument, 0, 'X'}, |
435 | {"rss", required_argument, 0, 'r'}, | 408 | {0, 0, 0, 0}}; |
436 | {"pcpu", required_argument, 0, 'P'}, | 409 | |
437 | {"elapsed", required_argument, 0, 'e'}, | 410 | for (int index = 1; index < argc; index++) { |
438 | {"argument-array", required_argument, 0, 'a'}, | 411 | if (strcmp("-to", argv[index]) == 0) { |
439 | {"help", no_argument, 0, 'h'}, | 412 | strcpy(argv[index], "-t"); |
440 | {"version", no_argument, 0, 'V'}, | 413 | } |
441 | {"verbose", no_argument, 0, 'v'}, | 414 | } |
442 | {"ereg-argument-array", required_argument, 0, CHAR_MAX+1}, | ||
443 | {"input-file", required_argument, 0, CHAR_MAX+2}, | ||
444 | {"no-kthreads", required_argument, 0, 'k'}, | ||
445 | {"traditional-filter", no_argument, 0, 'T'}, | ||
446 | {"exclude-process", required_argument, 0, 'X'}, | ||
447 | {0, 0, 0, 0} | ||
448 | }; | ||
449 | 415 | ||
450 | for (c = 1; c < argc; c++) | 416 | check_procs_config_wrapper result = { |
451 | if (strcmp ("-to", argv[c]) == 0) | 417 | .errorcode = OK, |
452 | strcpy (argv[c], "-t"); | 418 | .config = check_procs_config_init(), |
419 | }; | ||
453 | 420 | ||
454 | while (1) { | 421 | while (true) { |
455 | c = getopt_long (argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T:X:", | 422 | int option = 0; |
456 | longopts, &option); | 423 | int option_index = getopt_long(argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T:X:", longopts, &option); |
457 | 424 | ||
458 | if (c == -1 || c == EOF) | 425 | if (option_index == -1 || option_index == EOF) { |
459 | break; | 426 | break; |
427 | } | ||
460 | 428 | ||
461 | switch (c) { | 429 | switch (option_index) { |
462 | case '?': /* help */ | 430 | case '?': /* help */ |
463 | usage5 (); | 431 | usage5(); |
464 | case 'h': /* help */ | 432 | case 'h': /* help */ |
465 | print_help (); | 433 | print_help(); |
466 | exit (STATE_UNKNOWN); | 434 | exit(STATE_UNKNOWN); |
467 | case 'V': /* version */ | 435 | case 'V': /* version */ |
468 | print_revision (progname, NP_VERSION); | 436 | print_revision(progname, NP_VERSION); |
469 | exit (STATE_UNKNOWN); | 437 | exit(STATE_UNKNOWN); |
470 | case 't': /* timeout period */ | 438 | case 't': /* timeout period */ |
471 | if (!is_integer (optarg)) | 439 | if (!is_integer(optarg)) { |
472 | usage2 (_("Timeout interval must be a positive integer"), optarg); | 440 | usage2(_("Timeout interval must be a positive integer"), optarg); |
473 | else | 441 | } else { |
474 | timeout_interval = atoi (optarg); | 442 | timeout_interval = atoi(optarg); |
443 | } | ||
475 | break; | 444 | break; |
476 | case 'c': /* critical threshold */ | 445 | case 'c': /* critical threshold */ |
477 | critical_range = optarg; | 446 | result.config.critical_range = optarg; |
478 | break; | 447 | break; |
479 | case 'w': /* warning threshold */ | 448 | case 'w': /* warning threshold */ |
480 | warning_range = optarg; | 449 | result.config.warning_range = optarg; |
481 | break; | 450 | break; |
482 | case 'p': /* process id */ | 451 | case 'p': { /* process id */ |
483 | if (sscanf (optarg, "%d%[^0-9]", &ppid, tmp) == 1) { | 452 | static char tmp[MAX_INPUT_BUFFER]; |
484 | xasprintf (&fmt, "%s%sPPID = %d", (fmt ? fmt : "") , (options ? ", " : ""), ppid); | 453 | if (sscanf(optarg, "%d%[^0-9]", &result.config.ppid, tmp) == 1) { |
485 | options |= PPID; | 454 | xasprintf(&result.config.fmt, "%s%sPPID = %d", (result.config.fmt ? result.config.fmt : ""), |
455 | (result.config.options ? ", " : ""), result.config.ppid); | ||
456 | result.config.options |= PPID; | ||
486 | break; | 457 | break; |
487 | } | 458 | } |
488 | usage4 (_("Parent Process ID must be an integer!")); | 459 | usage4(_("Parent Process ID must be an integer!")); |
489 | case 's': /* status */ | 460 | } |
490 | if (statopts) | 461 | case 's': /* status */ |
462 | if (result.config.statopts) { | ||
491 | break; | 463 | break; |
492 | else | 464 | } else { |
493 | statopts = optarg; | 465 | result.config.statopts = optarg; |
494 | xasprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); | 466 | } |
495 | options |= STAT; | 467 | xasprintf(&result.config.fmt, _("%s%sSTATE = %s"), (result.config.fmt ? result.config.fmt : ""), |
468 | (result.config.options ? ", " : ""), result.config.statopts); | ||
469 | result.config.options |= STAT; | ||
496 | break; | 470 | break; |
497 | case 'u': /* user or user id */ | 471 | case 'u': /* user or user id */ { |
498 | if (is_integer (optarg)) { | 472 | struct passwd *pw; |
499 | uid = atoi (optarg); | 473 | if (is_integer(optarg)) { |
500 | pw = getpwuid ((uid_t) uid); | 474 | result.config.uid = atoi(optarg); |
475 | pw = getpwuid(result.config.uid); | ||
501 | /* check to be sure user exists */ | 476 | /* check to be sure user exists */ |
502 | if (pw == NULL) | 477 | if (pw == NULL) { |
503 | usage2 (_("UID was not found"), optarg); | 478 | usage2(_("UID was not found"), optarg); |
504 | } | 479 | } |
505 | else { | 480 | } else { |
506 | pw = getpwnam (optarg); | 481 | pw = getpwnam(optarg); |
507 | /* check to be sure user exists */ | 482 | /* check to be sure user exists */ |
508 | if (pw == NULL) | 483 | if (pw == NULL) { |
509 | usage2 (_("User name was not found"), optarg); | 484 | usage2(_("User name was not found"), optarg); |
485 | } | ||
510 | /* then get uid */ | 486 | /* then get uid */ |
511 | uid = pw->pw_uid; | 487 | result.config.uid = pw->pw_uid; |
512 | } | 488 | } |
513 | user = pw->pw_name; | 489 | |
514 | xasprintf (&fmt, "%s%sUID = %d (%s)", (fmt ? fmt : ""), (options ? ", " : ""), | 490 | char *user = pw->pw_name; |
515 | uid, user); | 491 | xasprintf(&result.config.fmt, "%s%sUID = %d (%s)", (result.config.fmt ? result.config.fmt : ""), |
516 | options |= USER; | 492 | (result.config.options ? ", " : ""), result.config.uid, user); |
517 | break; | 493 | result.config.options |= USER; |
518 | case 'C': /* command */ | 494 | } break; |
495 | case 'C': /* command */ | ||
519 | /* TODO: allow this to be passed in with --metric */ | 496 | /* TODO: allow this to be passed in with --metric */ |
520 | if (prog) | 497 | if (result.config.prog) { |
521 | break; | 498 | break; |
522 | else | 499 | } else { |
523 | prog = optarg; | 500 | result.config.prog = optarg; |
524 | xasprintf (&fmt, _("%s%scommand name '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), | 501 | } |
525 | prog); | 502 | xasprintf(&result.config.fmt, _("%s%scommand name '%s'"), (result.config.fmt ? result.config.fmt : ""), |
526 | options |= PROG; | 503 | (result.config.options ? ", " : ""), result.config.prog); |
504 | result.config.options |= PROG; | ||
527 | break; | 505 | break; |
528 | case 'X': | 506 | case 'X': |
529 | if(exclude_progs) | 507 | if (result.config.exclude_progs) { |
530 | break; | 508 | break; |
531 | else | 509 | } else { |
532 | exclude_progs = optarg; | 510 | result.config.exclude_progs = optarg; |
533 | xasprintf (&fmt, _("%s%sexclude progs '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), | 511 | } |
534 | exclude_progs); | 512 | xasprintf(&result.config.fmt, _("%s%sexclude progs '%s'"), (result.config.fmt ? result.config.fmt : ""), |
535 | char *p = strtok(exclude_progs, ","); | 513 | (result.config.options ? ", " : ""), result.config.exclude_progs); |
536 | 514 | char *tmp_pointer = strtok(result.config.exclude_progs, ","); | |
537 | while(p){ | 515 | |
538 | exclude_progs_arr = realloc(exclude_progs_arr, sizeof(char*) * ++exclude_progs_counter); | 516 | while (tmp_pointer) { |
539 | exclude_progs_arr[exclude_progs_counter-1] = p; | 517 | result.config.exclude_progs_arr = |
540 | p = strtok(NULL, ","); | 518 | realloc(result.config.exclude_progs_arr, sizeof(char *) * ++result.config.exclude_progs_counter); |
519 | result.config.exclude_progs_arr[result.config.exclude_progs_counter - 1] = tmp_pointer; | ||
520 | tmp_pointer = strtok(NULL, ","); | ||
541 | } | 521 | } |
542 | 522 | ||
543 | options |= EXCLUDE_PROGS; | 523 | result.config.options |= EXCLUDE_PROGS; |
544 | break; | 524 | break; |
545 | case 'a': /* args (full path name with args) */ | 525 | case 'a': /* args (full path name with args) */ |
546 | /* TODO: allow this to be passed in with --metric */ | 526 | /* TODO: allow this to be passed in with --metric */ |
547 | if (args) | 527 | if (result.config.args) { |
548 | break; | 528 | break; |
549 | else | 529 | } else { |
550 | args = optarg; | 530 | result.config.args = optarg; |
551 | xasprintf (&fmt, "%s%sargs '%s'", (fmt ? fmt : ""), (options ? ", " : ""), args); | 531 | } |
552 | options |= ARGS; | 532 | xasprintf(&result.config.fmt, "%s%sargs '%s'", (result.config.fmt ? result.config.fmt : ""), |
533 | (result.config.options ? ", " : ""), result.config.args); | ||
534 | result.config.options |= ARGS; | ||
553 | break; | 535 | break; |
554 | case CHAR_MAX+1: | 536 | case CHAR_MAX + 1: { |
555 | err = regcomp(&re_args, optarg, cflags); | 537 | int cflags = REG_NOSUB | REG_EXTENDED; |
538 | int err = regcomp(&result.config.re_args, optarg, cflags); | ||
556 | if (err != 0) { | 539 | if (err != 0) { |
557 | regerror (err, &re_args, errbuf, MAX_INPUT_BUFFER); | 540 | char errbuf[MAX_INPUT_BUFFER]; |
558 | die (STATE_UNKNOWN, "PROCS %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); | 541 | regerror(err, &result.config.re_args, errbuf, MAX_INPUT_BUFFER); |
542 | die(STATE_UNKNOWN, "PROCS %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); | ||
559 | } | 543 | } |
560 | /* Strip off any | within the regex optarg */ | 544 | /* Strip off any | within the regex optarg */ |
561 | temp_string = strdup(optarg); | 545 | char *temp_string = strdup(optarg); |
562 | while(temp_string[i]!='\0'){ | 546 | int index = 0; |
563 | if(temp_string[i]=='|') | 547 | while (temp_string[index] != '\0') { |
564 | temp_string[i]=','; | 548 | if (temp_string[index] == '|') { |
565 | i++; | 549 | temp_string[index] = ','; |
566 | } | 550 | } |
567 | xasprintf (&fmt, "%s%sregex args '%s'", (fmt ? fmt : ""), (options ? ", " : ""), temp_string); | 551 | index++; |
568 | options |= EREG_ARGS; | 552 | } |
569 | break; | 553 | xasprintf(&result.config.fmt, "%s%sregex args '%s'", (result.config.fmt ? result.config.fmt : ""), |
570 | case 'r': /* RSS */ | 554 | (result.config.options ? ", " : ""), temp_string); |
571 | if (sscanf (optarg, "%d%[^0-9]", &rss, tmp) == 1) { | 555 | result.config.options |= EREG_ARGS; |
572 | xasprintf (&fmt, "%s%sRSS >= %d", (fmt ? fmt : ""), (options ? ", " : ""), rss); | 556 | } break; |
573 | options |= RSS; | 557 | case 'r': { /* RSS */ |
558 | static char tmp[MAX_INPUT_BUFFER]; | ||
559 | if (sscanf(optarg, "%d%[^0-9]", &result.config.rss, tmp) == 1) { | ||
560 | xasprintf(&result.config.fmt, "%s%sRSS >= %d", (result.config.fmt ? result.config.fmt : ""), | ||
561 | (result.config.options ? ", " : ""), result.config.rss); | ||
562 | result.config.options |= RSS; | ||
574 | break; | 563 | break; |
575 | } | 564 | } |
576 | usage4 (_("RSS must be an integer!")); | 565 | usage4(_("RSS must be an integer!")); |
577 | case 'z': /* VSZ */ | 566 | } |
578 | if (sscanf (optarg, "%d%[^0-9]", &vsz, tmp) == 1) { | 567 | case 'z': { /* VSZ */ |
579 | xasprintf (&fmt, "%s%sVSZ >= %d", (fmt ? fmt : ""), (options ? ", " : ""), vsz); | 568 | static char tmp[MAX_INPUT_BUFFER]; |
580 | options |= VSZ; | 569 | if (sscanf(optarg, "%d%[^0-9]", &result.config.vsz, tmp) == 1) { |
570 | xasprintf(&result.config.fmt, "%s%sVSZ >= %d", (result.config.fmt ? result.config.fmt : ""), | ||
571 | (result.config.options ? ", " : ""), result.config.vsz); | ||
572 | result.config.options |= VSZ; | ||
581 | break; | 573 | break; |
582 | } | 574 | } |
583 | usage4 (_("VSZ must be an integer!")); | 575 | usage4(_("VSZ must be an integer!")); |
584 | case 'P': /* PCPU */ | 576 | } |
577 | case 'P': { /* PCPU */ | ||
585 | /* TODO: -P 1.5.5 is accepted */ | 578 | /* TODO: -P 1.5.5 is accepted */ |
586 | if (sscanf (optarg, "%f%[^0-9.]", &pcpu, tmp) == 1) { | 579 | static char tmp[MAX_INPUT_BUFFER]; |
587 | xasprintf (&fmt, "%s%sPCPU >= %.2f", (fmt ? fmt : ""), (options ? ", " : ""), pcpu); | 580 | if (sscanf(optarg, "%f%[^0-9.]", &result.config.pcpu, tmp) == 1) { |
588 | options |= PCPU; | 581 | xasprintf(&result.config.fmt, "%s%sPCPU >= %.2f", (result.config.fmt ? result.config.fmt : ""), |
582 | (result.config.options ? ", " : ""), result.config.pcpu); | ||
583 | result.config.options |= PCPU; | ||
589 | break; | 584 | break; |
590 | } | 585 | } |
591 | usage4 (_("PCPU must be a float!")); | 586 | usage4(_("PCPU must be a float!")); |
587 | } | ||
592 | case 'm': | 588 | case 'm': |
593 | xasprintf (&metric_name, "%s", optarg); | 589 | xasprintf(&result.config.metric_name, "%s", optarg); |
594 | if ( strcmp(optarg, "PROCS") == 0) { | 590 | if (strcmp(optarg, "PROCS") == 0) { |
595 | metric = METRIC_PROCS; | 591 | result.config.metric = METRIC_PROCS; |
596 | break; | 592 | break; |
597 | } | 593 | } |
598 | else if ( strcmp(optarg, "VSZ") == 0) { | 594 | if (strcmp(optarg, "VSZ") == 0) { |
599 | metric = METRIC_VSZ; | 595 | result.config.metric = METRIC_VSZ; |
600 | break; | 596 | break; |
601 | } | 597 | } |
602 | else if ( strcmp(optarg, "RSS") == 0 ) { | 598 | if (strcmp(optarg, "RSS") == 0) { |
603 | metric = METRIC_RSS; | 599 | result.config.metric = METRIC_RSS; |
604 | break; | 600 | break; |
605 | } | 601 | } |
606 | else if ( strcmp(optarg, "CPU") == 0 ) { | 602 | if (strcmp(optarg, "CPU") == 0) { |
607 | metric = METRIC_CPU; | 603 | result.config.metric = METRIC_CPU; |
608 | break; | 604 | break; |
609 | } | 605 | } |
610 | else if ( strcmp(optarg, "ELAPSED") == 0) { | 606 | if (strcmp(optarg, "ELAPSED") == 0) { |
611 | metric = METRIC_ELAPSED; | 607 | result.config.metric = METRIC_ELAPSED; |
612 | break; | 608 | break; |
613 | } | 609 | } |
614 | 610 | ||
615 | usage4 (_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!")); | 611 | usage4(_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!")); |
616 | case 'k': /* linux kernel thread filter */ | 612 | case 'k': /* linux kernel thread filter */ |
617 | kthread_filter = 1; | 613 | result.config.kthread_filter = true; |
618 | break; | 614 | break; |
619 | case 'v': /* command */ | 615 | case 'v': /* command */ |
620 | verbose++; | 616 | verbose++; |
621 | break; | 617 | break; |
622 | case 'T': | 618 | case 'T': |
623 | usepid = 1; | 619 | result.config.usepid = true; |
624 | break; | 620 | break; |
625 | case CHAR_MAX+2: | 621 | case CHAR_MAX + 2: |
626 | input_filename = optarg; | 622 | result.config.input_filename = optarg; |
627 | break; | 623 | break; |
628 | } | 624 | } |
629 | } | 625 | } |
630 | 626 | ||
631 | c = optind; | 627 | int index = optind; |
632 | if ((! warning_range) && argv[c]) | 628 | if ((!result.config.warning_range) && argv[index]) { |
633 | warning_range = argv[c++]; | 629 | result.config.warning_range = argv[index++]; |
634 | if ((! critical_range) && argv[c]) | 630 | } |
635 | critical_range = argv[c++]; | 631 | if ((!result.config.critical_range) && argv[index]) { |
636 | if (statopts == NULL && argv[c]) { | 632 | result.config.critical_range = argv[index++]; |
637 | xasprintf (&statopts, "%s", argv[c++]); | 633 | } |
638 | xasprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); | 634 | if (result.config.statopts == NULL && argv[index]) { |
639 | options |= STAT; | 635 | xasprintf(&result.config.statopts, "%s", argv[index++]); |
636 | xasprintf(&result.config.fmt, _("%s%sSTATE = %s"), (result.config.fmt ? result.config.fmt : ""), | ||
637 | (result.config.options ? ", " : ""), result.config.statopts); | ||
638 | result.config.options |= STAT; | ||
640 | } | 639 | } |
641 | 640 | ||
642 | /* this will abort in case of invalid ranges */ | 641 | /* this will abort in case of invalid ranges */ |
643 | set_thresholds (&procs_thresholds, warning_range, critical_range); | 642 | set_thresholds(&result.config.procs_thresholds, result.config.warning_range, result.config.critical_range); |
644 | 643 | ||
645 | return validate_arguments (); | 644 | return validate_arguments(result); |
646 | } | 645 | } |
647 | 646 | ||
647 | check_procs_config_wrapper validate_arguments(check_procs_config_wrapper config_wrapper) { | ||
648 | if (config_wrapper.config.options == 0) { | ||
649 | config_wrapper.config.options = ALL; | ||
650 | } | ||
648 | 651 | ||
652 | if (config_wrapper.config.statopts == NULL) { | ||
653 | config_wrapper.config.statopts = strdup(""); | ||
654 | } | ||
649 | 655 | ||
650 | int | 656 | if (config_wrapper.config.prog == NULL) { |
651 | validate_arguments () | 657 | config_wrapper.config.prog = strdup(""); |
652 | { | 658 | } |
653 | if (options == 0) | ||
654 | options = ALL; | ||
655 | |||
656 | if (statopts==NULL) | ||
657 | statopts = strdup(""); | ||
658 | |||
659 | if (prog==NULL) | ||
660 | prog = strdup(""); | ||
661 | 659 | ||
662 | if (args==NULL) | 660 | if (config_wrapper.config.args == NULL) { |
663 | args = strdup(""); | 661 | config_wrapper.config.args = strdup(""); |
662 | } | ||
664 | 663 | ||
665 | if (fmt==NULL) | 664 | if (config_wrapper.config.fmt == NULL) { |
666 | fmt = strdup(""); | 665 | config_wrapper.config.fmt = strdup(""); |
666 | } | ||
667 | 667 | ||
668 | if (fails==NULL) | 668 | if (config_wrapper.config.fails == NULL) { |
669 | fails = strdup(""); | 669 | config_wrapper.config.fails = strdup(""); |
670 | } | ||
670 | 671 | ||
671 | return options; | 672 | // return options; |
673 | return config_wrapper; | ||
672 | } | 674 | } |
673 | 675 | ||
674 | |||
675 | /* convert the elapsed time to seconds */ | 676 | /* convert the elapsed time to seconds */ |
676 | int | 677 | int convert_to_seconds(char *etime, enum metric metric) { |
677 | convert_to_seconds(char *etime) { | 678 | int hyphcnt = 0; |
678 | 679 | int coloncnt = 0; | |
679 | char *ptr; | 680 | for (char *ptr = etime; *ptr != '\0'; ptr++) { |
680 | int total; | ||
681 | |||
682 | int hyphcnt; | ||
683 | int coloncnt; | ||
684 | int days; | ||
685 | int hours; | ||
686 | int minutes; | ||
687 | int seconds; | ||
688 | |||
689 | hyphcnt = 0; | ||
690 | coloncnt = 0; | ||
691 | days = 0; | ||
692 | hours = 0; | ||
693 | minutes = 0; | ||
694 | seconds = 0; | ||
695 | |||
696 | for (ptr = etime; *ptr != '\0'; ptr++) { | ||
697 | 681 | ||
698 | if (*ptr == '-') { | 682 | if (*ptr == '-') { |
699 | hyphcnt++; | 683 | hyphcnt++; |
@@ -705,9 +689,12 @@ convert_to_seconds(char *etime) { | |||
705 | } | 689 | } |
706 | } | 690 | } |
707 | 691 | ||
692 | int days = 0; | ||
693 | int hours = 0; | ||
694 | int minutes = 0; | ||
695 | int seconds = 0; | ||
708 | if (hyphcnt > 0) { | 696 | if (hyphcnt > 0) { |
709 | sscanf(etime, "%d-%d:%d:%d", | 697 | sscanf(etime, "%d-%d:%d:%d", &days, &hours, &minutes, &seconds); |
710 | &days, &hours, &minutes, &seconds); | ||
711 | /* linux 2.6.5/2.6.6 reporting some processes with infinite | 698 | /* linux 2.6.5/2.6.6 reporting some processes with infinite |
712 | * elapsed times for some reason */ | 699 | * elapsed times for some reason */ |
713 | if (days == 49710) { | 700 | if (days == 49710) { |
@@ -715,135 +702,125 @@ convert_to_seconds(char *etime) { | |||
715 | } | 702 | } |
716 | } else { | 703 | } else { |
717 | if (coloncnt == 2) { | 704 | if (coloncnt == 2) { |
718 | sscanf(etime, "%d:%d:%d", | 705 | sscanf(etime, "%d:%d:%d", &hours, &minutes, &seconds); |
719 | &hours, &minutes, &seconds); | ||
720 | } else if (coloncnt == 1) { | 706 | } else if (coloncnt == 1) { |
721 | sscanf(etime, "%d:%d", | 707 | sscanf(etime, "%d:%d", &minutes, &seconds); |
722 | &minutes, &seconds); | ||
723 | } | 708 | } |
724 | } | 709 | } |
725 | 710 | ||
726 | total = (days * 86400) + | 711 | int total = (days * 86400) + (hours * 3600) + (minutes * 60) + seconds; |
727 | (hours * 3600) + | ||
728 | (minutes * 60) + | ||
729 | seconds; | ||
730 | 712 | ||
731 | if (verbose >= 3 && metric == METRIC_ELAPSED) { | 713 | if (verbose >= 3 && metric == METRIC_ELAPSED) { |
732 | printf("seconds: %d\n", total); | 714 | printf("seconds: %d\n", total); |
733 | } | 715 | } |
734 | return total; | 716 | return total; |
735 | } | 717 | } |
736 | 718 | ||
719 | void print_help(void) { | ||
720 | print_revision(progname, NP_VERSION); | ||
737 | 721 | ||
738 | void | 722 | printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"); |
739 | print_help (void) | 723 | printf(COPYRIGHT, copyright, email); |
740 | { | ||
741 | print_revision (progname, NP_VERSION); | ||
742 | |||
743 | printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"); | ||
744 | printf (COPYRIGHT, copyright, email); | ||
745 | 724 | ||
746 | printf ("%s\n", _("Checks all processes and generates WARNING or CRITICAL states if the specified")); | 725 | printf("%s\n", _("Checks all processes and generates WARNING or CRITICAL states if the specified")); |
747 | printf ("%s\n", _("metric is outside the required threshold ranges. The metric defaults to number")); | 726 | printf("%s\n", _("metric is outside the required threshold ranges. The metric defaults to number")); |
748 | printf ("%s\n", _("of processes. Search filters can be applied to limit the processes to check.")); | 727 | printf("%s\n", _("of processes. Search filters can be applied to limit the processes to check.")); |
749 | 728 | ||
750 | printf ("\n\n"); | 729 | printf("\n\n"); |
751 | 730 | ||
752 | printf ("%s\n", _("The parent process, check_procs itself and any child process of check_procs (ps)")); | 731 | printf("%s\n", _("The parent process, check_procs itself and any child process of check_procs (ps)")); |
753 | printf ("%s\n", _("are excluded from any checks to prevent false positives.")); | 732 | printf("%s\n", _("are excluded from any checks to prevent false positives.")); |
754 | 733 | ||
755 | printf ("\n\n"); | 734 | printf("\n\n"); |
756 | 735 | ||
757 | print_usage (); | 736 | print_usage(); |
758 | 737 | ||
759 | printf (UT_HELP_VRSN); | 738 | printf(UT_HELP_VRSN); |
760 | printf (UT_EXTRA_OPTS); | 739 | printf(UT_EXTRA_OPTS); |
761 | printf (" %s\n", "-w, --warning=RANGE"); | 740 | printf(" %s\n", "-w, --warning=RANGE"); |
762 | printf (" %s\n", _("Generate warning state if metric is outside this range")); | 741 | printf(" %s\n", _("Generate warning state if metric is outside this range")); |
763 | printf (" %s\n", "-c, --critical=RANGE"); | 742 | printf(" %s\n", "-c, --critical=RANGE"); |
764 | printf (" %s\n", _("Generate critical state if metric is outside this range")); | 743 | printf(" %s\n", _("Generate critical state if metric is outside this range")); |
765 | printf (" %s\n", "-m, --metric=TYPE"); | 744 | printf(" %s\n", "-m, --metric=TYPE"); |
766 | printf (" %s\n", _("Check thresholds against metric. Valid types:")); | 745 | printf(" %s\n", _("Check thresholds against metric. Valid types:")); |
767 | printf (" %s\n", _("PROCS - number of processes (default)")); | 746 | printf(" %s\n", _("PROCS - number of processes (default)")); |
768 | printf (" %s\n", _("VSZ - virtual memory size")); | 747 | printf(" %s\n", _("VSZ - virtual memory size")); |
769 | printf (" %s\n", _("RSS - resident set memory size")); | 748 | printf(" %s\n", _("RSS - resident set memory size")); |
770 | printf (" %s\n", _("CPU - percentage CPU")); | 749 | printf(" %s\n", _("CPU - percentage CPU")); |
771 | /* only linux etime is support currently */ | 750 | /* only linux etime is support currently */ |
772 | #if defined( __linux__ ) | 751 | #if defined(__linux__) |
773 | printf (" %s\n", _("ELAPSED - time elapsed in seconds")); | 752 | printf(" %s\n", _("ELAPSED - time elapsed in seconds")); |
774 | #endif /* defined(__linux__) */ | 753 | #endif /* defined(__linux__) */ |
775 | printf (UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); | 754 | printf(UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); |
776 | 755 | ||
777 | printf (" %s\n", "-v, --verbose"); | 756 | printf(" %s\n", "-v, --verbose"); |
778 | printf (" %s\n", _("Extra information. Up to 3 verbosity levels")); | 757 | printf(" %s\n", _("Extra information. Up to 3 verbosity levels")); |
779 | 758 | ||
780 | printf (" %s\n", "-T, --traditional"); | 759 | printf(" %s\n", "-T, --traditional"); |
781 | printf (" %s\n", _("Filter own process the traditional way by PID instead of /proc/pid/exe")); | 760 | printf(" %s\n", _("Filter own process the traditional way by PID instead of /proc/pid/exe")); |
782 | 761 | ||
783 | printf ("\n"); | 762 | printf("\n"); |
784 | printf ("%s\n", "Filters:"); | 763 | printf("%s\n", "Filters:"); |
785 | printf (" %s\n", "-s, --state=STATUSFLAGS"); | 764 | printf(" %s\n", "-s, --state=STATUSFLAGS"); |
786 | printf (" %s\n", _("Only scan for processes that have, in the output of `ps`, one or")); | 765 | printf(" %s\n", _("Only scan for processes that have, in the output of `ps`, one or")); |
787 | printf (" %s\n", _("more of the status flags you specify (for example R, Z, S, RS,")); | 766 | printf(" %s\n", _("more of the status flags you specify (for example R, Z, S, RS,")); |
788 | printf (" %s\n", _("RSZDT, plus others based on the output of your 'ps' command).")); | 767 | printf(" %s\n", _("RSZDT, plus others based on the output of your 'ps' command).")); |
789 | printf (" %s\n", "-p, --ppid=PPID"); | 768 | printf(" %s\n", "-p, --ppid=PPID"); |
790 | printf (" %s\n", _("Only scan for children of the parent process ID indicated.")); | 769 | printf(" %s\n", _("Only scan for children of the parent process ID indicated.")); |
791 | printf (" %s\n", "-z, --vsz=VSZ"); | 770 | printf(" %s\n", "-z, --vsz=VSZ"); |
792 | printf (" %s\n", _("Only scan for processes with VSZ higher than indicated.")); | 771 | printf(" %s\n", _("Only scan for processes with VSZ higher than indicated.")); |
793 | printf (" %s\n", "-r, --rss=RSS"); | 772 | printf(" %s\n", "-r, --rss=RSS"); |
794 | printf (" %s\n", _("Only scan for processes with RSS higher than indicated.")); | 773 | printf(" %s\n", _("Only scan for processes with RSS higher than indicated.")); |
795 | printf (" %s\n", "-P, --pcpu=PCPU"); | 774 | printf(" %s\n", "-P, --pcpu=PCPU"); |
796 | printf (" %s\n", _("Only scan for processes with PCPU higher than indicated.")); | 775 | printf(" %s\n", _("Only scan for processes with PCPU higher than indicated.")); |
797 | printf (" %s\n", "-u, --user=USER"); | 776 | printf(" %s\n", "-u, --user=USER"); |
798 | printf (" %s\n", _("Only scan for processes with user name or ID indicated.")); | 777 | printf(" %s\n", _("Only scan for processes with user name or ID indicated.")); |
799 | printf (" %s\n", "-a, --argument-array=STRING"); | 778 | printf(" %s\n", "-a, --argument-array=STRING"); |
800 | printf (" %s\n", _("Only scan for processes with args that contain STRING.")); | 779 | printf(" %s\n", _("Only scan for processes with args that contain STRING.")); |
801 | printf (" %s\n", "--ereg-argument-array=STRING"); | 780 | printf(" %s\n", "--ereg-argument-array=STRING"); |
802 | printf (" %s\n", _("Only scan for processes with args that contain the regex STRING.")); | 781 | printf(" %s\n", _("Only scan for processes with args that contain the regex STRING.")); |
803 | printf (" %s\n", "-C, --command=COMMAND"); | 782 | printf(" %s\n", "-C, --command=COMMAND"); |
804 | printf (" %s\n", _("Only scan for exact matches of COMMAND (without path).")); | 783 | printf(" %s\n", _("Only scan for exact matches of COMMAND (without path).")); |
805 | printf (" %s\n", "-X, --exclude-process"); | 784 | printf(" %s\n", "-X, --exclude-process"); |
806 | printf (" %s\n", _("Exclude processes which match this comma separated list")); | 785 | printf(" %s\n", _("Exclude processes which match this comma separated list")); |
807 | printf (" %s\n", "-k, --no-kthreads"); | 786 | printf(" %s\n", "-k, --no-kthreads"); |
808 | printf (" %s\n", _("Only scan for non kernel threads (works on Linux only).")); | 787 | printf(" %s\n", _("Only scan for non kernel threads (works on Linux only).")); |
809 | 788 | ||
810 | printf(_("\n\ | 789 | printf(_("\n\ |
811 | RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\ | 790 | RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\ |
812 | specified 'max:min', a warning status will be generated if the\n\ | 791 | specified 'max:min', a warning status will be generated if the\n\ |
813 | count is inside the specified range\n\n")); | 792 | count is inside the specified range\n\n")); |
814 | 793 | ||
815 | printf(_("\ | 794 | printf(_("\ |
816 | This plugin checks the number of currently running processes and\n\ | 795 | This plugin checks the number of currently running processes and\n\ |
817 | generates WARNING or CRITICAL states if the process count is outside\n\ | 796 | generates WARNING or CRITICAL states if the process count is outside\n\ |
818 | the specified threshold ranges. The process count can be filtered by\n\ | 797 | the specified threshold ranges. The process count can be filtered by\n\ |
819 | process owner, parent process PID, current state (e.g., 'Z'), or may\n\ | 798 | process owner, parent process PID, current state (e.g., 'Z'), or may\n\ |
820 | be the total number of running processes\n\n")); | 799 | be the total number of running processes\n\n")); |
821 | 800 | ||
822 | printf ("%s\n", _("Examples:")); | 801 | printf("%s\n", _("Examples:")); |
823 | printf (" %s\n", "check_procs -w 2:2 -c 2:1024 -C portsentry"); | 802 | printf(" %s\n", "check_procs -w 2:2 -c 2:1024 -C portsentry"); |
824 | printf (" %s\n", _("Warning if not two processes with command name portsentry.")); | 803 | printf(" %s\n", _("Warning if not two processes with command name portsentry.")); |
825 | printf (" %s\n\n", _("Critical if < 2 or > 1024 processes")); | 804 | printf(" %s\n\n", _("Critical if < 2 or > 1024 processes")); |
826 | printf (" %s\n", "check_procs -c 1: -C sshd"); | 805 | printf(" %s\n", "check_procs -c 1: -C sshd"); |
827 | printf (" %s\n", _("Critical if not at least 1 process with command sshd")); | 806 | printf(" %s\n", _("Critical if not at least 1 process with command sshd")); |
828 | printf (" %s\n", "check_procs -w 1024 -c 1: -C sshd"); | 807 | printf(" %s\n", "check_procs -w 1024 -c 1: -C sshd"); |
829 | printf (" %s\n", _("Warning if > 1024 processes with command name sshd.")); | 808 | printf(" %s\n", _("Warning if > 1024 processes with command name sshd.")); |
830 | printf (" %s\n\n", _("Critical if < 1 processes with command name sshd.")); | 809 | printf(" %s\n\n", _("Critical if < 1 processes with command name sshd.")); |
831 | printf (" %s\n", "check_procs -w 10 -a '/usr/local/bin/perl' -u root"); | 810 | printf(" %s\n", "check_procs -w 10 -a '/usr/local/bin/perl' -u root"); |
832 | printf (" %s\n", _("Warning alert if > 10 processes with command arguments containing")); | 811 | printf(" %s\n", _("Warning alert if > 10 processes with command arguments containing")); |
833 | printf (" %s\n\n", _("'/usr/local/bin/perl' and owned by root")); | 812 | printf(" %s\n\n", _("'/usr/local/bin/perl' and owned by root")); |
834 | printf (" %s\n", "check_procs -w 50000 -c 100000 --metric=VSZ"); | 813 | printf(" %s\n", "check_procs -w 50000 -c 100000 --metric=VSZ"); |
835 | printf (" %s\n\n", _("Alert if VSZ of any processes over 50K or 100K")); | 814 | printf(" %s\n\n", _("Alert if VSZ of any processes over 50K or 100K")); |
836 | printf (" %s\n", "check_procs -w 10 -c 20 --metric=CPU"); | 815 | printf(" %s\n", "check_procs -w 10 -c 20 --metric=CPU"); |
837 | printf (" %s\n", _("Alert if CPU of any processes over 10\% or 20\%")); | 816 | printf(" %s\n", _("Alert if CPU of any processes over 10%% or 20%%")); |
838 | 817 | ||
839 | printf (UT_SUPPORT); | 818 | printf(UT_SUPPORT); |
840 | } | 819 | } |
841 | 820 | ||
842 | void | 821 | void print_usage(void) { |
843 | print_usage (void) | 822 | printf("%s\n", _("Usage:")); |
844 | { | 823 | printf("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname); |
845 | printf ("%s\n", _("Usage:")); | 824 | printf(" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n"); |
846 | printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname); | 825 | printf(" [-C command] [-X process_to_exclude] [-k] [-t timeout] [-v]\n"); |
847 | printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n"); | ||
848 | printf (" [-C command] [-X process_to_exclude] [-k] [-t timeout] [-v]\n"); | ||
849 | } | 826 | } |