* support extra two arguments to nsdispatch():

const char *method		/* method name for dynamic linking */
	const ns_src defaults[]		/* list of defaults */
* document above, and expand other docco.
This commit is contained in:
lukem 1999-01-19 07:58:05 +00:00
parent ecaf658368
commit 37df672063
2 changed files with 116 additions and 58 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: nsdispatch.3,v 1.3 1999/01/16 07:55:43 lukem Exp $
.\" $NetBSD: nsdispatch.3,v 1.4 1999/01/19 07:58:05 lukem Exp $
.\"
.\" Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -34,7 +34,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd January 16, 1999
.Dd January 19, 1999
.Dt NSDISPATCH 3
.Os NetBSD
.Sh NAME
@ -43,7 +43,14 @@
.Sh SYNOPSIS
.Fd #include <nsswitch.h>
.Ft int
.Fn nsdispatch "void *retval" "const ns_dtab dtab[]" "const char *database" "..."
.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
@ -55,28 +62,25 @@ for the database
.Va database
until a successful entry is found.
.Pp
The return value from the last function invoked is stored at
the location specified in
.Va retval .
.Va retval
is passed to each callback function to modify as necessary
(to pass back to the caller of
.Fn nsdispatch )
.Pp
The optional extra arguments given in
.Va ...
are passed to the appropriate callback function as a variable argument
list of the type
.Va va_list .
.Pp
The format of the
.Va dtab
is an array of
.Va ns_dtab
structure is as follows:
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 [];
} ns_dtab;
.Ed
.Pp
For each source type that is implemented, and entry with
.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
@ -92,15 +96,74 @@ values for
.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 absent
.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_NISPLUS NISPLUS -offset indent
.Bl -column NS_COMPAT COMPAT -offset indent
.Sy #define value
.It NSSRC_FILES "files"
.It NSSRC_DNS "dns"
.It NSSRC_NIS "nis"
.It NSSRC_NISPLUS "nisplus"
.It NSSRC_COMPAT "compat"
.El
.Pp

View File

@ -1,4 +1,4 @@
/* $NetBSD: nsdispatch.c,v 1.4 1999/01/17 04:49:04 lukem Exp $ */
/* $NetBSD: nsdispatch.c,v 1.5 1999/01/19 07:58:05 lukem Exp $ */
/*-
* Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
@ -50,6 +50,15 @@
#include <unistd.h>
/*
* default sourcelist: `files'
*/
const ns_src __nsdefaultsrc[] = {
{ NSSRC_FILES, NS_SUCCESS },
{ 0 },
};
static int _nsmapsize = 0;
static ns_dbt *_nsmap = NULL;
@ -121,26 +130,18 @@ _nsdbtget(name)
const char *name;
{
static time_t confmod;
static ns_dbt dbt;
struct stat statbuf;
ns_dbt *ndbt;
ns_dbt dbt;
extern FILE *_nsyyin;
extern int _nsyyparse __P((void));
if (dbt.srclist == NULL) { /* construct dummy `files' entry */
ns_src src;
src.name = NSSRC_FILES;
src.flags = NS_SUCCESS;
_nsdbtaddsrc(&dbt, &src);
}
dbt.name = name;
if (confmod) {
if (stat(_PATH_NS_CONF, &statbuf) == -1)
return (&dbt);
return (NULL);
if (confmod < statbuf.st_mtime) {
int i, j;
@ -164,19 +165,16 @@ _nsdbtget(name)
}
if (!confmod) {
if (stat(_PATH_NS_CONF, &statbuf) == -1)
return (&dbt);
return (NULL);
_nsyyin = fopen(_PATH_NS_CONF, "r");
if (_nsyyin == NULL)
return (&dbt);
return (NULL);
_nsyyparse();
(void)fclose(_nsyyin);
qsort(_nsmap, _nsmapsize, sizeof(ns_dbt), _nscmp);
confmod = statbuf.st_mtime;
}
ndbt = bsearch(&dbt, _nsmap, _nsmapsize, sizeof(ns_dbt), _nscmp);
if (ndbt != NULL)
return (ndbt);
return (&dbt);
return (bsearch(&dbt, _nsmap, _nsmapsize, sizeof(ns_dbt), _nscmp));
}
@ -209,58 +207,55 @@ _nsdbtput(dbt)
int
#if __STDC__
nsdispatch(void *retval, const ns_dtab disp_tab[], const char *database, ...)
nsdispatch(void *retval, const ns_dtab disp_tab[], const char *database,
const char *method, const ns_src defaults[], ...)
#else
nsdispatch(retval, disp_tab, database, va_alist)
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;
#if _NS_DEBUG
_nsdumpdbt(dbt);
fprintf(stderr, "nsdispatch: %s\n", database);
#endif
for (i = 0; i < dbt->srclistsize; i++) {
#if _NS_DEBUG
fprintf(stderr, " source=%s", dbt->srclist[i]->source);
#endif
for (i = 0; i < srclistsize; i++) {
for (curdisp = 0; disp_tab[curdisp].src != NULL; curdisp++)
if (strcasecmp(disp_tab[curdisp].src,
dbt->srclist[i].name) == 0)
srclist[i].name) == 0)
break;
result = 0;
if (disp_tab[curdisp].callback) {
#if __STDC__
va_start(ap, database);
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 _NS_DEBUG
fprintf(stderr, " result=%d (%d)", result,
(result & dbt->srclist[i].flags));
#endif
if (result & dbt->srclist[i].flags) {
#if _NS_DEBUG
fprintf(stderr, " MATCH!\n");
#endif
if (result & srclist[i].flags) {
break;
}
}
#if _NS_DEBUG
fprintf(stderr, "\n");
#endif
}
return (result ? result : NS_NOTFOUND);
}