-/*
-** Copyright (C) 2006- Sami Kerola <kerolasa@iki.fi>
-**
-** This program is free software; you can redistribute it and/or modify
+/* http://dhcpd-pools.sourceforge.net/
+** Copyright 2006- Sami Kerola <kerolasa@iki.fi>
+**
+** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
+** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
-**
+**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
-**
+**
** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#else /* Not STDC_HEADERS */
-extern void exit();
extern char *malloc();
#define EXIT_FAILURE 1 /* Failing exit status. */
#define EXIT_SUCCESS 0 /* Successful exit status. */
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
+#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 600
+#endif
#include <fcntl.h>
#include <errno.h>
#include <err.h>
#include <ctype.h>
+#include <assert.h>
#include "dhcpd-pools.h"
#include "defaults.h"
-/* Parse dhcpd.leases file. All performance boosts for this
- * function are wellcome */
+/* Parse dhcpd.leases file. All performance boosts for this function are
+ * wellcome */
int parse_leases(void)
{
FILE *dhcpd_leases;
- char *line, *ipstring, *macstring, *macstring2;
+ char *line, *ipstring, *macstring;
struct in_addr inp;
struct stat lease_file_stats;
+ struct macaddr_t *macaddr_p;
unsigned long leasesmallocsize;
unsigned long touchesmallocsize;
unsigned long backupsmallocsize;
dhcpd_leases = fopen(config.dhcpdlease_file, "r");
if (dhcpd_leases == NULL) {
- eprintf("parse_leases: %s:", config.dhcpdlease_file);
- exit(EXIT_FAILURE);
+ err(EXIT_FAILURE, "parse_leases: %s",
+ config.dhcpdlease_file);
}
-#ifdef POSIX_FADV_NOREUSE
- posix_fadvise((long) dhcpd_leases, 0, 0, POSIX_FADV_NOREUSE);
+#ifdef POSIX_FADV_WILLNEED
+ posix_fadvise((long) dhcpd_leases, 0, 0, POSIX_FADV_WILLNEED);
if (errno) {
- eprintf("parse_leases: fadvise:");
- exit(EXIT_FAILURE);
+ err(EXIT_FAILURE, "parse_leases: fadvise %s",
+ config.dhcpdlease_file);
}
-#endif /* POSIX_FADV_NOREUSE */
+#endif /* POSIX_FADV_WILLNEED */
#ifdef POSIX_FADV_SEQUENTIAL
posix_fadvise((long) dhcpd_leases, 0, 0, POSIX_FADV_SEQUENTIAL);
if (errno) {
- eprintf("parse_leases: fadvise:");
- exit(EXIT_FAILURE);
+ err(EXIT_FAILURE, "parse_leases: fadvise %s",
+ config.dhcpdlease_file);
}
#endif /* POSIX_FADV_SEQUENTIAL */
+
/* 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. */
+ * 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)) {
- eprintf("parse_leases: %s:", config.dhcpdlease_file);
- exit(EXIT_FAILURE);
+ err(EXIT_FAILURE, "parse_leases: %s",
+ config.dhcpdlease_file);
}
leasesmallocsize = (lease_file_stats.st_size / 250) + MAXLEN - 2;
touchesmallocsize = (lease_file_stats.st_size / 250) + MAXLEN - 2;
line = safe_malloc(sizeof(long int) * MAXLEN);
ipstring = safe_malloc(sizeof(long int) * MAXLEN);
- macstring = safe_malloc(sizeof(long int) * MAXLEN);
- macstring2 = safe_malloc(sizeof(long int) * MAXLEN);
+ if (config.output_format[0] == 'X') {
+ macstring = safe_malloc(sizeof(char) * 18);
+ macaddr = safe_malloc(sizeof(struct macaddr_t));
+ macaddr_p = macaddr;
+ macaddr_p->next = NULL;
+ }
while (!feof(dhcpd_leases)) {
fgets(line, MAXLEN, dhcpd_leases);
else if (strstr(line, "binding state active")) {
leases[num_leases] = htonl(inp.s_addr);
num_leases++;
- if (leasesmallocsize < num_leases) {
- errx(EXIT_FAILURE, "parse_leases: running out of lease memory, report a bug");
- }
+ assert(!(leasesmallocsize < num_leases));
sw_active_lease = 1;
} else if (strstr(line, " binding state free")) {
touches[num_touches] = htonl(inp.s_addr);
num_touches++;
- if (touchesmallocsize < num_touches) {
- errx(EXIT_FAILURE, "parse_leases: running out of touch memory, report a bug");
- }
+ assert(!(touchesmallocsize < num_touches));
} else if (strstr(line, " binding state backup")) {
if (num_backups == 0) {
backups =
}
backups[num_backups] = htonl(inp.s_addr);
num_backups++;
- if (backupsmallocsize < num_backups) {
- errx(EXIT_FAILURE, "parse_leases: running out of backup IPs memory, report a bug");
- }
+ assert(!(backupsmallocsize < num_backups));
}
- /* FIXME: move to output.c and use FILE *outfile */
- if ((config.output_format[0] == 'X')
+ if ((macaddr != NULL)
&& (sw_active_lease == 1)
&& (strstr(line, "hardware ethernet"))) {
nth_field(3, macstring, line);
- macstring[strlen(macstring) - 1] = '\0';
-
- printf
- ("<active_lease>\n\t<ip>%s</ip>\n\t<macaddress>%s</macaddress>\n</active_lease>\n",
- ipstring, macstring);
+ macstring[17] = '\0';
+ macaddr_p->ethernet = safe_strdup(macstring);
+ macaddr_p->ip = safe_strdup(ipstring);
+ macaddr_p->next =
+ safe_malloc(sizeof(struct macaddr_t));
+ macaddr_p = macaddr_p->next;
+ macaddr_p->next = NULL;
}
}
+ free(line);
+ free(ipstring);
+ if (macaddr != NULL) {
+ free(macstring);
+ }
return 0;
}
-/* Like strcpy but for field which is separated by white spaces.
- * Number of first field is 1 and not 0 like C programs should
- * have. Question of semantics, send mail to author if this
- * annoys. All performance boosts for this function are well
- * come. */
+/* Like strcpy but for field which is separated by white spaces. Number of
+ * first field is 1 and not 0 like C programs should have. Question of
+ * semantics, send mail to author if this annoys. All performance boosts for
+ * this function are well come. */
int nth_field(int n, char *dest, const char *src)
{
int i, j = 0, wordn = 0, len;
}
}
-/* TODO: This spagetti monster function need to be rewrote at
- * least ones. */
+/* FIXME: This spagetti monster function need to be rewrote at least ones. */
char *parse_config(int is_include, char *config_file,
char *current_shared_name,
char *next_free_shared_name,
/* Open configuration file */
dhcpd_config = fopen(config_file, "r");
if (dhcpd_config == NULL) {
- eprintf("parse_config: %s:", config_file);
- exit(EXIT_FAILURE);
+ err(EXIT_FAILURE, "parse_config: %s", config_file);
}
-#ifdef POSIX_FADV_NOREUSE
- posix_fadvise((long) dhcpd_config, 0, 0, POSIX_FADV_NOREUSE);
+#ifdef POSIX_FADV_WILLNEED
+ posix_fadvise((long) dhcpd_config, 0, 0, POSIX_FADV_WILLNEED);
if (errno) {
- eprintf("parse_config: fadvise:");
- exit(EXIT_FAILURE);
+ err(EXIT_FAILURE, "parse_config: fadvise %s", config_file);
}
-#endif /* POSIX_FADV_NOREUSE */
+#endif /* POSIX_FADV_WILLNEED */
#ifdef POSIX_FADV_SEQUENTIAL
posix_fadvise((long) dhcpd_config, 0, 0, POSIX_FADV_SEQUENTIAL);
if (errno) {
- eprintf("parse_config: fadvise:");
- exit(EXIT_FAILURE);
+ err(EXIT_FAILURE, "parse_config: fadvise %s", config_file);
}
#endif /* POSIX_FADV_SEQUENTIAL */
+
/* Very hairy stuff begins. */
while (!feof(dhcpd_config)) {
c = fgetc(dhcpd_config);
}
continue;
case '\n':
- /* New line resets comment section, but not if quoted */
+ /* New line resets comment section, but
+ * not if quoted */
if (quote == false) {
comment = false;
}
newclause = true;
i = 0;
} else if (argument == 2) {
- /* Range ends to ; and this hair in code make two
- * ranges wrote to gether like...
+ /* Range ends to ; and this hair in code
+ * make two ranges wrote to gether like...
*
* range 10.20.30.40 10.20.30.41;range 10.20.30.42 10.20.30.43;
- *
+ *
* ...to be interpreted correctly. */
c = ' ';
}
if (braces_shared == braces) {
current_shared_name =
shared_net_names;
- /* TODO: Using 1000 is lame, but works. */
+ /* FIXME: Using 1000 is lame, but
+ * works. */
braces_shared = 1000;
shared_p = shared_networks;
}
- /* Not literally true, but works for this program */
+ /* Not literally true, but works for this
+ * program */
newclause = true;
}
continue;
&& (!isspace(c) || quote == true)) {
word[i] = c;
i++;
- /* Long word which is almost causing overflow. Not any of words
- * this program is looking for are this long. */
+ /* Long word which is almost causing overflow. None
+ * of words are this long which the program is
+ * searching. */
if (MAXLEN < i) {
newclause = false;
i = 0;
range_p->shared_net = shared_p;
num_ranges++;
if (RANGES < num_ranges) {
- eprintf
- ("parse_config: Range space full! Increase RANGES and recompile.");
- exit(EXIT_FAILURE);
+ errx(EXIT_FAILURE,
+ "parse_config: Range space full! Increase RANGES and recompile.");
}
newclause = true;
break;
/* printf ("range 1nd ip: %s\n", word); */
range_p = ranges + num_ranges;
if (!(inet_aton(word, &inp))) {
- /* word was not ip, try again */
+ /* word was not ip, try
+ * again */
break;
}
range_p->first_ip = htonl(inp.s_addr) - 1;
shared_p->used = 0;
shared_p->touched = 0;
shared_p->backups = 0;
- /* Temporary abuse of argument variable */
+ /* Temporary abuse of argument
+ * variable */
argument =
strlen(next_free_shared_name) + 1;
- if (last_shared_name >
- next_free_shared_name + argument) {
+ if (next_free_shared_name + argument <
+ last_shared_name) {
next_free_shared_name += argument;
} else {
- /* TODO: make this go away by reallocationg more space. */
- eprintf
- ("parse_config: End of shared-network space, increase SHARED_NETWORKS_NAMES and recompile");
- exit(EXIT_FAILURE);
+ /* FIXME: make this go
+ * away by reallocationg
+ * more space. */
+ errx(EXIT_FAILURE,
+ "parse_config: End of shared-network space, increase SHARED_NETWORKS_NAMES and recompile");
}
argument = 0;
braces_shared = braces;
argument = 0;
break;
default:
- eprintf
- ("parse_config: This cannot happen, report a bug!");
- exit(EXIT_FAILURE);
+ warnx("impossible occurred, report a bug");
+ assert(0);
}
}
}