Subject: changing resolv.conf ?
To: None <tech-net@netbsd.org>
From: Assar Westerlund <assar@netbsd.org>
List: tech-net
Date: 07/26/2001 16:28:03
--=-=-=

I got tired of the problem of applications still using old (and
invalid) nameservers since that was what resolv.conf had when they
were started a few sleep-and-wakeup-dhcp cycles back.  Here's a simple
patch that will re-read /etc/resolv.conf when the timestamp has
changed.  Comments?

/assar


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment; filename=resolv.diff

Index: lib/libc/shlib_version
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/shlib_version,v
retrieving revision 1.107
diff -u -w -r1.107 shlib_version
--- lib/libc/shlib_version	2001/07/18 23:10:01	1.107
+++ lib/libc/shlib_version	2001/07/26 14:25:09
@@ -9,4 +9,4 @@
 # - libc/gen/timezone.c: remove; __timezone13 -> timezone.
 #
 major=12
-minor=77
+minor=78
Index: lib/libc/include/namespace.h
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/include/namespace.h,v
retrieving revision 1.65
diff -u -w -r1.65 namespace.h
--- lib/libc/include/namespace.h	2001/05/07 17:25:58	1.65
+++ lib/libc/include/namespace.h	2001/07/26 14:25:13
@@ -360,6 +360,7 @@
 #define regexec			_regexec
 #define regfree			_regfree
 #define registerrpc		_registerrpc
+#define res_condinit		_res_condinit
 #define res_init		_res_init
 #define res_mkquery		_res_mkquery
 #define res_query		_res_query
Index: lib/libc/net/getaddrinfo.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/net/getaddrinfo.c,v
retrieving revision 1.53
diff -u -w -r1.53 getaddrinfo.c
--- lib/libc/net/getaddrinfo.c	2001/01/25 22:50:55	1.53
+++ lib/libc/net/getaddrinfo.c	2001/07/26 14:25:13
@@ -1678,7 +1678,7 @@
 	rcode = NOERROR;
 	ancount = 0;
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+	if (res_condinit() == -1) {
 		h_errno = NETDB_INTERNAL;
 		return (-1);
 	}
@@ -1787,7 +1787,7 @@
 
 	hp = (HEADER *)(void *)target->answer;	/*XXX*/
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+	if (res_condinit() == -1) {
 		h_errno = NETDB_INTERNAL;
 		return (-1);
 	}
@@ -1927,7 +1927,7 @@
 	_DIAGASSERT(name != NULL);
 	/* XXX: target may be NULL??? */
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+	if (res_condinit() == -1) {
 		h_errno = NETDB_INTERNAL;
 		return (-1);
 	}
Index: lib/libc/net/gethnamaddr.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/net/gethnamaddr.c,v
retrieving revision 1.40
diff -u -w -r1.40 gethnamaddr.c
--- lib/libc/net/gethnamaddr.c	2001/04/26 12:55:32	1.40
+++ lib/libc/net/gethnamaddr.c	2001/07/26 14:25:13
@@ -530,7 +530,7 @@
 
 	_DIAGASSERT(name != NULL);
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+	if (res_condinit() == -1) {
 		h_errno = NETDB_INTERNAL;
 		return (NULL);
 	}
Index: lib/libc/net/getnetnamadr.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/net/getnetnamadr.c,v
retrieving revision 1.20
diff -u -w -r1.20 getnetnamadr.c
--- lib/libc/net/getnetnamadr.c	2000/12/20 20:51:08	1.20
+++ lib/libc/net/getnetnamadr.c	2001/07/26 14:25:13
@@ -357,7 +357,7 @@
 		{ 0 }
 	};
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+	if (res_condinit() == -1) {
 		h_errno = NETDB_INTERNAL;
 		return (NULL);
 	}
@@ -454,7 +454,7 @@
 
 	_DIAGASSERT(net != NULL);
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+	if (res_condinit() == -1) {
 		h_errno = NETDB_INTERNAL;
 		return (NULL);
 	}
Index: lib/libc/net/hesiod.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/net/hesiod.c,v
retrieving revision 1.16
diff -u -w -r1.16 hesiod.c
--- lib/libc/net/hesiod.c	2001/02/13 15:41:18	1.16
+++ lib/libc/net/hesiod.c	2001/07/26 14:25:13
@@ -421,7 +421,7 @@
 	_DIAGASSERT(name != NULL);
 
 		/* Make sure the resolver is initialized. */
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+	if (res_condinit() == -1)
 		return NULL;
 
 		/* Construct the query. */
Index: lib/libc/net/res_debug.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/net/res_debug.c,v
retrieving revision 1.30
diff -u -w -r1.30 res_debug.c
--- lib/libc/net/res_debug.c	2000/12/20 20:44:14	1.30
+++ lib/libc/net/res_debug.c	2001/07/26 14:25:13
@@ -290,7 +290,7 @@
 	_DIAGASSERT(msg != NULL);
 	_DIAGASSERT(file != NULL);
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+	if (res_condinit() == -1)
 		return;
 
 #define TruncTest(x) if (x > endMark) goto trunc
@@ -526,7 +526,7 @@
 	_DIAGASSERT(msg != NULL);
 	_DIAGASSERT(file != NULL);
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+	if (res_condinit() == -1) {
 		h_errno = NETDB_INTERNAL;
 		return (NULL);
 	}
Index: lib/libc/net/res_init.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/net/res_init.c,v
retrieving revision 1.36
diff -u -w -r1.36 res_init.c
--- lib/libc/net/res_init.c	2000/08/09 14:41:03	1.36
+++ lib/libc/net/res_init.c	2001/07/26 14:25:13
@@ -69,6 +69,7 @@
 #include <sys/param.h>
 #include <sys/socket.h>
 #include <sys/time.h>
