/* Copyright (c) 1997, 1998, 1999, 2000, 2006 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 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 <string.h>
#include <rpcsvc/nis.h>

#include "nis_xdr.h"
#include "nis_intern.h"

nis_server **
nis_getservlist (const_nis_name dir)
{
  nis_result *res;
  nis_server **serv;

  res = nis_lookup (dir, FOLLOW_LINKS);

  if (res != NULL && NIS_RES_STATUS (res) == NIS_SUCCESS)
    {
      unsigned long i;
      nis_server *server;

      serv =
	malloc (sizeof (nis_server *) *
		(NIS_RES_OBJECT (res)->DI_data.do_servers.do_servers_len + 1));
      if (__builtin_expect (serv == NULL, 0))
	{
	  nis_freeresult (res);
	  return NULL;
	}

      for (i = 0; i < NIS_RES_OBJECT (res)->DI_data.do_servers.do_servers_len;
	   ++i)
	{
	  server =
	    &NIS_RES_OBJECT (res)->DI_data.do_servers.do_servers_val[i];
	  serv[i] = calloc (1, sizeof (nis_server));
	  if (__builtin_expect (serv[i] == NULL, 0))
	    {
	    free_all:
	      while (i-- > 0)
		{
		  free (serv[i]->pkey.n_bytes);
		  if (serv[i]->ep.ep_val != NULL)
		    {
		      unsigned long int j;
		      for (j = 0; j < serv[i]->ep.ep_len; ++j)
			{
			  free (serv[i]->ep.ep_val[j].proto);
			  free (serv[i]->ep.ep_val[j].family);
			  free (serv[i]->ep.ep_val[j].uaddr);
			}
		      free (serv[i]->ep.ep_val);
		    }
		  free (serv[i]->name);
		  free (serv[i]);
		}

	      free (serv);

	      nis_freeresult (res);

	      return NULL;
	    }

	  if (server->name != NULL)
	    {
	      serv[i]->name = strdup (server->name);
	      if (__builtin_expect (serv[i]->name == NULL, 0))
		{
		  ++i;
		  goto free_all;
		}
	    }

          serv[i]->ep.ep_len = server->ep.ep_len;
          if (serv[i]->ep.ep_len > 0)
            {
              unsigned long int j;

              serv[i]->ep.ep_val =
		malloc (server->ep.ep_len * sizeof (endpoint));
	      if (__builtin_expect (serv[i]->ep.ep_val == NULL, 0))
		{
		  ++i;
		  goto free_all;
		}

              for (j = 0; j < serv[i]->ep.ep_len; ++j)
                {
                  if (server->ep.ep_val[j].uaddr)
                    serv[i]->ep.ep_val[j].uaddr =
		      strdup (server->ep.ep_val[j].uaddr);
                  else
                    serv[i]->ep.ep_val[j].uaddr = NULL;
                  if (server->ep.ep_val[j].family)
		    serv[i]->ep.ep_val[j].family =
		      strdup (server->ep.ep_val[j].family);
                  else
                    serv[i]->ep.ep_val[j].family = NULL;
                  if (server->ep.ep_val[j].proto)
		    serv[i]->ep.ep_val[j].proto =
		      strdup (server->ep.ep_val[j].proto);
                  else
		    serv[i]->ep.ep_val[j].proto = NULL;
                }
            }

          serv[i]->key_type = server->key_type;
          serv[i]->pkey.n_len = server->pkey.n_len;
          if (server->pkey.n_len > 0)
            {
              serv[i]->pkey.n_bytes = malloc (server->pkey.n_len);
              if (__builtin_expect (serv[i]->pkey.n_bytes == NULL, 0))
		{
		  ++i;
		  goto free_all;
		}
              memcpy (serv[i]->pkey.n_bytes, server->pkey.n_bytes,
                      server->pkey.n_len);
            }
        }
      serv[i] = NULL;
    }
  else
    {
      serv = malloc (sizeof (nis_server *));
      if (__builtin_expect (serv != NULL, 0))
	serv[0] = NULL;
    }

  nis_freeresult (res);

  return serv;
}

void
nis_freeservlist (nis_server **serv)
{
  int i;

  if (serv == NULL)
    return;

  i = 0;
  while (serv[i] != NULL)
    {
      xdr_free ((xdrproc_t)_xdr_nis_server, (char *)serv[i]);
      free (serv[i]);
      ++i;
    }
  free (serv);
}
