Blame nss/getXXbyYY_r.c

Packit Service 82fcde
/* Copyright (C) 1996-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#include <assert.h>
Packit Service 82fcde
#include <atomic.h>
Packit Service 82fcde
#include <errno.h>
Packit Service 82fcde
#include <stdbool.h>
Packit Service 82fcde
#include "nsswitch.h"
Packit Service 82fcde
#include "sysdep.h"
Packit Service 82fcde
#ifdef USE_NSCD
Packit Service 82fcde
# include <nscd/nscd_proto.h>
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifdef NEED__RES
Packit Service 82fcde
# include <resolv/resolv_context.h>
Packit Service 82fcde
#endif
Packit Service 82fcde
/*******************************************************************\
Packit Service 82fcde
|* Here we assume several symbols to be defined:		   *|
Packit Service 82fcde
|*								   *|
Packit Service 82fcde
|* LOOKUP_TYPE   - the return type of the function		   *|
Packit Service 82fcde
|*								   *|
Packit Service 82fcde
|* FUNCTION_NAME - name of the non-reentrant function		   *|
Packit Service 82fcde
|*								   *|
Packit Service 82fcde
|* DATABASE_NAME - name of the database the function accesses	   *|
Packit Service 82fcde
|*		   (e.g., host, services, ...)			   *|
Packit Service 82fcde
|*								   *|
Packit Service 82fcde
|* ADD_PARAMS    - additional parameters, can vary in number	   *|
Packit Service 82fcde
|*								   *|
Packit Service 82fcde
|* ADD_VARIABLES - names of additional parameters		   *|
Packit Service 82fcde
|*								   *|
Packit Service 82fcde
|* Optionally the following vars can be defined:		   *|
Packit Service 82fcde
|*								   *|
Packit Service 82fcde
|* EXTRA_PARAMS  - optional parameters, can vary in number	   *|
Packit Service 82fcde
|*								   *|
Packit Service 82fcde
|* EXTRA_VARIABLES - names of optional parameter		   *|
Packit Service 82fcde
|*								   *|
Packit Service 82fcde
|* FUNCTION2_NAME - alternative name of the non-reentrant function *|
Packit Service 82fcde
|*								   *|
Packit Service 82fcde
|* NEED_H_ERRNO  - an extra parameter will be passed to point to   *|
Packit Service 82fcde
|*		   the global `h_errno' variable.		   *|
Packit Service 82fcde
|*								   *|
Packit Service 82fcde
|* NEED__RES     - obtain a struct resolv_context resolver context *|
Packit Service 82fcde
|*								   *|
Packit Service 82fcde
|* PREPROCESS    - code run before anything else		   *|
Packit Service 82fcde
|*								   *|
Packit Service 82fcde
|* POSTPROCESS   - code run after the lookup			   *|
Packit Service 82fcde
|*								   *|
Packit Service 82fcde
\*******************************************************************/
Packit Service 82fcde
Packit Service 82fcde
/* To make the real sources a bit prettier.  */
Packit Service 82fcde
#define REENTRANT_NAME APPEND_R (FUNCTION_NAME)
Packit Service 82fcde
#ifdef FUNCTION2_NAME
Packit Service 82fcde
# define REENTRANT2_NAME APPEND_R (FUNCTION2_NAME)
Packit Service 82fcde
#else
Packit Service 82fcde
# define REENTRANT2_NAME NULL
Packit Service 82fcde
#endif
Packit Service 82fcde
#define APPEND_R(name) APPEND_R1 (name)
Packit Service 82fcde
#define APPEND_R1(name) name##_r
Packit Service 82fcde
#define INTERNAL(name) INTERNAL1 (name)
Packit Service 82fcde
#define INTERNAL1(name) __##name
Packit Service 82fcde
#define NEW(name) NEW1 (name)
Packit Service 82fcde
#define NEW1(name) __new_##name
Packit Service 82fcde
Packit Service 82fcde
#ifdef USE_NSCD
Packit Service 82fcde
# define NSCD_NAME ADD_NSCD (REENTRANT_NAME)
Packit Service 82fcde
# define ADD_NSCD(name) ADD_NSCD1 (name)
Packit Service 82fcde
# define ADD_NSCD1(name) __nscd_##name
Packit Service 82fcde
# define NOT_USENSCD_NAME ADD_NOT_NSCDUSE (DATABASE_NAME)
Packit Service 82fcde
# define ADD_NOT_NSCDUSE(name) ADD_NOT_NSCDUSE1 (name)
Packit Service 82fcde
# define ADD_NOT_NSCDUSE1(name) __nss_not_use_nscd_##name
Packit Service 82fcde
# define CONCAT2(arg1, arg2) CONCAT2_2 (arg1, arg2)
Packit Service 82fcde
# define CONCAT2_2(arg1, arg2) arg1##arg2
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#define FUNCTION_NAME_STRING STRINGIZE (FUNCTION_NAME)
Packit Service 82fcde
#define REENTRANT_NAME_STRING STRINGIZE (REENTRANT_NAME)
Packit Service 82fcde
#ifdef FUNCTION2_NAME
Packit Service 82fcde
# define REENTRANT2_NAME_STRING STRINGIZE (REENTRANT2_NAME)
Packit Service 82fcde
#else
Packit Service 82fcde
# define REENTRANT2_NAME_STRING NULL
Packit Service 82fcde
#endif
Packit Service 82fcde
#define DATABASE_NAME_STRING STRINGIZE (DATABASE_NAME)
Packit Service 82fcde
#define STRINGIZE(name) STRINGIZE1 (name)
Packit Service 82fcde
#define STRINGIZE1(name) #name
Packit Service 82fcde
Packit Service 82fcde
#ifndef DB_LOOKUP_FCT
Packit Service 82fcde
# define DB_LOOKUP_FCT CONCAT3_1 (__nss_, DATABASE_NAME, _lookup2)
Packit Service 82fcde
# define CONCAT3_1(Pre, Name, Post) CONCAT3_2 (Pre, Name, Post)
Packit Service 82fcde
# define CONCAT3_2(Pre, Name, Post) Pre##Name##Post
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Sometimes we need to store error codes in the `h_errno' variable.  */
Packit Service 82fcde
#ifdef NEED_H_ERRNO
Packit Service 82fcde
# define H_ERRNO_PARM , int *h_errnop
Packit Service 82fcde
# define H_ERRNO_VAR , h_errnop
Packit Service 82fcde
# define H_ERRNO_VAR_P h_errnop
Packit Service 82fcde
#else
Packit Service 82fcde
# define H_ERRNO_PARM
Packit Service 82fcde
# define H_ERRNO_VAR
Packit Service 82fcde
# define H_ERRNO_VAR_P NULL
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#ifndef EXTRA_PARAMS
Packit Service 82fcde
# define EXTRA_PARAMS
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef EXTRA_VARIABLES
Packit Service 82fcde
# define EXTRA_VARIABLES
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#ifdef HAVE_AF
Packit Service 82fcde
# define AF_VAL af
Packit Service 82fcde
#else
Packit Service 82fcde
# define AF_VAL AF_INET
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Set defaults for merge functions that haven't been defined.  */
Packit Service 82fcde
#ifndef DEEPCOPY_FN
Packit Service 82fcde
static inline int
Packit Service 82fcde
__copy_einval (LOOKUP_TYPE a,
Packit Service 82fcde
	       const size_t b,
Packit Service 82fcde
	       LOOKUP_TYPE *c,
Packit Service 82fcde
	       char *d,
Packit Service 82fcde
	       char **e)
Packit Service 82fcde
{
Packit Service 82fcde
  return EINVAL;
Packit Service 82fcde
}
Packit Service 82fcde
# define DEEPCOPY_FN __copy_einval
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#ifndef MERGE_FN
Packit Service 82fcde
static inline int
Packit Service 82fcde
__merge_einval (LOOKUP_TYPE *a,
Packit Service 82fcde
		char *b,
Packit Service 82fcde
		char *c,
Packit Service 82fcde
		size_t d,
Packit Service 82fcde
		LOOKUP_TYPE *e,
Packit Service 82fcde
		char *f)
Packit Service 82fcde
{
Packit Service 82fcde
  return EINVAL;
Packit Service 82fcde
}
Packit Service 82fcde
# define MERGE_FN __merge_einval
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#define CHECK_MERGE(err, status)		\
Packit Service 82fcde
  ({						\
Packit Service 82fcde
    do						\
Packit Service 82fcde
      {						\
Packit Service 82fcde
	if (err)				\
Packit Service 82fcde
	  {					\
Packit Service 82fcde
	    __set_errno (err);			\
Packit Service 82fcde
	    if (err == ERANGE)			\
Packit Service 82fcde
	      status = NSS_STATUS_TRYAGAIN;	\
Packit Service 82fcde
	    else				\
Packit Service 82fcde
	      status = NSS_STATUS_UNAVAIL;	\
Packit Service 82fcde
	    break;				\
Packit Service 82fcde
	  }					\
Packit Service 82fcde
      }						\
Packit Service 82fcde
    while (0);					\
Packit Service 82fcde
  })
Packit Service 82fcde
Packit Service 82fcde
/* Type of the lookup function we need here.  */
Packit Service 82fcde
typedef enum nss_status (*lookup_function) (ADD_PARAMS, LOOKUP_TYPE *, char *,
Packit Service 82fcde
					    size_t, int * H_ERRNO_PARM
Packit Service 82fcde
					    EXTRA_PARAMS);
Packit Service 82fcde
Packit Service 82fcde
/* The lookup function for the first entry of this service.  */
Packit Service 82fcde
extern int DB_LOOKUP_FCT (service_user **nip, const char *name,
Packit Service 82fcde
			  const char *name2, void **fctp);
Packit Service 82fcde
libc_hidden_proto (DB_LOOKUP_FCT)
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
Packit Service 82fcde
			   size_t buflen, LOOKUP_TYPE **result H_ERRNO_PARM
Packit Service 82fcde
			   EXTRA_PARAMS)
Packit Service 82fcde
{
Packit Service 82fcde
  static bool startp_initialized;
Packit Service 82fcde
  static service_user *startp;
Packit Service 82fcde
  static lookup_function start_fct;
Packit Service 82fcde
  service_user *nip;
Packit Service 82fcde
  int do_merge = 0;
Packit Service 82fcde
  LOOKUP_TYPE mergegrp;
Packit Service 82fcde
  char *mergebuf = NULL;
Packit Service 82fcde
  char *endptr = NULL;
Packit Service 82fcde
  union
Packit Service 82fcde
  {
Packit Service 82fcde
    lookup_function l;
Packit Service 82fcde
    void *ptr;
Packit Service 82fcde
  } fct;
Packit Service 82fcde
  int no_more, err;
Packit Service 82fcde
  enum nss_status status = NSS_STATUS_UNAVAIL;
Packit Service 82fcde
#ifdef USE_NSCD
Packit Service 82fcde
  int nscd_status;
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifdef NEED_H_ERRNO
Packit Service 82fcde
  bool any_service = false;
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#ifdef NEED__RES
Packit Service 82fcde
  /* The HANDLE_DIGITS_DOTS case below already needs the resolver
Packit Service 82fcde
     configuration, so this has to happen early.  */
Packit Service 82fcde
  struct resolv_context *res_ctx = __resolv_context_get ();
Packit Service 82fcde
  if (res_ctx == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      *h_errnop = NETDB_INTERNAL;
Packit Service 82fcde
      *result = NULL;
Packit Service 82fcde
      return errno;
Packit Service 82fcde
    }
Packit Service 82fcde
#endif /* NEED__RES */
Packit Service 82fcde
Packit Service 82fcde
#ifdef PREPROCESS
Packit Service 82fcde
  PREPROCESS;
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#ifdef HANDLE_DIGITS_DOTS
Packit Service 82fcde
  switch (__nss_hostname_digits_dots (name, resbuf, &buffer, NULL,
Packit Service 82fcde
				      buflen, result, &status, AF_VAL,
Packit Service 82fcde
				      H_ERRNO_VAR_P))
Packit Service 82fcde
    {
Packit Service 82fcde
    case -1:
Packit Service 82fcde
# ifdef NEED__RES
Packit Service 82fcde
      __resolv_context_put (res_ctx);
Packit Service 82fcde
# endif
Packit Service 82fcde
      return errno;
Packit Service 82fcde
    case 1:
Packit Service 82fcde
#ifdef NEED_H_ERRNO
Packit Service 82fcde
      any_service = true;
Packit Service 82fcde
#endif
Packit Service 82fcde
      goto done;
Packit Service 82fcde
    }
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#ifdef USE_NSCD
Packit Service 82fcde
  if (NOT_USENSCD_NAME > 0 && ++NOT_USENSCD_NAME > NSS_NSCD_RETRY)
Packit Service 82fcde
    NOT_USENSCD_NAME = 0;
Packit Service 82fcde
Packit Service 82fcde
  if (!NOT_USENSCD_NAME
Packit Service 82fcde
      && !__nss_database_custom[CONCAT2 (NSS_DBSIDX_, DATABASE_NAME)])
Packit Service 82fcde
    {
Packit Service 82fcde
      nscd_status = NSCD_NAME (ADD_VARIABLES, resbuf, buffer, buflen, result
Packit Service 82fcde
			       H_ERRNO_VAR);
Packit Service 82fcde
      if (nscd_status >= 0)
Packit Service 82fcde
	{
Packit Service 82fcde
# ifdef NEED__RES
Packit Service 82fcde
	  __resolv_context_put (res_ctx);
Packit Service 82fcde
# endif
Packit Service 82fcde
	  return nscd_status;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
  if (! startp_initialized)
Packit Service 82fcde
    {
Packit Service 82fcde
      no_more = DB_LOOKUP_FCT (&nip, REENTRANT_NAME_STRING,
Packit Service 82fcde
			       REENTRANT2_NAME_STRING, &fct.ptr);
Packit Service 82fcde
      if (no_more)
Packit Service 82fcde
	{
Packit Service 82fcde
	  void *tmp_ptr = (service_user *) -1l;
Packit Service 82fcde
#ifdef PTR_MANGLE
Packit Service 82fcde
	  PTR_MANGLE (tmp_ptr);
Packit Service 82fcde
#endif
Packit Service 82fcde
	  startp = tmp_ptr;
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  void *tmp_ptr = fct.l;
Packit Service 82fcde
#ifdef PTR_MANGLE
Packit Service 82fcde
	  PTR_MANGLE (tmp_ptr);
Packit Service 82fcde
#endif
Packit Service 82fcde
	  start_fct = tmp_ptr;
Packit Service 82fcde
	  tmp_ptr = nip;
Packit Service 82fcde
#ifdef PTR_MANGLE
Packit Service 82fcde
	  PTR_MANGLE (tmp_ptr);
Packit Service 82fcde
#endif
Packit Service 82fcde
	  startp = tmp_ptr;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* Make sure start_fct and startp are written before
Packit Service 82fcde
	 startp_initialized.  */
Packit Service 82fcde
      atomic_write_barrier ();
Packit Service 82fcde
      startp_initialized = true;
Packit Service 82fcde
    }
Packit Service 82fcde
  else
Packit Service 82fcde
    {
Packit Service 82fcde
      fct.l = start_fct;
Packit Service 82fcde
      nip = startp;
Packit Service 82fcde
#ifdef PTR_DEMANGLE
Packit Service 82fcde
      PTR_DEMANGLE (fct.l);
Packit Service 82fcde
      PTR_DEMANGLE (nip);
Packit Service 82fcde
#endif
Packit Service 82fcde
      no_more = nip == (service_user *) -1l;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  while (no_more == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
#ifdef NEED_H_ERRNO
Packit Service 82fcde
      any_service = true;
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
      status = DL_CALL_FCT (fct.l, (ADD_VARIABLES, resbuf, buffer, buflen,
Packit Service 82fcde
				    &errno H_ERRNO_VAR EXTRA_VARIABLES));
Packit Service 82fcde
Packit Service 82fcde
      /* The status is NSS_STATUS_TRYAGAIN and errno is ERANGE the
Packit Service 82fcde
	 provided buffer is too small.  In this case we should give
Packit Service 82fcde
	 the user the possibility to enlarge the buffer and we should
Packit Service 82fcde
	 not simply go on with the next service (even if the TRYAGAIN
Packit Service 82fcde
	 action tells us so).  */
Packit Service 82fcde
      if (status == NSS_STATUS_TRYAGAIN
Packit Service 82fcde
#ifdef NEED_H_ERRNO
Packit Service 82fcde
	  && *h_errnop == NETDB_INTERNAL
Packit Service 82fcde
#endif
Packit Service 82fcde
	  && errno == ERANGE)
Packit Service 82fcde
	break;
Packit Service 82fcde
Packit Service 82fcde
      if (do_merge)
Packit Service 82fcde
	{
Packit Service 82fcde
Packit Service 82fcde
	  if (status == NSS_STATUS_SUCCESS)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      /* The previous loop saved a buffer for merging.
Packit Service 82fcde
		 Perform the merge now.  */
Packit Service 82fcde
	      err = MERGE_FN (&mergegrp, mergebuf, endptr, buflen, resbuf,
Packit Service 82fcde
			      buffer);
Packit Service 82fcde
	      CHECK_MERGE (err,status);
Packit Service 82fcde
	      do_merge = 0;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  else
Packit Service 82fcde
	    {
Packit Service 82fcde
	      /* If the result wasn't SUCCESS, copy the saved buffer back
Packit Service 82fcde
	         into the result buffer and set the status back to
Packit Service 82fcde
	         NSS_STATUS_SUCCESS to match the previous pass through the
Packit Service 82fcde
	         loop.
Packit Service 82fcde
	          * If the next action is CONTINUE, it will overwrite the value
Packit Service 82fcde
	            currently in the buffer and return the new value.
Packit Service 82fcde
	          * If the next action is RETURN, we'll return the previously-
Packit Service 82fcde
	            acquired values.
Packit Service 82fcde
	          * If the next action is MERGE, then it will be added to the
Packit Service 82fcde
	            buffer saved from the previous source.  */
Packit Service 82fcde
	      err = DEEPCOPY_FN (mergegrp, buflen, resbuf, buffer, NULL);
Packit Service 82fcde
	      CHECK_MERGE (err, status);
Packit Service 82fcde
	      status = NSS_STATUS_SUCCESS;
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* If we were are configured to merge this value with the next one,
Packit Service 82fcde
         save the current value of the group struct.  */
Packit Service 82fcde
      if (nss_next_action (nip, status) == NSS_ACTION_MERGE
Packit Service 82fcde
	  && status == NSS_STATUS_SUCCESS)
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* Copy the current values into a buffer to be merged with the next
Packit Service 82fcde
	     set of retrieved values.  */
Packit Service 82fcde
	  if (mergebuf == NULL)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      /* Only allocate once and reuse it for as many merges as we need
Packit Service 82fcde
	         to perform.  */
Packit Service 82fcde
	      mergebuf = malloc (buflen);
Packit Service 82fcde
	      if (mergebuf == NULL)
Packit Service 82fcde
		{
Packit Service 82fcde
		  __set_errno (ENOMEM);
Packit Service 82fcde
		  status = NSS_STATUS_UNAVAIL;
Packit Service 82fcde
		  break;
Packit Service 82fcde
		}
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  err = DEEPCOPY_FN (*resbuf, buflen, &mergegrp, mergebuf, &endptr);
Packit Service 82fcde
	  CHECK_MERGE (err, status);
Packit Service 82fcde
	  do_merge = 1;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      no_more = __nss_next2 (&nip, REENTRANT_NAME_STRING,
Packit Service 82fcde
			     REENTRANT2_NAME_STRING, &fct.ptr, status, 0);
Packit Service 82fcde
    }
Packit Service 82fcde
  free (mergebuf);
Packit Service 82fcde
  mergebuf = NULL;
Packit Service 82fcde
Packit Service 82fcde
#ifdef HANDLE_DIGITS_DOTS
Packit Service 82fcde
done:
Packit Service 82fcde
#endif
Packit Service 82fcde
  *result = status == NSS_STATUS_SUCCESS ? resbuf : NULL;
Packit Service 82fcde
#ifdef NEED_H_ERRNO
Packit Service 82fcde
  if (status == NSS_STATUS_UNAVAIL && !any_service && errno != ENOENT)
Packit Service 82fcde
    /* This happens when we weren't able to use a service for reasons other
Packit Service 82fcde
       than the module not being found.  In such a case, we'd want to tell the
Packit Service 82fcde
       caller that errno has the real reason for failure.  */
Packit Service 82fcde
    *h_errnop = NETDB_INTERNAL;
Packit Service 82fcde
  else if (status != NSS_STATUS_SUCCESS && !any_service)
Packit Service 82fcde
    /* We were not able to use any service.  */
Packit Service 82fcde
    *h_errnop = NO_RECOVERY;
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifdef POSTPROCESS
Packit Service 82fcde
  POSTPROCESS;
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#ifdef NEED__RES
Packit Service 82fcde
  /* This has to happen late because the POSTPROCESS stage above might
Packit Service 82fcde
     need the resolver context.  */
Packit Service 82fcde
  __resolv_context_put (res_ctx);
Packit Service 82fcde
#endif /* NEED__RES */
Packit Service 82fcde
Packit Service 82fcde
  int res;
Packit Service 82fcde
  if (status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND)
Packit Service 82fcde
    res = 0;
Packit Service 82fcde
  /* Don't pass back ERANGE if this is not for a too-small buffer.  */
Packit Service 82fcde
  else if (errno == ERANGE && status != NSS_STATUS_TRYAGAIN)
Packit Service 82fcde
    res = EINVAL;
Packit Service 82fcde
#ifdef NEED_H_ERRNO
Packit Service 82fcde
  /* These functions only set errno if h_errno is NETDB_INTERNAL.  */
Packit Service 82fcde
  else if (status == NSS_STATUS_TRYAGAIN && *h_errnop != NETDB_INTERNAL)
Packit Service 82fcde
    res = EAGAIN;
Packit Service 82fcde
#endif
Packit Service 82fcde
  else
Packit Service 82fcde
    return errno;
Packit Service 82fcde
Packit Service 82fcde
  __set_errno (res);
Packit Service 82fcde
  return res;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
#ifdef NO_COMPAT_NEEDED
Packit Service 82fcde
strong_alias (INTERNAL (REENTRANT_NAME), REENTRANT_NAME);
Packit Service 82fcde
#elif !defined FUNCTION2_NAME
Packit Service 82fcde
# include <shlib-compat.h>
Packit Service 82fcde
# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1_2)
Packit Service 82fcde
#  define OLD(name) OLD1 (name)
Packit Service 82fcde
#  define OLD1(name) __old_##name
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
attribute_compat_text_section
Packit Service 82fcde
OLD (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
Packit Service 82fcde
		      size_t buflen, LOOKUP_TYPE **result H_ERRNO_PARM)
Packit Service 82fcde
{
Packit Service 82fcde
  int ret = INTERNAL (REENTRANT_NAME) (ADD_VARIABLES, resbuf, buffer,
Packit Service 82fcde
				       buflen, result H_ERRNO_VAR);
Packit Service 82fcde
Packit Service 82fcde
  if (ret != 0 || result == NULL)
Packit Service 82fcde
    ret = -1;
Packit Service 82fcde
Packit Service 82fcde
  return ret;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#  define do_symbol_version(real, name, version) \
Packit Service 82fcde
  compat_symbol (libc, real, name, version)
Packit Service 82fcde
do_symbol_version (OLD (REENTRANT_NAME), REENTRANT_NAME, GLIBC_2_0);
Packit Service 82fcde
# endif
Packit Service 82fcde
Packit Service 82fcde
/* As INTERNAL (REENTRANT_NAME) may be hidden, we need an alias
Packit Service 82fcde
   in between so that the REENTRANT_NAME@@GLIBC_2.1.2 is not
Packit Service 82fcde
   hidden too.  */
Packit Service 82fcde
strong_alias (INTERNAL (REENTRANT_NAME), NEW (REENTRANT_NAME));
Packit Service 82fcde
Packit Service 82fcde
# define do_default_symbol_version(real, name, version) \
Packit Service 82fcde
  versioned_symbol (libc, real, name, version)
Packit Service 82fcde
do_default_symbol_version (NEW (REENTRANT_NAME),
Packit Service 82fcde
			   REENTRANT_NAME, GLIBC_2_1_2);
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
nss_interface_function (REENTRANT_NAME)