]> git.ipfire.org Git - thirdparty/glibc.git/blob - nis/nis_table.c
Update.
[thirdparty/glibc.git] / nis / nis_table.c
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.
4
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.
9
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.
14
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. */
19
20 #include <string.h>
21 #include <rpcsvc/nis.h>
22 #include <rpcsvc/nislib.h>
23 #include "nis_intern.h"
24
25 static void
26 splitname (const_nis_name name, nis_name *ibr_name, int *srch_len,
27 nis_attr **srch_val)
28 {
29 char *cptr, *key, *val, *next;
30 int size;
31
32 if (name == NULL)
33 return;
34
35 cptr = strdup (name);
36 if (srch_len)
37 *srch_len = 0;
38 if (srch_val)
39 *srch_val = NULL;
40 size = 0;
41
42 /* Not of "[key=value,key=value,...],foo.." format? */
43 if (cptr[0] != '[')
44 {
45 *ibr_name = cptr;
46 return;
47 }
48
49 *ibr_name = strchr (cptr, ']');
50 if (*ibr_name == NULL || (*ibr_name)[1] != ',')
51 {
52 free (cptr);
53 *ibr_name = NULL;
54 return;
55 }
56
57 *ibr_name[0] = '\0';
58 *ibr_name += 2;
59 *ibr_name = strdup (*ibr_name);
60
61 if (srch_len == NULL || srch_val == NULL)
62 {
63 free (cptr);
64 return;
65 }
66
67 key = (cptr) + 1;
68 do
69 {
70 next = strchr (key, ',');
71 if (next)
72 {
73 next[0] = '\0';
74 ++next;
75 }
76
77 val = strchr (key, '=');
78 if (!val)
79 {
80 free (cptr);
81 *srch_val = malloc (sizeof (char *));
82 if (*srch_val == NULL)
83 {
84 free (cptr);
85 free (*ibr_name);
86 *ibr_name = NULL;
87 return;
88 }
89 (*srch_val)[*srch_len].zattr_val.zattr_val_len = 0;
90 (*srch_val)[*srch_len].zattr_val.zattr_val_val = NULL;
91 return;
92 }
93
94 val[0] = '\0';
95 ++val;
96
97 if ((*srch_len) + 1 >= size)
98 {
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)
105 {
106 free (cptr);
107 free (*ibr_name);
108 *ibr_name = NULL;
109 return;
110 }
111 }
112
113 (*srch_val)[*srch_len].zattr_ndx = strdup (key);
114 if (((*srch_val)[*srch_len].zattr_ndx) == NULL)
115 {
116 free (cptr);
117 free (*ibr_name);
118 *ibr_name = NULL;
119 return;
120 }
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)
124 {
125 free (cptr);
126 free (*ibr_name);
127 *ibr_name = NULL;
128 return;
129 }
130 ++(*srch_len);
131
132 key = next;
133
134 }
135 while (next);
136
137 free (cptr);
138 }
139
140 static struct ib_request *
141 __create_ib_request (const_nis_name name, struct ib_request *ibreq,
142 u_long flags)
143 {
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)
149 {
150 nis_name *names;
151
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);
159 }
160
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;
171
172 return ibreq;
173 }
174
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)
181 {
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 */
187
188 res = calloc (1, sizeof (nis_result));
189
190 if (__create_ib_request (name, &ibreq, flags) == NULL)
191 {
192 res->status = NIS_BADNAME;
193 return res;
194 }
195
196 while (is_link)
197 {
198 memset (res, '\0', sizeof (nis_result));
199
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)
204 {
205 res->status = result;
206 nis_free_request (&ibreq);
207 return res;
208 }
209
210 nis_free_request (&ibreq);
211
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;
218
219 if (is_link)
220 {
221 if ((flags & FOLLOW_LINKS) == FOLLOW_LINKS)
222 {
223 if (count_links == 16)
224 {
225 res->status = NIS_LINKNAMEERROR;
226 return res;
227 }
228 else
229 ++count_links;
230
231 if (__create_ib_request (res->objects.objects_val->LI_data.li_name,
232 &ibreq, flags) == NULL)
233 {
234 res->status = NIS_BADNAME;
235 return res;
236 }
237 }
238 else
239 {
240 res->status = NIS_NOTSEARCHABLE;
241 return res;
242 }
243 }
244 }
245
246 if (callback != NULL &&
247 (res->status == NIS_SUCCESS || res->status == NIS_S_SUCCESS))
248 {
249 unsigned int i;
250
251 for (i = 0; i < res->objects.objects_len; ++i)
252 if ((*callback) (name, &(res->objects.objects_val)[i], userdata) != 0)
253 break;
254 }
255
256 return res;
257 }
258
259 nis_result *
260 nis_add_entry (const_nis_name name, const nis_object *obj,
261 u_long flags)
262 {
263 nis_result *res;
264 struct ib_request ibreq;
265 nis_error status;
266
267 res = calloc (1, sizeof (nis_result));
268
269 if (__create_ib_request (name, &ibreq, flags) == NULL)
270 {
271 res->status = NIS_BADNAME;
272 return res;
273 }
274
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;
278
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;
285
286 nis_free_request (&ibreq);
287
288 return res;
289 }
290
291 nis_result *
292 nis_modify_entry (const_nis_name name, const nis_object *obj,
293 u_long flags)
294 {
295 nis_result *res;
296 struct ib_request ibreq;
297 nis_error status;
298
299 res = calloc (1, sizeof (nis_result));
300
301 if (__create_ib_request (name, &ibreq, flags) == NULL)
302 {
303 res->status = NIS_BADNAME;
304 return res;
305 }
306
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;
310
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;
316
317 nis_free_request (&ibreq);
318
319 return res;
320 }
321
322 nis_result *
323 nis_remove_entry (const_nis_name name, const nis_object *obj,
324 u_long flags)
325 {
326 nis_result *res;
327 struct ib_request ibreq;
328 nis_error status;
329
330 res = calloc (1, sizeof (nis_result));
331
332 if (__create_ib_request (name, &ibreq, flags) == NULL)
333 {
334 res->status = NIS_BADNAME;
335 return res;
336 }
337
338 ibreq.ibr_flags = flags;
339 if (obj != NULL)
340 {
341 ibreq.ibr_obj.ibr_obj_val = nis_clone_object (obj, NULL);
342 ibreq.ibr_obj.ibr_obj_len = 1;
343 }
344
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;
350
351 nis_free_request (&ibreq);
352
353 return res;
354 }
355
356 nis_result *
357 nis_first_entry (const_nis_name name)
358 {
359 nis_result *res;
360 struct ib_request ibreq;
361 nis_error status;
362
363 res = calloc (1, sizeof (nis_result));
364
365 if (__create_ib_request (name, &ibreq, 0) == NULL)
366 {
367 res->status = NIS_BADNAME;
368 return res;
369 }
370
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;
376
377 nis_free_request (&ibreq);
378
379 return res;
380 }
381
382 nis_result *
383 nis_next_entry (const_nis_name name, const netobj *cookie)
384 {
385 nis_result *res;
386 struct ib_request ibreq;
387 nis_error status;
388
389 res = calloc (1, sizeof (nis_result));
390
391 if (__create_ib_request (name, &ibreq, 0) == NULL)
392 {
393 res->status = NIS_BADNAME;
394 return res;
395 }
396
397 if (cookie != NULL)
398 {
399 ibreq.ibr_cookie.n_bytes = malloc (cookie->n_len);
400 if (ibreq.ibr_cookie.n_bytes == NULL)
401 {
402 res->status = NIS_NOMEMORY;
403 free (res);
404 return NULL;
405 }
406 memcpy (ibreq.ibr_cookie.n_bytes, cookie->n_bytes, cookie->n_len);
407 ibreq.ibr_cookie.n_len = cookie->n_len;
408 }
409
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;
415
416 nis_free_request (&ibreq);
417
418 return res;
419 }