Package: monitoring-plugins / 2.2-6

13_check_apt_list_packages Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
From 43ce70bcdbebb0b699bf936ac1763c423cd7f069 Mon Sep 17 00:00:00 2001
From: Valentin Vidic <Valentin.Vidic@CARNet.hr>
Date: Mon, 16 Jan 2017 10:43:15 +0100
Subject: [PATCH] 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);
 }