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