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 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 36 * Portions Copyright (c) 1996,1999 by Internet Software Consortium. 37 * 38 * Permission to use, copy, modify, and distribute this software for any 39 * purpose with or without fee is hereby granted, provided that the above 40 * copyright notice and this permission notice appear in all copies. 41 * 42 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 43 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 44 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 45 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 46 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 47 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 48 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 49 */ 50 51 #if defined(LIBC_SCCS) && !defined(lint) 52 static const char rcsid[] = "$Id: lcl_pr.c,v 1.4 2006/03/09 23:57:56 marka 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 <netinet/in.h> 61 #include <arpa/nameser.h> 62 #include <resolv.h> 63 64 #include <errno.h> 65 #include <fcntl.h> 66 #include <string.h> 67 #include <stdio.h> 68 #include <stdlib.h> 69 70 #include <irs.h> 71 #include <isc/memcluster.h> 72 73 #include "port_after.h" 74 75 #include "irs_p.h" 76 #include "lcl_p.h" 77 78 #ifndef _PATH_PROTOCOLS 79 #define _PATH_PROTOCOLS "/etc/protocols" 80 #endif 81 #define MAXALIASES 35 82 83 /* Types */ 84 85 struct pvt { 86 FILE * fp; 87 char line[BUFSIZ+1]; 88 char * dbuf; 89 struct protoent proto; 90 char * proto_aliases[MAXALIASES]; 91 }; 92 93 /* Forward */ 94 95 static void pr_close(struct irs_pr *); 96 static struct protoent * pr_next(struct irs_pr *); 97 static struct protoent * pr_byname(struct irs_pr *, const char *); 98 static struct protoent * pr_bynumber(struct irs_pr *, int); 99 static void pr_rewind(struct irs_pr *); 100 static void pr_minimize(struct irs_pr *); 101 102 /* Portability. */ 103 104 #ifndef SEEK_SET 105 # define SEEK_SET 0 106 #endif 107 108 /* Public */ 109 110 struct irs_pr * 111 irs_lcl_pr(struct irs_acc *this) { 112 struct irs_pr *pr; 113 struct pvt *pvt; 114 115 if (!(pr = memget(sizeof *pr))) { 116 errno = ENOMEM; 117 return (NULL); 118 } 119 if (!(pvt = memget(sizeof *pvt))) { 120 memput(pr, sizeof *this); 121 errno = ENOMEM; 122 return (NULL); 123 } 124 memset(pvt, 0, sizeof *pvt); 125 pr->private = pvt; 126 pr->close = pr_close; 127 pr->byname = pr_byname; 128 pr->bynumber = pr_bynumber; 129 pr->next = pr_next; 130 pr->rewind = pr_rewind; 131 pr->minimize = pr_minimize; 132 pr->res_get = NULL; 133 pr->res_set = NULL; 134 return (pr); 135 } 136 137 /* Methods */ 138 139 static void 140 pr_close(struct irs_pr *this) { 141 struct pvt *pvt = (struct pvt *)this->private; 142 143 if (pvt->fp) 144 (void) fclose(pvt->fp); 145 if (pvt->dbuf) 146 free(pvt->dbuf); 147 memput(pvt, sizeof *pvt); 148 memput(this, sizeof *this); 149 } 150 151 static struct protoent * 152 pr_byname(struct irs_pr *this, const char *name) { 153 154 struct protoent *p; 155 char **cp; 156 157 pr_rewind(this); 158 while ((p = pr_next(this))) { 159 if (!strcmp(p->p_name, name)) 160 goto found; 161 for (cp = p->p_aliases; *cp; cp++) 162 if (!strcmp(*cp, name)) 163 goto found; 164 } 165 found: 166 return (p); 167 } 168 169 static struct protoent * 170 pr_bynumber(struct irs_pr *this, int proto) { 171 struct protoent *p; 172 173 pr_rewind(this); 174 while ((p = pr_next(this))) 175 if (p->p_proto == proto) 176 break; 177 return (p); 178 } 179 180 static void 181 pr_rewind(struct irs_pr *this) { 182 struct pvt *pvt = (struct pvt *)this->private; 183 184 if (pvt->fp) { 185 if (fseek(pvt->fp, 0L, SEEK_SET) == 0) 186 return; 187 (void)fclose(pvt->fp); 188 } 189 if (!(pvt->fp = fopen(_PATH_PROTOCOLS, "r" ))) 190 return; 191 if (fcntl(fileno(pvt->fp), F_SETFD, 1) < 0) { 192 (void)fclose(pvt->fp); 193 pvt->fp = NULL; 194 } 195 } 196 197 static struct protoent * 198 pr_next(struct irs_pr *this) { 199 struct pvt *pvt = (struct pvt *)this->private; 200 char *p, *cp, **q; 201 char *bufp, *ndbuf, *dbuf = NULL; 202 int c, bufsiz, offset; 203 204 if (!pvt->fp) 205 pr_rewind(this); 206 if (!pvt->fp) 207 return (NULL); 208 if (pvt->dbuf) { 209 free(pvt->dbuf); 210 pvt->dbuf = NULL; 211 } 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 pvt->dbuf = dbuf; 281 return (&pvt->proto); 282 } 283 284 static void 285 pr_minimize(struct irs_pr *this) { 286 struct pvt *pvt = (struct pvt *)this->private; 287 288 if (pvt->fp != NULL) { 289 (void)fclose(pvt->fp); 290 pvt->fp = NULL; 291 } 292 } 293 294 /*! \file */ 295