diff options
-rw-r--r-- | plugins/check_apt.c | 119 |
1 files changed, 99 insertions, 20 deletions
diff --git a/plugins/check_apt.c b/plugins/check_apt.c index 8d020f50..867fe41e 100644 --- a/plugins/check_apt.c +++ b/plugins/check_apt.c | |||
@@ -33,15 +33,20 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; | |||
33 | 33 | ||
34 | #define APTGET_UPGRADE "/usr/bin/apt-get -o 'Debug::NoLocking=true' -s -qq upgrade" | 34 | #define APTGET_UPGRADE "/usr/bin/apt-get -o 'Debug::NoLocking=true' -s -qq upgrade" |
35 | #define APTGET_DISTUPGRADE "/usr/bin/apt-get -o 'Debug::NoLocking=true' -s -qq dist-upgrade" | 35 | #define APTGET_DISTUPGRADE "/usr/bin/apt-get -o 'Debug::NoLocking=true' -s -qq dist-upgrade" |
36 | #define APTGET_UPDATE "/usr/bin/apt-get update" | 36 | #define APTGET_UPDATE "/usr/bin/apt-get -q update" |
37 | 37 | ||
38 | int process_arguments(int, char **); | 38 | int process_arguments(int, char **); |
39 | void print_help(void); | 39 | void print_help(void); |
40 | void print_usage(void); | 40 | void print_usage(void); |
41 | 41 | ||
42 | int run_update(void); | ||
42 | int run_upgrade(int *pkgcount); | 43 | int run_upgrade(int *pkgcount); |
43 | 44 | ||
44 | static int verbose = 0; | 45 | static int verbose = 0; |
46 | static int do_update = 0; | ||
47 | static int dist_upgrade = 0; | ||
48 | static int stderr_warning = 0; | ||
49 | static int exec_warning = 0; | ||
45 | 50 | ||
46 | int main (int argc, char **argv) { | 51 | int main (int argc, char **argv) { |
47 | int result=STATE_UNKNOWN, packages_available=0; | 52 | int result=STATE_UNKNOWN, packages_available=0; |
@@ -57,17 +62,31 @@ int main (int argc, char **argv) { | |||
57 | /* handle timeouts gracefully... */ | 62 | /* handle timeouts gracefully... */ |
58 | alarm (timeout_interval); | 63 | alarm (timeout_interval); |
59 | 64 | ||
65 | /* if they want to run apt-get update first... */ | ||
66 | if(do_update) result = run_update(); | ||
67 | |||
60 | /* apt-get upgrade */ | 68 | /* apt-get upgrade */ |
61 | result = run_upgrade(&packages_available); | 69 | result = max_state(result, run_upgrade(&packages_available)); |
70 | |||
71 | if(stderr_warning){ | ||
72 | fprintf(stderr, "warning, output detected on stderr. "); | ||
73 | fprintf(stderr, "re-run with -v for more information.\n"); | ||
74 | } | ||
62 | 75 | ||
63 | if(packages_available > 0){ | 76 | if(packages_available > 0){ |
64 | result = STATE_WARNING; | 77 | result = max_state(result, STATE_WARNING); |
65 | printf("APT WARNING: "); | ||
66 | } else { | 78 | } else { |
67 | result = STATE_OK; | 79 | result = max_state(result, STATE_OK); |
68 | printf("APT OK: "); | ||
69 | } | 80 | } |
70 | printf("%d packages available for upgrade\n", packages_available); | 81 | |
82 | printf("APT %s: %d packages available for %s.%s%s%s\n", | ||
83 | state_text(result), | ||
84 | packages_available, | ||
85 | (dist_upgrade)?"dist-upgrade":"upgrade", | ||
86 | (stderr_warning)?" (warnings detected)":"", | ||
87 | (stderr_warning && exec_warning)?",":"", | ||
88 | (exec_warning)?" (errors detected)":"" | ||
89 | ); | ||
71 | 90 | ||
72 | return result; | 91 | return result; |
73 | } | 92 | } |
@@ -81,11 +100,13 @@ int process_arguments (int argc, char **argv) { | |||
81 | {"help", no_argument, 0, 'h'}, | 100 | {"help", no_argument, 0, 'h'}, |
82 | {"verbose", no_argument, 0, 'v'}, | 101 | {"verbose", no_argument, 0, 'v'}, |
83 | {"timeout", required_argument, 0, 't'}, | 102 | {"timeout", required_argument, 0, 't'}, |
103 | {"update", no_argument, 0, 'u'}, | ||
104 | {"dist-upgrade", no_argument, 0, 'd'}, | ||
84 | {0, 0, 0, 0} | 105 | {0, 0, 0, 0} |
85 | }; | 106 | }; |
86 | 107 | ||
87 | while(1) { | 108 | while(1) { |
88 | c = getopt_long(argc, argv, "hVvt", longopts, NULL); | 109 | c = getopt_long(argc, argv, "hVvt:ud", longopts, NULL); |
89 | 110 | ||
90 | if(c == -1 || c == EOF || c == 1) break; | 111 | if(c == -1 || c == EOF || c == 1) break; |
91 | 112 | ||
@@ -102,6 +123,12 @@ int process_arguments (int argc, char **argv) { | |||
102 | case 't': | 123 | case 't': |
103 | timeout_interval=atoi(optarg); | 124 | timeout_interval=atoi(optarg); |
104 | break; | 125 | break; |
126 | case 'd': | ||
127 | dist_upgrade=1; | ||
128 | break; | ||
129 | case 'u': | ||
130 | do_update=1; | ||
131 | break; | ||
105 | default: | 132 | default: |
106 | /* print short usage statement if args not parsable */ | 133 | /* print short usage statement if args not parsable */ |
107 | usage_va(_("Unknown argument - %s"), optarg); | 134 | usage_va(_("Unknown argument - %s"), optarg); |
@@ -123,15 +150,21 @@ found in Debian GNU/Linux\n\ | |||
123 | \n\n")); | 150 | \n\n")); |
124 | print_usage(); | 151 | print_usage(); |
125 | printf(_(UT_HELP_VRSN)); | 152 | printf(_(UT_HELP_VRSN)); |
126 | printf(_("\ | 153 | printf(_(UT_TIMEOUT), timeout_interval); |
127 | -t, --timeout=INTEGER\n\ | 154 | printf(_("\n\ |
128 | Seconds to wait for plugin execution to complete\n\ | 155 | -d, --dist-upgrade\n\ |
129 | ")); | 156 | Perform a dist-upgrade instead of normal upgrade.\n\n\ |
157 | The following options require root privileges and should be used with care: \ | ||
158 | \n\n")); | ||
159 | printf(_("\ | ||
160 | -u, --update\n\ | ||
161 | First perform an 'apt-get update' (note: you may also need to use -t)\ | ||
162 | \n\n")); | ||
130 | } | 163 | } |
131 | 164 | ||
132 | /* simple usage heading */ | 165 | /* simple usage heading */ |
133 | void print_usage(void){ | 166 | void print_usage(void){ |
134 | printf ("Usage: %s [-u] [-t timeout]\n", progname); | 167 | printf ("Usage: %s [-du] [-t timeout]\n", progname); |
135 | } | 168 | } |
136 | 169 | ||
137 | /* run an apt-get upgrade */ | 170 | /* run an apt-get upgrade */ |
@@ -140,15 +173,26 @@ int run_upgrade(int *pkgcount){ | |||
140 | struct output chld_out, chld_err; | 173 | struct output chld_out, chld_err; |
141 | 174 | ||
142 | /* run the upgrade */ | 175 | /* run the upgrade */ |
143 | if((result = np_runcmd(APTGET_UPGRADE, &chld_out, &chld_err, 0)) != 0) | 176 | if(dist_upgrade==0){ |
144 | result = STATE_WARNING; | 177 | result = np_runcmd(APTGET_UPGRADE, &chld_out, &chld_err, 0); |
178 | } else { | ||
179 | result = np_runcmd(APTGET_DISTUPGRADE, &chld_out, &chld_err, 0); | ||
180 | } | ||
181 | /* apt-get only changes exit status if there is an internal error */ | ||
182 | if(result != 0){ | ||
183 | exec_warning=1; | ||
184 | result = STATE_UNKNOWN; | ||
185 | fprintf(stderr, "'%s' exited with non-zero status.\n%s\n", | ||
186 | APTGET_UPGRADE, | ||
187 | "Run again with -v for more info."); | ||
188 | } | ||
145 | 189 | ||
146 | /* parse the output, which should only consist of lines like | 190 | /* parse the output, which should only consist of lines like |
147 | * | 191 | * |
148 | * Inst package .... | 192 | * Inst package .... |
149 | * Conf package .... | 193 | * Conf package .... |
150 | * | 194 | * |
151 | * so we'll filter based on "Inst" | 195 | * so we'll filter based on "Inst". If we ever want to do |
152 | */ | 196 | */ |
153 | for(i = 0; i < chld_out.lines; i++) { | 197 | for(i = 0; i < chld_out.lines; i++) { |
154 | if(strncmp(chld_out.line[i], "Inst", 4)==0){ | 198 | if(strncmp(chld_out.line[i], "Inst", 4)==0){ |
@@ -162,12 +206,47 @@ int run_upgrade(int *pkgcount){ | |||
162 | 206 | ||
163 | /* If we get anything on stderr, at least set warning */ | 207 | /* If we get anything on stderr, at least set warning */ |
164 | if(chld_err.buflen){ | 208 | if(chld_err.buflen){ |
165 | fprintf(stderr, "warning, output detected on stderr\n"); | 209 | stderr_warning=1; |
166 | for(i = 0; i < chld_err.lines; i++) { | 210 | result = max_state(result, STATE_WARNING); |
167 | printf("got this: %s\n", chld_err.line[i]); | 211 | if(verbose){ |
168 | result = max_state (result, STATE_WARNING); | 212 | for(i = 0; i < chld_err.lines; i++) { |
213 | printf("%s\n", chld_err.line[i]); | ||
214 | } | ||
215 | } | ||
216 | } | ||
217 | return result; | ||
218 | } | ||
219 | |||
220 | /* run an apt-get update (needs root) */ | ||
221 | int run_update(void){ | ||
222 | int i=0, result=STATE_UNKNOWN; | ||
223 | struct output chld_out, chld_err; | ||
224 | |||
225 | /* run the upgrade */ | ||
226 | result = np_runcmd(APTGET_UPDATE, &chld_out, &chld_err, 0); | ||
227 | /* apt-get only changes exit status if there is an internal error */ | ||
228 | if(result != 0){ | ||
229 | exec_warning=1; | ||
230 | result = STATE_UNKNOWN; | ||
231 | fprintf(stderr, "'%s' exited with non-zero status.\n", | ||
232 | APTGET_UPDATE); | ||
233 | } | ||
234 | |||
235 | if(verbose){ | ||
236 | for(i = 0; i < chld_out.lines; i++) { | ||
237 | printf("%s\n", chld_out.line[i]); | ||
169 | } | 238 | } |
170 | } | 239 | } |
171 | 240 | ||
241 | /* If we get anything on stderr, at least set warning */ | ||
242 | if(chld_err.buflen){ | ||
243 | stderr_warning=1; | ||
244 | result = max_state(result, STATE_WARNING); | ||
245 | if(verbose){ | ||
246 | for(i = 0; i < chld_err.lines; i++) { | ||
247 | printf("%s\n", chld_err.line[i]); | ||
248 | } | ||
249 | } | ||
250 | } | ||
172 | return result; | 251 | return result; |
173 | } | 252 | } |