source: rtems-libbsd/freebsd/lib/libc/rpc/getrpcent.c

6-freebsd-12
Last change on this file was 37323bb, checked in by Sebastian Huber <sebastian.huber@…>, on 09/23/19 at 10:49:10

Update to FreeBSD stable/12 2019-09-23

Git mirror commit 7e8d1444023128d34fb9aa4e4515928a4f794d1b.

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