OSDN Git Service

libc/inet: convert to foo-y kbuild style
[uclinux-h8/uClibc.git] / libc / inet / getproto.c
1 /*
2 ** protocols.c                           /etc/protocols access functions
3 **
4 ** This file is part of the NYS Library.
5 **
6 ** The NYS Library is free software; you can redistribute it and/or
7 ** modify it under the terms of the GNU Library General Public License as
8 ** published by the Free Software Foundation; either version 2 of the
9 ** License, or (at your option) any later version.
10 **
11 ** The NYS Library is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 ** Library General Public License for more details.
15 **
16 ** You should have received a copy of the GNU Library General Public
17 ** License along with the NYS Library; see the file COPYING.LIB.  If
18 ** not, write to the Free Software Foundation, Inc., 675 Mass Ave,
19 ** Cambridge, MA 02139, USA.
20 **
21 **
22 ** Copyright (c) 1983 Regents of the University of California.
23 ** All rights reserved.
24 **
25 ** Redistribution and use in source and binary forms, with or without
26 ** modification, are permitted provided that the following conditions
27 ** are met:
28 ** 1. Redistributions of source code must retain the above copyright
29 **    notice, this list of conditions and the following disclaimer.
30 ** 2. Redistributions in binary form must reproduce the above copyright
31 **    notice, this list of conditions and the following disclaimer in the
32 **    documentation and/or other materials provided with the distribution.
33 ** 3. All advertising materials mentioning features or use of this software
34 **    must display the following acknowledgement:
35 **      This product includes software developed by the University of
36 **      California, Berkeley and its contributors.
37 ** 4. Neither the name of the University nor the names of its contributors
38 **    may be used to endorse or promote products derived from this software
39 **    without specific prior written permission.
40 **
41 ** THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
42 ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 ** ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
45 ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 ** SUCH DAMAGE.
52 */
53
54 #define __FORCE_GLIBC
55 #include <features.h>
56 #include <sys/types.h>
57 #include <sys/socket.h>
58 #include <netdb.h>
59 #include <stdio.h>
60 #include <stdlib.h>
61 #include <string.h>
62 #include <errno.h>
63 #include <unistd.h>
64
65
66 #include <bits/uClibc_mutex.h>
67 __UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
68
69
70
71 #define MAXALIASES      35
72 #define SBUFSIZE        (BUFSIZ + 1 + (sizeof(char *) * MAXALIASES))
73
74 static FILE *protof = NULL;
75 static struct protoent proto;
76 static char *static_aliases = NULL;
77 static smallint proto_stayopen;
78
79 static void __initbuf(void)
80 {
81     if (!static_aliases) {
82         static_aliases = malloc(SBUFSIZE);
83         if (!static_aliases)
84             abort();
85     }
86 }
87
88 void setprotoent(int f)
89 {
90     __UCLIBC_MUTEX_LOCK(mylock);
91     if (protof == NULL)
92         protof = fopen(_PATH_PROTOCOLS, "r" );
93     else
94         rewind(protof);
95     if (f) proto_stayopen = 1;
96     __UCLIBC_MUTEX_UNLOCK(mylock);
97 }
98 libc_hidden_def(setprotoent)
99
100 void endprotoent(void)
101 {
102     __UCLIBC_MUTEX_LOCK(mylock);
103     if (protof) {
104         fclose(protof);
105         protof = NULL;
106     }
107     proto_stayopen = 0;
108     __UCLIBC_MUTEX_UNLOCK(mylock);
109 }
110 libc_hidden_def(endprotoent)
111
112 int getprotoent_r(struct protoent *result_buf,
113                   char *buf, size_t buflen,
114                   struct protoent **result)
115 {
116     char *p;
117     register char *cp, **q;
118     char **proto_aliases;
119     char *line;
120     int rv;
121
122     *result = NULL;
123
124     if (buflen < sizeof(*proto_aliases)*MAXALIASES) {
125         errno=ERANGE;
126         return errno;
127     }
128     __UCLIBC_MUTEX_LOCK(mylock);
129     proto_aliases=(char **)buf;
130     buf+=sizeof(*proto_aliases)*MAXALIASES;
131     buflen-=sizeof(*proto_aliases)*MAXALIASES;
132
133     if (buflen < BUFSIZ+1) {
134         errno=rv=ERANGE;
135         goto DONE;
136     }
137     line=buf;
138     buf+=BUFSIZ+1;
139     buflen-=BUFSIZ+1;
140
141     if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL) {
142         rv=errno;
143         goto DONE;
144     }
145 again:
146     if ((p = fgets(line, BUFSIZ, protof)) == NULL) {
147         rv=TRY_AGAIN;
148         goto DONE;
149     }
150
151     if (*p == '#')
152         goto again;
153     cp = strpbrk(p, "#\n");
154     if (cp == NULL)
155         goto again;
156     *cp = '\0';
157     result_buf->p_name = p;
158     cp = strpbrk(p, " \t");
159     if (cp == NULL)
160         goto again;
161     *cp++ = '\0';
162     while (*cp == ' ' || *cp == '\t')
163         cp++;
164     p = strpbrk(cp, " \t");
165     if (p != NULL)
166         *p++ = '\0';
167     result_buf->p_proto = atoi(cp);
168     q = result_buf->p_aliases = proto_aliases;
169     if (p != NULL) {
170         cp = p;
171         while (cp && *cp) {
172             if (*cp == ' ' || *cp == '\t') {
173                 cp++;
174                 continue;
175             }
176             if (q < &proto_aliases[MAXALIASES - 1])
177                 *q++ = cp;
178             cp = strpbrk(cp, " \t");
179             if (cp != NULL)
180                 *cp++ = '\0';
181         }
182     }
183     *q = NULL;
184     *result=result_buf;
185     rv = 0;
186 DONE:
187     __UCLIBC_MUTEX_UNLOCK(mylock);
188     return rv;
189 }
190 libc_hidden_def(getprotoent_r)
191
192 struct protoent * getprotoent(void)
193 {
194     struct protoent *result;
195
196     __initbuf();
197     getprotoent_r(&proto, static_aliases, SBUFSIZE, &result);
198     return result;
199 }
200
201
202 int getprotobyname_r(const char *name,
203                     struct protoent *result_buf,
204                     char *buf, size_t buflen,
205                     struct protoent **result)
206 {
207     register char **cp;
208     int ret;
209
210     __UCLIBC_MUTEX_LOCK(mylock);
211     setprotoent(proto_stayopen);
212     while (!(ret=getprotoent_r(result_buf, buf, buflen, result))) {
213         if (strcmp(result_buf->p_name, name) == 0)
214             break;
215         for (cp = result_buf->p_aliases; *cp != 0; cp++)
216             if (strcmp(*cp, name) == 0)
217                 goto found;
218     }
219 found:
220     if (!proto_stayopen)
221         endprotoent();
222     __UCLIBC_MUTEX_UNLOCK(mylock);
223     return *result?0:ret;
224 }
225 libc_hidden_def(getprotobyname_r)
226
227
228 struct protoent * getprotobyname(const char *name)
229 {
230     struct protoent *result;
231
232     __initbuf();
233     getprotobyname_r(name, &proto, static_aliases, SBUFSIZE, &result);
234     return result;
235 }
236
237
238 int getprotobynumber_r (int proto_num,
239                         struct protoent *result_buf,
240                         char *buf, size_t buflen,
241                         struct protoent **result)
242 {
243     int ret;
244
245     __UCLIBC_MUTEX_LOCK(mylock);
246     setprotoent(proto_stayopen);
247     while (!(ret=getprotoent_r(result_buf, buf, buflen, result)))
248         if (result_buf->p_proto == proto_num)
249             break;
250     if (!proto_stayopen)
251         endprotoent();
252     __UCLIBC_MUTEX_UNLOCK(mylock);
253     return *result?0:ret;
254 }
255 libc_hidden_def(getprotobynumber_r)
256
257 struct protoent * getprotobynumber(int proto_num)
258 {
259     struct protoent *result;
260
261     __initbuf();
262     getprotobynumber_r(proto_num, &proto, static_aliases,
263                        SBUFSIZE, &result);
264     return result;
265 }
266