xref: /dflybsd-src/lib/libc/rpc/getrpcent.c (revision ce0e08e21d42c06c0014fae6b9d27144aa5109b0)
1 /*
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.
9  *
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.
13  *
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.
17  *
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.
21  *
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.
25  *
26  * Sun Microsystems, Inc.
27  * 2550 Garcia Avenue
28  * Mountain View, California  94043
29  *
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.14 2003/02/27 13:40:01 nectar Exp $
33  * $DragonFly: src/lib/libc/rpc/getrpcent.c,v 1.4 2005/11/13 12:27:04 swildner Exp $
34  */
35 
36 /*
37  * Copyright (c) 1984 by Sun Microsystems, Inc.
38  */
39 
40 #include "namespace.h"
41 #include <sys/types.h>
42 
43 #include <netinet/in.h>
44 #include <arpa/inet.h>
45 
46 #include <assert.h>
47 #include <netdb.h>
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51 
52 #include <rpc/rpc.h>
53 #ifdef YP
54 #include <rpcsvc/yp_prot.h>
55 #include <rpcsvc/ypclnt.h>
56 #endif
57 #include "un-namespace.h"
58 #include "libc_private.h"
59 
60 /*
61  * Internet version.
62  */
63 static struct rpcdata {
64 	FILE	*rpcf;
65 	int	stayopen;
66 #define	MAXALIASES	35
67 	char	*rpc_aliases[MAXALIASES];
68 	struct	rpcent rpc;
69 	char	line[BUFSIZ+1];
70 #ifdef	YP
71 	char	*domain;
72 	char	*current;
73 	int	currentlen;
74 #endif
75 } *rpcdata;
76 
77 static	struct rpcent *interpret(char *val, size_t len);
78 
79 #ifdef	YP
80 static int	__yp_nomap = 0;
81 #endif	/* YP */
82 
83 #define	RPCDB	"/etc/rpc"
84 
85 static struct rpcdata *_rpcdata(void);
86 
87 static struct rpcdata *
88 _rpcdata(void)
89 {
90 	struct rpcdata *d = rpcdata;
91 
92 	if (d == 0) {
93 		d = (struct rpcdata *)calloc(1, sizeof (struct rpcdata));
94 		rpcdata = d;
95 	}
96 	return (d);
97 }
98 
99 struct rpcent *
100 getrpcbynumber(int number)
101 {
102 #ifdef	YP
103 	int reason;
104 	char adrstr[16];
105 #endif
106 	struct rpcent *p;
107 	struct rpcdata *d = _rpcdata();
108 
109 	if (d == 0)
110 		return (0);
111 #ifdef	YP
112         if (!__yp_nomap && _yp_check(&d->domain)) {
113                 sprintf(adrstr, "%d", number);
114                 reason = yp_match(d->domain, "rpc.bynumber", adrstr, strlen(adrstr),
115                                   &d->current, &d->currentlen);
116                 switch(reason) {
117                 case 0:
118                         break;
119                 case YPERR_MAP:
120                         __yp_nomap = 1;
121                         goto no_yp;
122                         break;
123                 default:
124                         return(0);
125                         break;
126                 }
127                 d->current[d->currentlen] = '\0';
128                 p = interpret(d->current, d->currentlen);
129                 free(d->current);
130                 return p;
131         }
132 no_yp:
133 #endif	/* YP */
134 
135 	setrpcent(0);
136 	while ((p = getrpcent()) != NULL) {
137 		if (p->r_number == number)
138 			break;
139 	}
140 	endrpcent();
141 	return (p);
142 }
143 
144 struct rpcent *
145 getrpcbyname(char *name)
146 {
147 	struct rpcent *rpc = NULL;
148 	char **rp;
149 
150 	assert(name != NULL);
151 
152 	setrpcent(0);
153 	while ((rpc = getrpcent()) != NULL) {
154 		if (strcmp(rpc->r_name, name) == 0)
155 			goto done;
156 		for (rp = rpc->r_aliases; *rp != NULL; rp++) {
157 			if (strcmp(*rp, name) == 0)
158 				goto done;
159 		}
160 	}
161 done:
162 	endrpcent();
163 	return (rpc);
164 }
165 
166 void
167 setrpcent(int f)
168 {
169 	struct rpcdata *d = _rpcdata();
170 
171 	if (d == 0)
172 		return;
173 #ifdef	YP
174         if (!__yp_nomap && _yp_check(NULL)) {
175                 if (d->current)
176                         free(d->current);
177                 d->current = NULL;
178                 d->currentlen = 0;
179                 return;
180         }
181         __yp_nomap = 0;
182 #endif	/* YP */
183 	if (d->rpcf == NULL)
184 		d->rpcf = fopen(RPCDB, "r");
185 	else
186 		rewind(d->rpcf);
187 	d->stayopen |= f;
188 }
189 
190 void
191 endrpcent(void)
192 {
193 	struct rpcdata *d = _rpcdata();
194 
195 	if (d == 0)
196 		return;
197 #ifdef	YP
198         if (!__yp_nomap && _yp_check(NULL)) {
199         	if (d->current && !d->stayopen)
200                         free(d->current);
201                 d->current = NULL;
202                 d->currentlen = 0;
203                 return;
204         }
205         __yp_nomap = 0;
206 #endif	/* YP */
207 	if (d->rpcf && !d->stayopen) {
208 		fclose(d->rpcf);
209 		d->rpcf = NULL;
210 	}
211 }
212 
213 struct rpcent *
214 getrpcent(void)
215 {
216 	struct rpcdata *d = _rpcdata();
217 #ifdef	YP
218 	struct rpcent *hp;
219 	int reason;
220 	char *val = NULL;
221 	int vallen;
222 #endif
223 
224 	if (d == 0)
225 		return(NULL);
226 #ifdef	YP
227         if (!__yp_nomap && _yp_check(&d->domain)) {
228                 if (d->current == NULL && d->currentlen == 0) {
229                         reason = yp_first(d->domain, "rpc.bynumber",
230                                           &d->current, &d->currentlen,
231                                           &val, &vallen);
232                 } else {
233                         reason = yp_next(d->domain, "rpc.bynumber",
234                                          d->current, d->currentlen,
235                                          &d->current, &d->currentlen,
236                                          &val, &vallen);
237                 }
238                 switch(reason) {
239                 case 0:
240                         break;
241                 case YPERR_MAP:
242                         __yp_nomap = 1;
243                         goto no_yp;
244                         break;
245                 default:
246                         return(0);
247                         break;
248                 }
249                 val[vallen] = '\0';
250                 hp = interpret(val, vallen);
251                 free(val);
252                 return hp;
253         }
254 no_yp:
255 #endif	/* YP */
256 	if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL)
257 		return (NULL);
258 	/* -1 so there is room to append a \n below */
259         if (fgets(d->line, BUFSIZ - 1, d->rpcf) == NULL)
260 		return (NULL);
261 	return (interpret(d->line, strlen(d->line)));
262 }
263 
264 static struct rpcent *
265 interpret(char *val, size_t len)
266 {
267 	struct rpcdata *d = _rpcdata();
268 	char *p;
269 	char *cp, **q;
270 
271 	assert(val != NULL);
272 
273 	if (d == 0)
274 		return (0);
275 	strncpy(d->line, val, BUFSIZ);
276 	d->line[BUFSIZ] = '\0';
277 	p = d->line;
278 	p[len] = '\n';
279 	if (*p == '#')
280 		return (getrpcent());
281 	cp = strpbrk(p, "#\n");
282 	if (cp == NULL)
283 		return (getrpcent());
284 	*cp = '\0';
285 	cp = strpbrk(p, " \t");
286 	if (cp == NULL)
287 		return (getrpcent());
288 	*cp++ = '\0';
289 	/* THIS STUFF IS INTERNET SPECIFIC */
290 	d->rpc.r_name = d->line;
291 	while (*cp == ' ' || *cp == '\t')
292 		cp++;
293 	d->rpc.r_number = atoi(cp);
294 	q = d->rpc.r_aliases = d->rpc_aliases;
295 	cp = strpbrk(cp, " \t");
296 	if (cp != NULL)
297 		*cp++ = '\0';
298 	while (cp && *cp) {
299 		if (*cp == ' ' || *cp == '\t') {
300 			cp++;
301 			continue;
302 		}
303 		if (q < &(d->rpc_aliases[MAXALIASES - 1]))
304 			*q++ = cp;
305 		cp = strpbrk(cp, " \t");
306 		if (cp != NULL)
307 			*cp++ = '\0';
308 	}
309 	*q = NULL;
310 	return (&d->rpc);
311 }
312 
313