mirror of
git://git.code.sf.net/p/dhcpd-pools/code
synced 2025-12-16 15:57:00 +00:00
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:
parent
adda925c1e
commit
1875a13733
12 changed files with 551 additions and 626 deletions
1
src/.indent.pro
vendored
1
src/.indent.pro
vendored
|
|
@ -1,5 +1,6 @@
|
|||
-linux
|
||||
-TFILE
|
||||
-Tconf_t
|
||||
-Tipaddr_t
|
||||
-Tleases_t
|
||||
-Toff_t
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ dhcpd_pools_LDADD = $(top_builddir)/lib/libdhcpd_pools.la
|
|||
|
||||
dhcpd_pools_SOURCES = \
|
||||
src/analyze.c \
|
||||
src/defaults.h \
|
||||
src/dhcpd-pools.c \
|
||||
src/dhcpd-pools.h \
|
||||
src/getdata.c \
|
||||
|
|
|
|||
|
|
@ -47,28 +47,27 @@
|
|||
|
||||
/*! \brief Prepare data for analysis. The function will sort leases and
|
||||
* ranges. */
|
||||
void prepare_data(void)
|
||||
void prepare_data(struct conf_t *state)
|
||||
{
|
||||
/* Sort leases */
|
||||
HASH_SORT(leases, leasecomp);
|
||||
HASH_SORT(state->leases, leasecomp);
|
||||
/* Sort ranges */
|
||||
qsort(ranges, (size_t)num_ranges, sizeof(struct range_t), &rangecomp);
|
||||
qsort(state->ranges, state->num_ranges, sizeof(struct range_t), &rangecomp);
|
||||
}
|
||||
|
||||
/*! \brief Perform counting. Join leases with ranges, and update counters. */
|
||||
void do_counting(void)
|
||||
void do_counting(struct conf_t *state)
|
||||
{
|
||||
struct range_t *restrict range_p;
|
||||
const struct leases_t *restrict l = leases;
|
||||
struct range_t *restrict range_p = state->ranges;
|
||||
const struct leases_t *restrict l = state->leases;
|
||||
unsigned long i, k, block_size;
|
||||
|
||||
/* Walk through ranges */
|
||||
range_p = ranges;
|
||||
for (i = 0; i < num_ranges; i++) {
|
||||
for (i = 0; i < state->num_ranges; i++) {
|
||||
while (l != NULL && ipcomp(&range_p->first_ip, &l->ip) < 0)
|
||||
l = l->hh.prev; /* rewind */
|
||||
if (l == NULL)
|
||||
l = leases;
|
||||
l = state->leases;
|
||||
for (; l != NULL && ipcomp(&l->ip, &range_p->last_ip) <= 0; l = l->hh.next) {
|
||||
if (ipcomp(&l->ip, &range_p->first_ip) < 0)
|
||||
continue; /* cannot happen? */
|
||||
|
|
@ -107,15 +106,15 @@ void do_counting(void)
|
|||
/* FIXME: During count of other shared networks default network
|
||||
* and all networks got mixed together semantically. The below
|
||||
* fixes the problem, but is not elegant. */
|
||||
shared_networks->available = 0;
|
||||
shared_networks->used = 0;
|
||||
shared_networks->touched = 0;
|
||||
range_p = ranges;
|
||||
for (k = 0; k < num_ranges; k++) {
|
||||
shared_networks->available += get_range_size(range_p);
|
||||
shared_networks->used += range_p->count;
|
||||
shared_networks->touched += range_p->touched;
|
||||
shared_networks->backups += range_p->backups;
|
||||
state->shared_networks->available = 0;
|
||||
state->shared_networks->used = 0;
|
||||
state->shared_networks->touched = 0;
|
||||
range_p = state->ranges;
|
||||
for (k = 0; k < state->num_ranges; k++) {
|
||||
state->shared_networks->available += get_range_size(range_p);
|
||||
state->shared_networks->used += range_p->count;
|
||||
state->shared_networks->touched += range_p->touched;
|
||||
state->shared_networks->backups += range_p->backups;
|
||||
range_p++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* The dhcpd-pools has BSD 2-clause license which also known as "Simplified
|
||||
* BSD License" or "FreeBSD License".
|
||||
*
|
||||
* Copyright 2006- Sami Kerola. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are
|
||||
* those of the authors and should not be interpreted as representing
|
||||
* official policies, either expressed or implied, of Sami Kerola.
|
||||
*/
|
||||
|
||||
/*! \file defaults.h
|
||||
* \brief Default settings which cannot be changed without recompiling
|
||||
* the software.
|
||||
*/
|
||||
|
||||
#ifndef DHCPD_POOLS_DEFAULTS_H
|
||||
# define DHCPD_POOLS_DEFAULTS_H 1
|
||||
|
||||
# include "dhcpd-pools.h"
|
||||
|
||||
/*! \var MAXLEN
|
||||
* \brief Maximum expected line length in dhcpd.conf and dhcpd.leases
|
||||
* files. */
|
||||
static const size_t MAXLEN = 1024;
|
||||
|
||||
/*! \var SHARED_NETWORKS
|
||||
* \brief Maximum number of different shared networks in dhcpd.conf file. */
|
||||
static const unsigned int SHARED_NETWORKS = 8192;
|
||||
|
||||
#endif /* DHCPD_POOLS_DEFAULTS_H */
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,8 +35,6 @@
|
|||
|
||||
/*! \file dhcpd-pools.h
|
||||
* \brief Global definitions of structures, enums, and function prototypes.
|
||||
* FIXME: The file has too many global variables. Most of them should be
|
||||
* removed, if not all.
|
||||
*/
|
||||
|
||||
#ifndef DHCPD_POOLS_H
|
||||
|
|
@ -76,6 +74,17 @@ union ipaddr_t {
|
|||
uint32_t v4;
|
||||
unsigned char v6[16];
|
||||
};
|
||||
|
||||
/*! \enum dhcpd_magic_numbers
|
||||
* \brief MAXLEN is maximum expected line length in dhcpd.conf and
|
||||
* dhcpd.leases, and SHARED_NETWORKS is maximum number of different shared
|
||||
* networks in dhcpd.conf file.
|
||||
*/
|
||||
enum dhcpd_magic_numbers {
|
||||
MAXLEN = 1024,
|
||||
SHARED_NETWORKS = 8192
|
||||
};
|
||||
|
||||
/*! \enum dhcp_version
|
||||
* \brief The IP version, IPv4 or IPv6, served by the dhcpd.
|
||||
*/
|
||||
|
|
@ -214,18 +223,24 @@ struct output_sort {
|
|||
comparer_t func;
|
||||
struct output_sort *next;
|
||||
};
|
||||
/*! \struct configuration_t
|
||||
* \brief Runtime configuration.
|
||||
/*! \struct conf_t
|
||||
* \brief Runtime configuration state.
|
||||
*/
|
||||
struct configuration_t {
|
||||
struct conf_t {
|
||||
struct shared_network_t *shared_networks;
|
||||
unsigned int num_shared_networks;
|
||||
struct range_t *ranges;
|
||||
unsigned int num_ranges;
|
||||
size_t ranges_size;
|
||||
struct leases_t *leases;
|
||||
char dhcpv6;
|
||||
enum dhcp_version ip_version;
|
||||
char *dhcpdconf_file;
|
||||
char *dhcpdlease_file;
|
||||
int output_format;
|
||||
const char *dhcpdconf_file;
|
||||
const char *dhcpdlease_file;
|
||||
const int output_format;
|
||||
struct output_sort *sorts;
|
||||
char *output_file;
|
||||
char *mustach_template;
|
||||
const char *output_file;
|
||||
const char *mustach_template;
|
||||
double warning;
|
||||
double critical;
|
||||
double warn_count;
|
||||
|
|
@ -237,50 +252,67 @@ struct configuration_t {
|
|||
snet_alarms:1,
|
||||
perfdata:1,
|
||||
all_as_shared:1,
|
||||
header_limit:3,
|
||||
header_limit:4,
|
||||
number_limit:3,
|
||||
skip_ok:1,
|
||||
color_mode:2;
|
||||
};
|
||||
|
||||
/* Global variables */
|
||||
/* \var config Runtime configuration. */
|
||||
extern struct configuration_t config;
|
||||
/* \var shared_networks Pointer holding shared network count results. */
|
||||
extern struct shared_network_t *shared_networks;
|
||||
/* \var num_shared_networks Number of shared networks found. */
|
||||
extern unsigned int num_shared_networks;
|
||||
/* \var ranges Pointer holding range count results. */
|
||||
extern struct range_t *ranges;
|
||||
/* \var num_ranges Number of ranges found. */
|
||||
extern unsigned int num_ranges;
|
||||
/* \var leases Pointer holding all leases. */
|
||||
extern struct leases_t *leases;
|
||||
/*! \var RANGES Maximum number of ranges. */
|
||||
extern unsigned int RANGES;
|
||||
|
||||
/* Function prototypes */
|
||||
extern void prepare_memory(void);
|
||||
extern void set_ipv_functions(int version);
|
||||
extern int parse_leases(const int print_mac_addreses);
|
||||
extern void parse_config(int, const char *restrict, struct shared_network_t *restrict)
|
||||
__attribute__ ((nonnull(2, 3)));
|
||||
extern void prepare_data(void);
|
||||
extern void do_counting(void);
|
||||
extern void flip_ranges(struct range_t *restrict flip_me, struct range_t *restrict tmp_ranges)
|
||||
__attribute__ ((nonnull(1, 2)));
|
||||
/* support functions */
|
||||
extern int (*parse_ipaddr) (const char *restrict src, union ipaddr_t *restrict dst);
|
||||
extern int parse_ipaddr_init(const char *restrict src,
|
||||
union ipaddr_t *restrict dst);
|
||||
extern int parse_ipaddr_v4(const char *restrict src, union ipaddr_t *restrict dst);
|
||||
extern int parse_ipaddr_v6(const char *restrict src, union ipaddr_t *restrict dst);
|
||||
|
||||
extern void parse_cidr(struct range_t *range_p, const char *word);
|
||||
/* analyze.c */
|
||||
extern void prepare_data(struct conf_t *state);
|
||||
extern void do_counting(struct conf_t *state);
|
||||
|
||||
/* getdata.c */
|
||||
extern int parse_leases(struct conf_t *state, const int print_mac_addreses);
|
||||
extern void parse_config(struct conf_t *state, const int is_include,
|
||||
const char *restrict config_file,
|
||||
struct shared_network_t *restrict shared_p);
|
||||
|
||||
/* hash.c */
|
||||
extern void (*add_lease) (struct conf_t *state, union ipaddr_t *addr, enum ltype type);
|
||||
extern void add_lease_init(struct conf_t *state, union ipaddr_t *addr, enum ltype type);
|
||||
extern void add_lease_v4(struct conf_t *state, union ipaddr_t *addr, enum ltype type);
|
||||
extern void add_lease_v6(struct conf_t *state, union ipaddr_t *addr, enum ltype type);
|
||||
|
||||
extern struct leases_t *(*find_lease) (struct conf_t *state, union ipaddr_t *addr);
|
||||
extern struct leases_t *find_lease_init(struct conf_t *state, union ipaddr_t *addr);
|
||||
extern struct leases_t *find_lease_v4(struct conf_t *state, union ipaddr_t *addr);
|
||||
extern struct leases_t *find_lease_v6(struct conf_t *state, union ipaddr_t *addr);
|
||||
|
||||
extern void delete_lease(struct conf_t *state, struct leases_t *lease);
|
||||
extern void delete_all_leases(struct conf_t *state);
|
||||
|
||||
/* mustach-dhcpd-pools.c */
|
||||
extern int mustach_dhcpd_pools(struct conf_t *state);
|
||||
|
||||
/* other.c */
|
||||
extern void set_ipv_functions(struct conf_t *state, int version);
|
||||
extern void flip_ranges(struct conf_t *state);
|
||||
extern void clean_up(struct conf_t *state);
|
||||
extern void parse_cidr(struct conf_t *state, struct range_t *range_p, const char *word);
|
||||
extern int parse_color_mode(const char *restrict optarg);
|
||||
extern double strtod_or_err(const char *restrict str, const char *restrict errmesg);
|
||||
extern void __attribute__ ((noreturn)) print_version(void);
|
||||
extern void __attribute__ ((noreturn)) usage(int status);
|
||||
|
||||
extern int (*parse_ipaddr) (struct conf_t *state, const char *restrict src,
|
||||
union ipaddr_t *restrict dst);
|
||||
extern int parse_ipaddr_init(struct conf_t *state, const char *restrict src,
|
||||
union ipaddr_t *restrict dst);
|
||||
extern int parse_ipaddr_v4(struct conf_t *state, const char *restrict src,
|
||||
union ipaddr_t *restrict dst);
|
||||
extern int parse_ipaddr_v6(struct conf_t *state, const char *restrict src,
|
||||
union ipaddr_t *restrict dst);
|
||||
|
||||
extern int (*xstrstr) (struct conf_t *state, const char *restrict str);
|
||||
extern int xstrstr_init(struct conf_t *state, const char *restrict str);
|
||||
extern int xstrstr_v4(struct conf_t *state, const char *restrict str);
|
||||
extern int xstrstr_v6(struct conf_t *state, const char *restrict str);
|
||||
|
||||
extern void (*copy_ipaddr) (union ipaddr_t *restrict dst, const union ipaddr_t *restrict src);
|
||||
extern void copy_ipaddr_init(union ipaddr_t *restrict dst,
|
||||
const union ipaddr_t *restrict src);
|
||||
extern void copy_ipaddr_init(union ipaddr_t *restrict dst, const union ipaddr_t *restrict src);
|
||||
extern void copy_ipaddr_v4(union ipaddr_t *restrict dst, const union ipaddr_t *restrict src);
|
||||
extern void copy_ipaddr_v6(union ipaddr_t *restrict dst, const union ipaddr_t *restrict src);
|
||||
|
||||
|
|
@ -294,26 +326,17 @@ extern double get_range_size_init(const struct range_t *r);
|
|||
extern double get_range_size_v4(const struct range_t *r);
|
||||
extern double get_range_size_v6(const struct range_t *r);
|
||||
|
||||
extern int (*xstrstr) (const char *restrict str);
|
||||
extern int xstrstr_init(const char *restrict str);
|
||||
extern int xstrstr_v4(const char *restrict str)
|
||||
_DP_ATTRIBUTE_HOT;
|
||||
extern int xstrstr_v6(const char *restrict str)
|
||||
_DP_ATTRIBUTE_HOT;
|
||||
/* output.c */
|
||||
extern void range_output_helper(struct conf_t *state, struct output_helper_t *oh,
|
||||
struct range_t *range_p);
|
||||
extern void shnet_output_helper(struct conf_t *state, struct output_helper_t *oh,
|
||||
struct shared_network_t *shared_p);
|
||||
extern int output_analysis(struct conf_t *state, const char output_format);
|
||||
|
||||
extern int parse_color_mode(const char *restrict optarg);
|
||||
extern double strtod_or_err(const char *restrict str, const char *restrict errmesg);
|
||||
extern void __attribute__ ((noreturn)) print_version(void);
|
||||
extern void __attribute__ ((noreturn)) usage(int status);
|
||||
/* qsort required functions... */
|
||||
/* ...for ranges and... */
|
||||
extern int (*ipcomp) (const union ipaddr_t *restrict a, const union ipaddr_t *restrict b);
|
||||
extern int ipcomp_init(const union ipaddr_t *restrict a,
|
||||
const union ipaddr_t *restrict b);
|
||||
extern int ipcomp_v4(const union ipaddr_t *restrict a,
|
||||
const union ipaddr_t *restrict b);
|
||||
extern int ipcomp_v6(const union ipaddr_t *restrict a,
|
||||
const union ipaddr_t *restrict b);
|
||||
/* sort.c */
|
||||
extern void mergesort_ranges(struct conf_t *state,
|
||||
struct range_t *restrict orig, unsigned int size,
|
||||
struct range_t *restrict temp, const int root_call);
|
||||
|
||||
extern int (*leasecomp) (const struct leases_t *restrict a, const struct leases_t *restrict b);
|
||||
extern int leasecomp_init(const struct leases_t *restrict a
|
||||
|
|
@ -322,6 +345,14 @@ extern int leasecomp_init(const struct leases_t *restrict a
|
|||
extern int leasecomp_v4(const struct leases_t *restrict a, const struct leases_t *restrict b);
|
||||
extern int leasecomp_v6(const struct leases_t *restrict a, const struct leases_t *restrict b);
|
||||
|
||||
extern int (*ipcomp) (const union ipaddr_t *restrict a, const union ipaddr_t *restrict b);
|
||||
extern int ipcomp_init(const union ipaddr_t *restrict a, const union ipaddr_t *restrict b);
|
||||
extern int ipcomp_v4(const union ipaddr_t *restrict a, const union ipaddr_t *restrict b);
|
||||
extern int ipcomp_v6(const union ipaddr_t *restrict a, const union ipaddr_t *restrict b);
|
||||
|
||||
extern int rangecomp(const void *restrict r1, const void *restrict r2)
|
||||
__attribute__ ((nonnull(1, 2)));
|
||||
|
||||
extern int comp_cur(struct range_t *r1, struct range_t *r2);
|
||||
extern int comp_double(double f1, double f2);
|
||||
extern int comp_ip(struct range_t *r1, struct range_t *r2);
|
||||
|
|
@ -330,35 +361,10 @@ extern int comp_percent(struct range_t *r1, struct range_t *r2);
|
|||
extern int comp_tc(struct range_t *r1, struct range_t *r2);
|
||||
extern int comp_tcperc(struct range_t *r1, struct range_t *r2);
|
||||
extern int comp_touched(struct range_t *r1, struct range_t *r2);
|
||||
extern int rangecomp(const void *restrict r1, const void *restrict r2)
|
||||
__attribute__ ((nonnull(1, 2)));
|
||||
/* sort function pointer and functions */
|
||||
|
||||
extern comparer_t field_selector(char c);
|
||||
extern double ret_percent(struct range_t r);
|
||||
extern double ret_tc(struct range_t r);
|
||||
extern double ret_tcperc(struct range_t r);
|
||||
extern void mergesort_ranges(struct range_t *restrict orig, int size,
|
||||
struct range_t *restrict temp)
|
||||
__attribute__ ((nonnull(1, 3)));
|
||||
/* output function */
|
||||
extern void range_output_helper(struct output_helper_t *oh, struct range_t *range_p);
|
||||
extern void shnet_output_helper(struct output_helper_t *oh, struct shared_network_t *shared_p);
|
||||
extern int output_analysis(const char);
|
||||
extern int mustach_dhcpd_pools(void);
|
||||
/* Memory release, file closing etc */
|
||||
extern void clean_up(void);
|
||||
/* Hash functions */
|
||||
extern void (*add_lease) (union ipaddr_t *addr, enum ltype type);
|
||||
extern void add_lease_init(union ipaddr_t *addr, enum ltype type);
|
||||
extern void add_lease_v4(union ipaddr_t *addr, enum ltype type);
|
||||
extern void add_lease_v6(union ipaddr_t *addr, enum ltype type);
|
||||
|
||||
extern struct leases_t *(*find_lease) (union ipaddr_t *addr);
|
||||
extern struct leases_t *find_lease_init(union ipaddr_t *addr);
|
||||
extern struct leases_t *find_lease_v4(union ipaddr_t *addr);
|
||||
extern struct leases_t *find_lease_v6(union ipaddr_t *addr);
|
||||
|
||||
extern void delete_lease(struct leases_t *lease);
|
||||
extern void delete_all_leases(void);
|
||||
|
||||
#endif /* DHCPD_POOLS_H */
|
||||
#endif /* DHCPD_POOLS_H */
|
||||
|
|
|
|||
|
|
@ -54,11 +54,10 @@
|
|||
#include "xalloc.h"
|
||||
|
||||
#include "dhcpd-pools.h"
|
||||
#include "defaults.h"
|
||||
|
||||
/*! \brief Lease file parser. The parser can only read ISC DHCPD
|
||||
* dhcpd.leases file format. */
|
||||
int parse_leases(const int print_mac_addreses)
|
||||
int parse_leases(struct conf_t *state, const int print_mac_addreses)
|
||||
{
|
||||
FILE *dhcpd_leases;
|
||||
char *line, *ipstring, macstring[20], *stop;
|
||||
|
|
@ -66,68 +65,68 @@ int parse_leases(const int print_mac_addreses)
|
|||
struct stat lease_file_stats;
|
||||
struct leases_t *lease;
|
||||
|
||||
dhcpd_leases = fopen(config.dhcpdlease_file, "r");
|
||||
dhcpd_leases = fopen(state->dhcpdlease_file, "r");
|
||||
if (dhcpd_leases == NULL)
|
||||
error(EXIT_FAILURE, errno, "parse_leases: %s", config.dhcpdlease_file);
|
||||
error(EXIT_FAILURE, errno, "parse_leases: %s", state->dhcpdlease_file);
|
||||
#ifdef HAVE_POSIX_FADVISE
|
||||
# ifdef POSIX_FADV_SEQUENTIAL
|
||||
if (posix_fadvise(fileno(dhcpd_leases), 0, 0, POSIX_FADV_SEQUENTIAL) != 0)
|
||||
error(EXIT_FAILURE, errno, "parse_leases: fadvise %s", config.dhcpdlease_file);
|
||||
error(EXIT_FAILURE, errno, "parse_leases: fadvise %s", state->dhcpdlease_file);
|
||||
# endif /* POSIX_FADV_SEQUENTIAL */
|
||||
#endif /* HAVE_POSIX_FADVISE */
|
||||
/* I found out that there's one lease address per 300 bytes in
|
||||
* dhcpd.leases file. Malloc is little bit pessimistic and uses 250.
|
||||
* If someone has higher density in lease file I'm interested to
|
||||
* hear about that. */
|
||||
if (stat(config.dhcpdlease_file, &lease_file_stats))
|
||||
error(EXIT_FAILURE, errno, "parse_leases: %s", config.dhcpdlease_file);
|
||||
if (stat(state->dhcpdlease_file, &lease_file_stats))
|
||||
error(EXIT_FAILURE, errno, "parse_leases: %s", state->dhcpdlease_file);
|
||||
line = xmalloc(sizeof(char) * MAXLEN);
|
||||
line[0] = '\0';
|
||||
ipstring = xmalloc(sizeof(char) * MAXLEN);
|
||||
ipstring[0] = '\0';
|
||||
while (!feof(dhcpd_leases)) {
|
||||
if (!fgets(line, MAXLEN, dhcpd_leases) && ferror(dhcpd_leases))
|
||||
error(EXIT_FAILURE, errno, "parse_leases: %s", config.dhcpdlease_file);
|
||||
switch (xstrstr(line)) {
|
||||
error(EXIT_FAILURE, errno, "parse_leases: %s", state->dhcpdlease_file);
|
||||
switch (xstrstr(state, line)) {
|
||||
/* It's a lease, save IP */
|
||||
case PREFIX_LEASE:
|
||||
stop =
|
||||
memccpy(ipstring,
|
||||
line + (config.ip_version ==
|
||||
line + (state->ip_version ==
|
||||
IPv4 ? 6 : 9), ' ', strlen(line));
|
||||
if (stop != NULL) {
|
||||
--stop;
|
||||
*stop = '\0';
|
||||
}
|
||||
parse_ipaddr(ipstring, &addr);
|
||||
parse_ipaddr(state, ipstring, &addr);
|
||||
break;
|
||||
case PREFIX_BINDING_STATE_FREE:
|
||||
case PREFIX_BINDING_STATE_ABANDONED:
|
||||
case PREFIX_BINDING_STATE_EXPIRED:
|
||||
case PREFIX_BINDING_STATE_RELEASED:
|
||||
if ((lease = find_lease(&addr)) != NULL)
|
||||
delete_lease(lease);
|
||||
add_lease(&addr, FREE);
|
||||
if ((lease = find_lease(state, &addr)) != NULL)
|
||||
delete_lease(state, lease);
|
||||
add_lease(state, &addr, FREE);
|
||||
break;
|
||||
case PREFIX_BINDING_STATE_ACTIVE:
|
||||
/* remove old entry, if exists */
|
||||
if ((lease = find_lease(&addr)) != NULL)
|
||||
delete_lease(lease);
|
||||
add_lease(&addr, ACTIVE);
|
||||
if ((lease = find_lease(state, &addr)) != NULL)
|
||||
delete_lease(state, lease);
|
||||
add_lease(state, &addr, ACTIVE);
|
||||
break;
|
||||
case PREFIX_BINDING_STATE_BACKUP:
|
||||
/* remove old entry, if exists */
|
||||
if ((lease = find_lease(&addr)) != NULL)
|
||||
delete_lease(lease);
|
||||
add_lease(&addr, BACKUP);
|
||||
config.backups_found = 1;
|
||||
if ((lease = find_lease(state, &addr)) != NULL)
|
||||
delete_lease(state, lease);
|
||||
add_lease(state, &addr, BACKUP);
|
||||
state->backups_found = 1;
|
||||
break;
|
||||
case PREFIX_HARDWARE_ETHERNET:
|
||||
if (print_mac_addreses == 0)
|
||||
break;
|
||||
memcpy(macstring, line + 20, 17);
|
||||
macstring[17] = '\0';
|
||||
if ((lease = find_lease(&addr)) != NULL)
|
||||
if ((lease = find_lease(state, &addr)) != NULL)
|
||||
lease->ethernet = xstrdup(macstring);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -144,13 +143,13 @@ int parse_leases(const int print_mac_addreses)
|
|||
/*! \brief Keyword search in dhcpd.conf file.
|
||||
* \param s A line from the dhcpd.conf file.
|
||||
* \return Indicator what configuration was found. */
|
||||
static int is_interesting_config_clause(char const *restrict s)
|
||||
static int is_interesting_config_clause(struct conf_t *state, char const *restrict s)
|
||||
{
|
||||
if (strstr(s, "range"))
|
||||
return ITS_A_RANGE_FIRST_IP;
|
||||
if (strstr(s, "shared-network"))
|
||||
return ITS_A_SHAREDNET;
|
||||
if (config.all_as_shared) {
|
||||
if (state->all_as_shared) {
|
||||
if (strstr(s, "subnet"))
|
||||
return ITS_A_SUBNET;
|
||||
if (strstr(s, "netmask"))
|
||||
|
|
@ -178,7 +177,7 @@ static void reorder_last_first(struct range_t *range_p)
|
|||
* FIXME: This spaghetti monster function need to be rewrote at least
|
||||
* ones.
|
||||
*/
|
||||
void parse_config(int is_include, const char *restrict config_file,
|
||||
void parse_config(struct conf_t *state, const int is_include, const char *restrict config_file,
|
||||
struct shared_network_t *restrict shared_p)
|
||||
{
|
||||
FILE *dhcpd_config;
|
||||
|
|
@ -193,7 +192,7 @@ void parse_config(int is_include, const char *restrict config_file,
|
|||
word = xmalloc(sizeof(char) * MAXLEN);
|
||||
if (is_include)
|
||||
/* Default place holder for ranges "All networks". */
|
||||
shared_p->name = shared_networks->name;
|
||||
shared_p->name = state->shared_networks->name;
|
||||
/* Open configuration file */
|
||||
dhcpd_config = fopen(config_file, "r");
|
||||
if (dhcpd_config == NULL)
|
||||
|
|
@ -283,7 +282,7 @@ void parse_config(int is_include, const char *restrict config_file,
|
|||
/* FIXME: Using 1000 is lame, but
|
||||
* works. */
|
||||
braces_shared = 1000;
|
||||
shared_p = shared_networks;
|
||||
shared_p = state->shared_networks;
|
||||
}
|
||||
/* Not literally 1, but works for this
|
||||
* program */
|
||||
|
|
@ -321,7 +320,7 @@ void parse_config(int is_include, const char *restrict config_file,
|
|||
if (word[i - 1] != '{')
|
||||
newclause = 0;
|
||||
i = 0;
|
||||
argument = is_interesting_config_clause(word);
|
||||
argument = is_interesting_config_clause(state, word);
|
||||
if (argument == ITS_A_RANGE_FIRST_IP)
|
||||
one_ip_range = 1;
|
||||
}
|
||||
|
|
@ -334,14 +333,14 @@ void parse_config(int is_include, const char *restrict config_file,
|
|||
switch (argument) {
|
||||
case ITS_A_RANGE_SECOND_IP:
|
||||
/* printf ("range 2nd ip: %s\n", word); */
|
||||
range_p = ranges + num_ranges;
|
||||
range_p = state->ranges + state->num_ranges;
|
||||
argument = ITS_NOTHING_INTERESTING;
|
||||
if (strchr(word, '/')) {
|
||||
parse_cidr(range_p, word);
|
||||
parse_cidr(state, range_p, word);
|
||||
one_ip_range = 0;
|
||||
} else {
|
||||
/* not cidr */
|
||||
parse_ipaddr(word, &addr);
|
||||
parse_ipaddr(state, word, &addr);
|
||||
if (one_ip_range == 1) {
|
||||
one_ip_range = 0;
|
||||
copy_ipaddr(&range_p->first_ip, &addr);
|
||||
|
|
@ -354,18 +353,18 @@ void parse_config(int is_include, const char *restrict config_file,
|
|||
range_p->touched = 0;
|
||||
range_p->backups = 0;
|
||||
range_p->shared_net = shared_p;
|
||||
num_ranges++;
|
||||
if (RANGES < num_ranges + 1) {
|
||||
RANGES *= 2;
|
||||
ranges = xrealloc(ranges, sizeof(struct range_t) * RANGES);
|
||||
range_p = ranges + num_ranges;
|
||||
state->num_ranges++;
|
||||
if (state->ranges_size <= state->num_ranges) {
|
||||
state->ranges_size *= 2;
|
||||
state->ranges = xrealloc(state->ranges, sizeof(struct range_t) * state->ranges_size);
|
||||
range_p = state->ranges + state->num_ranges;
|
||||
}
|
||||
newclause = 1;
|
||||
break;
|
||||
case ITS_A_RANGE_FIRST_IP:
|
||||
/* printf ("range 1nd ip: %s\n", word); */
|
||||
range_p = ranges + num_ranges;
|
||||
if (!(parse_ipaddr(word, &addr)))
|
||||
range_p = state->ranges + state->num_ranges;
|
||||
if (!(parse_ipaddr(state, word, &addr)))
|
||||
/* word was not ip, try again */
|
||||
break;
|
||||
copy_ipaddr(&range_p->first_ip, &addr);
|
||||
|
|
@ -375,23 +374,19 @@ void parse_config(int is_include, const char *restrict config_file,
|
|||
case ITS_A_SHAREDNET:
|
||||
case ITS_A_SUBNET:
|
||||
/* ignore subnets inside a shared-network */
|
||||
if (argument == ITS_A_SUBNET && shared_p != shared_networks) {
|
||||
if (argument == ITS_A_SUBNET && shared_p != state->shared_networks) {
|
||||
argument = ITS_NOTHING_INTERESTING;
|
||||
break;
|
||||
}
|
||||
/* printf ("shared-network named: %s\n", word); */
|
||||
num_shared_networks++;
|
||||
shared_p = shared_networks + num_shared_networks;
|
||||
state->num_shared_networks++;
|
||||
shared_p = state->shared_networks + state->num_shared_networks;
|
||||
shared_p->name = xstrdup(word);
|
||||
shared_p->available = 0;
|
||||
shared_p->used = 0;
|
||||
shared_p->touched = 0;
|
||||
shared_p->backups = 0;
|
||||
shared_p->netmask = (argument == ITS_A_SUBNET ? -1 : 0); /* do not fill in netmask */
|
||||
if (SHARED_NETWORKS < num_shared_networks + 2)
|
||||
if (SHARED_NETWORKS < state->num_shared_networks + 2)
|
||||
/* FIXME: make this to go away by reallocating more space. */
|
||||
error(EXIT_FAILURE, 0,
|
||||
"parse_config: increase default.h SHARED_NETWORKS and recompile");
|
||||
"parse_config: increase SHARED_NETWORKS in dhcpd-pools.h and recompile");
|
||||
/* record network's mask too */
|
||||
if (argument == ITS_A_SUBNET)
|
||||
newclause = 1;
|
||||
|
|
@ -401,7 +396,7 @@ void parse_config(int is_include, const char *restrict config_file,
|
|||
case ITS_A_NETMASK:
|
||||
/* fill in only when requested to do so */
|
||||
if (shared_p->netmask) {
|
||||
if (!(parse_ipaddr(word, &addr)))
|
||||
if (!(parse_ipaddr(state, word, &addr)))
|
||||
break;
|
||||
shared_p->netmask = 32;
|
||||
while ((addr.v4 & 0x01) == 0) {
|
||||
|
|
@ -419,7 +414,7 @@ void parse_config(int is_include, const char *restrict config_file,
|
|||
case ITS_AN_INCLUDE:
|
||||
/* printf ("include file: %s\n", word); */
|
||||
argument = ITS_NOTHING_INTERESTING;
|
||||
parse_config(0, word, shared_p);
|
||||
parse_config(state, 0, word, shared_p);
|
||||
newclause = 1;
|
||||
break;
|
||||
case ITS_NOTHING_INTERESTING:
|
||||
|
|
|
|||
36
src/hash.c
36
src/hash.c
|
|
@ -50,30 +50,30 @@
|
|||
/*! \brief Add a lease to hash array.
|
||||
* \param addr Binary IP to be added in leases hash.
|
||||
* \param type Lease state of the IP. */
|
||||
void add_lease_init(union ipaddr_t *addr
|
||||
void add_lease_init(struct conf_t *state __attribute__ ((unused)), union ipaddr_t *addr
|
||||
__attribute__ ((unused)), enum ltype type __attribute__ ((unused)))
|
||||
{
|
||||
}
|
||||
|
||||
void add_lease_v4(union ipaddr_t *addr, enum ltype type)
|
||||
void add_lease_v4(struct conf_t *state, union ipaddr_t *addr, enum ltype type)
|
||||
{
|
||||
struct leases_t *l;
|
||||
|
||||
l = xmalloc(sizeof(struct leases_t));
|
||||
copy_ipaddr(&l->ip, addr);
|
||||
l->type = type;
|
||||
HASH_ADD_INT(leases, ip.v4, l);
|
||||
HASH_ADD_INT(state->leases, ip.v4, l);
|
||||
l->ethernet = NULL;
|
||||
}
|
||||
|
||||
void add_lease_v6(union ipaddr_t *addr, enum ltype type)
|
||||
void add_lease_v6(struct conf_t *state, union ipaddr_t *addr, enum ltype type)
|
||||
{
|
||||
struct leases_t *l;
|
||||
|
||||
l = xmalloc(sizeof(struct leases_t));
|
||||
copy_ipaddr(&l->ip, addr);
|
||||
l->type = type;
|
||||
HASH_ADD_V6(leases, ip.v6, l);
|
||||
HASH_ADD_V6(state->leases, ip.v6, l);
|
||||
l->ethernet = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -81,57 +81,57 @@ void add_lease_v6(union ipaddr_t *addr, enum ltype type)
|
|||
* \param addr Binary IP searched from leases hash.
|
||||
* \return A lease structure about requested IP, or NULL.
|
||||
*/
|
||||
struct leases_t *find_lease_init(union ipaddr_t *addr __attribute__ ((unused)))
|
||||
struct leases_t *find_lease_init(struct conf_t *state __attribute__ ((unused)), union ipaddr_t *addr __attribute__ ((unused)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct leases_t *find_lease_v4(union ipaddr_t *addr)
|
||||
struct leases_t *find_lease_v4(struct conf_t *state, union ipaddr_t *addr)
|
||||
{
|
||||
struct leases_t *l;
|
||||
|
||||
HASH_FIND_INT(leases, &addr->v4, l);
|
||||
HASH_FIND_INT(state->leases, &addr->v4, l);
|
||||
return l;
|
||||
}
|
||||
|
||||
struct leases_t *find_lease_v6(union ipaddr_t *addr)
|
||||
struct leases_t *find_lease_v6(struct conf_t *state, union ipaddr_t *addr)
|
||||
{
|
||||
struct leases_t *l;
|
||||
|
||||
HASH_FIND_V6(leases, &addr->v4, l);
|
||||
HASH_FIND_V6(state->leases, &addr->v4, l);
|
||||
return l;
|
||||
}
|
||||
|
||||
/*! \brief Delete a lease from hash array.
|
||||
* \param lease Pointer to lease hash. */
|
||||
void delete_lease(struct leases_t *lease)
|
||||
void delete_lease(struct conf_t *state, struct leases_t *lease)
|
||||
{
|
||||
free(lease->ethernet);
|
||||
HASH_DEL(leases, lease);
|
||||
HASH_DEL(state->leases, lease);
|
||||
free(lease);
|
||||
}
|
||||
|
||||
/*! \brief Delete all leases from hash array. */
|
||||
#ifdef HASH_ITER
|
||||
void delete_all_leases(void)
|
||||
void delete_all_leases(struct conf_t *state)
|
||||
{
|
||||
struct leases_t *l, *tmp;
|
||||
|
||||
HASH_ITER(hh, leases, l, tmp) {
|
||||
HASH_ITER(hh, state->leases, l, tmp) {
|
||||
free(l->ethernet);
|
||||
HASH_DEL(leases, l);
|
||||
HASH_DEL(state->leases, l);
|
||||
free(l);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void delete_all_leases(void)
|
||||
void delete_all_leases(struct conf_t *state)
|
||||
{
|
||||
while (leases) {
|
||||
struct leases_t *l;
|
||||
|
||||
l = leases;
|
||||
l = state->leases;
|
||||
free(l->ethernet);
|
||||
HASH_DEL(leases, l); /* leases advances to next on delete */
|
||||
HASH_DEL(state->leases, l); /* leases advances to next on delete */
|
||||
free(l);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
#include "xalloc.h"
|
||||
|
||||
struct expl {
|
||||
struct conf_t *state;
|
||||
struct range_t *range_p;
|
||||
struct shared_network_t *shnet_p;
|
||||
struct output_helper_t oh;
|
||||
|
|
@ -130,7 +131,7 @@ static int must_put_range(void *closure, const char *name, int escape
|
|||
fprintf(file, "%g", e->oh.tcp);
|
||||
return 0;
|
||||
}
|
||||
if (config.backups_found == 1) {
|
||||
if (e->state->backups_found == 1) {
|
||||
if (!strcmp(name, "backup_count")) {
|
||||
fprintf(file, "%g", e->range_p->backups);
|
||||
return 0;
|
||||
|
|
@ -184,7 +185,7 @@ static int must_put_shnet(void *closure, const char *name, int escape
|
|||
fprintf(file, "%g", e->oh.tcp);
|
||||
return 0;
|
||||
}
|
||||
if (config.backups_found == 1) {
|
||||
if (e->state->backups_found == 1) {
|
||||
if (!strcmp(name, "backup_count")) {
|
||||
fprintf(file, "%g", e->shnet_p->backups);
|
||||
return 0;
|
||||
|
|
@ -210,8 +211,8 @@ static int must_next_range(void *closure)
|
|||
e->current--;
|
||||
if (e->current <= 0)
|
||||
return 0;
|
||||
range_output_helper(&e->oh, e->range_p);
|
||||
} while (config.skip_ok && e->oh.status == STATUS_OK);
|
||||
range_output_helper(e->state, &e->oh, e->range_p);
|
||||
} while (e->state->skip_ok && e->oh.status == STATUS_OK);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -224,8 +225,8 @@ static int must_next_shnet(void *closure)
|
|||
e->current--;
|
||||
if (e->current <= 0)
|
||||
return 0;
|
||||
shnet_output_helper(&e->oh, e->shnet_p);
|
||||
} while (config.skip_ok && e->oh.status == STATUS_OK);
|
||||
shnet_output_helper(e->state, &e->oh, e->shnet_p);
|
||||
} while (e->state->skip_ok && e->oh.status == STATUS_OK);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -236,8 +237,8 @@ static int must_enter(void *closure, const char *name)
|
|||
if (!strcmp(name, "subnets")) {
|
||||
itf.put = must_put_range;
|
||||
itf.next = must_next_range;
|
||||
e->current = num_ranges + 1;
|
||||
e->range_p = ranges;
|
||||
e->current = e->state->num_ranges + 1;
|
||||
e->range_p = e->state->ranges;
|
||||
/* must_next_range() will skip_ok when needed */
|
||||
e->range_p--;
|
||||
return must_next_range(closure);
|
||||
|
|
@ -245,15 +246,15 @@ static int must_enter(void *closure, const char *name)
|
|||
if (!strcmp(name, "shared-networks")) {
|
||||
itf.put = must_put_shnet;
|
||||
itf.next = must_next_shnet;
|
||||
e->shnet_p = shared_networks;
|
||||
e->current = num_shared_networks + 1;
|
||||
e->shnet_p = e->state->shared_networks;
|
||||
e->current = e->state->num_shared_networks + 1;
|
||||
return must_next_shnet(closure);
|
||||
}
|
||||
if (!strcmp(name, "summary")) {
|
||||
itf.put = must_put_shnet;
|
||||
itf.next = must_next_shnet;
|
||||
e->shnet_p = shared_networks;
|
||||
shnet_output_helper(&e->oh, e->shnet_p);
|
||||
e->shnet_p = e->state->shared_networks;
|
||||
shnet_output_helper(e->state, &e->oh, e->shnet_p);
|
||||
e->current = 1;
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -264,8 +265,8 @@ static int must_leave(void *closure __attribute__ ((unused)))
|
|||
{
|
||||
struct expl *e = closure;
|
||||
|
||||
e->shnet_p = shared_networks;
|
||||
e->range_p = ranges;
|
||||
e->shnet_p = e->state->shared_networks;
|
||||
e->range_p = e->state->ranges;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -289,19 +290,19 @@ static char *must_read_template(const char *filename)
|
|||
}
|
||||
|
||||
|
||||
int mustach_dhcpd_pools(void)
|
||||
int mustach_dhcpd_pools(struct conf_t *state)
|
||||
{
|
||||
struct expl e;
|
||||
struct expl e = { .state = state };
|
||||
char *template;
|
||||
FILE *outfile;
|
||||
int ret;
|
||||
|
||||
template = must_read_template(config.mustach_template);
|
||||
if (config.output_file[0]) {
|
||||
outfile = fopen(config.output_file, "w+");
|
||||
template = must_read_template(state->mustach_template);
|
||||
if (state->output_file) {
|
||||
outfile = fopen(state->output_file, "w+");
|
||||
if (outfile == NULL) {
|
||||
error(EXIT_FAILURE, errno, "mustach_dhcpd_pools: fopen: %s",
|
||||
config.output_file);
|
||||
state->output_file);
|
||||
}
|
||||
} else {
|
||||
outfile = stdout;
|
||||
|
|
|
|||
88
src/other.c
88
src/other.c
|
|
@ -55,7 +55,6 @@
|
|||
#include "xalloc.h"
|
||||
|
||||
#include "dhcpd-pools.h"
|
||||
#include "defaults.h"
|
||||
|
||||
char *(*cidr_last)(union ipaddr_t *restrict addr, const int mask);
|
||||
static char *cidr_last_v4(union ipaddr_t *restrict addr, const int mask);
|
||||
|
|
@ -64,12 +63,12 @@ static char *cidr_last_v6(union ipaddr_t *restrict addr, const int mask);
|
|||
/*! \brief Set function pointers depending on IP version.
|
||||
* \param ip IP version.
|
||||
*/
|
||||
void set_ipv_functions(int version)
|
||||
void set_ipv_functions(struct conf_t *state, int version)
|
||||
{
|
||||
switch (version) {
|
||||
|
||||
case IPv4:
|
||||
config.ip_version = version;
|
||||
state->ip_version = version;
|
||||
add_lease = add_lease_v4;
|
||||
copy_ipaddr = copy_ipaddr_v4;
|
||||
find_lease = find_lease_v4;
|
||||
|
|
@ -83,7 +82,7 @@ void set_ipv_functions(int version)
|
|||
break;
|
||||
|
||||
case IPv6:
|
||||
config.ip_version = version;
|
||||
state->ip_version = version;
|
||||
add_lease = add_lease_v6;
|
||||
copy_ipaddr = copy_ipaddr_v6;
|
||||
find_lease = find_lease_v6;
|
||||
|
|
@ -97,7 +96,7 @@ void set_ipv_functions(int version)
|
|||
break;
|
||||
|
||||
case IPvUNKNOWN:
|
||||
config.ip_version = version;
|
||||
state->ip_version = version;
|
||||
add_lease = add_lease_init;
|
||||
copy_ipaddr = copy_ipaddr_init;
|
||||
find_lease = find_lease_init;
|
||||
|
|
@ -122,21 +121,21 @@ void set_ipv_functions(int version)
|
|||
* \param dst An union which will hold conversion result.
|
||||
* \return Was parsing successful.
|
||||
*/
|
||||
int parse_ipaddr_init(const char *restrict src, union ipaddr_t *restrict dst)
|
||||
int parse_ipaddr_init(struct conf_t *state, const char *restrict src, union ipaddr_t *restrict dst)
|
||||
{
|
||||
struct in_addr addr;
|
||||
struct in6_addr addr6;
|
||||
|
||||
if (inet_aton(src, &addr) == 1)
|
||||
set_ipv_functions(IPv4);
|
||||
set_ipv_functions(state, IPv4);
|
||||
else if (inet_pton(AF_INET6, src, &addr6) == 1)
|
||||
set_ipv_functions(IPv6);
|
||||
set_ipv_functions(state, IPv6);
|
||||
else
|
||||
return 0;
|
||||
return parse_ipaddr(src, dst);
|
||||
return parse_ipaddr(state, src, dst);
|
||||
}
|
||||
|
||||
int parse_ipaddr_v4(const char *restrict src, union ipaddr_t *restrict dst)
|
||||
int parse_ipaddr_v4(struct conf_t *state __attribute__ ((unused)), const char *restrict src, union ipaddr_t *restrict dst)
|
||||
{
|
||||
int rv;
|
||||
struct in_addr addr;
|
||||
|
|
@ -146,7 +145,7 @@ int parse_ipaddr_v4(const char *restrict src, union ipaddr_t *restrict dst)
|
|||
return rv == 1;
|
||||
}
|
||||
|
||||
int parse_ipaddr_v6(const char *restrict src, union ipaddr_t *restrict dst)
|
||||
int parse_ipaddr_v6(struct conf_t *state __attribute__ ((unused)), const char *restrict src, union ipaddr_t *restrict dst)
|
||||
{
|
||||
int rv;
|
||||
struct in6_addr addr;
|
||||
|
|
@ -210,7 +209,7 @@ static char *cidr_last_v6(union ipaddr_t *restrict addr, const int mask)
|
|||
return xstrdup(ip);
|
||||
}
|
||||
|
||||
void parse_cidr(struct range_t *range_p, const char *word)
|
||||
void parse_cidr(struct conf_t *state, struct range_t *range_p, const char *word)
|
||||
{
|
||||
char *divider;
|
||||
int mask;
|
||||
|
|
@ -224,20 +223,20 @@ void parse_cidr(struct range_t *range_p, const char *word)
|
|||
if (mask < 0)
|
||||
error(EXIT_FAILURE, 0, "cidr %s invalid mask %s", word,
|
||||
divider);
|
||||
if (config.ip_version == IPvUNKNOWN) {
|
||||
if (state->ip_version == IPvUNKNOWN) {
|
||||
if (!strchr(word, ':'))
|
||||
set_ipv_functions(IPv4);
|
||||
set_ipv_functions(state, IPv4);
|
||||
else
|
||||
set_ipv_functions(IPv6);
|
||||
set_ipv_functions(state, IPv6);
|
||||
}
|
||||
|
||||
/* start of the range is easy */
|
||||
parse_ipaddr(word, &addr);
|
||||
parse_ipaddr(state, word, &addr);
|
||||
copy_ipaddr(&range_p->first_ip, &addr);
|
||||
|
||||
/* end of the range depends cidr size */
|
||||
last = cidr_last(&addr, mask);
|
||||
parse_ipaddr(last, &addr);
|
||||
parse_ipaddr(state, last, &addr);
|
||||
copy_ipaddr(&range_p->last_ip, &addr);
|
||||
free(last);
|
||||
}
|
||||
|
|
@ -332,18 +331,14 @@ double get_range_size_v6(const struct range_t *r)
|
|||
* \param str A line from dhcpd.conf
|
||||
* \return prefix_t enum value
|
||||
*/
|
||||
int
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
|
||||
__attribute__ ((hot))
|
||||
#endif
|
||||
xstrstr_init(const char *restrict str)
|
||||
int xstrstr_init(struct conf_t *state, const char *restrict str)
|
||||
{
|
||||
if (memcmp("lease ", str, 6)) {
|
||||
set_ipv_functions(IPv4);
|
||||
set_ipv_functions(state, IPv4);
|
||||
return PREFIX_LEASE;
|
||||
}
|
||||
if (memcmp(" iaaddr ", str, 9)) {
|
||||
set_ipv_functions(IPv6);
|
||||
set_ipv_functions(state, IPv6);
|
||||
return PREFIX_LEASE;
|
||||
}
|
||||
return NUM_OF_PREFIX;
|
||||
|
|
@ -359,7 +354,7 @@ int
|
|||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
|
||||
__attribute__ ((hot))
|
||||
#endif
|
||||
xstrstr_v4(const char *restrict str)
|
||||
xstrstr_v4(struct conf_t *state __attribute__ ((unused)), const char *restrict str)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
|
|
@ -412,7 +407,7 @@ int
|
|||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
|
||||
__attribute__ ((hot))
|
||||
#endif
|
||||
xstrstr_v6(const char *restrict str)
|
||||
xstrstr_v6(struct conf_t *state __attribute__ ((unused)), const char *restrict str)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
|
|
@ -495,43 +490,38 @@ double strtod_or_err(const char *restrict str, const char *restrict errmesg)
|
|||
}
|
||||
|
||||
/*! \brief Reverse range.
|
||||
* Used before output, if a caller has requested reverse sorting.
|
||||
* FIXME: The temporary memory area handling should be internal to this
|
||||
* function, not a parameter.
|
||||
*
|
||||
* \param flip_me The range that needs to be inverted.
|
||||
* \param tmp_ranges Temporary memory area for the flip. */
|
||||
void flip_ranges(struct range_t *restrict flip_me, struct range_t *restrict tmp_ranges)
|
||||
* Used before output, if a caller has requested reverse sorting. */
|
||||
void flip_ranges(struct conf_t *state)
|
||||
{
|
||||
unsigned int i = num_ranges - 1, j;
|
||||
unsigned int i = state->num_ranges - 1, j;
|
||||
struct range_t *tmp_ranges;
|
||||
|
||||
for (j = 0; j < num_ranges; j++, i--)
|
||||
*(tmp_ranges + j) = *(flip_me + i);
|
||||
memcpy(flip_me, tmp_ranges, num_ranges * sizeof(struct range_t));
|
||||
tmp_ranges = xmalloc(sizeof(struct range_t) * state->num_ranges);
|
||||
for (j = 0; j < state->num_ranges; j++, i--)
|
||||
*(tmp_ranges + j) = *(state->ranges + i);
|
||||
memcpy(state->ranges, tmp_ranges, state->num_ranges * sizeof(struct range_t));
|
||||
free(tmp_ranges);
|
||||
}
|
||||
|
||||
/*! \brief Free memory, flush buffers etc. */
|
||||
void clean_up(void)
|
||||
void clean_up(struct conf_t *state)
|
||||
{
|
||||
struct output_sort *cur, *next;
|
||||
|
||||
/* Just in case there something in buffers */
|
||||
if (fflush(NULL))
|
||||
error(EXIT_FAILURE, errno, "clean_up: fflush");
|
||||
free(config.dhcpdconf_file);
|
||||
free(config.dhcpdlease_file);
|
||||
free(config.output_file);
|
||||
free(ranges);
|
||||
delete_all_leases();
|
||||
if (shared_networks) {
|
||||
free(state->ranges);
|
||||
delete_all_leases(state);
|
||||
if (state->shared_networks) {
|
||||
unsigned int i;
|
||||
|
||||
num_shared_networks++;
|
||||
for (i = 0; i < num_shared_networks; i++)
|
||||
free((shared_networks + i)->name);
|
||||
free(shared_networks);
|
||||
state->num_shared_networks++;
|
||||
for (i = 0; i < state->num_shared_networks; i++)
|
||||
free((state->shared_networks + i)->name);
|
||||
free(state->shared_networks);
|
||||
}
|
||||
for (cur = config.sorts; cur; cur = next) {
|
||||
for (cur = state->sorts; cur; cur = next) {
|
||||
next = cur->next;
|
||||
free(cur);
|
||||
}
|
||||
|
|
|
|||
398
src/output.c
398
src/output.c
|
|
@ -60,34 +60,34 @@
|
|||
#include "dhcpd-pools.h"
|
||||
|
||||
/*! \brief Calculate range percentages and such. */
|
||||
void range_output_helper(struct output_helper_t *oh, struct range_t *range_p)
|
||||
void range_output_helper(struct conf_t *state, struct output_helper_t *oh, struct range_t *range_p)
|
||||
{
|
||||
/* counts and calculations */
|
||||
oh->range_size = get_range_size(range_p);
|
||||
oh->percent = (double)(100 * range_p->count) / oh->range_size;
|
||||
oh->tc = range_p->touched + range_p->count;
|
||||
oh->tcp = (double)(100 * oh->tc) / oh->range_size;
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
oh->bup = (double)(100 * range_p->backups) / oh->range_size;
|
||||
}
|
||||
/* set status */
|
||||
oh->status = STATUS_OK;
|
||||
if (config.critical < oh->percent
|
||||
&& (oh->range_size - range_p->count) < config.crit_count)
|
||||
if (state->critical < oh->percent
|
||||
&& (oh->range_size - range_p->count) < state->crit_count)
|
||||
oh->status = STATUS_CRIT;
|
||||
else if (config.warning < oh->percent
|
||||
&& (oh->range_size - range_p->count) < config.warn_count)
|
||||
else if (state->warning < oh->percent
|
||||
&& (oh->range_size - range_p->count) < state->warn_count)
|
||||
oh->status = STATUS_WARN;
|
||||
if (oh->status != STATUS_OK) {
|
||||
if (oh->range_size <= config.minsize)
|
||||
if (oh->range_size <= state->minsize)
|
||||
oh->status = STATUS_IGNORED;
|
||||
else if (config.snet_alarms && range_p->shared_net != shared_networks)
|
||||
else if (state->snet_alarms && range_p->shared_net != state->shared_networks)
|
||||
oh->status = STATUS_SUPPRESSED;
|
||||
}
|
||||
}
|
||||
|
||||
/*! \brief Calculate shared network percentages and such. */
|
||||
void shnet_output_helper(struct output_helper_t *oh, struct shared_network_t *shared_p)
|
||||
void shnet_output_helper(struct conf_t *state, struct output_helper_t *oh, struct shared_network_t *shared_p)
|
||||
{
|
||||
/* counts and calculations */
|
||||
oh->tc = shared_p->touched + shared_p->used;
|
||||
|
|
@ -99,7 +99,7 @@ void shnet_output_helper(struct output_helper_t *oh, struct shared_network_t *sh
|
|||
oh->percent = (double)(100 * shared_p->used) / shared_p->available;
|
||||
oh->tcp =
|
||||
(double)((100 * (shared_p->touched + shared_p->used)) / shared_p->available);
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
oh->bup = (double)(100 * shared_p->backups) / shared_p->available;
|
||||
}
|
||||
}
|
||||
|
|
@ -108,15 +108,15 @@ void shnet_output_helper(struct output_helper_t *oh, struct shared_network_t *sh
|
|||
oh->status = STATUS_SUPPRESSED;
|
||||
return;
|
||||
}
|
||||
if (shared_p->available <= config.minsize) {
|
||||
if (shared_p->available <= state->minsize) {
|
||||
oh->status = STATUS_IGNORED;
|
||||
return;
|
||||
}
|
||||
if (config.critical < oh->percent && shared_p->used < config.crit_count) {
|
||||
if (state->critical < oh->percent && shared_p->used < state->crit_count) {
|
||||
oh->status = STATUS_CRIT;
|
||||
return;
|
||||
}
|
||||
if (config.warning < oh->percent && shared_p->used < config.warn_count) {
|
||||
if (state->warning < oh->percent && shared_p->used < state->warn_count) {
|
||||
oh->status = STATUS_WARN;
|
||||
return;
|
||||
}
|
||||
|
|
@ -144,14 +144,14 @@ static int start_color(struct output_helper_t *oh, FILE *outfile)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static FILE *open_outfile(void)
|
||||
static FILE *open_outfile(struct conf_t *state)
|
||||
{
|
||||
FILE *outfile;
|
||||
|
||||
if (config.output_file[0]) {
|
||||
outfile = fopen(config.output_file, "w+");
|
||||
if (state->output_file) {
|
||||
outfile = fopen(state->output_file, "w+");
|
||||
if (outfile == NULL) {
|
||||
error(EXIT_FAILURE, errno, "open_outfile: %s", config.output_file);
|
||||
error(EXIT_FAILURE, errno, "open_outfile: %s", state->output_file);
|
||||
}
|
||||
} else {
|
||||
outfile = stdout;
|
||||
|
|
@ -171,24 +171,24 @@ static void close_outfile(FILE *outfile)
|
|||
}
|
||||
|
||||
/*! \brief Text output format, which is the default. */
|
||||
static int output_txt(void)
|
||||
static int output_txt(struct conf_t *state)
|
||||
{
|
||||
unsigned int i;
|
||||
struct range_t *range_p;
|
||||
struct shared_network_t *shared_p;
|
||||
struct output_helper_t oh;
|
||||
FILE *outfile;
|
||||
int max_ipaddr_length = config.ip_version == IPv6 ? 39 : 16;
|
||||
int max_ipaddr_length = state->ip_version == IPv6 ? 39 : 16;
|
||||
|
||||
if (config.color_mode == color_auto && isatty(STDIN_FILENO)) {
|
||||
config.color_mode = color_on;
|
||||
if (state->color_mode == color_auto && isatty(STDIN_FILENO)) {
|
||||
state->color_mode = color_on;
|
||||
}
|
||||
|
||||
outfile = open_outfile();
|
||||
range_p = ranges;
|
||||
shared_p = shared_networks;
|
||||
outfile = open_outfile(state);
|
||||
range_p = state->ranges;
|
||||
shared_p = state->shared_networks;
|
||||
|
||||
if (config.header_limit & R_BIT) {
|
||||
if (state->header_limit & R_BIT) {
|
||||
fprintf(outfile, "Ranges:\n");
|
||||
fprintf
|
||||
(outfile,
|
||||
|
|
@ -198,20 +198,20 @@ static int output_txt(void)
|
|||
"first ip",
|
||||
max_ipaddr_length,
|
||||
"last ip", "max", "cur", "percent", "touch", "t+c", "t+c perc");
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
fprintf(outfile, " bu bu perc");
|
||||
}
|
||||
fprintf(outfile, "\n");
|
||||
}
|
||||
if (config.number_limit & R_BIT) {
|
||||
for (i = 0; i < num_ranges; i++) {
|
||||
if (state->number_limit & R_BIT) {
|
||||
for (i = 0; i < state->num_ranges; i++) {
|
||||
int color_set = 0;
|
||||
range_output_helper(&oh, range_p);
|
||||
if (config.skip_ok && oh.status == STATUS_OK) {
|
||||
range_output_helper(state, &oh, range_p);
|
||||
if (state->skip_ok && oh.status == STATUS_OK) {
|
||||
range_p++;
|
||||
continue;
|
||||
}
|
||||
if (config.color_mode == color_on)
|
||||
if (state->color_mode == color_on)
|
||||
color_set = start_color(&oh, outfile);
|
||||
if (range_p->shared_net) {
|
||||
fprintf(outfile, "%-20s", range_p->shared_net->name);
|
||||
|
|
@ -233,7 +233,7 @@ static int output_txt(void)
|
|||
range_p->touched,
|
||||
oh.tc,
|
||||
oh.tcp);
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
fprintf(outfile, "%7g %8.3f",
|
||||
range_p->backups, oh.bup);
|
||||
}
|
||||
|
|
@ -243,26 +243,26 @@ static int output_txt(void)
|
|||
range_p++;
|
||||
}
|
||||
}
|
||||
if (config.number_limit & R_BIT && config.header_limit & S_BIT) {
|
||||
if (state->number_limit & R_BIT && state->header_limit & S_BIT) {
|
||||
fprintf(outfile, "\n");
|
||||
}
|
||||
if (config.header_limit & S_BIT) {
|
||||
if (state->header_limit & S_BIT) {
|
||||
fprintf(outfile, "Shared networks:\n");
|
||||
fprintf(outfile,
|
||||
"name max cur percent touch t+c t+c perc");
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
fprintf(outfile, " bu bu perc");
|
||||
}
|
||||
fprintf(outfile, "\n");
|
||||
}
|
||||
if (config.number_limit & S_BIT) {
|
||||
for (i = 0; i < num_shared_networks; i++) {
|
||||
if (state->number_limit & S_BIT) {
|
||||
for (i = 0; i < state->num_shared_networks; i++) {
|
||||
int color_set = 0;
|
||||
shared_p++;
|
||||
shnet_output_helper(&oh, shared_p);
|
||||
if (config.skip_ok && oh.status == STATUS_OK)
|
||||
shnet_output_helper(state, &oh, shared_p);
|
||||
if (state->skip_ok && oh.status == STATUS_OK)
|
||||
continue;
|
||||
if (config.color_mode == color_on)
|
||||
if (state->color_mode == color_on)
|
||||
color_set = start_color(&oh, outfile);
|
||||
fprintf(outfile,
|
||||
"%-20s %5g %5g %10.3f %7g %6g %9.3f",
|
||||
|
|
@ -273,7 +273,7 @@ static int output_txt(void)
|
|||
shared_p->touched,
|
||||
oh.tc,
|
||||
oh.tcp);
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
fprintf(outfile, "%7g %8.3f",
|
||||
shared_p->backups,
|
||||
oh.bup);
|
||||
|
|
@ -283,36 +283,36 @@ static int output_txt(void)
|
|||
fprintf(outfile, "\n");
|
||||
}
|
||||
}
|
||||
if (config.number_limit & S_BIT && config.header_limit & A_BIT) {
|
||||
if (state->number_limit & S_BIT && state->header_limit & A_BIT) {
|
||||
fprintf(outfile, "\n");
|
||||
}
|
||||
if (config.header_limit & A_BIT) {
|
||||
if (state->header_limit & A_BIT) {
|
||||
fprintf(outfile, "Sum of all ranges:\n");
|
||||
fprintf(outfile,
|
||||
"name max cur percent touch t+c t+c perc");
|
||||
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
fprintf(outfile, " bu bu perc");
|
||||
}
|
||||
fprintf(outfile, "\n");
|
||||
}
|
||||
if (config.number_limit & A_BIT) {
|
||||
if (state->number_limit & A_BIT) {
|
||||
int color_set = 0;
|
||||
shnet_output_helper(&oh, shared_networks);
|
||||
if (config.color_mode == color_on)
|
||||
shnet_output_helper(state, &oh, state->shared_networks);
|
||||
if (state->color_mode == color_on)
|
||||
color_set = start_color(&oh, outfile);
|
||||
fprintf(outfile, "%-20s %5g %5g %10.3f %7g %6g %9.3f",
|
||||
shared_networks->name,
|
||||
shared_networks->available,
|
||||
shared_networks->used,
|
||||
state->shared_networks->name,
|
||||
state->shared_networks->available,
|
||||
state->shared_networks->used,
|
||||
oh.percent,
|
||||
shared_networks->touched,
|
||||
state->shared_networks->touched,
|
||||
oh.tc,
|
||||
oh.tcp);
|
||||
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
fprintf(outfile, "%7g %8.3f",
|
||||
shared_networks->backups,
|
||||
state->shared_networks->backups,
|
||||
oh.bup);
|
||||
}
|
||||
if (color_set)
|
||||
|
|
@ -324,7 +324,7 @@ static int output_txt(void)
|
|||
}
|
||||
|
||||
/*! \brief The xml output formats. */
|
||||
static int output_xml(const int print_mac_addreses)
|
||||
static int output_xml(struct conf_t *state, const int print_mac_addreses)
|
||||
{
|
||||
unsigned int i;
|
||||
struct range_t *range_p;
|
||||
|
|
@ -332,16 +332,16 @@ static int output_xml(const int print_mac_addreses)
|
|||
struct output_helper_t oh;
|
||||
FILE *outfile;
|
||||
|
||||
outfile = open_outfile();
|
||||
range_p = ranges;
|
||||
shared_p = shared_networks;
|
||||
outfile = open_outfile(state);
|
||||
range_p = state->ranges;
|
||||
shared_p = state->shared_networks;
|
||||
|
||||
fprintf(outfile, "<dhcpstatus>\n");
|
||||
|
||||
if (print_mac_addreses == 1) {
|
||||
struct leases_t *l;
|
||||
|
||||
for (l = leases; l != NULL; l = l->hh.next) {
|
||||
for (l = state->leases; l != NULL; l = l->hh.next) {
|
||||
if (l->type == ACTIVE) {
|
||||
fputs("<active_lease>\n\t<ip>", outfile);
|
||||
fputs(ntop_ipaddr(&l->ip), outfile);
|
||||
|
|
@ -354,10 +354,10 @@ static int output_xml(const int print_mac_addreses)
|
|||
}
|
||||
}
|
||||
|
||||
if (config.number_limit & R_BIT) {
|
||||
for (i = 0; i < num_ranges; i++) {
|
||||
range_output_helper(&oh, range_p);
|
||||
if (config.skip_ok && oh.status == STATUS_OK) {
|
||||
if (state->number_limit & R_BIT) {
|
||||
for (i = 0; i < state->num_ranges; i++) {
|
||||
range_output_helper(state, &oh, range_p);
|
||||
if (state->skip_ok && oh.status == STATUS_OK) {
|
||||
range_p++;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -379,11 +379,11 @@ static int output_xml(const int print_mac_addreses)
|
|||
}
|
||||
}
|
||||
|
||||
if (config.number_limit & S_BIT) {
|
||||
for (i = 0; i < num_shared_networks; i++) {
|
||||
if (state->number_limit & S_BIT) {
|
||||
for (i = 0; i < state->num_shared_networks; i++) {
|
||||
shared_p++;
|
||||
shnet_output_helper(&oh, shared_p);
|
||||
if (config.skip_ok && oh.status == STATUS_OK)
|
||||
shnet_output_helper(state, &oh, shared_p);
|
||||
if (state->skip_ok && oh.status == STATUS_OK)
|
||||
continue;
|
||||
fprintf(outfile, "<shared-network>\n");
|
||||
fprintf(outfile, "\t<location>%s</location>\n", shared_p->name);
|
||||
|
|
@ -396,14 +396,14 @@ static int output_xml(const int print_mac_addreses)
|
|||
}
|
||||
}
|
||||
|
||||
if (config.header_limit & A_BIT) {
|
||||
if (state->header_limit & A_BIT) {
|
||||
fprintf(outfile, "<summary>\n");
|
||||
fprintf(outfile, "\t<location>%s</location>\n", shared_networks->name);
|
||||
fprintf(outfile, "\t<defined>%g</defined>\n", shared_networks->available);
|
||||
fprintf(outfile, "\t<used>%g</used>\n", shared_networks->used);
|
||||
fprintf(outfile, "\t<touched>%g</touched>\n", shared_networks->touched);
|
||||
fprintf(outfile, "\t<location>%s</location>\n", state->shared_networks->name);
|
||||
fprintf(outfile, "\t<defined>%g</defined>\n", state->shared_networks->available);
|
||||
fprintf(outfile, "\t<used>%g</used>\n", state->shared_networks->used);
|
||||
fprintf(outfile, "\t<touched>%g</touched>\n", state->shared_networks->touched);
|
||||
fprintf(outfile, "\t<free>%g</free>\n",
|
||||
shared_networks->available - shared_networks->used);
|
||||
state->shared_networks->available - state->shared_networks->used);
|
||||
fprintf(outfile, "</summary>\n");
|
||||
}
|
||||
|
||||
|
|
@ -413,7 +413,7 @@ static int output_xml(const int print_mac_addreses)
|
|||
}
|
||||
|
||||
/*! \brief The json output formats. */
|
||||
static int output_json(const int print_mac_addreses)
|
||||
static int output_json(struct conf_t *state, const int print_mac_addreses)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
struct range_t *range_p;
|
||||
|
|
@ -422,9 +422,9 @@ static int output_json(const int print_mac_addreses)
|
|||
FILE *outfile;
|
||||
unsigned int sep;
|
||||
|
||||
outfile = open_outfile();
|
||||
range_p = ranges;
|
||||
shared_p = shared_networks;
|
||||
outfile = open_outfile(state);
|
||||
range_p = state->ranges;
|
||||
shared_p = state->shared_networks;
|
||||
sep = 0;
|
||||
|
||||
fprintf(outfile, "{\n");
|
||||
|
|
@ -433,7 +433,7 @@ static int output_json(const int print_mac_addreses)
|
|||
struct leases_t *l;
|
||||
|
||||
fprintf(outfile, " \"active_leases\": [");
|
||||
for (l = leases; l != NULL; l = l->hh.next) {
|
||||
for (l = state->leases; l != NULL; l = l->hh.next) {
|
||||
if (l->type == ACTIVE) {
|
||||
if (i == 0) {
|
||||
i = 1;
|
||||
|
|
@ -453,14 +453,14 @@ static int output_json(const int print_mac_addreses)
|
|||
sep++;
|
||||
}
|
||||
|
||||
if (config.number_limit & R_BIT) {
|
||||
if (state->number_limit & R_BIT) {
|
||||
if (sep) {
|
||||
fprintf(outfile, ",\n");
|
||||
}
|
||||
fprintf(outfile, " \"subnets\": [\n");
|
||||
for (i = 0; i < num_ranges; i++) {
|
||||
range_output_helper(&oh, range_p);
|
||||
if (config.skip_ok && oh.status == STATUS_OK) {
|
||||
for (i = 0; i < state->num_ranges; i++) {
|
||||
range_output_helper(state, &oh, range_p);
|
||||
if (state->skip_ok && oh.status == STATUS_OK) {
|
||||
range_p++;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -484,14 +484,14 @@ static int output_json(const int print_mac_addreses)
|
|||
fprintf(outfile, "\"percent\":%g, ", oh.percent);
|
||||
fprintf(outfile, "\"touch_count\":%g, ", oh.tc);
|
||||
fprintf(outfile, "\"touch_percent\":%g, ", oh.tcp);
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
fprintf(outfile, "\"backup_count\":%g, ", range_p->backups);
|
||||
fprintf(outfile, "\"backup_percent\":%g, ", oh.bup);
|
||||
}
|
||||
fprintf(outfile, "\"status\":%d ", oh.status);
|
||||
|
||||
range_p++;
|
||||
if (i + 1 < num_ranges)
|
||||
if (i + 1 < state->num_ranges)
|
||||
fprintf(outfile, "},\n");
|
||||
else
|
||||
fprintf(outfile, "}\n");
|
||||
|
|
@ -500,15 +500,15 @@ static int output_json(const int print_mac_addreses)
|
|||
sep++;
|
||||
}
|
||||
|
||||
if (config.number_limit & S_BIT) {
|
||||
if (state->number_limit & S_BIT) {
|
||||
if (sep) {
|
||||
fprintf(outfile, ",\n");
|
||||
}
|
||||
fprintf(outfile, " \"shared-networks\": [\n");
|
||||
for (i = 0; i < num_shared_networks; i++) {
|
||||
for (i = 0; i < state->num_shared_networks; i++) {
|
||||
shared_p++;
|
||||
shnet_output_helper(&oh, shared_p);
|
||||
if (config.skip_ok && oh.status == STATUS_OK)
|
||||
shnet_output_helper(state, &oh, shared_p);
|
||||
if (state->skip_ok && oh.status == STATUS_OK)
|
||||
continue;
|
||||
fprintf(outfile, " ");
|
||||
fprintf(outfile, "{ ");
|
||||
|
|
@ -526,7 +526,7 @@ static int output_json(const int print_mac_addreses)
|
|||
fprintf(outfile, "\"touch_percent\":\"%g\", ", oh.tcp);
|
||||
else
|
||||
fprintf(outfile, "\"touch_percent\":%g, ", oh.tcp);
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
fprintf(outfile, "\"backup_count\":%g, ", shared_p->backups);
|
||||
if (shared_p->available == 0)
|
||||
fprintf(outfile, "\"backup_percent\":\"%g\", ", oh.bup);
|
||||
|
|
@ -534,7 +534,7 @@ static int output_json(const int print_mac_addreses)
|
|||
fprintf(outfile, "\"backup_percent\":%g, ", oh.bup);
|
||||
}
|
||||
fprintf(outfile, "\"status\":%d ", oh.status);
|
||||
if (i + 1 < num_shared_networks)
|
||||
if (i + 1 < state->num_shared_networks)
|
||||
fprintf(outfile, "},\n");
|
||||
else
|
||||
fprintf(outfile, "}\n");
|
||||
|
|
@ -543,23 +543,23 @@ static int output_json(const int print_mac_addreses)
|
|||
sep++;
|
||||
}
|
||||
|
||||
if (config.header_limit & A_BIT) {
|
||||
shnet_output_helper(&oh, shared_networks);
|
||||
if (state->header_limit & A_BIT) {
|
||||
shnet_output_helper(state, &oh, state->shared_networks);
|
||||
if (sep) {
|
||||
fprintf(outfile, ",\n");
|
||||
}
|
||||
fprintf(outfile, " \"summary\": {\n");
|
||||
fprintf(outfile, " \"location\":\"%s\",\n", shared_networks->name);
|
||||
fprintf(outfile, " \"defined\":%g,\n", shared_networks->available);
|
||||
fprintf(outfile, " \"used\":%g,\n", shared_networks->used);
|
||||
fprintf(outfile, " \"touched\":%g,\n", shared_networks->touched);
|
||||
fprintf(outfile, " \"location\":\"%s\",\n", state->shared_networks->name);
|
||||
fprintf(outfile, " \"defined\":%g,\n", state->shared_networks->available);
|
||||
fprintf(outfile, " \"used\":%g,\n", state->shared_networks->used);
|
||||
fprintf(outfile, " \"touched\":%g,\n", state->shared_networks->touched);
|
||||
fprintf(outfile, " \"free\":%g,\n",
|
||||
shared_networks->available - shared_networks->used);
|
||||
state->shared_networks->available - state->shared_networks->used);
|
||||
fprintf(outfile, " \"percent\":%g,\n", oh.percent);
|
||||
fprintf(outfile, " \"touch_count\":%g,\n", oh.tc);
|
||||
fprintf(outfile, " \"touch_percent\":%g,\n", oh.tcp);
|
||||
if (config.backups_found == 1) {
|
||||
fprintf(outfile, " \"backup_count\":%g,\n", shared_p->backups);
|
||||
if (state->backups_found == 1) {
|
||||
fprintf(outfile, " \"backup_count\":%g,\n", state->shared_networks->backups);
|
||||
fprintf(outfile, " \"backup_percent\":%g,\n", oh.bup);
|
||||
}
|
||||
fprintf(outfile, " \"status\":%d\n", oh.status);
|
||||
|
|
@ -574,14 +574,14 @@ static int output_json(const int print_mac_addreses)
|
|||
*
|
||||
* \param f Output file descriptor.
|
||||
*/
|
||||
static void html_header(FILE *restrict f)
|
||||
static void html_header(struct conf_t *state, FILE *restrict f)
|
||||
{
|
||||
char outstr[200];
|
||||
struct tm *tmp, result;
|
||||
|
||||
struct stat statbuf;
|
||||
|
||||
stat(config.dhcpdlease_file, &statbuf);
|
||||
stat(state->dhcpdlease_file, &statbuf);
|
||||
|
||||
tmp = localtime_r(&statbuf.st_mtime, &result);
|
||||
if (tmp == NULL) {
|
||||
|
|
@ -608,7 +608,7 @@ static void html_header(FILE *restrict f)
|
|||
fprintf(f, "<body>\n");
|
||||
fprintf(f, "<div class=\"container\">\n");
|
||||
fprintf(f, "<h2>ISC DHCPD status</h2>\n");
|
||||
fprintf(f, "<small>File %s was last modified at %s</small><hr />\n", config.dhcpdlease_file, outstr);
|
||||
fprintf(f, "<small>File %s was last modified at %s</small><hr />\n", state->dhcpdlease_file, outstr);
|
||||
}
|
||||
|
||||
/*! \brief Footer for full html output format.
|
||||
|
|
@ -713,7 +713,7 @@ static void newsection(FILE *restrict f, char const *restrict title)
|
|||
}
|
||||
|
||||
/*! \brief Output html format. */
|
||||
static int output_html(void)
|
||||
static int output_html(struct conf_t *state)
|
||||
{
|
||||
unsigned int i;
|
||||
struct range_t *range_p;
|
||||
|
|
@ -721,13 +721,13 @@ static int output_html(void)
|
|||
struct output_helper_t oh;
|
||||
FILE *outfile;
|
||||
|
||||
outfile = open_outfile();
|
||||
range_p = ranges;
|
||||
shared_p = shared_networks;
|
||||
html_header(outfile);
|
||||
outfile = open_outfile(state);
|
||||
range_p = state->ranges;
|
||||
shared_p = state->shared_networks;
|
||||
html_header(state, outfile);
|
||||
newsection(outfile, "Sum of all");
|
||||
table_start(outfile, "a", "all");
|
||||
if (config.header_limit & A_BIT) {
|
||||
if (state->header_limit & A_BIT) {
|
||||
start_tag(outfile, "thead");
|
||||
start_tag(outfile, "tr");
|
||||
output_line(outfile, "th", "name");
|
||||
|
|
@ -737,26 +737,26 @@ static int output_html(void)
|
|||
output_line(outfile, "th", "touch");
|
||||
output_line(outfile, "th", "t+c");
|
||||
output_line(outfile, "th", "t+c perc");
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
output_line(outfile, "th", "bu");
|
||||
output_line(outfile, "th", "bu perc");
|
||||
}
|
||||
end_tag(outfile, "tr");
|
||||
end_tag(outfile, "thead");
|
||||
}
|
||||
if (config.number_limit & A_BIT) {
|
||||
if (state->number_limit & A_BIT) {
|
||||
start_tag(outfile, "tbody");
|
||||
start_tag(outfile, "tr");
|
||||
shnet_output_helper(&oh, shared_networks);
|
||||
output_line(outfile, "td", shared_networks->name);
|
||||
output_double(outfile, "td", shared_networks->available);
|
||||
output_double(outfile, "td", shared_networks->used);
|
||||
shnet_output_helper(state, &oh, state->shared_networks);
|
||||
output_line(outfile, "td", state->shared_networks->name);
|
||||
output_double(outfile, "td", state->shared_networks->available);
|
||||
output_double(outfile, "td", state->shared_networks->used);
|
||||
output_float(outfile, "td", oh.percent);
|
||||
output_double(outfile, "td", shared_networks->touched);
|
||||
output_double(outfile, "td", state->shared_networks->touched);
|
||||
output_double(outfile, "td", oh.tc);
|
||||
output_float(outfile, "td", oh.tcp);
|
||||
if (config.backups_found == 1) {
|
||||
output_double(outfile, "td", shared_networks->backups);
|
||||
if (state->backups_found == 1) {
|
||||
output_double(outfile, "td", state->shared_networks->backups);
|
||||
output_float(outfile, "td", oh.tcp);
|
||||
}
|
||||
end_tag(outfile, "tr");
|
||||
|
|
@ -765,7 +765,7 @@ static int output_html(void)
|
|||
table_end(outfile);
|
||||
newsection(outfile, "Shared networks");
|
||||
table_start(outfile, "s", "snet");
|
||||
if (config.header_limit & S_BIT) {
|
||||
if (state->header_limit & S_BIT) {
|
||||
start_tag(outfile, "thead");
|
||||
start_tag(outfile, "tr");
|
||||
output_line(outfile, "th", "name");
|
||||
|
|
@ -775,19 +775,19 @@ static int output_html(void)
|
|||
output_line(outfile, "th", "touch");
|
||||
output_line(outfile, "th", "t+c");
|
||||
output_line(outfile, "th", "t+c perc");
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
output_line(outfile, "th", "bu");
|
||||
output_line(outfile, "th", "bu perc");
|
||||
}
|
||||
end_tag(outfile, "tr");
|
||||
end_tag(outfile, "thead");
|
||||
}
|
||||
if (config.number_limit & S_BIT) {
|
||||
if (state->number_limit & S_BIT) {
|
||||
start_tag(outfile, "tbody");
|
||||
for (i = 0; i < num_shared_networks; i++) {
|
||||
for (i = 0; i < state->num_shared_networks; i++) {
|
||||
shared_p++;
|
||||
shnet_output_helper(&oh, shared_networks);
|
||||
if (config.skip_ok && oh.status == STATUS_OK)
|
||||
shnet_output_helper(state, &oh, state->shared_networks);
|
||||
if (state->skip_ok && oh.status == STATUS_OK)
|
||||
continue;
|
||||
start_tag(outfile, "tr");
|
||||
output_line(outfile, "td", shared_p->name);
|
||||
|
|
@ -797,7 +797,7 @@ static int output_html(void)
|
|||
output_double(outfile, "td", shared_p->touched);
|
||||
output_double(outfile, "td", oh.tc);
|
||||
output_float(outfile, "td", oh.tcp);
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
output_double(outfile, "td", shared_p->backups);
|
||||
output_float(outfile, "td", oh.bup);
|
||||
}
|
||||
|
|
@ -808,7 +808,7 @@ static int output_html(void)
|
|||
table_end(outfile);
|
||||
newsection(outfile, "Ranges");
|
||||
table_start(outfile, "r", "ranges");
|
||||
if (config.header_limit & R_BIT) {
|
||||
if (state->header_limit & R_BIT) {
|
||||
start_tag(outfile, "thead");
|
||||
start_tag(outfile, "tr");
|
||||
output_line(outfile, "th", "shared net name");
|
||||
|
|
@ -820,18 +820,18 @@ static int output_html(void)
|
|||
output_line(outfile, "th", "touch");
|
||||
output_line(outfile, "th", "t+c");
|
||||
output_line(outfile, "th", "t+c perc");
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
output_line(outfile, "th", "bu");
|
||||
output_line(outfile, "th", "bu perc");
|
||||
}
|
||||
end_tag(outfile, "tr");
|
||||
end_tag(outfile, "thead");
|
||||
}
|
||||
if (config.number_limit & R_BIT) {
|
||||
if (state->number_limit & R_BIT) {
|
||||
start_tag(outfile, "tbody");
|
||||
for (i = 0; i < num_ranges; i++) {
|
||||
range_output_helper(&oh, range_p);
|
||||
if (config.skip_ok && oh.status == STATUS_OK) {
|
||||
for (i = 0; i < state->num_ranges; i++) {
|
||||
range_output_helper(state, &oh, range_p);
|
||||
if (state->skip_ok && oh.status == STATUS_OK) {
|
||||
range_p++;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -849,7 +849,7 @@ static int output_html(void)
|
|||
output_double(outfile, "td", range_p->touched);
|
||||
output_double(outfile, "td", oh.tc);
|
||||
output_float(outfile, "td", oh.tcp);
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
output_double(outfile, "td", range_p->backups);
|
||||
output_float(outfile, "td", oh.bup);
|
||||
}
|
||||
|
|
@ -865,7 +865,7 @@ static int output_html(void)
|
|||
}
|
||||
|
||||
/*! \brief Output cvs format. */
|
||||
static int output_csv(void)
|
||||
static int output_csv(struct conf_t *state)
|
||||
{
|
||||
unsigned int i;
|
||||
struct range_t *range_p;
|
||||
|
|
@ -873,23 +873,23 @@ static int output_csv(void)
|
|||
struct output_helper_t oh;
|
||||
FILE *outfile;
|
||||
|
||||
outfile = open_outfile();
|
||||
range_p = ranges;
|
||||
shared_p = shared_networks;
|
||||
if (config.header_limit & R_BIT) {
|
||||
outfile = open_outfile(state);
|
||||
range_p = state->ranges;
|
||||
shared_p = state->shared_networks;
|
||||
if (state->header_limit & R_BIT) {
|
||||
fprintf(outfile, "\"Ranges:\"\n");
|
||||
fprintf
|
||||
(outfile,
|
||||
"\"shared net name\",\"first ip\",\"last ip\",\"max\",\"cur\",\"percent\",\"touch\",\"t+c\",\"t+c perc\"");
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
fprintf(outfile, ",\"bu\",\"bu perc\"");
|
||||
}
|
||||
fprintf(outfile, "\n");
|
||||
}
|
||||
if (config.number_limit & R_BIT) {
|
||||
for (i = 0; i < num_ranges; i++) {
|
||||
range_output_helper(&oh, range_p);
|
||||
if (config.skip_ok && oh.status == STATUS_OK) {
|
||||
if (state->number_limit & R_BIT) {
|
||||
for (i = 0; i < state->num_ranges; i++) {
|
||||
range_output_helper(state, &oh, range_p);
|
||||
if (state->skip_ok && oh.status == STATUS_OK) {
|
||||
range_p++;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -908,7 +908,7 @@ static int output_csv(void)
|
|||
range_p->touched,
|
||||
oh.tc,
|
||||
oh.tcp);
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
fprintf(outfile, ",\"%g\",\"%.3f\"",
|
||||
range_p->backups,
|
||||
oh.bup);
|
||||
|
|
@ -919,21 +919,21 @@ static int output_csv(void)
|
|||
}
|
||||
fprintf(outfile, "\n");
|
||||
}
|
||||
if (config.header_limit & S_BIT) {
|
||||
if (state->header_limit & S_BIT) {
|
||||
fprintf(outfile, "\"Shared networks:\"\n");
|
||||
fprintf(outfile,
|
||||
"\"name\",\"max\",\"cur\",\"percent\",\"touch\",\"t+c\",\"t+c perc\"");
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
fprintf(outfile, ",\"bu\",\"bu perc\"");
|
||||
}
|
||||
fprintf(outfile, "\n");
|
||||
}
|
||||
if (config.number_limit & S_BIT) {
|
||||
if (state->number_limit & S_BIT) {
|
||||
|
||||
for (i = 0; i < num_shared_networks; i++) {
|
||||
for (i = 0; i < state->num_shared_networks; i++) {
|
||||
shared_p++;
|
||||
shnet_output_helper(&oh, shared_p);
|
||||
if (config.skip_ok && oh.status == STATUS_OK)
|
||||
shnet_output_helper(state, &oh, shared_p);
|
||||
if (state->skip_ok && oh.status == STATUS_OK)
|
||||
continue;
|
||||
fprintf(outfile,
|
||||
"\"%s\",\"%g\",\"%g\",\"%.3f\",\"%g\",\"%g\",\"%.3f\"",
|
||||
|
|
@ -944,7 +944,7 @@ static int output_csv(void)
|
|||
shared_p->touched,
|
||||
oh.tc,
|
||||
oh.tcp);
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
fprintf(outfile, ",\"%g\",\"%.3f\"",
|
||||
shared_p->backups,
|
||||
oh.bup);
|
||||
|
|
@ -954,29 +954,29 @@ static int output_csv(void)
|
|||
}
|
||||
fprintf(outfile, "\n");
|
||||
}
|
||||
if (config.header_limit & A_BIT) {
|
||||
if (state->header_limit & A_BIT) {
|
||||
fprintf(outfile, "\"Sum of all ranges:\"\n");
|
||||
fprintf(outfile,
|
||||
"\"name\",\"max\",\"cur\",\"percent\",\"touch\",\"t+c\",\"t+c perc\"");
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
fprintf(outfile, ",\"bu\",\"bu perc\"");
|
||||
}
|
||||
fprintf(outfile, "\n");
|
||||
}
|
||||
if (config.number_limit & A_BIT) {
|
||||
shnet_output_helper(&oh, shared_networks);
|
||||
if (state->number_limit & A_BIT) {
|
||||
shnet_output_helper(state, &oh, state->shared_networks);
|
||||
fprintf(outfile,
|
||||
"\"%s\",\"%g\",\"%g\",\"%.3f\",\"%g\",\"%g\",\"%.3f\"",
|
||||
shared_networks->name,
|
||||
shared_networks->available,
|
||||
shared_networks->used,
|
||||
state->shared_networks->name,
|
||||
state->shared_networks->available,
|
||||
state->shared_networks->used,
|
||||
oh.percent,
|
||||
shared_networks->touched,
|
||||
state->shared_networks->touched,
|
||||
oh.tc,
|
||||
oh.tcp);
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
fprintf(outfile, "%7g %8.3f",
|
||||
shared_networks->backups,
|
||||
state->shared_networks->backups,
|
||||
oh.bup);
|
||||
}
|
||||
fprintf(outfile, "\n");
|
||||
|
|
@ -986,7 +986,7 @@ static int output_csv(void)
|
|||
}
|
||||
|
||||
/*! \brief Output alarm text, and return program exit value. */
|
||||
static int output_alarming(void)
|
||||
static int output_alarming(struct conf_t *state)
|
||||
{
|
||||
FILE *outfile;
|
||||
struct range_t *range_p;
|
||||
|
|
@ -997,14 +997,14 @@ static int output_alarming(void)
|
|||
int rw = 0, rc = 0, ro = 0, ri = 0, sw = 0, sc = 0, so = 0, si = 0;
|
||||
int ret_val;
|
||||
|
||||
outfile = open_outfile();
|
||||
range_p = ranges;
|
||||
outfile = open_outfile(state);
|
||||
range_p = state->ranges;
|
||||
range_size = get_range_size(range_p);
|
||||
shared_p = shared_networks;
|
||||
shared_p = state->shared_networks;
|
||||
|
||||
if (config.number_limit & R_BIT) {
|
||||
for (i = 0; i < num_ranges; i++) {
|
||||
range_output_helper(&oh, range_p);
|
||||
if (state->number_limit & R_BIT) {
|
||||
for (i = 0; i < state->num_ranges; i++) {
|
||||
range_output_helper(state, &oh, range_p);
|
||||
switch (oh.status) {
|
||||
case STATUS_SUPPRESSED:
|
||||
break;
|
||||
|
|
@ -1026,10 +1026,10 @@ static int output_alarming(void)
|
|||
range_p++;
|
||||
}
|
||||
}
|
||||
if (config.number_limit & S_BIT) {
|
||||
for (i = 0; i < num_shared_networks; i++) {
|
||||
if (state->number_limit & S_BIT) {
|
||||
for (i = 0; i < state->num_shared_networks; i++) {
|
||||
shared_p++;
|
||||
shnet_output_helper(&oh, shared_p);
|
||||
shnet_output_helper(state, &oh, shared_p);
|
||||
switch (oh.status) {
|
||||
case STATUS_IGNORED:
|
||||
si++;
|
||||
|
|
@ -1056,14 +1056,14 @@ static int output_alarming(void)
|
|||
else
|
||||
ret_val = STATE_OK;
|
||||
|
||||
if ((0 < rc && config.number_limit & R_BIT)
|
||||
|| (0 < sc && config.number_limit & S_BIT)) {
|
||||
if ((0 < rc && state->number_limit & R_BIT)
|
||||
|| (0 < sc && state->number_limit & S_BIT)) {
|
||||
fprintf(outfile, "CRITICAL: %s:", program_name);
|
||||
} else if ((0 < rw && config.number_limit & R_BIT)
|
||||
|| (0 < sw && config.number_limit & S_BIT)) {
|
||||
} else if ((0 < rw && state->number_limit & R_BIT)
|
||||
|| (0 < sw && state->number_limit & S_BIT)) {
|
||||
fprintf(outfile, "WARNING: %s:", program_name);
|
||||
} else {
|
||||
if (config.number_limit & A_BIT)
|
||||
if (state->number_limit & A_BIT)
|
||||
fprintf(outfile, "OK:");
|
||||
else {
|
||||
if (close_stream(outfile)) {
|
||||
|
|
@ -1072,7 +1072,7 @@ static int output_alarming(void)
|
|||
return ret_val;
|
||||
}
|
||||
}
|
||||
if (config.header_limit & R_BIT) {
|
||||
if (state->header_limit & R_BIT) {
|
||||
fprintf(outfile, " Ranges - crit: %d warn: %d ok: %d", rc, rw, ro);
|
||||
if (ri != 0) {
|
||||
fprintf(outfile, " ignored: %d", ri);
|
||||
|
|
@ -1081,22 +1081,22 @@ static int output_alarming(void)
|
|||
if (ri != 0) {
|
||||
fprintf(outfile, " range_ignored=%d", ri);
|
||||
}
|
||||
if (config.perfdata == 1 && config.number_limit & R_BIT) {
|
||||
for (i = 0; i < num_ranges; i++) {
|
||||
if (state->perfdata == 1 && state->number_limit & R_BIT) {
|
||||
for (i = 0; i < state->num_ranges; i++) {
|
||||
range_p--;
|
||||
range_size = get_range_size(range_p);
|
||||
if (config.minsize < range_size) {
|
||||
if (state->minsize < range_size) {
|
||||
fprintf(outfile, " %s_r=",
|
||||
ntop_ipaddr(&range_p->first_ip));
|
||||
fprintf(outfile, "%g;%g;%g;0;%g",
|
||||
range_p->count,
|
||||
(range_size * config.warning / 100),
|
||||
(range_size * config.critical / 100),
|
||||
(range_size * state->warning / 100),
|
||||
(range_size * state->critical / 100),
|
||||
range_size);
|
||||
fprintf(outfile, " %s_rt=%g",
|
||||
ntop_ipaddr(&range_p->first_ip),
|
||||
range_p->touched);
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
fprintf(outfile, " %s_rbu=%g",
|
||||
ntop_ipaddr(&range_p->first_ip),
|
||||
range_p->backups);
|
||||
|
|
@ -1108,7 +1108,7 @@ static int output_alarming(void)
|
|||
} else {
|
||||
fprintf(outfile, " ");
|
||||
}
|
||||
if (config.header_limit & S_BIT) {
|
||||
if (state->header_limit & S_BIT) {
|
||||
fprintf(outfile, "Shared nets - crit: %d warn: %d ok: %d", sc, sw, so);
|
||||
if (si != 0) {
|
||||
fprintf(outfile, " ignored: %d", si);
|
||||
|
|
@ -1117,19 +1117,19 @@ static int output_alarming(void)
|
|||
if (si != 0) {
|
||||
fprintf(outfile, " snet_ignored=%d", si);
|
||||
}
|
||||
if (config.perfdata == 1 && config.header_limit & R_BIT) {
|
||||
for (i = 0; i < num_shared_networks; i++) {
|
||||
if (config.minsize < shared_p->available) {
|
||||
if (state->perfdata == 1 && state->header_limit & R_BIT) {
|
||||
for (i = 0; i < state->num_shared_networks; i++) {
|
||||
if (state->minsize < shared_p->available) {
|
||||
fprintf(outfile, " '%s_s'=%g;%g;%g;0;%g",
|
||||
shared_p->name,
|
||||
shared_p->used,
|
||||
(shared_p->available * config.warning / 100),
|
||||
(shared_p->available * config.critical / 100),
|
||||
(shared_p->available * state->warning / 100),
|
||||
(shared_p->available * state->critical / 100),
|
||||
shared_p->available);
|
||||
fprintf(outfile, " '%s_st'=%g",
|
||||
shared_p->name,
|
||||
shared_p->touched);
|
||||
if (config.backups_found == 1) {
|
||||
if (state->backups_found == 1) {
|
||||
fprintf(outfile, " '%s_sbu'=%g",
|
||||
shared_p->name,
|
||||
shared_p->backups);
|
||||
|
|
@ -1146,44 +1146,44 @@ static int output_alarming(void)
|
|||
}
|
||||
|
||||
/*! \brief Return output_format_names enum based on single char input. */
|
||||
int output_analysis(const char c)
|
||||
int output_analysis(struct conf_t *state, const char output_format)
|
||||
{
|
||||
int ret = 1;
|
||||
switch (c) {
|
||||
switch (output_format) {
|
||||
case 't':
|
||||
ret = output_txt();
|
||||
ret = output_txt(state);
|
||||
break;
|
||||
case 'a':
|
||||
ret = output_alarming();
|
||||
ret = output_alarming(state);
|
||||
break;
|
||||
case 'h':
|
||||
error(EXIT_FAILURE, 0, "html table only output format is deprecated");
|
||||
break;
|
||||
case 'H':
|
||||
ret = output_html();
|
||||
ret = output_html(state);
|
||||
break;
|
||||
case 'x':
|
||||
ret = output_xml(0);
|
||||
ret = output_xml(state, 0);
|
||||
break;
|
||||
case 'X':
|
||||
ret = output_xml(1);
|
||||
ret = output_xml(state, 1);
|
||||
break;
|
||||
case 'j':
|
||||
ret = output_json(0);
|
||||
ret = output_json(state, 0);
|
||||
break;
|
||||
case 'J':
|
||||
ret = output_json(1);
|
||||
ret = output_json(state, 1);
|
||||
break;
|
||||
case 'c':
|
||||
ret = output_csv();
|
||||
ret = output_csv(state);
|
||||
break;
|
||||
#ifdef BUILD_MUSTACH
|
||||
case 'm':
|
||||
ret = mustach_dhcpd_pools();
|
||||
ret = mustach_dhcpd_pools(state);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
error(EXIT_FAILURE, 0, "unknown output format: '%c'", c);
|
||||
error(EXIT_FAILURE, 0, "unknown output format: '%c'", output_format);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
55
src/sort.c
55
src/sort.c
|
|
@ -47,6 +47,7 @@
|
|||
#include "error.h"
|
||||
#include "progname.h"
|
||||
#include "quote.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
#include "dhcpd-pools.h"
|
||||
|
||||
|
|
@ -239,7 +240,6 @@ comparer_t field_selector(char c)
|
|||
default:
|
||||
{
|
||||
char str[2] = { c, '\0' };
|
||||
clean_up();
|
||||
error(EXIT_FAILURE, 0, "field_selector: unknown sort order: %s", quote(str));
|
||||
}
|
||||
}
|
||||
|
|
@ -251,12 +251,13 @@ comparer_t field_selector(char c)
|
|||
* \param right The right side of the merge sort.
|
||||
* \return Relevant for merge sort decision.
|
||||
*/
|
||||
static int merge(struct range_t *restrict left, struct range_t *restrict right)
|
||||
int merge(struct conf_t *state, struct range_t *restrict left,
|
||||
struct range_t *restrict right)
|
||||
{
|
||||
struct output_sort *p;
|
||||
int ret;
|
||||
|
||||
for (p = config.sorts; p; p = p->next) {
|
||||
for (p = state->sorts; p; p = p->next) {
|
||||
if (p->func == NULL) {
|
||||
/* String sorting is special. */
|
||||
ret = strcmp(left->shared_net->name, right->shared_net->name);
|
||||
|
|
@ -274,43 +275,46 @@ static int merge(struct range_t *restrict left, struct range_t *restrict right)
|
|||
}
|
||||
|
||||
/*! \brief Mergesort for range table.
|
||||
* \param orig Pointer to range that is requested to be sorted.
|
||||
* \param size Number of ranges to be sorted.
|
||||
* \param temp Temporary memory space, needed when a values has to be
|
||||
* flipped.
|
||||
*/
|
||||
void mergesort_ranges(struct range_t *restrict orig, int size, struct range_t *restrict temp)
|
||||
void mergesort_ranges(struct conf_t *state, struct range_t *restrict orig, unsigned int size,
|
||||
struct range_t *restrict temp, const int root_call)
|
||||
{
|
||||
int left, right, i;
|
||||
unsigned int left, i, u_right;
|
||||
int s_right;
|
||||
struct range_t hold;
|
||||
|
||||
if (temp == NULL)
|
||||
temp = xmalloc(sizeof(struct range_t) * size);
|
||||
|
||||
/* Merge sort split size */
|
||||
static const int MIN_MERGE_SIZE = 8;
|
||||
static const unsigned int MIN_MERGE_SIZE = 8;
|
||||
|
||||
if (size < MIN_MERGE_SIZE) {
|
||||
for (left = 0; left < size; left++) {
|
||||
hold = *(orig + left);
|
||||
for (right = left - 1; 0 <= right; right--) {
|
||||
if (merge((orig + right), &hold))
|
||||
for (s_right = left - 1; 0 <= s_right; s_right--) {
|
||||
if (merge(state, (orig + s_right), &hold))
|
||||
break;
|
||||
*(orig + right + 1) = *(orig + right);
|
||||
*(orig + s_right + 1) = *(orig + s_right);
|
||||
}
|
||||
*(orig + right + 1) = hold;
|
||||
*(orig + s_right + 1) = hold;
|
||||
}
|
||||
if (root_call)
|
||||
free(temp);
|
||||
return;
|
||||
}
|
||||
mergesort_ranges(orig, size / 2, temp);
|
||||
mergesort_ranges(orig + size / 2, size - size / 2, temp);
|
||||
mergesort_ranges(state, orig, size / 2, temp, 0);
|
||||
mergesort_ranges(state, orig + size / 2, size - size / 2, temp, 0);
|
||||
left = 0;
|
||||
right = size / 2;
|
||||
u_right = size / 2;
|
||||
i = 0;
|
||||
while (left < size / 2 && right < size) {
|
||||
if (merge((orig + left), (orig + right))) {
|
||||
while (left < size / 2 && u_right < size) {
|
||||
if (merge(state, (orig + left), (orig + u_right))) {
|
||||
*(temp + i) = *(orig + left);
|
||||
left++;
|
||||
} else {
|
||||
*(temp + i) = *(orig + right);
|
||||
right++;
|
||||
*(temp + i) = *(orig + u_right);
|
||||
u_right++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
|
@ -319,10 +323,13 @@ void mergesort_ranges(struct range_t *restrict orig, int size, struct range_t *r
|
|||
left++;
|
||||
i++;
|
||||
}
|
||||
while (right < size) {
|
||||
*(temp + i) = *(orig + right);
|
||||
right++;
|
||||
while (u_right < size) {
|
||||
*(temp + i) = *(orig + u_right);
|
||||
u_right++;
|
||||
i++;
|
||||
}
|
||||
memcpy(orig, temp, size * sizeof(struct range_t));
|
||||
|
||||
if (root_call)
|
||||
free(temp);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue