Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 3 Aug 1999 09:53:33 -0600
From:      Oscar Bonilla <obonilla@fisicc-ufm.edu>
To:        freebsd-hackers@freebsd.org
Subject:   NSS Project
Message-ID:  <19990803095333.A14120@fisicc-ufm.edu>

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

--ZPt4rx8FFjLCG7dd
Content-Type: text/plain; charset=us-ascii


Following on the NSS (Name Service Switch):

*Step One:  I ported the NetBSD implementation of nsdispatch(3) as implemented 
by Luke Mewburn. See attached patch to libc and new header file. I'm also
attaching the man page for /etc/nsswitch.conf. Right now it compiles,
installs, and works for some simple tests I've run.

*Step Two: make getpwent, getgrent, and friends actually use the nsdispatch
function. I've already started looking at the source, but am having trouble
with the NIS part. Maybe someone more knowledgeable could write the NIS
function.

Basically we have to reduce each of the functions to a simple nsdispatch 
call and then implement the real functions... Here's an example from
getpwent.c

/* Basically we reduce getpwent to a simple nsdispatch call */

struct passwd *
getpwent()
{
	int r;
	static const ns_dtab dtab[] = {
		NS_FILES_CB(_local_getpw, NULL)
		NS_DNS_CB(_dns_getpw, NULL)
		NS_NIS_CB(_nis_getpw, NULL)
		NS_COMPAT_CB(_compat_getpwent, NULL)
		{ 0 }
	};

	r = nsdispatch(NULL, dtab, NSDB_PASSWD, "getpwent", compatsrc,
	    _PW_KEYBYNUM);
	if (r != NS_SUCCESS)
		return (struct passwd *)NULL;
	return &_pw_passwd;
}

The we have to implement _local_getpw, _dns_getpw, _nis_getpw, 
and _compat_getpwent and make them behave as expected.

NetBSD seems to support having the passwd database on DNS using something
called HESIOD (I hadn't heard about it before). I don't think FreeBSD has
any sort of support for this. 

*Step Three: Implement _ldap_getpw :)

If anyone has any comments, suggestions, etc. I would appreciate it.

Regards,

-Oscar

-- 
For PGP Public Key: finger obonilla@fisicc-ufm.edu

--ZPt4rx8FFjLCG7dd
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="nsswitch.conf.5"

.\"	$NetBSD: nsswitch.conf.5,v 1.14 1999/03/17 20:19:47 garbled Exp $
.\"
.\"  Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
.\"  All rights reserved.
.\" 
.\"  This code is derived from software contributed to The NetBSD Foundation
.\"  by Luke Mewburn.
.\" 
.\"  Redistribution and use in source and binary forms, with or without
.\"  modification, are permitted provided that the following conditions
.\"  are met:
.\"  1. Redistributions of source code must retain the above copyright
.\"     notice, this list of conditions and the following disclaimer.
.\"  2. Redistributions in binary form must reproduce the above copyright
.\"     notice, this list of conditions and the following disclaimer in the
.\"     documentation and/or other materials provided with the distribution.
.\"  3. All advertising materials mentioning features or use of this software
.\"     must display the following acknowledgement:
.\"  	This product includes software developed by Luke Mewburn.
.\"  4. The name of the author may not be used to endorse or promote products
.\"     derived from this software without specific prior written permission.
.\"  
.\"  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\"  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\"  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\"  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
.\"  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
.\"  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
.\"  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
.\"  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
.\"  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
.\"  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd January 22, 1998
.Dt NSSWITCH.CONF 5
.Os
.Sh NAME
.Nm nsswitch.conf
.Nd name-service switch configuration file
.Sh DESCRIPTION
The
.Nm
file specifies how the
.Xr nsdispatch 3
(name-service switch dispatcher) routines in the C library should operate.
.Pp
The configuration file controls how a process looks up various databases
containing information regarding hosts, users (passwords), groups,
netgroups, etc.
Each database comes from a source (such as local files, DNS, and
.Tn NIS ) ,
and the order to look up the sources is specified in
.Nm nsswitch.conf .
.Pp
Each entry in 
.Nm
consists of a database name, and a space separated list of sources.
Each source can have an optional trailing criterion that determines
whether the next listed source is used, or the search terminates at
the current source.
Each criterion consists of one or more status codes, and actions to
take if that status code occurs.
.Ss Sources
The following sources are implemented:
.Bl -column "compat" -offset indent -compact
.Sy Source	Description
.It files	Local files, such as
.Pa /etc/hosts ,
and
.Pa /etc/passwd .
.It dns	Internet Domain Name System.
.Dq hosts
and
.Sq networks
use
.Sy IN
class entries, all other databases use
.Sy HS
class (Hesiod) entries.
.It nis	NIS (formerly YP)
.It compat	support
.Sq +/-
in the
.Dq passwd
and
.Dq group
databases.
If this is present, it must be the only source for that entry.
.El
.Ss Databases
The following databases are used by the following C library functions:
.Bl -column "netgroup" -offset indent -compact
.Sy Database	Used by
.It group	
.Xr getpwent 3
.It hosts	
.Xr gethostbyname 3
.It netgroup	
.Xr getnetgrent 3
.It networks	
.Xr getnetbyname 3
.It passwd	
.Xr getpwent 3
.It shells	
.Xr getusershell 3
.El
.Ss Status codes
The following status codes are available:
.Bl -column "tryagain" -offset indent -compact
.Sy Status	Description
.It success	The requested entry was found.
.It notfound	The entry is not present at this source.
.It tryagain	The source is busy, and may respond to retries.
.It unavail	The source is not responding, or entry is corrupt.
.El
.Ss Actions
For each of the status codes, one of two actions is possible:
.Bl -column "continue" -offset indent -compact
.Sy Action	Description
.It continue	Try the next source
.It return	Return with the current result
.El
.Ss Format of file
A
.Tn BNF
description of the syntax of
.Nm
is:
.Bl -column "<criterion>" -offset indent
.It <entry>	::=
<database> ":" [<source> [<criteria>]]*
.It <criteria>	::=
"[" <criterion>+ "]"
.It <criterion>	::=
<status> "=" <action>
.It <status>	::=
"success" | "notfound" | "unavail" | "tryagain"
.It <action>	::=
"return" | "continue"
.El
.Pp
Each entry starts on a new line in the file.
A
.Sq #
delimits a comment to end of line.
Blank lines are ignored.
A
.Sq \e
at the end of a line escapes the newline, and causes the next line to
be a continuation of the current line.
All entries are case-insensitive.
.Pp
The default criteria is to return on
.Dq success ,
and continue on anything else (i.e,
.Li [success=return notfound=continue unavail=continue tryagain=continue]
).
.Ss Compat mode: +/- syntax
In historical multi-source implementations, the
.Sq +
and
.Sq -
characters are used to specify the importing of user password and
group information from
.Tn NIS .
Although
.Nm
provides alternative methods of accessing distributed sources such as
.Tn NIS ,
specifying a sole source of
.Dq compat
will provide the historical behaviour.
.Pp
An alternative source for the information accessed via
.Sq +/-
can be used by specifying
.Dq passwd_compat: source .
.Dq source
in this case can be
.Sq dns ,
.Sq nis ,
or
any other source except for
.Sq files
and
.Sq compat .
.Ss Notes
Historically, many of the databases had enumeration functions, often of
the form
.Fn getXXXent .
These made sense when the databases were in local files, but don't make
sense or have lesser relevance when there are possibly multiple sources,
each of an unknown size.
The interfaces are still provided for compatibility, but the source
may not be able to provide complete entries, or duplicate entries may
be retrieved if multiple sources that contain similar information are
specified.
.Pp
To ensure compatibility with previous and current implementations, the
.Dq compat
source must appear alone for a given database.
.Ss Default source lists
If, for any reason,
.Nm nsswitch.conf
doesn't exist, or it has missing or corrupt entries,
.Xr nsdispatch 3
will default to an entry of
.Dq files
for the requested database.
Exceptions are:
.Bl -column passwd_compat "dns files" -offset indent
.Sy Database	Default source list
.It group	compat
.It group_compat	nis
.It hosts	dns files
.It netgroup	files [notfound=return] nis
.It passwd	compat
.It passwd_compat	nis
.El
.Sh FILES
.Bl -tag -width /etc/nsswitch.conf -compact
.It Pa /etc/nsswitch.conf
The file
.Nm
resides in
.Pa /etc .
.El
.Sh EXAMPLES
To lookup hosts in
.Pa /etc/hosts
and then from the DNS, and lookup user information from
.Tn NIS
then files, use:
.Bl -column "passwd:" -offset indent
.It hosts:	files dns
.It passwd:	nis [notfound=return] files
.It group:	nis [notfound=return] files
.El
.Pp
The criteria
.Dq [notfound=return]
sets a policy of "if the user is notfound in nis, don't try files."
This treats nis as the authoritive source of information, except
when the server is down.
.Sh SEE ALSO
.Xr nsdispatch 3 ,
.Xr resolv.conf 5 ,
.Xr named 8 ,
.Xr ypbind 8
.Sh HISTORY
The
.Nm
file format first appeared in
.Nx 1.4 .
.Sh AUTHORS
Luke Mewburn
.Aq lukem@netbsd.org
wrote this freely distributable name-service switch implementation,
using ideas from the
.Tn ULTRIX
.Xr svc.conf 5
and
.Tn Solaris
.Xr nsswitch.conf 4
manual pages.

--ZPt4rx8FFjLCG7dd
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="nsswitch.h"

/*	$NetBSD: nsswitch.h,v 1.6 1999/01/26 01:04:07 lukem Exp $	*/

/*-
 * Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Luke Mewburn.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *        This product includes software developed by the NetBSD
 *        Foundation, Inc. and its contributors.
 * 4. Neither the name of The NetBSD Foundation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _NSSWITCH_H
#define _NSSWITCH_H	1

#include <sys/types.h>

#if __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif

#ifndef _PATH_NS_CONF
#define _PATH_NS_CONF	"/etc/nsswitch.conf"
#endif

#define	NS_CONTINUE	0
#define	NS_RETURN	1

#define	NS_SUCCESS	(1<<0)		/* entry was found */
#define	NS_UNAVAIL	(1<<1)		/* source not responding, or corrupt */
#define	NS_NOTFOUND	(1<<2)		/* source responded 'no such entry' */
#define	NS_TRYAGAIN	(1<<3)		/* source busy, may respond to retrys */
#define	NS_STATUSMASK	0x000000ff	/* bitmask to get the status flags */

/*
 * currently implemented sources
 */
#define NSSRC_FILES	"files"		/* local files */
#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 */

/*
 * currently implemented databases
 */
#define NSDB_HOSTS		"hosts"
#define NSDB_GROUP		"group"
#define NSDB_GROUP_COMPAT	"group_compat"
#define NSDB_NETGROUP		"netgroup"
#define NSDB_NETWORKS		"networks"
#define NSDB_PASSWD		"passwd"
#define NSDB_PASSWD_COMPAT	"passwd_compat"
#define NSDB_SHELLS		"shells"

/*
 * suggested databases to implement
 */
#define NSDB_ALIASES		"aliases"
#define NSDB_AUTH		"auth"
#define NSDB_AUTOMOUNT		"automount"
#define NSDB_BOOTPARAMS		"bootparams"
#define NSDB_ETHERS		"ethers"
#define NSDB_EXPORTS		"exports"
#define NSDB_NETMASKS		"netmasks"
#define NSDB_PHONES		"phones"
#define NSDB_PRINTCAP		"printcap"
#define NSDB_PROTOCOLS		"protocols"
#define NSDB_REMOTE		"remote"
#define NSDB_RPC		"rpc"
#define NSDB_SENDMAILVARS	"sendmailvars"
#define NSDB_SERVICES		"services"
#define NSDB_TERMCAP		"termcap"
#define NSDB_TTYS		"ttys"

/*
 * ns_dtab - `nsswitch dispatch table'
 * contains an entry for each source and the appropriate function to call
 */
typedef struct {
	const char	 *src;
	int		(*callback)(void *retval, void *cb_data, va_list ap);
	void		 *cb_data;
} ns_dtab;

/*
 * macros to help build an ns_dtab[]
 */
#define NS_FILES_CB(F,C)	{ NSSRC_FILES,	F,	C },
#define NS_COMPAT_CB(F,C)	{ NSSRC_COMPAT,	F,	C },
 
#ifdef HESIOD
#   define NS_DNS_CB(F,C)	{ NSSRC_DNS,	F,	C },
#else
#   define NS_DNS_CB(F,C)
#endif

#ifdef YP
#   define NS_NIS_CB(F,C)	{ NSSRC_NIS,	F,	C },
#else
#   define NS_NIS_CB(F,C)
#endif

/*
 * ns_src - `nsswitch source'
 * used by the nsparser routines to store a mapping between a source
 * and its dispatch control flags for a given database.
 */
typedef struct {
	const char	*name;
	u_int32_t	 flags;
} ns_src;


/*
 * default sourcelist (if nsswitch.conf is missing, corrupt,
 * or the requested database doesn't have an entry.
 */
extern const ns_src __nsdefaultsrc[];


#ifdef _NS_PRIVATE

/*
 * private data structures for back-end nsswitch implementation
 */

/*
 * ns_dbt - `nsswitch database thang'
 * for each database in /etc/nsswitch.conf there is a ns_dbt, with its
 * name and a list of ns_src's containing the source information.
 */
typedef struct {
	const char	*name;		/* name of database */
	ns_src		*srclist;	/* list of sources */
	int		 srclistsize;	/* size of srclist */
} ns_dbt;

#endif /* _NS_PRIVATE */


#include <sys/cdefs.h>

__BEGIN_DECLS
extern	int	nsdispatch	__P((void *, const ns_dtab [], const char *,
				    const char *, const ns_src [], ...));

#ifdef _NS_PRIVATE
extern	void		 _nsdbtaddsrc __P((ns_dbt *, const ns_src *));
extern	void		 _nsdbtdump __P((const ns_dbt *));
extern	const ns_dbt	*_nsdbtget __P((const char *));
extern	void		 _nsdbtput __P((const ns_dbt *));
extern	void		 _nsyyerror __P((const char *));
extern	int		 _nsyylex __P((void));
extern	int		 _nsyylineno;
#endif /* _NS_PRIVATE */

__END_DECLS

#endif /* !_NSSWITCH_H */

--ZPt4rx8FFjLCG7dd
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=patch

diff -ruN libc.orig/net/Makefile.inc libc/net/Makefile.inc
--- libc.orig/net/Makefile.inc	Thu Jul 29 10:52:31 1999
+++ libc/net/Makefile.inc	Tue Aug  3 08:28:28 1999
@@ -13,18 +13,31 @@
 	inet_netof.c inet_network.c inet_ntoa.c inet_ntop.c \
 	inet_pton.c linkaddr.c map_v4v6.c ns_addr.c ns_name.c ns_netint.c \
 	ns_ntoa.c ns_parse.c ns_print.c ns_ttl.c nsap_addr.c \
+	nsdispatch.c nslexer.l nsparser.y \
 	rcmd.c recv.c res_comp.c res_data.c res_debug.c \
 	res_init.c res_mkquery.c res_mkupdate.c res_query.c res_send.c \
 	res_update.c send.c
 # not supported: iso_addr.c 
 
+CLEANFILES+= ${.CURDIR}/net/nsparser.c ${.CURDIR}/net/nsparser.h
+
+YFLAGS+= -d -p_nsyy
+LFLAGS+= -P_nsyy -o/dev/stdout
+
+nsparser.h: nsparser.y
+	${YACC} ${YFLAGS} -o ${.CURDIR}/net/nsparser.c ${.CURDIR}/net/nsparser.y
+
+nslexer.c: nslexer.l nsparser.h
+	${LEX} ${LFLAGS} ${.CURDIR}/net/nslexer.l | sed -e '/YY_BUF_SIZE/s/16384/1024/' > ${.TARGET}
+
+
 # machine-dependent net sources
 .include "${.CURDIR}/../libc/${MACHINE_ARCH}/net/Makefile.inc"
 
 .if ${LIB} == "c"
 MAN3+=	addr2ascii.3 byteorder.3 ethers.3 gethostbyname.3 \
 	getnetent.3 getprotoent.3 getservent.3 \
-	inet.3 linkaddr.3 rcmd.3 resolver.3
+	nsdispatch.3 inet.3 linkaddr.3 rcmd.3 resolver.3
 # not installed: iso_addr.3 ns.3
 
 MLINKS+=addr2ascii.3 ascii2addr.3
@@ -52,4 +65,5 @@
 MLINKS+=resolver.3 dn_comp.3 resolver.3 dn_expand.3 resolver.3 res_init.3 \
 	resolver.3 res_mkquery.3 resolver.3 res_query.3 \
 	resolver.3 res_search.3 resolver.3 res_send.3
+MLINKS+=nsdispatch.3
 .endif
