No empty .Rs/.Re
[netbsd-mini2440.git] / external / bsd / libbind / dist / irs / nis_sv.c
blob563c1722f0b0c0957a61a9a9ea33cc3369fca7ed
1 /* $NetBSD$ */
3 /*
4 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (c) 1996,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: nis_sv.c,v 1.4 2005/04/27 04:56:34 sra Exp";
22 #endif /* LIBC_SCCS and not lint */
24 /* Imports */
26 #include "port_before.h"
28 #ifndef WANT_IRS_NIS
29 static int __bind_irs_nis_unneeded;
30 #else
32 #include <sys/types.h>
33 #include <netinet/in.h>
34 #include <arpa/nameser.h>
35 #include <resolv.h>
36 #include <sys/socket.h>
37 #ifdef T_NULL
38 #undef T_NULL /* Silence re-definition warning of T_NULL. */
39 #endif
40 #include <rpc/rpc.h>
41 #include <rpc/xdr.h>
42 #include <rpcsvc/yp_prot.h>
43 #include <rpcsvc/ypclnt.h>
45 #include <ctype.h>
46 #include <errno.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
51 #include <isc/memcluster.h>
52 #include <irs.h>
54 #include "port_after.h"
56 #include "irs_p.h"
57 #include "nis_p.h"
59 /* Definitions */
61 struct pvt {
62 int needrewind;
63 char * nis_domain;
64 char * curkey_data;
65 int curkey_len;
66 char * curval_data;
67 int curval_len;
68 char line[BUFSIZ+1];
69 struct servent serv;
70 char * svbuf;
73 enum do_what { do_none = 0x0, do_key = 0x1, do_val = 0x2, do_all = 0x3 };
75 static /*const*/ char services_byname[] = "services.byname";
77 /* Forward */
79 static void sv_close(struct irs_sv*);
80 static struct servent * sv_next(struct irs_sv *);
81 static struct servent * sv_byname(struct irs_sv *, const char *,
82 const char *);
83 static struct servent * sv_byport(struct irs_sv *, int, const char *);
84 static void sv_rewind(struct irs_sv *);
85 static void sv_minimize(struct irs_sv *);
87 static struct servent * makeservent(struct irs_sv *this);
88 static void nisfree(struct pvt *, enum do_what);
90 /* Public */
92 struct irs_sv *
93 irs_nis_sv(struct irs_acc *this) {
94 struct irs_sv *sv;
95 struct pvt *pvt;
97 if (!(sv = memget(sizeof *sv))) {
98 errno = ENOMEM;
99 return (NULL);
101 memset(sv, 0x5e, sizeof *sv);
102 if (!(pvt = memget(sizeof *pvt))) {
103 memput(sv, sizeof *sv);
104 errno = ENOMEM;
105 return (NULL);
107 memset(pvt, 0, sizeof *pvt);
108 pvt->needrewind = 1;
109 pvt->nis_domain = ((struct nis_p *)this->private)->domain;
110 sv->private = pvt;
111 sv->close = sv_close;
112 sv->next = sv_next;
113 sv->byname = sv_byname;
114 sv->byport = sv_byport;
115 sv->rewind = sv_rewind;
116 sv->minimize = sv_minimize;
117 sv->res_get = NULL;
118 sv->res_set = NULL;
119 return (sv);
122 /* Methods */
124 static void
125 sv_close(struct irs_sv *this) {
126 struct pvt *pvt = (struct pvt *)this->private;
128 nisfree(pvt, do_all);
129 if (pvt->serv.s_aliases)
130 free(pvt->serv.s_aliases);
131 if (pvt->svbuf)
132 free(pvt->svbuf);
133 memput(pvt, sizeof *pvt);
134 memput(this, sizeof *this);
137 static struct servent *
138 sv_byname(struct irs_sv *this, const char *name, const char *proto) {
139 struct servent *serv;
140 char **sap;
142 sv_rewind(this);
143 while ((serv = sv_next(this)) != NULL) {
144 if (proto != NULL && strcmp(proto, serv->s_proto))
145 continue;
146 if (!strcmp(name, serv->s_name))
147 break;
148 for (sap = serv->s_aliases; sap && *sap; sap++)
149 if (!strcmp(name, *sap))
150 break;
152 return (serv);
155 static struct servent *
156 sv_byport(struct irs_sv *this, int port, const char *proto) {
157 struct servent *serv;
159 sv_rewind(this);
160 while ((serv = sv_next(this)) != NULL) {
161 if (proto != NULL && strcmp(proto, serv->s_proto))
162 continue;
163 if (serv->s_port == port)
164 break;
166 return (serv);
169 static void
170 sv_rewind(struct irs_sv *this) {
171 struct pvt *pvt = (struct pvt *)this->private;
173 pvt->needrewind = 1;
176 static struct servent *
177 sv_next(struct irs_sv *this) {
178 struct pvt *pvt = (struct pvt *)this->private;
179 struct servent *rval;
180 int r;
182 do {
183 if (pvt->needrewind) {
184 nisfree(pvt, do_all);
185 r = yp_first(pvt->nis_domain, services_byname,
186 &pvt->curkey_data, &pvt->curkey_len,
187 &pvt->curval_data, &pvt->curval_len);
188 pvt->needrewind = 0;
189 } else {
190 char *newkey_data;
191 int newkey_len;
193 nisfree(pvt, do_val);
194 r = yp_next(pvt->nis_domain, services_byname,
195 pvt->curkey_data, pvt->curkey_len,
196 &newkey_data, &newkey_len,
197 &pvt->curval_data, &pvt->curval_len);
198 nisfree(pvt, do_key);
199 pvt->curkey_data = newkey_data;
200 pvt->curkey_len = newkey_len;
202 if (r != 0) {
203 errno = ENOENT;
204 return (NULL);
206 rval = makeservent(this);
207 } while (rval == NULL);
208 return (rval);
211 static void
212 sv_minimize(struct irs_sv *this) {
213 UNUSED(this);
214 /* NOOP */
217 /* Private */
219 static struct servent *
220 makeservent(struct irs_sv *this) {
221 struct pvt *pvt = (struct pvt *)this->private;
222 static const char spaces[] = " \t";
223 char *p, **t;
224 int n, m;
226 if (pvt->svbuf)
227 free(pvt->svbuf);
228 pvt->svbuf = pvt->curval_data;
229 pvt->curval_data = NULL;
231 if (pvt->serv.s_aliases) {
232 free(pvt->serv.s_aliases);
233 pvt->serv.s_aliases = NULL;
236 if ((p = strpbrk(pvt->svbuf, "#\n")))
237 *p = '\0';
239 p = pvt->svbuf;
241 pvt->serv.s_name = p;
242 p += strcspn(p, spaces);
243 if (!*p)
244 goto cleanup;
245 *p++ = '\0';
246 p += strspn(p, spaces);
248 pvt->serv.s_port = htons((u_short) atoi(p));
249 pvt->serv.s_proto = NULL;
251 while (*p && !isspace((unsigned char)*p))
252 if (*p++ == '/')
253 pvt->serv.s_proto = p;
254 if (!pvt->serv.s_proto)
255 goto cleanup;
256 if (*p) {
257 *p++ = '\0';
258 p += strspn(p, spaces);
261 n = m = 0;
262 while (*p) {
263 if ((n + 1) >= m || !pvt->serv.s_aliases) {
264 m += 10;
265 t = realloc(pvt->serv.s_aliases, m * sizeof(char *));
266 if (!t) {
267 errno = ENOMEM;
268 goto cleanup;
270 pvt->serv.s_aliases = t;
272 pvt->serv.s_aliases[n++] = p;
273 p += strcspn(p, spaces);
274 if (!*p)
275 break;
276 *p++ = '\0';
277 p += strspn(p, spaces);
279 if (!pvt->serv.s_aliases)
280 pvt->serv.s_aliases = malloc(sizeof(char *));
281 if (!pvt->serv.s_aliases)
282 goto cleanup;
283 pvt->serv.s_aliases[n] = NULL;
284 return (&pvt->serv);
286 cleanup:
287 if (pvt->serv.s_aliases) {
288 free(pvt->serv.s_aliases);
289 pvt->serv.s_aliases = NULL;
291 if (pvt->svbuf) {
292 free(pvt->svbuf);
293 pvt->svbuf = NULL;
295 return (NULL);
298 static void
299 nisfree(struct pvt *pvt, enum do_what do_what) {
300 if ((do_what & do_key) && pvt->curkey_data) {
301 free(pvt->curkey_data);
302 pvt->curkey_data = NULL;
304 if ((do_what & do_val) && pvt->curval_data) {
305 free(pvt->curval_data);
306 pvt->curval_data = NULL;
310 #endif /*WANT_IRS_NIS*/
312 /*! \file */