mirror of
git://git.code.sf.net/p/dhcpd-pools/code
synced 2025-12-17 00:06:59 +00:00
remove upper limit of sort order definitions
Unlikely to be needed by anyone, but because arbitrary limits are from code style point of view ugly. Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
parent
327691f34a
commit
0369340710
5 changed files with 72 additions and 59 deletions
|
|
@ -57,9 +57,9 @@ or monitor subset of data.
|
||||||
Path to the dhcpd.leases file.
|
Path to the dhcpd.leases file.
|
||||||
.TP
|
.TP
|
||||||
\fB\-s\fR, \fB\-\-sort\fR=\fI[nimcptTe]\fR
|
\fB\-s\fR, \fB\-\-sort\fR=\fI[nimcptTe]\fR
|
||||||
Sort ranges by chosen fields as a sorting keys. Maximum of five sort keys
|
Sort ranges by chosen fields as a sorting keys. Keys weight from left to
|
||||||
can be defined. Keys weight from left to right, i.e., if more weighting keys
|
right, i.e., if more weighting keys are equal next one is used. The IP
|
||||||
are equal next one is used. The IP field is default sort key.
|
field is default sort key.
|
||||||
.TP
|
.TP
|
||||||
\fB\-r\fR, \fB\-\-reverse\fR
|
\fB\-r\fR, \fB\-\-reverse\fR
|
||||||
Sort results in reverse order.
|
Sort results in reverse order.
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ struct leases_t *(*find_lease) (union ipaddr_t *ip);
|
||||||
* alarming. */
|
* alarming. */
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i, sorts = 0;
|
int i;
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
char const *tmp;
|
char const *tmp;
|
||||||
struct range_t *tmp_ranges;
|
struct range_t *tmp_ranges;
|
||||||
|
|
@ -150,6 +150,7 @@ int main(int argc, char **argv)
|
||||||
/* Default sort order is by IPs small to big */
|
/* Default sort order is by IPs small to big */
|
||||||
config.reverse_order = false;
|
config.reverse_order = false;
|
||||||
config.backups_found = false;
|
config.backups_found = false;
|
||||||
|
prepare_memory();
|
||||||
/* Parse command line options */
|
/* Parse command line options */
|
||||||
while (1) {
|
while (1) {
|
||||||
int c;
|
int c;
|
||||||
|
|
@ -171,16 +172,23 @@ int main(int argc, char **argv)
|
||||||
strncpy(config.output_format, optarg, (size_t)1);
|
strncpy(config.output_format, optarg, (size_t)1);
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
|
{
|
||||||
/* Output sorting option */
|
/* Output sorting option */
|
||||||
sorts = strlen(optarg);
|
struct output_sort *p = config.sorts;
|
||||||
if (5 < sorts) {
|
|
||||||
error(0, 0, "main: only first 5 sort orders will be used");
|
while (p && p->next)
|
||||||
strncpy(config.sort, optarg, (size_t)5);
|
p = p->next;
|
||||||
sorts = 5;
|
for (i = 0; i < strlen(optarg); i++) {
|
||||||
} else
|
if (config.sorts == NULL) {
|
||||||
strncpy(config.sort, optarg, (size_t)sorts);
|
config.sorts = xcalloc(1, sizeof(struct output_sort));
|
||||||
for (i = 0; i < sorts; i++)
|
p = config.sorts;
|
||||||
field_selector(config.sort[i]);
|
} else {
|
||||||
|
p->next = xcalloc(1, sizeof(struct output_sort));
|
||||||
|
p = p->next;
|
||||||
|
}
|
||||||
|
p->func = field_selector(optarg[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
/* What ever sort in reverse order */
|
/* What ever sort in reverse order */
|
||||||
|
|
@ -269,14 +277,13 @@ int main(int argc, char **argv)
|
||||||
error(EXIT_FAILURE, 0, "main: unknown output format `%c'", config.output_format[0]);
|
error(EXIT_FAILURE, 0, "main: unknown output format `%c'", config.output_format[0]);
|
||||||
}
|
}
|
||||||
/* Do the job */
|
/* Do the job */
|
||||||
prepare_memory();
|
|
||||||
set_ipv_functions(VERSION_UNKNOWN);
|
set_ipv_functions(VERSION_UNKNOWN);
|
||||||
parse_config(true, config.dhcpdconf_file, shared_networks);
|
parse_config(true, config.dhcpdconf_file, shared_networks);
|
||||||
parse_leases();
|
parse_leases();
|
||||||
prepare_data();
|
prepare_data();
|
||||||
do_counting();
|
do_counting();
|
||||||
tmp_ranges = xmalloc(sizeof(struct range_t) * num_ranges);
|
tmp_ranges = xmalloc(sizeof(struct range_t) * num_ranges);
|
||||||
if (sorts != 0)
|
if (config.sorts != NULL)
|
||||||
mergesort_ranges(ranges, num_ranges, tmp_ranges);
|
mergesort_ranges(ranges, num_ranges, tmp_ranges);
|
||||||
if (config.reverse_order == true)
|
if (config.reverse_order == true)
|
||||||
flip_ranges(ranges, tmp_ranges);
|
flip_ranges(ranges, tmp_ranges);
|
||||||
|
|
@ -300,4 +307,5 @@ void prepare_memory(void)
|
||||||
shared_networks->used = 0;
|
shared_networks->used = 0;
|
||||||
shared_networks->touched = 0;
|
shared_networks->touched = 0;
|
||||||
shared_networks->backups = 0;
|
shared_networks->backups = 0;
|
||||||
|
config.sorts = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -115,27 +115,6 @@ enum prefix_t {
|
||||||
PREFIX_HARDWARE_ETHERNET,
|
PREFIX_HARDWARE_ETHERNET,
|
||||||
NUM_OF_PREFIX
|
NUM_OF_PREFIX
|
||||||
};
|
};
|
||||||
/*! \struct configuration_t
|
|
||||||
* \brief Runtime configuration.
|
|
||||||
*/
|
|
||||||
struct configuration_t {
|
|
||||||
char dhcpv6;
|
|
||||||
enum dhcp_version dhcp_version;
|
|
||||||
char *dhcpdconf_file;
|
|
||||||
char *dhcpdlease_file;
|
|
||||||
char output_format[2];
|
|
||||||
char sort[6];
|
|
||||||
bool reverse_order;
|
|
||||||
char *output_file;
|
|
||||||
int output_limit[2];
|
|
||||||
bool backups_found;
|
|
||||||
bool snet_alarms;
|
|
||||||
double warning;
|
|
||||||
double critical;
|
|
||||||
double warn_count;
|
|
||||||
double crit_count;
|
|
||||||
double minsize;
|
|
||||||
};
|
|
||||||
/*! \struct shared_network_t
|
/*! \struct shared_network_t
|
||||||
* \brief Counters for an individual shared network.
|
* \brief Counters for an individual shared network.
|
||||||
*/
|
*/
|
||||||
|
|
@ -200,6 +179,36 @@ enum limbits {
|
||||||
# define STATE_WARNING 1
|
# define STATE_WARNING 1
|
||||||
# define STATE_CRITICAL 2
|
# define STATE_CRITICAL 2
|
||||||
|
|
||||||
|
typedef int (*comparer_t) (struct range_t *r1, struct range_t *r2);
|
||||||
|
|
||||||
|
/*! \struct output_sort
|
||||||
|
* \brief Linked list of sort functions.
|
||||||
|
*/
|
||||||
|
struct output_sort {
|
||||||
|
comparer_t func;
|
||||||
|
struct output_sort *next;
|
||||||
|
};
|
||||||
|
/*! \struct configuration_t
|
||||||
|
* \brief Runtime configuration.
|
||||||
|
*/
|
||||||
|
struct configuration_t {
|
||||||
|
char dhcpv6;
|
||||||
|
enum dhcp_version dhcp_version;
|
||||||
|
char *dhcpdconf_file;
|
||||||
|
char *dhcpdlease_file;
|
||||||
|
char output_format[2];
|
||||||
|
struct output_sort *sorts;
|
||||||
|
bool reverse_order;
|
||||||
|
char *output_file;
|
||||||
|
int output_limit[2];
|
||||||
|
bool backups_found;
|
||||||
|
bool snet_alarms;
|
||||||
|
double warning;
|
||||||
|
double critical;
|
||||||
|
double warn_count;
|
||||||
|
double crit_count;
|
||||||
|
double minsize;
|
||||||
|
};
|
||||||
/* Global variables */
|
/* Global variables */
|
||||||
/* \var prefix_length Length of each prefix. */
|
/* \var prefix_length Length of each prefix. */
|
||||||
extern int prefix_length[2][NUM_OF_PREFIX];
|
extern int prefix_length[2][NUM_OF_PREFIX];
|
||||||
|
|
@ -289,7 +298,6 @@ extern int comp_touched(struct range_t *r1, struct range_t *r2) _DP_ATTRIBUTE_PU
|
||||||
extern int rangecomp(const void *__restrict r1, const void *__restrict r2)
|
extern int rangecomp(const void *__restrict r1, const void *__restrict r2)
|
||||||
__attribute__ ((nonnull(1, 2)));
|
__attribute__ ((nonnull(1, 2)));
|
||||||
/* sort function pointer and functions */
|
/* sort function pointer and functions */
|
||||||
typedef int (*comparer_t) (struct range_t *r1, struct range_t *r2);
|
|
||||||
extern comparer_t field_selector(char c);
|
extern comparer_t field_selector(char c);
|
||||||
extern double ret_percent(struct range_t r);
|
extern double ret_percent(struct range_t r);
|
||||||
extern double ret_tc(struct range_t r) _DP_ATTRIBUTE_CONST;
|
extern double ret_tc(struct range_t r) _DP_ATTRIBUTE_CONST;
|
||||||
|
|
|
||||||
|
|
@ -402,6 +402,8 @@ void flip_ranges(struct range_t *restrict flip_me, struct range_t *restrict tmp_
|
||||||
/*! \brief Free memory, flush buffers etc. */
|
/*! \brief Free memory, flush buffers etc. */
|
||||||
void clean_up(void)
|
void clean_up(void)
|
||||||
{
|
{
|
||||||
|
struct output_sort *cur, *next;
|
||||||
|
|
||||||
/* Just in case there something in buffers */
|
/* Just in case there something in buffers */
|
||||||
if (fflush(NULL))
|
if (fflush(NULL))
|
||||||
error(0, 0, "clean_up: fflush");
|
error(0, 0, "clean_up: fflush");
|
||||||
|
|
@ -418,6 +420,10 @@ void clean_up(void)
|
||||||
free((shared_networks + i)->name);
|
free((shared_networks + i)->name);
|
||||||
free(shared_networks);
|
free(shared_networks);
|
||||||
}
|
}
|
||||||
|
for (cur = config.sorts; cur; cur = next) {
|
||||||
|
next = cur->next;
|
||||||
|
free(cur);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief A version printing. */
|
/*! \brief A version printing. */
|
||||||
|
|
|
||||||
35
src/sort.c
35
src/sort.c
|
|
@ -220,7 +220,7 @@ comparer_t field_selector(char c)
|
||||||
{
|
{
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'n':
|
case 'n':
|
||||||
break;
|
return NULL;
|
||||||
case 'i':
|
case 'i':
|
||||||
return comp_ip;
|
return comp_ip;
|
||||||
case 'm':
|
case 'm':
|
||||||
|
|
@ -249,32 +249,23 @@ comparer_t field_selector(char c)
|
||||||
*/
|
*/
|
||||||
static int merge(struct range_t *restrict left, struct range_t *restrict right)
|
static int merge(struct range_t *restrict left, struct range_t *restrict right)
|
||||||
{
|
{
|
||||||
int i, len, ret;
|
struct output_sort *p;
|
||||||
comparer_t comparer;
|
int ret;
|
||||||
int cmp;
|
|
||||||
|
|
||||||
len = strlen(config.sort);
|
for (p = config.sorts; p; p = p->next) {
|
||||||
for (i = 0; i < len; i++) {
|
if (p->func == NULL) {
|
||||||
/* Handling strings is case of it's own */
|
/* String sorting is special. */
|
||||||
if (config.sort[i] == 'n') {
|
|
||||||
ret = strcmp(left->shared_net->name, right->shared_net->name);
|
ret = strcmp(left->shared_net->name, right->shared_net->name);
|
||||||
if (0 < ret)
|
} else {
|
||||||
return (0);
|
/* Range sorts are common. */
|
||||||
if (ret < 0)
|
ret = p->func(left, right);
|
||||||
return (1);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
/* Select which function is pointed by comparer */
|
if (0 < ret)
|
||||||
comparer = field_selector(config.sort[i]);
|
return (0);
|
||||||
cmp = comparer(left, right);
|
if (ret < 0)
|
||||||
/* If fields are equal use next sort method */
|
|
||||||
if (cmp == 0)
|
|
||||||
continue;
|
|
||||||
if (cmp < 0)
|
|
||||||
return (1);
|
return (1);
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
/* If all comparers where equal */
|
/* this is reached if nothing was sorted */
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue