2 ** services.c /etc/services access functions
4 ** This file is part of the NYS Library.
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.
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.
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.
22 ** Copyright (c) 1983 Regents of the University of California.
23 ** All rights reserved.
25 ** Redistribution and use in source and binary forms, with or without
26 ** modification, are permitted provided that the following conditions
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.
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
57 #include <sys/types.h>
58 #include <sys/socket.h>
63 #include <netinet/in.h>
64 #include <arpa/inet.h>
67 libc_hidden_proto(strcmp)
68 libc_hidden_proto(strpbrk)
69 libc_hidden_proto(fopen)
70 libc_hidden_proto(fclose)
71 libc_hidden_proto(atoi)
72 libc_hidden_proto(rewind)
73 libc_hidden_proto(fgets)
74 libc_hidden_proto(abort)
76 #ifdef __UCLIBC_HAS_THREADS__
78 static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
80 #define LOCK __pthread_mutex_lock(&mylock)
81 #define UNLOCK __pthread_mutex_unlock(&mylock)
87 #define SBUFSIZE (BUFSIZ + 1 + (sizeof(char *) * MAXALIASES))
89 static FILE *servf = NULL;
90 static struct servent serv;
91 static char *servbuf = NULL;
92 static int serv_stayopen;
94 static void __initbuf(void)
97 servbuf = malloc(SBUFSIZE);
103 void setservent(int f)
107 servf = fopen(_PATH_SERVICES, "r" );
113 libc_hidden_proto(setservent)
114 libc_hidden_def(setservent)
116 void endservent(void)
126 libc_hidden_proto(endservent)
127 libc_hidden_def(endservent)
129 int getservent_r(struct servent * result_buf,
130 char * buf, size_t buflen,
131 struct servent ** result)
134 register char *cp, **q;
140 if (buflen < sizeof(*serv_aliases)*MAXALIASES) {
145 serv_aliases=(char **)buf;
146 buf+=sizeof(*serv_aliases)*MAXALIASES;
147 buflen-=sizeof(*serv_aliases)*MAXALIASES;
149 if (buflen < BUFSIZ+1) {
158 if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL) {
164 if ((p = fgets(line, BUFSIZ, servf)) == NULL) {
171 cp = strpbrk(p, "#\n");
175 result_buf->s_name = p;
176 p = strpbrk(p, " \t");
180 while (*p == ' ' || *p == '\t')
182 cp = strpbrk(p, ",/");
186 result_buf->s_port = htons((u_short)atoi(p));
187 result_buf->s_proto = cp;
188 q = result_buf->s_aliases = serv_aliases;
189 cp = strpbrk(cp, " \t");
193 if (*cp == ' ' || *cp == '\t') {
197 if (q < &serv_aliases[MAXALIASES - 1])
199 cp = strpbrk(cp, " \t");
208 libc_hidden_proto(getservent_r)
209 libc_hidden_def(getservent_r)
211 struct servent * getservent(void)
213 struct servent *result;
216 getservent_r(&serv, servbuf, SBUFSIZE, &result);
220 int getservbyname_r(const char *name, const char *proto,
221 struct servent * result_buf, char * buf, size_t buflen,
222 struct servent ** result)
228 setservent(serv_stayopen);
229 while (!(ret=getservent_r(result_buf, buf, buflen, result))) {
230 if (strcmp(name, result_buf->s_name) == 0)
232 for (cp = result_buf->s_aliases; *cp; cp++)
233 if (strcmp(name, *cp) == 0)
237 if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
243 return *result?0:ret;
245 libc_hidden_proto(getservbyname_r)
246 libc_hidden_def(getservbyname_r)
248 struct servent *getservbyname(const char *name, const char *proto)
250 struct servent *result;
253 getservbyname_r(name, proto, &serv, servbuf, SBUFSIZE, &result);
258 int getservbyport_r(int port, const char *proto,
259 struct servent * result_buf, char * buf,
260 size_t buflen, struct servent ** result)
265 setservent(serv_stayopen);
266 while (!(ret=getservent_r(result_buf, buf, buflen, result))) {
267 if (result_buf->s_port != port)
269 if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
275 return *result?0:ret;
277 libc_hidden_proto(getservbyport_r)
278 libc_hidden_def(getservbyport_r)
280 struct servent * getservbyport(int port, const char *proto)
282 struct servent *result;
285 getservbyport_r(port, proto, &serv, servbuf, SBUFSIZE, &result);
288 libc_hidden_proto(getservbyport)
289 libc_hidden_def(getservbyport)