Browse Source

Only update resolv.conf if changed (avoid logspam)

Steven Barth 11 years ago
parent
commit
486aa750a1
3 changed files with 47 additions and 2 deletions
  1. 16 2
      interface-ip.c
  2. 28 0
      utils.c
  3. 3 0
      utils.h

+ 16 - 2
interface-ip.c

@@ -781,10 +781,11 @@ interface_write_resolv_conf(void)
 	struct interface *iface;
 	char *path = alloca(strlen(resolv_conf) + 5);
 	FILE *f;
+	uint32_t crcold, crcnew;
 
 	sprintf(path, "%s.tmp", resolv_conf);
 	unlink(path);
-	f = fopen(path, "w");
+	f = fopen(path, "w+");
 	if (!f) {
 		D(INTERFACE, "Failed to open %s for writing\n", path);
 		return;
@@ -805,8 +806,21 @@ interface_write_resolv_conf(void)
 		if (!iface->proto_ip.no_dns)
 			write_resolv_conf_entries(f, &iface->proto_ip);
 	}
+	fflush(f);
+	rewind(f);
+	crcnew = crc32_file(f);
 	fclose(f);
-	if (rename(path, resolv_conf) < 0) {
+
+	crcold = crcnew + 1;
+	f = fopen(resolv_conf, "r");
+	if (f) {
+		crcold = crc32_file(f);
+		fclose(f);
+	}
+
+	if (crcold == crcnew) {
+		unlink(path);
+	} else if (rename(path, resolv_conf) < 0) {
 		D(INTERFACE, "Failed to replace %s\n", resolv_conf);
 		unlink(path);
 	}

+ 28 - 0
utils.c

@@ -140,3 +140,31 @@ format_macaddr(uint8_t *mac)
 
 	return str;
 }
+
+uint32_t
+crc32_file(FILE *fp)
+{
+	static uint32_t *crcvals = NULL;
+	if (!crcvals) {
+		crcvals = malloc(sizeof(*crcvals) * 256);
+
+		for (size_t i = 0; i < 256; ++i) {
+			uint32_t c = i;
+			for (size_t j = 0; j < 8; ++j)
+				c = (c & 1) ? (0xEDB88320 ^ (c >> 1)) : (c >> 1);
+			crcvals[i] = c;
+		}
+	}
+
+	uint8_t buf[1024];
+	size_t len;
+	uint32_t c = 0xFFFFFFFF;
+
+	do {
+		len = fread(buf, 1, sizeof(buf), fp);
+		for (size_t i = 0; i < len; ++i)
+			c = crcvals[(c ^ buf[i]) & 0xFF] ^ (c >> 8);
+	} while (len == sizeof(buf));
+
+	return c ^ 0xFFFFFFFF;
+}

+ 3 - 0
utils.h

@@ -14,6 +14,7 @@
 #ifndef __NETIFD_UTILS_H
 #define __NETIFD_UTILS_H
 
+#include <stdio.h>
 #include <libubox/list.h>
 #include <libubox/avl.h>
 #include <libubox/avl-cmp.h>
@@ -109,6 +110,8 @@ int parse_ip_and_netmask(int af, const char *str, void *addr, unsigned int *netm
 
 char * format_macaddr(uint8_t *mac);
 
+uint32_t crc32_file(FILE *fp);
+
 #ifdef __APPLE__
 #define s6_addr32	__u6_addr.__u6_addr32
 #endif