diff options
Diffstat (limited to 'plugins/check_apt.c')
-rw-r--r-- | plugins/check_apt.c | 824 |
1 files changed, 483 insertions, 341 deletions
diff --git a/plugins/check_apt.c b/plugins/check_apt.c index 5c0f6e28..9ed5b6cf 100644 --- a/plugins/check_apt.c +++ b/plugins/check_apt.c | |||
@@ -1,188 +1,250 @@ | |||
1 | /***************************************************************************** | 1 | /***************************************************************************** |
2 | * | 2 | * |
3 | * Monitoring check_apt plugin | 3 | * Monitoring check_apt plugin |
4 | * | 4 | * |
5 | * License: GPL | 5 | * License: GPL |
6 | * Copyright (c) 2006-2008 Monitoring Plugins Development Team | 6 | * Copyright (c) 2006-2024 Monitoring Plugins Development Team |
7 | * | 7 | * |
8 | * Original author: Sean Finney | 8 | * Original author: Sean Finney |
9 | * | 9 | * |
10 | * Description: | 10 | * Description: |
11 | * | 11 | * |
12 | * This file contains the check_apt plugin | 12 | * This file contains the check_apt plugin |
13 | * | 13 | * |
14 | * Check for available updates in apt package management systems | 14 | * Check for available updates in apt package management systems |
15 | * | 15 | * |
16 | * | 16 | * |
17 | * This program is free software: you can redistribute it and/or modify | 17 | * This program is free software: you can redistribute it and/or modify |
18 | * it under the terms of the GNU General Public License as published by | 18 | * it under the terms of the GNU General Public License as published by |
19 | * the Free Software Foundation, either version 3 of the License, or | 19 | * the Free Software Foundation, either version 3 of the License, or |
20 | * (at your option) any later version. | 20 | * (at your option) any later version. |
21 | * | 21 | * |
22 | * This program is distributed in the hope that it will be useful, | 22 | * This program is distributed in the hope that it will be useful, |
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
25 | * GNU General Public License for more details. | 25 | * GNU General Public License for more details. |
26 | * | 26 | * |
27 | * You should have received a copy of the GNU General Public License | 27 | * You should have received a copy of the GNU General Public License |
28 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 28 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
29 | * | 29 | * |
30 | *****************************************************************************/ | 30 | *****************************************************************************/ |
31 | 31 | ||
32 | #include "perfdata.h" | ||
32 | const char *progname = "check_apt"; | 33 | const char *progname = "check_apt"; |
33 | const char *copyright = "2006-2008"; | 34 | const char *copyright = "2006-2024"; |
34 | const char *email = "devel@monitoring-plugins.org"; | 35 | const char *email = "devel@monitoring-plugins.org"; |
35 | 36 | ||
37 | #include "states.h" | ||
38 | #include "output.h" | ||
36 | #include "common.h" | 39 | #include "common.h" |
37 | #include "runcmd.h" | 40 | #include "runcmd.h" |
38 | #include "utils.h" | 41 | #include "utils.h" |
39 | #include "regex.h" | 42 | #include "regex.h" |
43 | #include "check_apt.d/config.h" | ||
40 | 44 | ||
41 | /* some constants */ | ||
42 | typedef enum { UPGRADE, DIST_UPGRADE, NO_UPGRADE } upgrade_type; | ||
43 | |||
44 | /* Character for hidden input file option (for testing). */ | ||
45 | #define INPUT_FILE_OPT CHAR_MAX+1 | ||
46 | /* the default opts can be overridden via the cmdline */ | 45 | /* the default opts can be overridden via the cmdline */ |
47 | #define UPGRADE_DEFAULT_OPTS "-o 'Debug::NoLocking=true' -s -qq" | 46 | const char *UPGRADE_DEFAULT_OPTS = "-o 'Debug::NoLocking=true' -s -qq"; |
48 | #define UPDATE_DEFAULT_OPTS "-q" | 47 | const char *UPDATE_DEFAULT_OPTS = "-q"; |
48 | |||
49 | /* until i commit the configure.in patch which gets this, i'll define | 49 | /* until i commit the configure.in patch which gets this, i'll define |
50 | * it here as well */ | 50 | * it here as well */ |
51 | #ifndef PATH_TO_APTGET | 51 | #ifndef PATH_TO_APTGET |
52 | # define PATH_TO_APTGET "/usr/bin/apt-get" | 52 | # define PATH_TO_APTGET "/usr/bin/apt-get" |
53 | #endif /* PATH_TO_APTGET */ | 53 | #endif /* PATH_TO_APTGET */ |
54 | |||
54 | /* String found at the beginning of the apt output lines we're interested in */ | 55 | /* String found at the beginning of the apt output lines we're interested in */ |
55 | #define PKGINST_PREFIX "Inst " | 56 | const char *PKGINST_PREFIX = "Inst "; |
56 | /* the RE that catches security updates */ | 57 | /* the RE that catches security updates */ |
57 | #define SECURITY_RE "^[^\\(]*\\(.* (Debian-Security:|Ubuntu:[^/]*/[^-]*-security)" | 58 | const char *SECURITY_RE = "^[^\\(]*\\(.* (Debian-Security:|Ubuntu:[^/]*/[^-]*-security)"; |
58 | 59 | ||
59 | /* some standard functions */ | 60 | /* some standard functions */ |
60 | int process_arguments(int, char **); | 61 | typedef struct { |
61 | void print_help(void); | 62 | int errorcode; |
63 | check_apt_config config; | ||
64 | } check_apt_config_wrapper; | ||
65 | static check_apt_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); | ||
66 | static void print_help(void); | ||
62 | void print_usage(void); | 67 | void print_usage(void); |
63 | 68 | ||
64 | /* construct the appropriate apt-get cmdline */ | 69 | /* construct the appropriate apt-get cmdline */ |
65 | char* construct_cmdline(upgrade_type u, const char *opts); | 70 | static char *construct_cmdline(upgrade_type /*u*/, const char * /*opts*/); |
71 | |||
66 | /* run an apt-get update */ | 72 | /* run an apt-get update */ |
67 | int run_update(void); | 73 | typedef struct { |
74 | mp_subcheck sc; | ||
75 | bool stderr_warning; | ||
76 | bool exec_warning; | ||
77 | } run_update_result; | ||
78 | static run_update_result run_update(char *update_opts); | ||
79 | |||
80 | typedef struct { | ||
81 | int errorcode; | ||
82 | size_t package_count; | ||
83 | size_t security_package_count; | ||
84 | char **packages_list; | ||
85 | char **secpackages_list; | ||
86 | bool exec_warning; | ||
87 | } run_upgrade_result; | ||
88 | |||
68 | /* run an apt-get upgrade */ | 89 | /* run an apt-get upgrade */ |
69 | int run_upgrade(int *pkgcount, int *secpkgcount, char ***pkglist, char ***secpkglist); | 90 | run_upgrade_result run_upgrade(upgrade_type upgrade, const char *do_include, const char *do_exclude, |
91 | const char *do_critical, const char *upgrade_opts, | ||
92 | const char *input_filename); | ||
93 | |||
70 | /* add another clause to a regexp */ | 94 | /* add another clause to a regexp */ |
71 | char* add_to_regexp(char *expr, const char *next); | 95 | static char *add_to_regexp(char * /*expr*/, const char * /*next*/); |
72 | /* extract package name from Inst line */ | 96 | /* extract package name from Inst line */ |
73 | char* pkg_name(char *line); | 97 | static char *pkg_name(char * /*line*/); |
74 | /* string comparison function for qsort */ | 98 | /* string comparison function for qsort */ |
75 | int cmpstringp(const void *p1, const void *p2); | 99 | static int cmpstringp(const void * /*p1*/, const void * /*p2*/); |
76 | 100 | ||
77 | /* configuration variables */ | 101 | /* configuration variables */ |
78 | static int verbose = 0; /* -v */ | 102 | static int verbose = 0; /* -v */ |
79 | static bool list = false; /* list packages available for upgrade */ | ||
80 | static bool do_update = false; /* whether to call apt-get update */ | ||
81 | static bool only_critical = false; /* whether to warn about non-critical updates */ | ||
82 | static upgrade_type upgrade = UPGRADE; /* which type of upgrade to do */ | ||
83 | static char *upgrade_opts = NULL; /* options to override defaults for upgrade */ | ||
84 | static char *update_opts = NULL; /* options to override defaults for update */ | ||
85 | static char *do_include = NULL; /* regexp to only include certain packages */ | ||
86 | static char *do_exclude = NULL; /* regexp to only exclude certain packages */ | ||
87 | static char *do_critical = NULL; /* regexp specifying critical packages */ | ||
88 | static char *input_filename = NULL; /* input filename for testing */ | ||
89 | /* number of packages available for upgrade to return WARNING status */ | ||
90 | static int packages_warning = 1; | ||
91 | 103 | ||
92 | /* other global variables */ | 104 | /* other global variables */ |
93 | static int stderr_warning = 0; /* if a cmd issued output on stderr */ | 105 | static bool stderr_warning = false; /* if a cmd issued output on stderr */ |
94 | static int exec_warning = 0; /* if a cmd exited non-zero */ | 106 | static bool exec_warning = false; /* if a cmd exited non-zero */ |
95 | |||
96 | int main (int argc, char **argv) { | ||
97 | int result=STATE_UNKNOWN, packages_available=0, sec_count=0; | ||
98 | char **packages_list=NULL, **secpackages_list=NULL; | ||
99 | 107 | ||
108 | int main(int argc, char **argv) { | ||
100 | /* Parse extra opts if any */ | 109 | /* Parse extra opts if any */ |
101 | argv=np_extra_opts(&argc, argv, progname); | 110 | argv = np_extra_opts(&argc, argv, progname); |
102 | 111 | ||
103 | if (process_arguments(argc, argv) == ERROR) | 112 | check_apt_config_wrapper tmp_config = process_arguments(argc, argv); |
113 | |||
114 | if (tmp_config.errorcode == ERROR) { | ||
104 | usage_va(_("Could not parse arguments")); | 115 | usage_va(_("Could not parse arguments")); |
116 | } | ||
117 | |||
118 | const check_apt_config config = tmp_config.config; | ||
119 | |||
120 | if (config.output_format_is_set) { | ||
121 | mp_set_format(config.output_format); | ||
122 | } | ||
105 | 123 | ||
106 | /* Set signal handling and alarm timeout */ | 124 | /* Set signal handling and alarm timeout */ |
107 | if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) { | 125 | if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { |
108 | usage_va(_("Cannot catch SIGALRM")); | 126 | usage_va(_("Cannot catch SIGALRM")); |
109 | } | 127 | } |
110 | 128 | ||
111 | /* handle timeouts gracefully... */ | 129 | /* handle timeouts gracefully... */ |
112 | alarm (timeout_interval); | 130 | alarm(timeout_interval); |
113 | 131 | ||
132 | mp_check overall = mp_check_init(); | ||
114 | /* if they want to run apt-get update first... */ | 133 | /* if they want to run apt-get update first... */ |
115 | if(do_update) result = run_update(); | 134 | if (config.do_update) { |
135 | run_update_result update_result = run_update(config.update_opts); | ||
136 | |||
137 | mp_add_subcheck_to_check(&overall, update_result.sc); | ||
138 | } | ||
116 | 139 | ||
117 | /* apt-get upgrade */ | 140 | /* apt-get upgrade */ |
118 | result = max_state(result, run_upgrade(&packages_available, &sec_count, &packages_list, &secpackages_list)); | 141 | run_upgrade_result upgrad_res = |
119 | 142 | run_upgrade(config.upgrade, config.do_include, config.do_exclude, config.do_critical, | |
120 | if(sec_count > 0){ | 143 | config.upgrade_opts, config.input_filename); |
121 | result = max_state(result, STATE_CRITICAL); | 144 | |
122 | } else if(packages_available >= packages_warning && only_critical == false){ | 145 | mp_subcheck sc_run_upgrade = mp_subcheck_init(); |
123 | result = max_state(result, STATE_WARNING); | 146 | if (upgrad_res.errorcode == OK) { |
124 | } else if(result > STATE_UNKNOWN){ | 147 | sc_run_upgrade = mp_set_subcheck_state(sc_run_upgrade, STATE_OK); |
125 | result = STATE_UNKNOWN; | 148 | } |
149 | xasprintf(&sc_run_upgrade.output, "Executed apt upgrade (dry run)"); | ||
150 | |||
151 | mp_add_subcheck_to_check(&overall, sc_run_upgrade); | ||
152 | |||
153 | size_t packages_available = upgrad_res.package_count; | ||
154 | size_t number_of_security_updates = upgrad_res.security_package_count; | ||
155 | char **packages_list = upgrad_res.packages_list; | ||
156 | char **secpackages_list = upgrad_res.secpackages_list; | ||
157 | |||
158 | mp_perfdata pd_security_updates = perfdata_init(); | ||
159 | pd_security_updates.value = mp_create_pd_value(number_of_security_updates); | ||
160 | pd_security_updates.label = "critical_updates"; | ||
161 | |||
162 | mp_subcheck sc_security_updates = mp_subcheck_init(); | ||
163 | xasprintf(&sc_security_updates.output, "Security updates available: %zu", | ||
164 | number_of_security_updates); | ||
165 | mp_add_perfdata_to_subcheck(&sc_security_updates, pd_security_updates); | ||
166 | |||
167 | if (number_of_security_updates > 0) { | ||
168 | sc_security_updates = mp_set_subcheck_state(sc_security_updates, STATE_CRITICAL); | ||
169 | } else { | ||
170 | sc_security_updates = mp_set_subcheck_state(sc_security_updates, STATE_OK); | ||
171 | } | ||
172 | |||
173 | mp_perfdata pd_other_updates = perfdata_init(); | ||
174 | pd_other_updates.value = mp_create_pd_value(packages_available); | ||
175 | pd_other_updates.label = "available_upgrades"; | ||
176 | |||
177 | mp_subcheck sc_other_updates = mp_subcheck_init(); | ||
178 | |||
179 | xasprintf(&sc_other_updates.output, "Updates available: %zu", packages_available); | ||
180 | sc_other_updates = mp_set_subcheck_default_state(sc_other_updates, STATE_OK); | ||
181 | mp_add_perfdata_to_subcheck(&sc_other_updates, pd_other_updates); | ||
182 | |||
183 | if (packages_available >= config.packages_warning && !config.only_critical) { | ||
184 | sc_other_updates = mp_set_subcheck_state(sc_other_updates, STATE_WARNING); | ||
126 | } | 185 | } |
127 | 186 | ||
128 | printf(_("APT %s: %d packages available for %s (%d critical updates). %s%s%s%s|available_upgrades=%d;;;0 critical_updates=%d;;;0\n"), | 187 | if (config.list) { |
129 | state_text(result), | 188 | qsort(secpackages_list, number_of_security_updates, sizeof(char *), cmpstringp); |
130 | packages_available, | 189 | qsort(packages_list, packages_available - number_of_security_updates, sizeof(char *), |
131 | (upgrade==DIST_UPGRADE)?"dist-upgrade":"upgrade", | 190 | cmpstringp); |
132 | sec_count, | 191 | |
133 | (stderr_warning)?" warnings detected":"", | 192 | for (size_t i = 0; i < number_of_security_updates; i++) { |
134 | (stderr_warning && exec_warning)?",":"", | 193 | xasprintf(&sc_security_updates.output, "%s\n%s (security)", sc_security_updates.output, |
135 | (exec_warning)?" errors detected":"", | 194 | secpackages_list[i]); |
136 | (stderr_warning||exec_warning)?".":"", | 195 | } |
137 | packages_available, | 196 | |
138 | sec_count | 197 | if (!config.only_critical) { |
139 | ); | 198 | for (size_t i = 0; i < packages_available - number_of_security_updates; i++) { |
140 | 199 | xasprintf(&sc_other_updates.output, "%s\n%s", sc_other_updates.output, | |
141 | if(list) { | 200 | packages_list[i]); |
142 | qsort(secpackages_list, sec_count, sizeof(char*), cmpstringp); | 201 | } |
143 | qsort(packages_list, packages_available-sec_count, sizeof(char*), cmpstringp); | ||
144 | |||
145 | for(int i = 0; i < sec_count; i++) | ||
146 | printf("%s (security)\n", secpackages_list[i]); | ||
147 | |||
148 | if (only_critical == false) { | ||
149 | for(int i = 0; i < packages_available - sec_count; i++) | ||
150 | printf("%s\n", packages_list[i]); | ||
151 | } | 202 | } |
152 | } | 203 | } |
204 | mp_add_subcheck_to_check(&overall, sc_security_updates); | ||
205 | mp_add_subcheck_to_check(&overall, sc_other_updates); | ||
153 | 206 | ||
154 | return result; | 207 | mp_exit(overall); |
155 | } | 208 | } |
156 | 209 | ||
157 | /* process command-line arguments */ | 210 | /* process command-line arguments */ |
158 | int process_arguments (int argc, char **argv) { | 211 | check_apt_config_wrapper process_arguments(int argc, char **argv) { |
159 | int c; | 212 | enum { |
160 | 213 | /* Character for hidden input file option (for testing). */ | |
161 | static struct option longopts[] = { | 214 | INPUT_FILE_OPT = CHAR_MAX + 1, |
162 | {"version", no_argument, 0, 'V'}, | 215 | output_format_index, |
163 | {"help", no_argument, 0, 'h'}, | 216 | }; |
164 | {"verbose", no_argument, 0, 'v'}, | 217 | static struct option longopts[] = {{"version", no_argument, 0, 'V'}, |
165 | {"timeout", required_argument, 0, 't'}, | 218 | {"help", no_argument, 0, 'h'}, |
166 | {"update", optional_argument, 0, 'u'}, | 219 | {"verbose", no_argument, 0, 'v'}, |
167 | {"upgrade", optional_argument, 0, 'U'}, | 220 | {"timeout", required_argument, 0, 't'}, |
168 | {"no-upgrade", no_argument, 0, 'n'}, | 221 | {"update", optional_argument, 0, 'u'}, |
169 | {"dist-upgrade", optional_argument, 0, 'd'}, | 222 | {"upgrade", optional_argument, 0, 'U'}, |
170 | {"list", no_argument, false, 'l'}, | 223 | {"no-upgrade", no_argument, 0, 'n'}, |
171 | {"include", required_argument, 0, 'i'}, | 224 | {"dist-upgrade", optional_argument, 0, 'd'}, |
172 | {"exclude", required_argument, 0, 'e'}, | 225 | {"list", no_argument, 0, 'l'}, |
173 | {"critical", required_argument, 0, 'c'}, | 226 | {"include", required_argument, 0, 'i'}, |
174 | {"only-critical", no_argument, 0, 'o'}, | 227 | {"exclude", required_argument, 0, 'e'}, |
175 | {"input-file", required_argument, 0, INPUT_FILE_OPT}, | 228 | {"critical", required_argument, 0, 'c'}, |
176 | {"packages-warning", required_argument, 0, 'w'}, | 229 | {"only-critical", no_argument, 0, 'o'}, |
177 | {0, 0, 0, 0} | 230 | {"input-file", required_argument, 0, INPUT_FILE_OPT}, |
231 | {"packages-warning", required_argument, 0, 'w'}, | ||
232 | {"output-format", required_argument, 0, output_format_index}, | ||
233 | {0, 0, 0, 0}}; | ||
234 | |||
235 | check_apt_config_wrapper result = { | ||
236 | .errorcode = OK, | ||
237 | .config = check_apt_config_init(), | ||
178 | }; | 238 | }; |
179 | 239 | ||
180 | while(1) { | 240 | while (true) { |
181 | c = getopt_long(argc, argv, "hVvt:u::U::d::nli:e:c:ow:", longopts, NULL); | 241 | int option_char = getopt_long(argc, argv, "hVvt:u::U::d::nli:e:c:ow:", longopts, NULL); |
182 | 242 | ||
183 | if(c == -1 || c == EOF || c == 1) break; | 243 | if (option_char == -1 || option_char == EOF || option_char == 1) { |
244 | break; | ||
245 | } | ||
184 | 246 | ||
185 | switch(c) { | 247 | switch (option_char) { |
186 | case 'h': | 248 | case 'h': |
187 | print_help(); | 249 | print_help(); |
188 | exit(STATE_UNKNOWN); | 250 | exit(STATE_UNKNOWN); |
@@ -193,124 +255,153 @@ int process_arguments (int argc, char **argv) { | |||
193 | verbose++; | 255 | verbose++; |
194 | break; | 256 | break; |
195 | case 't': | 257 | case 't': |
196 | timeout_interval=atoi(optarg); | 258 | timeout_interval = atoi(optarg); |
197 | break; | 259 | break; |
198 | case 'd': | 260 | case 'd': |
199 | upgrade=DIST_UPGRADE; | 261 | result.config.upgrade = DIST_UPGRADE; |
200 | if(optarg!=NULL){ | 262 | if (optarg != NULL) { |
201 | upgrade_opts=strdup(optarg); | 263 | result.config.upgrade_opts = strdup(optarg); |
202 | if(upgrade_opts==NULL) die(STATE_UNKNOWN, "strdup failed"); | 264 | if (result.config.upgrade_opts == NULL) { |
265 | die(STATE_UNKNOWN, "strdup failed"); | ||
266 | } | ||
203 | } | 267 | } |
204 | break; | 268 | break; |
205 | case 'U': | 269 | case 'U': |
206 | upgrade=UPGRADE; | 270 | result.config.upgrade = UPGRADE; |
207 | if(optarg!=NULL){ | 271 | if (optarg != NULL) { |
208 | upgrade_opts=strdup(optarg); | 272 | result.config.upgrade_opts = strdup(optarg); |
209 | if(upgrade_opts==NULL) die(STATE_UNKNOWN, "strdup failed"); | 273 | if (result.config.upgrade_opts == NULL) { |
274 | die(STATE_UNKNOWN, "strdup failed"); | ||
275 | } | ||
210 | } | 276 | } |
211 | break; | 277 | break; |
212 | case 'n': | 278 | case 'n': |
213 | upgrade=NO_UPGRADE; | 279 | result.config.upgrade = NO_UPGRADE; |
214 | break; | 280 | break; |
215 | case 'u': | 281 | case 'u': |
216 | do_update=true; | 282 | result.config.do_update = true; |
217 | if(optarg!=NULL){ | 283 | if (optarg != NULL) { |
218 | update_opts=strdup(optarg); | 284 | result.config.update_opts = strdup(optarg); |
219 | if(update_opts==NULL) die(STATE_UNKNOWN, "strdup failed"); | 285 | if (result.config.update_opts == NULL) { |
286 | die(STATE_UNKNOWN, "strdup failed"); | ||
287 | } | ||
220 | } | 288 | } |
221 | break; | 289 | break; |
222 | case 'l': | 290 | case 'l': |
223 | list=true; | 291 | result.config.list = true; |
224 | break; | 292 | break; |
225 | case 'i': | 293 | case 'i': |
226 | do_include=add_to_regexp(do_include, optarg); | 294 | result.config.do_include = add_to_regexp(result.config.do_include, optarg); |
227 | break; | 295 | break; |
228 | case 'e': | 296 | case 'e': |
229 | do_exclude=add_to_regexp(do_exclude, optarg); | 297 | result.config.do_exclude = add_to_regexp(result.config.do_exclude, optarg); |
230 | break; | 298 | break; |
231 | case 'c': | 299 | case 'c': |
232 | do_critical=add_to_regexp(do_critical, optarg); | 300 | result.config.do_critical = add_to_regexp(result.config.do_critical, optarg); |
233 | break; | 301 | break; |
234 | case 'o': | 302 | case 'o': |
235 | only_critical=true; | 303 | result.config.only_critical = true; |
236 | break; | 304 | break; |
237 | case INPUT_FILE_OPT: | 305 | case INPUT_FILE_OPT: |
238 | input_filename = optarg; | 306 | result.config.input_filename = optarg; |
239 | break; | 307 | break; |
240 | case 'w': | 308 | case 'w': |
241 | packages_warning = atoi(optarg); | 309 | result.config.packages_warning = atoi(optarg); |
310 | break; | ||
311 | case output_format_index: { | ||
312 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
313 | if (!parser.parsing_success) { | ||
314 | // TODO List all available formats here, maybe add anothoer usage function | ||
315 | printf("Invalid output format: %s\n", optarg); | ||
316 | exit(STATE_UNKNOWN); | ||
317 | } | ||
318 | |||
319 | result.config.output_format_is_set = true; | ||
320 | result.config.output_format = parser.output_format; | ||
242 | break; | 321 | break; |
322 | } | ||
243 | default: | 323 | default: |
244 | /* print short usage statement if args not parsable */ | 324 | /* print short usage statement if args not parsable */ |
245 | usage5(); | 325 | usage5(); |
246 | } | 326 | } |
247 | } | 327 | } |
248 | 328 | ||
249 | return OK; | 329 | return result; |
250 | } | 330 | } |
251 | 331 | ||
252 | |||
253 | /* run an apt-get upgrade */ | 332 | /* run an apt-get upgrade */ |
254 | int run_upgrade(int *pkgcount, int *secpkgcount, char ***pkglist, char ***secpkglist){ | 333 | run_upgrade_result run_upgrade(const upgrade_type upgrade, const char *do_include, |
255 | int result=STATE_UNKNOWN, regres=0, pc=0, spc=0; | 334 | const char *do_exclude, const char *do_critical, |
256 | struct output chld_out, chld_err; | 335 | const char *upgrade_opts, const char *input_filename) { |
257 | regex_t ireg, ereg, sreg; | 336 | regex_t exclude_regex; |
258 | char *cmdline=NULL, rerrbuf[64]; | ||
259 | |||
260 | /* initialize ereg as it is possible it is printed while uninitialized */ | 337 | /* initialize ereg as it is possible it is printed while uninitialized */ |
261 | memset(&ereg, '\0', sizeof(ereg.buffer)); | 338 | memset(&exclude_regex, '\0', sizeof(exclude_regex.buffer)); |
262 | 339 | ||
263 | if(upgrade==NO_UPGRADE) return STATE_OK; | 340 | run_upgrade_result result = { |
341 | .errorcode = OK, | ||
342 | }; | ||
264 | 343 | ||
344 | if (upgrade == NO_UPGRADE) { | ||
345 | result.errorcode = OK; | ||
346 | return result; | ||
347 | } | ||
348 | |||
349 | int regres = 0; | ||
350 | regex_t include_regex; | ||
351 | char rerrbuf[64]; | ||
265 | /* compile the regexps */ | 352 | /* compile the regexps */ |
266 | if (do_include != NULL) { | 353 | if (do_include != NULL) { |
267 | regres=regcomp(&ireg, do_include, REG_EXTENDED); | 354 | regres = regcomp(&include_regex, do_include, REG_EXTENDED); |
268 | if (regres!=0) { | 355 | if (regres != 0) { |
269 | regerror(regres, &ireg, rerrbuf, 64); | 356 | regerror(regres, &include_regex, rerrbuf, 64); |
270 | die(STATE_UNKNOWN, _("%s: Error compiling regexp: %s"), progname, rerrbuf); | 357 | die(STATE_UNKNOWN, _("%s: Error compiling regexp: %s"), progname, rerrbuf); |
271 | } | 358 | } |
272 | } | 359 | } |
273 | 360 | ||
274 | if(do_exclude!=NULL){ | 361 | if (do_exclude != NULL) { |
275 | regres=regcomp(&ereg, do_exclude, REG_EXTENDED); | 362 | regres = regcomp(&exclude_regex, do_exclude, REG_EXTENDED); |
276 | if(regres!=0) { | 363 | if (regres != 0) { |
277 | regerror(regres, &ereg, rerrbuf, 64); | 364 | regerror(regres, &exclude_regex, rerrbuf, 64); |
278 | die(STATE_UNKNOWN, _("%s: Error compiling regexp: %s"), | 365 | die(STATE_UNKNOWN, _("%s: Error compiling regexp: %s"), progname, rerrbuf); |
279 | progname, rerrbuf); | ||
280 | } | 366 | } |
281 | } | 367 | } |
282 | 368 | ||
369 | regex_t sreg; | ||
283 | const char *crit_ptr = (do_critical != NULL) ? do_critical : SECURITY_RE; | 370 | const char *crit_ptr = (do_critical != NULL) ? do_critical : SECURITY_RE; |
284 | regres=regcomp(&sreg, crit_ptr, REG_EXTENDED); | 371 | regres = regcomp(&sreg, crit_ptr, REG_EXTENDED); |
285 | if(regres!=0) { | 372 | if (regres != 0) { |
286 | regerror(regres, &ereg, rerrbuf, 64); | 373 | regerror(regres, &exclude_regex, rerrbuf, 64); |
287 | die(STATE_UNKNOWN, _("%s: Error compiling regexp: %s"), | 374 | die(STATE_UNKNOWN, _("%s: Error compiling regexp: %s"), progname, rerrbuf); |
288 | progname, rerrbuf); | ||
289 | } | 375 | } |
290 | 376 | ||
291 | cmdline=construct_cmdline(upgrade, upgrade_opts); | 377 | output chld_out; |
378 | output chld_err; | ||
379 | char *cmdline = NULL; | ||
380 | cmdline = construct_cmdline(upgrade, upgrade_opts); | ||
292 | if (input_filename != NULL) { | 381 | if (input_filename != NULL) { |
293 | /* read input from a file for testing */ | 382 | /* read input from a file for testing */ |
294 | result = cmd_file_read(input_filename, &chld_out, 0); | 383 | result.errorcode = cmd_file_read(input_filename, &chld_out, 0); |
295 | } else { | 384 | } else { |
296 | /* run the upgrade */ | 385 | /* run the upgrade */ |
297 | result = np_runcmd(cmdline, &chld_out, &chld_err, 0); | 386 | result.errorcode = np_runcmd(cmdline, &chld_out, &chld_err, 0); |
298 | } | 387 | } |
299 | 388 | ||
300 | /* apt-get upgrade only changes exit status if there is an | 389 | // apt-get upgrade only changes exit status if there is an |
301 | * internal error when run in dry-run mode. therefore we will | 390 | // internal error when run in dry-run mode. |
302 | * treat such an error as UNKNOWN */ | 391 | if (result.errorcode != 0) { |
303 | if(result != 0){ | 392 | result.exec_warning = true; |
304 | exec_warning=1; | 393 | result.errorcode = ERROR; |
305 | result = STATE_UNKNOWN; | 394 | // fprintf(stderr, _("'%s' exited with non-zero status.\n"), cmdline); |
306 | fprintf(stderr, _("'%s' exited with non-zero status.\n"), | ||
307 | cmdline); | ||
308 | } | 395 | } |
309 | 396 | ||
310 | *pkglist=malloc(sizeof(char *) * chld_out.lines); | 397 | char **pkglist = malloc(sizeof(char *) * chld_out.lines); |
311 | if(!pkglist) die(STATE_UNKNOWN, "malloc failed!\n"); | 398 | if (!pkglist) { |
312 | *secpkglist=malloc(sizeof(char *) * chld_out.lines); | 399 | die(STATE_UNKNOWN, "malloc failed!\n"); |
313 | if(!secpkglist) die(STATE_UNKNOWN, "malloc failed!\n"); | 400 | } |
401 | char **secpkglist = malloc(sizeof(char *) * chld_out.lines); | ||
402 | if (!secpkglist) { | ||
403 | die(STATE_UNKNOWN, "malloc failed!\n"); | ||
404 | } | ||
314 | 405 | ||
315 | /* parse the output, which should only consist of lines like | 406 | /* parse the output, which should only consist of lines like |
316 | * | 407 | * |
@@ -321,242 +412,293 @@ int run_upgrade(int *pkgcount, int *secpkgcount, char ***pkglist, char ***secpkg | |||
321 | * we may need to switch to the --print-uris output format, | 412 | * we may need to switch to the --print-uris output format, |
322 | * in which case the logic here will slightly change. | 413 | * in which case the logic here will slightly change. |
323 | */ | 414 | */ |
324 | for(size_t i = 0; i < chld_out.lines; i++) { | 415 | size_t package_counter = 0; |
325 | if(verbose){ | 416 | size_t security_package_counter = 0; |
417 | for (size_t i = 0; i < chld_out.lines; i++) { | ||
418 | if (verbose) { | ||
326 | printf("%s\n", chld_out.line[i]); | 419 | printf("%s\n", chld_out.line[i]); |
327 | } | 420 | } |
421 | |||
328 | /* if it is a package we care about */ | 422 | /* if it is a package we care about */ |
329 | if (strncmp(PKGINST_PREFIX, chld_out.line[i], strlen(PKGINST_PREFIX)) == 0 && | 423 | if (strncmp(PKGINST_PREFIX, chld_out.line[i], strlen(PKGINST_PREFIX)) == 0 && |
330 | (do_include == NULL || regexec(&ireg, chld_out.line[i], 0, NULL, 0) == 0)) { | 424 | (do_include == NULL || regexec(&include_regex, chld_out.line[i], 0, NULL, 0) == 0)) { |
331 | /* if we're not excluding, or it's not in the | 425 | /* if we're not excluding, or it's not in the |
332 | * list of stuff to exclude */ | 426 | * list of stuff to exclude */ |
333 | if(do_exclude==NULL || | 427 | if (do_exclude == NULL || regexec(&exclude_regex, chld_out.line[i], 0, NULL, 0) != 0) { |
334 | regexec(&ereg, chld_out.line[i], 0, NULL, 0)!=0){ | 428 | package_counter++; |
335 | pc++; | 429 | if (regexec(&sreg, chld_out.line[i], 0, NULL, 0) == 0) { |
336 | if(regexec(&sreg, chld_out.line[i], 0, NULL, 0)==0){ | 430 | security_package_counter++; |
337 | spc++; | 431 | |
338 | if(verbose) printf("*"); | 432 | if (verbose) { |
339 | (*secpkglist)[spc-1] = pkg_name(chld_out.line[i]); | 433 | printf("*"); |
434 | } | ||
435 | |||
436 | (secpkglist)[security_package_counter - 1] = pkg_name(chld_out.line[i]); | ||
340 | } else { | 437 | } else { |
341 | (*pkglist)[pc-spc-1] = pkg_name(chld_out.line[i]); | 438 | (pkglist)[package_counter - security_package_counter - 1] = |
439 | pkg_name(chld_out.line[i]); | ||
342 | } | 440 | } |
343 | if(verbose){ | 441 | if (verbose) { |
344 | printf("*%s\n", chld_out.line[i]); | 442 | printf("*%s\n", chld_out.line[i]); |
345 | } | 443 | } |
346 | } | 444 | } |
347 | } | 445 | } |
348 | } | 446 | } |
349 | *pkgcount=pc; | 447 | |
350 | *secpkgcount=spc; | 448 | result.package_count = package_counter; |
449 | result.security_package_count = security_package_counter; | ||
450 | result.packages_list = pkglist; | ||
451 | result.secpackages_list = secpkglist; | ||
351 | 452 | ||
352 | /* If we get anything on stderr, at least set warning */ | 453 | /* If we get anything on stderr, at least set warning */ |
353 | if (input_filename == NULL && chld_err.buflen) { | 454 | if (input_filename == NULL && chld_err.buflen) { |
354 | stderr_warning=1; | 455 | stderr_warning = true; |
355 | result = max_state(result, STATE_WARNING); | 456 | result.errorcode = ERROR; |
356 | if(verbose){ | 457 | |
357 | for(size_t i = 0; i < chld_err.lines; i++) { | 458 | if (verbose) { |
459 | for (size_t i = 0; i < chld_err.lines; i++) { | ||
358 | fprintf(stderr, "%s\n", chld_err.line[i]); | 460 | fprintf(stderr, "%s\n", chld_err.line[i]); |
359 | } | 461 | } |
360 | } | 462 | } |
361 | } | 463 | } |
362 | if (do_include != NULL) regfree(&ireg); | 464 | |
465 | if (do_include != NULL) { | ||
466 | regfree(&include_regex); | ||
467 | } | ||
468 | |||
363 | regfree(&sreg); | 469 | regfree(&sreg); |
364 | if(do_exclude!=NULL) regfree(&ereg); | 470 | |
471 | if (do_exclude != NULL) { | ||
472 | regfree(&exclude_regex); | ||
473 | } | ||
474 | |||
365 | free(cmdline); | 475 | free(cmdline); |
476 | |||
366 | return result; | 477 | return result; |
367 | } | 478 | } |
368 | 479 | ||
369 | /* run an apt-get update (needs root) */ | 480 | /* run an apt-get update (needs root) */ |
370 | int run_update(void){ | 481 | run_update_result run_update(char *update_opts) { |
371 | int result=STATE_UNKNOWN; | ||
372 | struct output chld_out, chld_err; | ||
373 | char *cmdline; | 482 | char *cmdline; |
374 | |||
375 | /* run the update */ | 483 | /* run the update */ |
376 | cmdline = construct_cmdline(NO_UPGRADE, update_opts); | 484 | cmdline = construct_cmdline(NO_UPGRADE, update_opts); |
377 | result = np_runcmd(cmdline, &chld_out, &chld_err, 0); | 485 | |
486 | run_update_result result = { | ||
487 | .exec_warning = false, | ||
488 | .stderr_warning = false, | ||
489 | .sc = mp_subcheck_init(), | ||
490 | }; | ||
491 | |||
492 | result.sc = mp_set_subcheck_default_state(result.sc, STATE_OK); | ||
493 | xasprintf(&result.sc.output, "executing '%s' first", cmdline); | ||
494 | |||
495 | output chld_out; | ||
496 | output chld_err; | ||
497 | int cmd_error = np_runcmd(cmdline, &chld_out, &chld_err, 0); | ||
378 | /* apt-get update changes exit status if it can't fetch packages. | 498 | /* apt-get update changes exit status if it can't fetch packages. |
379 | * since we were explicitly asked to do so, this is treated as | 499 | * since we were explicitly asked to do so, this is treated as |
380 | * a critical error. */ | 500 | * a critical error. */ |
381 | if(result != 0){ | 501 | if (cmd_error != 0) { |
382 | exec_warning=1; | 502 | exec_warning = true; |
383 | result = STATE_CRITICAL; | 503 | result.sc = mp_set_subcheck_state(result.sc, STATE_CRITICAL); |
384 | fprintf(stderr, _("'%s' exited with non-zero status.\n"), | 504 | xasprintf(&result.sc.output, _("'%s' exited with non-zero status.\n"), cmdline); |
385 | cmdline); | ||
386 | } | 505 | } |
387 | 506 | ||
388 | if(verbose){ | 507 | if (verbose) { |
389 | for(size_t i = 0; i < chld_out.lines; i++) { | 508 | for (size_t i = 0; i < chld_out.lines; i++) { |
390 | printf("%s\n", chld_out.line[i]); | 509 | printf("%s\n", chld_out.line[i]); |
391 | } | 510 | } |
392 | } | 511 | } |
393 | 512 | ||
394 | /* If we get anything on stderr, at least set warning */ | 513 | /* If we get anything on stderr, at least set warning */ |
395 | if(chld_err.buflen){ | 514 | if (chld_err.buflen) { |
396 | stderr_warning=1; | 515 | stderr_warning = true; |
397 | result = max_state(result, STATE_WARNING); | 516 | result.sc = mp_set_subcheck_state( |
398 | if(verbose){ | 517 | result.sc, max_state(mp_compute_subcheck_state(result.sc), STATE_WARNING)); |
399 | for(size_t i = 0; i < chld_err.lines; i++) { | 518 | if (verbose) { |
519 | for (size_t i = 0; i < chld_err.lines; i++) { | ||
400 | fprintf(stderr, "%s\n", chld_err.line[i]); | 520 | fprintf(stderr, "%s\n", chld_err.line[i]); |
401 | } | 521 | } |
402 | } | 522 | } |
403 | } | 523 | } |
524 | |||
404 | free(cmdline); | 525 | free(cmdline); |
526 | |||
405 | return result; | 527 | return result; |
406 | } | 528 | } |
407 | 529 | ||
408 | char* pkg_name(char *line){ | 530 | char *pkg_name(char *line) { |
409 | char *start=NULL, *space=NULL, *pkg=NULL; | 531 | char *start = line + strlen(PKGINST_PREFIX); |
410 | int len=0; | ||
411 | 532 | ||
412 | start = line + strlen(PKGINST_PREFIX); | 533 | size_t len = strlen(start); |
413 | len = strlen(start); | ||
414 | 534 | ||
415 | space = index(start, ' '); | 535 | char *space = index(start, ' '); |
416 | if(space!=NULL){ | 536 | if (space != NULL) { |
417 | len = space - start; | 537 | len = space - start; |
418 | } | 538 | } |
419 | 539 | ||
420 | pkg=malloc(sizeof(char)*(len+1)); | 540 | char *pkg = malloc(sizeof(char) * (len + 1)); |
421 | if(!pkg) die(STATE_UNKNOWN, "malloc failed!\n"); | 541 | if (!pkg) { |
542 | die(STATE_UNKNOWN, "malloc failed!\n"); | ||
543 | } | ||
422 | 544 | ||
423 | strncpy(pkg, start, len); | 545 | strncpy(pkg, start, len); |
424 | pkg[len]='\0'; | 546 | pkg[len] = '\0'; |
425 | 547 | ||
426 | return pkg; | 548 | return pkg; |
427 | } | 549 | } |
428 | 550 | ||
429 | int cmpstringp(const void *p1, const void *p2){ | 551 | int cmpstringp(const void *left_string, const void *right_string) { |
430 | return strcmp(* (char * const *) p1, * (char * const *) p2); | 552 | return strcmp(*(char *const *)left_string, *(char *const *)right_string); |
431 | } | 553 | } |
432 | 554 | ||
433 | char* add_to_regexp(char *expr, const char *next){ | 555 | char *add_to_regexp(char *expr, const char *next) { |
434 | char *re=NULL; | 556 | char *regex_string = NULL; |
435 | 557 | ||
436 | if(expr==NULL){ | 558 | if (expr == NULL) { |
437 | re=malloc(sizeof(char)*(strlen("()")+strlen(next)+1)); | 559 | regex_string = malloc(sizeof(char) * (strlen("()") + strlen(next) + 1)); |
438 | if(!re) die(STATE_UNKNOWN, "malloc failed!\n"); | 560 | if (!regex_string) { |
439 | sprintf(re, "(%s)", next); | 561 | die(STATE_UNKNOWN, "malloc failed!\n"); |
562 | } | ||
563 | sprintf(regex_string, "(%s)", next); | ||
440 | } else { | 564 | } else { |
441 | /* resize it, adding an extra char for the new '|' separator */ | 565 | /* resize it, adding an extra char for the new '|' separator */ |
442 | re=realloc(expr, sizeof(char)*(strlen(expr)+1+strlen(next)+1)); | 566 | regex_string = realloc(expr, sizeof(char) * (strlen(expr) + 1 + strlen(next) + 1)); |
443 | if(!re) die(STATE_UNKNOWN, "realloc failed!\n"); | 567 | if (!regex_string) { |
568 | die(STATE_UNKNOWN, "realloc failed!\n"); | ||
569 | } | ||
444 | /* append it starting at ')' in the old re */ | 570 | /* append it starting at ')' in the old re */ |
445 | sprintf((char*)(re+strlen(re)-1), "|%s)", next); | 571 | sprintf((char *)(regex_string + strlen(regex_string) - 1), "|%s)", next); |
446 | } | 572 | } |
447 | 573 | ||
448 | return re; | 574 | return regex_string; |
449 | } | 575 | } |
450 | 576 | ||
451 | char* construct_cmdline(upgrade_type u, const char *opts){ | 577 | char *construct_cmdline(upgrade_type upgrade, const char *opts) { |
452 | int len=0; | 578 | const char *opts_ptr = NULL; |
453 | const char *opts_ptr=NULL, *aptcmd=NULL; | 579 | const char *aptcmd = NULL; |
454 | char *cmd=NULL; | ||
455 | 580 | ||
456 | switch(u){ | 581 | switch (upgrade) { |
457 | case UPGRADE: | 582 | case UPGRADE: |
458 | if(opts==NULL) opts_ptr=UPGRADE_DEFAULT_OPTS; | 583 | if (opts == NULL) { |
459 | else opts_ptr=opts; | 584 | opts_ptr = UPGRADE_DEFAULT_OPTS; |
460 | aptcmd="upgrade"; | 585 | } else { |
586 | opts_ptr = opts; | ||
587 | } | ||
588 | aptcmd = "upgrade"; | ||
461 | break; | 589 | break; |
462 | case DIST_UPGRADE: | 590 | case DIST_UPGRADE: |
463 | if(opts==NULL) opts_ptr=UPGRADE_DEFAULT_OPTS; | 591 | if (opts == NULL) { |
464 | else opts_ptr=opts; | 592 | opts_ptr = UPGRADE_DEFAULT_OPTS; |
465 | aptcmd="dist-upgrade"; | 593 | } else { |
594 | opts_ptr = opts; | ||
595 | } | ||
596 | aptcmd = "dist-upgrade"; | ||
466 | break; | 597 | break; |
467 | case NO_UPGRADE: | 598 | case NO_UPGRADE: |
468 | if(opts==NULL) opts_ptr=UPDATE_DEFAULT_OPTS; | 599 | if (opts == NULL) { |
469 | else opts_ptr=opts; | 600 | opts_ptr = UPDATE_DEFAULT_OPTS; |
470 | aptcmd="update"; | 601 | } else { |
602 | opts_ptr = opts; | ||
603 | } | ||
604 | aptcmd = "update"; | ||
471 | break; | 605 | break; |
472 | } | 606 | } |
473 | 607 | ||
474 | len+=strlen(PATH_TO_APTGET)+1; /* "/usr/bin/apt-get " */ | 608 | size_t len = 0; |
475 | len+=strlen(opts_ptr)+1; /* "opts " */ | 609 | len += strlen(PATH_TO_APTGET) + 1; /* "/usr/bin/apt-get " */ |
476 | len+=strlen(aptcmd)+1; /* "upgrade\0" */ | 610 | len += strlen(opts_ptr) + 1; /* "opts " */ |
611 | len += strlen(aptcmd) + 1; /* "upgrade\0" */ | ||
477 | 612 | ||
478 | cmd=(char*)malloc(sizeof(char)*len); | 613 | char *cmd = (char *)malloc(sizeof(char) * len); |
479 | if(cmd==NULL) die(STATE_UNKNOWN, "malloc failed"); | 614 | if (cmd == NULL) { |
615 | die(STATE_UNKNOWN, "malloc failed"); | ||
616 | } | ||
480 | sprintf(cmd, "%s %s %s", PATH_TO_APTGET, opts_ptr, aptcmd); | 617 | sprintf(cmd, "%s %s %s", PATH_TO_APTGET, opts_ptr, aptcmd); |
481 | return cmd; | 618 | return cmd; |
482 | } | 619 | } |
483 | 620 | ||
484 | /* informative help message */ | 621 | /* informative help message */ |
485 | void | 622 | void print_help(void) { |
486 | print_help (void) | 623 | print_revision(progname, NP_VERSION); |
487 | { | 624 | |
488 | print_revision(progname, NP_VERSION); | 625 | printf(_(COPYRIGHT), copyright, email); |
489 | 626 | ||
490 | printf(_(COPYRIGHT), copyright, email); | 627 | printf("%s\n", _("This plugin checks for software updates on systems that use")); |
491 | 628 | printf("%s\n", _("package management systems based on the apt-get(8) command")); | |
492 | printf("%s\n", _("This plugin checks for software updates on systems that use")); | 629 | printf("%s\n", _("found in Debian GNU/Linux")); |
493 | printf("%s\n", _("package management systems based on the apt-get(8) command")); | 630 | |
494 | printf("%s\n", _("found in Debian GNU/Linux")); | 631 | printf("\n\n"); |
495 | 632 | ||
496 | printf ("\n\n"); | 633 | print_usage(); |
497 | 634 | ||
498 | print_usage(); | 635 | printf(UT_HELP_VRSN); |
499 | 636 | printf(UT_EXTRA_OPTS); | |
500 | printf(UT_HELP_VRSN); | 637 | |
501 | printf(UT_EXTRA_OPTS); | 638 | printf(UT_PLUG_TIMEOUT, timeout_interval); |
502 | 639 | ||
503 | printf(UT_PLUG_TIMEOUT, timeout_interval); | 640 | printf(" %s\n", "-n, --no-upgrade"); |
504 | 641 | printf(" %s\n", _("Do not run the upgrade. Probably not useful (without -u at least).")); | |
505 | printf (" %s\n", "-n, --no-upgrade"); | 642 | printf(" %s\n", "-l, --list"); |
506 | printf (" %s\n", _("Do not run the upgrade. Probably not useful (without -u at least).")); | 643 | printf(" %s\n", _("List packages available for upgrade. Packages are printed sorted by")); |
507 | printf (" %s\n", "-l, --list"); | 644 | printf(" %s\n", _("name with security packages listed first.")); |
508 | printf (" %s\n", _("List packages available for upgrade. Packages are printed sorted by")); | 645 | printf(" %s\n", "-i, --include=REGEXP"); |
509 | printf (" %s\n", _("name with security packages listed first.")); | 646 | printf(" %s\n", |
510 | printf (" %s\n", "-i, --include=REGEXP"); | 647 | _("Include only packages matching REGEXP. Can be specified multiple times")); |
511 | printf (" %s\n", _("Include only packages matching REGEXP. Can be specified multiple times")); | 648 | printf(" %s\n", _("the values will be combined together. Any packages matching this list")); |
512 | printf (" %s\n", _("the values will be combined together. Any packages matching this list")); | 649 | printf(" %s\n", _("cause the plugin to return WARNING status. Others will be ignored.")); |
513 | printf (" %s\n", _("cause the plugin to return WARNING status. Others will be ignored.")); | 650 | printf(" %s\n", _("Default is to include all packages.")); |
514 | printf (" %s\n", _("Default is to include all packages.")); | 651 | printf(" %s\n", "-e, --exclude=REGEXP"); |
515 | printf (" %s\n", "-e, --exclude=REGEXP"); | 652 | printf(" %s\n", _("Exclude packages matching REGEXP from the list of packages that would")); |
516 | printf (" %s\n", _("Exclude packages matching REGEXP from the list of packages that would")); | 653 | printf(" %s\n", _("otherwise be included. Can be specified multiple times; the values")); |
517 | printf (" %s\n", _("otherwise be included. Can be specified multiple times; the values")); | 654 | printf(" %s\n", _("will be combined together. Default is to exclude no packages.")); |
518 | printf (" %s\n", _("will be combined together. Default is to exclude no packages.")); | 655 | printf(" %s\n", "-c, --critical=REGEXP"); |
519 | printf (" %s\n", "-c, --critical=REGEXP"); | 656 | printf(" %s\n", |
520 | printf (" %s\n", _("If the full package information of any of the upgradable packages match")); | 657 | _("If the full package information of any of the upgradable packages match")); |
521 | printf (" %s\n", _("this REGEXP, the plugin will return CRITICAL status. Can be specified")); | 658 | printf(" %s\n", _("this REGEXP, the plugin will return CRITICAL status. Can be specified")); |
522 | printf (" %s\n", _("multiple times like above. Default is a regexp matching security")); | 659 | printf(" %s\n", _("multiple times like above. Default is a regexp matching security")); |
523 | printf (" %s\n", _("upgrades for Debian and Ubuntu:")); | 660 | printf(" %s\n", _("upgrades for Debian and Ubuntu:")); |
524 | printf (" \t%s\n", SECURITY_RE); | 661 | printf(" \t%s\n", SECURITY_RE); |
525 | printf (" %s\n", _("Note that the package must first match the include list before its")); | 662 | printf(" %s\n", _("Note that the package must first match the include list before its")); |
526 | printf (" %s\n", _("information is compared against the critical list.")); | 663 | printf(" %s\n", _("information is compared against the critical list.")); |
527 | printf (" %s\n", "-o, --only-critical"); | 664 | printf(" %s\n", "-o, --only-critical"); |
528 | printf (" %s\n", _("Only warn about upgrades matching the critical list. The total number")); | 665 | printf(" %s\n", _("Only warn about upgrades matching the critical list. The total number")); |
529 | printf (" %s\n", _("of upgrades will be printed, but any non-critical upgrades will not cause")); | 666 | printf(" %s\n", |
530 | printf (" %s\n", _("the plugin to return WARNING status.")); | 667 | _("of upgrades will be printed, but any non-critical upgrades will not cause")); |
531 | printf (" %s\n", "-w, --packages-warning"); | 668 | printf(" %s\n", _("the plugin to return WARNING status.")); |
532 | printf (" %s\n", _("Minimum number of packages available for upgrade to return WARNING status.")); | 669 | printf(" %s\n", "-w, --packages-warning"); |
533 | printf (" %s\n\n", _("Default is 1 package.")); | 670 | printf(" %s\n", |
534 | 671 | _("Minimum number of packages available for upgrade to return WARNING status.")); | |
535 | printf ("%s\n\n", _("The following options require root privileges and should be used with care:")); | 672 | printf(" %s\n\n", _("Default is 1 package.")); |
536 | printf (" %s\n", "-u, --update=OPTS"); | 673 | |
537 | printf (" %s\n", _("First perform an 'apt-get update'. An optional OPTS parameter overrides")); | 674 | printf(UT_OUTPUT_FORMAT); |
538 | printf (" %s\n", _("the default options. Note: you may also need to adjust the global")); | 675 | |
539 | printf (" %s\n", _("timeout (with -t) to prevent the plugin from timing out if apt-get")); | 676 | printf("%s\n\n", |
540 | printf (" %s\n", _("upgrade is expected to take longer than the default timeout.")); | 677 | _("The following options require root privileges and should be used with care:")); |
541 | printf (" %s\n", "-U, --upgrade=OPTS"); | 678 | printf(" %s\n", "-u, --update=OPTS"); |
542 | printf (" %s\n", _("Perform an upgrade. If an optional OPTS argument is provided,")); | 679 | printf(" %s\n", |
543 | printf (" %s\n", _("apt-get will be run with these command line options instead of the")); | 680 | _("First perform an 'apt-get update'. An optional OPTS parameter overrides")); |
544 | printf (" %s", _("default ")); | 681 | printf(" %s\n", _("the default options. Note: you may also need to adjust the global")); |
545 | printf ("(%s).\n", UPGRADE_DEFAULT_OPTS); | 682 | printf(" %s\n", _("timeout (with -t) to prevent the plugin from timing out if apt-get")); |
546 | printf (" %s\n", _("Note that you may be required to have root privileges if you do not use")); | 683 | printf(" %s\n", _("upgrade is expected to take longer than the default timeout.")); |
547 | printf (" %s\n", _("the default options, which will only run a simulation and NOT perform the upgrade")); | 684 | printf(" %s\n", "-U, --upgrade=OPTS"); |
548 | printf (" %s\n", "-d, --dist-upgrade=OPTS"); | 685 | printf(" %s\n", _("Perform an upgrade. If an optional OPTS argument is provided,")); |
549 | printf (" %s\n", _("Perform a dist-upgrade instead of normal upgrade. Like with -U OPTS")); | 686 | printf(" %s\n", _("apt-get will be run with these command line options instead of the")); |
550 | printf (" %s\n", _("can be provided to override the default options.")); | 687 | printf(" %s", _("default ")); |
551 | 688 | printf("(%s).\n", UPGRADE_DEFAULT_OPTS); | |
552 | printf(UT_SUPPORT); | 689 | printf(" %s\n", |
690 | _("Note that you may be required to have root privileges if you do not use")); | ||
691 | printf(" %s\n", | ||
692 | _("the default options, which will only run a simulation and NOT perform the upgrade")); | ||
693 | printf(" %s\n", "-d, --dist-upgrade=OPTS"); | ||
694 | printf(" %s\n", _("Perform a dist-upgrade instead of normal upgrade. Like with -U OPTS")); | ||
695 | printf(" %s\n", _("can be provided to override the default options.")); | ||
696 | |||
697 | printf(UT_SUPPORT); | ||
553 | } | 698 | } |
554 | 699 | ||
555 | |||
556 | /* simple usage heading */ | 700 | /* simple usage heading */ |
557 | void | 701 | void print_usage(void) { |
558 | print_usage(void) | 702 | printf("%s\n", _("Usage:")); |
559 | { | 703 | printf("%s [[-d|-u|-U]opts] [-n] [-l] [-t timeout] [-w packages-warning]\n", progname); |
560 | printf ("%s\n", _("Usage:")); | ||
561 | printf ("%s [[-d|-u|-U]opts] [-n] [-l] [-t timeout] [-w packages-warning]\n", progname); | ||
562 | } | 704 | } |