all files: replace global variables with runtime config state structure

Earlier variables magically appeared to scope of functions that took void as
argument.  One could figure out perhaps they were globals, but programs that
do that are unnessarily hard to follow.

Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
Sami Kerola 2017-11-12 13:35:04 +00:00
parent adda925c1e
commit 1875a13733
No known key found for this signature in database
GPG key ID: A9553245FDE9B739
12 changed files with 551 additions and 626 deletions

View file

@ -54,37 +54,38 @@
#include "xalloc.h"
#include "dhcpd-pools.h"
#include "defaults.h"
/* Global variables */
struct configuration_t config;
struct shared_network_t *shared_networks;
unsigned int num_shared_networks;
struct range_t *ranges;
unsigned int num_ranges;
struct leases_t *leases;
unsigned int RANGES;
/* Function pointers */
int (*parse_ipaddr) (const char *restrict src, union ipaddr_t *restrict dst);
int (*parse_ipaddr) (struct conf_t *state, const char *restrict src, union ipaddr_t *restrict dst);
void (*copy_ipaddr) (union ipaddr_t *restrict dst, const union ipaddr_t *restrict src);
const char *(*ntop_ipaddr) (const union ipaddr_t *ip);
double (*get_range_size) (const struct range_t *r);
int (*xstrstr) (const char *restrict str);
int (*xstrstr) (struct conf_t *state, const char *restrict str);
int (*ipcomp) (const union ipaddr_t *restrict a, const union ipaddr_t *restrict b);
int (*leasecomp) (const struct leases_t *restrict a, const struct leases_t *restrict b);
void (*add_lease) (union ipaddr_t *ip, enum ltype type);
struct leases_t *(*find_lease) (union ipaddr_t *ip);
void (*add_lease) (struct conf_t *state, union ipaddr_t *ip, enum ltype type);
struct leases_t *(*find_lease) (struct conf_t *state, union ipaddr_t *ip);
static int return_limit(const char c)
{
if ('0' <= c && c < '8')
return c - '0';
clean_up();
error(EXIT_FAILURE, 0, "return_limit: output mask %s is illegal", quote(optarg));
return 0;
}
/*! \brief Run time initialization. Global allocations, counter
* initializations, etc are here. */
static void prepare_memory(struct conf_t *state)
{
/* The SHARED_NETWORKS is a static value from defaults.h */
state->shared_networks = xcalloc(sizeof(struct shared_network_t), SHARED_NETWORKS);
state->ranges = xmalloc(sizeof(struct range_t) * state->ranges_size);
/* First shared network entry is all networks */
state->shared_networks->name = xstrdup("All networks");
}
/*! \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
@ -97,11 +98,21 @@ static int return_limit(const char c)
* alarming. */
int main(int argc, char **argv)
{
struct conf_t state = {
.warning = ALARM_WARN,
.critical = ALARM_CRIT,
.warn_count = 0x100000000, /* == 2^32 that is the entire IPv4 space */
.crit_count = 0x100000000, /* basically turns off the count criteria */
.header_limit = 8,
.color_mode = color_auto,
.ranges_size = 64,
.ip_version = IPvUNKNOWN,
0
};
int option_index = 0;
char output_format = '\0';
int alarming = 0;
char const *tmp;
struct range_t *tmp_ranges;
enum {
OPT_SNET_ALARMS = CHAR_MAX + 1,
OPT_WARN,
@ -143,36 +154,10 @@ int main(int argc, char **argv)
atexit(close_stdout);
set_program_name(argv[0]);
/* 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.snet_alarms = 0;
config.warning = ALARM_WARN;
config.critical = ALARM_CRIT;
config.warn_count = 0x100000000; /* == 2^32 that is the entire IPv4 space */
config.crit_count = 0x100000000; /* basically turns off the count criteria */
config.perfdata = 0;
config.color_mode = color_auto;
/* File location defaults */
strncpy(config.dhcpdconf_file, DHCPDCONF_FILE, MAXLEN - 1);
strncpy(config.dhcpdlease_file, DHCPDLEASE_FILE, MAXLEN - 1);
tmp = OUTPUT_LIMIT;
config.header_limit = (*tmp - '0');
tmp++;
config.number_limit = (*tmp - '0');
/* Default sort order is by IPs small to big */
config.reverse_order = 0;
config.backups_found = 0;
/* Treat single networks as shared with network CIDR as name */
config.all_as_shared = 0;
prepare_memory();
set_ipv_functions(IPvUNKNOWN);
prepare_memory(&state);
set_ipv_functions(&state, IPvUNKNOWN);
/* Parse command line options */
while (1) {
int c;
@ -183,11 +168,11 @@ int main(int argc, char **argv)
switch (c) {
case 'c':
/* config file */
strncpy(config.dhcpdconf_file, optarg, MAXLEN - 1);
state.dhcpdconf_file = optarg;
break;
case 'l':
/* lease file */
strncpy(config.dhcpdlease_file, optarg, MAXLEN - 1);
state.dhcpdlease_file = optarg;
break;
case 'f':
/* Output format */
@ -196,15 +181,15 @@ int main(int argc, char **argv)
case 's':
{
/* Output sorting option */
struct output_sort *p = config.sorts;
struct output_sort *p = state.sorts;
size_t len;
while (p && p->next)
p = p->next;
for (len = 0; len < strlen(optarg); len++) {
if (config.sorts == NULL) {
config.sorts = xcalloc(1, sizeof(struct output_sort));
p = config.sorts;
if (state.sorts == NULL) {
state.sorts = xcalloc(1, sizeof(struct output_sort));
p = state.sorts;
} else {
p->next = xcalloc(1, sizeof(struct output_sort));
p = p->next;
@ -215,62 +200,62 @@ int main(int argc, char **argv)
break;
case 'r':
/* What ever sort in reverse order */
config.reverse_order = 1;
state.reverse_order = 1;
break;
case 'o':
/* Output file */
strncpy(config.output_file, optarg, MAXLEN - 1);
state.output_file = optarg;
break;
case 'L':
/* Specification what will be printed */
config.header_limit = return_limit(optarg[0]);
config.number_limit = return_limit(optarg[1]);
state.header_limit = return_limit(optarg[0]);
state.number_limit = return_limit(optarg[1]);
break;
case OPT_MUSTACH:
#ifdef BUILD_MUSTACH
config.mustach_template = optarg;
state.mustach_template = optarg;
output_format = 'm';
#else
error(EXIT_FAILURE, 0, "compiled without mustach support");
#endif
break;
case OPT_COLOR:
config.color_mode = parse_color_mode(optarg);
if (config.color_mode == color_unknown)
state.color_mode = parse_color_mode(optarg);
if (state.color_mode == color_unknown)
error(EXIT_FAILURE, errno, "unknown color mode: %s", quote(optarg));
break;
case OPT_SKIP_OK:
config.skip_ok = 1;
state.skip_ok = 1;
break;
case OPT_SNET_ALARMS:
config.snet_alarms = 1;
state.snet_alarms = 1;
break;
case OPT_WARN:
alarming = 1;
config.warning = strtod_or_err(optarg, "illegal argument");
state.warning = strtod_or_err(optarg, "illegal argument");
break;
case OPT_CRIT:
alarming = 1;
config.critical = strtod_or_err(optarg, "illegal argument");
state.critical = strtod_or_err(optarg, "illegal argument");
break;
case OPT_WARN_COUNT:
alarming = 1;
config.warn_count = strtod_or_err(optarg, "illegal argument");
state.warn_count = strtod_or_err(optarg, "illegal argument");
break;
case OPT_CRIT_COUNT:
alarming = 1;
config.crit_count = strtod_or_err(optarg, "illegal argument");
state.crit_count = strtod_or_err(optarg, "illegal argument");
break;
case OPT_MINSIZE:
config.minsize = strtod_or_err(optarg, "illegal argument");
state.minsize = strtod_or_err(optarg, "illegal argument");
break;
case OPT_SET_IPV:
switch(optarg[0]) {
case '4':
set_ipv_functions(IPv4);
set_ipv_functions(&state, IPv4);
break;
case '6':
set_ipv_functions(IPv6);
set_ipv_functions(&state, IPv6);
break;
default:
error(EXIT_FAILURE, 0, "unknown --ip-version argument: %s", optarg);
@ -278,11 +263,11 @@ int main(int argc, char **argv)
break;
case 'p':
/* Print additional performance data in alarming mode */
config.perfdata = 1;
state.perfdata = 1;
break;
case 'A':
/* Treat single networks as shared with network CIDR as name */
config.all_as_shared = 1;
state.all_as_shared = 1;
break;
case 'v':
/* Print version */
@ -295,48 +280,45 @@ int main(int argc, char **argv)
program_name);
}
}
/* Use default dhcpd.conf when user did not define anything. */
if (state.dhcpdconf_file == NULL)
state.dhcpdconf_file = DHCPDCONF_FILE;
/* Use default dhcpd.leases when user did not define anything. */
if (state.dhcpdlease_file == NULL)
state.dhcpdlease_file = DHCPDLEASE_FILE;
/* Use default limits when user did not define anything. */
if (state.header_limit == 8) {
char const *default_limit = OUTPUT_LIMIT;
state.header_limit = return_limit(default_limit[0]);
state.number_limit = return_limit(default_limit[1]);
}
/* Output format is not defined, if alarm thresholds are then it's
* alarming, else use the default. */
if (output_format == '\0') {
if (alarming == 1)
output_format = 'a';
else {
const char *const def = OUTPUT_FORMAT;
output_format = def[0];
const char *const default_format = OUTPUT_FORMAT;
output_format = default_format[0];
}
}
/* Do the job */
parse_config(1, config.dhcpdconf_file, shared_networks);
parse_config(&state, 1, state.dhcpdconf_file, state.shared_networks);
if (output_format == 'X' || output_format == 'J')
parse_leases(1);
parse_leases(&state, 1);
else
parse_leases(0);
prepare_data();
do_counting();
tmp_ranges = xmalloc(sizeof(struct range_t) * num_ranges);
if (config.sorts != NULL)
mergesort_ranges(ranges, num_ranges, tmp_ranges);
if (config.reverse_order == 1)
flip_ranges(ranges, tmp_ranges);
free(tmp_ranges);
ret_val = output_analysis(output_format);
clean_up();
parse_leases(&state, 0);
prepare_data(&state);
do_counting(&state);
if (state.sorts != NULL)
mergesort_ranges(&state, state.ranges, state.num_ranges, NULL, 1);
if (state.reverse_order == 1)
flip_ranges(&state);
ret_val = output_analysis(&state, output_format);
clean_up(&state);
return (ret_val);
}
/*! \brief Run time initialization. Global allocations, counter
* initializations, etc are here. */
void prepare_memory(void)
{
config.ip_version = IPvUNKNOWN;
RANGES = 64;
num_ranges = num_shared_networks = 0;
shared_networks = xmalloc(sizeof(struct shared_network_t) * SHARED_NETWORKS);
ranges = xmalloc(sizeof(struct range_t) * RANGES);
/* First shared network entry is all networks */
shared_networks->name = xstrdup("All networks");
shared_networks->used = 0;
shared_networks->touched = 0;
shared_networks->backups = 0;
config.sorts = NULL;
}