GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libc/net/getprotoent.c Lines: 0 76 0.0 %
Date: 2017-11-07 Branches: 0 56 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: getprotoent.c,v 1.13 2015/09/14 07:38:38 guenther Exp $ */
2
/*
3
 * Copyright (c) 1983, 1993
4
 *	The Regents of the University of California.  All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 * 3. Neither the name of the University nor the names of its contributors
15
 *    may be used to endorse or promote products derived from this software
16
 *    without specific prior written permission.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
 * SUCH DAMAGE.
29
 */
30
31
#include <sys/types.h>
32
#include <sys/socket.h>
33
34
#include <errno.h>
35
#include <limits.h>
36
#include <netdb.h>
37
#include <stdio.h>
38
#include <stdlib.h>
39
#include <string.h>
40
41
void
42
setprotoent_r(int f, struct protoent_data *pd)
43
{
44
	if (pd->fp == NULL)
45
		pd->fp = fopen(_PATH_PROTOCOLS, "re" );
46
	else
47
		rewind(pd->fp);
48
	pd->stayopen |= f;
49
}
50
DEF_WEAK(setprotoent_r);
51
52
void
53
endprotoent_r(struct protoent_data *pd)
54
{
55
	if (pd->fp) {
56
		fclose(pd->fp);
57
		pd->fp = NULL;
58
	}
59
	free(pd->aliases);
60
	pd->aliases = NULL;
61
	pd->maxaliases = 0;
62
	free(pd->line);
63
	pd->line = NULL;
64
	pd->stayopen = 0;
65
}
66
DEF_WEAK(endprotoent_r);
67
68
int
69
getprotoent_r(struct protoent *pe, struct protoent_data *pd)
70
{
71
	char *p, *cp, **q, *endp;
72
	size_t len;
73
	long l;
74
	int serrno;
75
76
	if (pd->fp == NULL && (pd->fp = fopen(_PATH_PROTOCOLS, "re" )) == NULL)
77
		return (-1);
78
again:
79
	if ((p = fgetln(pd->fp, &len)) == NULL)
80
		return (-1);
81
	if (len == 0 || *p == '#' || *p == '\n')
82
		goto again;
83
	if (p[len-1] == '\n')
84
		len--;
85
	if ((cp = memchr(p, '#', len)) != NULL)
86
		len = cp - p;
87
	cp = realloc(pd->line, len + 1);
88
	if (cp == NULL)
89
		return (-1);
90
	pd->line = pe->p_name = memcpy(cp, p, len);
91
	cp[len] = '\0';
92
	cp = strpbrk(cp, " \t");
93
	if (cp == NULL)
94
		goto again;
95
	*cp++ = '\0';
96
	while (*cp == ' ' || *cp == '\t')
97
		cp++;
98
	p = strpbrk(cp, " \t");
99
	if (p != NULL)
100
		*p++ = '\0';
101
	l = strtol(cp, &endp, 10);
102
	if (endp == cp || *endp != '\0' || l < 0 || l >= INT_MAX)
103
		goto again;
104
	pe->p_proto = l;
105
	if (pd->aliases == NULL) {
106
		pd->maxaliases = 5;
107
		pd->aliases = calloc(pd->maxaliases, sizeof(char *));
108
		if (pd->aliases == NULL) {
109
			serrno = errno;
110
			endprotoent_r(pd);
111
			errno = serrno;
112
			return (-1);
113
		}
114
	}
115
	q = pe->p_aliases = pd->aliases;
116
	if (p != NULL) {
117
		cp = p;
118
		while (cp && *cp) {
119
			if (*cp == ' ' || *cp == '\t') {
120
				cp++;
121
				continue;
122
			}
123
			if (q == &pe->p_aliases[pd->maxaliases - 1]) {
124
				p = reallocarray(pe->p_aliases,
125
				    pd->maxaliases, 2 * sizeof(char *));
126
				if (p == NULL) {
127
					serrno = errno;
128
					endprotoent_r(pd);
129
					errno = serrno;
130
					return (-1);
131
				}
132
				pd->maxaliases *= 2;
133
				q = (char **)p + (q - pe->p_aliases);
134
				pe->p_aliases = pd->aliases = (char **)p;
135
			}
136
			*q++ = cp;
137
			cp = strpbrk(cp, " \t");
138
			if (cp != NULL)
139
				*cp++ = '\0';
140
		}
141
	}
142
	*q = NULL;
143
	return (0);
144
}
145
DEF_WEAK(getprotoent_r);
146
147
struct protoent_data _protoent_data;	/* shared with getproto{,name}.c */
148
149
void
150
setprotoent(int f)
151
{
152
	setprotoent_r(f, &_protoent_data);
153
}
154
155
void
156
endprotoent(void)
157
{
158
	endprotoent_r(&_protoent_data);
159
}
160
161
struct protoent *
162
getprotoent(void)
163
{
164
	static struct protoent proto;
165
166
	if (getprotoent_r(&proto, &_protoent_data) != 0)
167
		return (NULL);
168
	return (&proto);
169
}