1 /* vi: set sw=4 ts=4: */
3 * Copyright (C) 2010 Bernhard Reutner-Fischer <uclibc@uclibc.org>
5 * Licensed under LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
9 # service-name port/protocol [aliases ...]
10 discard 9/udp sink null
12 service-name: case sensitive friendly name of the service
13 port: decimal port number
14 protocol: protocols(5) compatible entry
15 aliases: case sensitive optional space or tab separated list of other names
22 #include <netinet/in.h>
23 #include <arpa/inet.h>
26 #include "internal/parse_config.h"
28 #include <bits/uClibc_mutex.h>
29 __UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
32 #define MAXALIASES 8 /* we seldomly need more than 1 alias */
33 #define MAXTOKENS (MINTOKENS + MAXALIASES + 1)
34 #define BUFSZ (255) /* one line */
35 #define SBUFSIZE (BUFSZ + 1 + (sizeof(char *) * MAXTOKENS))
37 static parser_t *servp = NULL;
38 static struct servent serve;
39 static char *servbuf = NULL;
40 static size_t servbuf_sz = SBUFSIZE;
41 static smallint serv_stayopen;
43 void setservent(int stayopen)
45 __UCLIBC_MUTEX_LOCK(mylock);
48 servp = config_open(_PATH_SERVICES);
51 __UCLIBC_MUTEX_UNLOCK(mylock);
53 libc_hidden_def(setservent)
57 __UCLIBC_MUTEX_LOCK(mylock);
63 __UCLIBC_MUTEX_UNLOCK(mylock);
65 libc_hidden_def(endservent)
67 int getservent_r(struct servent *result_buf,
68 char *buf, size_t buflen, struct servent **result)
71 const size_t aliaslen = sizeof(char *) * MAXTOKENS;
76 || (buflen - aliaslen) < BUFSZ + 1)
79 __UCLIBC_MUTEX_LOCK(mylock);
82 setservent(serv_stayopen);
87 servp->data_len = aliaslen;
88 servp->line_len = buflen - aliaslen;
89 /* <name>[[:space:]]<port>/<proto>[[:space:]][<aliases>] */
90 if (!config_read(servp, &tok, MAXTOKENS - 1, MINTOKENS, "# \t/", PARSE_NORMAL)) {
93 result_buf->s_name = *(tok++);
94 result_buf->s_port = htons((u_short) atoi(*(tok++)));
95 result_buf->s_proto = *(tok++);
96 result_buf->s_aliases = tok;
100 __UCLIBC_MUTEX_UNLOCK(mylock);
105 libc_hidden_def(getservent_r)
107 static void __initbuf(void)
110 servbuf = malloc(SBUFSIZE);
115 struct servent *getservent(void)
117 struct servent *result;
120 getservent_r(&serve, servbuf, servbuf_sz, &result);
124 int getservbyname_r(const char *name, const char *proto,
125 struct servent *result_buf, char *buf, size_t buflen,
126 struct servent **result)
131 __UCLIBC_MUTEX_LOCK(mylock);
132 setservent(serv_stayopen);
133 while (!(ret = getservent_r(result_buf, buf, buflen, result))) {
134 if (strcmp(name, result_buf->s_name) == 0)
136 for (cp = result_buf->s_aliases; *cp; cp++)
137 if (strcmp(name, *cp) == 0)
141 if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
146 __UCLIBC_MUTEX_UNLOCK(mylock);
147 return *result ? 0 : ret;
149 libc_hidden_def(getservbyname_r)
151 struct servent *getservbyname(const char *name, const char *proto)
153 struct servent *result;
156 getservbyname_r(name, proto, &serve, servbuf, servbuf_sz, &result);
161 int getservbyport_r(int port, const char *proto,
162 struct servent *result_buf, char *buf,
163 size_t buflen, struct servent **result)
167 __UCLIBC_MUTEX_LOCK(mylock);
168 setservent(serv_stayopen);
169 while (!(ret = getservent_r(result_buf, buf, buflen, result))) {
170 if (result_buf->s_port != port)
172 if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
177 __UCLIBC_MUTEX_UNLOCK(mylock);
178 return *result ? 0 : ret;
180 libc_hidden_def(getservbyport_r)
182 struct servent *getservbyport(int port, const char *proto)
184 struct servent *result;
187 getservbyport_r(port, proto, &serve, servbuf, servbuf_sz, &result);
190 libc_hidden_def(getservbyport)