xref: /freebsd/lib/libc/net/getprotoent.c (revision d8f77b45290fd175d136d87aa80b6dea46c483fe)
158f0484fSRodney W. Grimes /*
258f0484fSRodney W. Grimes  * Copyright (c) 1983, 1993
358f0484fSRodney W. Grimes  *	The Regents of the University of California.  All rights reserved.
458f0484fSRodney W. Grimes  *
558f0484fSRodney W. Grimes  * Redistribution and use in source and binary forms, with or without
658f0484fSRodney W. Grimes  * modification, are permitted provided that the following conditions
758f0484fSRodney W. Grimes  * are met:
858f0484fSRodney W. Grimes  * 1. Redistributions of source code must retain the above copyright
958f0484fSRodney W. Grimes  *    notice, this list of conditions and the following disclaimer.
1058f0484fSRodney W. Grimes  * 2. Redistributions in binary form must reproduce the above copyright
1158f0484fSRodney W. Grimes  *    notice, this list of conditions and the following disclaimer in the
1258f0484fSRodney W. Grimes  *    documentation and/or other materials provided with the distribution.
1358f0484fSRodney W. Grimes  * 3. All advertising materials mentioning features or use of this software
1458f0484fSRodney W. Grimes  *    must display the following acknowledgement:
1558f0484fSRodney W. Grimes  *	This product includes software developed by the University of
1658f0484fSRodney W. Grimes  *	California, Berkeley and its contributors.
1758f0484fSRodney W. Grimes  * 4. Neither the name of the University nor the names of its contributors
1858f0484fSRodney W. Grimes  *    may be used to endorse or promote products derived from this software
1958f0484fSRodney W. Grimes  *    without specific prior written permission.
2058f0484fSRodney W. Grimes  *
2158f0484fSRodney W. Grimes  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2258f0484fSRodney W. Grimes  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2358f0484fSRodney W. Grimes  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2458f0484fSRodney W. Grimes  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2558f0484fSRodney W. Grimes  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2658f0484fSRodney W. Grimes  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2758f0484fSRodney W. Grimes  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2858f0484fSRodney W. Grimes  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2958f0484fSRodney W. Grimes  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3058f0484fSRodney W. Grimes  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3158f0484fSRodney W. Grimes  * SUCH DAMAGE.
3258f0484fSRodney W. Grimes  */
3358f0484fSRodney W. Grimes 
3458f0484fSRodney W. Grimes #if defined(LIBC_SCCS) && !defined(lint)
3558f0484fSRodney W. Grimes static char sccsid[] = "@(#)getprotoent.c	8.1 (Berkeley) 6/4/93";
3658f0484fSRodney W. Grimes #endif /* LIBC_SCCS and not lint */
378fb3f3f6SDavid E. O'Brien #include <sys/cdefs.h>
388fb3f3f6SDavid E. O'Brien __FBSDID("$FreeBSD$");
3958f0484fSRodney W. Grimes 
4058f0484fSRodney W. Grimes #include <sys/types.h>
4158f0484fSRodney W. Grimes #include <sys/socket.h>
42d8f77b45SStefan Farfeleder #include <limits.h>
4358f0484fSRodney W. Grimes #include <netdb.h>
4458f0484fSRodney W. Grimes #include <stdio.h>
4558f0484fSRodney W. Grimes #include <stdlib.h>
4658f0484fSRodney W. Grimes #include <string.h>
4792b6f7beSHajimu UMEMOTO #include "namespace.h"
4892b6f7beSHajimu UMEMOTO #include "reentrant.h"
4992b6f7beSHajimu UMEMOTO #include "un-namespace.h"
5092b6f7beSHajimu UMEMOTO #include "netdb_private.h"
5158f0484fSRodney W. Grimes 
5292b6f7beSHajimu UMEMOTO static struct protodata protodata;
5392b6f7beSHajimu UMEMOTO static thread_key_t protodata_key;
5492b6f7beSHajimu UMEMOTO static once_t protodata_init_once = ONCE_INITIALIZER;
5592b6f7beSHajimu UMEMOTO static int protodata_thr_keycreated = 0;
5658f0484fSRodney W. Grimes 
5792b6f7beSHajimu UMEMOTO static void
5892b6f7beSHajimu UMEMOTO protoent_data_clear(struct protoent_data *ped)
5992b6f7beSHajimu UMEMOTO {
6092b6f7beSHajimu UMEMOTO 	if (ped->fp) {
6192b6f7beSHajimu UMEMOTO 		fclose(ped->fp);
6292b6f7beSHajimu UMEMOTO 		ped->fp = NULL;
6392b6f7beSHajimu UMEMOTO 	}
6492b6f7beSHajimu UMEMOTO }
6592b6f7beSHajimu UMEMOTO 
6692b6f7beSHajimu UMEMOTO static void
6792b6f7beSHajimu UMEMOTO protodata_free(void *ptr)
6892b6f7beSHajimu UMEMOTO {
6992b6f7beSHajimu UMEMOTO 	struct protodata *pd = ptr;
7092b6f7beSHajimu UMEMOTO 
7192b6f7beSHajimu UMEMOTO 	if (pd == NULL)
7292b6f7beSHajimu UMEMOTO 		return;
7392b6f7beSHajimu UMEMOTO 	protoent_data_clear(&pd->data);
7492b6f7beSHajimu UMEMOTO 	free(pd);
7592b6f7beSHajimu UMEMOTO }
7692b6f7beSHajimu UMEMOTO 
7792b6f7beSHajimu UMEMOTO static void
7892b6f7beSHajimu UMEMOTO protodata_keycreate(void)
7992b6f7beSHajimu UMEMOTO {
8092b6f7beSHajimu UMEMOTO 	protodata_thr_keycreated =
8192b6f7beSHajimu UMEMOTO 	    (thr_keycreate(&protodata_key, protodata_free) == 0);
8292b6f7beSHajimu UMEMOTO }
8392b6f7beSHajimu UMEMOTO 
8492b6f7beSHajimu UMEMOTO struct protodata *
8592b6f7beSHajimu UMEMOTO __protodata_init(void)
8692b6f7beSHajimu UMEMOTO {
8792b6f7beSHajimu UMEMOTO 	struct protodata *pd;
8892b6f7beSHajimu UMEMOTO 
8992b6f7beSHajimu UMEMOTO 	if (thr_main() != 0)
9092b6f7beSHajimu UMEMOTO 		return (&protodata);
9192b6f7beSHajimu UMEMOTO 	if (thr_once(&protodata_init_once, protodata_keycreate) != 0 ||
9292b6f7beSHajimu UMEMOTO 	    !protodata_thr_keycreated)
9392b6f7beSHajimu UMEMOTO 		return (NULL);
9492b6f7beSHajimu UMEMOTO 	if ((pd = thr_getspecific(protodata_key)) != NULL)
9592b6f7beSHajimu UMEMOTO 		return (pd);
9692b6f7beSHajimu UMEMOTO 	if ((pd = calloc(1, sizeof(*pd))) == NULL)
9792b6f7beSHajimu UMEMOTO 		return (NULL);
9892b6f7beSHajimu UMEMOTO 	if (thr_setspecific(protodata_key, pd) == 0)
9992b6f7beSHajimu UMEMOTO 		return (pd);
10092b6f7beSHajimu UMEMOTO 	free(pd);
10192b6f7beSHajimu UMEMOTO 	return (NULL);
10292b6f7beSHajimu UMEMOTO }
10358f0484fSRodney W. Grimes 
10458f0484fSRodney W. Grimes void
10592b6f7beSHajimu UMEMOTO setprotoent_r(int f, struct protoent_data *ped)
10658f0484fSRodney W. Grimes {
10792b6f7beSHajimu UMEMOTO 	if (ped->fp == NULL)
10892b6f7beSHajimu UMEMOTO 		ped->fp = fopen(_PATH_PROTOCOLS, "r");
10958f0484fSRodney W. Grimes 	else
11092b6f7beSHajimu UMEMOTO 		rewind(ped->fp);
11192b6f7beSHajimu UMEMOTO 	ped->stayopen |= f;
11258f0484fSRodney W. Grimes }
11358f0484fSRodney W. Grimes 
11458f0484fSRodney W. Grimes void
11592b6f7beSHajimu UMEMOTO endprotoent_r(struct protoent_data *ped)
11658f0484fSRodney W. Grimes {
11792b6f7beSHajimu UMEMOTO 	if (ped->fp) {
11892b6f7beSHajimu UMEMOTO 		fclose(ped->fp);
11992b6f7beSHajimu UMEMOTO 		ped->fp = NULL;
12058f0484fSRodney W. Grimes 	}
12192b6f7beSHajimu UMEMOTO 	ped->stayopen = 0;
12258f0484fSRodney W. Grimes }
12358f0484fSRodney W. Grimes 
12492b6f7beSHajimu UMEMOTO int
12592b6f7beSHajimu UMEMOTO getprotoent_r(struct protoent *pe, struct protoent_data *ped)
12658f0484fSRodney W. Grimes {
12758f0484fSRodney W. Grimes 	char *p;
12892b6f7beSHajimu UMEMOTO 	char *cp, **q, *endp;
12992b6f7beSHajimu UMEMOTO 	long l;
13058f0484fSRodney W. Grimes 
13192b6f7beSHajimu UMEMOTO 	if (ped->fp == NULL && (ped->fp = fopen(_PATH_PROTOCOLS, "r")) == NULL)
13292b6f7beSHajimu UMEMOTO 		return (-1);
13358f0484fSRodney W. Grimes again:
134a2a77501SHajimu UMEMOTO 	if ((p = fgets(ped->line, sizeof ped->line, ped->fp)) == NULL)
13592b6f7beSHajimu UMEMOTO 		return (-1);
13658f0484fSRodney W. Grimes 	if (*p == '#')
13758f0484fSRodney W. Grimes 		goto again;
13858f0484fSRodney W. Grimes 	cp = strpbrk(p, "#\n");
1397b6cc404SMaxim Sobolev 	if (cp != NULL)
14058f0484fSRodney W. Grimes 		*cp = '\0';
14192b6f7beSHajimu UMEMOTO 	pe->p_name = p;
14258f0484fSRodney W. Grimes 	cp = strpbrk(p, " \t");
14358f0484fSRodney W. Grimes 	if (cp == NULL)
14458f0484fSRodney W. Grimes 		goto again;
14558f0484fSRodney W. Grimes 	*cp++ = '\0';
14658f0484fSRodney W. Grimes 	while (*cp == ' ' || *cp == '\t')
14758f0484fSRodney W. Grimes 		cp++;
14858f0484fSRodney W. Grimes 	p = strpbrk(cp, " \t");
14958f0484fSRodney W. Grimes 	if (p != NULL)
15058f0484fSRodney W. Grimes 		*p++ = '\0';
15192b6f7beSHajimu UMEMOTO 	l = strtol(cp, &endp, 10);
15292b6f7beSHajimu UMEMOTO 	if (endp == cp || *endp != '\0' || l < 0 || l > USHRT_MAX)
15392b6f7beSHajimu UMEMOTO 		goto again;
15492b6f7beSHajimu UMEMOTO 	pe->p_proto = l;
15592b6f7beSHajimu UMEMOTO 	q = pe->p_aliases = ped->aliases;
15658f0484fSRodney W. Grimes 	if (p != NULL) {
15758f0484fSRodney W. Grimes 		cp = p;
15858f0484fSRodney W. Grimes 		while (cp && *cp) {
15958f0484fSRodney W. Grimes 			if (*cp == ' ' || *cp == '\t') {
16058f0484fSRodney W. Grimes 				cp++;
16158f0484fSRodney W. Grimes 				continue;
16258f0484fSRodney W. Grimes 			}
163a2a77501SHajimu UMEMOTO 			if (q < &ped->aliases[_MAXALIASES - 1])
16458f0484fSRodney W. Grimes 				*q++ = cp;
16558f0484fSRodney W. Grimes 			cp = strpbrk(cp, " \t");
16658f0484fSRodney W. Grimes 			if (cp != NULL)
16758f0484fSRodney W. Grimes 				*cp++ = '\0';
16858f0484fSRodney W. Grimes 		}
16958f0484fSRodney W. Grimes 	}
17058f0484fSRodney W. Grimes 	*q = NULL;
17192b6f7beSHajimu UMEMOTO 	return (0);
17292b6f7beSHajimu UMEMOTO }
17392b6f7beSHajimu UMEMOTO 
17492b6f7beSHajimu UMEMOTO void
17592b6f7beSHajimu UMEMOTO setprotoent(int f)
17692b6f7beSHajimu UMEMOTO {
17792b6f7beSHajimu UMEMOTO 	struct protodata *pd;
17892b6f7beSHajimu UMEMOTO 
17992b6f7beSHajimu UMEMOTO 	if ((pd = __protodata_init()) == NULL)
18092b6f7beSHajimu UMEMOTO 		return;
18192b6f7beSHajimu UMEMOTO 	setprotoent_r(f, &pd->data);
18292b6f7beSHajimu UMEMOTO }
18392b6f7beSHajimu UMEMOTO 
18492b6f7beSHajimu UMEMOTO void
18592b6f7beSHajimu UMEMOTO endprotoent(void)
18692b6f7beSHajimu UMEMOTO {
18792b6f7beSHajimu UMEMOTO 	struct protodata *pd;
18892b6f7beSHajimu UMEMOTO 
18992b6f7beSHajimu UMEMOTO 	if ((pd = __protodata_init()) == NULL)
19092b6f7beSHajimu UMEMOTO 		return;
19192b6f7beSHajimu UMEMOTO 	endprotoent_r(&pd->data);
19292b6f7beSHajimu UMEMOTO }
19392b6f7beSHajimu UMEMOTO 
19492b6f7beSHajimu UMEMOTO struct protoent *
19592b6f7beSHajimu UMEMOTO getprotoent(void)
19692b6f7beSHajimu UMEMOTO {
19792b6f7beSHajimu UMEMOTO 	struct protodata *pd;
19892b6f7beSHajimu UMEMOTO 
19992b6f7beSHajimu UMEMOTO 	if ((pd = __protodata_init()) == NULL)
20092b6f7beSHajimu UMEMOTO 		return (NULL);
20192b6f7beSHajimu UMEMOTO 	if (getprotoent_r(&pd->proto, &pd->data) != 0)
20292b6f7beSHajimu UMEMOTO 		return (NULL);
20392b6f7beSHajimu UMEMOTO 	return (&pd->proto);
20458f0484fSRodney W. Grimes }
205