Sync libc/stdlib with FreeBSD (ignoring jemalloc, pts, and gdtoa):
[dragonfly.git] / lib / libc / rpc / getrpcent.c
bloba5b8b55878d794b473a441bad9515b4b894a9320
1 /*
2 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3 * unrestricted use provided that this legend is included on all tape
4 * media and as a part of the software program in whole or part. Users
5 * may copy or modify Sun RPC without charge, but are not authorized
6 * to license or distribute it to anyone else except as part of a product or
7 * program developed by the user or with the express written consent of
8 * Sun Microsystems, Inc.
10 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
14 * Sun RPC is provided with no support and without any obligation on the
15 * part of Sun Microsystems, Inc. to assist in its use, correction,
16 * modification or enhancement.
18 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20 * OR ANY PART THEREOF.
22 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23 * or profits or other special, indirect and consequential damages, even if
24 * Sun has been advised of the possibility of such damages.
26 * Sun Microsystems, Inc.
27 * 2550 Garcia Avenue
28 * Mountain View, California 94043
30 * @(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro
31 * $NetBSD: getrpcent.c,v 1.17 2000/01/22 22:19:17 mycroft Exp $
32 * $FreeBSD: src/lib/libc/rpc/getrpcent.c,v 1.16 2007/05/17 03:34:33 jon Exp $
33 * $DragonFly: src/lib/libc/rpc/getrpcent.c,v 1.4 2005/11/13 12:27:04 swildner Exp $
37 * Copyright (c) 1984 by Sun Microsystems, Inc.
40 #include <sys/param.h>
41 #include <sys/types.h>
42 #include <sys/socket.h>
43 #include <arpa/inet.h>
44 #include <assert.h>
45 #include <errno.h>
46 #include <nsswitch.h>
47 #include <netinet/in.h>
48 #include <stdio.h>
49 #include <string.h>
50 #include <stdarg.h>
51 #include <stdlib.h>
52 #include <rpc/rpc.h>
53 #ifdef YP
54 #include <rpcsvc/yp_prot.h>
55 #include <rpcsvc/ypclnt.h>
56 #endif
57 #include <unistd.h>
58 #include "namespace.h"
59 #include "reentrant.h"
60 #include "un-namespace.h"
61 #include "libc_private.h"
62 #include "nss_tls.h"
63 #ifdef NS_CACHING
64 #include "nscache.h"
65 #endif
67 #define RPCDB "/etc/rpc"
69 /* nsswitch declarations */
70 enum constants
72 SETRPCENT = 1,
73 ENDRPCENT = 2,
74 RPCENT_STORAGE_INITIAL = 1 << 10, /* 1 KByte */
75 RPCENT_STORAGE_MAX = 1 << 20, /* 1 MByte */
78 static const ns_src defaultsrc[] = {
79 { NSSRC_FILES, NS_SUCCESS },
80 #ifdef YP
81 { NSSRC_NIS, NS_SUCCESS },
82 #endif
83 { NULL, 0 }
86 /* files backend declarations */
87 struct files_state {
88 FILE *fp;
89 int stayopen;
92 static int files_rpcent(void *, void *, va_list);
93 static int files_setrpcent(void *, void *, va_list);
95 static void files_endstate(void *);
96 NSS_TLS_HANDLING(files);
98 /* nis backend declarations */
99 #ifdef YP
100 struct nis_state {
101 char domain[MAXHOSTNAMELEN];
102 char *current;
103 int currentlen;
104 int stepping;
105 int no_name_map;
108 static int nis_rpcent(void *, void *, va_list);
109 static int nis_setrpcent(void *, void *, va_list);
111 static void nis_endstate(void *);
112 NSS_TLS_HANDLING(nis);
113 #endif
115 /* get** wrappers for get**_r functions declarations */
116 struct rpcent_state {
117 struct rpcent rpc;
118 char *buffer;
119 size_t bufsize;
121 static void rpcent_endstate(void *);
122 NSS_TLS_HANDLING(rpcent);
124 union key {
125 const char *name;
126 int number;
129 static int wrap_getrpcbyname_r(union key, struct rpcent *, char *,
130 size_t, struct rpcent **);
131 static int wrap_getrpcbynumber_r(union key, struct rpcent *, char *,
132 size_t, struct rpcent **);
133 static int wrap_getrpcent_r(union key, struct rpcent *, char *,
134 size_t, struct rpcent **);
135 static struct rpcent *getrpc(int (*fn)(union key, struct rpcent *, char *,
136 size_t, struct rpcent **), union key);
138 #ifdef NS_CACHING
139 static int rpc_id_func(char *, size_t *, va_list, void *);
140 static int rpc_marshal_func(char *, size_t *, void *, va_list, void *);
141 static int rpc_unmarshal_func(char *, size_t, void *, va_list, void *);
142 #endif
144 static int
145 rpcent_unpack(char *p, struct rpcent *rpc, char **r_aliases,
146 size_t aliases_size, int *errnop)
148 char *cp, **q;
150 assert(p != NULL);
152 if (*p == '#')
153 return (-1);
154 cp = strpbrk(p, "#\n");
155 if (cp == NULL)
156 return (-1);
157 *cp = '\0';
158 cp = strpbrk(p, " \t");
159 if (cp == NULL)
160 return (-1);
161 *cp++ = '\0';
162 /* THIS STUFF IS INTERNET SPECIFIC */
163 rpc->r_name = p;
164 while (*cp == ' ' || *cp == '\t')
165 cp++;
166 rpc->r_number = atoi(cp);
167 q = rpc->r_aliases = r_aliases;
168 cp = strpbrk(cp, " \t");
169 if (cp != NULL)
170 *cp++ = '\0';
171 while (cp && *cp) {
172 if (*cp == ' ' || *cp == '\t') {
173 cp++;
174 continue;
176 if (q < &(r_aliases[aliases_size - 1]))
177 *q++ = cp;
178 else {
179 *errnop = ERANGE;
180 return -1;
183 cp = strpbrk(cp, " \t");
184 if (cp != NULL)
185 *cp++ = '\0';
187 *q = NULL;
188 return 0;
191 /* files backend implementation */
192 static void
193 files_endstate(void *p)
195 FILE * f;
197 if (p == NULL)
198 return;
200 f = ((struct files_state *)p)->fp;
201 if (f != NULL)
202 fclose(f);
204 free(p);
207 static int
208 files_rpcent(void *retval, void *mdata, va_list ap)
210 char *name;
211 int number;
212 struct rpcent *rpc;
213 char *buffer;
214 size_t bufsize;
215 int *errnop;
217 char *line;
218 size_t linesize;
219 char **aliases;
220 int aliases_size;
221 char **rp;
223 struct files_state *st;
224 int rv;
225 int stayopen;
226 enum nss_lookup_type how;
228 how = (enum nss_lookup_type)mdata;
229 switch (how)
231 case nss_lt_name:
232 name = va_arg(ap, char *);
233 break;
234 case nss_lt_id:
235 number = va_arg(ap, int);
236 break;
237 case nss_lt_all:
238 break;
239 default:
240 return (NS_NOTFOUND);
243 rpc = va_arg(ap, struct rpcent *);
244 buffer = va_arg(ap, char *);
245 bufsize = va_arg(ap, size_t);
246 errnop = va_arg(ap, int *);
248 *errnop = files_getstate(&st);
249 if (*errnop != 0)
250 return (NS_UNAVAIL);
252 if (st->fp == NULL && (st->fp = fopen(RPCDB, "r")) == NULL) {
253 *errnop = errno;
254 return (NS_UNAVAIL);
257 if (how == nss_lt_all)
258 stayopen = 1;
259 else {
260 rewind(st->fp);
261 stayopen = st->stayopen;
264 do {
265 if ((line = fgetln(st->fp, &linesize)) == NULL) {
266 *errnop = errno;
267 rv = NS_RETURN;
268 break;
271 if (bufsize <= linesize + _ALIGNBYTES + sizeof(char *)) {
272 *errnop = ERANGE;
273 rv = NS_RETURN;
274 break;
277 aliases = (char **)_ALIGN(&buffer[linesize+1]);
278 aliases_size = (buffer + bufsize -
279 (char *)aliases)/sizeof(char *);
280 if (aliases_size < 1) {
281 *errnop = ERANGE;
282 rv = NS_RETURN;
283 break;
286 memcpy(buffer, line, linesize);
287 buffer[linesize] = '\0';
289 rv = rpcent_unpack(buffer, rpc, aliases, aliases_size, errnop);
290 if (rv != 0) {
291 if (*errnop == 0) {
292 rv = NS_NOTFOUND;
293 continue;
295 else {
296 rv = NS_RETURN;
297 break;
301 switch (how)
303 case nss_lt_name:
304 if (strcmp(rpc->r_name, name) == 0)
305 goto done;
306 for (rp = rpc->r_aliases; *rp != NULL; rp++) {
307 if (strcmp(*rp, name) == 0)
308 goto done;
310 rv = NS_NOTFOUND;
311 continue;
312 done:
313 rv = NS_SUCCESS;
314 break;
315 case nss_lt_id:
316 rv = (rpc->r_number == number) ? NS_SUCCESS :
317 NS_NOTFOUND;
318 break;
319 case nss_lt_all:
320 rv = NS_SUCCESS;
321 break;
324 } while (!(rv & NS_TERMINATE));
326 if (!stayopen && st->fp!=NULL) {
327 fclose(st->fp);
328 st->fp = NULL;
331 if ((rv == NS_SUCCESS) && (retval != NULL))
332 *((struct rpcent **)retval) = rpc;
334 return (rv);
337 static int
338 files_setrpcent(void *retval, void *mdata, va_list ap)
340 struct files_state *st;
341 int rv;
342 int f;
344 rv = files_getstate(&st);
345 if (rv != 0)
346 return (NS_UNAVAIL);
348 switch ((enum constants)mdata)
350 case SETRPCENT:
351 f = va_arg(ap,int);
352 if (st->fp == NULL)
353 st->fp = fopen(RPCDB, "r");
354 else
355 rewind(st->fp);
356 st->stayopen |= f;
357 break;
358 case ENDRPCENT:
359 if (st->fp != NULL) {
360 fclose(st->fp);
361 st->fp = NULL;
363 st->stayopen = 0;
364 break;
365 default:
366 break;
369 return (NS_UNAVAIL);
372 /* nis backend implementation */
373 #ifdef YP
374 static void
375 nis_endstate(void *p)
377 if (p == NULL)
378 return;
380 free(((struct nis_state *)p)->current);
381 free(p);
384 static int
385 nis_rpcent(void *retval, void *mdata, va_list ap)
387 char *name;
388 int number;
389 struct rpcent *rpc;
390 char *buffer;
391 size_t bufsize;
392 int *errnop;
394 char **rp;
395 char **aliases;
396 int aliases_size;
398 char *lastkey;
399 char *resultbuf;
400 int resultbuflen;
401 char buf[YPMAXRECORD + 2];
403 struct nis_state *st;
404 int rv;
405 enum nss_lookup_type how;
406 int no_name_active;
408 how = (enum nss_lookup_type)mdata;
409 switch (how)
411 case nss_lt_name:
412 name = va_arg(ap, char *);
413 break;
414 case nss_lt_id:
415 number = va_arg(ap, int);
416 break;
417 case nss_lt_all:
418 break;
419 default:
420 return (NS_NOTFOUND);
423 rpc = va_arg(ap, struct rpcent *);
424 buffer = va_arg(ap, char *);
425 bufsize = va_arg(ap, size_t);
426 errnop = va_arg(ap, int *);
428 *errnop = nis_getstate(&st);
429 if (*errnop != 0)
430 return (NS_UNAVAIL);
432 if (st->domain[0] == '\0') {
433 if (getdomainname(st->domain, sizeof(st->domain)) != 0) {
434 *errnop = errno;
435 return (NS_UNAVAIL);
439 no_name_active = 0;
440 do {
441 switch (how)
443 case nss_lt_name:
444 if (!st->no_name_map)
446 snprintf(buf, sizeof buf, "%s", name);
447 rv = yp_match(st->domain, "rpc.byname", buf,
448 strlen(buf), &resultbuf, &resultbuflen);
450 switch (rv) {
451 case 0:
452 break;
453 case YPERR_MAP:
454 st->stepping = 0;
455 no_name_active = 1;
456 how = nss_lt_all;
458 rv = NS_NOTFOUND;
459 continue;
460 default:
461 rv = NS_NOTFOUND;
462 goto fin;
464 } else {
465 st->stepping = 0;
466 no_name_active = 1;
467 how = nss_lt_all;
469 rv = NS_NOTFOUND;
470 continue;
472 break;
473 case nss_lt_id:
474 snprintf(buf, sizeof buf, "%d", number);
475 if (yp_match(st->domain, "rpc.bynumber", buf,
476 strlen(buf), &resultbuf, &resultbuflen)) {
477 rv = NS_NOTFOUND;
478 goto fin;
480 break;
481 case nss_lt_all:
482 if (!st->stepping) {
483 rv = yp_first(st->domain, "rpc.bynumber",
484 &st->current,
485 &st->currentlen, &resultbuf,
486 &resultbuflen);
487 if (rv) {
488 rv = NS_NOTFOUND;
489 goto fin;
491 st->stepping = 1;
492 } else {
493 lastkey = st->current;
494 rv = yp_next(st->domain, "rpc.bynumber",
495 st->current,
496 st->currentlen, &st->current,
497 &st->currentlen,
498 &resultbuf, &resultbuflen);
499 free(lastkey);
500 if (rv) {
501 st->stepping = 0;
502 rv = NS_NOTFOUND;
503 goto fin;
506 break;
509 /* we need a room for additional \n symbol */
510 if (bufsize <= resultbuflen + 1 + _ALIGNBYTES +
511 sizeof(char *)) {
512 *errnop = ERANGE;
513 rv = NS_RETURN;
514 break;
517 aliases=(char **)_ALIGN(&buffer[resultbuflen+2]);
518 aliases_size = (buffer + bufsize - (char *)aliases) /
519 sizeof(char *);
520 if (aliases_size < 1) {
521 *errnop = ERANGE;
522 rv = NS_RETURN;
523 break;
527 * rpcent_unpack expects lines terminated with \n -- make it happy
529 memcpy(buffer, resultbuf, resultbuflen);
530 buffer[resultbuflen] = '\n';
531 buffer[resultbuflen+1] = '\0';
532 free(resultbuf);
534 if (rpcent_unpack(buffer, rpc, aliases, aliases_size,
535 errnop) != 0) {
536 if (*errnop == 0)
537 rv = NS_NOTFOUND;
538 else
539 rv = NS_RETURN;
540 } else {
541 if ((how == nss_lt_all) && (no_name_active != 0)) {
542 if (strcmp(rpc->r_name, name) == 0)
543 goto done;
544 for (rp = rpc->r_aliases; *rp != NULL; rp++) {
545 if (strcmp(*rp, name) == 0)
546 goto done;
548 rv = NS_NOTFOUND;
549 continue;
550 done:
551 rv = NS_SUCCESS;
552 } else
553 rv = NS_SUCCESS;
556 } while (!(rv & NS_TERMINATE) && (how == nss_lt_all));
558 fin:
559 if ((rv == NS_SUCCESS) && (retval != NULL))
560 *((struct rpcent **)retval) = rpc;
562 return (rv);
565 static int
566 nis_setrpcent(void *retval, void *mdata, va_list ap)
568 struct nis_state *st;
569 int rv;
571 rv = nis_getstate(&st);
572 if (rv != 0)
573 return (NS_UNAVAIL);
575 switch ((enum constants)mdata)
577 case SETRPCENT:
578 case ENDRPCENT:
579 free(st->current);
580 st->current = NULL;
581 st->stepping = 0;
582 break;
583 default:
584 break;
587 return (NS_UNAVAIL);
589 #endif
591 #ifdef NS_CACHING
592 static int
593 rpc_id_func(char *buffer, size_t *buffer_size, va_list ap, void *cache_mdata)
595 char *name;
596 int rpc;
598 size_t desired_size, size;
599 enum nss_lookup_type lookup_type;
600 int res = NS_UNAVAIL;
602 lookup_type = (enum nss_lookup_type)cache_mdata;
603 switch (lookup_type) {
604 case nss_lt_name:
605 name = va_arg(ap, char *);
607 size = strlen(name);
608 desired_size = sizeof(enum nss_lookup_type) + size + 1;
609 if (desired_size > *buffer_size) {
610 res = NS_RETURN;
611 goto fin;
614 memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type));
615 memcpy(buffer + sizeof(enum nss_lookup_type), name, size + 1);
617 res = NS_SUCCESS;
618 break;
619 case nss_lt_id:
620 rpc = va_arg(ap, int);
622 desired_size = sizeof(enum nss_lookup_type) + sizeof(int);
623 if (desired_size > *buffer_size) {
624 res = NS_RETURN;
625 goto fin;
628 memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type));
629 memcpy(buffer + sizeof(enum nss_lookup_type), &rpc,
630 sizeof(int));
632 res = NS_SUCCESS;
633 break;
634 default:
635 /* should be unreachable */
636 return (NS_UNAVAIL);
639 fin:
640 *buffer_size = desired_size;
641 return (res);
644 static int
645 rpc_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap,
646 void *cache_mdata)
648 char *name;
649 int num;
650 struct rpcent *rpc;
651 char *orig_buf;
652 size_t orig_buf_size;
654 struct rpcent new_rpc;
655 size_t desired_size, size, aliases_size;
656 char *p;
657 char **alias;
659 switch ((enum nss_lookup_type)cache_mdata) {
660 case nss_lt_name:
661 name = va_arg(ap, char *);
662 break;
663 case nss_lt_id:
664 num = va_arg(ap, int);
665 break;
666 case nss_lt_all:
667 break;
668 default:
669 /* should be unreachable */
670 return (NS_UNAVAIL);
673 rpc = va_arg(ap, struct rpcent *);
674 orig_buf = va_arg(ap, char *);
675 orig_buf_size = va_arg(ap, size_t);
677 desired_size = _ALIGNBYTES + sizeof(struct rpcent) + sizeof(char *);
678 if (rpc->r_name != NULL)
679 desired_size += strlen(rpc->r_name) + 1;
681 if (rpc->r_aliases != NULL) {
682 aliases_size = 0;
683 for (alias = rpc->r_aliases; *alias; ++alias) {
684 desired_size += strlen(*alias) + 1;
685 ++aliases_size;
688 desired_size += _ALIGNBYTES + (aliases_size + 1) *
689 sizeof(char *);
692 if (*buffer_size < desired_size) {
693 /* this assignment is here for future use */
694 *buffer_size = desired_size;
695 return (NS_RETURN);
698 memcpy(&new_rpc, rpc, sizeof(struct rpcent));
700 *buffer_size = desired_size;
701 memset(buffer, 0, desired_size);
702 p = buffer + sizeof(struct rpcent) + sizeof(char *);
703 memcpy(buffer + sizeof(struct rpcent), &p, sizeof(char *));
704 p = (char *)_ALIGN(p);
706 if (new_rpc.r_name != NULL) {
707 size = strlen(new_rpc.r_name);
708 memcpy(p, new_rpc.r_name, size);
709 new_rpc.r_name = p;
710 p += size + 1;
713 if (new_rpc.r_aliases != NULL) {
714 p = (char *)_ALIGN(p);
715 memcpy(p, new_rpc.r_aliases, sizeof(char *) * aliases_size);
716 new_rpc.r_aliases = (char **)p;
717 p += sizeof(char *) * (aliases_size + 1);
719 for (alias = new_rpc.r_aliases; *alias; ++alias) {
720 size = strlen(*alias);
721 memcpy(p, *alias, size);
722 *alias = p;
723 p += size + 1;
727 memcpy(buffer, &new_rpc, sizeof(struct rpcent));
728 return (NS_SUCCESS);
731 static int
732 rpc_unmarshal_func(char *buffer, size_t buffer_size, void *retval, va_list ap,
733 void *cache_mdata)
735 char *name;
736 int num;
737 struct rpcent *rpc;
738 char *orig_buf;
739 size_t orig_buf_size;
740 int *ret_errno;
742 char *p;
743 char **alias;
745 switch ((enum nss_lookup_type)cache_mdata) {
746 case nss_lt_name:
747 name = va_arg(ap, char *);
748 break;
749 case nss_lt_id:
750 num = va_arg(ap, int);
751 break;
752 case nss_lt_all:
753 break;
754 default:
755 /* should be unreachable */
756 return (NS_UNAVAIL);
759 rpc = va_arg(ap, struct rpcent *);
760 orig_buf = va_arg(ap, char *);
761 orig_buf_size = va_arg(ap, size_t);
762 ret_errno = va_arg(ap, int *);
764 if (orig_buf_size <
765 buffer_size - sizeof(struct rpcent) - sizeof(char *)) {
766 *ret_errno = ERANGE;
767 return (NS_RETURN);
770 memcpy(rpc, buffer, sizeof(struct rpcent));
771 memcpy(&p, buffer + sizeof(struct rpcent), sizeof(char *));
773 orig_buf = (char *)_ALIGN(orig_buf);
774 memcpy(orig_buf, buffer + sizeof(struct rpcent) + sizeof(char *) +
775 _ALIGN(p) - (size_t)p,
776 buffer_size - sizeof(struct rpcent) - sizeof(char *) -
777 _ALIGN(p) + (size_t)p);
778 p = (char *)_ALIGN(p);
780 NS_APPLY_OFFSET(rpc->r_name, orig_buf, p, char *);
781 if (rpc->r_aliases != NULL) {
782 NS_APPLY_OFFSET(rpc->r_aliases, orig_buf, p, char **);
784 for (alias = rpc->r_aliases ; *alias; ++alias)
785 NS_APPLY_OFFSET(*alias, orig_buf, p, char *);
788 if (retval != NULL)
789 *((struct rpcent **)retval) = rpc;
791 return (NS_SUCCESS);
794 NSS_MP_CACHE_HANDLING(rpc);
795 #endif /* NS_CACHING */
798 /* get**_r functions implementation */
799 static int
800 getrpcbyname_r(const char *name, struct rpcent *rpc, char *buffer,
801 size_t bufsize, struct rpcent **result)
803 #ifdef NS_CACHING
804 static const nss_cache_info cache_info =
805 NS_COMMON_CACHE_INFO_INITIALIZER(
806 rpc, (void *)nss_lt_name,
807 rpc_id_func, rpc_marshal_func, rpc_unmarshal_func);
808 #endif
809 static const ns_dtab dtab[] = {
810 { NSSRC_FILES, files_rpcent, (void *)nss_lt_name },
811 #ifdef YP
812 { NSSRC_NIS, nis_rpcent, (void *)nss_lt_name },
813 #endif
814 #ifdef NS_CACHING
815 NS_CACHE_CB(&cache_info)
816 #endif
817 { NULL, NULL, NULL }
819 int rv, ret_errno;
821 ret_errno = 0;
822 *result = NULL;
823 rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbyname_r", defaultsrc,
824 name, rpc, buffer, bufsize, &ret_errno);
826 if (rv == NS_SUCCESS)
827 return (0);
828 else
829 return (ret_errno);
832 static int
833 getrpcbynumber_r(int number, struct rpcent *rpc, char *buffer,
834 size_t bufsize, struct rpcent **result)
836 #ifdef NS_CACHING
837 static const nss_cache_info cache_info =
838 NS_COMMON_CACHE_INFO_INITIALIZER(
839 rpc, (void *)nss_lt_id,
840 rpc_id_func, rpc_marshal_func, rpc_unmarshal_func);
841 #endif
842 static const ns_dtab dtab[] = {
843 { NSSRC_FILES, files_rpcent, (void *)nss_lt_id },
844 #ifdef YP
845 { NSSRC_NIS, nis_rpcent, (void *)nss_lt_id },
846 #endif
847 #ifdef NS_CACHING
848 NS_CACHE_CB(&cache_info)
849 #endif
850 { NULL, NULL, NULL }
852 int rv, ret_errno;
854 ret_errno = 0;
855 *result = NULL;
856 rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbynumber_r", defaultsrc,
857 number, rpc, buffer, bufsize, &ret_errno);
859 if (rv == NS_SUCCESS)
860 return (0);
861 else
862 return (ret_errno);
865 static int
866 getrpcent_r(struct rpcent *rpc, char *buffer, size_t bufsize,
867 struct rpcent **result)
869 #ifdef NS_CACHING
870 static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER(
871 rpc, (void *)nss_lt_all,
872 rpc_marshal_func, rpc_unmarshal_func);
873 #endif
874 static const ns_dtab dtab[] = {
875 { NSSRC_FILES, files_rpcent, (void *)nss_lt_all },
876 #ifdef YP
877 { NSSRC_NIS, nis_rpcent, (void *)nss_lt_all },
878 #endif
879 #ifdef NS_CACHING
880 NS_CACHE_CB(&cache_info)
881 #endif
882 { NULL, NULL, NULL }
884 int rv, ret_errno;
886 ret_errno = 0;
887 *result = NULL;
888 rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcent_r", defaultsrc,
889 rpc, buffer, bufsize, &ret_errno);
891 if (rv == NS_SUCCESS)
892 return (0);
893 else
894 return (ret_errno);
897 /* get** wrappers for get**_r functions implementation */
898 static void
899 rpcent_endstate(void *p)
901 if (p == NULL)
902 return;
904 free(((struct rpcent_state *)p)->buffer);
905 free(p);
908 static int
909 wrap_getrpcbyname_r(union key key, struct rpcent *rpc, char *buffer,
910 size_t bufsize, struct rpcent **res)
912 return (getrpcbyname_r(key.name, rpc, buffer, bufsize, res));
915 static int
916 wrap_getrpcbynumber_r(union key key, struct rpcent *rpc, char *buffer,
917 size_t bufsize, struct rpcent **res)
919 return (getrpcbynumber_r(key.number, rpc, buffer, bufsize, res));
922 static int
923 wrap_getrpcent_r(union key key __unused, struct rpcent *rpc, char *buffer,
924 size_t bufsize, struct rpcent **res)
926 return (getrpcent_r(rpc, buffer, bufsize, res));
929 static struct rpcent *
930 getrpc(int (*fn)(union key, struct rpcent *, char *, size_t, struct rpcent **),
931 union key key)
933 int rv;
934 struct rpcent *res;
935 struct rpcent_state * st;
937 rv=rpcent_getstate(&st);
938 if (rv != 0) {
939 errno = rv;
940 return NULL;
943 if (st->buffer == NULL) {
944 st->buffer = malloc(RPCENT_STORAGE_INITIAL);
945 if (st->buffer == NULL)
946 return (NULL);
947 st->bufsize = RPCENT_STORAGE_INITIAL;
949 do {
950 rv = fn(key, &st->rpc, st->buffer, st->bufsize, &res);
951 if (res == NULL && rv == ERANGE) {
952 free(st->buffer);
953 if ((st->bufsize << 1) > RPCENT_STORAGE_MAX) {
954 st->buffer = NULL;
955 errno = ERANGE;
956 return (NULL);
958 st->bufsize <<= 1;
959 st->buffer = malloc(st->bufsize);
960 if (st->buffer == NULL)
961 return (NULL);
963 } while (res == NULL && rv == ERANGE);
964 if (rv != 0)
965 errno = rv;
967 return (res);
970 struct rpcent *
971 getrpcbyname(char *name)
973 union key key;
975 key.name = name;
977 return (getrpc(wrap_getrpcbyname_r, key));
980 struct rpcent *
981 getrpcbynumber(int number)
983 union key key;
985 key.number = number;
987 return (getrpc(wrap_getrpcbynumber_r, key));
990 struct rpcent *
991 getrpcent(void)
993 union key key;
995 key.number = 0; /* not used */
997 return (getrpc(wrap_getrpcent_r, key));
1000 void
1001 setrpcent(int stayopen)
1003 #ifdef NS_CACHING
1004 static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER(
1005 rpc, (void *)nss_lt_all,
1006 NULL, NULL);
1007 #endif
1009 static const ns_dtab dtab[] = {
1010 { NSSRC_FILES, files_setrpcent, (void *)SETRPCENT },
1011 #ifdef YP
1012 { NSSRC_NIS, nis_setrpcent, (void *)SETRPCENT },
1013 #endif
1014 #ifdef NS_CACHING
1015 NS_CACHE_CB(&cache_info)
1016 #endif
1017 { NULL, NULL, NULL }
1020 nsdispatch(NULL, dtab, NSDB_RPC, "setrpcent", defaultsrc, stayopen);
1023 void
1024 endrpcent(void)
1026 #ifdef NS_CACHING
1027 static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER(
1028 rpc, (void *)nss_lt_all,
1029 NULL, NULL);
1030 #endif
1032 static const ns_dtab dtab[] = {
1033 { NSSRC_FILES, files_setrpcent, (void *)ENDRPCENT },
1034 #ifdef YP
1035 { NSSRC_NIS, nis_setrpcent, (void *)ENDRPCENT },
1036 #endif
1037 #ifdef NS_CACHING
1038 NS_CACHE_CB(&cache_info)
1039 #endif
1040 { NULL, NULL, NULL }
1043 nsdispatch(NULL, dtab, NSDB_RPC, "endrpcent", defaultsrc);