]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/bind/lib/irs/lcl_sv.c
This commit was generated by cvs2svn to compensate for changes in r52894,
[FreeBSD/FreeBSD.git] / contrib / bind / lib / irs / lcl_sv.c
1 /*
2  * Copyright (c) 1989, 1993, 1995
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by the University of
16  *      California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34 /*
35  * Portions Copyright (c) 1996 by Internet Software Consortium.
36  *
37  * Permission to use, copy, modify, and distribute this software for any
38  * purpose with or without fee is hereby granted, provided that the above
39  * copyright notice and this permission notice appear in all copies.
40  *
41  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
42  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
43  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
44  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
45  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
46  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
47  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
48  * SOFTWARE.
49  */
50
51 #if defined(LIBC_SCCS) && !defined(lint)
52 static const char rcsid[] = "$Id: lcl_sv.c,v 1.11 1997/12/04 04:57:58 halley Exp $";
53 #endif /* LIBC_SCCS and not lint */
54
55 /* extern */
56
57 #include "port_before.h"
58
59 #include <sys/types.h>
60 #include <sys/socket.h>
61
62 #include <netinet/in.h>
63
64 #include <errno.h>
65 #include <fcntl.h>
66 #include <stdio.h>
67 #include <string.h>
68 #include <stdlib.h>
69
70 #include <irs.h>
71
72 #include "port_after.h"
73
74 #include "irs_p.h"
75 #include "lcl_p.h"
76
77 #define MAXALIASES      35
78
79 /* Types */
80
81 struct pvt {
82         FILE *          fp;
83         char            line[BUFSIZ+1];
84         struct servent  serv;
85         char *          serv_aliases[MAXALIASES];
86 };
87
88 /* Forward */
89
90 static void                     sv_close(struct irs_sv*);
91 static struct servent *         sv_next(struct irs_sv *);
92 static struct servent *         sv_byname(struct irs_sv *, const char *,
93                                           const char *);
94 static struct servent *         sv_byport(struct irs_sv *, int, const char *);
95 static void                     sv_rewind(struct irs_sv *);
96 static void                     sv_minimize(struct irs_sv *);
97
98 /* Portability */
99
100 #ifndef SEEK_SET
101 # define SEEK_SET 0
102 #endif
103
104 /* Public */
105
106 struct irs_sv *
107 irs_lcl_sv(struct irs_acc *this) {
108         struct irs_sv *sv;
109         struct pvt *pvt;
110         
111         if (!(sv = (struct irs_sv *)malloc(sizeof *sv))) {
112                 errno = ENOMEM;
113                 return (NULL);
114         }
115         memset(sv, 0x5e, sizeof *sv);
116         if (!(pvt = (struct pvt *)malloc(sizeof *pvt))) {
117                 free(sv);
118                 errno = ENOMEM;
119                 return (NULL);
120         }
121         memset(pvt, 0, sizeof *pvt);
122         sv->private = pvt;
123         sv->close = sv_close;
124         sv->next = sv_next;
125         sv->byname = sv_byname;
126         sv->byport = sv_byport;
127         sv->rewind = sv_rewind;
128         sv->minimize = sv_minimize;
129         return (sv);
130 }
131
132 /* Methods */
133
134 static void
135 sv_close(struct irs_sv *this) {
136         struct pvt *pvt = (struct pvt *)this->private;
137         
138         if (pvt->fp)
139                 fclose(pvt->fp);
140         free(pvt);
141         free(this);
142 }
143
144 static struct servent *
145 sv_byname(struct irs_sv *this, const char *name, const char *proto) {
146         register struct servent *p;
147         register char **cp;
148
149         sv_rewind(this);
150         while ((p = sv_next(this))) {
151                 if (strcmp(name, p->s_name) == 0)
152                         goto gotname;
153                 for (cp = p->s_aliases; *cp; cp++)
154                         if (strcmp(name, *cp) == 0)
155                                 goto gotname;
156                 continue;
157  gotname:
158                 if (proto == NULL || strcmp(p->s_proto, proto) == 0)
159                         break;
160         }
161         return (p);
162 }
163
164 static struct servent *
165 sv_byport(struct irs_sv *this, int port, const char *proto) {
166         register struct servent *p;
167
168         sv_rewind(this);
169         while ((p = sv_next(this))) {
170                 if (p->s_port != port)
171                         continue;
172                 if (proto == NULL || strcmp(p->s_proto, proto) == 0)
173                         break;
174         }
175         return (p);
176 }
177
178 static void
179 sv_rewind(struct irs_sv *this) {
180         struct pvt *pvt = (struct pvt *)this->private;
181
182         if (pvt->fp) {
183                 if (fseek(pvt->fp, 0L, SEEK_SET) == 0)
184                         return;
185                 (void)fclose(pvt->fp);
186         }
187         if (!(pvt->fp = fopen(_PATH_SERVICES, "r" )))
188                 return;
189         if (fcntl(fileno(pvt->fp), F_SETFD, 1) < 0) {
190                 (void)fclose(pvt->fp);
191                 pvt->fp = NULL;
192         }
193 }
194
195 static struct servent *
196 sv_next(struct irs_sv *this) {
197         struct pvt *pvt = (struct pvt *)this->private;
198         char *p;
199         register char *cp, **q;
200
201         if (!pvt->fp)
202                 sv_rewind(this);
203         if (!pvt->fp)
204                 return (NULL);
205  again:
206         if ((p = fgets(pvt->line, BUFSIZ, pvt->fp)) == NULL)
207                 return (NULL);
208         if (*p == '#')
209                 goto again;
210         cp = strpbrk(p, "#\n");
211         if (cp == NULL)
212                 goto again;
213         *cp = '\0';
214         pvt->serv.s_name = p;
215         p = strpbrk(p, " \t");
216         if (p == NULL)
217                 goto again;
218         *p++ = '\0';
219         while (*p == ' ' || *p == '\t')
220                 p++;
221         cp = strpbrk(p, ",/");
222         if (cp == NULL)
223                 goto again;
224         *cp++ = '\0';
225         pvt->serv.s_port = htons((u_short)atoi(p));
226         pvt->serv.s_proto = cp;
227         q = pvt->serv.s_aliases = pvt->serv_aliases;
228         cp = strpbrk(cp, " \t");
229         if (cp != NULL)
230                 *cp++ = '\0';
231         while (cp && *cp) {
232                 if (*cp == ' ' || *cp == '\t') {
233                         cp++;
234                         continue;
235                 }
236                 if (q < &pvt->serv_aliases[MAXALIASES - 1])
237                         *q++ = cp;
238                 cp = strpbrk(cp, " \t");
239                 if (cp != NULL)
240                         *cp++ = '\0';
241         }
242         *q = NULL;
243         return (&pvt->serv);
244 }
245
246 static void
247 sv_minimize(struct irs_sv *this) {
248         struct pvt *pvt = (struct pvt *)this->private;
249
250         if (pvt->fp != NULL) {
251                 (void)fclose(pvt->fp);
252                 pvt->fp = NULL;
253         }
254 }