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

55-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since f41a394 was 60b1d40, checked in by Sebastian Huber <sebastian.huber@…>, on 06/09/16 at 08:23:57

RPC(3): Import from FreeBSD

  • Property mode set to 100644
File size: 21.5 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 * Copyright (c) 2009, Sun Microsystems, Inc.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 * - Redistributions of source code must retain the above copyright notice,
12 *   this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above copyright notice,
14 *   this list of conditions and the following disclaimer in the documentation
15 *   and/or other materials provided with the distribution.
16 * - Neither the name of Sun Microsystems, Inc. nor the names of its
17 *   contributors may be used to endorse or promote products derived
18 *   from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#if defined(LIBC_SCCS) && !defined(lint)
34static char *sccsid = "@(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro";
35#endif
36#include <sys/cdefs.h>
37__FBSDID("$FreeBSD$");
38
39/*
40 * Copyright (c) 1984 by Sun Microsystems, Inc.
41 */
42
43#include <rtems/bsd/sys/param.h>
44#include <sys/types.h>
45#include <sys/socket.h>
46#include <arpa/inet.h>
47#include <assert.h>
48#include <errno.h>
49#include <nsswitch.h>
50#include <netinet/in.h>
51#include <stdio.h>
52#include <string.h>
53#include <stdarg.h>
54#include <stdlib.h>
55#include <rpc/rpc.h>
56#ifdef YP
57#include <rpcsvc/yp_prot.h>
58#include <rpcsvc/ypclnt.h>
59#endif
60#include <unistd.h>
61#include "namespace.h"
62#include "reentrant.h"
63#include "un-namespace.h"
64#include "libc_private.h"
65#include "nss_tls.h"
66#ifdef NS_CACHING
67#include "nscache.h"
68#endif
69
70#define RPCDB   "/etc/rpc"
71
72/* nsswitch declarations */
73enum constants
74{
75        SETRPCENT = 1,
76        ENDRPCENT = 2,
77        RPCENT_STORAGE_INITIAL  = 1 << 10, /* 1 KByte */
78        RPCENT_STORAGE_MAX      = 1 << 20, /* 1 MByte */
79};
80
81static const ns_src defaultsrc[] = {
82        { NSSRC_FILES, NS_SUCCESS },
83#ifdef YP
84        { NSSRC_NIS, NS_SUCCESS },
85#endif
86        { NULL, 0 }
87};
88
89/* files backend declarations */
90struct files_state {
91        FILE    *fp;
92        int     stayopen;
93};
94
95static  int     files_rpcent(void *, void *, va_list);
96static  int     files_setrpcent(void *, void *, va_list);
97
98static  void    files_endstate(void *);
99NSS_TLS_HANDLING(files);
100
101/* nis backend declarations */
102#ifdef YP
103struct nis_state {
104        char    domain[MAXHOSTNAMELEN];
105        char    *current;
106        int     currentlen;
107        int     stepping;
108        int     no_name_map;
109};
110
111static  int     nis_rpcent(void *, void *, va_list);
112static  int     nis_setrpcent(void *, void *, va_list);
113
114static  void    nis_endstate(void *);
115NSS_TLS_HANDLING(nis);
116#endif
117
118/* get** wrappers for get**_r functions declarations */
119struct rpcent_state {
120        struct rpcent   rpc;
121        char            *buffer;
122        size_t  bufsize;
123};
124static  void    rpcent_endstate(void *);
125NSS_TLS_HANDLING(rpcent);
126
127union key {
128        const char      *name;
129        int             number;
130};
131
132static int wrap_getrpcbyname_r(union key, struct rpcent *, char *,
133                        size_t, struct rpcent **);
134static int wrap_getrpcbynumber_r(union key, struct rpcent *, char *,
135                        size_t, struct rpcent **);
136static int wrap_getrpcent_r(union key, struct rpcent *, char *,
137                        size_t, struct rpcent **);
138static struct rpcent *getrpc(int (*fn)(union key, struct rpcent *, char *,
139                        size_t, struct rpcent **), union key);
140
141#ifdef NS_CACHING
142static int rpc_id_func(char *, size_t *, va_list, void *);
143static int rpc_marshal_func(char *, size_t *, void *, va_list, void *);
144static int rpc_unmarshal_func(char *, size_t, void *, va_list, void *);
145#endif
146
147static int
148rpcent_unpack(char *p, struct rpcent *rpc, char **r_aliases,
149        size_t aliases_size, int *errnop)
150{
151        char *cp, **q;
152
153        assert(p != NULL);
154
155        if (*p == '#')
156                return (-1);
157        cp = strpbrk(p, "#\n");
158        if (cp == NULL)
159                return (-1);
160        *cp = '\0';
161        cp = strpbrk(p, " \t");
162        if (cp == NULL)
163                return (-1);
164        *cp++ = '\0';
165        /* THIS STUFF IS INTERNET SPECIFIC */
166        rpc->r_name = p;
167        while (*cp == ' ' || *cp == '\t')
168                cp++;
169        rpc->r_number = atoi(cp);
170        q = rpc->r_aliases = r_aliases;
171        cp = strpbrk(cp, " \t");
172        if (cp != NULL)
173                *cp++ = '\0';
174        while (cp && *cp) {
175                if (*cp == ' ' || *cp == '\t') {
176                        cp++;
177                        continue;
178                }
179                if (q < &(r_aliases[aliases_size - 1]))
180                        *q++ = cp;
181                else {
182                        *errnop = ERANGE;
183                        return -1;
184                }
185
186                cp = strpbrk(cp, " \t");
187                if (cp != NULL)
188                        *cp++ = '\0';
189        }
190        *q = NULL;
191        return 0;
192}
193
194/* files backend implementation */
195static  void
196files_endstate(void *p)
197{
198        FILE * f;
199
200        if (p == NULL)
201                return;
202
203        f = ((struct files_state *)p)->fp;
204        if (f != NULL)
205                fclose(f);
206
207        free(p);
208}
209
210static int
211files_rpcent(void *retval, void *mdata, va_list ap)
212{
213        char *name;
214        int number;
215        struct rpcent *rpc;
216        char *buffer;
217        size_t bufsize;
218        int *errnop;
219
220        char *line;
221        size_t linesize;
222        char **aliases;
223        int aliases_size;
224        char **rp;
225
226        struct files_state      *st;
227        int rv;
228        int stayopen;
229        enum nss_lookup_type how;
230
231        how = (enum nss_lookup_type)mdata;
232        switch (how)
233        {
234        case nss_lt_name:
235                name = va_arg(ap, char *);
236                break;
237        case nss_lt_id:
238                number = va_arg(ap, int);
239                break;
240        case nss_lt_all:
241                break;
242        default:
243                return (NS_NOTFOUND);
244        }
245
246        rpc = va_arg(ap, struct rpcent *);
247        buffer = va_arg(ap, char *);
248        bufsize = va_arg(ap, size_t);
249        errnop = va_arg(ap, int *);
250
251        *errnop = files_getstate(&st);
252        if (*errnop != 0)
253                return (NS_UNAVAIL);
254
255        if (st->fp == NULL && (st->fp = fopen(RPCDB, "r")) == NULL) {
256                *errnop = errno;
257                return (NS_UNAVAIL);
258        }
259
260        if (how == nss_lt_all)
261                stayopen = 1;
262        else {
263                rewind(st->fp);
264                stayopen = st->stayopen;
265        }
266
267        do {
268                if ((line = fgetln(st->fp, &linesize)) == NULL) {
269                        *errnop = errno;
270                        rv = NS_RETURN;
271                        break;
272                }
273
274                if (bufsize <= linesize + _ALIGNBYTES + sizeof(char *)) {
275                        *errnop = ERANGE;
276                        rv = NS_RETURN;
277                        break;
278                }
279
280                aliases = (char **)_ALIGN(&buffer[linesize+1]);
281                aliases_size = (buffer + bufsize -
282                        (char *)aliases)/sizeof(char *);
283                if (aliases_size < 1) {
284                        *errnop = ERANGE;
285                        rv = NS_RETURN;
286                        break;
287                }
288
289                memcpy(buffer, line, linesize);
290                buffer[linesize] = '\0';
291
292                rv = rpcent_unpack(buffer, rpc, aliases, aliases_size, errnop);
293                if (rv != 0) {
294                        if (*errnop == 0) {
295                                rv = NS_NOTFOUND;
296                                continue;
297                        }
298                        else {
299                                rv = NS_RETURN;
300                                break;
301                        }
302                }
303
304                switch (how)
305                {
306                case nss_lt_name:
307                        if (strcmp(rpc->r_name, name) == 0)
308                                goto done;
309                        for (rp = rpc->r_aliases; *rp != NULL; rp++) {
310                                if (strcmp(*rp, name) == 0)
311                                        goto done;
312                        }
313                        rv = NS_NOTFOUND;
314                        continue;
315done:
316                        rv = NS_SUCCESS;
317                        break;
318                case nss_lt_id:
319                        rv = (rpc->r_number == number) ? NS_SUCCESS :
320                                NS_NOTFOUND;
321                        break;
322                case nss_lt_all:
323                        rv = NS_SUCCESS;
324                        break;
325                }
326
327        } while (!(rv & NS_TERMINATE));
328
329        if (!stayopen && st->fp!=NULL) {
330                fclose(st->fp);
331                st->fp = NULL;
332        }
333
334        if ((rv == NS_SUCCESS) && (retval != NULL))
335                *((struct rpcent **)retval) = rpc;
336
337        return (rv);
338}
339
340static int
341files_setrpcent(void *retval, void *mdata, va_list ap)
342{
343        struct files_state      *st;
344        int     rv;
345        int     f;
346
347        rv = files_getstate(&st);
348        if (rv != 0)
349                return (NS_UNAVAIL);
350
351        switch ((enum constants)mdata)
352        {
353        case SETRPCENT:
354                f = va_arg(ap,int);
355                if (st->fp == NULL)
356                        st->fp = fopen(RPCDB, "r");
357                else
358                        rewind(st->fp);
359                st->stayopen |= f;
360                break;
361        case ENDRPCENT:
362                if (st->fp != NULL) {
363                        fclose(st->fp);
364                        st->fp = NULL;
365                }
366                st->stayopen = 0;
367                break;
368        default:
369                break;
370        }
371
372        return (NS_UNAVAIL);
373}
374
375/* nis backend implementation */
376#ifdef YP
377static  void
378nis_endstate(void *p)
379{
380        if (p == NULL)
381                return;
382
383        free(((struct nis_state *)p)->current);
384        free(p);
385}
386
387static int
388nis_rpcent(void *retval, void *mdata, va_list ap)
389{
390        char            *name;
391        int             number;
392        struct rpcent   *rpc;
393        char            *buffer;
394        size_t  bufsize;
395        int             *errnop;
396
397        char            **rp;
398        char            **aliases;
399        int             aliases_size;
400
401        char    *lastkey;
402        char    *resultbuf;
403        int     resultbuflen;
404        char    buf[YPMAXRECORD + 2];
405
406        struct nis_state        *st;
407        int             rv;
408        enum nss_lookup_type    how;
409        int     no_name_active;
410
411        how = (enum nss_lookup_type)mdata;
412        switch (how)
413        {
414        case nss_lt_name:
415                name = va_arg(ap, char *);
416                break;
417        case nss_lt_id:
418                number = va_arg(ap, int);
419                break;
420        case nss_lt_all:
421                break;
422        default:
423                return (NS_NOTFOUND);
424        }
425
426        rpc = va_arg(ap, struct rpcent *);
427        buffer = va_arg(ap, char *);
428        bufsize = va_arg(ap, size_t);
429        errnop = va_arg(ap, int *);
430
431        *errnop = nis_getstate(&st);
432        if (*errnop != 0)
433                return (NS_UNAVAIL);
434
435        if (st->domain[0] == '\0') {
436                if (getdomainname(st->domain, sizeof(st->domain)) != 0) {
437                        *errnop = errno;
438                        return (NS_UNAVAIL);
439                }
440        }
441
442        no_name_active = 0;
443        do {
444                switch (how)
445                {
446                case nss_lt_name:
447                        if (!st->no_name_map)
448                        {
449                                snprintf(buf, sizeof buf, "%s", name);
450                                rv = yp_match(st->domain, "rpc.byname", buf,
451                                        strlen(buf), &resultbuf, &resultbuflen);
452
453                                switch (rv) {
454                                case 0:
455                                        break;
456                                case YPERR_MAP:
457                                        st->stepping = 0;
458                                        no_name_active = 1;
459                                        how = nss_lt_all;
460
461                                        rv = NS_NOTFOUND;
462                                        continue;
463                                default:
464                                        rv = NS_NOTFOUND;
465                                        goto fin;
466                                }
467                        } else {
468                                st->stepping = 0;
469                                no_name_active = 1;
470                                how = nss_lt_all;
471
472                                rv = NS_NOTFOUND;
473                                continue;
474                        }
475                break;
476                case nss_lt_id:
477                        snprintf(buf, sizeof buf, "%d", number);
478                        if (yp_match(st->domain, "rpc.bynumber", buf,
479                                strlen(buf), &resultbuf, &resultbuflen)) {
480                                rv = NS_NOTFOUND;
481                                goto fin;
482                        }
483                        break;
484                case nss_lt_all:
485                                if (!st->stepping) {
486                                        rv = yp_first(st->domain, "rpc.bynumber",
487                                                &st->current,
488                                                &st->currentlen, &resultbuf,
489                                                &resultbuflen);
490                                        if (rv) {
491                                                rv = NS_NOTFOUND;
492                                                goto fin;
493                                        }
494                                        st->stepping = 1;
495                                } else {
496                                        lastkey = st->current;
497                                        rv = yp_next(st->domain, "rpc.bynumber",
498                                                st->current,
499                                                st->currentlen, &st->current,
500                                                &st->currentlen,
501                                                &resultbuf,     &resultbuflen);
502                                        free(lastkey);
503                                        if (rv) {
504                                                st->stepping = 0;
505                                                rv = NS_NOTFOUND;
506                                                goto fin;
507                                        }
508                                }
509                        break;
510                }
511
512                /* we need a room for additional \n symbol */
513                if (bufsize <= resultbuflen + 1 + _ALIGNBYTES +
514                    sizeof(char *)) {
515                        *errnop = ERANGE;
516                        rv = NS_RETURN;
517                        break;
518                }
519
520                aliases=(char **)_ALIGN(&buffer[resultbuflen+2]);
521                aliases_size = (buffer + bufsize - (char *)aliases) /
522                        sizeof(char *);
523                if (aliases_size < 1) {
524                        *errnop = ERANGE;
525                        rv = NS_RETURN;
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(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()
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()
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}
Note: See TracBrowser for help on using the repository browser.