fix build with uclibc-ng
[project/librpc-uclibc.git] / getrpcent.c
1 /* @(#)getrpcent.c 2.2 88/07/29 4.0 RPCSRC */
2
3 /*
4 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
5 * unrestricted use provided that this legend is included on all tape
6 * media and as a part of the software program in whole or part. Users
7 * may copy or modify Sun RPC without charge, but are not authorized
8 * to license or distribute it to anyone else except as part of a product or
9 * program developed by the user.
10 *
11 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
12 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
13 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
14 *
15 * Sun RPC is provided with no support and without any obligation on the
16 * part of Sun Microsystems, Inc. to assist in its use, correction,
17 * modification or enhancement.
18 *
19 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
20 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
21 * OR ANY PART THEREOF.
22 *
23 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
24 * or profits or other special, indirect and consequential damages, even if
25 * Sun has been advised of the possibility of such damages.
26 *
27 * Sun Microsystems, Inc.
28 * 2550 Garcia Avenue
29 * Mountain View, California 94043
30 */
31
32 /*
33 * Copyright (c) 1985 by Sun Microsystems, Inc.
34 */
35
36 #define __FORCE_GLIBC
37 #include <features.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include <sys/types.h>
41 #include <rpc/rpc.h>
42 #include <netdb.h>
43 #include <sys/socket.h>
44 #include <arpa/inet.h>
45 #include <errno.h>
46
47
48 /*
49 * Internet version.
50 */
51 static struct rpcdata {
52 FILE *rpcf;
53 char *current;
54 int currentlen;
55 int stayopen;
56 #define MAXALIASES 35
57 char *rpc_aliases[MAXALIASES];
58 struct rpcent rpc;
59 char line[BUFSIZ + 1];
60 char *domain;
61 } *rpcdata;
62
63 static const char RPCDB[] = "/etc/rpc";
64
65 static struct rpcdata *_rpcdata(void)
66 {
67 register struct rpcdata *d = rpcdata;
68
69 if (d == NULL) {
70 d = (struct rpcdata *) calloc(1, sizeof(struct rpcdata));
71
72 rpcdata = d;
73 }
74 return d;
75 }
76
77 void endrpcent(void)
78 {
79 register struct rpcdata *d = _rpcdata();
80
81 if (d == NULL)
82 return;
83 if (d->stayopen)
84 return;
85 free(d->current);
86 d->current = NULL;
87 if (d->rpcf) {
88 fclose(d->rpcf);
89 d->rpcf = NULL;
90 }
91 }
92 libc_hidden_def(endrpcent)
93
94 void setrpcent(int f)
95 {
96 register struct rpcdata *d = _rpcdata();
97
98 if (d == NULL)
99 return;
100 if (d->rpcf == NULL)
101 d->rpcf = fopen(RPCDB, "r");
102 else
103 rewind(d->rpcf);
104 free(d->current);
105 d->current = NULL;
106 d->stayopen |= f;
107 }
108 libc_hidden_def(setrpcent)
109
110 static struct rpcent *interpret(struct rpcdata *);
111
112 static struct rpcent *__get_next_rpcent(struct rpcdata *d)
113 {
114 if (fgets(d->line, BUFSIZ, d->rpcf) == NULL)
115 return NULL;
116 return interpret(d);
117 }
118
119 struct rpcent *getrpcent(void)
120 {
121 register struct rpcdata *d = _rpcdata();
122
123 if (d == NULL)
124 return NULL;
125 if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL)
126 return NULL;
127 return __get_next_rpcent(d);
128 }
129 libc_hidden_def(getrpcent)
130
131 struct rpcent *getrpcbynumber(register int number)
132 {
133 register struct rpcdata *d = _rpcdata();
134 register struct rpcent *rpc;
135
136 if (d == NULL)
137 return NULL;
138 setrpcent(0);
139 while ((rpc = getrpcent())) {
140 if (rpc->r_number == number)
141 break;
142 }
143 endrpcent();
144 return rpc;
145 }
146 libc_hidden_def(getrpcbynumber)
147
148 struct rpcent *getrpcbyname(const char *name)
149 {
150 struct rpcent *rpc;
151 char **rp;
152
153 setrpcent(0);
154 while ((rpc = getrpcent())) {
155 if (strcmp(rpc->r_name, name) == 0)
156 return rpc;
157 for (rp = rpc->r_aliases; *rp != NULL; rp++) {
158 if (strcmp(*rp, name) == 0)
159 return rpc;
160 }
161 }
162 endrpcent();
163 return NULL;
164 }
165 libc_hidden_def(getrpcbyname)
166
167 #ifdef __linux__
168 static char *firstwhite(char *s)
169 {
170 char *s1, *s2;
171
172 s1 = strchr(s, ' ');
173 s2 = strchr(s, '\t');
174 if (s1) {
175 if (s2)
176 return (s1 < s2) ? s1 : s2;
177 else
178 return s1;
179 } else
180 return s2;
181 }
182 #endif
183
184 static struct rpcent *interpret(register struct rpcdata *d)
185 {
186 char *p;
187 register char *cp, **q;
188
189 p = d->line;
190 d->line[strlen(p)-1] = '\n';
191 if (*p == '#')
192 return __get_next_rpcent(d);
193 cp = strchr(p, '#');
194 if (cp == NULL) {
195 cp = strchr(p, '\n');
196 if (cp == NULL)
197 return __get_next_rpcent(d);
198 }
199 *cp = '\0';
200 #ifdef __linux__
201 if ((cp = firstwhite(p)))
202 *cp++ = 0;
203 else
204 return __get_next_rpcent(d);
205 #else
206 cp = strchr(p, ' ');
207 if (cp == NULL) {
208 cp = strchr(p, '\t');
209 if (cp == NULL)
210 return __get_next_rpcent(d);
211 }
212 *cp++ = '\0';
213 #endif
214 /* THIS STUFF IS INTERNET SPECIFIC */
215 d->rpc.r_name = d->line;
216 while (*cp == ' ' || *cp == '\t')
217 cp++;
218 d->rpc.r_number = atoi(cp);
219 q = d->rpc.r_aliases = d->rpc_aliases;
220 #ifdef __linux__
221 if ((cp = firstwhite(cp)))
222 *cp++ = '\0';
223 #else
224 cp = strchr(p, ' ');
225 if (cp != NULL)
226 *cp++ = '\0';
227 else {
228 cp = strchr(p, '\t');
229 if (cp != NULL)
230 *cp++ = '\0';
231 }
232 #endif
233 while (cp && *cp) {
234 if (*cp == ' ' || *cp == '\t') {
235 cp++;
236 continue;
237 }
238 if (q < &(d->rpc_aliases[MAXALIASES - 1]))
239 *q++ = cp;
240 #ifdef __linux__
241 if ((cp = firstwhite(cp)))
242 *cp++ = '\0';
243 #else
244 cp = strchr(p, ' ');
245 if (cp != NULL)
246 *cp++ = '\0';
247 else {
248 cp = strchr(p, '\t');
249 if (cp != NULL)
250 *cp++ = '\0';
251 }
252 #endif
253 }
254 *q = NULL;
255 return &d->rpc;
256 }
257
258 #if defined(__UCLIBC_HAS_REENTRANT_RPC__)
259
260 __UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
261
262
263 static int __copy_rpcent(struct rpcent *r, struct rpcent *result_buf, char *buffer,
264 size_t buflen, struct rpcent **result)
265 {
266 size_t i, s;
267
268 *result = NULL;
269
270 if (!r)
271 return ENOENT;
272
273 /* copy the struct from the shared mem */
274 memset(result_buf, 0x00, sizeof(*result_buf));
275 memset(buffer, 0x00, buflen);
276
277 result_buf->r_number = r->r_number;
278
279 /* copy the aliases ... need to not only copy the alias strings,
280 * but the array of pointers to the alias strings */
281 i = 0;
282 while (r->r_aliases[i++]) ;
283
284 s = i-- * sizeof(char*);
285 if (buflen < s)
286 goto err_out;
287 result_buf->r_aliases = (char**)buffer;
288 buffer += s;
289 buflen -= s;
290
291 while (i-- > 0) {
292 s = strlen(r->r_aliases[i]) + 1;
293 if (buflen < s)
294 goto err_out;
295 result_buf->r_aliases[i] = buffer;
296 buffer += s;
297 buflen -= s;
298 memcpy(result_buf->r_aliases[i], r->r_aliases[i], s);
299 }
300
301 /* copy the name */
302 i = strlen(r->r_name);
303 if (buflen <= i)
304 goto err_out;
305 result_buf->r_name = buffer;
306 memcpy(result_buf->r_name, r->r_name, i);
307
308 /* that was a hoot eh ? */
309 *result = result_buf;
310
311 return 0;
312 err_out:
313 return ERANGE;
314 }
315
316 int getrpcbynumber_r(int number, struct rpcent *result_buf, char *buffer,
317 size_t buflen, struct rpcent **result)
318 {
319 int ret;
320 __UCLIBC_MUTEX_LOCK(mylock);
321 ret = __copy_rpcent(getrpcbynumber(number), result_buf, buffer, buflen, result);
322 __UCLIBC_MUTEX_UNLOCK(mylock);
323 return ret;
324 }
325
326 int getrpcbyname_r(const char *name, struct rpcent *result_buf, char *buffer,
327 size_t buflen, struct rpcent **result)
328 {
329 int ret;
330 __UCLIBC_MUTEX_LOCK(mylock);
331 ret = __copy_rpcent(getrpcbyname(name), result_buf, buffer, buflen, result);
332 __UCLIBC_MUTEX_UNLOCK(mylock);
333 return ret;
334 }
335
336 int getrpcent_r(struct rpcent *result_buf, char *buffer,
337 size_t buflen, struct rpcent **result)
338 {
339 int ret;
340 __UCLIBC_MUTEX_LOCK(mylock);
341 ret = __copy_rpcent(getrpcent(), result_buf, buffer, buflen, result);
342 __UCLIBC_MUTEX_UNLOCK(mylock);
343 return ret;
344 }
345
346 #endif /* __UCLIBC_HAS_REENTRANT_RPC__ */