summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Barth <steven@midlink.org>2013-02-19 09:36:23 +0100
committerSteven Barth <steven@midlink.org>2013-02-19 09:36:23 +0100
commit486aa750a164d41905beb61afec89268e3eb7f48 (patch)
tree0cec21957cdba8f99a4dcdeffad97c21102f4cb0
parent35d767f41931df99533fccd0fbf3aa844d869139 (diff)
downloadnetifd-486aa750a164d41905beb61afec89268e3eb7f48.tar.gz
Only update resolv.conf if changed (avoid logspam)
-rw-r--r--interface-ip.c18
-rw-r--r--utils.c28
-rw-r--r--utils.h3
3 files changed, 47 insertions, 2 deletions
diff --git a/interface-ip.c b/interface-ip.c
index df2904f..fc5a4a3 100644
--- a/interface-ip.c
+++ b/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);
}
diff --git a/utils.c b/utils.c
index 14e966a..6b53c22 100644
--- a/utils.c
+++ b/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;
+}
diff --git a/utils.h b/utils.h
index d675a5c..3a8e557 100644
--- a/utils.h
+++ b/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