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 #include "port_before.h" 52 53 #include <sys/types.h> 54 #include <netinet/in.h> 55 #include <arpa/nameser.h> 56 #include <resolv.h> 57 58 #include <errno.h> 59 #include <fcntl.h> 60 #include <string.h> 61 #include <stdio.h> 62 #include <stdlib.h> 63 64 #include <irs.h> 65 #include <isc/memcluster.h> 66 67 #include "port_after.h" 68 69 #include "irs_p.h" 70 #include "lcl_p.h" 71 72 #ifndef _PATH_PROTOCOLS 73 #define _PATH_PROTOCOLS "/etc/protocols" 74 #endif 75 #define MAXALIASES 35 76 77 /* Types */ 78 79 struct pvt { 80 FILE * fp; 81 char line[BUFSIZ+1]; 82 char * dbuf; 83 struct protoent proto; 84 char * proto_aliases[MAXALIASES]; 85 }; 86 87 /* Forward */ 88 89 static void pr_close(struct irs_pr *); 90 static struct protoent * pr_next(struct irs_pr *); 91 static struct protoent * pr_byname(struct irs_pr *, const char *); 92 static struct protoent * pr_bynumber(struct irs_pr *, int); 93 static void pr_rewind(struct irs_pr *); 94 static void pr_minimize(struct irs_pr *); 95 96 /* Portability. */ 97 98 #ifndef SEEK_SET 99 # define SEEK_SET 0 100 #endif 101 102 /* Public */ 103 104 struct irs_pr * 105 irs_lcl_pr(struct irs_acc *this) { 106 struct irs_pr *pr; 107 struct pvt *pvt; 108 109 if (!(pr = memget(sizeof *pr))) { 110 errno = ENOMEM; 111 return (NULL); 112 } 113 if (!(pvt = memget(sizeof *pvt))) { 114 memput(pr, sizeof *this); 115 errno = ENOMEM; 116 return (NULL); 117 } 118 memset(pvt, 0, sizeof *pvt); 119 pr->private = pvt; 120 pr->close = pr_close; 121 pr->byname = pr_byname; 122 pr->bynumber = pr_bynumber; 123 pr->next = pr_next; 124 pr->rewind = pr_rewind; 125 pr->minimize = pr_minimize; 126 pr->res_get = NULL; 127 pr->res_set = NULL; 128 return (pr); 129 } 130 131 /* Methods */ 132 133 static void 134 pr_close(struct irs_pr *this) { 135 struct pvt *pvt = (struct pvt *)this->private; 136 137 if (pvt->fp) 138 (void) fclose(pvt->fp); 139 if (pvt->dbuf) 140 free(pvt->dbuf); 141 memput(pvt, sizeof *pvt); 142 memput(this, sizeof *this); 143 } 144 145 static struct protoent * 146 pr_byname(struct irs_pr *this, const char *name) { 147 148 struct protoent *p; 149 char **cp; 150 151 pr_rewind(this); 152 while ((p = pr_next(this))) { 153 if (!strcmp(p->p_name, name)) 154 goto found; 155 for (cp = p->p_aliases; *cp; cp++) 156 if (!strcmp(*cp, name)) 157 goto found; 158 } 159 found: 160 return (p); 161 } 162 163 static struct protoent * 164 pr_bynumber(struct irs_pr *this, int proto) { 165 struct protoent *p; 166 167 pr_rewind(this); 168 while ((p = pr_next(this))) 169 if (p->p_proto == proto) 170 break; 171 return (p); 172 } 173 174 static void 175 pr_rewind(struct irs_pr *this) { 176 struct pvt *pvt = (struct pvt *)this->private; 177 178 if (pvt->fp) { 179 if (fseek(pvt->fp, 0L, SEEK_SET) == 0) 180 return; 181 (void)fclose(pvt->fp); 182 } 183 if (!(pvt->fp = fopen(_PATH_PROTOCOLS, "r" ))) 184 return; 185 if (fcntl(fileno(pvt->fp), F_SETFD, 1) < 0) { 186 (void)fclose(pvt->fp); 187 pvt->fp = NULL; 188 } 189 } 190 191 static struct protoent * 192 pr_next(struct irs_pr *this) { 193 struct pvt *pvt = (struct pvt *)this->private; 194 char *p, *cp, **q; 195 char *bufp, *ndbuf, *dbuf = NULL; 196 int c, bufsiz, offset; 197 198 if (!pvt->fp) 199 pr_rewind(this); 200 if (!pvt->fp) 201 return (NULL); 202 if (pvt->dbuf) { 203 free(pvt->dbuf); 204 pvt->dbuf = NULL; 205 } 206 bufp = pvt->line; 207 bufsiz = BUFSIZ; 208 offset = 0; 209 again: 210 if ((p = fgets(bufp + offset, bufsiz - offset, pvt->fp)) == NULL) { 211 if (dbuf) 212 free(dbuf); 213 return (NULL); 214 } 215 if (!strchr(p, '\n') && !feof(pvt->fp)) { 216 #define GROWBUF 1024 217 /* allocate space for longer line */ 218 if (dbuf == NULL) { 219 if ((ndbuf = malloc(bufsiz + GROWBUF)) != NULL) 220 strcpy(ndbuf, bufp); 221 } else 222 ndbuf = realloc(dbuf, bufsiz + GROWBUF); 223 if (ndbuf) { 224 dbuf = ndbuf; 225 bufp = dbuf; 226 bufsiz += GROWBUF; 227 offset = strlen(dbuf); 228 } else { 229 /* allocation failed; skip this long line */ 230 while ((c = getc(pvt->fp)) != EOF) 231 if (c == '\n') 232 break; 233 if (c != EOF) 234 ungetc(c, pvt->fp); 235 } 236 goto again; 237 } 238 239 p -= offset; 240 offset = 0; 241 242 if (*p == '#') 243 goto again; 244 cp = strpbrk(p, "#\n"); 245 if (cp != NULL) 246 *cp = '\0'; 247 pvt->proto.p_name = p; 248 cp = strpbrk(p, " \t"); 249 if (cp == NULL) 250 goto again; 251 *cp++ = '\0'; 252 while (*cp == ' ' || *cp == '\t') 253 cp++; 254 p = strpbrk(cp, " \t"); 255 if (p != NULL) 256 *p++ = '\0'; 257 pvt->proto.p_proto = atoi(cp); 258 q = pvt->proto.p_aliases = pvt->proto_aliases; 259 if (p != NULL) { 260 cp = p; 261 while (cp && *cp) { 262 if (*cp == ' ' || *cp == '\t') { 263 cp++; 264 continue; 265 } 266 if (q < &pvt->proto_aliases[MAXALIASES - 1]) 267 *q++ = cp; 268 cp = strpbrk(cp, " \t"); 269 if (cp != NULL) 270 *cp++ = '\0'; 271 } 272 } 273 *q = NULL; 274 pvt->dbuf = dbuf; 275 return (&pvt->proto); 276 } 277 278 static void 279 pr_minimize(struct irs_pr *this) { 280 struct pvt *pvt = (struct pvt *)this->private; 281 282 if (pvt->fp != NULL) { 283 (void)fclose(pvt->fp); 284 pvt->fp = NULL; 285 } 286 } 287 288 /*! \file */ 289