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