getprotoent.c revision 145279
11573Srgrimes/* 21573Srgrimes * Copyright (c) 1983, 1993 31573Srgrimes * The Regents of the University of California. All rights reserved. 41573Srgrimes * 51573Srgrimes * Redistribution and use in source and binary forms, with or without 61573Srgrimes * modification, are permitted provided that the following conditions 71573Srgrimes * are met: 81573Srgrimes * 1. Redistributions of source code must retain the above copyright 91573Srgrimes * notice, this list of conditions and the following disclaimer. 101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111573Srgrimes * notice, this list of conditions and the following disclaimer in the 121573Srgrimes * documentation and/or other materials provided with the distribution. 131573Srgrimes * 3. All advertising materials mentioning features or use of this software 141573Srgrimes * must display the following acknowledgement: 151573Srgrimes * This product includes software developed by the University of 161573Srgrimes * California, Berkeley and its contributors. 171573Srgrimes * 4. Neither the name of the University nor the names of its contributors 181573Srgrimes * may be used to endorse or promote products derived from this software 191573Srgrimes * without specific prior written permission. 201573Srgrimes * 211573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311573Srgrimes * SUCH DAMAGE. 321573Srgrimes */ 331573Srgrimes 341573Srgrimes#if defined(LIBC_SCCS) && !defined(lint) 351573Srgrimesstatic char sccsid[] = "@(#)getprotoent.c 8.1 (Berkeley) 6/4/93"; 361573Srgrimes#endif /* LIBC_SCCS and not lint */ 3792889Sobrien#include <sys/cdefs.h> 3892889Sobrien__FBSDID("$FreeBSD: head/lib/libc/net/getprotoent.c 145279 2005-04-19 14:41:13Z ume $"); 391573Srgrimes 401573Srgrimes#include <sys/types.h> 411573Srgrimes#include <sys/socket.h> 421573Srgrimes#include <netdb.h> 431573Srgrimes#include <stdio.h> 441573Srgrimes#include <stdlib.h> 451573Srgrimes#include <string.h> 46145279Sume#include "namespace.h" 47145279Sume#include "reentrant.h" 48145279Sume#include "un-namespace.h" 49145279Sume#include "netdb_private.h" 501573Srgrimes 51145279Sumestatic struct protodata protodata; 52145279Sumestatic thread_key_t protodata_key; 53145279Sumestatic once_t protodata_init_once = ONCE_INITIALIZER; 54145279Sumestatic int protodata_thr_keycreated = 0; 551573Srgrimes 56145279Sumestatic void 57145279Sumeprotoent_data_clear(struct protoent_data *ped) 58145279Sume{ 59145279Sume if (ped->fp) { 60145279Sume fclose(ped->fp); 61145279Sume ped->fp = NULL; 62145279Sume } 63145279Sume} 641573Srgrimes 65145279Sumestatic void 66145279Sumeprotodata_free(void *ptr) 67145279Sume{ 68145279Sume struct protodata *pd = ptr; 69145279Sume 70145279Sume if (pd == NULL) 71145279Sume return; 72145279Sume protoent_data_clear(&pd->data); 73145279Sume free(pd); 74145279Sume} 75145279Sume 76145279Sumestatic void 77145279Sumeprotodata_keycreate(void) 78145279Sume{ 79145279Sume protodata_thr_keycreated = 80145279Sume (thr_keycreate(&protodata_key, protodata_free) == 0); 81145279Sume} 82145279Sume 83145279Sumestruct protodata * 84145279Sume__protodata_init(void) 85145279Sume{ 86145279Sume struct protodata *pd; 87145279Sume 88145279Sume if (thr_main() != 0) 89145279Sume return (&protodata); 90145279Sume if (thr_once(&protodata_init_once, protodata_keycreate) != 0 || 91145279Sume !protodata_thr_keycreated) 92145279Sume return (NULL); 93145279Sume if ((pd = thr_getspecific(protodata_key)) != NULL) 94145279Sume return (pd); 95145279Sume if ((pd = calloc(1, sizeof(*pd))) == NULL) 96145279Sume return (NULL); 97145279Sume if (thr_setspecific(protodata_key, pd) == 0) 98145279Sume return (pd); 99145279Sume free(pd); 100145279Sume return (NULL); 101145279Sume} 102145279Sume 1031573Srgrimesvoid 104145279Sumesetprotoent_r(int f, struct protoent_data *ped) 1051573Srgrimes{ 106145279Sume if (ped->fp == NULL) 107145279Sume ped->fp = fopen(_PATH_PROTOCOLS, "r"); 1081573Srgrimes else 109145279Sume rewind(ped->fp); 110145279Sume ped->stayopen |= f; 1111573Srgrimes} 1121573Srgrimes 1131573Srgrimesvoid 114145279Sumeendprotoent_r(struct protoent_data *ped) 1151573Srgrimes{ 116145279Sume if (ped->fp) { 117145279Sume fclose(ped->fp); 118145279Sume ped->fp = NULL; 1191573Srgrimes } 120145279Sume ped->stayopen = 0; 1211573Srgrimes} 1221573Srgrimes 123145279Sumeint 124145279Sumegetprotoent_r(struct protoent *pe, struct protoent_data *ped) 1251573Srgrimes{ 1261573Srgrimes char *p; 127145279Sume char *cp, **q, *endp; 128145279Sume long l; 1291573Srgrimes 130145279Sume if (ped->fp == NULL && (ped->fp = fopen(_PATH_PROTOCOLS, "r")) == NULL) 131145279Sume return (-1); 1321573Srgrimesagain: 133145279Sume if ((p = fgets(ped->line, BUFSIZ, ped->fp)) == NULL) 134145279Sume return (-1); 1351573Srgrimes if (*p == '#') 1361573Srgrimes goto again; 1371573Srgrimes cp = strpbrk(p, "#\n"); 138139612Ssobomax if (cp != NULL) 139139612Ssobomax *cp = '\0'; 140145279Sume pe->p_name = p; 1411573Srgrimes cp = strpbrk(p, " \t"); 1421573Srgrimes if (cp == NULL) 1431573Srgrimes goto again; 1441573Srgrimes *cp++ = '\0'; 1451573Srgrimes while (*cp == ' ' || *cp == '\t') 1461573Srgrimes cp++; 1471573Srgrimes p = strpbrk(cp, " \t"); 1481573Srgrimes if (p != NULL) 1491573Srgrimes *p++ = '\0'; 150145279Sume l = strtol(cp, &endp, 10); 151145279Sume if (endp == cp || *endp != '\0' || l < 0 || l > USHRT_MAX) 152145279Sume goto again; 153145279Sume pe->p_proto = l; 154145279Sume q = pe->p_aliases = ped->aliases; 1551573Srgrimes if (p != NULL) { 1561573Srgrimes cp = p; 1571573Srgrimes while (cp && *cp) { 1581573Srgrimes if (*cp == ' ' || *cp == '\t') { 1591573Srgrimes cp++; 1601573Srgrimes continue; 1611573Srgrimes } 162145279Sume if (q < &ped->aliases[PROTOENT_MAXALIASES - 1]) 1631573Srgrimes *q++ = cp; 1641573Srgrimes cp = strpbrk(cp, " \t"); 1651573Srgrimes if (cp != NULL) 1661573Srgrimes *cp++ = '\0'; 1671573Srgrimes } 1681573Srgrimes } 1691573Srgrimes *q = NULL; 170145279Sume return (0); 1711573Srgrimes} 172145279Sume 173145279Sumevoid 174145279Sumesetprotoent(int f) 175145279Sume{ 176145279Sume struct protodata *pd; 177145279Sume 178145279Sume if ((pd = __protodata_init()) == NULL) 179145279Sume return; 180145279Sume setprotoent_r(f, &pd->data); 181145279Sume} 182145279Sume 183145279Sumevoid 184145279Sumeendprotoent(void) 185145279Sume{ 186145279Sume struct protodata *pd; 187145279Sume 188145279Sume if ((pd = __protodata_init()) == NULL) 189145279Sume return; 190145279Sume endprotoent_r(&pd->data); 191145279Sume} 192145279Sume 193145279Sumestruct protoent * 194145279Sumegetprotoent(void) 195145279Sume{ 196145279Sume struct protodata *pd; 197145279Sume 198145279Sume if ((pd = __protodata_init()) == NULL) 199145279Sume return (NULL); 200145279Sume if (getprotoent_r(&pd->proto, &pd->data) != 0) 201145279Sume return (NULL); 202145279Sume return (&pd->proto); 203145279Sume} 204