Update.
[glibc.git] / nis / nis_table.c
blobe9e35abf3bfb47db99435dfe1cef7c72163e1cac
1 /* Copyright (c) 1997 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
20 #include <string.h>
21 #include <rpcsvc/nis.h>
22 #include <rpcsvc/nislib.h>
23 #include "nis_intern.h"
25 static void
26 splitname (const_nis_name name, nis_name *ibr_name, int *srch_len,
27 nis_attr **srch_val)
29 char *cptr, *key, *val, *next;
30 int size;
32 if (name == NULL)
33 return;
35 cptr = strdup (name);
36 if (srch_len)
37 *srch_len = 0;
38 if (srch_val)
39 *srch_val = NULL;
40 size = 0;
42 /* Not of "[key=value,key=value,...],foo.." format? */
43 if (cptr[0] != '[')
45 *ibr_name = cptr;
46 return;
49 *ibr_name = strchr (cptr, ']');
50 if (*ibr_name == NULL || (*ibr_name)[1] != ',')
52 free (cptr);
53 *ibr_name = NULL;
54 return;
57 *ibr_name[0] = '\0';
58 *ibr_name += 2;
59 *ibr_name = strdup (*ibr_name);
61 if (srch_len == NULL || srch_val == NULL)
63 free (cptr);
64 return;
67 key = (cptr) + 1;
70 next = strchr (key, ',');
71 if (next)
73 next[0] = '\0';
74 ++next;
77 val = strchr (key, '=');
78 if (!val)
80 free (cptr);
81 *srch_val = malloc (sizeof (nis_attr));
82 if (*srch_val == NULL)
84 free (cptr);
85 free (*ibr_name);
86 *ibr_name = NULL;
87 return;
89 (*srch_val)[0].zattr_val.zattr_val_len = 0;
90 (*srch_val)[0].zattr_val.zattr_val_val = NULL;
91 return;
94 val[0] = '\0';
95 ++val;
97 if ((*srch_len) + 1 >= size)
99 size += 10;
100 if (size == 10)
101 *srch_val = malloc (size * sizeof (char *));
102 else
103 *srch_val = realloc (val, size * sizeof (char *));
104 if (*srch_val == NULL)
106 free (cptr);
107 free (*ibr_name);
108 *ibr_name = NULL;
109 return;
113 (*srch_val)[*srch_len].zattr_ndx = strdup (key);
114 if (((*srch_val)[*srch_len].zattr_ndx) == NULL)
116 free (cptr);
117 free (*ibr_name);
118 *ibr_name = NULL;
119 return;
121 (*srch_val)[*srch_len].zattr_val.zattr_val_len = strlen (val) + 1;
122 (*srch_val)[*srch_len].zattr_val.zattr_val_val = strdup (val);
123 if ((*srch_val)[*srch_len].zattr_val.zattr_val_val == NULL)
125 free (cptr);
126 free (*ibr_name);
127 *ibr_name = NULL;
128 return;
130 ++(*srch_len);
132 key = next;
135 while (next);
137 free (cptr);
140 static struct ib_request *
141 __create_ib_request (const_nis_name name, struct ib_request *ibreq,
142 u_long flags)
144 splitname (name, &ibreq->ibr_name, &ibreq->ibr_srch.ibr_srch_len,
145 &ibreq->ibr_srch.ibr_srch_val);
146 if (ibreq->ibr_name == NULL)
147 return NULL;
148 if ((flags & EXPAND_NAME) == EXPAND_NAME)
150 nis_name *names;
152 names = __nis_expandname (ibreq->ibr_name);
153 free (ibreq->ibr_name);
154 ibreq->ibr_name = NULL;
155 if (names == NULL)
156 return NULL;
157 ibreq->ibr_name = strdup (names[0]);
158 nis_freenames (names);
161 ibreq->ibr_flags = (flags & (RETURN_RESULT | ADD_OVERWRITE | REM_MULTIPLE |
162 MOD_SAMEOBJ | ADD_RESERVED | REM_RESERVED |
163 MOD_EXCLUSIVE));
164 ibreq->ibr_obj.ibr_obj_len = 0;
165 ibreq->ibr_obj.ibr_obj_val = NULL;
166 ibreq->ibr_cbhost.ibr_cbhost_len = 0;
167 ibreq->ibr_cbhost.ibr_cbhost_val = NULL;
168 ibreq->ibr_bufsize = 0;
169 ibreq->ibr_cookie.n_len = 0;
170 ibreq->ibr_cookie.n_bytes = NULL;
172 return ibreq;
175 nis_result *
176 nis_list (const_nis_name name, u_long flags,
177 int (*callback) (const_nis_name name,
178 const nis_object *object,
179 const void *userdata),
180 const void *userdata)
182 nis_result *res = NULL;
183 struct ib_request ibreq;
184 int result;
185 int count_links = 0; /* We will only follow 16 links! */
186 int is_link = 1; /* We should go at least once in the while loop */
188 res = calloc (1, sizeof (nis_result));
190 if (__create_ib_request (name, &ibreq, flags) == NULL)
192 res->status = NIS_BADNAME;
193 return res;
196 while (is_link)
198 memset (res, '\0', sizeof (nis_result));
200 if ((result = __do_niscall (ibreq.ibr_name, NIS_IBLIST,
201 (xdrproc_t) xdr_ib_request,
202 (caddr_t) &ibreq, (xdrproc_t) xdr_nis_result,
203 (caddr_t) res, flags)) != RPC_SUCCESS)
205 res->status = result;
206 nis_free_request (&ibreq);
207 return res;
210 nis_free_request (&ibreq);
212 if ((res->status == NIS_SUCCESS || res->status == NIS_S_SUCCESS) &&
213 (res->objects.objects_len > 0 &&
214 res->objects.objects_val->zo_data.zo_type == LINK_OBJ))
215 is_link = 1;
216 else
217 is_link = 0;
219 if (is_link)
221 if ((flags & FOLLOW_LINKS) == FOLLOW_LINKS)
223 if (count_links == 16)
225 res->status = NIS_LINKNAMEERROR;
226 return res;
228 else
229 ++count_links;
231 if (__create_ib_request (res->objects.objects_val->LI_data.li_name,
232 &ibreq, flags) == NULL)
234 res->status = NIS_BADNAME;
235 return res;
238 else
240 res->status = NIS_NOTSEARCHABLE;
241 return res;
246 if (callback != NULL &&
247 (res->status == NIS_SUCCESS || res->status == NIS_S_SUCCESS))
249 unsigned int i;
251 for (i = 0; i < res->objects.objects_len; ++i)
252 if ((*callback) (name, &(res->objects.objects_val)[i], userdata) != 0)
253 break;
256 return res;
259 nis_result *
260 nis_add_entry (const_nis_name name, const nis_object *obj,
261 u_long flags)
263 nis_result *res;
264 struct ib_request ibreq;
265 nis_error status;
267 res = calloc (1, sizeof (nis_result));
269 if (__create_ib_request (name, &ibreq, flags) == NULL)
271 res->status = NIS_BADNAME;
272 return res;
275 ibreq.ibr_flags = flags;
276 ibreq.ibr_obj.ibr_obj_val = nis_clone_object (obj, NULL);
277 ibreq.ibr_obj.ibr_obj_len = 1;
279 if ((status = __do_niscall (ibreq.ibr_name, NIS_IBADD,
280 (xdrproc_t) xdr_ib_request,
281 (caddr_t) &ibreq,
282 (xdrproc_t) xdr_nis_result,
283 (caddr_t) res, 0)) != RPC_SUCCESS)
284 res->status = status;
286 nis_free_request (&ibreq);
288 return res;
291 nis_result *
292 nis_modify_entry (const_nis_name name, const nis_object *obj,
293 u_long flags)
295 nis_result *res;
296 struct ib_request ibreq;
297 nis_error status;
299 res = calloc (1, sizeof (nis_result));
301 if (__create_ib_request (name, &ibreq, flags) == NULL)
303 res->status = NIS_BADNAME;
304 return res;
307 ibreq.ibr_flags = flags;
308 ibreq.ibr_obj.ibr_obj_val = nis_clone_object (obj, NULL);
309 ibreq.ibr_obj.ibr_obj_len = 1;
311 if ((status = __do_niscall (ibreq.ibr_name, NIS_IBMODIFY,
312 (xdrproc_t) xdr_ib_request,
313 (caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
314 (caddr_t) res, 0)) != RPC_SUCCESS)
315 res->status = status;
317 nis_free_request (&ibreq);
319 return res;
322 nis_result *
323 nis_remove_entry (const_nis_name name, const nis_object *obj,
324 u_long flags)
326 nis_result *res;
327 struct ib_request ibreq;
328 nis_error status;
330 res = calloc (1, sizeof (nis_result));
332 if (__create_ib_request (name, &ibreq, flags) == NULL)
334 res->status = NIS_BADNAME;
335 return res;
338 ibreq.ibr_flags = flags;
339 if (obj != NULL)
341 ibreq.ibr_obj.ibr_obj_val = nis_clone_object (obj, NULL);
342 ibreq.ibr_obj.ibr_obj_len = 1;
345 if ((status = __do_niscall (ibreq.ibr_name, NIS_IBREMOVE,
346 (xdrproc_t) xdr_ib_request,
347 (caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
348 (caddr_t) res, 0)) != RPC_SUCCESS)
349 res->status = status;
351 nis_free_request (&ibreq);
353 return res;
356 nis_result *
357 nis_first_entry (const_nis_name name)
359 nis_result *res;
360 struct ib_request ibreq;
361 nis_error status;
363 res = calloc (1, sizeof (nis_result));
365 if (__create_ib_request (name, &ibreq, 0) == NULL)
367 res->status = NIS_BADNAME;
368 return res;
371 if ((status = __do_niscall (ibreq.ibr_name, NIS_IBFIRST,
372 (xdrproc_t) xdr_ib_request,
373 (caddr_t) &ibreq, (xdrproc_t) xdr_nis_result,
374 (caddr_t) res, 0)) != RPC_SUCCESS)
375 res->status = status;
377 nis_free_request (&ibreq);
379 return res;
382 nis_result *
383 nis_next_entry (const_nis_name name, const netobj *cookie)
385 nis_result *res;
386 struct ib_request ibreq;
387 nis_error status;
389 res = calloc (1, sizeof (nis_result));
391 if (__create_ib_request (name, &ibreq, 0) == NULL)
393 res->status = NIS_BADNAME;
394 return res;
397 if (cookie != NULL)
399 ibreq.ibr_cookie.n_bytes = malloc (cookie->n_len);
400 if (ibreq.ibr_cookie.n_bytes == NULL)
402 res->status = NIS_NOMEMORY;
403 free (res);
404 return NULL;
406 memcpy (ibreq.ibr_cookie.n_bytes, cookie->n_bytes, cookie->n_len);
407 ibreq.ibr_cookie.n_len = cookie->n_len;
410 if ((status = __do_niscall (ibreq.ibr_name, NIS_IBNEXT,
411 (xdrproc_t) xdr_ib_request,
412 (caddr_t) &ibreq, (xdrproc_t) xdr_nis_result,
413 (caddr_t) res, 0)) != RPC_SUCCESS)
414 res->status = status;
416 nis_free_request (&ibreq);
418 return res;