2 * Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
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
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
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"
60 // libbind's internal headers aren't C++ safe
65 #define private private_data
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>
79 #include "port_after.h"
88 #include <FindDirectory.h>
91 #include <TypeConstants.h>
94 #define IRS_SV_MAXALIASES 35
96 struct service_private
{
98 char line
[BUFSIZ
+ 1];
99 struct servent servent
;
100 char* aliases
[IRS_SV_MAXALIASES
];
105 find_own_image(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
)) {
119 return B_ENTRY_NOT_FOUND
;
124 get_next_line(struct service_private
* service
)
126 if (service
->file
== NULL
)
128 return fgets(service
->line
, BUFSIZ
, service
->file
);
136 sv_close(struct irs_sv
*sv
)
138 struct service_private
*service
= (struct service_private
*)sv
->private_data
;
141 fclose(service
->file
);
143 memput(service
, sizeof *service
);
144 memput(sv
, sizeof *sv
);
149 sv_rewind(struct irs_sv
*sv
)
151 struct service_private
*service
152 = (struct service_private
*)sv
->private_data
;
155 if (fseek(service
->file
, 0L, SEEK_SET
) == 0)
157 fclose(service
->file
);
158 service
->file
= NULL
;
162 if (find_directory(B_SYSTEM_DATA_DIRECTORY
, -1, false, path
, sizeof(path
))
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)
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
179 if (find_own_image(&info
) != B_OK
)
183 int libraryFD
= open(info
.name
, O_RDONLY
);
187 // open the attribute
188 int attrFD
= fs_fopen_attr(libraryFD
, "services", B_STRING_TYPE
, O_RDONLY
);
193 // attach it to a FILE
194 service
->file
= fdopen(attrFD
, "r");
195 if (service
->file
== NULL
) {
200 if (fcntl(fileno(service
->file
), F_SETFD
, FD_CLOEXEC
) == 0)
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
;
214 if (service
->file
== NULL
)
217 if (service
->file
== NULL
)
221 if ((p
= get_next_line(service
)) == NULL
)
227 service
->servent
.s_name
= p
;
228 while (*p
&& *p
!= '\n' && *p
!= ' ' && *p
!= '\t' && *p
!= '#')
230 if (*p
== '\0' || *p
== '#' || *p
== '\n')
233 while (*p
== ' ' || *p
== '\t')
235 if (*p
== '\0' || *p
== '#' || *p
== '\n')
237 service
->servent
.s_port
= htons((u_short
)strtol(p
, &cp
, 10));
238 if (cp
== p
|| (*cp
!= '/' && *cp
!= ','))
241 service
->servent
.s_proto
= p
;
243 q
= service
->servent
.s_aliases
= service
->aliases
;
245 while (*p
&& *p
!= '\n' && *p
!= ' ' && *p
!= '\t' && *p
!= '#')
248 while (*p
== ' ' || *p
== '\t') {
250 while (*p
== ' ' || *p
== '\t')
252 if (*p
== '\0' || *p
== '#' || *p
== '\n')
254 if (q
< &service
->aliases
[IRS_SV_MAXALIASES
- 1])
256 while (*p
&& *p
!= '\n' && *p
!= ' ' && *p
!= '\t' && *p
!= '#')
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
;
273 while ((servent
= sv_next(sv
))) {
276 if (!strcmp(name
, servent
->s_name
))
278 for (alias
= servent
->s_aliases
; *alias
; alias
++) {
279 if (!strcmp(name
, *alias
))
284 if (protocol
== NULL
|| strcmp(servent
->s_proto
, protocol
) == 0)
291 static struct servent
*
292 sv_byport(struct irs_sv
*sv
, int port
, const char *protocol
)
294 struct servent
*servent
;
297 while ((servent
= sv_next(sv
))) {
298 if (servent
->s_port
!= port
)
300 if (protocol
== NULL
|| strcmp(servent
->s_proto
, protocol
) == 0)
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
;
322 extern "C" struct irs_sv
*
323 irs_lcl_sv(struct irs_acc */
*acc*/
)
325 struct service_private
*service
;
328 if ((sv
= (irs_sv
*)memget(sizeof *sv
)) == NULL
) {
332 if ((service
= (service_private
*)memget(sizeof *service
)) == NULL
) {
333 memput(sv
, sizeof *sv
);
338 memset(service
, 0, sizeof *service
);
340 sv
->private_data
= service
;
341 sv
->close
= sv_close
;
343 sv
->byname
= sv_byname
;
344 sv
->byport
= sv_byport
;
345 sv
->rewind
= sv_rewind
;
346 sv
->minimize
= sv_minimize
;