/* Copyright (C) 1997, 1999, 2000, 2002 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997.

   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, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <ctype.h>
#include <errno.h>
#include <grp.h>
#include <hesiod.h>
#include <nss.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>

#include "nss_hesiod.h"

/* Get the declaration of the parser function.  */
#define ENTNAME grent
#define STRUCTURE group
#define EXTERN_PARSER
#include <nss/nss_files/files-parse.c>

enum nss_status
_nss_hesiod_setgrent (int stayopen)
{
  return NSS_STATUS_SUCCESS;
}

enum nss_status
_nss_hesiod_endgrent (void)
{
  return NSS_STATUS_SUCCESS;
}

static enum nss_status
lookup (const char *name, const char *type, struct group *grp,
	char *buffer, size_t buflen, int *errnop)
{
  struct parser_data *data = (void *) buffer;
  size_t linebuflen;
  void *context;
  char **list;
  int parse_res;
  size_t len;
  int olderr = errno;

  context = _nss_hesiod_init ();
  if (context == NULL)
    return NSS_STATUS_UNAVAIL;

  list = hesiod_resolve (context, name, type);
  if (list == NULL)
    {
      int err = errno;
      hesiod_end (context);
      __set_errno (olderr);
      return err == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL;
    }

  linebuflen = buffer + buflen - data->linebuffer;
  len = strlen (*list) + 1;
  if (linebuflen < len)
    {
      hesiod_free_list (context, list);
      hesiod_end (context);
      *errnop = ERANGE;
      return NSS_STATUS_TRYAGAIN;
    }

  memcpy (data->linebuffer, *list, len);
  hesiod_free_list (context, list);
  hesiod_end (context);

  parse_res = _nss_files_parse_grent (buffer, grp, data, buflen, errnop);
  if (parse_res < 1)
    {
      __set_errno (olderr);
      return parse_res == -1 ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND;
    }

  return NSS_STATUS_SUCCESS;
}

enum nss_status
_nss_hesiod_getgrnam_r (const char *name, struct group *grp,
			char *buffer, size_t buflen, int *errnop)
{
  return lookup (name, "group", grp, buffer, buflen, errnop);
}

enum nss_status
_nss_hesiod_getgrgid_r (gid_t gid, struct group *grp,
			char *buffer, size_t buflen, int *errnop)
{
  char gidstr[21];	/* We will probably never have a gid_t with more
			   than 64 bits.  */

  snprintf (gidstr, sizeof gidstr, "%d", gid);

  return lookup (gidstr, "gid", grp, buffer, buflen, errnop);
}

static int
internal_gid_in_list (const gid_t *list, const gid_t g, long int len)
{
  while (len > 0)
    {
      if (*list == g)
	return 1;
      --len;
      ++list;
    }
  return 0;
}

static enum nss_status
internal_gid_from_group (void *context, const char *groupname, gid_t *group)
{
  char **grp_res;
  enum nss_status status = NSS_STATUS_NOTFOUND;

  grp_res = hesiod_resolve (context, groupname, "group");
  if (grp_res != NULL && *grp_res != NULL)
    {
      char *p = *grp_res;

      /* Skip to third field.  */
      while (*p != '\0' && *p != ':')
	++p;
      if (*p != '\0')
	++p;
      while (*p != '\0' && *p != ':')
	++p;
      if (*p != '\0')
	{
	  char *endp;
	  char *q = ++p;
	  long int val;

	  while (*q != '\0' && *q != ':')
	    ++q;

	  val = strtol (p, &endp, 10);
	  if (sizeof (gid_t) == sizeof (long int) || (gid_t) val == val)
	    {
	      *group = val;
	      if (endp == q && endp != p)
		status = NSS_STATUS_SUCCESS;
	    }
        }
      hesiod_free_list (context, grp_res);
    }
  return status;
}

enum nss_status
_nss_hesiod_initgroups_dyn (const char *user, gid_t group, long int *start,
			    long int *size, gid_t **groupsp, long int limit,
			    int *errnop)
{
  enum nss_status status = NSS_STATUS_SUCCESS;
  char **list = NULL;
  char *p;
  void *context;
  gid_t *groups = *groupsp;
  int save_errno;

  context = _nss_hesiod_init ();
  if (context == NULL)
    return NSS_STATUS_UNAVAIL;

  list = hesiod_resolve (context, user, "grplist");

  if (list == NULL)
    {
      hesiod_end (context);
      return errno == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL;
    }

  if (!internal_gid_in_list (groups, group, *start))
    {
      if (__builtin_expect (*start == *size, 0))
	{
	  /* Need a bigger buffer.  */
	  gid_t *newgroups;
	  long int newsize;

	  if (limit > 0 && *size == limit)
	    /* We reached the maximum.  */
	    goto done;

	  if (limit <= 0)
	    newsize = 2 * *size;
	  else
	    newsize = MIN (limit, 2 * *size);

	  newgroups = realloc (groups, newsize * sizeof (*groups));
	  if (newgroups == NULL)
	    goto done;
	  *groupsp = groups = newgroups;
	  *size = newsize;
	}

      groups[(*start)++] = group;
    }

  save_errno = errno;

  p = *list;
  while (*p != '\0')
    {
      char *endp;
      char *q;
      long int val;

      status = NSS_STATUS_NOTFOUND;

      q = p;
      while (*q != '\0' && *q != ':' && *q != ',')
	++q;

      if (*q != '\0')
	*q++ = '\0';

      __set_errno (0);
      val = strtol (p, &endp, 10);
      /* Test whether the number is representable in a variable of
         type `gid_t'.  If not ignore the number.  */
      if ((sizeof (gid_t) == sizeof (long int) || (gid_t) val == val)
	  && errno == 0)
	{
	  if (*endp == '\0' && endp != p)
	    {
	      group = val;
	      status = NSS_STATUS_SUCCESS;
	    }
	  else
	    status = internal_gid_from_group (context, p, &group);

	  if (status == NSS_STATUS_SUCCESS
	      && !internal_gid_in_list (groups, group, *start))
	    {
	      if (__builtin_expect (*start == *size, 0))
		{
		  /* Need a bigger buffer.  */
		  gid_t *newgroups;
		  long int newsize;

		  if (limit > 0 && *size == limit)
		    /* We reached the maximum.  */
		    goto done;

		  if (limit <= 0)
		    newsize = 2 * *size;
		  else
		    newsize = MIN (limit, 2 * *size);

		  newgroups = realloc (groups, newsize * sizeof (*groups));
		  if (newgroups == NULL)
		    goto done;
		  *groupsp = groups = newgroups;
		  *size = newsize;
		}

	      groups[(*start)++] = group;
	    }
	}

      p = q;
    }

  __set_errno (save_errno);

 done:
  hesiod_free_list (context, list);
  hesiod_end (context);

  return NSS_STATUS_SUCCESS;
}
