]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libc/net/getnetbyht.c
libc: only export hesiod symbols when enabled
[FreeBSD/FreeBSD.git] / lib / libc / net / getnetbyht.c
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 1983, 1993
5  *      The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
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.
18  *
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
29  * SUCH DAMAGE.
30  */
31
32 /* Portions Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
33  *      Dep. Matematica Universidade de Coimbra, Portugal, Europe
34  *
35  * Permission to use, copy, modify, and distribute this software for any
36  * purpose with or without fee is hereby granted, provided that the above
37  * copyright notice and this permission notice appear in all copies.
38  *
39  * from getnetent.c     1.1 (Coimbra) 93/06/02
40  */
41
42 #include <sys/types.h>
43 #include <sys/socket.h>
44 #include <netinet/in.h>
45 #include <arpa/inet.h>
46 #include <arpa/nameser.h>
47 #include <errno.h>
48 #include <netdb.h>
49 #include <resolv.h>
50 #include <stdio.h>
51 #include <string.h>
52 #include <stdarg.h>
53 #include <nsswitch.h>
54 #include "netdb_private.h"
55
56 void
57 _setnethtent(int f, struct netent_data *ned)
58 {
59
60         if (ned->netf == NULL)
61                 ned->netf = fopen(_PATH_NETWORKS, "re");
62         else
63                 rewind(ned->netf);
64         ned->stayopen |= f;
65 }
66
67 void
68 _endnethtent(struct netent_data *ned)
69 {
70
71         if (ned->netf) {
72                 fclose(ned->netf);
73                 ned->netf = NULL;
74         }
75         ned->stayopen = 0;
76 }
77
78 static int
79 getnetent_p(struct netent *ne, struct netent_data *ned)
80 {
81         char *p, *bp, *ep;
82         char *cp, **q;
83         int len;
84         char line[BUFSIZ + 1];
85
86         if (ned->netf == NULL &&
87             (ned->netf = fopen(_PATH_NETWORKS, "re")) == NULL)
88                 return (-1);
89 again:
90         p = fgets(line, sizeof line, ned->netf);
91         if (p == NULL)
92                 return (-1);
93         if (*p == '#')
94                 goto again;
95         cp = strpbrk(p, "#\n");
96         if (cp != NULL)
97                 *cp = '\0';
98         bp = ned->netbuf;
99         ep = ned->netbuf + sizeof ned->netbuf;
100         ne->n_name = bp;
101         cp = strpbrk(p, " \t");
102         if (cp == NULL)
103                 goto again;
104         *cp++ = '\0';
105         len = strlen(p) + 1;
106         if (ep - bp < len) {
107                 RES_SET_H_ERRNO(__res_state(), NO_RECOVERY);
108                 return (-1);
109         }
110         strlcpy(bp, p, ep - bp);
111         bp += len;
112         while (*cp == ' ' || *cp == '\t')
113                 cp++;
114         p = strpbrk(cp, " \t");
115         if (p != NULL)
116                 *p++ = '\0';
117         ne->n_net = inet_network(cp);
118         ne->n_addrtype = AF_INET;
119         q = ne->n_aliases = ned->net_aliases;
120         if (p != NULL) {
121                 cp = p;
122                 while (cp && *cp) {
123                         if (*cp == ' ' || *cp == '\t') {
124                                 cp++;
125                                 continue;
126                         }
127                         if (q >= &ned->net_aliases[_MAXALIASES - 1])
128                                 break;
129                         p = strpbrk(cp, " \t");
130                         if (p != NULL)
131                                 *p++ = '\0';
132                         len = strlen(cp) + 1;
133                         if (ep - bp < len)
134                                 break;
135                         strlcpy(bp, cp, ep - bp);
136                         *q++ = bp;
137                         bp += len;
138                         cp = p;
139                 }
140         }
141         *q = NULL;
142         return (0);
143 }
144
145 int
146 getnetent_r(struct netent *nptr, char *buffer, size_t buflen,
147     struct netent **result, int *h_errnop)
148 {
149         struct netent_data *ned;
150         struct netent ne;
151         res_state statp;
152
153         statp = __res_state();
154         if ((ned = __netent_data_init()) == NULL) {
155                 RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
156                 *h_errnop = statp->res_h_errno;
157                 return (-1);
158         }
159         if (getnetent_p(&ne, ned) != 0)
160                 return (-1);
161         if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
162                 RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
163                 *h_errnop = statp->res_h_errno;
164                 return ((errno != 0) ? errno : -1);
165         }
166         *result = nptr;
167         return (0);
168 }
169
170 struct netent *
171 getnetent(void)
172 {
173         struct netdata *nd;
174         struct netent *rval;
175         int ret_h_errno;
176
177         if ((nd = __netdata_init()) == NULL)
178                 return (NULL);
179         if (getnetent_r(&nd->net, nd->data, sizeof(nd->data), &rval,
180             &ret_h_errno) != 0)
181                 return (NULL);
182         return (rval);
183 }
184
185 int
186 _ht_getnetbyname(void *rval, void *cb_data, va_list ap)
187 {
188         const char *name;
189         char *buffer;
190         size_t buflen;
191         int *errnop, *h_errnop;
192         struct netent *nptr, ne;
193         struct netent_data *ned;
194         char **cp;
195         res_state statp;
196         int error;
197
198         name = va_arg(ap, const char *);
199         nptr = va_arg(ap, struct netent *);
200         buffer = va_arg(ap, char *);
201         buflen = va_arg(ap, size_t);
202         errnop = va_arg(ap, int *);
203         h_errnop = va_arg(ap, int *);
204
205         statp = __res_state();
206         if ((ned = __netent_data_init()) == NULL) {
207                 RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
208                 *h_errnop = statp->res_h_errno;
209                 return (NS_UNAVAIL);
210         }
211
212         _setnethtent(ned->stayopen, ned);
213         while ((error = getnetent_p(&ne, ned)) == 0) {
214                 if (strcasecmp(ne.n_name, name) == 0)
215                         break;
216                 for (cp = ne.n_aliases; *cp != 0; cp++)
217                         if (strcasecmp(*cp, name) == 0)
218                                 goto found;
219         }
220 found:
221         if (!ned->stayopen)
222                 _endnethtent(ned);
223         if (error != 0) {
224                 *h_errnop = statp->res_h_errno;
225                 return (NS_NOTFOUND);
226         }
227         if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
228                 *errnop = errno;
229                 RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
230                 *h_errnop = statp->res_h_errno;
231                 return (NS_RETURN);
232         }
233         *((struct netent **)rval) = nptr;
234         return (NS_SUCCESS);
235 }
236
237 int
238 _ht_getnetbyaddr(void *rval, void *cb_data, va_list ap)
239 {
240         uint32_t net;
241         int type;
242         char *buffer;
243         size_t buflen;
244         int *errnop, *h_errnop;
245         struct netent *nptr, ne;
246         struct netent_data *ned;
247         res_state statp;
248         int error;
249
250         net = va_arg(ap, uint32_t);
251         type = va_arg(ap, int);
252         nptr = va_arg(ap, struct netent *);
253         buffer = va_arg(ap, char *);
254         buflen = va_arg(ap, size_t);
255         errnop = va_arg(ap, int *);
256         h_errnop = va_arg(ap, int *);
257
258         statp = __res_state();
259         if ((ned = __netent_data_init()) == NULL) {
260                 RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
261                 *h_errnop = statp->res_h_errno;
262                 return (NS_UNAVAIL);
263         }
264
265         _setnethtent(ned->stayopen, ned);
266         while ((error = getnetent_p(&ne, ned)) == 0)
267                 if (ne.n_addrtype == type && ne.n_net == net)
268                         break;
269         if (!ned->stayopen)
270                 _endnethtent(ned);
271         if (error != 0) {
272                 *h_errnop = statp->res_h_errno;
273                 return (NS_NOTFOUND);
274         }
275         if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
276                 *errnop = errno;
277                 RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
278                 *h_errnop = statp->res_h_errno;
279                 return (NS_RETURN);
280         }
281         *((struct netent **)rval) = nptr;
282         return (NS_SUCCESS);
283 }