* 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. .\" Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
.\" All rights reserved. .\" All rights reserved.
@ -34,7 +34,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE. .\" POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd January 16, 1999 .Dd January 19, 1999
.Dt NSDISPATCH 3 .Dt NSDISPATCH 3
.Os NetBSD .Os NetBSD
.Sh NAME .Sh NAME
@ -43,7 +43,14 @@
.Sh SYNOPSIS .Sh SYNOPSIS
.Fd #include <nsswitch.h> .Fd #include <nsswitch.h>
.Ft int .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 .Sh DESCRIPTION
The The
.Fn nsdispatch .Fn nsdispatch
@ -55,28 +62,25 @@ for the database
.Va database .Va database
until a successful entry is found. until a successful entry is found.
.Pp .Pp
The return value from the last function invoked is stored at .Va retval
the location specified in is passed to each callback function to modify as necessary
.Va retval . (to pass back to the caller of
.Fn nsdispatch )
.Pp .Pp
The optional extra arguments given in .Va dtab
.Va ... is an array of
are passed to the appropriate callback function as a variable argument
list of the type
.Va va_list .
.Pp
The format of the
.Va ns_dtab .Va ns_dtab
structure is as follows: structures, which have the following format:
.Bd -literal -offset indent .Bd -literal -offset indent
typedef struct { typedef struct {
const char *src; const char *src;
int (*cb)(void *retval, void *cb_data, va_list ap); int (*cb)(void *retval, void *cb_data, va_list ap);
void *cb_data; void *cb_data;
} ns_dtab []; } ns_dtab;
.Ed .Ed
.Pp .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 .Va src
set to the name of the source, set to the name of the source,
.Va cb .Va cb
@ -92,15 +96,74 @@ values for
.Va cb , .Va cb ,
and and
.Va cb_data . .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 .Ss Valid source types
Whilst there is support for arbitrary sources, the following Whilst there is support for arbitrary sources, the following
#defines for commonly implementated sources are available: #defines for commonly implementated sources are available:
.Bl -column NS_NISPLUS NISPLUS -offset indent .Bl -column NS_COMPAT COMPAT -offset indent
.Sy #define value .Sy #define value
.It NSSRC_FILES "files" .It NSSRC_FILES "files"
.It NSSRC_DNS "dns" .It NSSRC_DNS "dns"
.It NSSRC_NIS "nis" .It NSSRC_NIS "nis"
.It NSSRC_NISPLUS "nisplus"
.It NSSRC_COMPAT "compat" .It NSSRC_COMPAT "compat"
.El .El
.Pp .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. * Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
@ -50,6 +50,15 @@
#include <unistd.h> #include <unistd.h>
/*
* default sourcelist: `files'
*/
const ns_src __nsdefaultsrc[] = {
{ NSSRC_FILES, NS_SUCCESS },
{ 0 },
};
static int _nsmapsize = 0; static int _nsmapsize = 0;
static ns_dbt *_nsmap = NULL; static ns_dbt *_nsmap = NULL;
@ -121,26 +130,18 @@ _nsdbtget(name)
const char *name; const char *name;
{ {
static time_t confmod; static time_t confmod;
static ns_dbt dbt;
struct stat statbuf; struct stat statbuf;
ns_dbt *ndbt; ns_dbt dbt;
extern FILE *_nsyyin; extern FILE *_nsyyin;
extern int _nsyyparse __P((void)); 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; dbt.name = name;
if (confmod) { if (confmod) {
if (stat(_PATH_NS_CONF, &statbuf) == -1) if (stat(_PATH_NS_CONF, &statbuf) == -1)
return (&dbt); return (NULL);
if (confmod < statbuf.st_mtime) { if (confmod < statbuf.st_mtime) {
int i, j; int i, j;
@ -164,19 +165,16 @@ _nsdbtget(name)
} }
if (!confmod) { if (!confmod) {
if (stat(_PATH_NS_CONF, &statbuf) == -1) if (stat(_PATH_NS_CONF, &statbuf) == -1)
return (&dbt); return (NULL);
_nsyyin = fopen(_PATH_NS_CONF, "r"); _nsyyin = fopen(_PATH_NS_CONF, "r");
if (_nsyyin == NULL) if (_nsyyin == NULL)
return (&dbt); return (NULL);
_nsyyparse(); _nsyyparse();
(void)fclose(_nsyyin); (void)fclose(_nsyyin);
qsort(_nsmap, _nsmapsize, sizeof(ns_dbt), _nscmp); qsort(_nsmap, _nsmapsize, sizeof(ns_dbt), _nscmp);
confmod = statbuf.st_mtime; confmod = statbuf.st_mtime;
} }
ndbt = bsearch(&dbt, _nsmap, _nsmapsize, sizeof(ns_dbt), _nscmp); return (bsearch(&dbt, _nsmap, _nsmapsize, sizeof(ns_dbt), _nscmp));
if (ndbt != NULL)
return (ndbt);
return (&dbt);
} }
@ -209,58 +207,55 @@ _nsdbtput(dbt)
int int
#if __STDC__ #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 #else
nsdispatch(retval, disp_tab, database, va_alist) nsdispatch(retval, disp_tab, database, method, defaults, va_alist)
void *retval; void *retval;
const ns_dtab disp_tab[]; const ns_dtab disp_tab[];
const char *database; const char *database;
const char *method;
const ns_src defaults[];
va_dcl va_dcl
#endif #endif
{ {
va_list ap; va_list ap;
int i, curdisp, result; int i, curdisp, result;
const ns_dbt *dbt; const ns_dbt *dbt;
const ns_src *srclist;
int srclistsize;
dbt = _nsdbtget(database); 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; result = 0;
#if _NS_DEBUG for (i = 0; i < srclistsize; i++) {
_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 (curdisp = 0; disp_tab[curdisp].src != NULL; curdisp++) for (curdisp = 0; disp_tab[curdisp].src != NULL; curdisp++)
if (strcasecmp(disp_tab[curdisp].src, if (strcasecmp(disp_tab[curdisp].src,
dbt->srclist[i].name) == 0) srclist[i].name) == 0)
break; break;
result = 0; result = 0;
if (disp_tab[curdisp].callback) { if (disp_tab[curdisp].callback) {
#if __STDC__ #if __STDC__
va_start(ap, database); va_start(ap, defaults);
#else #else
va_start(ap); va_start(ap);
#endif #endif
result = disp_tab[curdisp].callback(retval, result = disp_tab[curdisp].callback(retval,
disp_tab[curdisp].cb_data, ap); disp_tab[curdisp].cb_data, ap);
va_end(ap); va_end(ap);
#if _NS_DEBUG if (result & srclist[i].flags) {
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
break; break;
} }
} }
#if _NS_DEBUG
fprintf(stderr, "\n");
#endif
} }
return (result ? result : NS_NOTFOUND); return (result ? result : NS_NOTFOUND);
} }