xref: /netbsd-src/external/bsd/libbind/dist/irs/getservent_r.c (revision 5bbd2a12505d72a8177929a37b5cee489d0a1cfd)
1*5bbd2a12Schristos /*	$NetBSD: getservent_r.c,v 1.1.1.2 2012/09/09 16:07:59 christos Exp $	*/
2b5677b36Schristos 
3b5677b36Schristos /*
4b5677b36Schristos  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5b5677b36Schristos  * Copyright (c) 1998-1999 by Internet Software Consortium.
6b5677b36Schristos  *
7b5677b36Schristos  * Permission to use, copy, modify, and distribute this software for any
8b5677b36Schristos  * purpose with or without fee is hereby granted, provided that the above
9b5677b36Schristos  * copyright notice and this permission notice appear in all copies.
10b5677b36Schristos  *
11b5677b36Schristos  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
12b5677b36Schristos  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13b5677b36Schristos  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
14b5677b36Schristos  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15b5677b36Schristos  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16b5677b36Schristos  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17b5677b36Schristos  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18b5677b36Schristos  */
19b5677b36Schristos 
20b5677b36Schristos #if defined(LIBC_SCCS) && !defined(lint)
21b5677b36Schristos static const char rcsid[] = "Id: getservent_r.c,v 1.6 2006/08/01 01:14:16 marka Exp ";
22b5677b36Schristos #endif /* LIBC_SCCS and not lint */
23b5677b36Schristos 
24b5677b36Schristos #include <port_before.h>
25b5677b36Schristos #if !defined(_REENTRANT) || !defined(DO_PTHREADS)
26b5677b36Schristos 	static int getservent_r_not_required = 0;
27b5677b36Schristos #else
28b5677b36Schristos #include <errno.h>
29b5677b36Schristos #include <string.h>
30b5677b36Schristos #include <stdio.h>
31b5677b36Schristos #include <sys/types.h>
32b5677b36Schristos #include <netinet/in.h>
33b5677b36Schristos #include <netdb.h>
34b5677b36Schristos #include <sys/param.h>
35b5677b36Schristos #include <port_after.h>
36b5677b36Schristos 
37b5677b36Schristos #ifdef SERV_R_RETURN
38b5677b36Schristos 
39b5677b36Schristos static SERV_R_RETURN
40b5677b36Schristos copy_servent(struct servent *, struct servent *, SERV_R_COPY_ARGS);
41b5677b36Schristos 
42b5677b36Schristos SERV_R_RETURN
getservbyname_r(const char * name,const char * proto,struct servent * sptr,SERV_R_ARGS)43b5677b36Schristos getservbyname_r(const char *name, const char *proto,
44b5677b36Schristos 		struct servent *sptr, SERV_R_ARGS) {
45b5677b36Schristos 	struct servent *se = getservbyname(name, proto);
46b5677b36Schristos #ifdef SERV_R_SETANSWER
47b5677b36Schristos 	int n = 0;
48b5677b36Schristos 
49b5677b36Schristos 	if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0)
50b5677b36Schristos 		*answerp = NULL;
51b5677b36Schristos 	else
52b5677b36Schristos 		*answerp = sptr;
53b5677b36Schristos 
54b5677b36Schristos 	return (n);
55b5677b36Schristos #else
56b5677b36Schristos 	if (se == NULL)
57b5677b36Schristos 		return (SERV_R_BAD);
58b5677b36Schristos 
59b5677b36Schristos 	return (copy_servent(se, sptr, SERV_R_COPY));
60b5677b36Schristos #endif
61b5677b36Schristos }
62b5677b36Schristos 
63b5677b36Schristos SERV_R_RETURN
getservbyport_r(int port,const char * proto,struct servent * sptr,SERV_R_ARGS)64b5677b36Schristos getservbyport_r(int port, const char *proto,
65b5677b36Schristos 		struct servent *sptr, SERV_R_ARGS) {
66b5677b36Schristos 	struct servent *se = getservbyport(port, proto);
67b5677b36Schristos #ifdef SERV_R_SETANSWER
68b5677b36Schristos 	int n = 0;
69b5677b36Schristos 
70b5677b36Schristos 	if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0)
71b5677b36Schristos 		*answerp = NULL;
72b5677b36Schristos 	else
73b5677b36Schristos 		*answerp = sptr;
74b5677b36Schristos 
75b5677b36Schristos 	return (n);
76b5677b36Schristos #else
77b5677b36Schristos 	if (se == NULL)
78b5677b36Schristos 		return (SERV_R_BAD);
79b5677b36Schristos 
80b5677b36Schristos 	return (copy_servent(se, sptr, SERV_R_COPY));
81b5677b36Schristos #endif
82b5677b36Schristos }
83b5677b36Schristos 
84b5677b36Schristos /*%
85b5677b36Schristos  *	These assume a single context is in operation per thread.
86b5677b36Schristos  *	If this is not the case we will need to call irs directly
87b5677b36Schristos  *	rather than through the base functions.
88b5677b36Schristos  */
89b5677b36Schristos 
90b5677b36Schristos SERV_R_RETURN
getservent_r(struct servent * sptr,SERV_R_ARGS)91b5677b36Schristos getservent_r(struct servent *sptr, SERV_R_ARGS) {
92b5677b36Schristos 	struct servent *se = getservent();
93b5677b36Schristos #ifdef SERV_R_SETANSWER
94b5677b36Schristos 	int n = 0;
95b5677b36Schristos 
96b5677b36Schristos 	if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0)
97b5677b36Schristos 		*answerp = NULL;
98b5677b36Schristos 	else
99b5677b36Schristos 		*answerp = sptr;
100b5677b36Schristos 
101b5677b36Schristos 	return (n);
102b5677b36Schristos #else
103b5677b36Schristos 	if (se == NULL)
104b5677b36Schristos 		return (SERV_R_BAD);
105b5677b36Schristos 
106b5677b36Schristos 	return (copy_servent(se, sptr, SERV_R_COPY));
107b5677b36Schristos #endif
108b5677b36Schristos }
109b5677b36Schristos 
110b5677b36Schristos SERV_R_SET_RETURN
111b5677b36Schristos #ifdef SERV_R_ENT_ARGS
setservent_r(int stay_open,SERV_R_ENT_ARGS)112b5677b36Schristos setservent_r(int stay_open, SERV_R_ENT_ARGS)
113b5677b36Schristos #else
114b5677b36Schristos setservent_r(int stay_open)
115b5677b36Schristos #endif
116b5677b36Schristos {
117b5677b36Schristos #ifdef SERV_R_ENT_UNUSED
118b5677b36Schristos 	SERV_R_ENT_UNUSED;
119b5677b36Schristos #endif
120b5677b36Schristos 	setservent(stay_open);
121b5677b36Schristos #ifdef SERV_R_SET_RESULT
122b5677b36Schristos 	return (SERV_R_SET_RESULT);
123b5677b36Schristos #endif
124b5677b36Schristos }
125b5677b36Schristos 
126b5677b36Schristos SERV_R_END_RETURN
127b5677b36Schristos #ifdef SERV_R_ENT_ARGS
endservent_r(SERV_R_ENT_ARGS)128b5677b36Schristos endservent_r(SERV_R_ENT_ARGS)
129b5677b36Schristos #else
130b5677b36Schristos endservent_r()
131b5677b36Schristos #endif
132b5677b36Schristos {
133b5677b36Schristos #ifdef SERV_R_ENT_UNUSED
134b5677b36Schristos 	SERV_R_ENT_UNUSED;
135b5677b36Schristos #endif
136b5677b36Schristos 	endservent();
137b5677b36Schristos 	SERV_R_END_RESULT(SERV_R_OK);
138b5677b36Schristos }
139b5677b36Schristos 
140b5677b36Schristos /* Private */
141b5677b36Schristos 
142b5677b36Schristos #ifndef SERVENT_DATA
143b5677b36Schristos static SERV_R_RETURN
copy_servent(struct servent * se,struct servent * sptr,SERV_R_COPY_ARGS)144b5677b36Schristos copy_servent(struct servent *se, struct servent *sptr, SERV_R_COPY_ARGS) {
145b5677b36Schristos 	char *cp;
146b5677b36Schristos 	int i, n;
147b5677b36Schristos 	int numptr, len;
148b5677b36Schristos 
149b5677b36Schristos 	/* Find out the amount of space required to store the answer. */
150b5677b36Schristos 	numptr = 1; /*%< NULL ptr */
151b5677b36Schristos 	len = (char *)ALIGN(buf) - buf;
152b5677b36Schristos 	for (i = 0; se->s_aliases[i]; i++, numptr++) {
153b5677b36Schristos 		len += strlen(se->s_aliases[i]) + 1;
154b5677b36Schristos 	}
155b5677b36Schristos 	len += strlen(se->s_name) + 1;
156b5677b36Schristos 	len += strlen(se->s_proto) + 1;
157b5677b36Schristos 	len += numptr * sizeof(char*);
158b5677b36Schristos 
159b5677b36Schristos 	if (len > (int)buflen) {
160b5677b36Schristos 		errno = ERANGE;
161b5677b36Schristos 		return (SERV_R_BAD);
162b5677b36Schristos 	}
163b5677b36Schristos 
164b5677b36Schristos 	/* copy port value */
165b5677b36Schristos 	sptr->s_port = se->s_port;
166b5677b36Schristos 
167b5677b36Schristos 	cp = (char *)ALIGN(buf) + numptr * sizeof(char *);
168b5677b36Schristos 
169b5677b36Schristos 	/* copy official name */
170b5677b36Schristos 	n = strlen(se->s_name) + 1;
171b5677b36Schristos 	strcpy(cp, se->s_name);
172b5677b36Schristos 	sptr->s_name = cp;
173b5677b36Schristos 	cp += n;
174b5677b36Schristos 
175b5677b36Schristos 	/* copy aliases */
176b5677b36Schristos 	sptr->s_aliases = (char **)ALIGN(buf);
177b5677b36Schristos 	for (i = 0 ; se->s_aliases[i]; i++) {
178b5677b36Schristos 		n = strlen(se->s_aliases[i]) + 1;
179b5677b36Schristos 		strcpy(cp, se->s_aliases[i]);
180b5677b36Schristos 		sptr->s_aliases[i] = cp;
181b5677b36Schristos 		cp += n;
182b5677b36Schristos 	}
183b5677b36Schristos 	sptr->s_aliases[i] = NULL;
184b5677b36Schristos 
185b5677b36Schristos 	/* copy proto */
186b5677b36Schristos 	n = strlen(se->s_proto) + 1;
187b5677b36Schristos 	strcpy(cp, se->s_proto);
188b5677b36Schristos 	sptr->s_proto = cp;
189b5677b36Schristos 	cp += n;
190b5677b36Schristos 
191b5677b36Schristos 	return (SERV_R_OK);
192b5677b36Schristos }
193b5677b36Schristos #else /* !SERVENT_DATA */
194b5677b36Schristos static int
copy_servent(struct servent * se,struct servent * sptr,SERV_R_COPY_ARGS)195b5677b36Schristos copy_servent(struct servent *se, struct servent *sptr, SERV_R_COPY_ARGS) {
196b5677b36Schristos 	char *cp, *eob;
197b5677b36Schristos 	int i, n;
198b5677b36Schristos 
199b5677b36Schristos 	/* copy port value */
200b5677b36Schristos 	sptr->s_port = se->s_port;
201b5677b36Schristos 
202b5677b36Schristos 	/* copy official name */
203b5677b36Schristos 	cp = sdptr->line;
204b5677b36Schristos 	eob = sdptr->line + sizeof(sdptr->line);
205b5677b36Schristos 	if ((n = strlen(se->s_name) + 1) < (eob - cp)) {
206b5677b36Schristos 		strcpy(cp, se->s_name);
207b5677b36Schristos 		sptr->s_name = cp;
208b5677b36Schristos 		cp += n;
209b5677b36Schristos 	} else {
210b5677b36Schristos 		return (-1);
211b5677b36Schristos 	}
212b5677b36Schristos 
213b5677b36Schristos 	/* copy aliases */
214b5677b36Schristos 	i = 0;
215b5677b36Schristos 	sptr->s_aliases = sdptr->serv_aliases;
216b5677b36Schristos 	while (se->s_aliases[i] && i < (_MAXALIASES-1)) {
217b5677b36Schristos 		if ((n = strlen(se->s_aliases[i]) + 1) < (eob - cp)) {
218b5677b36Schristos 			strcpy(cp, se->s_aliases[i]);
219b5677b36Schristos 			sptr->s_aliases[i] = cp;
220b5677b36Schristos 			cp += n;
221b5677b36Schristos 		} else {
222b5677b36Schristos 			break;
223b5677b36Schristos 		}
224b5677b36Schristos 		i++;
225b5677b36Schristos 	}
226b5677b36Schristos 	sptr->s_aliases[i] = NULL;
227b5677b36Schristos 
228b5677b36Schristos 	/* copy proto */
229b5677b36Schristos 	if ((n = strlen(se->s_proto) + 1) < (eob - cp)) {
230b5677b36Schristos 		strcpy(cp, se->s_proto);
231b5677b36Schristos 		sptr->s_proto = cp;
232b5677b36Schristos 		cp += n;
233b5677b36Schristos 	} else {
234b5677b36Schristos 		return (-1);
235b5677b36Schristos 	}
236b5677b36Schristos 
237b5677b36Schristos 	return (SERV_R_OK);
238b5677b36Schristos }
239b5677b36Schristos #endif /* !SERVENT_DATA */
240b5677b36Schristos #else /*SERV_R_RETURN */
241b5677b36Schristos 	static int getservent_r_unknown_system = 0;
242b5677b36Schristos #endif /*SERV_R_RETURN */
243b5677b36Schristos #endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
244b5677b36Schristos /*! \file */
245