OSDN Git Service

- trim any trailing whitespace
[uclinux-h8/uClibc.git] / libc / inet / rpc / 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 /* Experimentally off - libc_hidden_proto(memcpy) */
48 /* Experimentally off - libc_hidden_proto(memset) */
49 /* Experimentally off - libc_hidden_proto(strchr) */
50 /* Experimentally off - libc_hidden_proto(strcmp) */
51 /* Experimentally off - libc_hidden_proto(strlen) */
52 libc_hidden_proto(fopen)
53 libc_hidden_proto(fclose)
54 libc_hidden_proto(atoi)
55 libc_hidden_proto(rewind)
56 libc_hidden_proto(fgets)
57
58 /*
59  * Internet version.
60  */
61 static struct rpcdata {
62         FILE *rpcf;
63         char *current;
64         int currentlen;
65         int stayopen;
66 #define MAXALIASES      35
67         char *rpc_aliases[MAXALIASES];
68         struct rpcent rpc;
69         char line[BUFSIZ + 1];
70         char *domain;
71 } *rpcdata;
72
73 static char RPCDB[] = "/etc/rpc";
74
75 static struct rpcdata *_rpcdata(void)
76 {
77         register struct rpcdata *d = rpcdata;
78
79         if (d == NULL) {
80                 d = (struct rpcdata *) calloc(1, sizeof(struct rpcdata));
81
82                 rpcdata = d;
83         }
84         return d;
85 }
86
87 libc_hidden_proto(endrpcent)
88 void endrpcent(void)
89 {
90         register struct rpcdata *d = _rpcdata();
91
92         if (d == NULL)
93                 return;
94         if (d->stayopen)
95                 return;
96         free(d->current);
97         d->current = NULL;
98         if (d->rpcf) {
99                 fclose(d->rpcf);
100                 d->rpcf = NULL;
101         }
102 }
103 libc_hidden_def(endrpcent)
104
105 libc_hidden_proto(setrpcent)
106 void setrpcent(int f)
107 {
108         register struct rpcdata *d = _rpcdata();
109
110         if (d == NULL)
111                 return;
112         if (d->rpcf == NULL)
113                 d->rpcf = fopen(RPCDB, "r");
114         else
115                 rewind(d->rpcf);
116         free(d->current);
117         d->current = NULL;
118         d->stayopen |= f;
119 }
120 libc_hidden_def(setrpcent)
121
122 static struct rpcent *interpret(struct rpcdata *);
123
124 static struct rpcent *__get_next_rpcent(struct rpcdata *d)
125 {
126         if (fgets(d->line, BUFSIZ, d->rpcf) == NULL)
127                 return NULL;
128         return interpret(d);
129 }
130
131 libc_hidden_proto(getrpcent)
132 struct rpcent *getrpcent(void)
133 {
134         register struct rpcdata *d = _rpcdata();
135
136         if (d == NULL)
137                 return NULL;
138         if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL)
139                 return NULL;
140         return __get_next_rpcent(d);
141 }
142 libc_hidden_def(getrpcent)
143
144 libc_hidden_proto(getrpcbynumber)
145 struct rpcent *getrpcbynumber(register int number)
146 {
147         register struct rpcdata *d = _rpcdata();
148         register struct rpcent *rpc;
149
150         if (d == NULL)
151                 return NULL;
152         setrpcent(0);
153         while ((rpc = getrpcent())) {
154                 if (rpc->r_number == number)
155                         break;
156         }
157         endrpcent();
158         return rpc;
159 }
160 libc_hidden_def(getrpcbynumber)
161
162 libc_hidden_proto(getrpcbyname)
163 struct rpcent *getrpcbyname(const char *name)
164 {
165         struct rpcent *rpc;
166         char **rp;
167
168         setrpcent(0);
169         while ((rpc = getrpcent())) {
170                 if (strcmp(rpc->r_name, name) == 0)
171                         return rpc;
172                 for (rp = rpc->r_aliases; *rp != NULL; rp++) {
173                         if (strcmp(*rp, name) == 0)
174                                 return rpc;
175                 }
176         }
177         endrpcent();
178         return NULL;
179 }
180 libc_hidden_def(getrpcbyname)
181
182 #ifdef __linux__
183 static char *firstwhite(char *s)
184 {
185         char *s1, *s2;
186
187         s1 = strchr(s, ' ');
188         s2 = strchr(s, '\t');
189         if (s1) {
190                 if (s2)
191                         return (s1 < s2) ? s1 : s2;
192                 else
193                         return s1;
194         } else
195                 return s2;
196 }
197 #endif
198
199 static struct rpcent *interpret(register struct rpcdata *d)
200 {
201         char *p;
202         register char *cp, **q;
203
204         p = d->line;
205         d->line[strlen(p)-1] = '\n';
206         if (*p == '#')
207                 return __get_next_rpcent(d);
208         cp = strchr(p, '#');
209         if (cp == NULL) {
210                 cp = strchr(p, '\n');
211                 if (cp == NULL)
212                         return __get_next_rpcent(d);
213         }
214         *cp = '\0';
215 #ifdef __linux__
216         if ((cp = firstwhite(p)))
217                 *cp++ = 0;
218         else
219                 return __get_next_rpcent(d);
220 #else
221         cp = strchr(p, ' ');
222         if (cp == NULL) {
223                 cp = strchr(p, '\t');
224                 if (cp == NULL)
225                         return __get_next_rpcent(d);
226         }
227         *cp++ = '\0';
228 #endif
229         /* THIS STUFF IS INTERNET SPECIFIC */
230         d->rpc.r_name = d->line;
231         while (*cp == ' ' || *cp == '\t')
232                 cp++;
233         d->rpc.r_number = atoi(cp);
234         q = d->rpc.r_aliases = d->rpc_aliases;
235 #ifdef __linux__
236         if ((cp = firstwhite(cp)))
237                 *cp++ = '\0';
238 #else
239         cp = strchr(p, ' ');
240         if (cp != NULL)
241                 *cp++ = '\0';
242         else {
243                 cp = strchr(p, '\t');
244                 if (cp != NULL)
245                         *cp++ = '\0';
246         }
247 #endif
248         while (cp && *cp) {
249                 if (*cp == ' ' || *cp == '\t') {
250                         cp++;
251                         continue;
252                 }
253                 if (q < &(d->rpc_aliases[MAXALIASES - 1]))
254                         *q++ = cp;
255 #ifdef __linux__
256                 if ((cp = firstwhite(cp)))
257                         *cp++ = '\0';
258 #else
259                 cp = strchr(p, ' ');
260                 if (cp != NULL)
261                         *cp++ = '\0';
262                 else {
263                         cp = strchr(p, '\t');
264                         if (cp != NULL)
265                                 *cp++ = '\0';
266                 }
267 #endif
268         }
269         *q = NULL;
270         return &d->rpc;
271 }
272
273 #if defined(__UCLIBC_HAS_REENTRANT_RPC__)
274
275 #include <bits/uClibc_mutex.h>
276 __UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
277
278
279 static int __copy_rpcent(struct rpcent *r, struct rpcent *result_buf, char *buffer,
280                 size_t buflen, struct rpcent **result)
281 {
282         size_t i, s;
283
284         *result = NULL;
285
286         if (!r)
287                 return ENOENT;
288
289         /* copy the struct from the shared mem */
290         memset(result_buf, 0x00, sizeof(*result_buf));
291         memset(buffer, 0x00, buflen);
292
293         result_buf->r_number = r->r_number;
294
295         /* copy the aliases ... need to not only copy the alias strings,
296          * but the array of pointers to the alias strings */
297         i = 0;
298         while (r->r_aliases[i++]) ;
299
300         s = i-- * sizeof(char*);
301         if (buflen < s)
302                 goto err_out;
303         result_buf->r_aliases = (char**)buffer;
304         buffer += s;
305         buflen -= s;
306
307         while (i-- > 0) {
308                 s = strlen(r->r_aliases[i]) + 1;
309                 if (buflen < s)
310                         goto err_out;
311                 result_buf->r_aliases[i] = buffer;
312                 buffer += s;
313                 buflen -= s;
314                 memcpy(result_buf->r_aliases[i], r->r_aliases[i], s);
315         }
316
317         /* copy the name */
318         i = strlen(r->r_name);
319         if (buflen <= i)
320                 goto err_out;
321         result_buf->r_name = buffer;
322         memcpy(result_buf->r_name, r->r_name, i);
323
324         /* that was a hoot eh ? */
325         *result = result_buf;
326
327         return 0;
328 err_out:
329         return ERANGE;
330 }
331
332 int getrpcbynumber_r(int number, struct rpcent *result_buf, char *buffer,
333                 size_t buflen, struct rpcent **result)
334 {
335         int ret;
336         __UCLIBC_MUTEX_LOCK(mylock);
337         ret = __copy_rpcent(getrpcbynumber(number), result_buf, buffer, buflen, result);
338         __UCLIBC_MUTEX_UNLOCK(mylock);
339         return ret;
340 }
341
342 int getrpcbyname_r(const char *name, struct rpcent *result_buf, char *buffer,
343                 size_t buflen, struct rpcent **result)
344 {
345         int ret;
346         __UCLIBC_MUTEX_LOCK(mylock);
347         ret = __copy_rpcent(getrpcbyname(name), result_buf, buffer, buflen, result);
348         __UCLIBC_MUTEX_UNLOCK(mylock);
349         return ret;
350 }
351
352 int getrpcent_r(struct rpcent *result_buf, char *buffer,
353                 size_t buflen, struct rpcent **result)
354 {
355         int ret;
356         __UCLIBC_MUTEX_LOCK(mylock);
357         ret = __copy_rpcent(getrpcent(), result_buf, buffer, buflen, result);
358         __UCLIBC_MUTEX_UNLOCK(mylock);
359         return ret;
360 }
361
362 #endif /* __UCLIBC_HAS_REENTRANT_RPC__ */