X-Git-Url: http://git.asbjorn.biz/?p=debian%2Fdhcpd-pools.git;a=blobdiff_plain;f=src%2Fgetdata.c;h=5456b6599907c1e6b36a8e115c4963f61c04fab0;hp=2fc1f5f6a4738fda3e158ecbd78058d9eb2ee912;hb=HEAD;hpb=ee35f8bb1f94b177675ab84b963a0fe61cd201eb diff --git a/src/getdata.c b/src/getdata.c index 2fc1f5f..5456b65 100644 --- a/src/getdata.c +++ b/src/getdata.c @@ -1,19 +1,18 @@ -/* -** Copyright (C) 2006- Sami Kerola -** -** This program is free software; you can redistribute it and/or modify +/* http://dhcpd-pools.sourceforge.net/ +** Copyright 2006- Sami Kerola +** +** 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 . */ #ifdef HAVE_CONFIG_H @@ -27,7 +26,6 @@ #ifdef HAVE_STDLIB_H #include #else /* Not STDC_HEADERS */ -extern void exit(); extern char *malloc(); #define EXIT_FAILURE 1 /* Failing exit status. */ #define EXIT_SUCCESS 0 /* Successful exit status. */ @@ -45,22 +43,27 @@ extern char *malloc(); #include #include #include +#ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE 600 +#endif #include #include +#include #include +#include #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 = NULL; struct in_addr inp; struct stat lease_file_stats; + struct macaddr_t *macaddr_p = NULL; unsigned long leasesmallocsize; unsigned long touchesmallocsize; unsigned long backupsmallocsize; @@ -70,30 +73,31 @@ int parse_leases(void) 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; @@ -104,8 +108,12 @@ int parse_leases(void) 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); @@ -120,10 +128,12 @@ int parse_leases(void) else if (strstr(line, "binding state active")) { leases[num_leases] = htonl(inp.s_addr); num_leases++; + assert(!(leasesmallocsize < num_leases)); sw_active_lease = 1; } else if (strstr(line, " binding state free")) { touches[num_touches] = htonl(inp.s_addr); num_touches++; + assert(!(touchesmallocsize < num_touches)); } else if (strstr(line, " binding state backup")) { if (num_backups == 0) { backups = @@ -132,43 +142,35 @@ int parse_leases(void) } backups[num_backups] = htonl(inp.s_addr); num_backups++; + assert(!(backupsmallocsize < num_backups)); } - if ((sw_active_lease == 1) + if ((macaddr != NULL) + && (sw_active_lease == 1) && (strstr(line, "hardware ethernet"))) { nth_field(3, macstring, line); - macstring[strlen(macstring) - 1] = '\0'; - - if (config.output_format[0] == 'X') { - printf - ("\n\t%s\n\t%s\n\n", - ipstring, macstring); - }; - } - - if ((leasesmallocsize < num_leases) || - (touchesmallocsize < num_touches) || - (backupsmallocsize < num_backups)) { - printf("WARNING: running out of memory\n"); - printf("\tlease/touch/backup = %lu/%lu/%lu\n", - leasesmallocsize, touchesmallocsize, - backupsmallocsize); - printf("\tlease/touch/backup = %lu/%lu/%lu\n", - num_leases, num_touches, num_backups); - printf - ("Code should realloc() and init new memory, but no time to write that now!\n"); - exit(EXIT_FAILURE); + 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); + } + fclose(dhcpd_leases); 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; @@ -198,10 +200,10 @@ int nth_field(int n, char *dest, const char *src) /* dhcpd.conf interesting words */ int is_interesting_config_clause(char *s) { - if (strstr(s, "shared-network")) { - return 1; - } else if (strstr(s, "range")) { + if (strstr(s, "range")) { return 3; + } else if (strstr(s, "shared-network")) { + return 1; } else if (strstr(s, "include")) { return 4; } else { @@ -209,12 +211,9 @@ int is_interesting_config_clause(char *s) } } -/* TODO: 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, - struct shared_network_t *shared_p) +/* FIXME: This spagetti monster function need to be rewrote at least ones. */ +void parse_config(int is_include, char *config_file, + struct shared_network_t *shared_p) { FILE *dhcpd_config; int i = 0, newclause = true, argument = false, comment = @@ -224,36 +223,31 @@ char *parse_config(int is_include, char *config_file, struct in_addr inp; struct range_t *range_p; - char *last_shared_name; - last_shared_name = SHARED_NETWORKS_NAMES + shared_net_names; - word = safe_malloc(sizeof(char) * MAXLEN); if (is_include) { /* Default place holder for ranges "All networks". */ - shared_p->name = current_shared_name; + shared_p->name = shared_networks->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); @@ -273,7 +267,8 @@ char *parse_config(int is_include, char *config_file, } 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; } @@ -288,11 +283,11 @@ char *parse_config(int is_include, char *config_file, 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 = ' '; } @@ -319,13 +314,13 @@ char *parse_config(int is_include, char *config_file, braces--; /* End of shared-network */ 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; @@ -348,8 +343,9 @@ char *parse_config(int is_include, char *config_file, && (!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; @@ -372,37 +368,6 @@ char *parse_config(int is_include, char *config_file, i = 0; switch (argument) { - case 0: - /* printf ("nothing interesting: %s\n", word); */ - argument = 0; - break; - case 1: - /* printf ("shared-network named: %s\n", word); */ - strcpy(next_free_shared_name, word); - shared_p = - shared_networks + num_shared_networks; - num_shared_networks++; - shared_p++; - shared_p->name = next_free_shared_name; - shared_p->available = 0; - shared_p->used = 0; - shared_p->touched = 0; - shared_p->backups = 0; - /* Temporary abuse of argument variable */ - argument = - strlen(next_free_shared_name) + 1; - if (last_shared_name > - next_free_shared_name + argument) { - 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); - } - argument = 0; - braces_shared = braces; - break; case 2: /* printf ("range 2nd ip: %s\n", word); */ range_p = ranges + num_ranges; @@ -414,10 +379,14 @@ char *parse_config(int is_include, char *config_file, range_p->backups = 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); + if (RANGES < num_ranges + 1) { + RANGES *= 2; + ranges = + safe_realloc(ranges, + sizeof(struct + range_t) * + RANGES); + range_p = ranges + num_ranges; } newclause = true; break; @@ -425,29 +394,51 @@ char *parse_config(int is_include, char *config_file, /* 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; argument = 2; break; + case 1: + /* printf ("shared-network named: %s\n", word); */ + num_shared_networks++; + shared_p = + shared_networks + num_shared_networks; + shared_p->name = safe_strdup(word); + shared_p->available = 0; + shared_p->used = 0; + shared_p->touched = 0; + shared_p->backups = 0; + if (SHARED_NETWORKS < + num_shared_networks + 2) { + /* FIXME: make this + * away by reallocationg + * more space. */ + errx(EXIT_FAILURE, + "parse_config: increase default.h SHARED_NETWORKS and recompile"); + } + argument = 0; + braces_shared = braces; + break; case 4: /* printf ("include file: %s\n", word); */ argument = 0; - next_free_shared_name = - parse_config(false, word, - current_shared_name, - next_free_shared_name, - shared_p); + parse_config(false, word, shared_p); newclause = true; break; + case 0: + /* printf ("nothing interesting: %s\n", word); */ + argument = 0; + break; default: - eprintf - ("parse_config: This cannot happen, report a bug!"); - exit(EXIT_FAILURE); + warnx("impossible occurred, report a bug"); + assert(0); } } } free(word); - return next_free_shared_name; + fclose(dhcpd_config); + return; }