Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 20 Jun 2006 23:37:04 -0400
From:      Justin Hibbits <jrh29@eecs.cwru.edu>
To:        freebsd-current@freebsd.org
Subject:   ~/.hosts patch
Message-ID:  <C41481BC-89F3-457E-9FD0-CB85CE7B93E7@eecs.cwru.edu>

next in thread | raw e-mail | index | archive | help

--Apple-Mail-7-755132590
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=US-ASCII;
	delsp=yes;
	format=flowed

Hey folks, got an interesting patch.  This adds a ~/.hosts file  
(personal version of /etc/hosts).  It was written against 6-STABLE  
about a week before 6.1 was released, and has been sitting collecting  
dust for the last month and a half.  Currently it augments /etc/hosts  
instead of replacing it or prepending it.  Any comments?  One  
suggestion that was made was to make it an nss module so that it  
could be controlled by the admin.  It probably could use some cleanup  
as well, just putting it out here for proof of concept for now, and  
some direction.

- Justin
--Apple-Mail-7-755132590
Content-Transfer-Encoding: 7bit
Content-Type: application/octet-stream;
	x-unix-mode=0644;
	name="hosts.diff"
Content-Disposition: attachment;
	filename=hosts.diff

diff -u net2/getaddrinfo.c net/getaddrinfo.c
--- net2/getaddrinfo.c	Tue Jun 20 14:27:41 2006
+++ net/getaddrinfo.c	Mon May  1 18:19:17 2006
@@ -84,6 +84,7 @@
 #include <rpcsvc/yp_prot.h>
 #include <rpcsvc/ypclnt.h>
 #include <netdb.h>
+#include <pwd.h>
 #include <resolv.h>
 #include <string.h>
 #include <stdlib.h>
@@ -270,10 +271,10 @@
 static int addr4sort(struct addrinfo *);
 #endif
 static int _dns_getaddrinfo(void *, void *, va_list);
-static void _sethtent(FILE **);
+static void _sethtent(FILE **, int state, int oldstate);
 static void _endhtent(FILE **);
 static struct addrinfo *_gethtent(FILE **, const char *,
-	const struct addrinfo *);
+	const struct addrinfo *, int *state);
 static int _files_getaddrinfo(void *, void *, va_list);
 #ifdef YP
 static struct addrinfo *_yphostent(char *, const struct addrinfo *);
@@ -2003,12 +2004,34 @@
 }
 
 static void
-_sethtent(FILE **hostf)
+_sethtent(FILE **hostf, int state, int oldstate)
 {
 	if (!*hostf)
 		*hostf = fopen(_PATH_HOSTS, "r");
-	else
+	else if (state == 0 && oldstate == 0)
 		rewind(*hostf);
+	else {
+		if (geteuid() == getuid()){
+			char *home = getenv("HOME");
+			char *home_hostf;
+			struct passwd *pwd = getpwuid(geteuid());
+			if (pwd == NULL) {
+				*hostf = NULL;
+				return;
+			}
+			if (home == NULL)
+				home = pwd->pw_dir;
+			home_hostf = malloc(strlen(home) + sizeof("/.hosts") + 1);
+			if (home_hostf != NULL) {
+				strcpy(home_hostf, home);
+				strcat(home_hostf, "/.hosts");
+				*hostf = fopen(home_hostf, "r");
+				free(home_hostf);
+			}
+		}
+		else
+			*hostf = NULL;
+	}
 }
 
 static void
@@ -2021,7 +2044,7 @@
 }
 
 static struct addrinfo *
