/* Copyright (C) 2000-2014 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#include <errno.h>
#include <netdb.h>
#include "nsswitch.h"

/* Set up NIP to run through the services.  If ALL is zero, use NIP's
   current location if it's not nil.  Return nonzero if there are no
   services (left).  */
static int
setup (const char *func_name, db_lookup_function lookup_fct,
       void **fctp, service_user **nip, service_user **startp, int all)
{
  int no_more;
  if (*startp == NULL)
    {
      no_more = lookup_fct (nip, func_name, NULL, fctp);
      *startp = no_more ? (service_user *) -1l : *nip;
    }
  else if (*startp == (service_user *) -1l)
    /* No services at all.  */
    return 1;
  else
    {
      if (all || !*nip)
	/* Reset to the beginning of the service list.  */
	*nip = *startp;
      /* Look up the first function.  */
      no_more = __nss_lookup (nip, func_name, NULL, fctp);
    }
  return no_more;
}

void
__nss_setent (const char *func_name, db_lookup_function lookup_fct,
	      service_user **nip, service_user **startp,
	      service_user **last_nip, int stayopen, int *stayopen_tmp,
	      int res)
{
  union
  {
    setent_function f;
    void *ptr;
  } fct;
  int no_more;

  if (res && __res_maybe_init (&_res, 0) == -1)
    {
      __set_h_errno (NETDB_INTERNAL);
      return;
    }

  /* Cycle through the services and run their `setXXent' functions until
     we find an available service.  */
  no_more = setup (func_name, lookup_fct, &fct.ptr, nip,
		   startp, 1);
  while (! no_more)
    {
      int is_last_nip = *nip == *last_nip;
      enum nss_status status;

      if (stayopen_tmp)
	status = DL_CALL_FCT (fct.f, (*stayopen_tmp));
      else
	status = DL_CALL_FCT (fct.f, (0));

      no_more = __nss_next2 (nip, func_name, NULL, &fct.ptr, status, 0);
      if (is_last_nip)
	*last_nip = *nip;
    }

  if (stayopen_tmp)
    *stayopen_tmp = stayopen;
}


void
__nss_endent (const char *func_name, db_lookup_function lookup_fct,
	      service_user **nip, service_user **startp,
	      service_user **last_nip, int res)
{
  union
  {
    endent_function f;
    void *ptr;
  } fct;
  int no_more;

  if (res && __res_maybe_init (&_res, 0) == -1)
    {
      __set_h_errno (NETDB_INTERNAL);
      return;
    }

  /* Cycle through all the services and run their endXXent functions.  */
  no_more = setup (func_name, lookup_fct, &fct.ptr, nip, startp, 1);
  while (! no_more)
    {
      /* Ignore status, we force check in __NSS_NEXT.  */
      DL_CALL_FCT (fct.f, ());

      if (*nip == *last_nip)
	/* We have processed all services which were used.  */
	break;

      no_more = __nss_next2 (nip, func_name, NULL, &fct.ptr, 0, 1);
    }
  *last_nip = *nip = NULL;
}


int
__nss_getent_r (const char *getent_func_name,
		const char *setent_func_name,
		db_lookup_function lookup_fct,
		service_user **nip, service_user **startp,
		service_user **last_nip, int *stayopen_tmp, int res,
		void *resbuf, char *buffer, size_t buflen,
		void **result, int *h_errnop)
{
  union
  {
    getent_function f;
    void *ptr;
  } fct;
  int no_more;
  enum nss_status status;

  if (res && __res_maybe_init (&_res, 0) == -1)
    {
      *h_errnop = NETDB_INTERNAL;
      *result = NULL;
      return errno;
    }

  /* Initialize status to return if no more functions are found.  */
  status = NSS_STATUS_NOTFOUND;

  /* Run through available functions, starting with the same function last
     run.  We will repeat each function as long as it succeeds, and then go
     on to the next service action.  */
  no_more = setup (getent_func_name, lookup_fct, &fct.ptr, nip,
		   startp, 0);
  while (! no_more)
    {
      int is_last_nip = *nip == *last_nip;

      status = DL_CALL_FCT (fct.f,
			    (resbuf, buffer, buflen, &errno, &h_errno));

      /* 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
	  && (h_errnop == NULL || *h_errnop == NETDB_INTERNAL)
	  && errno == ERANGE)
	break;

      do
	{
	  no_more = __nss_next2 (nip, getent_func_name, NULL, &fct.ptr,
				 status, 0);

	  if (is_last_nip)
	    *last_nip = *nip;

	  if (! no_more)
	    {
	      /* Call the `setXXent' function.  This wasn't done before.  */
	      union
	      {
		setent_function f;
		void *ptr;
	      } sfct;

	      no_more = __nss_lookup (nip, setent_func_name, NULL, &sfct.ptr);

	      if (! no_more)
	        {
		  if (stayopen_tmp)
		    status = DL_CALL_FCT (sfct.f, (*stayopen_tmp));
		  else
		    status = DL_CALL_FCT (sfct.f, (0));
		}
	      else
		status = NSS_STATUS_NOTFOUND;
	    }
	}
      while (! no_more && status != NSS_STATUS_SUCCESS);
    }

  *result = status == NSS_STATUS_SUCCESS ? resbuf : NULL;
  return (status == NSS_STATUS_SUCCESS ? 0
	  : status != NSS_STATUS_TRYAGAIN ? ENOENT
	  /* h_errno functions only set errno if h_errno is NETDB_INTERNAL.  */
	  : (h_errnop == NULL || *h_errnop == NETDB_INTERNAL) ? errno
	  : EAGAIN);
}
