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