/* module_analysis */ int module_analysis(void) { OUTPUT(("%s", _YELLOW("Analysing measurements"))); if (PERFEXPERT_SUCCESS != output_analysis()) { OUTPUT(("%s", _ERROR("printing analysis report"))); return PERFEXPERT_ERROR; } return PERFEXPERT_SUCCESS; }
/*! \brief Start of execution. Parse options, and call other other * functions one after another. At the moment adding threading support * would be difficult, but there does not seem to be valid reason to * consider that. Overall the analysis already quick enough even without * making it parallel. * * \return Return value indicates success or fail or analysis, unless * either --warning or --critical options are in use, which makes the * return value in some cases to match with Nagios expectations about * alarming. */ int main(int argc, char **argv) { int i, sorts = 0; int option_index = 0; char const *tmp; struct range_t *tmp_ranges; enum { OPT_WARN = CHAR_MAX + 1, OPT_CRIT }; int ret_val; /* Options for getopt_long */ static struct option const long_options[] = { {"config", required_argument, NULL, 'c'}, {"leases", required_argument, NULL, 'l'}, {"format", required_argument, NULL, 'f'}, {"sort", required_argument, NULL, 's'}, {"reverse", no_argument, NULL, 'r'}, {"output", required_argument, NULL, 'o'}, {"limit", required_argument, NULL, 'L'}, {"version", no_argument, NULL, 'v'}, {"help", no_argument, NULL, 'h'}, {"warning", required_argument, NULL, OPT_WARN}, {"critical", required_argument, NULL, OPT_CRIT}, {NULL, 0, NULL, 0} }; atexit(close_stdout); /* FIXME: These allocations should be fully dynamic, e.g., grow * if needed. */ config.dhcpdconf_file = xmalloc(sizeof(char) * MAXLEN); config.dhcpdlease_file = xmalloc(sizeof(char) * MAXLEN); config.output_file = xmalloc(sizeof(char) * MAXLEN); /* Make sure string has zero length if there is no * command line option */ config.output_file[0] = '\0'; /* Alarming defaults. */ config.warning = ALARM_WARN; config.critical = ALARM_CRIT; /* File location defaults */ strncpy(config.dhcpdconf_file, DHCPDCONF_FILE, MAXLEN - 1); strncpy(config.dhcpdlease_file, DHCPDLEASE_FILE, MAXLEN - 1); tmp = OUTPUT_LIMIT; config.output_limit[0] = (*tmp - '0'); tmp++; config.output_limit[1] = (*tmp - '0'); config.fullhtml = false; /* Make sure some output format is selected by default */ strncpy(config.output_format, OUTPUT_FORMAT, (size_t)1); /* Default sort order is by IPs small to big */ config.reverse_order = false; config.backups_found = false; /* Parse command line options */ while (1) { int c; c = getopt_long(argc, argv, "c:l:f:o:s:rL:vh", long_options, &option_index); if (c == EOF) break; switch (c) { case 'c': /* config file */ strncpy(config.dhcpdconf_file, optarg, MAXLEN - 1); break; case 'l': /* lease file */ strncpy(config.dhcpdlease_file, optarg, MAXLEN - 1); break; case 'f': /* Output format */ strncpy(config.output_format, optarg, (size_t)1); break; case 's': /* Output sorting option */ sorts = strlen(optarg); if (5 < sorts) { warnx ("main: only first 5 sort orders will be used"); strncpy(config.sort, optarg, (size_t)5); sorts = 5; } else { strncpy(config.sort, optarg, (size_t)sorts); } for (i = 0; i < sorts; i++) { field_selector(config.sort[i]); } break; case 'r': /* What ever sort in reverse order */ config.reverse_order = true; break; case 'o': /* Output file */ strncpy(config.output_file, optarg, MAXLEN - 1); break; case 'L': /* Specification what will be printed */ for (i = 0; i < 2; i++) { if (optarg[i] >= '0' && optarg[i] < '8') { config.output_limit[i] = optarg[i] - '0'; } else { errx(EXIT_FAILURE, "main: output mask `%s' is illegal", optarg); } } break; case OPT_WARN: strcpy(config.output_format, "a"); config.warning = strtod_or_err(optarg, "illegal argument"); break; case OPT_CRIT: strcpy(config.output_format, "a"); config.critical = strtod_or_err(optarg, "illegal argument"); break; case 'v': /* Print version */ print_version(); case 'h': /* Print help */ usage(EXIT_SUCCESS); default: errx(EXIT_FAILURE, "Try `%s --help' for more information.", program_invocation_short_name); } } /* Output function selection */ switch (config.output_format[0]) { case 't': output_analysis = output_txt; break; case 'a': output_analysis = output_alarming; break; case 'h': output_analysis = output_html; break; case 'H': output_analysis = output_html; config.fullhtml = true; break; case 'x': output_analysis = output_xml; break; case 'X': output_analysis = output_xml; break; case 'j': output_analysis = output_json; break; case 'J': output_analysis = output_json; break; case 'c': output_analysis = output_csv; break; default: errx(EXIT_FAILURE, "main: unknown output format `%c'", config.output_format[0]); } /* Do the job */ prepare_memory(); parse_config(true, config.dhcpdconf_file, shared_networks); parse_leases(); prepare_data(); do_counting(); tmp_ranges = xmalloc(sizeof(struct range_t) * num_ranges); if (sorts != 0) { mergesort_ranges(ranges, num_ranges, tmp_ranges); } if (config.reverse_order == true) { flip_ranges(ranges, tmp_ranges); } free(tmp_ranges); ret_val = output_analysis(); clean_up(); return (ret_val); }