tcp: Fix 64 bit build with debugging features enabled.
[haiku.git] / src / kits / network / netresolv / irs / lcl_sv.cpp
blobcece2d2690f5dd933668f585d13d098e322e3388
1 /*
2 * Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 */
6 /*
7 * Copyright (c) 1989, 1993, 1995
8 * The Regents of the University of California. All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
40 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
41 * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
43 * Permission to use, copy, modify, and distribute this software for any
44 * purpose with or without fee is hereby granted, provided that the above
45 * copyright notice and this permission notice appear in all copies.
47 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
48 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
49 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
50 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
51 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
52 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
53 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
57 #include "port_before.h"
59 extern "C" {
60 // libbind's internal headers aren't C++ safe
62 #include "irs_p.h"
63 #include "lcl_p.h"
65 #define private private_data
66 #include <irs.h>
67 #undef private
69 #include <isc/memcluster.h>
73 #include <sys/types.h>
74 #include <sys/socket.h>
75 #include <netinet/in.h>
76 #include <arpa/nameser.h>
77 #include <resolv.h>
79 #include "port_after.h"
81 #include <errno.h>
82 #include <fcntl.h>
83 #include <limits.h>
84 #include <stdio.h>
85 #include <string.h>
86 #include <stdlib.h>
88 #include <FindDirectory.h>
89 #include <fs_attr.h>
90 #include <image.h>
91 #include <TypeConstants.h>
94 #define IRS_SV_MAXALIASES 35
96 struct service_private {
97 FILE* file;
98 char line[BUFSIZ + 1];
99 struct servent servent;
100 char* aliases[IRS_SV_MAXALIASES];
104 static status_t
105 find_own_image(image_info* _info)
107 int32 cookie = 0;
108 image_info info;
109 while (get_next_image_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) {
110 if (((addr_t)info.text <= (addr_t)find_own_image
111 && (addr_t)info.text + (size_t)info.text_size
112 > (addr_t)find_own_image)) {
113 // found us
114 *_info = info;
115 return B_OK;
119 return B_ENTRY_NOT_FOUND;
123 static char*
124 get_next_line(struct service_private* service)
126 if (service->file == NULL)
127 return NULL;
128 return fgets(service->line, BUFSIZ, service->file);
132 // #pragma mark -
135 static void
136 sv_close(struct irs_sv *sv)
138 struct service_private *service = (struct service_private *)sv->private_data;
140 if (service->file)
141 fclose(service->file);
143 memput(service, sizeof *service);
144 memput(sv, sizeof *sv);
148 static void
149 sv_rewind(struct irs_sv *sv)
151 struct service_private *service
152 = (struct service_private *)sv->private_data;
154 if (service->file) {
155 if (fseek(service->file, 0L, SEEK_SET) == 0)
156 return;
157 fclose(service->file);
158 service->file = NULL;
161 char path[PATH_MAX];
162 if (find_directory(B_SYSTEM_DATA_DIRECTORY, -1, false, path, sizeof(path))
163 == B_OK) {
164 strlcat(path, "/network/services", sizeof(path));
166 if ((service->file = fopen(path, "r")) != NULL) {
167 if (fcntl(fileno(service->file), F_SETFD, FD_CLOEXEC) == 0)
168 return;
170 fclose(service->file);
171 service->file = NULL;
175 // opening the standard file has file has failed, use the attribute
177 // find our library image
178 image_info info;
179 if (find_own_image(&info) != B_OK)
180 return;
182 // open the library
183 int libraryFD = open(info.name, O_RDONLY);
184 if (libraryFD < 0)
185 return;
187 // open the attribute
188 int attrFD = fs_fopen_attr(libraryFD, "services", B_STRING_TYPE, O_RDONLY);
189 close(libraryFD);
190 if (attrFD < 0)
191 return;
193 // attach it to a FILE
194 service->file = fdopen(attrFD, "r");
195 if (service->file == NULL) {
196 close(attrFD);
197 return;
200 if (fcntl(fileno(service->file), F_SETFD, FD_CLOEXEC) == 0)
201 return;
203 fclose(service->file);
204 service->file = NULL;
208 static struct servent *
209 sv_next(struct irs_sv *sv)
211 struct service_private *service = (struct service_private *)sv->private_data;
212 char *p, *cp, **q;
214 if (service->file == NULL)
215 sv_rewind(sv);
217 if (service->file == NULL)
218 return NULL;
220 again:
221 if ((p = get_next_line(service)) == NULL)
222 return NULL;
224 if (*p == '#')
225 goto again;
227 service->servent.s_name = p;
228 while (*p && *p != '\n' && *p != ' ' && *p != '\t' && *p != '#')
229 ++p;
230 if (*p == '\0' || *p == '#' || *p == '\n')
231 goto again;
232 *p++ = '\0';
233 while (*p == ' ' || *p == '\t')
234 p++;
235 if (*p == '\0' || *p == '#' || *p == '\n')
236 goto again;
237 service->servent.s_port = htons((u_short)strtol(p, &cp, 10));
238 if (cp == p || (*cp != '/' && *cp != ','))
239 goto again;
240 p = cp + 1;
241 service->servent.s_proto = p;
243 q = service->servent.s_aliases = service->aliases;
245 while (*p && *p != '\n' && *p != ' ' && *p != '\t' && *p != '#')
246 ++p;
248 while (*p == ' ' || *p == '\t') {
249 *p++ = '\0';
250 while (*p == ' ' || *p == '\t')
251 ++p;
252 if (*p == '\0' || *p == '#' || *p == '\n')
253 break;
254 if (q < &service->aliases[IRS_SV_MAXALIASES - 1])
255 *q++ = p;
256 while (*p && *p != '\n' && *p != ' ' && *p != '\t' && *p != '#')
257 ++p;
260 *p = '\0';
261 *q = NULL;
262 return &service->servent;
266 static struct servent *
267 sv_byname(struct irs_sv *sv, const char *name, const char *protocol)
269 struct servent *servent;
271 sv_rewind(sv);
273 while ((servent = sv_next(sv))) {
274 char **alias;
276 if (!strcmp(name, servent->s_name))
277 goto gotname;
278 for (alias = servent->s_aliases; *alias; alias++) {
279 if (!strcmp(name, *alias))
280 goto gotname;
282 continue;
283 gotname:
284 if (protocol == NULL || strcmp(servent->s_proto, protocol) == 0)
285 break;
287 return servent;
291 static struct servent *
292 sv_byport(struct irs_sv *sv, int port, const char *protocol)
294 struct servent *servent;
296 sv_rewind(sv);
297 while ((servent = sv_next(sv))) {
298 if (servent->s_port != port)
299 continue;
300 if (protocol == NULL || strcmp(servent->s_proto, protocol) == 0)
301 break;
303 return servent;
307 static void
308 sv_minimize(struct irs_sv *sv)
310 struct service_private *service = (struct service_private *)sv->private_data;
312 if (service->file != NULL) {
313 fclose(service->file);
314 service->file = NULL;
319 // #pragma mark -
322 extern "C" struct irs_sv *
323 irs_lcl_sv(struct irs_acc */*acc*/)
325 struct service_private *service;
326 struct irs_sv *sv;
328 if ((sv = (irs_sv *)memget(sizeof *sv)) == NULL) {
329 errno = ENOMEM;
330 return NULL;
332 if ((service = (service_private *)memget(sizeof *service)) == NULL) {
333 memput(sv, sizeof *sv);
334 errno = ENOMEM;
335 return NULL;
338 memset(service, 0, sizeof *service);
340 sv->private_data = service;
341 sv->close = sv_close;
342 sv->next = sv_next;
343 sv->byname = sv_byname;
344 sv->byport = sv_byport;
345 sv->rewind = sv_rewind;
346 sv->minimize = sv_minimize;
347 sv->res_get = NULL;
348 sv->res_set = NULL;
350 return sv;