-_gethtent(FILE **hostf, const char *name, const struct addrinfo *pai)
+_gethtent(FILE **hostf, const char *name, const struct addrinfo *pai, int *state)
 {
 	char *p;
 	char *cp, *tname, *cname;
@@ -2033,8 +2056,16 @@
 	if (!*hostf && !(*hostf = fopen(_PATH_HOSTS, "r")))
 		return (NULL);
 again:
-	if (!(p = fgets(hostbuf, sizeof hostbuf, *hostf)))
-		return (NULL);
+	if (!(p = fgets(hostbuf, sizeof hostbuf, *hostf))) {
+		if (*state == 0)
+			_sethtent(hostf, 1, 0);
+		else
+			return (NULL);
+		*state = 1;
+		if (*hostf == NULL)
+			return(NULL);
+		goto again;
+	}
 	if (*p == '#')
 		goto again;
 	cp = strpbrk(p, "#\n");
@@ -2107,6 +2138,7 @@
 	struct addrinfo sentinel, *cur;
 	struct addrinfo *p;
 	FILE *hostf = NULL;
+	int state = 0;
 
 	name = va_arg(ap, char *);
 	pai = va_arg(ap, struct addrinfo *);
@@ -2114,8 +2146,8 @@
 	memset(&sentinel, 0, sizeof(sentinel));
 	cur = &sentinel;
 
-	_sethtent(&hostf);
-	while ((p = _gethtent(&hostf, name, pai)) != NULL) {
+	_sethtent(&hostf, 0, 0);
+	while ((p = _gethtent(&hostf, name, pai, &state)) != NULL) {
 		cur->ai_next = p;
 		while (cur && cur->ai_next)
 			cur = cur->ai_next;
diff -u net2/gethostbyht.c net/gethostbyht.c
--- net2/gethostbyht.c	Tue Jun 20 14:30:36 2006
+++ net/gethostbyht.c	Fri Apr 28 17:50:32 2006
@@ -55,17 +55,21 @@
 static char sccsid[] = "@(#)gethostnamadr.c	8.1 (Berkeley) 6/4/93";
 #endif /* LIBC_SCCS and not lint */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/net/gethostbyht.c,v 1.23 2005/04/30 20:07:01 ume Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/net/gethostbyht.c,v 1.23 2005/04/30 20:07:01 ume Exp $");
 
 #include <sys/param.h>
 #include <sys/socket.h>
+#include <sys/types.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <ctype.h>
+#include <pwd.h>
 #include <string.h>
 #include <stdarg.h>
+#include <unistd.h>
 #include <nsswitch.h>
 #include <arpa/nameser.h>	/* XXX */
 #include <resolv.h>		/* XXX */
@@ -74,10 +78,11 @@
 void
 _sethosthtent(int f, struct hostent_data *hed)
 {
-	if (!hed->hostf)
+	if (!hed->hostf || hed->user_hostf)
 		hed->hostf = fopen(_PATH_HOSTS, "r");
 	else
 		rewind(hed->hostf);
+	hed->user_hostf = 0;
 	hed->stayopen = f;
 }
 
@@ -87,6 +92,7 @@
 	if (hed->hostf && !hed->stayopen) {
 		(void) fclose(hed->hostf);
 		hed->hostf = NULL;
+		hed->user_hostf = 0;
 	}
 }
 
@@ -104,8 +110,37 @@
 	}
  again:
 	if (!(p = fgets(hostbuf, sizeof hostbuf, hed->hostf))) {
-		h_errno = HOST_NOT_FOUND;
-		return -1;
+		char *home_hostf;
+		struct passwd *pwd;
+		FILE *hostf_tmp;
+		if (hed->user_hostf == 1) {
+			goto enotfound;
+		}
+
+		if (geteuid() != getuid()) {
+			goto enotfound;
+		}
+
+		pwd = getpwuid(geteuid());
+		if (pwd == NULL) {
+			goto enotfound;
+		}
+		home_hostf = malloc(strlen(pwd->pw_dir) + sizeof("/.hosts") + 1);
+		if (home_hostf == NULL) {
+			goto enotfound;
+		}
+		strcpy(home_hostf, pwd->pw_dir);
+		strcat(home_hostf, "/.hosts");
+		/* Personal .hosts files are optional */
+		hostf_tmp = fopen(home_hostf, "r");
+		free(home_hostf);
+		if (!(hostf_tmp = fopen(home_hostf, "r"))) {
+			goto enotfound;
+		}
+		fclose(hed->hostf);
+		hed->hostf = hostf_tmp;
+		hed->user_hostf = 1;
+		goto again;
 	}
 	if (*p == '#')
 		goto again;
@@ -172,6 +207,10 @@
 	*q = NULL;
 	h_errno = NETDB_SUCCESS;
 	return 0;
+
+enotfound:
+	h_errno = HOST_NOT_FOUND;
+	return -1;
 }
 
 int
