blob: c59da7e66deddd1d4f0f6761c19eb8e0f70bc3e1 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/* vi: set sw=4 ts=4: */
2/*
3 * Copyright (C) 2010 Bernhard Reutner-Fischer <uclibc@uclibc.org>
4 *
5 * Licensed under LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
6 */
7
8/* /etc/protocols
9# protocol-name number [aliases ...]
10ip 0 IP # internet protocol, pseudo protocol number
11
12protocol-name: case sensitive friendly name of the IP protocol
13number: decimal protocol number
14aliases: case sensitive optional space or tab separated list of other names
15*/
16
17#include <features.h>
18#include <netdb.h>
19#include <string.h>
20#include <stdlib.h>
21#include <netinet/in.h>
22#include <arpa/inet.h>
23#include <errno.h>
24#include <unistd.h>
25#include "internal/parse_config.h"
26
27#include <bits/uClibc_mutex.h>
28__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
29
30#define MINTOKENS 2
31#define MAXALIASES 8 /* will probably never be more than one */
32#define MAXTOKENS (MINTOKENS + MAXALIASES + 1)
33#define BUFSZ (255) /* one line */
34#define SBUFSIZE (BUFSZ + 1 + (sizeof(char *) * MAXTOKENS))
35
36static parser_t *protop = NULL;
37static struct protoent protoe;
38static char *protobuf = NULL;
39static smallint proto_stayopen;
40
41void setprotoent(int stayopen)
42{
43 __UCLIBC_MUTEX_LOCK(mylock);
44 if (protop)
45 config_close(protop);
46 protop = config_open(_PATH_PROTOCOLS);
47 if (stayopen)
48 proto_stayopen = 1;
49 __UCLIBC_MUTEX_UNLOCK(mylock);
50}
51libc_hidden_def(setprotoent)
52
53void endprotoent(void)
54{
55 __UCLIBC_MUTEX_LOCK(mylock);
56 if (protop) {
57 config_close(protop);
58 protop = NULL;
59 }
60 proto_stayopen = 0;
61 __UCLIBC_MUTEX_UNLOCK(mylock);
62}
63libc_hidden_def(endprotoent)
64
65int getprotoent_r(struct protoent *result_buf,
66 char *buf, size_t buflen, struct protoent **result)
67{
68 char **tok = NULL;
69 const size_t aliaslen = sizeof(char *) * MAXTOKENS;
70 int ret = ERANGE;
71
72 *result = NULL;
73 if (buflen < aliaslen
74 || (buflen - aliaslen) < BUFSZ + 1)
75 goto DONE_NOUNLOCK;
76
77 __UCLIBC_MUTEX_LOCK(mylock);
78 //tok = (char **) buf;
79 ret = ENOENT;
80 if (protop == NULL)
81 setprotoent(proto_stayopen);
82 if (protop == NULL)
83 goto DONE;
84 protop->data = buf;
85 protop->data_len = aliaslen;
86 protop->line_len = buflen - aliaslen;
87 /* <name>[[:space:]]<protonumber>[[:space:]][<aliases>] */
88 if (!config_read(protop, &tok, MAXTOKENS - 1, MINTOKENS, "# \t/", PARSE_NORMAL)) {
89 goto DONE;
90 }
91 result_buf->p_name = *(tok++);
92 result_buf->p_proto = atoi(*(tok++));
93 result_buf->p_aliases = tok;
94 *result = result_buf;
95 ret = 0;
96 DONE:
97 __UCLIBC_MUTEX_UNLOCK(mylock);
98 DONE_NOUNLOCK:
99 errno = ret;
100 return errno;
101}
102libc_hidden_def(getprotoent_r)
103
104static void __initbuf(void)
105{
106 if (!protobuf) {
107 protobuf = malloc(SBUFSIZE);
108 if (!protobuf)
109 abort();
110 }
111}
112
113struct protoent *getprotoent(void)
114{
115 struct protoent *result;
116
117 __initbuf();
118 getprotoent_r(&protoe, protobuf, SBUFSIZE, &result);
119 return result;
120}
121
122int getprotobyname_r(const char *name,
123 struct protoent *result_buf, char *buf, size_t buflen,
124 struct protoent **result)
125{
126 register char **cp;
127 int ret;
128
129 __UCLIBC_MUTEX_LOCK(mylock);
130 setprotoent(proto_stayopen);
131 while (!(ret = getprotoent_r(result_buf, buf, buflen, result))) {
132 if (strcmp(name, result_buf->p_name) == 0)
133 break;
134 for (cp = result_buf->p_aliases; *cp; cp++)
135 if (strcmp(name, *cp) == 0)
136 goto gotname;
137 }
138 gotname:
139 if (!proto_stayopen)
140 endprotoent();
141 __UCLIBC_MUTEX_UNLOCK(mylock);
142 return *result ? 0 : ret;
143}
144libc_hidden_def(getprotobyname_r)
145
146struct protoent *getprotobyname(const char *name)
147{
148 struct protoent *result;
149
150 __initbuf();
151 getprotobyname_r(name, &protoe, protobuf, SBUFSIZE, &result);
152 return result;
153}
154
155int getprotobynumber_r(int proto,
156 struct protoent *result_buf, char *buf,
157 size_t buflen, struct protoent **result)
158{
159 int ret;
160
161 __UCLIBC_MUTEX_LOCK(mylock);
162 setprotoent(proto_stayopen);
163 while (!(ret = getprotoent_r(result_buf, buf, buflen, result))) {
164 if (proto == result_buf->p_proto)
165 break;
166 }
167 if (!proto_stayopen)
168 endprotoent();
169 __UCLIBC_MUTEX_UNLOCK(mylock);
170 return *result ? 0 : ret;
171}
172libc_hidden_def(getprotobynumber_r)
173
174struct protoent *getprotobynumber(int proto)
175{
176 struct protoent *result;
177
178 __initbuf();
179 getprotobynumber_r(proto, &protoe, protobuf, SBUFSIZE, &result);
180 return result;
181}
182