update from main archive 970619
[glibc/history.git] / nis / nis_table.c
blob4cfd7341730a9ecd12137dc54d45f9dc8402cbd8
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 nis_error status;
265 struct ib_request ibreq;
266 char *p1, *p2, *p3, *p4;
267 char buf1 [strlen (name) + 20];
268 char buf4 [strlen (name) + 20];
270 res = calloc (1, sizeof (nis_result));
272 if (__create_ib_request (name, &ibreq, flags) == NULL)
274 res->status = NIS_BADNAME;
275 return res;
278 ibreq.ibr_flags = flags;
279 ibreq.ibr_obj.ibr_obj_val = nis_clone_object (obj, NULL);
280 ibreq.ibr_obj.ibr_obj_len = 1;
282 p1 = ibreq.ibr_obj.ibr_obj_val[0].zo_name;
283 if (p1 == NULL || strlen (p1) == 0)
284 ibreq.ibr_obj.ibr_obj_val[0].zo_name =
285 nis_leaf_of_r (name, buf1, sizeof (buf1));
287 p2 = ibreq.ibr_obj.ibr_obj_val[0].zo_owner;
288 if (p2 == NULL || strlen (p2) == 0)
289 ibreq.ibr_obj.ibr_obj_val[0].zo_owner = nis_local_principal ();
291 p3 = ibreq.ibr_obj.ibr_obj_val[0].zo_group;
292 if (p3 == NULL || strlen (p3) == 0)
293 ibreq.ibr_obj.ibr_obj_val[0].zo_group = nis_local_group ();
295 p4 = ibreq.ibr_obj.ibr_obj_val[0].zo_domain;
296 ibreq.ibr_obj.ibr_obj_val[0].zo_domain =
297 nis_domain_of_r (name, buf4, sizeof (buf4));
299 if ((status = __do_niscall (ibreq.ibr_name, NIS_IBADD,
300 (xdrproc_t) xdr_ib_request,
301 (caddr_t) &ibreq,
302 (xdrproc_t) xdr_nis_result,
303 (caddr_t) res, 0)) != RPC_SUCCESS)
304 res->status = status;
306 ibreq.ibr_obj.ibr_obj_val[0].zo_name = p1;
307 ibreq.ibr_obj.ibr_obj_val[0].zo_owner = p2;
308 ibreq.ibr_obj.ibr_obj_val[0].zo_group = p3;
309 ibreq.ibr_obj.ibr_obj_val[0].zo_domain = p4;
311 nis_free_request (&ibreq);
313 return res;
316 nis_result *
317 nis_modify_entry (const_nis_name name, const nis_object *obj,
318 u_long flags)
320 nis_result *res;
321 nis_error status;
322 struct ib_request ibreq;
323 char *p1, *p2, *p3, *p4;
324 char buf1 [strlen (name) + 20];
325 char buf4 [strlen (name) + 20];
327 res = calloc (1, sizeof (nis_result));
329 if (__create_ib_request (name, &ibreq, flags) == NULL)
331 res->status = NIS_BADNAME;
332 return res;
335 ibreq.ibr_flags = flags;
336 ibreq.ibr_obj.ibr_obj_val = nis_clone_object (obj, NULL);
337 ibreq.ibr_obj.ibr_obj_len = 1;
339 p1 = ibreq.ibr_obj.ibr_obj_val[0].zo_name;
340 if (p1 == NULL || strlen (p1) == 0)
341 ibreq.ibr_obj.ibr_obj_val[0].zo_name =
342 nis_leaf_of_r (name, buf1, sizeof (buf1));
344 p2 = ibreq.ibr_obj.ibr_obj_val[0].zo_owner;
345 if (p2 == NULL || strlen (p2) == 0)
346 ibreq.ibr_obj.ibr_obj_val[0].zo_owner = nis_local_principal ();
348 p3 = ibreq.ibr_obj.ibr_obj_val[0].zo_group;
349 if (p3 == NULL || strlen (p3) == 0)
350 ibreq.ibr_obj.ibr_obj_val[0].zo_group = nis_local_group ();
352 p4 = ibreq.ibr_obj.ibr_obj_val[0].zo_domain;
353 ibreq.ibr_obj.ibr_obj_val[0].zo_domain =
354 nis_domain_of_r (name, buf4, sizeof (buf4));
356 if ((status = __do_niscall (ibreq.ibr_name, NIS_IBMODIFY,
357 (xdrproc_t) xdr_ib_request,
358 (caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
359 (caddr_t) res, 0)) != RPC_SUCCESS)
360 res->status = status;
362 ibreq.ibr_obj.ibr_obj_val[0].zo_name = p1;
363 ibreq.ibr_obj.ibr_obj_val[0].zo_owner = p2;
364 ibreq.ibr_obj.ibr_obj_val[0].zo_group = p3;
365 ibreq.ibr_obj.ibr_obj_val[0].zo_domain = p4;
367 nis_free_request (&ibreq);
369 return res;
372 nis_result *
373 nis_remove_entry (const_nis_name name, const nis_object *obj,
374 u_long flags)
376 nis_result *res;
377 struct ib_request ibreq;
378 nis_error status;
380 res = calloc (1, sizeof (nis_result));
382 if (__create_ib_request (name, &ibreq, flags) == NULL)
384 res->status = NIS_BADNAME;
385 return res;
388 ibreq.ibr_flags = flags;
389 if (obj != NULL)
391 ibreq.ibr_obj.ibr_obj_val = nis_clone_object (obj, NULL);
392 ibreq.ibr_obj.ibr_obj_len = 1;
395 if ((status = __do_niscall (ibreq.ibr_name, NIS_IBREMOVE,
396 (xdrproc_t) xdr_ib_request,
397 (caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
398 (caddr_t) res, 0)) != RPC_SUCCESS)
399 res->status = status;
401 nis_free_request (&ibreq);
403 return res;
406 nis_result *
407 nis_first_entry (const_nis_name name)
409 nis_result *res;
410 struct ib_request ibreq;
411 nis_error status;
413 res = calloc (1, sizeof (nis_result));
415 if (__create_ib_request (name, &ibreq, 0) == NULL)
417 res->status = NIS_BADNAME;
418 return res;
421 if ((status = __do_niscall (ibreq.ibr_name, NIS_IBFIRST,
422 (xdrproc_t) xdr_ib_request,
423 (caddr_t) &ibreq, (xdrproc_t) xdr_nis_result,
424 (caddr_t) res, 0)) != RPC_SUCCESS)
425 res->status = status;
427 nis_free_request (&ibreq);
429 return res;
432 nis_result *
433 nis_next_entry (const_nis_name name, const netobj *cookie)
435 nis_result *res;
436 struct ib_request ibreq;
437 nis_error status;
439 res = calloc (1, sizeof (nis_result));
441 if (__create_ib_request (name, &ibreq, 0) == NULL)
443 res->status = NIS_BADNAME;
444 return res;
447 if (cookie != NULL)
449 ibreq.ibr_cookie.n_bytes = malloc (cookie->n_len);
450 if (ibreq.ibr_cookie.n_bytes == NULL)
452 res->status = NIS_NOMEMORY;
453 free (res);
454 return NULL;
456 memcpy (ibreq.ibr_cookie.n_bytes, cookie->n_bytes, cookie->n_len);
457 ibreq.ibr_cookie.n_len = cookie->n_len;
460 if ((status = __do_niscall (ibreq.ibr_name, NIS_IBNEXT,
461 (xdrproc_t) xdr_ib_request,
462 (caddr_t) &ibreq, (xdrproc_t) xdr_nis_result,
463 (caddr_t) res, 0)) != RPC_SUCCESS)
464 res->status = status;
466 nis_free_request (&ibreq);
468 return res;