Module: monitoring-plugins
 Branch: master
 Commit: 43ce70bcdbebb0b699bf936ac1763c423cd7f069
 Author: Valentin Vidic <valentin.vi...@carnet.hr>
   Date: Mon Jan 16 10:43:15 2017 +0100
    URL: 
https://www.monitoring-plugins.org/repositories/monitoring-plugins/commit/?id=43ce70b

check_apt: Add -l/--list option to print packages

---

 plugins/check_apt.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 65 insertions(+), 7 deletions(-)

diff --git a/plugins/check_apt.c b/plugins/check_apt.c
index c90b3df..b69680c 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 */
@@ -87,7 +92,8 @@ 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,7 +113,7 @@ 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);
@@ -130,6 +136,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,6 +164,7 @@ 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'},
@@ -155,7 +174,7 @@ int process_arguments (int argc, char **argv) {
        };
 
        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:o", 
longopts, NULL);
 
                if(c == -1 || c == EOF || c == 1) break;
 
@@ -196,6 +215,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;
@@ -222,7 +244,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 +300,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 +329,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 +398,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 +505,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"));
@@ -490,5 +548,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]\n", progname);
 }

Reply via email to