xref: /illumos-gate/usr/src/lib/libresolv2/common/irs/lcl_pr.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
1 /*
2  * Copyright (c) 1997-2000 by Sun Microsystems, Inc.
3  * All rights reserved.
4  */
5 
6 /*
7  * Copyright (c) 1989, 1993, 1995
8  *	The Regents of the University of California.  All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
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.
25  *
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
36  * SUCH DAMAGE.
37  */
38 
39 /*
40  * Portions Copyright (c) 1996,1999 by Internet Software Consortium.
41  *
42  * Permission to use, copy, modify, and distribute this software for any
43  * purpose with or without fee is hereby granted, provided that the above
44  * copyright notice and this permission notice appear in all copies.
45  *
46  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
47  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
48  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
49  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53  * SOFTWARE.
54  */
55 
56 #pragma ident	"%Z%%M%	%I%	%E% SMI"
57 
58 #if defined(LIBC_SCCS) && !defined(lint)
59 static const char rcsid[] = "$Id: lcl_pr.c,v 1.18 1999/10/13 17:11:20 vixie Exp $";
60 #endif /* LIBC_SCCS and not lint */
61 
62 /* extern */
63 
64 #include "port_before.h"
65 
66 #include <sys/types.h>
67 #include <netinet/in.h>
68 #include <arpa/nameser.h>
69 #include <resolv.h>
70 
71 #include <errno.h>
72 #include <fcntl.h>
73 #include <string.h>
74 #include <stdio.h>
75 #include <stdlib.h>
76 
77 #include <irs.h>
78 #include <isc/memcluster.h>
79 
80 #include "port_after.h"
81 
82 #include "irs_p.h"
83 #include "lcl_p.h"
84 
85 #ifndef _PATH_PROTOCOLS
86 #define _PATH_PROTOCOLS "/etc/protocols"
87 #endif
88 #define MAXALIASES      35
89 
90 /* Types */
91 
92 struct pvt {
93 	FILE *		fp;
94 	char		line[BUFSIZ+1];
95 	struct protoent	proto;
96 	char *		proto_aliases[MAXALIASES];
97 };
98 
99 /* Forward */
100 
101 static void			pr_close(struct irs_pr *);
102 static struct protoent *	pr_next(struct irs_pr *);
103 static struct protoent *	pr_byname(struct irs_pr *, const char *);
104 static struct protoent *	pr_bynumber(struct irs_pr *, int);
105 static void			pr_rewind(struct irs_pr *);
106 static void			pr_minimize(struct irs_pr *);
107 
108 /* Portability. */
109 
110 #ifndef SEEK_SET
111 # define SEEK_SET 0
112 #endif
113 
114 /* Public */
115 
116 struct irs_pr *
117 irs_lcl_pr(struct irs_acc *this) {
118 	struct irs_pr *pr;
119 	struct pvt *pvt;
120 
121 	if (!(pr = memget(sizeof *pr))) {
122 		errno = ENOMEM;
123 		return (NULL);
124 	}
125 	if (!(pvt = memget(sizeof *pvt))) {
126 		memput(pr, sizeof *this);
127 		errno = ENOMEM;
128 		return (NULL);
129 	}
130 	memset(pvt, 0, sizeof *pvt);
131 	pr->private = pvt;
132 	pr->close = pr_close;
133 	pr->byname = pr_byname;
134 	pr->bynumber = pr_bynumber;
135 	pr->next = pr_next;
136 	pr->rewind = pr_rewind;
137 	pr->minimize = pr_minimize;
138 	pr->res_get = NULL;
139 	pr->res_set = NULL;
140 	return (pr);
141 }
142 
143 /* Methods */
144 
145 static void
146 pr_close(struct irs_pr *this) {
147 	struct pvt *pvt = (struct pvt *)this->private;
148 
149 	if (pvt->fp)
150 		(void) fclose(pvt->fp);
151 	memput(pvt, sizeof *pvt);
152 	memput(this, sizeof *this);
153 }
154 
155 static struct protoent *
156 pr_byname(struct irs_pr *this, const char *name) {
157 
158 	struct protoent *p;
159 	char **cp;
160 
161 	pr_rewind(this);
162 	while ((p = pr_next(this))) {
163 		if (!strcmp(p->p_name, name))
164 			goto found;
165 		for (cp = p->p_aliases; *cp; cp++)
166 			if (!strcmp(*cp, name))
167 				goto found;
168 	}
169  found:
170 	return (p);
171 }
172 
173 static struct protoent *
174 pr_bynumber(struct irs_pr *this, int proto) {
175 	struct protoent *p;
176 
177 	pr_rewind(this);
178 	while ((p = pr_next(this)))
179 		if (p->p_proto == proto)
180 			break;
181 	return (p);
182 }
183 
184 static void
185 pr_rewind(struct irs_pr *this) {
186 	struct pvt *pvt = (struct pvt *)this->private;
187 
188 	if (pvt->fp) {
189 		if (fseek(pvt->fp, 0L, SEEK_SET) == 0)
190 			return;
191 		(void)fclose(pvt->fp);
192 	}
193 	if (!(pvt->fp = fopen(_PATH_PROTOCOLS, "r" )))
194 		return;
195 	if (fcntl(fileno(pvt->fp), F_SETFD, 1) < 0) {
196 		(void)fclose(pvt->fp);
197 		pvt->fp = NULL;
198 	}
199 }
200 
201 static struct protoent *
202 pr_next(struct irs_pr *this) {
203 	struct pvt *pvt = (struct pvt *)this->private;
204 	char *p, *cp, **q;
205 	char *bufp, *ndbuf, *dbuf = NULL;
206 	int c, bufsiz, offset;
207 
208 	if (!pvt->fp)
209 		pr_rewind(this);
210 	if (!pvt->fp)
211 		return (NULL);
212 	bufp = pvt->line;
213 	bufsiz = BUFSIZ;
214 	offset = 0;
215  again:
216 	if ((p = fgets(bufp + offset, bufsiz - offset, pvt->fp)) == NULL) {
217 		if (dbuf)
218 			free(dbuf);
219 		return (NULL);
220 	}
221 	if (!strchr(p, '\n') && !feof(pvt->fp)) {
222 #define GROWBUF 1024
223 		/* allocate space for longer line */
224 		if (dbuf == NULL) {
225 			if ((ndbuf = malloc(bufsiz + GROWBUF)) != NULL)
226 				strcpy(ndbuf, bufp);
227 		} else
228 			ndbuf = realloc(dbuf, bufsiz + GROWBUF);
229 		if (ndbuf) {
230 			dbuf = ndbuf;
231 			bufp = dbuf;
232 			bufsiz += GROWBUF;
233 			offset = strlen(dbuf);
234 		} else {
235 			/* allocation failed; skip this long line */
236 			while ((c = getc(pvt->fp)) != EOF)
237 				if (c == '\n')
238 					break;
239 			if (c != EOF)
240 				ungetc(c, pvt->fp);
241 		}
242 		goto again;
243 	}
244 
245 	p -= offset;
246 	offset = 0;
247 
248 	if (*p == '#')
249 		goto again;
250 	cp = strpbrk(p, "#\n");
251 	if (cp != NULL)
252 		*cp = '\0';
253 	pvt->proto.p_name = p;
254 	cp = strpbrk(p, " \t");
255 	if (cp == NULL)
256 		goto again;
257 	*cp++ = '\0';
258 	while (*cp == ' ' || *cp == '\t')
259 		cp++;
260 	p = strpbrk(cp, " \t");
261 	if (p != NULL)
262 		*p++ = '\0';
263 	pvt->proto.p_proto = atoi(cp);
264 	q = pvt->proto.p_aliases = pvt->proto_aliases;
265 	if (p != NULL) {
266 		cp = p;
267 		while (cp && *cp) {
268 			if (*cp == ' ' || *cp == '\t') {
269 				cp++;
270 				continue;
271 			}
272 			if (q < &pvt->proto_aliases[MAXALIASES - 1])
273 				*q++ = cp;
274 			cp = strpbrk(cp, " \t");
275 			if (cp != NULL)
276 				*cp++ = '\0';
277 		}
278 	}
279 	*q = NULL;
280 	return (&pvt->proto);
281 }
282 
283 static void
284 pr_minimize(struct irs_pr *this) {
285 	struct pvt *pvt = (struct pvt *)this->private;
286 
287 	if (pvt->fp != NULL) {
288 		(void)fclose(pvt->fp);
289 		pvt->fp = NULL;
290 	}
291 }
292