Do not analyze if sort field selector is rubbish.
[debian/dhcpd-pools.git] / src / analyze.c
1 /*
2 ** Copyright (C) 2006- Sami Kerola <kerolasa@iki.fi>
3 **  
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.
8 ** 
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.
13 ** 
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.
17 */
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #include <stdlib.h>
24 #include <stdio.h>
25
26 #include "dhcpd-pools.h"
27
28 /* Clean up data */
29 int prepare_data(void)
30 {
31         unsigned long int i, j, k;
32
33         /* Sort leases */
34         qsort(leases, (size_t) num_leases, sizeof(long int), &intcomp);
35
36         /* Get rid of lease dublicates */
37         for (k = j = i = 0; i < num_leases; i++) {
38                 if (j != leases[i]) {
39                         leases[k] = leases[i];
40                         j = leases[i];
41                         k++;
42                 }
43         }
44         num_leases = k;
45
46         /* Delete touched IPs that are in use. */
47         j = 0;
48         for (i = 0; i < num_touches; i++) {
49                 if (bsearch
50                     (&touches[i], leases, (size_t) num_leases,
51                      sizeof(long int), &intcomp) == NULL) {
52                         touches[j] = touches[i];
53                         j++;
54                 }
55         }
56         num_touches = j;
57         qsort(touches, (size_t) num_touches, sizeof(long int), &intcomp);
58
59         /* Sort ranges */
60         qsort(ranges, (size_t) num_ranges, sizeof(struct range_t),
61               &rangecomp);
62
63         /* Sort backups */
64         if (0 < num_backups) {
65                 qsort(backups, (size_t) num_backups, sizeof(long int),
66                       &intcomp);
67         }
68
69         return 0;
70 }
71
72 /* Join leases and ranges into couter structs */
73 int do_counting(void)
74 {
75         struct range_t *range_p;
76         unsigned int i, j, k, m, block_size;
77
78         i = j = m = 0;
79         range_p = ranges;
80
81         /* Walk through ranges */
82         for (k = 0; k < num_ranges; k++) {
83                 /* Count IPs in use */
84                 for (; leases[i] < range_p->last_ip
85                      && (unsigned long) i < num_leases; i++) {
86                         if (leases[i] < range_p->first_ip) {
87                                 continue;
88                         }
89                         /* IP with in range */
90                         range_p->count++;
91                         if (range_p->shared_net) {
92                                 range_p->shared_net->used++;
93                         }
94                 }
95
96                 /* Count touched IPs */
97                 for (; touches[j] < range_p->last_ip
98                      && (unsigned long) j < num_touches; j++) {
99                         if (touches[j] < range_p->first_ip) {
100                                 continue;
101                         }
102                         /* IP with in range */
103                         range_p->touched++;
104                         if (range_p->shared_net) {
105                                 range_p->shared_net->touched++;
106                         }
107                 }
108
109                 /* Count backup IPs */
110                 if (0 < num_backups) {
111                         for (; backups[m] < range_p->last_ip
112                              && (unsigned long) m < num_touches; m++) {
113                                 if (touches[m] < range_p->first_ip) {
114                                         continue;
115                                 }
116                                 /* IP with in range */
117                                 range_p->backups++;
118                                 if (range_p->shared_net) {
119                                         range_p->shared_net->backups++;
120                                 }
121                         }
122                 }
123
124                 /* Size of range, shared net & all networks */
125                 block_size =
126                     (unsigned int) (range_p->last_ip - range_p->first_ip -
127                                     1);
128                 if (range_p->shared_net) {
129                         range_p->shared_net->available += block_size;
130                 }
131
132                 /* Go backwards one step so that not even a one IP will be
133                  * missed. This is possibly always unnecessary. */
134                 if (i) {
135                         i--;
136                 }
137                 if (j) {
138                         j--;
139                 }
140
141                 range_p++;
142         }
143
144         /* FIXME: During count of other shared networks default network and
145          * all networks got mixed to gether semantically. This fixes the
146          * problem, but is not elegant. */
147         shared_networks->available = 0;
148         shared_networks->used = 0;
149         shared_networks->touched = 0;
150         range_p = ranges;
151         for (k = 0; k < num_ranges; k++) {
152                 shared_networks->available +=
153                     range_p->last_ip - range_p->first_ip - 1;
154                 shared_networks->used += range_p->count;
155                 shared_networks->touched += range_p->touched;
156                 shared_networks->backups += range_p->backups;
157                 range_p++;
158         }
159
160         return 0;
161 }