1 /* $NetBSD: getservent_r.c,v 1.10 2010/04/25 00:54:46 joerg Exp $ */
4 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
33 #if defined(LIBC_SCCS) && !defined(lint)
35 static char sccsid
[] = "@(#)getservent.c 8.1 (Berkeley) 6/4/93";
37 __RCSID("$NetBSD: getservent_r.c,v 1.10 2010/04/25 00:54:46 joerg Exp $");
39 #endif /* LIBC_SCCS and not lint */
41 #include "namespace.h"
53 __weak_alias(endservent_r
,_endservent_r
)
54 __weak_alias(getservent_r
,_getservent_r
)
55 __weak_alias(setservent_r
,_setservent_r
)
59 _servent_open(struct servent_data
*sd
)
61 if (sd
->flags
& (_SV_CDB
| _SV_PLAINFILE
)) {
62 sd
->flags
|= _SV_FIRST
;
74 sd
->flags
|= _SV_FIRST
;
76 sd
->cdb
= cdbr_open(_PATH_SERVICES_CDB
, CDBR_DEFAULT
);
77 if (sd
->cdb
!= NULL
) {
82 sd
->plainfile
= fopen(_PATH_SERVICES
, "r");
83 if (sd
->plainfile
!= NULL
) {
84 sd
->flags
|= _SV_PLAINFILE
;
91 _servent_close(struct servent_data
*sd
)
93 if (sd
->flags
& _SV_CDB
) {
96 sd
->flags
&= ~_SV_CDB
;
99 if (sd
->flags
& _SV_PLAINFILE
) {
100 (void)fclose(sd
->plainfile
);
101 sd
->plainfile
= NULL
;
102 sd
->flags
&= ~_SV_PLAINFILE
;
104 sd
->flags
&= ~_SV_STAYOPEN
;
109 _servent_getline(struct servent_data
*sd
)
112 if (sd
->flags
& _SV_CDB
)
115 if ((sd
->flags
& _SV_PLAINFILE
) == 0)
121 if (sd
->flags
& _SV_FIRST
) {
122 (void)rewind((FILE *)sd
->plainfile
);
123 sd
->flags
&= ~_SV_FIRST
;
125 sd
->line
= fparseln(sd
->plainfile
, NULL
, NULL
, NULL
,
127 return sd
->line
== NULL
? -1 : 0;
131 _servent_parseline(struct servent_data
*sd
, struct servent
*sp
)
137 if (sd
->line
== NULL
)
140 sp
->s_name
= p
= sd
->line
;
141 p
= strpbrk(p
, " \t");
145 while (*p
== ' ' || *p
== '\t')
147 cp
= strpbrk(p
, ",/");
151 sp
->s_port
= htons((u_short
)atoi(p
));
153 if (sd
->aliases
== NULL
) {
155 sd
->aliases
= calloc(sd
->maxaliases
, sizeof(*sd
->aliases
));
156 if (sd
->aliases
== NULL
) {
163 sp
->s_aliases
= sd
->aliases
;
164 cp
= strpbrk(cp
, " \t");
168 if (*cp
== ' ' || *cp
== '\t') {
172 if (i
== sd
->maxaliases
- 2) {
174 q
= realloc(sd
->aliases
, sd
->maxaliases
* sizeof(*q
));
181 sp
->s_aliases
= sd
->aliases
= q
;
183 sp
->s_aliases
[i
++] = cp
;
184 cp
= strpbrk(cp
, " \t");
188 sp
->s_aliases
[i
] = NULL
;
193 setservent_r(int f
, struct servent_data
*sd
)
195 (void)_servent_open(sd
);
196 sd
->flags
|= f
? _SV_STAYOPEN
: 0;
200 endservent_r(struct servent_data
*sd
)
214 getservent_r(struct servent
*sp
, struct servent_data
*sd
)
217 if ((sd
->flags
& (_SV_CDB
| _SV_PLAINFILE
)) == 0 &&
218 _servent_open(sd
) == -1)
221 if (sd
->flags
& _SV_CDB
) {
225 if (sd
->flags
& _SV_FIRST
) {
227 sd
->flags
&= ~_SV_FIRST
;
230 if (cdbr_get(sd
->cdb
, sd
->cdb_index
, &data
, &len
))
233 return _servent_parsedb(sd
, sp
, data
, len
);
235 if (sd
->flags
& _SV_PLAINFILE
) {
237 if (_servent_getline(sd
) == -1)
239 if (_servent_parseline(sd
, sp
) == NULL
)
248 _servent_parsedb(struct servent_data
*sd
, struct servent
*sp
,
249 const uint8_t *data
, size_t len
)
255 if ((sd
->flags
& _SV_STAYOPEN
) == 0) {
256 if (len
> sd
->cdb_buf_len
) {
257 void *tmp
= realloc(sd
->cdb_buf
, len
);
261 sd
->cdb_buf_len
= len
;
263 memcpy(sd
->cdb_buf
, data
, len
);
269 sp
->s_port
= htobe16(be16dec(data
));
273 if (len
== 0 || len
< (size_t)data
[0] + 2)
275 sp
->s_proto
= __UNCONST(data
+ 1);
277 if (sp
->s_proto
[data
[0]] != '\0')
285 if (len
< (size_t)data
[0] + 2)
288 sp
->s_name
= __UNCONST(data
+ 1);
292 if (sd
->aliases
== NULL
) {
294 sd
->aliases
= malloc(sd
->maxaliases
* sizeof(char *));
295 if (sd
->aliases
== NULL
)
298 sp
->s_aliases
= sd
->aliases
;
301 if (len
< (size_t)data
[0] + 2)
303 if (i
== sd
->maxaliases
- 2) {
305 q
= realloc(sd
->aliases
, sd
->maxaliases
* sizeof(*q
));
308 sp
->s_aliases
= sd
->aliases
= q
;
310 sp
->s_aliases
[i
++] = __UNCONST(data
+ 1);
314 sp
->s_aliases
[i
] = NULL
;