diff -u net2/name6.c net/name6.c
--- net2/name6.c	Tue Jun 20 14:30:36 2006
+++ net/name6.c	Sat Apr 29 01:36:48 2006
@@ -112,6 +112,7 @@
 
 #include <errno.h>
 #include <netdb.h>
+#include <pwd.h>
 #include <resolv.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -220,7 +221,7 @@
 static int	 comp_dst(const void *, const void *);
 static int	 gai_addr2scopetype(struct sockaddr *);
 
-static FILE	*_files_open(int *errp);
+static FILE	*_files_open(int *errp, int state);
 static int	 _files_ghbyname(void *, void *, va_list);
 static int	 _files_ghbyaddr(void *, void *, va_list);
 #ifdef YP
@@ -1229,10 +1230,29 @@
  */
 
 static FILE *
-_files_open(int *errp)
+_files_open(int *errp, int state)
 {
-	FILE *fp;
-	fp = fopen(_PATH_HOSTS, "r");
+	FILE *fp = NULL;
+	if (state == 0)
+		fp = fopen(_PATH_HOSTS, "r");
+	else if (geteuid() == getuid()){
+		char *home = getenv("HOME");
+		char *home_hostf;
+		struct passwd *pwd = getpwuid(geteuid());
+		if (pwd == NULL) {
+			*errp = NO_RECOVERY;
+			return NULL;
+		}
+		if (home == NULL)
+			home = pwd->pw_dir;
+		home_hostf = malloc(strlen(home) + sizeof("/.hosts") + 1);
+		if (home_hostf != NULL) {
+			strcpy(home_hostf, home);
+			strcat(home_hostf, "/.hosts");
+			fp = fopen(home_hostf, "r");
+			free(home_hostf);
+		}
+	}
 	if (fp == NULL)
 		*errp = NO_RECOVERY;
 	return fp;
@@ -1251,6 +1271,7 @@
 	char *aliases[MAXALIASES + 1], *addrs[2];
 	union inx_addr addrbuf;
 	char buf[BUFSIZ];
+	int state = 0;
 
 	name = va_arg(ap, const char *);
 	af = va_arg(ap, int);
@@ -1258,7 +1279,8 @@
 
 	*(struct hostent **)rval = NULL;
 
-	if ((fp = _files_open(errp)) == NULL)
+search:
+	if ((fp = _files_open(errp, state)) == NULL)
 		return NS_UNAVAIL;
 	rethp = hp = NULL;
 
@@ -1307,6 +1329,10 @@
 		rethp = _hpmerge(rethp, hp, errp);
 	}
 	fclose(fp);
+	if (rethp == NULL && state == 0) {
+		state = 1;
+		goto search;
+	}
 	*(struct hostent **)rval = rethp;
 	return (rethp != NULL) ? NS_SUCCESS : NS_NOTFOUND;
 }
@@ -1325,6 +1351,7 @@
 	char *aliases[MAXALIASES + 1], *addrs[2];
 	union inx_addr addrbuf;
 	char buf[BUFSIZ];
+	int state = 0;
 
 	addr = va_arg(ap, const void *);
 	addrlen = va_arg(ap, int);
@@ -1333,7 +1360,8 @@
 
 	*(struct hostent**)rval = NULL;
 
-	if ((fp = _files_open(errp)) == NULL)
+search:
+	if ((fp = _files_open(errp, state)) == NULL)
 		return NS_UNAVAIL;
 	hp = NULL;
 	while (fgets(buf, sizeof(buf), fp)) {
@@ -1363,6 +1391,10 @@
 		break;
 	}
 	fclose(fp);
+	if (hp == NULL && state == 0) {
+		state = 1;
+		goto search;
+	}
 	*(struct hostent **)rval = hp;
 	return (hp != NULL) ? NS_SUCCESS : NS_NOTFOUND;
 }
diff -u net2/netdb_private.h net/netdb_private.h
--- net2/netdb_private.h	Tue Jun 20 14:30:36 2006
+++ net/netdb_private.h	Thu Apr 27 22:31:13 2006
@@ -43,6 +43,7 @@
 	char hostbuf[_HOSTBUFSIZE];
 	FILE *hostf;
 	int stayopen;
+	int user_hostf;
 #ifdef YP
 	char *yp_domain;
 #endif

--Apple-Mail-7-755132590--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?C41481BC-89F3-457E-9FD0-CB85CE7B93E7>