getprotoent.c revision 149313
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 149313 2005-08-20 07:59:13Z stefanf $"); 391573Srgrimes 401573Srgrimes#include <sys/types.h> 411573Srgrimes#include <sys/socket.h> 42149313Sstefanf#include <limits.h> 431573Srgrimes#include <netdb.h> 441573Srgrimes#include <stdio.h> 451573Srgrimes#include <stdlib.h> 461573Srgrimes#include <string.h> 47145279Sume#include "namespace.h" 48145279Sume#include "reentrant.h" 49145279Sume#include "un-namespace.h" 50145279Sume#include "netdb_private.h" 511573Srgrimes 52145279Sumestatic struct protodata protodata; 53145279Sumestatic thread_key_t protodata_key; 54145279Sumestatic once_t protodata_init_once = ONCE_INITIALIZER; 55145279Sumestatic int protodata_thr_keycreated = 0; 561573Srgrimes 57145279Sumestatic void 58145279Sumeprotoent_data_clear(struct protoent_data *ped) 59145279Sume{ 60145279Sume if (ped->fp) { 61145279Sume fclose(ped->fp); 62145279Sume ped->fp = NULL; 63145279Sume } 64145279Sume} 651573Srgrimes 66145279Sumestatic void 67145279Sumeprotodata_free(void *ptr) 68145279Sume{ 69145279Sume struct protodata *pd = ptr; 70145279Sume 71145279Sume if (pd == NULL) 72145279Sume return; 73145279Sume protoent_data_clear(&pd->data); 74145279Sume free(pd); 75145279Sume} 76145279Sume 77145279Sumestatic void 78145279Sumeprotodata_keycreate(void) 79145279Sume{ 80145279Sume protodata_thr_keycreated = 81145279Sume (thr_keycreate(&protodata_key, protodata_free) == 0); 82145279Sume} 83145279Sume 84145279Sumestruct protodata * 85145279Sume__protodata_init(void) 86145279Sume{ 87145279Sume struct protodata *pd; 88145279Sume 89145279Sume if (thr_main() != 0) 90145279Sume return (&protodata); 91145279Sume if (thr_once(&protodata_init_once, protodata_keycreate) != 0 || 92145279Sume !protodata_thr_keycreated) 93145279Sume return (NULL); 94145279Sume if ((pd = thr_getspecific(protodata_key)) != NULL) 95145279Sume return (pd); 96145279Sume if ((pd = calloc(1, sizeof(*pd))) == NULL) 97145279Sume return (NULL); 98145279Sume if (thr_setspecific(protodata_key, pd) == 0) 99145279Sume return (pd); 100145279Sume free(pd); 101145279Sume return (NULL); 102145279Sume} 103145279Sume 1041573Srgrimesvoid 105145279Sumesetprotoent_r(int f, struct protoent_data *ped) 1061573Srgrimes{ 107145279Sume if (ped->fp == NULL) 108145279Sume ped->fp = fopen(_PATH_PROTOCOLS, "r"); 1091573Srgrimes else 110145279Sume rewind(ped->fp); 111145279Sume ped->stayopen |= f; 1121573Srgrimes} 1131573Srgrimes 1141573Srgrimesvoid 115145279Sumeendprotoent_r(struct protoent_data *ped) 1161573Srgrimes{ 117145279Sume if (ped->fp) { 118145279Sume fclose(ped->fp); 119145279Sume ped->fp = NULL; 1201573Srgrimes } 121145279Sume ped->stayopen = 0; 1221573Srgrimes} 1231573Srgrimes 124145279Sumeint 125145279Sumegetprotoent_r(struct protoent *pe, struct protoent_data *ped) 1261573Srgrimes{ 1271573Srgrimes char *p; 128145279Sume char *cp, **q, *endp; 129145279Sume long l; 1301573Srgrimes 131145279Sume if (ped->fp == NULL && (ped->fp = fopen(_PATH_PROTOCOLS, "r")) == NULL) 132145279Sume return (-1); 1331573Srgrimesagain: 134145626Sume if ((p = fgets(ped->line, sizeof ped->line, ped->fp)) == NULL) 135145279Sume return (-1); 1361573Srgrimes if (*p == '#') 1371573Srgrimes goto again; 1381573Srgrimes cp = strpbrk(p, "#\n"); 139139612Ssobomax if (cp != NULL) 140139612Ssobomax *cp = '\0'; 141145279Sume pe->p_name = p; 1421573Srgrimes cp = strpbrk(p, " \t"); 1431573Srgrimes if (cp == NULL) 1441573Srgrimes goto again; 1451573Srgrimes *cp++ = '\0'; 1461573Srgrimes while (*cp == ' ' || *cp == '\t') 1471573Srgrimes cp++; 1481573Srgrimes p = strpbrk(cp, " \t"); 1491573Srgrimes if (p != NULL) 1501573Srgrimes *p++ = '\0'; 151145279Sume l = strtol(cp, &endp, 10); 152145279Sume if (endp == cp || *endp != '\0' || l < 0 || l > USHRT_MAX) 153145279Sume goto again; 154145279Sume pe->p_proto = l; 155145279Sume q = pe->p_aliases = ped->aliases; 1561573Srgrimes if (p != NULL) { 1571573Srgrimes cp = p; 1581573Srgrimes while (cp && *cp) { 1591573Srgrimes if (*cp == ' ' || *cp == '\t') { 1601573Srgrimes cp++; 1611573Srgrimes continue; 1621573Srgrimes } 163145626Sume if (q < &ped->aliases[_MAXALIASES - 1]) 1641573Srgrimes *q++ = cp; 1651573Srgrimes cp = strpbrk(cp, " \t"); 1661573Srgrimes if (cp != NULL) 1671573Srgrimes *cp++ = '\0'; 1681573Srgrimes } 1691573Srgrimes } 1701573Srgrimes *q = NULL; 171145279Sume return (0); 1721573Srgrimes} 173145279Sume 174145279Sumevoid 175145279Sumesetprotoent(int f) 176145279Sume{ 177145279Sume struct protodata *pd; 178145279Sume 179145279Sume if ((pd = __protodata_init()) == NULL) 180145279Sume return; 181145279Sume setprotoent_r(f, &pd->data); 182145279Sume} 183145279Sume 184145279Sumevoid 185145279Sumeendprotoent(void) 186145279Sume{ 187145279Sume struct protodata *pd; 188145279Sume 189145279Sume if ((pd = __protodata_init()) == NULL) 190145279Sume return; 191145279Sume endprotoent_r(&pd->data); 192145279Sume} 193145279Sume 194145279Sumestruct protoent * 195145279Sumegetprotoent(void) 196145279Sume{ 197145279Sume struct protodata *pd; 198145279Sume 199145279Sume if ((pd = __protodata_init()) == NULL) 200145279Sume return (NULL); 201145279Sume if (getprotoent_r(&pd->proto, &pd->data) != 0) 202145279Sume return (NULL); 203145279Sume return (&pd->proto); 204145279Sume} 205