Imported Upstream version 0.2.5
[platform/upstream/libtirpc.git] / src / getrpcent.c
1 /*
2  * Copyright (c) 2009, Sun Microsystems, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * - Redistributions of source code must retain the above copyright notice,
8  *   this list of conditions and the following disclaimer.
9  * - Redistributions in binary form must reproduce the above copyright notice,
10  *   this list of conditions and the following disclaimer in the documentation
11  *   and/or other materials provided with the distribution.
12  * - Neither the name of Sun Microsystems, Inc. nor the names of its
13  *   contributors may be used to endorse or promote products derived
14  *   from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 /*
30  * Copyright (c) 1984 by Sun Microsystems, Inc.
31  */
32
33 #include <sys/types.h>
34
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
37
38 #include <assert.h>
39 #include <netdb.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43
44 #include <rpc/rpc.h>
45 #ifdef YP
46 #include <rpcsvc/yp_prot.h>
47 #include <rpcsvc/ypclnt.h>
48 #endif
49 #if defined(__FreeBSD__) || defined(__NetBSD__)
50 #include <libc_private.h>
51 #endif
52
53 /*
54  * Internet version.
55  */
56 static struct rpcdata {
57         FILE    *rpcf;
58         int     stayopen;
59 #define MAXALIASES      35
60         char    *rpc_aliases[MAXALIASES];
61         struct  rpcent rpc;
62         char    line[BUFSIZ+1];
63 #ifdef  YP
64         char    *domain;
65         char    *current;
66         int     currentlen;
67 #endif
68 } *rpcdata;
69
70 static  struct rpcent *interpret(char *val, size_t len);
71
72 #ifdef  YP
73 static int      __yp_nomap = 0;
74 #endif  /* YP */
75
76 #define RPCDB   "/etc/rpc"
77
78 static struct rpcdata *_rpcdata(void);
79
80 static struct rpcdata *
81 _rpcdata()
82 {
83         struct rpcdata *d = rpcdata;
84
85         if (d == 0) {
86                 d = (struct rpcdata *)calloc(1, sizeof (struct rpcdata));
87                 rpcdata = d;
88         }
89         return (d);
90 }
91
92 #ifdef GQ
93 struct rpcent *
94 getrpcbynumber(number)
95         int number;
96 {
97 #ifdef  YP
98         int reason;
99         char adrstr[16];
100 #endif
101         struct rpcent *p;
102         struct rpcdata *d = _rpcdata();
103
104         if (d == 0)
105                 return (0);
106 #ifdef  YP
107         if (!__yp_nomap && _yp_check(&d->domain)) {
108                 sprintf(adrstr, "%d", number);
109                 reason = yp_match(d->domain, "rpc.bynumber", adrstr, strlen(adrstr),
110                                   &d->current, &d->currentlen);
111                 switch(reason) {
112                 case 0:
113                         break;
114                 case YPERR_MAP:
115                         __yp_nomap = 1;
116                         goto no_yp;
117                         break;
118                 default:
119                         return(0);
120                         break;
121                 }
122                 d->current[d->currentlen] = '\0';
123                 p = interpret(d->current, d->currentlen);
124                 (void) free(d->current);
125                 return p;
126         }
127 no_yp:
128 #endif  /* YP */
129
130         setrpcent(0);
131         while ((p = getrpcent()) != NULL) {
132                 if (p->r_number == number)
133                         break;
134         }
135         endrpcent();
136         return (p);
137 }
138
139 struct rpcent *
140 getrpcbyname(name)
141         const char *name;
142 {
143         struct rpcent *rpc = NULL;
144         char **rp;
145
146         assert(name != NULL);
147
148         setrpcent(0);
149         while ((rpc = getrpcent()) != NULL) {
150                 if (strcmp(rpc->r_name, name) == 0)
151                         goto done;
152                 for (rp = rpc->r_aliases; *rp != NULL; rp++) {
153                         if (strcmp(*rp, name) == 0)
154                                 goto done;
155                 }
156         }
157 done:
158         endrpcent();
159         return (rpc);
160 }
161 #endif /* GQ */
162
163 void
164 setrpcent(f)
165         int f;
166 {
167         struct rpcdata *d = _rpcdata();
168
169         if (d == 0)
170                 return;
171 #ifdef  YP
172         if (!__yp_nomap && _yp_check(NULL)) {
173                 if (d->current)
174                         free(d->current);
175                 d->current = NULL;
176                 d->currentlen = 0;
177                 return;
178         }
179         __yp_nomap = 0;
180 #endif  /* YP */
181         if (d->rpcf == NULL)
182                 d->rpcf = fopen(RPCDB, "r");
183         else
184                 rewind(d->rpcf);
185         d->stayopen |= f;
186 }
187
188 void
189 endrpcent()
190 {
191         struct rpcdata *d = _rpcdata();
192
193         if (d == 0)
194                 return;
195 #ifdef  YP
196         if (!__yp_nomap && _yp_check(NULL)) {
197                 if (d->current && !d->stayopen)
198                         free(d->current);
199                 d->current = NULL;
200                 d->currentlen = 0;
201                 return;
202         }
203         __yp_nomap = 0;
204 #endif  /* YP */
205         if (d->rpcf && !d->stayopen) {
206                 fclose(d->rpcf);
207                 d->rpcf = NULL;
208         }
209 }
210
211 struct rpcent *
212 getrpcent()
213 {
214         struct rpcdata *d = _rpcdata();
215 #ifdef  YP
216         struct rpcent *hp;
217         int reason;
218         char *val = NULL;
219         int vallen;
220 #endif
221
222         if (d == 0)
223                 return(NULL);
224 #ifdef  YP
225         if (!__yp_nomap && _yp_check(&d->domain)) {
226                 if (d->current == NULL && d->currentlen == 0) {
227                         reason = yp_first(d->domain, "rpc.bynumber",
228                                           &d->current, &d->currentlen,
229                                           &val, &vallen);
230                 } else {
231                         reason = yp_next(d->domain, "rpc.bynumber",
232                                          d->current, d->currentlen,
233                                          &d->current, &d->currentlen,
234                                          &val, &vallen);
235                 }
236                 switch(reason) {
237                 case 0:
238                         break;
239                 case YPERR_MAP:
240                         __yp_nomap = 1;
241                         goto no_yp;
242                         break;
243                 default:
244                         return(0);
245                         break;
246                 }
247                 val[vallen] = '\0';
248                 hp = interpret(val, vallen);
249                 (void) free(val);
250                 return hp;
251         }
252 no_yp:
253 #endif  /* YP */
254         if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL)
255                 return (NULL);
256         /* -1 so there is room to append a \n below */
257         if (fgets(d->line, BUFSIZ - 1, d->rpcf) == NULL)
258                 return (NULL);
259         return (interpret(d->line, strlen(d->line)));
260 }
261
262 static struct rpcent *
263 interpret(val, len)
264         char *val;
265         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         (void) 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