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