diff options
Diffstat (limited to 'plugins/check_apt.c')
-rw-r--r-- | plugins/check_apt.c | 56 |
1 files changed, 35 insertions, 21 deletions
diff --git a/plugins/check_apt.c b/plugins/check_apt.c index 7efa596..cf18661 100644 --- a/plugins/check_apt.c +++ b/plugins/check_apt.c | |||
@@ -41,6 +41,8 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; | |||
41 | /* some constants */ | 41 | /* some constants */ |
42 | typedef enum { UPGRADE, DIST_UPGRADE, NO_UPGRADE } upgrade_type; | 42 | typedef enum { UPGRADE, DIST_UPGRADE, NO_UPGRADE } upgrade_type; |
43 | 43 | ||
44 | /* Character for hidden input file option (for testing). */ | ||
45 | #define INPUT_FILE_OPT CHAR_MAX+1 | ||
44 | /* the default opts can be overridden via the cmdline */ | 46 | /* the default opts can be overridden via the cmdline */ |
45 | #define UPGRADE_DEFAULT_OPTS "-o 'Debug::NoLocking=true' -s -qq" | 47 | #define UPGRADE_DEFAULT_OPTS "-o 'Debug::NoLocking=true' -s -qq" |
46 | #define UPDATE_DEFAULT_OPTS "-q" | 48 | #define UPDATE_DEFAULT_OPTS "-q" |
@@ -49,8 +51,10 @@ typedef enum { UPGRADE, DIST_UPGRADE, NO_UPGRADE } upgrade_type; | |||
49 | #ifndef PATH_TO_APTGET | 51 | #ifndef PATH_TO_APTGET |
50 | # define PATH_TO_APTGET "/usr/bin/apt-get" | 52 | # define PATH_TO_APTGET "/usr/bin/apt-get" |
51 | #endif /* PATH_TO_APTGET */ | 53 | #endif /* PATH_TO_APTGET */ |
54 | /* String found at the beginning of the apt output lines we're interested in */ | ||
55 | #define PKGINST_PREFIX "Inst " | ||
52 | /* the RE that catches security updates */ | 56 | /* the RE that catches security updates */ |
53 | #define SECURITY_RE "^[^\\(]*\\([^ ]* (Debian-Security:|Ubuntu:[^/]*/[^-]*-security)" | 57 | #define SECURITY_RE "^[^\\(]*\\(.* (Debian-Security:|Ubuntu:[^/]*/[^-]*-security)" |
54 | 58 | ||
55 | /* some standard functions */ | 59 | /* some standard functions */ |
56 | int process_arguments(int, char **); | 60 | int process_arguments(int, char **); |
@@ -75,6 +79,7 @@ static char *update_opts = NULL; /* options to override defaults for update */ | |||
75 | static char *do_include = NULL; /* regexp to only include certain packages */ | 79 | static char *do_include = NULL; /* regexp to only include certain packages */ |
76 | static char *do_exclude = NULL; /* regexp to only exclude certain packages */ | 80 | static char *do_exclude = NULL; /* regexp to only exclude certain packages */ |
77 | static char *do_critical = NULL; /* regexp specifying critical packages */ | 81 | static char *do_critical = NULL; /* regexp specifying critical packages */ |
82 | static char *input_filename = NULL; /* input filename for testing */ | ||
78 | 83 | ||
79 | /* other global variables */ | 84 | /* other global variables */ |
80 | static int stderr_warning = 0; /* if a cmd issued output on stderr */ | 85 | static int stderr_warning = 0; /* if a cmd issued output on stderr */ |
@@ -141,6 +146,7 @@ int process_arguments (int argc, char **argv) { | |||
141 | {"include", required_argument, 0, 'i'}, | 146 | {"include", required_argument, 0, 'i'}, |
142 | {"exclude", required_argument, 0, 'e'}, | 147 | {"exclude", required_argument, 0, 'e'}, |
143 | {"critical", required_argument, 0, 'c'}, | 148 | {"critical", required_argument, 0, 'c'}, |
149 | {"input-file", required_argument, 0, INPUT_FILE_OPT}, | ||
144 | {0, 0, 0, 0} | 150 | {0, 0, 0, 0} |
145 | }; | 151 | }; |
146 | 152 | ||
@@ -195,6 +201,9 @@ int process_arguments (int argc, char **argv) { | |||
195 | case 'c': | 201 | case 'c': |
196 | do_critical=add_to_regexp(do_critical, optarg); | 202 | do_critical=add_to_regexp(do_critical, optarg); |
197 | break; | 203 | break; |
204 | case INPUT_FILE_OPT: | ||
205 | input_filename = optarg; | ||
206 | break; | ||
198 | default: | 207 | default: |
199 | /* print short usage statement if args not parsable */ | 208 | /* print short usage statement if args not parsable */ |
200 | usage5(); | 209 | usage5(); |
@@ -211,22 +220,18 @@ int run_upgrade(int *pkgcount, int *secpkgcount){ | |||
211 | struct output chld_out, chld_err; | 220 | struct output chld_out, chld_err; |
212 | regex_t ireg, ereg, sreg; | 221 | regex_t ireg, ereg, sreg; |
213 | char *cmdline=NULL, rerrbuf[64]; | 222 | char *cmdline=NULL, rerrbuf[64]; |
214 | const char *include_ptr=NULL, *crit_ptr=NULL; | ||
215 | 223 | ||
216 | if(upgrade==NO_UPGRADE) return STATE_OK; | 224 | if(upgrade==NO_UPGRADE) return STATE_OK; |
217 | 225 | ||
218 | /* compile the regexps */ | 226 | /* compile the regexps */ |
219 | if(do_include!=NULL) include_ptr=do_include; | 227 | if (do_include != NULL) { |
220 | else include_ptr="^Inst"; | 228 | regres=regcomp(&ireg, do_include, REG_EXTENDED); |
221 | if(do_critical!=NULL) crit_ptr=do_critical; | 229 | if (regres!=0) { |
222 | else crit_ptr=SECURITY_RE; | 230 | regerror(regres, &ireg, rerrbuf, 64); |
223 | 231 | die(STATE_UNKNOWN, _("%s: Error compiling regexp: %s"), progname, rerrbuf); | |
224 | regres=regcomp(&ireg, include_ptr, REG_EXTENDED); | 232 | } |
225 | if(regres!=0) { | ||
226 | regerror(regres, &ireg, rerrbuf, 64); | ||
227 | die(STATE_UNKNOWN, _("%s: Error compiling regexp: %s"), progname, rerrbuf); | ||
228 | } | 233 | } |
229 | 234 | ||
230 | if(do_exclude!=NULL){ | 235 | if(do_exclude!=NULL){ |
231 | regres=regcomp(&ereg, do_exclude, REG_EXTENDED); | 236 | regres=regcomp(&ereg, do_exclude, REG_EXTENDED); |
232 | if(regres!=0) { | 237 | if(regres!=0) { |
@@ -235,6 +240,8 @@ int run_upgrade(int *pkgcount, int *secpkgcount){ | |||
235 | progname, rerrbuf); | 240 | progname, rerrbuf); |
236 | } | 241 | } |
237 | } | 242 | } |
243 | |||
244 | const char *crit_ptr = (do_critical != NULL) ? do_critical : SECURITY_RE; | ||
238 | regres=regcomp(&sreg, crit_ptr, REG_EXTENDED); | 245 | regres=regcomp(&sreg, crit_ptr, REG_EXTENDED); |
239 | if(regres!=0) { | 246 | if(regres!=0) { |
240 | regerror(regres, &ereg, rerrbuf, 64); | 247 | regerror(regres, &ereg, rerrbuf, 64); |
@@ -243,8 +250,14 @@ int run_upgrade(int *pkgcount, int *secpkgcount){ | |||
243 | } | 250 | } |
244 | 251 | ||
245 | cmdline=construct_cmdline(upgrade, upgrade_opts); | 252 | cmdline=construct_cmdline(upgrade, upgrade_opts); |
246 | /* run the upgrade */ | 253 | if (input_filename != NULL) { |
247 | result = np_runcmd(cmdline, &chld_out, &chld_err, 0); | 254 | /* read input from a file for testing */ |
255 | result = cmd_file_read(input_filename, &chld_out, 0); | ||
256 | } else { | ||
257 | /* run the upgrade */ | ||
258 | result = np_runcmd(cmdline, &chld_out, &chld_err, 0); | ||
259 | } | ||
260 | |||
248 | /* apt-get upgrade only changes exit status if there is an | 261 | /* apt-get upgrade only changes exit status if there is an |
249 | * internal error when run in dry-run mode. therefore we will | 262 | * internal error when run in dry-run mode. therefore we will |
250 | * treat such an error as UNKNOWN */ | 263 | * treat such an error as UNKNOWN */ |
@@ -269,7 +282,8 @@ int run_upgrade(int *pkgcount, int *secpkgcount){ | |||
269 | printf("%s\n", chld_out.line[i]); | 282 | printf("%s\n", chld_out.line[i]); |
270 | } | 283 | } |
271 | /* if it is a package we care about */ | 284 | /* if it is a package we care about */ |
272 | if(regexec(&ireg, chld_out.line[i], 0, NULL, 0)==0){ | 285 | if (strncmp(PKGINST_PREFIX, chld_out.line[i], strlen(PKGINST_PREFIX)) == 0 && |
286 | (do_include == NULL || regexec(&ireg, chld_out.line[i], 0, NULL, 0) == 0)) { | ||
273 | /* if we're not excluding, or it's not in the | 287 | /* if we're not excluding, or it's not in the |
274 | * list of stuff to exclude */ | 288 | * list of stuff to exclude */ |
275 | if(do_exclude==NULL || | 289 | if(do_exclude==NULL || |
@@ -289,7 +303,7 @@ int run_upgrade(int *pkgcount, int *secpkgcount){ | |||
289 | *secpkgcount=spc; | 303 | *secpkgcount=spc; |
290 | 304 | ||
291 | /* If we get anything on stderr, at least set warning */ | 305 | /* If we get anything on stderr, at least set warning */ |
292 | if(chld_err.buflen){ | 306 | if (input_filename == NULL && chld_err.buflen) { |
293 | stderr_warning=1; | 307 | stderr_warning=1; |
294 | result = max_state(result, STATE_WARNING); | 308 | result = max_state(result, STATE_WARNING); |
295 | if(verbose){ | 309 | if(verbose){ |
@@ -298,7 +312,7 @@ int run_upgrade(int *pkgcount, int *secpkgcount){ | |||
298 | } | 312 | } |
299 | } | 313 | } |
300 | } | 314 | } |
301 | regfree(&ireg); | 315 | if (do_include != NULL) regfree(&ireg); |
302 | regfree(&sreg); | 316 | regfree(&sreg); |
303 | if(do_exclude!=NULL) regfree(&ereg); | 317 | if(do_exclude!=NULL) regfree(&ereg); |
304 | free(cmdline); | 318 | free(cmdline); |
@@ -348,15 +362,15 @@ char* add_to_regexp(char *expr, const char *next){ | |||
348 | char *re=NULL; | 362 | char *re=NULL; |
349 | 363 | ||
350 | if(expr==NULL){ | 364 | if(expr==NULL){ |
351 | re=malloc(sizeof(char)*(strlen("^Inst () ")+strlen(next)+1)); | 365 | re=malloc(sizeof(char)*(strlen("()")+strlen(next)+1)); |
352 | if(!re) die(STATE_UNKNOWN, "malloc failed!\n"); | 366 | if(!re) die(STATE_UNKNOWN, "malloc failed!\n"); |
353 | sprintf(re, "^Inst (%s) ", next); | 367 | sprintf(re, "(%s)", next); |
354 | } else { | 368 | } else { |
355 | /* resize it, adding an extra char for the new '|' separator */ | 369 | /* resize it, adding an extra char for the new '|' separator */ |
356 | re=realloc(expr, sizeof(char)*strlen(expr)+1+strlen(next)+1); | 370 | re=realloc(expr, sizeof(char)*(strlen(expr)+1+strlen(next)+1)); |
357 | if(!re) die(STATE_UNKNOWN, "realloc failed!\n"); | 371 | if(!re) die(STATE_UNKNOWN, "realloc failed!\n"); |
358 | /* append it starting at ')' in the old re */ | 372 | /* append it starting at ')' in the old re */ |
359 | sprintf((char*)(re+strlen(re)-2), "|%s) ", next); | 373 | sprintf((char*)(re+strlen(re)-1), "|%s)", next); |
360 | } | 374 | } |
361 | 375 | ||
362 | return re; | 376 | return re; |