| /* 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); |
| } |