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:
Sami Kerola 2015-11-30 00:49:42 +00:00
parent 327691f34a
commit 0369340710
No known key found for this signature in database
GPG key ID: A9553245FDE9B739
5 changed files with 72 additions and 59 deletions

View file

@ -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.

View file

@ -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;
} }

View file

@ -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;

View file

@ -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. */

View file

@ -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);
} }