diff -ruN libc.orig/net/nsdispatch.3 libc/net/nsdispatch.3
--- libc.orig/net/nsdispatch.3	Wed Dec 31 18:00:00 1969
+++ libc/net/nsdispatch.3	Mon Aug  2 10:45:24 1999
@@ -0,0 +1,225 @@
+.\"	$NetBSD: nsdispatch.3,v 1.8 1999/03/22 19:44:53 garbled Exp $
+.\"
+.\" Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Luke Mewburn.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"        This product includes software developed by the NetBSD
+.\"        Foundation, Inc. and its contributors.
+.\" 4. Neither the name of The NetBSD Foundation nor the names of its
+.\"    contributors may be used to endorse or promote products derived
+.\"    from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd January 19, 1999
+.Dt NSDISPATCH 3
+.Os
+.Sh NAME
+.Nm nsdispatch
+.Nd name-service switch dispatcher routine
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.Fd #include <nsswitch.h>
+.Ft int
+.Fo nsdispatch
+.Fa "void *retval"
+.Fa "const ns_dtab dtab[]"
+.Fa "const char *database"
+.Fa "const char *method"
+.Fa "const ns_src defaults[]"
+.Fa "..."
+.Fc
+.Sh DESCRIPTION
+The
+.Fn nsdispatch
+function invokes the callback functions specified in 
+.Va dtab
+in the order given in
+.Pa /etc/nsswitch.conf
+for the database
+.Va database
+until a successful entry is found.
+.Pp
+.Va retval
+is passed to each callback function to modify as necessary
+(to pass back to the caller of
+.Fn nsdispatch )
+.Pp
+.Va dtab
+is an array of
+.Va ns_dtab
+structures, which have the following format:
+.Bd -literal -offset indent
+typedef struct {
+	const char *src;
+	int (*cb)(void *retval, void *cb_data, va_list ap);
+	void *cb_data;
+} ns_dtab;
+.Ed
+.Pp
+.Bd -ragged -offset indent
+For each source type that is implemented, an entry with
+.Va src
+set to the name of the source,
+.Va cb
+defined as a function which handles that source, and
+.Va cb_data
+is used to pass arbritrary data to the callback function.
+The last entry in
+.Va dtab
+should contain
+.Dv NULL
+values for
+.Va src , 
+.Va cb ,
+and
+.Va cb_data .
+.Ed
+.Pp
+.Va method
+is usually the name of the function calling
+.Fn nsdispatch .
+When dynamic loading is supported, a symbol constructed from
+.Va database ,
+the current source, and
+.Va method
+will be used as the name to invoke the dynamically loaded function.
+.Pp
+.Va defaults
+contains a list of default sources to try in the case of
+a missing or corrupt
+.Xr nsswitch.conf 5 ,
+or if there isn't a relevant entry for
+.Va database .
+It is an array of
+.Va ns_src
+structures, which have the following format:
+.Bd -literal -offset indent
+typedef struct {
+	const char *src;
+	u_int32_t flags;
+} ns_src;
+.Ed
+.Pp
+.Bd -ragged -offset indent
+For each default source type, an entry with
+.Va src
+set to the name of the source, and
+.Va flags
+set to the relevant flags
+(usually 
+.Dv NS_SUCCESS ;
+refer to
+.Sx Callback return values
+for more information).
+The last entry in
+.Va defaults
+should have
+.Va src
+set to
+.Dv NULL
+and
+.Va flags
+set to 0.
+.Pp
+For convenience, a global variable defined as:
+.Dl extern const ns_src __nsdefaultsrc[];
+exists which contains a single default entry for
+.Sq files
+for use by callers which don't require complicated default rules.
+.Ed
+.Pp
+.Va Sq ...
+are optional extra arguments, which
+are passed to the appropriate callback function as a variable argument
+list of the type
+.Va va_list .
+.Ss Valid source types
+Whilst there is support for arbitrary sources, the following
+#defines for commonly implementated sources are available:
+.Bl -column NS_COMPAT COMPAT -offset indent
+.Sy #define	value
+.It NSSRC_FILES	"files"
+.It NSSRC_DNS	"dns"
+.It NSSRC_NIS	"nis"
+.It NSSRC_COMPAT	"compat"
+.El
+.Pp
+Refer to
+.Xr nsswitch.conf 5
+for a complete description of what each source type is.
+.Pp
+.Ss Callback return values
+The callback functions should return one of the following values
+depending upon status of the lookup:
+.Bl -column NS_NOTFOUND -offset indent
+.Sy "Return value"	Status code
+.It NS_SUCCESS	success
+.It NS_NOTFOUND	notfound
+.It NS_UNAVAIL	unavail
+.It NS_TRYAGAIN	tryagain
+.El
+.Pp
+Refer to
+.Xr nsswitch.conf 5
+for a complete description of what each status code is.
+.Pp
+.Nm
+returns the value of the callback that caused the dispatcher to finish,
+or NS_NOTFOUND otherwise.
+.Sh SEE ALSO
+.Xr hesiod 3 ,
+.Xr stdarg 3 ,
+.Xr ypclnt 3 ,
+.Xr nsswitch.conf 5
+.Sh HISTORY
+The
+.Nm
+routines first appeared in
+.Nx 1.4 .
+.Sh AUTHORS
+Luke Mewburn
+.Aq lukem@netbsd.org
+wrote this freely distributable name-service switch implementation,
+using ideas from the
+.Tn ULTRIX
+.Xr svc.conf 5
+and
+.Tn Solaris
+.Xr nsswitch.conf 4
+manual pages.
+.Sh BUGS
+The
+.Nm
+routines are not thread safe.
+This will be rectified in the future.
+.Pp
+Currently there is no support for dynamically loadable dispatcher callback
+functions.
+It is anticipated that this will be added in the future in the back-end
+without requiring changes to code that invokes
+.Fn nsdispatch .
diff -ruN libc.orig/net/nsdispatch.c libc/net/nsdispatch.c
--- libc.orig/net/nsdispatch.c	Wed Dec 31 18:00:00 1969
+++ libc/net/nsdispatch.c	Mon Aug  2 10:52:34 1999
@@ -0,0 +1,274 @@
+/*	$NetBSD: nsdispatch.c,v 1.9 1999/01/25 00:16:17 lukem Exp $	*/
+
+/*-
+ * Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Luke Mewburn.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: nsdispatch.c,v 1.9 1999/01/25 00:16:17 lukem Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <err.h>
+#include <fcntl.h>
+#define _NS_PRIVATE
+#include <nsswitch.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef __weak_alias
+__weak_alias(nsdispatch,_nsdispatch);
+#endif
+
+
+/*
+ * default sourcelist: `files'
+ */
+const ns_src __nsdefaultsrc[] = {
+	{ NSSRC_FILES, NS_SUCCESS },
+	{ 0 },
+};
+
+
+static	int			 _nsmapsize = 0;
+static	ns_dbt			*_nsmap = NULL;
+
+/*
+ * size of dynamic array chunk for _nsmap and _nsmap[x].srclist
+ */
+#define NSELEMSPERCHUNK		8
+
+
+int	_nscmp __P((const void *, const void *));
+
+
+int
+_nscmp(a, b)
+	const void *a;
+	const void *b;
+{
+	return (strcasecmp(((const ns_dbt *)a)->name,
+	    ((const ns_dbt *)b)->name));
+}
+
+
+void
+_nsdbtaddsrc(dbt, src)
+	ns_dbt		*dbt;
+	const ns_src	*src;
+{
+	if ((dbt->srclistsize % NSELEMSPERCHUNK) == 0) {
+		dbt->srclist = (ns_src *)realloc(dbt->srclist,
+		    (dbt->srclistsize + NSELEMSPERCHUNK) * sizeof(ns_src));
+		if (dbt->srclist == NULL)
+			err(1, "nsdispatch: memory allocation failure");
+	}
+	memmove(&dbt->srclist[dbt->srclistsize++], src, sizeof(ns_src));
+}
+
+
+void
+_nsdbtdump(dbt)
+	const ns_dbt *dbt;
+{
+	int i;
+
+	printf("%s (%d source%s):", dbt->name, dbt->srclistsize,
+	    dbt->srclistsize == 1 ? "" : "s");
+	for (i = 0; i < dbt->srclistsize; i++) {
+		printf(" %s", dbt->srclist[i].name);
+		if (!(dbt->srclist[i].flags &
+		    (NS_UNAVAIL|NS_NOTFOUND|NS_TRYAGAIN)) &&
+		    (dbt->srclist[i].flags & NS_SUCCESS))
+			continue;
+		printf(" [");
+		if (!(dbt->srclist[i].flags & NS_SUCCESS))
+			printf(" SUCCESS=continue");
+		if (dbt->srclist[i].flags & NS_UNAVAIL)
+			printf(" UNAVAIL=return");
+		if (dbt->srclist[i].flags & NS_NOTFOUND)
+			printf(" NOTFOUND=return");
+		if (dbt->srclist[i].flags & NS_TRYAGAIN)
+			printf(" TRYAGAIN=return");
+		printf(" ]");
+	}
+	printf("\n");
+}
+
+
+const ns_dbt *
+_nsdbtget(name)
+	const char	*name;
+{
+	static	time_t	 confmod;
+
+	struct stat	 statbuf;
+	ns_dbt		 dbt;
+
+	extern	FILE 	*_nsyyin;
+	extern	int	 _nsyyparse __P((void));
+
+	dbt.name = name;
+
+	if (confmod) {
+		if (stat(_PATH_NS_CONF, &statbuf) == -1)
+			return (NULL);
+		if (confmod < statbuf.st_mtime) {
+			int i, j;
+
+			for (i = 0; i < _nsmapsize; i++) {
+				for (j = 0; j < _nsmap[i].srclistsize; j++) {
+					if (_nsmap[i].srclist[j].name != NULL) {
+						/*LINTED const cast*/
+						free((void *)
+						    _nsmap[i].srclist[j].name);
+					}
+				}
+				if (_nsmap[i].srclist)
+					free(_nsmap[i].srclist);
+				if (_nsmap[i].name) {
+					/*LINTED const cast*/
+					free((void *)_nsmap[i].name);
+				}
+			}
+			if (_nsmap)
+				free(_nsmap);
+			_nsmap = NULL;
+			_nsmapsize = 0;
+			confmod = 0;
+		}
+	}
+	if (!confmod) {
+		if (stat(_PATH_NS_CONF, &statbuf) == -1)
+			return (NULL);
+		_nsyyin = fopen(_PATH_NS_CONF, "r");
+		if (_nsyyin == NULL)
+			return (NULL);
+		_nsyyparse();
+		(void)fclose(_nsyyin);
+		qsort(_nsmap, (size_t)_nsmapsize, sizeof(ns_dbt), _nscmp);
+		confmod = statbuf.st_mtime;
+	}
+	return (bsearch(&dbt, _nsmap, (size_t)_nsmapsize, sizeof(ns_dbt),
+	    _nscmp));
+}
+
+
+void
+_nsdbtput(dbt)
+	const ns_dbt *dbt;
+{
+	int	i;
+
+	for (i = 0; i < _nsmapsize; i++) {
+		if (_nscmp(dbt, &_nsmap[i]) == 0) {
+					/* overwrite existing entry */
+			if (_nsmap[i].srclist != NULL)
+				free(_nsmap[i].srclist);
+			memmove(&_nsmap[i], dbt, sizeof(ns_dbt));
+			return;
+		}
+	}
+
+	if ((_nsmapsize % NSELEMSPERCHUNK) == 0) {
+		_nsmap = (ns_dbt *)realloc(_nsmap,
+		    (_nsmapsize + NSELEMSPERCHUNK) * sizeof(ns_dbt));
+		if (_nsmap == NULL)
+			err(1, "nsdispatch: memory allocation failure");
+	}
+	memmove(&_nsmap[_nsmapsize++], dbt, sizeof(ns_dbt));
+}
+
+
+int
+#if __STDC__
+nsdispatch(void *retval, const ns_dtab disp_tab[], const char *database,
+	    const char *method, const ns_src defaults[], ...)
+#else
+nsdispatch(retval, disp_tab, database, method, defaults, va_alist)
+	void		*retval;
+	const ns_dtab	 disp_tab[];
+	const char	*database;
+	const char	*method;
+	const ns_src	 defaults[];
+	va_dcl
+#endif
+{
+	va_list		 ap;
+	int		 i, curdisp, result;
+	const ns_dbt	*dbt;
+	const ns_src	*srclist;
+	int		 srclistsize;
+
+	dbt = _nsdbtget(database);
+	if (dbt != NULL) {
+		srclist = dbt->srclist;
+		srclistsize = dbt->srclistsize;
+	} else {
+		srclist = defaults;
+		srclistsize = 0;
+		while (srclist[srclistsize].name != NULL)
+			srclistsize++;
+	}
+	result = 0;
+
+	for (i = 0; i < srclistsize; i++) {
+		for (curdisp = 0; disp_tab[curdisp].src != NULL; curdisp++)
+			if (strcasecmp(disp_tab[curdisp].src,
+			    srclist[i].name) == 0)
+				break;
+		result = 0;
+		if (disp_tab[curdisp].callback) {
+#if __STDC__
+			va_start(ap, defaults);
+#else
+			va_start(ap);
+#endif
+			result = disp_tab[curdisp].callback(retval,
+			    disp_tab[curdisp].cb_data, ap);
+			va_end(ap);
+			if (result & srclist[i].flags) {
+				break;
+			}
+		}
+	}
+	return (result ? result : NS_NOTFOUND);
+}
diff -ruN libc.orig/net/nslexer.l libc/net/nslexer.l
--- libc.orig/net/nslexer.l	Wed Dec 31 18:00:00 1969
+++ libc/net/nslexer.l	Mon Aug  2 10:45:24 1999
@@ -0,0 +1,115 @@
+%{
+/*	$NetBSD: nslexer.l,v 1.3 1999/01/25 00:16:17 lukem Exp $	*/
+
+/*-
+ * Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Luke Mewburn.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: nslexer.l,v 1.3 1999/01/25 00:16:17 lukem Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <ctype.h>
+#include <err.h>
+#define _NS_PRIVATE
+#include <nsswitch.h>
+#include <string.h>
+
+#include "nsparser.h"
+
+#define YY_NO_UNPUT
+
+%}
+
+%option yylineno
+
+BLANK		[ \t]
+CR		\n
+STRING		[a-zA-Z][a-zA-Z0-9_]*
+
+%%
+
+{BLANK}+	;			/* skip whitespace */
+
+#.*		;			/* skip comments */
+
+\\{CR}		;			/* allow continuation */
+
+{CR}		return NL;
+
+[sS][uU][cC][cC][eE][sS][sS]		return SUCCESS;
+[uU][nN][aA][vV][aA][iI][lL]		return UNAVAIL;
+[nN][oO][tT][fF][oO][uU][nN][dD]	return NOTFOUND;
+[tT][rR][yY][aA][gG][aA][iI][nN]	return TRYAGAIN;
+
+[rR][eE][tT][uU][rR][nN]		return RETURN;
+[cC][oO][nN][tT][iI][nN][uU][eE]	return CONTINUE;
+
+{STRING}	{
+			char *p;
+			int i;
+
+			if ((p = strdup(yytext)) == NULL)
+				err(1, "nsdispatch: memory allocation failure");
+
+			for (i = 0; i < strlen(p); i++) {
+				if (isupper((unsigned char)p[i]))
+					p[i] = tolower((unsigned char)p[i]);
+			}
+			_nsyylval.str = p;
+			return STRING;
+		}
+
+[:=\[\]]	return yytext[0];
+
+.		;	/* ignore all else */
+
+%%
+
+#undef _nsyywrap
+int
+_nsyywrap()
+{
+	return 1;
+} /* _nsyywrap */
+
+void
+_nsyyerror(msg)
+	const char *msg;
+{
+
+	 warnx("%s line %d: %s at '%s'", _PATH_NS_CONF, yylineno, msg, yytext);
+} /* _nsyyerror */
diff -ruN libc.orig/net/nsparser.y libc/net/nsparser.y
--- libc.orig/net/nsparser.y	Wed Dec 31 18:00:00 1969
+++ libc/net/nsparser.y	Mon Aug  2 10:45:24 1999
@@ -0,0 +1,174 @@
+%{
+/*	$NetBSD: nsparser.y,v 1.3 1999/01/25 00:16:18 lukem Exp $	*/
+
+/*-
+ * Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Luke Mewburn.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: nsparser.y,v 1.3 1999/01/25 00:16:18 lukem Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <err.h>
+#define _NS_PRIVATE
+#include <nsswitch.h>
+#include <stdio.h>
+#include <string.h>
+
+
+static	void	_nsaddsrctomap __P((const char *));
+
+static	ns_dbt		curdbt;
+static	ns_src		cursrc;
+%}
+
+%union {
+	char *str;
+	int   mapval;
+}
+
+%token	NL
+%token	SUCCESS UNAVAIL NOTFOUND TRYAGAIN
+%token	RETURN CONTINUE
+%token	<str> STRING
+
+%type	<mapval> Status Action
+
+%%
+
+File
+	:	/* empty */
+	| Lines
+	;
+
+Lines
+	: Entry
+	| Lines Entry
+	;
+
+Entry
+	: NL
+	| Database ':' NL
+	| Database ':' Srclist NL
+		{
+			_nsdbtput(&curdbt);
+		}
+	;
+
+Database
+	: STRING
+		{
+			curdbt.name = yylval.str;
+			curdbt.srclist = NULL;
+			curdbt.srclistsize = 0;
+		}
+	;
+
+Srclist
+	: Item
+	| Srclist Item
+	;
+
+Item
+	: STRING
+		{
+			cursrc.flags = NS_SUCCESS;
+			_nsaddsrctomap($1);
+		}
+	| STRING '[' { cursrc.flags = NS_SUCCESS; } Criteria ']'
+		{
+			_nsaddsrctomap($1);
+		}
+	;
+
+Criteria
+	: Criterion
+	| Criteria Criterion
+	;
+
+Criterion
+	: Status '=' Action
+		{
+			if ($3)		/* if action == RETURN set RETURN bit */
+				cursrc.flags |= $1;  
+			else		/* else unset it */
+				cursrc.flags &= ~$1;
+		}
+	;
+
+Status
+	: SUCCESS	{ $$ = NS_SUCCESS; }
+	| UNAVAIL	{ $$ = NS_UNAVAIL; }
+	| NOTFOUND	{ $$ = NS_NOTFOUND; }
+	| TRYAGAIN	{ $$ = NS_TRYAGAIN; }
+	;
+
+Action
+	: RETURN	{ $$ = 1L; }
+	| CONTINUE	{ $$ = 0L; }
+	;
+
+%%
+
+static void
+_nsaddsrctomap(elem)
+	const char *elem;
+{
+	int		i, lineno;
+	extern int	_nsyylineno;
+	extern char *	_nsyytext;
+
+	lineno = _nsyylineno - (*_nsyytext == '\n' ? 1 : 0);
+	if (curdbt.srclistsize > 0) {
+		if ((strcasecmp(elem, NSSRC_COMPAT) == 0) ||
+		    (strcasecmp(curdbt.srclist[0].name, NSSRC_COMPAT) == 0)) {
+				/* XXX: syslog the following */
+			warnx("%s line %d: 'compat' used with other sources",
+			    _PATH_NS_CONF, lineno);
+			return;
+		}
+	}
+	for (i = 0; i < curdbt.srclistsize; i++) {
+		if (strcasecmp(curdbt.srclist[i].name, elem) == 0) {
+				/* XXX: syslog the following */
+			warnx("%s line %d: duplicate source '%s'",
+			    _PATH_NS_CONF, lineno, elem);
+			return;
+		}
+	}
+	cursrc.name = elem;
+	_nsdbtaddsrc(&curdbt, &cursrc);
+}

--ZPt4rx8FFjLCG7dd--


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19990803095333.A14120>