OSDN Git Service

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