diff options
Diffstat (limited to 'plugins/check_apt.c')
| -rw-r--r-- | plugins/check_apt.c | 68 |
1 files changed, 42 insertions, 26 deletions
diff --git a/plugins/check_apt.c b/plugins/check_apt.c index 7efa596b..daeb7578 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 */ |
| @@ -107,11 +112,11 @@ int main (int argc, char **argv) { | |||
| 107 | result = max_state(result, STATE_CRITICAL); | 112 | result = max_state(result, STATE_CRITICAL); |
| 108 | } else if(packages_available > 0){ | 113 | } else if(packages_available > 0){ |
| 109 | result = max_state(result, STATE_WARNING); | 114 | result = max_state(result, STATE_WARNING); |
| 110 | } else { | 115 | } else if(result > STATE_UNKNOWN){ |
| 111 | result = max_state(result, STATE_OK); | 116 | result = STATE_UNKNOWN; |
| 112 | } | 117 | } |
| 113 | 118 | ||
| 114 | printf(_("APT %s: %d packages available for %s (%d critical updates). %s%s%s%s\n"), | 119 | printf(_("APT %s: %d packages available for %s (%d critical updates). %s%s%s%s|available_upgrades=%d;;;0 critical_updates=%d;;;0\n"), |
| 115 | state_text(result), | 120 | state_text(result), |
| 116 | packages_available, | 121 | packages_available, |
| 117 | (upgrade==DIST_UPGRADE)?"dist-upgrade":"upgrade", | 122 | (upgrade==DIST_UPGRADE)?"dist-upgrade":"upgrade", |
| @@ -119,7 +124,9 @@ int main (int argc, char **argv) { | |||
| 119 | (stderr_warning)?" warnings detected":"", | 124 | (stderr_warning)?" warnings detected":"", |
| 120 | (stderr_warning && exec_warning)?",":"", | 125 | (stderr_warning && exec_warning)?",":"", |
| 121 | (exec_warning)?" errors detected":"", | 126 | (exec_warning)?" errors detected":"", |
| 122 | (stderr_warning||exec_warning)?". run with -v for information.":"" | 127 | (stderr_warning||exec_warning)?". run with -v for information.":"", |
| 128 | packages_available, | ||
| 129 | sec_count | ||
| 123 | ); | 130 | ); |
| 124 | 131 | ||
| 125 | return result; | 132 | return result; |
| @@ -141,6 +148,7 @@ int process_arguments (int argc, char **argv) { | |||
| 141 | {"include", required_argument, 0, 'i'}, | 148 | {"include", required_argument, 0, 'i'}, |
| 142 | {"exclude", required_argument, 0, 'e'}, | 149 | {"exclude", required_argument, 0, 'e'}, |
| 143 | {"critical", required_argument, 0, 'c'}, | 150 | {"critical", required_argument, 0, 'c'}, |
| 151 | {"input-file", required_argument, 0, INPUT_FILE_OPT}, | ||
| 144 | {0, 0, 0, 0} | 152 | {0, 0, 0, 0} |
| 145 | }; | 153 | }; |
| 146 | 154 | ||
| @@ -195,6 +203,9 @@ int process_arguments (int argc, char **argv) { | |||
| 195 | case 'c': | 203 | case 'c': |
| 196 | do_critical=add_to_regexp(do_critical, optarg); | 204 | do_critical=add_to_regexp(do_critical, optarg); |
| 197 | break; | 205 | break; |
| 206 | case INPUT_FILE_OPT: | ||
| 207 | input_filename = optarg; | ||
| 208 | break; | ||
| 198 | default: | 209 | default: |
| 199 | /* print short usage statement if args not parsable */ | 210 | /* print short usage statement if args not parsable */ |
| 200 | usage5(); | 211 | usage5(); |
| @@ -211,22 +222,18 @@ int run_upgrade(int *pkgcount, int *secpkgcount){ | |||
| 211 | struct output chld_out, chld_err; | 222 | struct output chld_out, chld_err; |
| 212 | regex_t ireg, ereg, sreg; | 223 | regex_t ireg, ereg, sreg; |
| 213 | char *cmdline=NULL, rerrbuf[64]; | 224 | char *cmdline=NULL, rerrbuf[64]; |
| 214 | const char *include_ptr=NULL, *crit_ptr=NULL; | ||
| 215 | 225 | ||
| 216 | if(upgrade==NO_UPGRADE) return STATE_OK; | 226 | if(upgrade==NO_UPGRADE) return STATE_OK; |
| 217 | 227 | ||
| 218 | /* compile the regexps */ | 228 | /* compile the regexps */ |
| 219 | if(do_include!=NULL) include_ptr=do_include; | 229 | if (do_include != NULL) { |
| 220 | else include_ptr="^Inst"; | 230 | regres=regcomp(&ireg, do_include, REG_EXTENDED); |
| 221 | if(do_critical!=NULL) crit_ptr=do_critical; | 231 | if (regres!=0) { |
| 222 | else crit_ptr=SECURITY_RE; | 232 | regerror(regres, &ireg, rerrbuf, 64); |
| 223 | 233 | die(STATE_UNKNOWN, _("%s: Error compiling regexp: %s"), progname, rerrbuf); | |
| 224 | regres=regcomp(&ireg, include_ptr, REG_EXTENDED); | 234 | } |
| 225 | if(regres!=0) { | ||
| 226 | regerror(regres, &ireg, rerrbuf, 64); | ||
| 227 | die(STATE_UNKNOWN, _("%s: Error compiling regexp: %s"), progname, rerrbuf); | ||
| 228 | } | 235 | } |
| 229 | 236 | ||
| 230 | if(do_exclude!=NULL){ | 237 | if(do_exclude!=NULL){ |
| 231 | regres=regcomp(&ereg, do_exclude, REG_EXTENDED); | 238 | regres=regcomp(&ereg, do_exclude, REG_EXTENDED); |
| 232 | if(regres!=0) { | 239 | if(regres!=0) { |
| @@ -235,6 +242,8 @@ int run_upgrade(int *pkgcount, int *secpkgcount){ | |||
| 235 | progname, rerrbuf); | 242 | progname, rerrbuf); |
| 236 | } | 243 | } |
| 237 | } | 244 | } |
| 245 | |||
| 246 | const char *crit_ptr = (do_critical != NULL) ? do_critical : SECURITY_RE; | ||
| 238 | regres=regcomp(&sreg, crit_ptr, REG_EXTENDED); | 247 | regres=regcomp(&sreg, crit_ptr, REG_EXTENDED); |
| 239 | if(regres!=0) { | 248 | if(regres!=0) { |
| 240 | regerror(regres, &ereg, rerrbuf, 64); | 249 | regerror(regres, &ereg, rerrbuf, 64); |
| @@ -243,8 +252,14 @@ int run_upgrade(int *pkgcount, int *secpkgcount){ | |||
| 243 | } | 252 | } |
| 244 | 253 | ||
| 245 | cmdline=construct_cmdline(upgrade, upgrade_opts); | 254 | cmdline=construct_cmdline(upgrade, upgrade_opts); |
| 246 | /* run the upgrade */ | 255 | if (input_filename != NULL) { |
| 247 | result = np_runcmd(cmdline, &chld_out, &chld_err, 0); | 256 | /* read input from a file for testing */ |
| 257 | result = cmd_file_read(input_filename, &chld_out, 0); | ||
| 258 | } else { | ||
| 259 | /* run the upgrade */ | ||
| 260 | result = np_runcmd(cmdline, &chld_out, &chld_err, 0); | ||
| 261 | } | ||
| 262 | |||
| 248 | /* apt-get upgrade only changes exit status if there is an | 263 | /* apt-get upgrade only changes exit status if there is an |
| 249 | * internal error when run in dry-run mode. therefore we will | 264 | * internal error when run in dry-run mode. therefore we will |
| 250 | * treat such an error as UNKNOWN */ | 265 | * treat such an error as UNKNOWN */ |
| @@ -269,7 +284,8 @@ int run_upgrade(int *pkgcount, int *secpkgcount){ | |||
| 269 | printf("%s\n", chld_out.line[i]); | 284 | printf("%s\n", chld_out.line[i]); |
| 270 | } | 285 | } |
| 271 | /* if it is a package we care about */ | 286 | /* if it is a package we care about */ |
| 272 | if(regexec(&ireg, chld_out.line[i], 0, NULL, 0)==0){ | 287 | if (strncmp(PKGINST_PREFIX, chld_out.line[i], strlen(PKGINST_PREFIX)) == 0 && |
| 288 | (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 | 289 | /* if we're not excluding, or it's not in the |
| 274 | * list of stuff to exclude */ | 290 | * list of stuff to exclude */ |
| 275 | if(do_exclude==NULL || | 291 | if(do_exclude==NULL || |
| @@ -289,7 +305,7 @@ int run_upgrade(int *pkgcount, int *secpkgcount){ | |||
| 289 | *secpkgcount=spc; | 305 | *secpkgcount=spc; |
| 290 | 306 | ||
| 291 | /* If we get anything on stderr, at least set warning */ | 307 | /* If we get anything on stderr, at least set warning */ |
| 292 | if(chld_err.buflen){ | 308 | if (input_filename == NULL && chld_err.buflen) { |
| 293 | stderr_warning=1; | 309 | stderr_warning=1; |
| 294 | result = max_state(result, STATE_WARNING); | 310 | result = max_state(result, STATE_WARNING); |
| 295 | if(verbose){ | 311 | if(verbose){ |
| @@ -298,7 +314,7 @@ int run_upgrade(int *pkgcount, int *secpkgcount){ | |||
| 298 | } | 314 | } |
| 299 | } | 315 | } |
| 300 | } | 316 | } |
| 301 | regfree(&ireg); | 317 | if (do_include != NULL) regfree(&ireg); |
| 302 | regfree(&sreg); | 318 | regfree(&sreg); |
| 303 | if(do_exclude!=NULL) regfree(&ereg); | 319 | if(do_exclude!=NULL) regfree(&ereg); |
| 304 | free(cmdline); | 320 | free(cmdline); |
| @@ -348,15 +364,15 @@ char* add_to_regexp(char *expr, const char *next){ | |||
| 348 | char *re=NULL; | 364 | char *re=NULL; |
| 349 | 365 | ||
| 350 | if(expr==NULL){ | 366 | if(expr==NULL){ |
| 351 | re=malloc(sizeof(char)*(strlen("^Inst () ")+strlen(next)+1)); | 367 | re=malloc(sizeof(char)*(strlen("()")+strlen(next)+1)); |
| 352 | if(!re) die(STATE_UNKNOWN, "malloc failed!\n"); | 368 | if(!re) die(STATE_UNKNOWN, "malloc failed!\n"); |
| 353 | sprintf(re, "^Inst (%s) ", next); | 369 | sprintf(re, "(%s)", next); |
| 354 | } else { | 370 | } else { |
| 355 | /* resize it, adding an extra char for the new '|' separator */ | 371 | /* resize it, adding an extra char for the new '|' separator */ |
| 356 | re=realloc(expr, sizeof(char)*strlen(expr)+1+strlen(next)+1); | 372 | re=realloc(expr, sizeof(char)*(strlen(expr)+1+strlen(next)+1)); |
| 357 | if(!re) die(STATE_UNKNOWN, "realloc failed!\n"); | 373 | if(!re) die(STATE_UNKNOWN, "realloc failed!\n"); |
| 358 | /* append it starting at ')' in the old re */ | 374 | /* append it starting at ')' in the old re */ |
| 359 | sprintf((char*)(re+strlen(re)-2), "|%s) ", next); | 375 | sprintf((char*)(re+strlen(re)-1), "|%s)", next); |
| 360 | } | 376 | } |
| 361 | 377 | ||
| 362 | return re; | 378 | return re; |
| @@ -430,7 +446,7 @@ print_help (void) | |||
| 430 | printf (" %s\n", _("Do not run the upgrade. Probably not useful (without -u at least).")); | 446 | printf (" %s\n", _("Do not run the upgrade. Probably not useful (without -u at least).")); |
| 431 | printf (" %s\n", "-i, --include=REGEXP"); | 447 | printf (" %s\n", "-i, --include=REGEXP"); |
| 432 | printf (" %s\n", _("Include only packages matching REGEXP. Can be specified multiple times")); | 448 | printf (" %s\n", _("Include only packages matching REGEXP. Can be specified multiple times")); |
| 433 | printf (" %s\n", _("the values will be combined together. Any patches matching this list")); | 449 | printf (" %s\n", _("the values will be combined together. Any packages matching this list")); |
| 434 | printf (" %s\n", _("cause the plugin to return WARNING status. Others will be ignored.")); | 450 | printf (" %s\n", _("cause the plugin to return WARNING status. Others will be ignored.")); |
| 435 | printf (" %s\n", _("Default is to include all packages.")); | 451 | printf (" %s\n", _("Default is to include all packages.")); |
| 436 | printf (" %s\n", "-e, --exclude=REGEXP"); | 452 | printf (" %s\n", "-e, --exclude=REGEXP"); |
