-From b3c0d11d8bcf810b8f50f695ea36c8183fa4791a Mon Sep 17 00:00:00 2001
-From: Michael Tremer <michael.tremer@ipfire.org>
-Date: Mon, 28 Apr 2014 00:51:13 +0200
-Subject: [PATCH] Add support to read ISC DHCP lease file.
-
----
- Makefile | 2 +-
- src/cache.c | 13 +++-
- src/dnsmasq.c | 5 ++
- src/dnsmasq.h | 5 ++
- src/isc.c | 234 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- src/option.c | 2 +-
- 6 files changed, 256 insertions(+), 5 deletions(-)
- create mode 100644 src/isc.c
-
diff --git a/Makefile b/Makefile
index 292c8bd..5e0cdbe 100644
--- a/Makefile
+#endif
diff --git a/src/isc.c b/src/isc.c
new file mode 100644
-index 0000000..565e4e2
+index 0000000..5106442
--- /dev/null
+++ b/src/isc.c
-@@ -0,0 +1,234 @@
+@@ -0,0 +1,251 @@
+/* dnsmasq is Copyright (c) 2014 John Volpe, Simon Kelley and
+ Michael Tremer
+
+ struct isc_dhcp_lease* next;
+};
+
-+static struct isc_dhcp_lease* dhcp_lease_new() {
++static struct isc_dhcp_lease* dhcp_lease_new(const char* hostname) {
+ struct isc_dhcp_lease* lease = whine_malloc(sizeof(*lease));
+
-+ lease->name = NULL;
-+ lease->fqdn = NULL;
++ lease->name = strdup(hostname);
++ if (daemon->domain_suffix) {
++ asprintf(&lease->fqdn, "%s.%s", hostname, daemon->domain_suffix);
++ }
++ lease->expires = 0;
+ lease->next = NULL;
+
+ return lease;
+ return count ? 1 : 0;
+}
+
++static long get_utc_offset() {
++ time_t t = time(NULL);
++ struct tm* time_struct = localtime(&t);
++
++ return time_struct->tm_gmtoff;
++}
++
+static time_t parse_lease_time(const char* token_date, const char* token_time) {
+ time_t time = (time_t)(-1);
+ struct tm lease_time;
+
-+ static const int months[11] = {31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
-+
+ if (sscanf(token_date, "%d/%d/%d", &lease_time.tm_year, &lease_time.tm_mon, &lease_time.tm_mday) == 3) {
++ lease_time.tm_year -= 1900;
++ lease_time.tm_mon -= 1;
++
+ if (sscanf(token_time, "%d:%d:%d", &lease_time.tm_hour, &lease_time.tm_min, &lease_time.tm_sec) == 3) {
-+ /* There doesn't seem to be a universally available library function
-+ which converts broken-down _GMT_ time to seconds-in-epoch.
-+ The following was borrowed from ISC dhcpd sources, where
-+ it is noted that it might not be entirely accurate for odd seconds.
-+ Since we're trying to get the same answer as dhcpd, that's just
-+ fine here. */
-+ time = ((((((365 * (lease_time.tm_year - 1970) +
-+ (lease_time.tm_year - 1969) / 4 +
-+ (lease_time.tm_mon > 1 ? months[lease_time.tm_mon - 2] : 0) +
-+ (lease_time.tm_mon > 2 && !((lease_time.tm_year - 1972) & 3 )) +
-+ (lease_time.tm_mday - 1)) * 24) +
-+ lease_time.tm_hour) * 60) +
-+ lease_time.tm_mon) * 60) +
-+ lease_time.tm_sec;
++ time = mktime(&lease_time) + get_utc_offset();
+ }
+ }
+
+ return time;
+}
+
++static struct isc_dhcp_lease* find_lease(const char* hostname, struct isc_dhcp_lease* leases) {
++ struct isc_dhcp_lease* lease = leases;
++
++ while (lease) {
++ if (strcmp(hostname, lease->name) == 0) {
++ return lease;
++ }
++ lease = lease->next;
++ }
++
++ return NULL;
++}
++
+static off_t lease_file_size = (off_t)0;
+static ino_t lease_file_inode = (ino_t)0;
+
+ *dot = 0;
+ }
+
-+ struct isc_dhcp_lease* lease = dhcp_lease_new();
-+ lease->name = strdup(hostname);
-+ lease->addr = host_address;
-+ lease->expires = time_ends;
-+ lease->next = NULL;
++ // Search for an existing lease in the list
++ // with the given host name and update the data
++ // if needed.
++ struct isc_dhcp_lease* lease = find_lease(hostname, leases);
+
-+ if (daemon->domain_suffix) {
-+ asprintf(&lease->fqdn, "%s.%s", hostname, daemon->domain_suffix);
-+ }
++ // If no lease already exists, we create a new one
++ // and append it to the list.
++ if (!lease) {
++ lease = dhcp_lease_new(hostname);
+
-+ if (!leases)
++ lease->next = leases;
+ leases = lease;
-+ else
-+ leases->next = lease;
++ }
++
++ // Only update more recent leases.
++ if (lease->expires > time_ends)
++ continue;
++
++ lease->addr = host_address;
++ lease->expires = time_ends;
+ }
+ }
+ }
case 'l': /* --dhcp-leasefile */
daemon->lease_file = opt_string_alloc(arg);
break;
---
-1.9.0
-