getrpcent.c revision 309502
1/* $NetBSD: getrpcent.c,v 1.17 2000/01/22 22:19:17 mycroft Exp $ */ 2 3/*- 4 * Copyright (c) 2009, Sun Microsystems, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: 9 * - Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * - Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * - Neither the name of Sun Microsystems, Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#if defined(LIBC_SCCS) && !defined(lint) 32static char *sccsid = "@(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro"; 33#endif 34#include <sys/cdefs.h> 35__FBSDID("$FreeBSD: stable/10/lib/libc/rpc/getrpcent.c 309502 2016-12-03 18:56:28Z ngie $"); 36 37/* 38 * Copyright (c) 1984 by Sun Microsystems, Inc. 39 */ 40 41#include <sys/param.h> 42#include <sys/types.h> 43#include <sys/socket.h> 44#include <arpa/inet.h> 45#include <assert.h> 46#include <errno.h> 47#include <nsswitch.h> 48#include <netinet/in.h> 49#include <stdio.h> 50#include <string.h> 51#include <stdarg.h> 52#include <stdlib.h> 53#include <rpc/rpc.h> 54#ifdef YP 55#include <rpcsvc/yp_prot.h> 56#include <rpcsvc/ypclnt.h> 57#endif 58#include <unistd.h> 59#include "namespace.h" 60#include "reentrant.h" 61#include "un-namespace.h" 62#include "libc_private.h" 63#include "nss_tls.h" 64#ifdef NS_CACHING 65#include "nscache.h" 66#endif 67 68#define RPCDB "/etc/rpc" 69 70/* nsswitch declarations */ 71enum constants 72{ 73 SETRPCENT = 1, 74 ENDRPCENT = 2, 75 RPCENT_STORAGE_INITIAL = 1 << 10, /* 1 KByte */ 76 RPCENT_STORAGE_MAX = 1 << 20, /* 1 MByte */ 77}; 78 79static const ns_src defaultsrc[] = { 80 { NSSRC_FILES, NS_SUCCESS }, 81#ifdef YP 82 { NSSRC_NIS, NS_SUCCESS }, 83#endif 84 { NULL, 0 } 85}; 86 87/* files backend declarations */ 88struct files_state { 89 FILE *fp; 90 int stayopen; 91}; 92 93static int files_rpcent(void *, void *, va_list); 94static int files_setrpcent(void *, void *, va_list); 95 96static void files_endstate(void *); 97NSS_TLS_HANDLING(files); 98 99/* nis backend declarations */ 100#ifdef YP 101struct nis_state { 102 char domain[MAXHOSTNAMELEN]; 103 char *current; 104 int currentlen; 105 int stepping; 106 int no_name_map; 107}; 108 109static int nis_rpcent(void *, void *, va_list); 110static int nis_setrpcent(void *, void *, va_list); 111 112static void nis_endstate(void *); 113NSS_TLS_HANDLING(nis); 114#endif 115 116/* get** wrappers for get**_r functions declarations */ 117struct rpcent_state { 118 struct rpcent rpc; 119 char *buffer; 120 size_t bufsize; 121}; 122static void rpcent_endstate(void *); 123NSS_TLS_HANDLING(rpcent); 124 125union key { 126 const char *name; 127 int number; 128}; 129 130static int wrap_getrpcbyname_r(union key, struct rpcent *, char *, 131 size_t, struct rpcent **); 132static int wrap_getrpcbynumber_r(union key, struct rpcent *, char *, 133 size_t, struct rpcent **); 134static int wrap_getrpcent_r(union key, struct rpcent *, char *, 135 size_t, struct rpcent **); 136static struct rpcent *getrpc(int (*fn)(union key, struct rpcent *, char *, 137 size_t, struct rpcent **), union key); 138 139#ifdef NS_CACHING 140static int rpc_id_func(char *, size_t *, va_list, void *); 141static int rpc_marshal_func(char *, size_t *, void *, va_list, void *); 142static int rpc_unmarshal_func(char *, size_t, void *, va_list, void *); 143#endif 144 145static int 146rpcent_unpack(char *p, struct rpcent *rpc, char **r_aliases, 147 size_t aliases_size, int *errnop) 148{ 149 char *cp, **q; 150 151 assert(p != NULL); 152 153 if (*p == '#') 154 return (-1); 155 cp = strpbrk(p, "#\n"); 156 if (cp == NULL) 157 return (-1); 158 *cp = '\0'; 159 cp = strpbrk(p, " \t"); 160 if (cp == NULL) 161 return (-1); 162 *cp++ = '\0'; 163 /* THIS STUFF IS INTERNET SPECIFIC */ 164 rpc->r_name = p; 165 while (*cp == ' ' || *cp == '\t') 166 cp++; 167 rpc->r_number = atoi(cp); 168 q = rpc->r_aliases = r_aliases; 169 cp = strpbrk(cp, " \t"); 170 if (cp != NULL) 171 *cp++ = '\0'; 172 while (cp && *cp) { 173 if (*cp == ' ' || *cp == '\t') { 174 cp++; 175 continue; 176 } 177 if (q < &(r_aliases[aliases_size - 1])) 178 *q++ = cp; 179 else { 180 *errnop = ERANGE; 181 return -1; 182 } 183 184 cp = strpbrk(cp, " \t"); 185 if (cp != NULL) 186 *cp++ = '\0'; 187 } 188 *q = NULL; 189 return 0; 190} 191 192/* files backend implementation */ 193static void 194files_endstate(void *p) 195{ 196 FILE * f; 197 198 if (p == NULL) 199 return; 200 201 f = ((struct files_state *)p)->fp; 202 if (f != NULL) 203 fclose(f); 204 205 free(p); 206} 207 208static int 209files_rpcent(void *retval, void *mdata, va_list ap) 210{ 211 char *name; 212 int number; 213 struct rpcent *rpc; 214 char *buffer; 215 size_t bufsize; 216 int *errnop; 217 218 char *line; 219 size_t linesize; 220 char **aliases; 221 int aliases_size; 222 char **rp; 223 224 struct files_state *st; 225 int rv; 226 int stayopen; 227 enum nss_lookup_type how; 228 229 how = (enum nss_lookup_type)mdata; 230 switch (how) 231 { 232 case nss_lt_name: 233 name = va_arg(ap, char *); 234 break; 235 case nss_lt_id: 236 number = va_arg(ap, int); 237 break; 238 case nss_lt_all: 239 break; 240 default: 241 return (NS_NOTFOUND); 242 } 243 244 rpc = va_arg(ap, struct rpcent *); 245 buffer = va_arg(ap, char *); 246 bufsize = va_arg(ap, size_t); 247 errnop = va_arg(ap, int *); 248 249 *errnop = files_getstate(&st); 250 if (*errnop != 0) 251 return (NS_UNAVAIL); 252 253 if (st->fp == NULL && (st->fp = fopen(RPCDB, "r")) == NULL) { 254 *errnop = errno; 255 return (NS_UNAVAIL); 256 } 257 258 if (how == nss_lt_all) 259 stayopen = 1; 260 else { 261 rewind(st->fp); 262 stayopen = st->stayopen; 263 } 264 265 do { 266 if ((line = fgetln(st->fp, &linesize)) == NULL) { 267 *errnop = errno; 268 rv = NS_RETURN; 269 break; 270 } 271 272 if (bufsize <= linesize + _ALIGNBYTES + sizeof(char *)) { 273 *errnop = ERANGE; 274 rv = NS_RETURN; 275 break; 276 } 277 278 aliases = (char **)_ALIGN(&buffer[linesize+1]); 279 aliases_size = (buffer + bufsize - 280 (char *)aliases)/sizeof(char *); 281 if (aliases_size < 1) { 282 *errnop = ERANGE; 283 rv = NS_RETURN; 284 break; 285 } 286 287 memcpy(buffer, line, linesize); 288 buffer[linesize] = '\0'; 289 290 rv = rpcent_unpack(buffer, rpc, aliases, aliases_size, errnop); 291 if (rv != 0) { 292 if (*errnop == 0) { 293 rv = NS_NOTFOUND; 294 continue; 295 } 296 else { 297 rv = NS_RETURN; 298 break; 299 } 300 } 301 302 switch (how) 303 { 304 case nss_lt_name: 305 if (strcmp(rpc->r_name, name) == 0) 306 goto done; 307 for (rp = rpc->r_aliases; *rp != NULL; rp++) { 308 if (strcmp(*rp, name) == 0) 309 goto done; 310 } 311 rv = NS_NOTFOUND; 312 continue; 313done: 314 rv = NS_SUCCESS; 315 break; 316 case nss_lt_id: 317 rv = (rpc->r_number == number) ? NS_SUCCESS : 318 NS_NOTFOUND; 319 break; 320 case nss_lt_all: 321 rv = NS_SUCCESS; 322 break; 323 } 324 325 } while (!(rv & NS_TERMINATE)); 326 327 if (!stayopen && st->fp!=NULL) { 328 fclose(st->fp); 329 st->fp = NULL; 330 } 331 332 if ((rv == NS_SUCCESS) && (retval != NULL)) 333 *((struct rpcent **)retval) = rpc; 334 335 return (rv); 336} 337 338static int 339files_setrpcent(void *retval, void *mdata, va_list ap) 340{ 341 struct files_state *st; 342 int rv; 343 int f; 344 345 rv = files_getstate(&st); 346 if (rv != 0) 347 return (NS_UNAVAIL); 348 349 switch ((enum constants)mdata) 350 { 351 case SETRPCENT: 352 f = va_arg(ap,int); 353 if (st->fp == NULL) 354 st->fp = fopen(RPCDB, "r"); 355 else 356 rewind(st->fp); 357 st->stayopen |= f; 358 break; 359 case ENDRPCENT: 360 if (st->fp != NULL) { 361 fclose(st->fp); 362 st->fp = NULL; 363 } 364 st->stayopen = 0; 365 break; 366 default: 367 break; 368 } 369 370 return (NS_UNAVAIL); 371} 372 373/* nis backend implementation */ 374#ifdef YP 375static void 376nis_endstate(void *p) 377{ 378 if (p == NULL) 379 return; 380 381 free(((struct nis_state *)p)->current); 382 free(p); 383} 384 385static int 386nis_rpcent(void *retval, void *mdata, va_list ap) 387{ 388 char *name; 389 int number; 390 struct rpcent *rpc; 391 char *buffer; 392 size_t bufsize; 393 int *errnop; 394 395 char **rp; 396 char **aliases; 397 int aliases_size; 398 399 char *lastkey; 400 char *resultbuf; 401 int resultbuflen; 402 char buf[YPMAXRECORD + 2]; 403 404 struct nis_state *st; 405 int rv; 406 enum nss_lookup_type how; 407 int no_name_active; 408 409 how = (enum nss_lookup_type)mdata; 410 switch (how) 411 { 412 case nss_lt_name: 413 name = va_arg(ap, char *); 414 break; 415 case nss_lt_id: 416 number = va_arg(ap, int); 417 break; 418 case nss_lt_all: 419 break; 420 default: 421 return (NS_NOTFOUND); 422 } 423 424 rpc = va_arg(ap, struct rpcent *); 425 buffer = va_arg(ap, char *); 426 bufsize = va_arg(ap, size_t); 427 errnop = va_arg(ap, int *); 428 429 *errnop = nis_getstate(&st); 430 if (*errnop != 0) 431 return (NS_UNAVAIL); 432 433 if (st->domain[0] == '\0') { 434 if (getdomainname(st->domain, sizeof(st->domain)) != 0) { 435 *errnop = errno; 436 return (NS_UNAVAIL); 437 } 438 } 439 440 no_name_active = 0; 441 do { 442 switch (how) 443 { 444 case nss_lt_name: 445 if (!st->no_name_map) 446 { 447 snprintf(buf, sizeof buf, "%s", name); 448 rv = yp_match(st->domain, "rpc.byname", buf, 449 strlen(buf), &resultbuf, &resultbuflen); 450 451 switch (rv) { 452 case 0: 453 break; 454 case YPERR_MAP: 455 st->stepping = 0; 456 no_name_active = 1; 457 how = nss_lt_all; 458 459 rv = NS_NOTFOUND; 460 continue; 461 default: 462 rv = NS_NOTFOUND; 463 goto fin; 464 } 465 } else { 466 st->stepping = 0; 467 no_name_active = 1; 468 how = nss_lt_all; 469 470 rv = NS_NOTFOUND; 471 continue; 472 } 473 break; 474 case nss_lt_id: 475 snprintf(buf, sizeof buf, "%d", number); 476 if (yp_match(st->domain, "rpc.bynumber", buf, 477 strlen(buf), &resultbuf, &resultbuflen)) { 478 rv = NS_NOTFOUND; 479 goto fin; 480 } 481 break; 482 case nss_lt_all: 483 if (!st->stepping) { 484 rv = yp_first(st->domain, "rpc.bynumber", 485 &st->current, 486 &st->currentlen, &resultbuf, 487 &resultbuflen); 488 if (rv) { 489 rv = NS_NOTFOUND; 490 goto fin; 491 } 492 st->stepping = 1; 493 } else { 494 lastkey = st->current; 495 rv = yp_next(st->domain, "rpc.bynumber", 496 st->current, 497 st->currentlen, &st->current, 498 &st->currentlen, 499 &resultbuf, &resultbuflen); 500 free(lastkey); 501 if (rv) { 502 st->stepping = 0; 503 rv = NS_NOTFOUND; 504 goto fin; 505 } 506 } 507 break; 508 } 509 510 /* we need a room for additional \n symbol */ 511 if (bufsize <= resultbuflen + 1 + _ALIGNBYTES + 512 sizeof(char *)) { 513 *errnop = ERANGE; 514 rv = NS_RETURN; 515 free(resultbuf); 516 break; 517 } 518 519 aliases=(char **)_ALIGN(&buffer[resultbuflen+2]); 520 aliases_size = (buffer + bufsize - (char *)aliases) / 521 sizeof(char *); 522 if (aliases_size < 1) { 523 *errnop = ERANGE; 524 rv = NS_RETURN; 525 free(resultbuf); 526 break; 527 } 528 529 /* 530 * rpcent_unpack expects lines terminated with \n -- make it happy 531 */ 532 memcpy(buffer, resultbuf, resultbuflen); 533 buffer[resultbuflen] = '\n'; 534 buffer[resultbuflen+1] = '\0'; 535 free(resultbuf); 536 537 if (rpcent_unpack(buffer, rpc, aliases, aliases_size, 538 errnop) != 0) { 539 if (*errnop == 0) 540 rv = NS_NOTFOUND; 541 else 542 rv = NS_RETURN; 543 } else { 544 if ((how == nss_lt_all) && (no_name_active != 0)) { 545 if (strcmp(rpc->r_name, name) == 0) 546 goto done; 547 for (rp = rpc->r_aliases; *rp != NULL; rp++) { 548 if (strcmp(*rp, name) == 0) 549 goto done; 550 } 551 rv = NS_NOTFOUND; 552 continue; 553done: 554 rv = NS_SUCCESS; 555 } else 556 rv = NS_SUCCESS; 557 } 558 559 } while (!(rv & NS_TERMINATE) && (how == nss_lt_all)); 560 561fin: 562 if ((rv == NS_SUCCESS) && (retval != NULL)) 563 *((struct rpcent **)retval) = rpc; 564 565 return (rv); 566} 567 568static int 569nis_setrpcent(void *retval, void *mdata, va_list ap) 570{ 571 struct nis_state *st; 572 int rv; 573 574 rv = nis_getstate(&st); 575 if (rv != 0) 576 return (NS_UNAVAIL); 577 578 switch ((enum constants)mdata) 579 { 580 case SETRPCENT: 581 case ENDRPCENT: 582 free(st->current); 583 st->current = NULL; 584 st->stepping = 0; 585 break; 586 default: 587 break; 588 } 589 590 return (NS_UNAVAIL); 591} 592#endif 593 594#ifdef NS_CACHING 595static int 596rpc_id_func(char *buffer, size_t *buffer_size, va_list ap, void *cache_mdata) 597{ 598 char *name; 599 int rpc; 600 601 size_t desired_size, size; 602 enum nss_lookup_type lookup_type; 603 int res = NS_UNAVAIL; 604 605 lookup_type = (enum nss_lookup_type)cache_mdata; 606 switch (lookup_type) { 607 case nss_lt_name: 608 name = va_arg(ap, char *); 609 610 size = strlen(name); 611 desired_size = sizeof(enum nss_lookup_type) + size + 1; 612 if (desired_size > *buffer_size) { 613 res = NS_RETURN; 614 goto fin; 615 } 616 617 memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type)); 618 memcpy(buffer + sizeof(enum nss_lookup_type), name, size + 1); 619 620 res = NS_SUCCESS; 621 break; 622 case nss_lt_id: 623 rpc = va_arg(ap, int); 624 625 desired_size = sizeof(enum nss_lookup_type) + sizeof(int); 626 if (desired_size > *buffer_size) { 627 res = NS_RETURN; 628 goto fin; 629 } 630 631 memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type)); 632 memcpy(buffer + sizeof(enum nss_lookup_type), &rpc, 633 sizeof(int)); 634 635 res = NS_SUCCESS; 636 break; 637 default: 638 /* should be unreachable */ 639 return (NS_UNAVAIL); 640 } 641 642fin: 643 *buffer_size = desired_size; 644 return (res); 645} 646 647static int 648rpc_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap, 649 void *cache_mdata) 650{ 651 char *name; 652 int num; 653 struct rpcent *rpc; 654 char *orig_buf; 655 size_t orig_buf_size; 656 657 struct rpcent new_rpc; 658 size_t desired_size, size, aliases_size; 659 char *p; 660 char **alias; 661 662 switch ((enum nss_lookup_type)cache_mdata) { 663 case nss_lt_name: 664 name = va_arg(ap, char *); 665 break; 666 case nss_lt_id: 667 num = va_arg(ap, int); 668 break; 669 case nss_lt_all: 670 break; 671 default: 672 /* should be unreachable */ 673 return (NS_UNAVAIL); 674 } 675 676 rpc = va_arg(ap, struct rpcent *); 677 orig_buf = va_arg(ap, char *); 678 orig_buf_size = va_arg(ap, size_t); 679 680 desired_size = _ALIGNBYTES + sizeof(struct rpcent) + sizeof(char *); 681 if (rpc->r_name != NULL) 682 desired_size += strlen(rpc->r_name) + 1; 683 684 if (rpc->r_aliases != NULL) { 685 aliases_size = 0; 686 for (alias = rpc->r_aliases; *alias; ++alias) { 687 desired_size += strlen(*alias) + 1; 688 ++aliases_size; 689 } 690 691 desired_size += _ALIGNBYTES + (aliases_size + 1) * 692 sizeof(char *); 693 } 694 695 if (*buffer_size < desired_size) { 696 /* this assignment is here for future use */ 697 *buffer_size = desired_size; 698 return (NS_RETURN); 699 } 700 701 new_rpc = *rpc; 702 703 *buffer_size = desired_size; 704 memset(buffer, 0, desired_size); 705 p = buffer + sizeof(struct rpcent) + sizeof(char *); 706 memcpy(buffer + sizeof(struct rpcent), &p, sizeof(char *)); 707 p = (char *)_ALIGN(p); 708 709 if (new_rpc.r_name != NULL) { 710 size = strlen(new_rpc.r_name); 711 memcpy(p, new_rpc.r_name, size); 712 new_rpc.r_name = p; 713 p += size + 1; 714 } 715 716 if (new_rpc.r_aliases != NULL) { 717 p = (char *)_ALIGN(p); 718 memcpy(p, new_rpc.r_aliases, sizeof(char *) * aliases_size); 719 new_rpc.r_aliases = (char **)p; 720 p += sizeof(char *) * (aliases_size + 1); 721 722 for (alias = new_rpc.r_aliases; *alias; ++alias) { 723 size = strlen(*alias); 724 memcpy(p, *alias, size); 725 *alias = p; 726 p += size + 1; 727 } 728 } 729 730 memcpy(buffer, &new_rpc, sizeof(struct rpcent)); 731 return (NS_SUCCESS); 732} 733 734static int 735rpc_unmarshal_func(char *buffer, size_t buffer_size, void *retval, va_list ap, 736 void *cache_mdata) 737{ 738 char *name; 739 int num; 740 struct rpcent *rpc; 741 char *orig_buf; 742 size_t orig_buf_size; 743 int *ret_errno; 744 745 char *p; 746 char **alias; 747 748 switch ((enum nss_lookup_type)cache_mdata) { 749 case nss_lt_name: 750 name = va_arg(ap, char *); 751 break; 752 case nss_lt_id: 753 num = va_arg(ap, int); 754 break; 755 case nss_lt_all: 756 break; 757 default: 758 /* should be unreachable */ 759 return (NS_UNAVAIL); 760 } 761 762 rpc = va_arg(ap, struct rpcent *); 763 orig_buf = va_arg(ap, char *); 764 orig_buf_size = va_arg(ap, size_t); 765 ret_errno = va_arg(ap, int *); 766 767 if (orig_buf_size < 768 buffer_size - sizeof(struct rpcent) - sizeof(char *)) { 769 *ret_errno = ERANGE; 770 return (NS_RETURN); 771 } 772 773 memcpy(rpc, buffer, sizeof(struct rpcent)); 774 memcpy(&p, buffer + sizeof(struct rpcent), sizeof(char *)); 775 776 orig_buf = (char *)_ALIGN(orig_buf); 777 memcpy(orig_buf, buffer + sizeof(struct rpcent) + sizeof(char *) + 778 _ALIGN(p) - (size_t)p, 779 buffer_size - sizeof(struct rpcent) - sizeof(char *) - 780 _ALIGN(p) + (size_t)p); 781 p = (char *)_ALIGN(p); 782 783 NS_APPLY_OFFSET(rpc->r_name, orig_buf, p, char *); 784 if (rpc->r_aliases != NULL) { 785 NS_APPLY_OFFSET(rpc->r_aliases, orig_buf, p, char **); 786 787 for (alias = rpc->r_aliases ; *alias; ++alias) 788 NS_APPLY_OFFSET(*alias, orig_buf, p, char *); 789 } 790 791 if (retval != NULL) 792 *((struct rpcent **)retval) = rpc; 793 794 return (NS_SUCCESS); 795} 796 797NSS_MP_CACHE_HANDLING(rpc); 798#endif /* NS_CACHING */ 799 800 801/* get**_r functions implementation */ 802static int 803getrpcbyname_r(const char *name, struct rpcent *rpc, char *buffer, 804 size_t bufsize, struct rpcent **result) 805{ 806#ifdef NS_CACHING 807 static const nss_cache_info cache_info = 808 NS_COMMON_CACHE_INFO_INITIALIZER( 809 rpc, (void *)nss_lt_name, 810 rpc_id_func, rpc_marshal_func, rpc_unmarshal_func); 811#endif 812 static const ns_dtab dtab[] = { 813 { NSSRC_FILES, files_rpcent, (void *)nss_lt_name }, 814#ifdef YP 815 { NSSRC_NIS, nis_rpcent, (void *)nss_lt_name }, 816#endif 817#ifdef NS_CACHING 818 NS_CACHE_CB(&cache_info) 819#endif 820 { NULL, NULL, NULL } 821 }; 822 int rv, ret_errno; 823 824 ret_errno = 0; 825 *result = NULL; 826 rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbyname_r", defaultsrc, 827 name, rpc, buffer, bufsize, &ret_errno); 828 829 if (rv == NS_SUCCESS) 830 return (0); 831 else 832 return (ret_errno); 833} 834 835static int 836getrpcbynumber_r(int number, struct rpcent *rpc, char *buffer, 837 size_t bufsize, struct rpcent **result) 838{ 839#ifdef NS_CACHING 840 static const nss_cache_info cache_info = 841 NS_COMMON_CACHE_INFO_INITIALIZER( 842 rpc, (void *)nss_lt_id, 843 rpc_id_func, rpc_marshal_func, rpc_unmarshal_func); 844#endif 845 static const ns_dtab dtab[] = { 846 { NSSRC_FILES, files_rpcent, (void *)nss_lt_id }, 847#ifdef YP 848 { NSSRC_NIS, nis_rpcent, (void *)nss_lt_id }, 849#endif 850#ifdef NS_CACHING 851 NS_CACHE_CB(&cache_info) 852#endif 853 { NULL, NULL, NULL } 854 }; 855 int rv, ret_errno; 856 857 ret_errno = 0; 858 *result = NULL; 859 rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbynumber_r", defaultsrc, 860 number, rpc, buffer, bufsize, &ret_errno); 861 862 if (rv == NS_SUCCESS) 863 return (0); 864 else 865 return (ret_errno); 866} 867 868static int 869getrpcent_r(struct rpcent *rpc, char *buffer, size_t bufsize, 870 struct rpcent **result) 871{ 872#ifdef NS_CACHING 873 static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER( 874 rpc, (void *)nss_lt_all, 875 rpc_marshal_func, rpc_unmarshal_func); 876#endif 877 static const ns_dtab dtab[] = { 878 { NSSRC_FILES, files_rpcent, (void *)nss_lt_all }, 879#ifdef YP 880 { NSSRC_NIS, nis_rpcent, (void *)nss_lt_all }, 881#endif 882#ifdef NS_CACHING 883 NS_CACHE_CB(&cache_info) 884#endif 885 { NULL, NULL, NULL } 886 }; 887 int rv, ret_errno; 888 889 ret_errno = 0; 890 *result = NULL; 891 rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcent_r", defaultsrc, 892 rpc, buffer, bufsize, &ret_errno); 893 894 if (rv == NS_SUCCESS) 895 return (0); 896 else 897 return (ret_errno); 898} 899 900/* get** wrappers for get**_r functions implementation */ 901static void 902rpcent_endstate(void *p) 903{ 904 if (p == NULL) 905 return; 906 907 free(((struct rpcent_state *)p)->buffer); 908 free(p); 909} 910 911static int 912wrap_getrpcbyname_r(union key key, struct rpcent *rpc, char *buffer, 913 size_t bufsize, struct rpcent **res) 914{ 915 return (getrpcbyname_r(key.name, rpc, buffer, bufsize, res)); 916} 917 918static int 919wrap_getrpcbynumber_r(union key key, struct rpcent *rpc, char *buffer, 920 size_t bufsize, struct rpcent **res) 921{ 922 return (getrpcbynumber_r(key.number, rpc, buffer, bufsize, res)); 923} 924 925static int 926wrap_getrpcent_r(union key key __unused, struct rpcent *rpc, char *buffer, 927 size_t bufsize, struct rpcent **res) 928{ 929 return (getrpcent_r(rpc, buffer, bufsize, res)); 930} 931 932static struct rpcent * 933getrpc(int (*fn)(union key, struct rpcent *, char *, size_t, struct rpcent **), 934 union key key) 935{ 936 int rv; 937 struct rpcent *res; 938 struct rpcent_state * st; 939 940 rv=rpcent_getstate(&st); 941 if (rv != 0) { 942 errno = rv; 943 return NULL; 944 } 945 946 if (st->buffer == NULL) { 947 st->buffer = malloc(RPCENT_STORAGE_INITIAL); 948 if (st->buffer == NULL) 949 return (NULL); 950 st->bufsize = RPCENT_STORAGE_INITIAL; 951 } 952 do { 953 rv = fn(key, &st->rpc, st->buffer, st->bufsize, &res); 954 if (res == NULL && rv == ERANGE) { 955 free(st->buffer); 956 if ((st->bufsize << 1) > RPCENT_STORAGE_MAX) { 957 st->buffer = NULL; 958 errno = ERANGE; 959 return (NULL); 960 } 961 st->bufsize <<= 1; 962 st->buffer = malloc(st->bufsize); 963 if (st->buffer == NULL) 964 return (NULL); 965 } 966 } while (res == NULL && rv == ERANGE); 967 if (rv != 0) 968 errno = rv; 969 970 return (res); 971} 972 973struct rpcent * 974getrpcbyname(const char *name) 975{ 976 union key key; 977 978 key.name = name; 979 980 return (getrpc(wrap_getrpcbyname_r, key)); 981} 982 983struct rpcent * 984getrpcbynumber(int number) 985{ 986 union key key; 987 988 key.number = number; 989 990 return (getrpc(wrap_getrpcbynumber_r, key)); 991} 992 993struct rpcent * 994getrpcent(void) 995{ 996 union key key; 997 998 key.number = 0; /* not used */ 999 1000 return (getrpc(wrap_getrpcent_r, key)); 1001} 1002 1003void 1004setrpcent(int stayopen) 1005{ 1006#ifdef NS_CACHING 1007 static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER( 1008 rpc, (void *)nss_lt_all, 1009 NULL, NULL); 1010#endif 1011 1012 static const ns_dtab dtab[] = { 1013 { NSSRC_FILES, files_setrpcent, (void *)SETRPCENT }, 1014#ifdef YP 1015 { NSSRC_NIS, nis_setrpcent, (void *)SETRPCENT }, 1016#endif 1017#ifdef NS_CACHING 1018 NS_CACHE_CB(&cache_info) 1019#endif 1020 { NULL, NULL, NULL } 1021 }; 1022 1023 (void)nsdispatch(NULL, dtab, NSDB_RPC, "setrpcent", defaultsrc, 1024 stayopen); 1025} 1026 1027void 1028endrpcent(void) 1029{ 1030#ifdef NS_CACHING 1031 static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER( 1032 rpc, (void *)nss_lt_all, 1033 NULL, NULL); 1034#endif 1035 1036 static const ns_dtab dtab[] = { 1037 { NSSRC_FILES, files_setrpcent, (void *)ENDRPCENT }, 1038#ifdef YP 1039 { NSSRC_NIS, nis_setrpcent, (void *)ENDRPCENT }, 1040#endif 1041#ifdef NS_CACHING 1042 NS_CACHE_CB(&cache_info) 1043#endif 1044 { NULL, NULL, NULL } 1045 }; 1046 1047 (void)nsdispatch(NULL, dtab, NSDB_RPC, "endrpcent", defaultsrc); 1048} 1049