diff options
author | RincewindsHat <12514511+RincewindsHat@users.noreply.github.com> | 2021-12-02 16:42:05 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-02 16:42:05 +0100 |
commit | 911e44045d7291f5ede22739fd176ef55dd3de4a (patch) | |
tree | cf36b95a4a964b03d6ecf75770ced2cb3a2ac3a9 /plugins/check_apt.c | |
parent | 8294af907bd8482a86df749f562b7ec09e3faeed (diff) | |
parent | ed7cdf82a42f16532801ea4f118870ce9a130fcf (diff) | |
download | monitoring-plugins-911e44045d7291f5ede22739fd176ef55dd3de4a.tar.gz |
Merge branch 'master' into fix/shellcheck
Diffstat (limited to 'plugins/check_apt.c')
-rw-r--r-- | plugins/check_apt.c | 85 |
1 files changed, 76 insertions, 9 deletions
diff --git a/plugins/check_apt.c b/plugins/check_apt.c index c90b3df7..d7be5750 100644 --- a/plugins/check_apt.c +++ b/plugins/check_apt.c @@ -66,12 +66,17 @@ char* construct_cmdline(upgrade_type u, const char *opts); /* run an apt-get update */ int run_update(void); /* run an apt-get upgrade */ -int run_upgrade(int *pkgcount, int *secpkgcount); +int run_upgrade(int *pkgcount, int *secpkgcount, char ***pkglist, char ***secpkglist); /* add another clause to a regexp */ char* add_to_regexp(char *expr, const char *next); +/* extract package name from Inst line */ +char* pkg_name(char *line); +/* string comparison function for qsort */ +int cmpstringp(const void *p1, const void *p2); /* configuration variables */ static int verbose = 0; /* -v */ +static int list = 0; /* list packages available for upgrade */ static int do_update = 0; /* whether to call apt-get update */ static int only_critical = 0; /* whether to warn about non-critical updates */ static upgrade_type upgrade = UPGRADE; /* which type of upgrade to do */ @@ -81,13 +86,16 @@ static char *do_include = NULL; /* regexp to only include certain packages */ static char *do_exclude = NULL; /* regexp to only exclude certain packages */ static char *do_critical = NULL; /* regexp specifying critical packages */ static char *input_filename = NULL; /* input filename for testing */ +/* number of packages available for upgrade to return WARNING status */ +static int packages_warning = 1; /* other global variables */ static int stderr_warning = 0; /* if a cmd issued output on stderr */ static int exec_warning = 0; /* if a cmd exited non-zero */ int main (int argc, char **argv) { - int result=STATE_UNKNOWN, packages_available=0, sec_count=0; + int result=STATE_UNKNOWN, packages_available=0, sec_count=0, i=0; + char **packages_list=NULL, **secpackages_list=NULL; /* Parse extra opts if any */ argv=np_extra_opts(&argc, argv, progname); @@ -107,11 +115,11 @@ int main (int argc, char **argv) { if(do_update) result = run_update(); /* apt-get upgrade */ - result = max_state(result, run_upgrade(&packages_available, &sec_count)); + result = max_state(result, run_upgrade(&packages_available, &sec_count, &packages_list, &secpackages_list)); if(sec_count > 0){ result = max_state(result, STATE_CRITICAL); - } else if(packages_available > 0 && only_critical == 0){ + } else if(packages_available >= packages_warning && only_critical == 0){ result = max_state(result, STATE_WARNING); } else if(result > STATE_UNKNOWN){ result = STATE_UNKNOWN; @@ -130,6 +138,18 @@ int main (int argc, char **argv) { sec_count ); + if(list) { + qsort(secpackages_list, sec_count, sizeof(char*), cmpstringp); + qsort(packages_list, packages_available-sec_count, sizeof(char*), cmpstringp); + + for(i = 0; i < sec_count; i++) + printf("%s (security)\n", secpackages_list[i]); + if (only_critical == 0) { + for(i = 0; i < packages_available - sec_count; i++) + printf("%s\n", packages_list[i]); + } + } + return result; } @@ -146,16 +166,18 @@ int process_arguments (int argc, char **argv) { {"upgrade", optional_argument, 0, 'U'}, {"no-upgrade", no_argument, 0, 'n'}, {"dist-upgrade", optional_argument, 0, 'd'}, + {"list", no_argument, 0, 'l'}, {"include", required_argument, 0, 'i'}, {"exclude", required_argument, 0, 'e'}, {"critical", required_argument, 0, 'c'}, {"only-critical", no_argument, 0, 'o'}, {"input-file", required_argument, 0, INPUT_FILE_OPT}, + {"packages-warning", required_argument, 0, 'w'}, {0, 0, 0, 0} }; while(1) { - c = getopt_long(argc, argv, "hVvt:u::U::d::ni:e:c:o", longopts, NULL); + c = getopt_long(argc, argv, "hVvt:u::U::d::nli:e:c:ow:", longopts, NULL); if(c == -1 || c == EOF || c == 1) break; @@ -196,6 +218,9 @@ int process_arguments (int argc, char **argv) { if(update_opts==NULL) die(STATE_UNKNOWN, "strdup failed"); } break; + case 'l': + list=1; + break; case 'i': do_include=add_to_regexp(do_include, optarg); break; @@ -211,6 +236,9 @@ int process_arguments (int argc, char **argv) { case INPUT_FILE_OPT: input_filename = optarg; break; + case 'w': + packages_warning = atoi(optarg); + break; default: /* print short usage statement if args not parsable */ usage5(); @@ -222,7 +250,7 @@ int process_arguments (int argc, char **argv) { /* run an apt-get upgrade */ -int run_upgrade(int *pkgcount, int *secpkgcount){ +int run_upgrade(int *pkgcount, int *secpkgcount, char ***pkglist, char ***secpkglist){ int i=0, result=STATE_UNKNOWN, regres=0, pc=0, spc=0; struct output chld_out, chld_err; regex_t ireg, ereg, sreg; @@ -278,6 +306,11 @@ int run_upgrade(int *pkgcount, int *secpkgcount){ cmdline); } + *pkglist=malloc(sizeof(char *) * chld_out.lines); + if(!pkglist) die(STATE_UNKNOWN, "malloc failed!\n"); + *secpkglist=malloc(sizeof(char *) * chld_out.lines); + if(!secpkglist) die(STATE_UNKNOWN, "malloc failed!\n"); + /* parse the output, which should only consist of lines like * * Inst package .... @@ -302,6 +335,9 @@ int run_upgrade(int *pkgcount, int *secpkgcount){ if(regexec(&sreg, chld_out.line[i], 0, NULL, 0)==0){ spc++; if(verbose) printf("*"); + (*secpkglist)[spc-1] = pkg_name(chld_out.line[i]); + } else { + (*pkglist)[pc-spc-1] = pkg_name(chld_out.line[i]); } if(verbose){ printf("*%s\n", chld_out.line[i]); @@ -368,6 +404,31 @@ int run_update(void){ return result; } +char* pkg_name(char *line){ + char *start=NULL, *space=NULL, *pkg=NULL; + int len=0; + + start = line + strlen(PKGINST_PREFIX); + len = strlen(start); + + space = index(start, ' '); + if(space!=NULL){ + len = space - start; + } + + pkg=malloc(sizeof(char)*(len+1)); + if(!pkg) die(STATE_UNKNOWN, "malloc failed!\n"); + + strncpy(pkg, start, len); + pkg[len]='\0'; + + return pkg; +} + +int cmpstringp(const void *p1, const void *p2){ + return strcmp(* (char * const *) p1, * (char * const *) p2); +} + char* add_to_regexp(char *expr, const char *next){ char *re=NULL; @@ -450,8 +511,11 @@ print_help (void) printf (" %s\n", "-d, --dist-upgrade=OPTS"); printf (" %s\n", _("Perform a dist-upgrade instead of normal upgrade. Like with -U OPTS")); printf (" %s\n", _("can be provided to override the default options.")); - printf (" %s\n", " -n, --no-upgrade"); + printf (" %s\n", "-n, --no-upgrade"); printf (" %s\n", _("Do not run the upgrade. Probably not useful (without -u at least).")); + printf (" %s\n", "-l, --list"); + printf (" %s\n", _("List packages available for upgrade. Packages are printed sorted by")); + printf (" %s\n", _("name with security packages listed first.")); printf (" %s\n", "-i, --include=REGEXP"); printf (" %s\n", _("Include only packages matching REGEXP. Can be specified multiple times")); printf (" %s\n", _("the values will be combined together. Any packages matching this list")); @@ -472,7 +536,10 @@ print_help (void) printf (" %s\n", "-o, --only-critical"); printf (" %s\n", _("Only warn about upgrades matching the critical list. The total number")); printf (" %s\n", _("of upgrades will be printed, but any non-critical upgrades will not cause")); - printf (" %s\n\n", _("the plugin to return WARNING status.")); + printf (" %s\n", _("the plugin to return WARNING status.")); + printf (" %s\n", "-w, --packages-warning"); + printf (" %s\n", _("Minumum number of packages available for upgrade to return WARNING status.")); + printf (" %s\n\n", _("Default is 1 package.")); printf ("%s\n\n", _("The following options require root privileges and should be used with care:")); printf (" %s\n", "-u, --update=OPTS"); @@ -490,5 +557,5 @@ void print_usage(void) { printf ("%s\n", _("Usage:")); - printf ("%s [[-d|-u|-U]opts] [-n] [-t timeout]\n", progname); + printf ("%s [[-d|-u|-U]opts] [-n] [-l] [-t timeout] [-w packages-warning]\n", progname); } |