xref: /netbsd-src/external/bsd/libbind/dist/irs/nis_pr.c (revision 5bbd2a12505d72a8177929a37b5cee489d0a1cfd)
1 /*	$NetBSD: nis_pr.c,v 1.1.1.2 2012/09/09 16:07:55 christos Exp $	*/
2 
3 /*
4  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5  * Copyright (c) 1996,1999 by Internet Software Consortium.
6  *
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.
10  *
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.
18  */
19 
20 #if defined(LIBC_SCCS) && !defined(lint)
21 static const char rcsid[] = "Id: nis_pr.c,v 1.4 2005/04/27 04:56:33 sra Exp ";
22 #endif
23 
24 /* Imports */
25 
26 #include "port_before.h"
27 
28 #ifndef WANT_IRS_NIS
29 static int __bind_irs_nis_unneeded;
30 #else
31 
32 #include <sys/types.h>
33 #include <netinet/in.h>
34 #include <arpa/nameser.h>
35 #include <resolv.h>
36 #ifdef T_NULL
37 #undef T_NULL			/* Silence re-definition warning of T_NULL. */
38 #endif
39 #include <rpc/rpc.h>
40 #include <rpc/xdr.h>
41 #include <rpcsvc/yp_prot.h>
42 #include <rpcsvc/ypclnt.h>
43 
44 #include <stdio.h>
45 #include <string.h>
46 #include <netdb.h>
47 #include <ctype.h>
48 #include <stdlib.h>
49 #include <errno.h>
50 
51 #include <isc/memcluster.h>
52 #include <irs.h>
53 
54 #include "port_after.h"
55 
56 #include "irs_p.h"
57 #include "nis_p.h"
58 
59 /* Definitions */
60 
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 	struct protoent	proto;
69 	char *		prbuf;
70 };
71 
72 enum do_what { do_none = 0x0, do_key = 0x1, do_val = 0x2, do_all = 0x3 };
73 
74 static /*const*/ char protocols_byname[] =	"protocols.byname";
75 static /*const*/ char protocols_bynumber[] =	"protocols.bynumber";
76 
77 /* Forward */
78 
79 static void 			pr_close(struct irs_pr *);
80 static struct protoent *	pr_byname(struct irs_pr *, const char *);
81 static struct protoent *	pr_bynumber(struct irs_pr *, int);
82 static struct protoent *	pr_next(struct irs_pr *);
83 static void			pr_rewind(struct irs_pr *);
84 static void			pr_minimize(struct irs_pr *);
85 
86 static struct protoent *	makeprotoent(struct irs_pr *this);
87 static void			nisfree(struct pvt *, enum do_what);
88 
89 /* Public */
90 
91 struct irs_pr *
irs_nis_pr(struct irs_acc * this)92 irs_nis_pr(struct irs_acc *this) {
93 	struct irs_pr *pr;
94 	struct pvt *pvt;
95 
96 	if (!(pr = memget(sizeof *pr))) {
97 		errno = ENOMEM;
98 		return (NULL);
99 	}
100 	memset(pr, 0x5e, sizeof *pr);
101 	if (!(pvt = memget(sizeof *pvt))) {
102 		memput(pr, sizeof *pr);
103 		errno = ENOMEM;
104 		return (NULL);
105 	}
106 	memset(pvt, 0, sizeof *pvt);
107 	pvt->needrewind = 1;
108 	pvt->nis_domain = ((struct nis_p *)this->private)->domain;
109 	pr->private = pvt;
110 	pr->byname = pr_byname;
111 	pr->bynumber = pr_bynumber;
112 	pr->next = pr_next;
113 	pr->rewind = pr_rewind;
114 	pr->close = pr_close;
115 	pr->minimize = pr_minimize;
116 	pr->res_get = NULL;
117 	pr->res_set = NULL;
118 	return (pr);
119 }
120 
121 /* Methods. */
122 
123 static void
pr_close(struct irs_pr * this)124 pr_close(struct irs_pr *this) {
125 	struct pvt *pvt = (struct pvt *)this->private;
126 
127 	nisfree(pvt, do_all);
128 	if (pvt->proto.p_aliases)
129 		free(pvt->proto.p_aliases);
130 	if (pvt->prbuf)
131 		free(pvt->prbuf);
132 	memput(pvt, sizeof *pvt);
133 	memput(this, sizeof *this);
134 }
135 
136 static struct protoent *
pr_byname(struct irs_pr * this,const char * name)137 pr_byname(struct irs_pr *this, const char *name) {
138 	struct pvt *pvt = (struct pvt *)this->private;
139 	int r;
140 	char *tmp;
141 
142 	nisfree(pvt, do_val);
143 	DE_CONST(name, tmp);
144 	r = yp_match(pvt->nis_domain, protocols_byname, tmp,
145 		     strlen(tmp), &pvt->curval_data, &pvt->curval_len);
146 	if (r != 0) {
147 		errno = ENOENT;
148 		return (NULL);
149 	}
150 	return (makeprotoent(this));
151 }
152 
153 static struct protoent *
pr_bynumber(struct irs_pr * this,int num)154 pr_bynumber(struct irs_pr *this, int num) {
155 	struct pvt *pvt = (struct pvt *)this->private;
156 	char tmp[sizeof "-4294967295"];
157 	int r;
158 
159 	nisfree(pvt, do_val);
160 	(void) sprintf(tmp, "%d", num);
161 	r = yp_match(pvt->nis_domain, protocols_bynumber, tmp, strlen(tmp),
162 		     &pvt->curval_data, &pvt->curval_len);
163 	if (r != 0) {
164 		errno = ENOENT;
165 		return (NULL);
166 	}
167 	return (makeprotoent(this));
168 }
169 
170 static struct protoent *
pr_next(struct irs_pr * this)171 pr_next(struct irs_pr *this) {
172 	struct pvt *pvt = (struct pvt *)this->private;
173 	struct protoent *rval;
174 	int r;
175 
176 	do {
177 		if (pvt->needrewind) {
178 			nisfree(pvt, do_all);
179 			r = yp_first(pvt->nis_domain, protocols_bynumber,
180 				     &pvt->curkey_data, &pvt->curkey_len,
181 				     &pvt->curval_data, &pvt->curval_len);
182 			pvt->needrewind = 0;
183 		} else {
184 			char *newkey_data;
185 			int newkey_len;
186 
187 			nisfree(pvt, do_val);
188 			r = yp_next(pvt->nis_domain, protocols_bynumber,
189 				    pvt->curkey_data, pvt->curkey_len,
190 				    &newkey_data, &newkey_len,
191 				    &pvt->curval_data, &pvt->curval_len);
192 			nisfree(pvt, do_key);
193 			pvt->curkey_data = newkey_data;
194 			pvt->curkey_len = newkey_len;
195 		}
196 		if (r != 0) {
197 			errno = ENOENT;
198 			return (NULL);
199 		}
200 		rval = makeprotoent(this);
201 	} while (rval == NULL);
202 	return (rval);
203 }
204 
205 static void
pr_rewind(struct irs_pr * this)206 pr_rewind(struct irs_pr *this) {
207 	struct pvt *pvt = (struct pvt *)this->private;
208 
209 	pvt->needrewind = 1;
210 }
211 
212 static void
pr_minimize(struct irs_pr * this)213 pr_minimize(struct irs_pr *this) {
214 	UNUSED(this);
215 	/* NOOP */
216 }
217 
218 /* Private */
219 
220 static struct protoent *
makeprotoent(struct irs_pr * this)221 makeprotoent(struct irs_pr *this) {
222 	struct pvt *pvt = (struct pvt *)this->private;
223 	char *p, **t;
224 	int n, m;
225 
226 	if (pvt->prbuf)
227 		free(pvt->prbuf);
228 	pvt->prbuf = pvt->curval_data;
229 	pvt->curval_data = NULL;
230 
231 	for (p = pvt->prbuf; *p && *p != '#';)
232 		p++;
233 	while (p > pvt->prbuf && isspace((unsigned char)(p[-1])))
234 		p--;
235 	*p = '\0';
236 
237 	p = pvt->prbuf;
238 	n = m = 0;
239 
240 	pvt->proto.p_name = p;
241 	while (*p && !isspace((unsigned char)*p))
242 		p++;
243 	if (!*p)
244 		return (NULL);
245 	*p++ = '\0';
246 
247 	while (*p && isspace((unsigned char)*p))
248 		p++;
249 	pvt->proto.p_proto = atoi(p);
250 	while (*p && !isspace((unsigned char)*p))
251 		p++;
252 	*p++ = '\0';
253 
254 	while (*p) {
255 		if ((n + 1) >= m || !pvt->proto.p_aliases) {
256 			m += 10;
257 			t = realloc(pvt->proto.p_aliases,
258 				      m * sizeof(char *));
259 			if (!t) {
260 				errno = ENOMEM;
261 				goto cleanup;
262 			}
263 			pvt->proto.p_aliases = t;
264 		}
265 		pvt->proto.p_aliases[n++] = p;
266 		while (*p && !isspace((unsigned char)*p))
267 			p++;
268 		if (*p)
269 			*p++ = '\0';
270 	}
271 	if (!pvt->proto.p_aliases)
272 		pvt->proto.p_aliases = malloc(sizeof(char *));
273 	if (!pvt->proto.p_aliases)
274 		goto cleanup;
275 	pvt->proto.p_aliases[n] = NULL;
276 	return (&pvt->proto);
277 
278  cleanup:
279 	if (pvt->proto.p_aliases) {
280 		free(pvt->proto.p_aliases);
281 		pvt->proto.p_aliases = NULL;
282 	}
283 	if (pvt->prbuf) {
284 		free(pvt->prbuf);
285 		pvt->prbuf = NULL;
286 	}
287 	return (NULL);
288 }
289 
290 static void
nisfree(struct pvt * pvt,enum do_what do_what)291 nisfree(struct pvt *pvt, enum do_what do_what) {
292 	if ((do_what & do_key) && pvt->curkey_data) {
293 		free(pvt->curkey_data);
294 		pvt->curkey_data = NULL;
295 	}
296 	if ((do_what & do_val) && pvt->curval_data) {
297 		free(pvt->curval_data);
298 		pvt->curval_data = NULL;
299 	}
300 }
301 
302 #endif /*WANT_IRS_NIS*/
303 
304 /*! \file */
305