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