xref: /freebsd/lib/libc/net/getservent.c (revision 0ea3482342b4d7d6e71f3007ce4dafe445c639fd)
1 /*
2  * Copyright (c) 1983, 1993
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 #if defined(LIBC_SCCS) && !defined(lint)
35 static char sccsid[] = "@(#)getservent.c	8.1 (Berkeley) 6/4/93";
36 #endif /* LIBC_SCCS and not lint */
37 
38 #include <sys/types.h>
39 #include <sys/socket.h>
40 #include <netdb.h>
41 #include <stdio.h>
42 #include <string.h>
43 #include <stdlib.h>
44 #ifdef YP
45 #include <rpc/rpc.h>
46 #include <rpcsvc/yp_prot.h>
47 #include <rpcsvc/ypclnt.h>
48 static int serv_stepping_yp = 0;
49 #endif
50 
51 #define	MAXALIASES	35
52 
53 static FILE *servf = NULL;
54 static char line[BUFSIZ+1];
55 static struct servent serv;
56 static char *serv_aliases[MAXALIASES];
57 int _serv_stayopen;
58 
59 #ifdef YP
60 static int
61 _getypservent(line)
62 	char *line;
63 {
64 	static char *key = NULL;
65 	static int keylen;
66 	static char *yp_domain = NULL;
67 	char *lastkey, *result;
68 	int resultlen;
69 	int rv;
70 
71 	if(!yp_domain) {
72 		if(yp_get_default_domain(&yp_domain))
73 			return (0);
74 	}
75 
76 	if (!serv_stepping_yp) {
77 		if (key)
78 			free(key);
79 		if ((rv = yp_first(yp_domain, "services.byname", &key, &keylen,
80 			     &result, &resultlen))) {
81 			free(result);
82 			serv_stepping_yp = 0;
83 			return(0);
84 		}
85 		serv_stepping_yp = 1;
86 	} else {
87 		lastkey = key;
88 		rv = yp_next(yp_domain, "services.byname", key, keylen, &key,
89 			     &keylen, &result, &resultlen);
90 		free(lastkey);
91 		if (rv) {
92 			serv_stepping_yp = 0;
93 			return (0);
94 		}
95 	}
96 
97 	strncpy(line, result, BUFSIZ - 1);
98 	/* getservent() expects lines terminated with \n -- make it happy */
99 	strcat(line, "\n");
100 
101 	free(result);
102 
103 	return(1);
104 }
105 #endif
106 
107 void
108 setservent(f)
109 	int f;
110 {
111 	if (servf == NULL)
112 		servf = fopen(_PATH_SERVICES, "r" );
113 	else
114 		rewind(servf);
115 	_serv_stayopen |= f;
116 }
117 
118 void
119 endservent()
120 {
121 	if (servf) {
122 		fclose(servf);
123 		servf = NULL;
124 	}
125 	_serv_stayopen = 0;
126 }
127 
128 struct servent *
129 getservent()
130 {
131 	char *p;
132 	register char *cp, **q;
133 
134 #ifdef YP
135 	if (serv_stepping_yp && _getypservent(line)) {
136 		p = (char *)&line;
137 		goto unpack;
138 	}
139 tryagain:
140 #endif
141 	if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL)
142 		return (NULL);
143 again:
144 	if ((p = fgets(line, BUFSIZ, servf)) == NULL)
145 		return (NULL);
146 #ifdef YP
147 	if (*p == '+') {
148 		if (!_getypservent(&line))
149 			goto tryagain;
150 	}
151 unpack:
152 #endif
153 	if (*p == '#')
154 		goto again;
155 	cp = strpbrk(p, "#\n");
156 	if (cp == NULL)
157 		goto again;
158 	*cp = '\0';
159 	serv.s_name = p;
160 	p = strpbrk(p, " \t");
161 	if (p == NULL)
162 		goto again;
163 	*p++ = '\0';
164 	while (*p == ' ' || *p == '\t')
165 		p++;
166 	cp = strpbrk(p, ",/");
167 	if (cp == NULL)
168 		goto again;
169 	*cp++ = '\0';
170 	serv.s_port = htons((u_short)atoi(p));
171 	serv.s_proto = cp;
172 	q = serv.s_aliases = serv_aliases;
173 	cp = strpbrk(cp, " \t");
174 	if (cp != NULL)
175 		*cp++ = '\0';
176 	while (cp && *cp) {
177 		if (*cp == ' ' || *cp == '\t') {
178 			cp++;
179 			continue;
180 		}
181 		if (q < &serv_aliases[MAXALIASES - 1])
182 			*q++ = cp;
183 		cp = strpbrk(cp, " \t");
184 		if (cp != NULL)
185 			*cp++ = '\0';
186 	}
187 	*q = NULL;
188 	return (&serv);
189 }
190