+#include <sys/stat.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <arpa/nameser.h>
@@ -84,6 +85,7 @@
 
 #if defined(_LIBC) && defined(__weak_alias)
 __weak_alias(res_init,_res_init)
+__weak_alias(res_condinit,_res_condinit)
 #endif
 
 static void res_setoptions __P((char *, char *));
@@ -109,6 +111,10 @@
 struct __res_state_ext _res_ext;
 #endif /* INET6 */
 
+/* time stamp of configuration file */
+
+static struct timespec resolv_conf_ts;
+
 /*
  * Set up default settings.  If the configuration file exist, the values
  * there will have precedence.  Otherwise, the server address is set to
@@ -243,6 +249,13 @@
 	 line[sizeof(name) - 1] == '\t'))
 
 	if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
+	    int ret;
+	    struct stat sb;
+
+	    ret = fstat(fileno(fp), &sb);
+	    if (ret == 0)
+		resolv_conf_ts = sb.st_mtimespec;
+	    
 	    /* read the config file */
 	    while (fgets(buf, sizeof(buf), fp) != NULL) {
 		/* skip comments */
@@ -508,6 +521,20 @@
 	if ((cp = getenv("RES_OPTIONS")) != NULL)
 		res_setoptions(cp, "env");
 	_res.options |= RES_INIT;
+	return (0);
+}
+
+int
+res_condinit()
+{
+	struct stat sb;
+	int ret;
+
+	if (!(_res.options & RES_INIT))
+		return (res_init());
+	ret = stat(_PATH_RESCONF, &sb);
+	if (ret == 0 && timespeccmp(&sb.st_mtimespec, &resolv_conf_ts, >))
+		return (res_init());
 	return (0);
 }
 
Index: lib/libc/net/res_mkquery.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/net/res_mkquery.c,v
retrieving revision 1.21
diff -u -w -r1.21 res_mkquery.c
--- lib/libc/net/res_mkquery.c	2000/12/20 18:47:37	1.21
+++ lib/libc/net/res_mkquery.c	2001/07/26 14:25:13
@@ -106,7 +106,7 @@
 	/* data may be NULL */
 	/* newrr_in is not used */
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+	if (res_condinit() == -1) {
 		h_errno = NETDB_INTERNAL;
 		return (-1);
 	}
Index: lib/libc/net/res_query.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/net/res_query.c,v
retrieving revision 1.32
diff -u -w -r1.32 res_query.c
--- lib/libc/net/res_query.c	2000/12/20 20:51:08	1.32
+++ lib/libc/net/res_query.c	2001/07/26 14:25:13
@@ -120,7 +120,7 @@
 	_DIAGASSERT(name != NULL);
 	_DIAGASSERT(answer != NULL);
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+	if (res_condinit() == -1) {
 		h_errno = NETDB_INTERNAL;
 		return (-1);
 	}
@@ -203,7 +203,7 @@
 	_DIAGASSERT(name != NULL);
 	_DIAGASSERT(answer != NULL);
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+	if (res_condinit() == -1) {
 		h_errno = NETDB_INTERNAL;
 		return (-1);
 	}
@@ -347,7 +347,7 @@
 	/* domain may be NULL */
 	_DIAGASSERT(answer != NULL);
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+	if (res_condinit() == -1) {
 		h_errno = NETDB_INTERNAL;
 		return (-1);
 	}
Index: lib/libc/net/res_send.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/net/res_send.c,v
retrieving revision 1.33
diff -u -w -r1.33 res_send.c
--- lib/libc/net/res_send.c	2001/02/12 09:27:46	1.33
+++ lib/libc/net/res_send.c	2001/07/26 14:25:14
@@ -393,7 +393,7 @@
 	_DIAGASSERT(buf != NULL);
 	_DIAGASSERT(ans != NULL);
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+	if (res_condinit() == -1) {
 		/* errno should have been set by res_init() in this case. */
 		return (-1);
 	}
Index: lib/libc/net/sethostent.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/net/sethostent.c,v
retrieving revision 1.11
diff -u -w -r1.11 sethostent.c
--- lib/libc/net/sethostent.c	2000/01/22 22:19:16	1.11
+++ lib/libc/net/sethostent.c	2001/07/26 14:25:14
@@ -62,7 +62,7 @@
 	int stayopen;
 {
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+	if (res_condinit() == -1)
 		return;
 	if (stayopen)
 		_res.options |= RES_STAYOPEN | RES_USEVC;
Index: include/resolv.h
===================================================================
RCS file: /cvsroot/basesrc/include/resolv.h,v
retrieving revision 1.19
diff -u -w -r1.19 resolv.h
--- include/resolv.h	2000/08/09 14:40:52	1.19
+++ include/resolv.h	2001/07/26 14:25:21
@@ -281,6 +281,7 @@
 #ifdef BIND_RES_POSIX3
 #define	dn_expand	__dn_expand
 #define	res_init	__res_init
+#define	res_condinit	__res_condinit
 #define	res_query	__res_query
 #define	res_search	__res_search
 #define	res_querydomain	__res_querydomain
@@ -324,6 +325,7 @@
 int		dn_expand __P((const u_char *, const u_char *, const u_char *,
 			       char *, int));
 int		res_init __P((void));
+int		res_condinit __P((void));
 u_int		res_randomid __P((void));
 int		res_query __P((const char *, int, int, u_char *, int));
 int		res_search __P((const char *, int, int, u_char *, int));

--=-=-=--