summaryrefslogtreecommitdiffstats
path: root/plugins/check_apt.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_apt.c')
-rw-r--r--plugins/check_apt.c56
1 files changed, 35 insertions, 21 deletions
diff --git a/plugins/check_apt.c b/plugins/check_apt.c
index 7efa596b..cf186611 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 */
42typedef enum { UPGRADE, DIST_UPGRADE, NO_UPGRADE } upgrade_type; 42typedef 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 */
56int process_arguments(int, char **); 60int process_arguments(int, char **);
@@ -75,6 +79,7 @@ static char *update_opts = NULL; /* options to override defaults for update */
75static char *do_include = NULL; /* regexp to only include certain packages */ 79static char *do_include = NULL; /* regexp to only include certain packages */
76static char *do_exclude = NULL; /* regexp to only exclude certain packages */ 80static char *do_exclude = NULL; /* regexp to only exclude certain packages */
77static char *do_critical = NULL; /* regexp specifying critical packages */ 81static char *do_critical = NULL; /* regexp specifying critical packages */
82static char *input_filename = NULL; /* input filename for testing */
78 83
79/* other global variables */ 84/* other global variables */
80static int stderr_warning = 0; /* if a cmd issued output on stderr */ 85static 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;