2 ** Copyright (C) 2006- Sami Kerola <kerolasa@iki.fi>
4 ** This program is free software; you can redistribute it and/or modify
5 ** it under the terms of the GNU General Public License as published by
6 ** the Free Software Foundation; either version 2 of the License, or
7 ** (at your option) any later version.
9 ** This program is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ** GNU General Public License for more details.
14 ** You should have received a copy of the GNU General Public License
15 ** along with this program; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 #include "dhcpd-pools.h"
32 /* Sort functions for range sorting */
33 int intcomp(const void *x, const void *y)
35 if (*(unsigned long int *) x < *(unsigned long int *) y)
37 else if (*(unsigned long int *) y < *(unsigned long int *) x)
43 int rangecomp(const void *r1, const void *r2)
45 if ((((struct range_t *) r1)->first_ip) <
46 (((struct range_t *) r2)->first_ip))
48 else if ((((struct range_t *) r2)->first_ip) <
49 (((struct range_t *) r1)->first_ip))
55 unsigned long int ret_ip(struct range_t r)
60 unsigned long int ret_cur(struct range_t r)
65 unsigned long int ret_max(struct range_t r)
67 return (r.last_ip - r.first_ip);
70 unsigned long int ret_percent(struct range_t r)
73 f = (float) r.count / (r.last_ip - r.first_ip - 1);
74 return ((unsigned long int) (f * 100000));
77 unsigned long int ret_touched(struct range_t r)
82 unsigned long int ret_tc(struct range_t r)
84 return (r.count + r.touched);
87 unsigned long int ret_tcperc(struct range_t r)
90 f = (float) (r.count + r.touched) / (r.last_ip - r.first_ip - 1);
91 return ((unsigned long int) (f * 10000));
94 void field_selector(char c)
109 returner = ret_percent;
112 returner = ret_touched;
118 returner = ret_tcperc;
121 warnx("field_selector: unknown sort order `%c'", c);
122 errx(EXIT_FAILURE, "Try `%s --help' for more information.",
123 program_invocation_short_name);
127 /* Needed to support multiple key sorting. */
128 int get_order(struct range_t *left, struct range_t *right)
131 unsigned long int lint, rint;
133 len = strlen(config.sort);
134 for (i = 0; i < len; i++) {
135 /* Handling strings is case of it's own */
136 if (config.sort[i] == 'n') {
138 strcmp(left->shared_net->name,
139 right->shared_net->name);
142 } else if (ret < 0) {
149 /* Select which function is pointed by returner */
150 field_selector(config.sort[i]);
151 lint = returner(*left);
152 rint = returner(*right);
153 /* If fields are equal use next sort method */
163 /* If all returners where equal */
167 void mergesort_ranges(struct range_t *orig, int size, struct range_t *temp)
172 if (size < MIN_MERGE_SIZE) {
173 for (left = 0; left < size; left++) {
174 hold = *(orig + left);
175 for (right = left - 1; 0 <= right; right--) {
176 if (get_order((orig + right), &hold)) {
179 *(orig + right + 1) = *(orig + right);
181 *(orig + right + 1) = hold;
186 mergesort_ranges(orig, size / 2, temp);
187 mergesort_ranges(orig + size / 2, size - size / 2, temp);
193 while (left < size / 2 && right < size) {
194 if (get_order((orig + left), (orig + right))) {
195 *(temp + i) = *(orig + left);
198 *(temp + i) = *(orig + right);
203 while (left < size / 2) {
204 *(temp + i) = *(orig + left);
208 while (right < size) {
209 *(temp + i) = *(orig + right);
214 memcpy(orig, temp, size * sizeof(struct range_t));