svn commit: r206784 - in stable/8: include lib/libc/net share/man/man5

Hajimu UMEMOTO ume at FreeBSD.org
Sun Apr 18 04:07:33 UTC 2010


Author: ume
Date: Sun Apr 18 04:07:32 2010
New Revision: 206784
URL: http://svn.freebsd.org/changeset/base/206784

Log:
  MFC r206155, r206267: Add capability to use a db version of
  services.  It is enabled by specifying `db' as source of
  services in /etc/nsswitch.conf.

Modified:
  stable/8/include/netdb.h
  stable/8/include/nsswitch.h
  stable/8/lib/libc/net/getservent.c
  stable/8/lib/libc/net/nsdispatch.3
  stable/8/share/man/man5/nsswitch.conf.5
  stable/8/share/man/man5/services.5
Directory Properties:
  stable/8/include/   (props changed)
  stable/8/lib/libc/   (props changed)
  stable/8/lib/libc/stdtime/   (props changed)
  stable/8/share/man/man5/   (props changed)

Modified: stable/8/include/netdb.h
==============================================================================
--- stable/8/include/netdb.h	Sun Apr 18 03:52:41 2010	(r206783)
+++ stable/8/include/netdb.h	Sun Apr 18 04:07:32 2010	(r206784)
@@ -86,6 +86,7 @@ typedef	__uint32_t	uint32_t;
 #define	_PATH_NETWORKS	"/etc/networks"
 #define	_PATH_PROTOCOLS	"/etc/protocols"
 #define	_PATH_SERVICES	"/etc/services"
+#define	_PATH_SERVICES_DB "/var/db/services.db"
 
 #define	h_errno (*__h_errno())
 

Modified: stable/8/include/nsswitch.h
==============================================================================
--- stable/8/include/nsswitch.h	Sun Apr 18 03:52:41 2010	(r206783)
+++ stable/8/include/nsswitch.h	Sun Apr 18 04:07:32 2010	(r206784)
@@ -65,6 +65,7 @@
  * currently implemented sources
  */
 #define NSSRC_FILES	"files"		/* local files */
+#define	NSSRC_DB	"db"		/* database */
 #define	NSSRC_DNS	"dns"		/* DNS; IN for hosts, HS for others */
 #define	NSSRC_NIS	"nis"		/* YP/NIS */
 #define	NSSRC_COMPAT	"compat"	/* passwd,group in YP compat mode */

Modified: stable/8/lib/libc/net/getservent.c
==============================================================================
--- stable/8/lib/libc/net/getservent.c	Sun Apr 18 03:52:41 2010	(r206783)
+++ stable/8/lib/libc/net/getservent.c	Sun Apr 18 04:07:32 2010	(r206784)
@@ -37,7 +37,9 @@ __FBSDID("$FreeBSD$");
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <arpa/inet.h>
+#include <db.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <limits.h>
 #include <netdb.h>
 #include <nsswitch.h>
@@ -94,6 +96,19 @@ NSS_TLS_HANDLING(files);
 static int files_servent(void *, void *, va_list);
 static int files_setservent(void *, void *, va_list);
 
+/* db backend declarations */
+struct db_state
+{
+        DB *db;
+	int stayopen;
+	int keynum;
+};
+static void db_endstate(void *);
+NSS_TLS_HANDLING(db);
+
+static int db_servent(void *, void *, va_list);
+static int db_setservent(void *, void *, va_list);
+
 #ifdef YP
 /* nis backend declarations */
 static 	int 	nis_servent(void *, void *, va_list);
@@ -263,6 +278,8 @@ files_servent(void *retval, void *mdata,
 		{ NULL, 0 }
 	};
 	ns_dtab compat_dtab[] = {
+		{ NSSRC_DB, db_servent,
+			(void *)((struct servent_mdata *)mdata)->how },
 #ifdef YP
 		{ NSSRC_NIS, nis_servent,
 			(void *)((struct servent_mdata *)mdata)->how },
@@ -452,6 +469,183 @@ files_setservent(void *retval, void *mda
 	return (NS_UNAVAIL);
 }
 
+/* db backend implementation */
+static	void
+db_endstate(void *p)
+{
+	DB *db;
+
+	if (p == NULL)
+		return;
+
+	db = ((struct db_state *)p)->db;
+	if (db != NULL)
+		db->close(db);
+
+	free(p);
+}
+
+static int
+db_servent(void *retval, void *mdata, va_list ap)
+{
+	char buf[BUFSIZ];
+	DBT key, data, *result;
+	DB *db;
+
+	struct db_state *st;
+	int rv;
+	int stayopen;
+
+	enum nss_lookup_type how;
+	char *name;
+	char *proto;
+	int port;
+
+	struct servent *serv;
+	char *buffer;
+	size_t bufsize;
+	int *errnop;
+
+	name = NULL;
+	proto = NULL;
+	how = (enum nss_lookup_type)mdata;
+	switch (how) {
+	case nss_lt_name:
+		name = va_arg(ap, char *);
+		proto = va_arg(ap, char *);
+		break;
+	case nss_lt_id:
+		port = va_arg(ap, int);
+		proto = va_arg(ap, char *);
+		break;
+	case nss_lt_all:
+		break;
+	default:
+		return NS_NOTFOUND;
+	};
+
+	serv = va_arg(ap, struct servent *);
+	buffer  = va_arg(ap, char *);
+	bufsize = va_arg(ap, size_t);
+	errnop = va_arg(ap,int *);
+
+	*errnop = db_getstate(&st);
+	if (*errnop != 0)
+		return (NS_UNAVAIL);
+
+	if (how == nss_lt_all && st->keynum < 0)
+		return (NS_NOTFOUND);
+
+	if (st->db == NULL) {
+		st->db = dbopen(_PATH_SERVICES_DB, O_RDONLY, 0, DB_HASH, NULL);
+		if (st->db == NULL) {
+			*errnop = errno;
+			return (NS_UNAVAIL);
+		}
+	}
+
+	stayopen = (how == nss_lt_all) ? 1 : st->stayopen;
+	db = st->db;
+
+	do {
+		switch (how) {
+		case nss_lt_name:
+			key.data = buf;
+			if (proto == NULL)
+				key.size = snprintf(buf, sizeof(buf),
+				    "\376%s", name);
+			else
+				key.size = snprintf(buf, sizeof(buf),
+				    "\376%s/%s", name, proto);
+			key.size++;
+			if (db->get(db, &key, &data, 0) != 0 ||
+			    db->get(db, &data, &key, 0) != 0) {
+				rv = NS_NOTFOUND;
+				goto db_fin;
+			}
+			result = &key;
+			break;
+		case nss_lt_id:
+			key.data = buf;
+			port = htons(port);
+			if (proto == NULL)
+				key.size = snprintf(buf, sizeof(buf),
+				    "\377%d", port);
+			else
+				key.size = snprintf(buf, sizeof(buf),
+				    "\377%d/%s", port, proto);
+			key.size++;
+			if (db->get(db, &key, &data, 0) != 0 ||
+			    db->get(db, &data, &key, 0) != 0) {
+				rv = NS_NOTFOUND;
+				goto db_fin;
+			}
+			result = &key;
+			break;
+		case nss_lt_all:
+			key.data = buf;
+			key.size = snprintf(buf, sizeof(buf), "%d",
+			    st->keynum++);
+			key.size++;
+			if (db->get(db, &key, &data, 0) != 0) {
+				st->keynum = -1;
+				rv = NS_NOTFOUND;
+				goto db_fin;
+			}
+			result = &data;
+			break;
+		}
+
+		rv = parse_result(serv, buffer, bufsize, result->data,
+		    result->size - 1, errnop);
+
+	} while (!(rv & NS_TERMINATE) && how == nss_lt_all);
+
+db_fin:
+	if (!stayopen && st->db != NULL) {
+		db->close(db);
+		st->db = NULL;
+	}
+
+	if (rv == NS_SUCCESS && retval != NULL)
+		*(struct servent **)retval = serv;
+
+	return (rv);
+}
+
+static int
+db_setservent(void *retval, void *mdata, va_list ap)
+{
+	DB *db;
+	struct db_state *st;
+	int rv;
+	int f;
+
+	rv = db_getstate(&st);
+	if (rv != 0)
+		return (NS_UNAVAIL);
+
+	switch ((enum constants)mdata) {
+	case SETSERVENT:
+		f = va_arg(ap, int);
+		st->stayopen |= f;
+		st->keynum = 0;
+		break;
+	case ENDSERVENT:
+		db = st->db;
+		if (db != NULL) {
+			db->close(db);
+			st->db = NULL;
+		}
+		st->stayopen = 0;
+		break;
+	default:
+		break;
+	};
+
+	return (NS_UNAVAIL);
+}
+
 /* nis backend implementation */
 #ifdef YP
 static 	void
@@ -638,6 +832,7 @@ compat_setservent(void *retval, void *md
 		{ NULL, 0 }
 	};
 	ns_dtab compat_dtab[] = {
+		{ NSSRC_DB, db_setservent, mdata },
 #ifdef YP
 		{ NSSRC_NIS, nis_setservent, mdata },
 #endif
@@ -924,6 +1119,7 @@ getservbyname_r(const char *name, const 
 #endif /* NS_CACHING */
 	static const ns_dtab dtab[] = {
 		{ NSSRC_FILES, files_servent, (void *)&mdata },
+		{ NSSRC_DB, db_servent, (void *)nss_lt_name },
 #ifdef YP
 		{ NSSRC_NIS, nis_servent, (void *)nss_lt_name },
 #endif
@@ -960,6 +1156,7 @@ getservbyport_r(int port, const char *pr
 #endif
 	static const ns_dtab dtab[] = {
 		{ NSSRC_FILES, files_servent, (void *)&mdata },
+		{ NSSRC_DB, db_servent, (void *)nss_lt_id },
 #ifdef YP
 		{ NSSRC_NIS, nis_servent, (void *)nss_lt_id },
 #endif
@@ -995,6 +1192,7 @@ getservent_r(struct servent *serv, char 
 #endif
 	static const ns_dtab dtab[] = {
 		{ NSSRC_FILES, files_servent, (void *)&mdata },
+		{ NSSRC_DB, db_servent, (void *)nss_lt_all },
 #ifdef YP
 		{ NSSRC_NIS, nis_servent, (void *)nss_lt_all },
 #endif
@@ -1027,6 +1225,7 @@ setservent(int stayopen)
 #endif
 	static const ns_dtab dtab[] = {
 		{ NSSRC_FILES, files_setservent, (void *)SETSERVENT },
+		{ NSSRC_DB, db_setservent, (void *)SETSERVENT },
 #ifdef YP
 		{ NSSRC_NIS, nis_setservent, (void *)SETSERVENT },
 #endif
@@ -1051,6 +1250,7 @@ endservent()
 #endif
 	static const ns_dtab dtab[] = {
 		{ NSSRC_FILES, files_setservent, (void *)ENDSERVENT },
+		{ NSSRC_DB, db_setservent, (void *)ENDSERVENT },
 #ifdef YP
 		{ NSSRC_NIS, nis_setservent, (void *)ENDSERVENT },
 #endif

Modified: stable/8/lib/libc/net/nsdispatch.3
==============================================================================
--- stable/8/lib/libc/net/nsdispatch.3	Sun Apr 18 03:52:41 2010	(r206783)
+++ stable/8/lib/libc/net/nsdispatch.3	Sun Apr 18 04:07:32 2010	(r206784)
@@ -32,7 +32,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 22, 2007
+.Dd April 4, 2010
 .Dt NSDISPATCH 3
 .Os
 .Sh NAME
@@ -176,6 +176,7 @@ While there is support for arbitrary sou
 .Bl -column NSSRC_COMPAT compat -offset indent
 .It Sy "#define	value"
 .It Dv NSSRC_FILES Ta """files""
+.It Dv NSSRC_DB Ta """db""
 .It Dv NSSRC_DNS Ta """dns""
 .It Dv NSSRC_NIS Ta """nis""
 .It Dv NSSRC_COMPAT Ta """compat""

Modified: stable/8/share/man/man5/nsswitch.conf.5
==============================================================================
--- stable/8/share/man/man5/nsswitch.conf.5	Sun Apr 18 03:52:41 2010	(r206783)
+++ stable/8/share/man/man5/nsswitch.conf.5	Sun Apr 18 04:07:32 2010	(r206784)
@@ -33,7 +33,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd December 23, 2008
+.Dd April 4, 2010
 .Dt NSSWITCH.CONF 5
 .Os
 .Sh NAME
@@ -72,6 +72,8 @@ Local files, such as
 .Pa /etc/hosts ,
 and
 .Pa /etc/passwd .
+.It db
+Local database.
 .It dns
 Internet Domain Name System.
 .Dq hosts

Modified: stable/8/share/man/man5/services.5
==============================================================================
--- stable/8/share/man/man5/services.5	Sun Apr 18 03:52:41 2010	(r206783)
+++ stable/8/share/man/man5/services.5	Sun Apr 18 04:07:32 2010	(r206784)
@@ -32,7 +32,7 @@
 .\"     @(#)services.5	8.1 (Berkeley) 6/5/93
 .\" $FreeBSD$
 .\"
-.Dd June 5, 1993
+.Dd April 4, 2010
 .Dt SERVICES 5
 .Os
 .Sh NAME
@@ -65,6 +65,18 @@ not interpreted by the routines which se
 Service names may contain any printable
 character other than a field delimiter, newline,
 or comment character.
+.Pp
+If 
+.Dq db
+is specified as source in the
+.Xr nsswitch.conf 5 ,
+.Pa /var/db/services.db
+is searched.
+The database in
+.Pa /var/db/services.db
+needs to be updated with
+.Xr services_mkdb 8
+after changes to the services file have been applied.
 .Sh NIS INTERACTION
 Access to the NIS
 .Pa services.byname
@@ -84,6 +96,8 @@ file resides in
 .El
 .Sh SEE ALSO
 .Xr getservent 3
+.Xr nsswitch.conf 5
+.Xr services_mkdb 8
 .Sh HISTORY
 The
 .Nm


More information about the svn-src-stable mailing list