2 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3 * unrestricted use provided that this legend is included on all tape
4 * media and as a part of the software program in whole or part. Users
5 * may copy or modify Sun RPC without charge, but are not authorized
6 * to license or distribute it to anyone else except as part of a product or
7 * program developed by the user or with the express written consent of
8 * Sun Microsystems, Inc.
10 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
14 * Sun RPC is provided with no support and without any obligation on the
15 * part of Sun Microsystems, Inc. to assist in its use, correction,
16 * modification or enhancement.
18 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20 * OR ANY PART THEREOF.
22 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23 * or profits or other special, indirect and consequential damages, even if
24 * Sun has been advised of the possibility of such damages.
26 * Sun Microsystems, Inc.
28 * Mountain View, California 94043
30 * @(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro
31 * $NetBSD: getrpcent.c,v 1.17 2000/01/22 22:19:17 mycroft Exp $
32 * $FreeBSD: src/lib/libc/rpc/getrpcent.c,v 1.16 2007/05/17 03:34:33 jon Exp $
33 * $DragonFly: src/lib/libc/rpc/getrpcent.c,v 1.4 2005/11/13 12:27:04 swildner Exp $
37 * Copyright (c) 1984 by Sun Microsystems, Inc.
40 #include <sys/param.h>
41 #include <sys/types.h>
42 #include <sys/socket.h>
43 #include <arpa/inet.h>
47 #include <netinet/in.h>
54 #include <rpcsvc/yp_prot.h>
55 #include <rpcsvc/ypclnt.h>
58 #include "namespace.h"
59 #include "reentrant.h"
60 #include "un-namespace.h"
61 #include "libc_private.h"
67 #define RPCDB "/etc/rpc"
69 /* nsswitch declarations */
74 RPCENT_STORAGE_INITIAL
= 1 << 10, /* 1 KByte */
75 RPCENT_STORAGE_MAX
= 1 << 20, /* 1 MByte */
78 static const ns_src defaultsrc
[] = {
79 { NSSRC_FILES
, NS_SUCCESS
},
81 { NSSRC_NIS
, NS_SUCCESS
},
86 /* files backend declarations */
92 static int files_rpcent(void *, void *, va_list);
93 static int files_setrpcent(void *, void *, va_list);
95 static void files_endstate(void *);
96 NSS_TLS_HANDLING(files
);
98 /* nis backend declarations */
101 char domain
[MAXHOSTNAMELEN
];
108 static int nis_rpcent(void *, void *, va_list);
109 static int nis_setrpcent(void *, void *, va_list);
111 static void nis_endstate(void *);
112 NSS_TLS_HANDLING(nis
);
115 /* get** wrappers for get**_r functions declarations */
116 struct rpcent_state
{
121 static void rpcent_endstate(void *);
122 NSS_TLS_HANDLING(rpcent
);
129 static int wrap_getrpcbyname_r(union key
, struct rpcent
*, char *,
130 size_t, struct rpcent
**);
131 static int wrap_getrpcbynumber_r(union key
, struct rpcent
*, char *,
132 size_t, struct rpcent
**);
133 static int wrap_getrpcent_r(union key
, struct rpcent
*, char *,
134 size_t, struct rpcent
**);
135 static struct rpcent
*getrpc(int (*fn
)(union key
, struct rpcent
*, char *,
136 size_t, struct rpcent
**), union key
);
139 static int rpc_id_func(char *, size_t *, va_list, void *);
140 static int rpc_marshal_func(char *, size_t *, void *, va_list, void *);
141 static int rpc_unmarshal_func(char *, size_t, void *, va_list, void *);
145 rpcent_unpack(char *p
, struct rpcent
*rpc
, char **r_aliases
,
146 size_t aliases_size
, int *errnop
)
154 cp
= strpbrk(p
, "#\n");
158 cp
= strpbrk(p
, " \t");
162 /* THIS STUFF IS INTERNET SPECIFIC */
164 while (*cp
== ' ' || *cp
== '\t')
166 rpc
->r_number
= atoi(cp
);
167 q
= rpc
->r_aliases
= r_aliases
;
168 cp
= strpbrk(cp
, " \t");
172 if (*cp
== ' ' || *cp
== '\t') {
176 if (q
< &(r_aliases
[aliases_size
- 1]))
183 cp
= strpbrk(cp
, " \t");
191 /* files backend implementation */
193 files_endstate(void *p
)
200 f
= ((struct files_state
*)p
)->fp
;
208 files_rpcent(void *retval
, void *mdata
, va_list ap
)
223 struct files_state
*st
;
226 enum nss_lookup_type how
;
228 how
= (enum nss_lookup_type
)mdata
;
232 name
= va_arg(ap
, char *);
235 number
= va_arg(ap
, int);
240 return (NS_NOTFOUND
);
243 rpc
= va_arg(ap
, struct rpcent
*);
244 buffer
= va_arg(ap
, char *);
245 bufsize
= va_arg(ap
, size_t);
246 errnop
= va_arg(ap
, int *);
248 *errnop
= files_getstate(&st
);
252 if (st
->fp
== NULL
&& (st
->fp
= fopen(RPCDB
, "r")) == NULL
) {
257 if (how
== nss_lt_all
)
261 stayopen
= st
->stayopen
;
265 if ((line
= fgetln(st
->fp
, &linesize
)) == NULL
) {
271 if (bufsize
<= linesize
+ _ALIGNBYTES
+ sizeof(char *)) {
277 aliases
= (char **)_ALIGN(&buffer
[linesize
+1]);
278 aliases_size
= (buffer
+ bufsize
-
279 (char *)aliases
)/sizeof(char *);
280 if (aliases_size
< 1) {
286 memcpy(buffer
, line
, linesize
);
287 buffer
[linesize
] = '\0';
289 rv
= rpcent_unpack(buffer
, rpc
, aliases
, aliases_size
, errnop
);
304 if (strcmp(rpc
->r_name
, name
) == 0)
306 for (rp
= rpc
->r_aliases
; *rp
!= NULL
; rp
++) {
307 if (strcmp(*rp
, name
) == 0)
316 rv
= (rpc
->r_number
== number
) ? NS_SUCCESS
:
324 } while (!(rv
& NS_TERMINATE
));
326 if (!stayopen
&& st
->fp
!=NULL
) {
331 if ((rv
== NS_SUCCESS
) && (retval
!= NULL
))
332 *((struct rpcent
**)retval
) = rpc
;
338 files_setrpcent(void *retval
, void *mdata
, va_list ap
)
340 struct files_state
*st
;
344 rv
= files_getstate(&st
);
348 switch ((enum constants
)mdata
)
353 st
->fp
= fopen(RPCDB
, "r");
359 if (st
->fp
!= NULL
) {
372 /* nis backend implementation */
375 nis_endstate(void *p
)
380 free(((struct nis_state
*)p
)->current
);
385 nis_rpcent(void *retval
, void *mdata
, va_list ap
)
401 char buf
[YPMAXRECORD
+ 2];
403 struct nis_state
*st
;
405 enum nss_lookup_type how
;
408 how
= (enum nss_lookup_type
)mdata
;
412 name
= va_arg(ap
, char *);
415 number
= va_arg(ap
, int);
420 return (NS_NOTFOUND
);
423 rpc
= va_arg(ap
, struct rpcent
*);
424 buffer
= va_arg(ap
, char *);
425 bufsize
= va_arg(ap
, size_t);
426 errnop
= va_arg(ap
, int *);
428 *errnop
= nis_getstate(&st
);
432 if (st
->domain
[0] == '\0') {
433 if (getdomainname(st
->domain
, sizeof(st
->domain
)) != 0) {
444 if (!st
->no_name_map
)
446 snprintf(buf
, sizeof buf
, "%s", name
);
447 rv
= yp_match(st
->domain
, "rpc.byname", buf
,
448 strlen(buf
), &resultbuf
, &resultbuflen
);
474 snprintf(buf
, sizeof buf
, "%d", number
);
475 if (yp_match(st
->domain
, "rpc.bynumber", buf
,
476 strlen(buf
), &resultbuf
, &resultbuflen
)) {
483 rv
= yp_first(st
->domain
, "rpc.bynumber",
485 &st
->currentlen
, &resultbuf
,
493 lastkey
= st
->current
;
494 rv
= yp_next(st
->domain
, "rpc.bynumber",
496 st
->currentlen
, &st
->current
,
498 &resultbuf
, &resultbuflen
);
509 /* we need a room for additional \n symbol */
510 if (bufsize
<= resultbuflen
+ 1 + _ALIGNBYTES
+
517 aliases
=(char **)_ALIGN(&buffer
[resultbuflen
+2]);
518 aliases_size
= (buffer
+ bufsize
- (char *)aliases
) /
520 if (aliases_size
< 1) {
527 * rpcent_unpack expects lines terminated with \n -- make it happy
529 memcpy(buffer
, resultbuf
, resultbuflen
);
530 buffer
[resultbuflen
] = '\n';
531 buffer
[resultbuflen
+1] = '\0';
534 if (rpcent_unpack(buffer
, rpc
, aliases
, aliases_size
,
541 if ((how
== nss_lt_all
) && (no_name_active
!= 0)) {
542 if (strcmp(rpc
->r_name
, name
) == 0)
544 for (rp
= rpc
->r_aliases
; *rp
!= NULL
; rp
++) {
545 if (strcmp(*rp
, name
) == 0)
556 } while (!(rv
& NS_TERMINATE
) && (how
== nss_lt_all
));
559 if ((rv
== NS_SUCCESS
) && (retval
!= NULL
))
560 *((struct rpcent
**)retval
) = rpc
;
566 nis_setrpcent(void *retval
, void *mdata
, va_list ap
)
568 struct nis_state
*st
;
571 rv
= nis_getstate(&st
);
575 switch ((enum constants
)mdata
)
593 rpc_id_func(char *buffer
, size_t *buffer_size
, va_list ap
, void *cache_mdata
)
598 size_t desired_size
, size
;
599 enum nss_lookup_type lookup_type
;
600 int res
= NS_UNAVAIL
;
602 lookup_type
= (enum nss_lookup_type
)cache_mdata
;
603 switch (lookup_type
) {
605 name
= va_arg(ap
, char *);
608 desired_size
= sizeof(enum nss_lookup_type
) + size
+ 1;
609 if (desired_size
> *buffer_size
) {
614 memcpy(buffer
, &lookup_type
, sizeof(enum nss_lookup_type
));
615 memcpy(buffer
+ sizeof(enum nss_lookup_type
), name
, size
+ 1);
620 rpc
= va_arg(ap
, int);
622 desired_size
= sizeof(enum nss_lookup_type
) + sizeof(int);
623 if (desired_size
> *buffer_size
) {
628 memcpy(buffer
, &lookup_type
, sizeof(enum nss_lookup_type
));
629 memcpy(buffer
+ sizeof(enum nss_lookup_type
), &rpc
,
635 /* should be unreachable */
640 *buffer_size
= desired_size
;
645 rpc_marshal_func(char *buffer
, size_t *buffer_size
, void *retval
, va_list ap
,
652 size_t orig_buf_size
;
654 struct rpcent new_rpc
;
655 size_t desired_size
, size
, aliases_size
;
659 switch ((enum nss_lookup_type
)cache_mdata
) {
661 name
= va_arg(ap
, char *);
664 num
= va_arg(ap
, int);
669 /* should be unreachable */
673 rpc
= va_arg(ap
, struct rpcent
*);
674 orig_buf
= va_arg(ap
, char *);
675 orig_buf_size
= va_arg(ap
, size_t);
677 desired_size
= _ALIGNBYTES
+ sizeof(struct rpcent
) + sizeof(char *);
678 if (rpc
->r_name
!= NULL
)
679 desired_size
+= strlen(rpc
->r_name
) + 1;
681 if (rpc
->r_aliases
!= NULL
) {
683 for (alias
= rpc
->r_aliases
; *alias
; ++alias
) {
684 desired_size
+= strlen(*alias
) + 1;
688 desired_size
+= _ALIGNBYTES
+ (aliases_size
+ 1) *
692 if (*buffer_size
< desired_size
) {
693 /* this assignment is here for future use */
694 *buffer_size
= desired_size
;
698 memcpy(&new_rpc
, rpc
, sizeof(struct rpcent
));
700 *buffer_size
= desired_size
;
701 memset(buffer
, 0, desired_size
);
702 p
= buffer
+ sizeof(struct rpcent
) + sizeof(char *);
703 memcpy(buffer
+ sizeof(struct rpcent
), &p
, sizeof(char *));
704 p
= (char *)_ALIGN(p
);
706 if (new_rpc
.r_name
!= NULL
) {
707 size
= strlen(new_rpc
.r_name
);
708 memcpy(p
, new_rpc
.r_name
, size
);
713 if (new_rpc
.r_aliases
!= NULL
) {
714 p
= (char *)_ALIGN(p
);
715 memcpy(p
, new_rpc
.r_aliases
, sizeof(char *) * aliases_size
);
716 new_rpc
.r_aliases
= (char **)p
;
717 p
+= sizeof(char *) * (aliases_size
+ 1);
719 for (alias
= new_rpc
.r_aliases
; *alias
; ++alias
) {
720 size
= strlen(*alias
);
721 memcpy(p
, *alias
, size
);
727 memcpy(buffer
, &new_rpc
, sizeof(struct rpcent
));
732 rpc_unmarshal_func(char *buffer
, size_t buffer_size
, void *retval
, va_list ap
,
739 size_t orig_buf_size
;
745 switch ((enum nss_lookup_type
)cache_mdata
) {
747 name
= va_arg(ap
, char *);
750 num
= va_arg(ap
, int);
755 /* should be unreachable */
759 rpc
= va_arg(ap
, struct rpcent
*);
760 orig_buf
= va_arg(ap
, char *);
761 orig_buf_size
= va_arg(ap
, size_t);
762 ret_errno
= va_arg(ap
, int *);
765 buffer_size
- sizeof(struct rpcent
) - sizeof(char *)) {
770 memcpy(rpc
, buffer
, sizeof(struct rpcent
));
771 memcpy(&p
, buffer
+ sizeof(struct rpcent
), sizeof(char *));
773 orig_buf
= (char *)_ALIGN(orig_buf
);
774 memcpy(orig_buf
, buffer
+ sizeof(struct rpcent
) + sizeof(char *) +
775 _ALIGN(p
) - (size_t)p
,
776 buffer_size
- sizeof(struct rpcent
) - sizeof(char *) -
777 _ALIGN(p
) + (size_t)p
);
778 p
= (char *)_ALIGN(p
);
780 NS_APPLY_OFFSET(rpc
->r_name
, orig_buf
, p
, char *);
781 if (rpc
->r_aliases
!= NULL
) {
782 NS_APPLY_OFFSET(rpc
->r_aliases
, orig_buf
, p
, char **);
784 for (alias
= rpc
->r_aliases
; *alias
; ++alias
)
785 NS_APPLY_OFFSET(*alias
, orig_buf
, p
, char *);
789 *((struct rpcent
**)retval
) = rpc
;
794 NSS_MP_CACHE_HANDLING(rpc
);
795 #endif /* NS_CACHING */
798 /* get**_r functions implementation */
800 getrpcbyname_r(const char *name
, struct rpcent
*rpc
, char *buffer
,
801 size_t bufsize
, struct rpcent
**result
)
804 static const nss_cache_info cache_info
=
805 NS_COMMON_CACHE_INFO_INITIALIZER(
806 rpc
, (void *)nss_lt_name
,
807 rpc_id_func
, rpc_marshal_func
, rpc_unmarshal_func
);
809 static const ns_dtab dtab
[] = {
810 { NSSRC_FILES
, files_rpcent
, (void *)nss_lt_name
},
812 { NSSRC_NIS
, nis_rpcent
, (void *)nss_lt_name
},
815 NS_CACHE_CB(&cache_info
)
823 rv
= nsdispatch(result
, dtab
, NSDB_RPC
, "getrpcbyname_r", defaultsrc
,
824 name
, rpc
, buffer
, bufsize
, &ret_errno
);
826 if (rv
== NS_SUCCESS
)
833 getrpcbynumber_r(int number
, struct rpcent
*rpc
, char *buffer
,
834 size_t bufsize
, struct rpcent
**result
)
837 static const nss_cache_info cache_info
=
838 NS_COMMON_CACHE_INFO_INITIALIZER(
839 rpc
, (void *)nss_lt_id
,
840 rpc_id_func
, rpc_marshal_func
, rpc_unmarshal_func
);
842 static const ns_dtab dtab
[] = {
843 { NSSRC_FILES
, files_rpcent
, (void *)nss_lt_id
},
845 { NSSRC_NIS
, nis_rpcent
, (void *)nss_lt_id
},
848 NS_CACHE_CB(&cache_info
)
856 rv
= nsdispatch(result
, dtab
, NSDB_RPC
, "getrpcbynumber_r", defaultsrc
,
857 number
, rpc
, buffer
, bufsize
, &ret_errno
);
859 if (rv
== NS_SUCCESS
)
866 getrpcent_r(struct rpcent
*rpc
, char *buffer
, size_t bufsize
,
867 struct rpcent
**result
)
870 static const nss_cache_info cache_info
= NS_MP_CACHE_INFO_INITIALIZER(
871 rpc
, (void *)nss_lt_all
,
872 rpc_marshal_func
, rpc_unmarshal_func
);
874 static const ns_dtab dtab
[] = {
875 { NSSRC_FILES
, files_rpcent
, (void *)nss_lt_all
},
877 { NSSRC_NIS
, nis_rpcent
, (void *)nss_lt_all
},
880 NS_CACHE_CB(&cache_info
)
888 rv
= nsdispatch(result
, dtab
, NSDB_RPC
, "getrpcent_r", defaultsrc
,
889 rpc
, buffer
, bufsize
, &ret_errno
);
891 if (rv
== NS_SUCCESS
)
897 /* get** wrappers for get**_r functions implementation */
899 rpcent_endstate(void *p
)
904 free(((struct rpcent_state
*)p
)->buffer
);
909 wrap_getrpcbyname_r(union key key
, struct rpcent
*rpc
, char *buffer
,
910 size_t bufsize
, struct rpcent
**res
)
912 return (getrpcbyname_r(key
.name
, rpc
, buffer
, bufsize
, res
));
916 wrap_getrpcbynumber_r(union key key
, struct rpcent
*rpc
, char *buffer
,
917 size_t bufsize
, struct rpcent
**res
)
919 return (getrpcbynumber_r(key
.number
, rpc
, buffer
, bufsize
, res
));
923 wrap_getrpcent_r(union key key __unused
, struct rpcent
*rpc
, char *buffer
,
924 size_t bufsize
, struct rpcent
**res
)
926 return (getrpcent_r(rpc
, buffer
, bufsize
, res
));
929 static struct rpcent
*
930 getrpc(int (*fn
)(union key
, struct rpcent
*, char *, size_t, struct rpcent
**),
935 struct rpcent_state
* st
;
937 rv
=rpcent_getstate(&st
);
943 if (st
->buffer
== NULL
) {
944 st
->buffer
= malloc(RPCENT_STORAGE_INITIAL
);
945 if (st
->buffer
== NULL
)
947 st
->bufsize
= RPCENT_STORAGE_INITIAL
;
950 rv
= fn(key
, &st
->rpc
, st
->buffer
, st
->bufsize
, &res
);
951 if (res
== NULL
&& rv
== ERANGE
) {
953 if ((st
->bufsize
<< 1) > RPCENT_STORAGE_MAX
) {
959 st
->buffer
= malloc(st
->bufsize
);
960 if (st
->buffer
== NULL
)
963 } while (res
== NULL
&& rv
== ERANGE
);
971 getrpcbyname(char *name
)
977 return (getrpc(wrap_getrpcbyname_r
, key
));
981 getrpcbynumber(int number
)
987 return (getrpc(wrap_getrpcbynumber_r
, key
));
995 key
.number
= 0; /* not used */
997 return (getrpc(wrap_getrpcent_r
, key
));
1001 setrpcent(int stayopen
)
1004 static const nss_cache_info cache_info
= NS_MP_CACHE_INFO_INITIALIZER(
1005 rpc
, (void *)nss_lt_all
,
1009 static const ns_dtab dtab
[] = {
1010 { NSSRC_FILES
, files_setrpcent
, (void *)SETRPCENT
},
1012 { NSSRC_NIS
, nis_setrpcent
, (void *)SETRPCENT
},
1015 NS_CACHE_CB(&cache_info
)
1017 { NULL
, NULL
, NULL
}
1020 nsdispatch(NULL
, dtab
, NSDB_RPC
, "setrpcent", defaultsrc
, stayopen
);
1027 static const nss_cache_info cache_info
= NS_MP_CACHE_INFO_INITIALIZER(
1028 rpc
, (void *)nss_lt_all
,
1032 static const ns_dtab dtab
[] = {
1033 { NSSRC_FILES
, files_setrpcent
, (void *)ENDRPCENT
},
1035 { NSSRC_NIS
, nis_setrpcent
, (void *)ENDRPCENT
},
1038 NS_CACHE_CB(&cache_info
)
1040 { NULL
, NULL
, NULL
}
1043 nsdispatch(NULL
, dtab
, NSDB_RPC
, "endrpcent", defaultsrc
);