-/* Copyright (C) 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#include <errno.h>
#include "nsswitch.h"
+#include <nscd/nscd_proto.h>
/*******************************************************************\
|* Here we assume several symbols to be defined: *|
#define INTERNAL(name) INTERNAL1 (name)
#define INTERNAL1(name) __##name
+#ifdef USE_NSCD
+# define NSCD_NAME ADD_NSCD (REENTRANT_NAME)
+# define ADD_NSCD(name) ADD_NSCD1 (name)
+# define ADD_NSCD1(name) __nscd_##name
+# define NOT_USENSCD_NAME ADD_NOT_NSCDUSE (DATABASE_NAME)
+# define ADD_NOT_NSCDUSE(name) ADD_NOT_NSCDUSE1 (name)
+# define ADD_NOT_NSCDUSE1(name) __nss_not_use_nscd_##name
+#endif
+
#define FUNCTION_NAME_STRING STRINGIZE (FUNCTION_NAME)
#define REENTRANT_NAME_STRING STRINGIZE (REENTRANT_NAME)
#define DATABASE_NAME_STRING STRINGIZE (DATABASE_NAME)
/* Type of the lookup function we need here. */
-typedef int (*lookup_function) (ADD_PARAMS, LOOKUP_TYPE *, char *, int
- H_ERRNO_PARM);
+typedef int (*lookup_function) (ADD_PARAMS, LOOKUP_TYPE *, char *, size_t,
+ int * H_ERRNO_PARM);
/* Some usages of this file might use this variable. */
extern struct __res_state _res;
/* The lookup function for the first entry of this service. */
extern int DB_LOOKUP_FCT (service_user **nip, const char *name, void **fctp);
+/* Interval in which we transfer retry to contact the NSCD. */
+#define NSS_NSCD_RETRY 100
int
lookup_function fct;
int no_more;
enum nss_status status = NSS_STATUS_UNAVAIL;
+#ifdef USE_NSCD
+ int nscd_status;
+#endif
+
+#ifdef HANDLE_DIGITS_DOTS
+# define resbuf (*resbuf)
+# include "digits_dots.c"
+# undef resbuf
+#endif
+
+#ifdef USE_NSCD
+ if (NOT_USENSCD_NAME && ++NOT_USENSCD_NAME > NSS_NSCD_RETRY)
+ NOT_USENSCD_NAME = 0;
+
+ if (!NOT_USENSCD_NAME)
+ {
+ nscd_status = NSCD_NAME (ADD_VARIABLES, resbuf, buffer, buflen
+ H_ERRNO_VAR);
+ if (nscd_status < 1)
+ {
+ *result = nscd_status == 0 ? resbuf : NULL;
+ return nscd_status;
+ }
+ }
+#endif
if (startp == NULL)
{
no_more = DB_LOOKUP_FCT (&nip, REENTRANT_NAME_STRING, (void **) &fct);
if (no_more)
- startp = (service_user *) -1;
+ startp = (service_user *) -1l;
else
{
startp = nip;
if ((_res.options & RES_INIT) == 0 && res_init () == -1)
{
*h_errnop = NETDB_INTERNAL;
- return NULL;
+ *result = NULL;
+ return -1;
}
#endif /* need _res */
}
else
{
fct = start_fct;
- no_more = (nip = startp) == (service_user *) -1;
+ no_more = (nip = startp) == (service_user *) -1l;
}
while (no_more == 0)
{
- status = (*fct) (ADD_VARIABLES, resbuf, buffer, buflen H_ERRNO_VAR);
+ status = (*fct) (ADD_VARIABLES, resbuf, buffer, buflen,
+ &errno H_ERRNO_VAR);
+
+ /* The status is NSS_STATUS_TRYAGAIN and errno is ERANGE the
+ provided buffer is too small. In this case we should give
+ the user the possibility to enlarge the buffer and we should
+ not simply go on with the next service (even if the TRYAGAIN
+ action tells us so). */
+ if (status == NSS_STATUS_TRYAGAIN
+#ifdef NEED_H_ERRNO
+ && *h_errnop == NETDB_INTERNAL
+#endif
+ && errno == ERANGE)
+ break;
no_more = __nss_next (&nip, REENTRANT_NAME_STRING,
(void **) &fct, status, 0);
}
+#ifdef HANDLE_DIGITS_DOTS
+done:
+#endif
*result = status == NSS_STATUS_SUCCESS ? resbuf : NULL;
return status == NSS_STATUS_SUCCESS ? 0 : -1;
}
-#define do_weak_alias(n1, n2) weak_alias ((n1), (n2))
+#define do_weak_alias(n1, n2) weak_alias (n1, (n2))
do_weak_alias (INTERNAL (REENTRANT_NAME), REENTRANT_NAME)