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