]> git.proxmox.com Git - mirror_edk2.git/blame - StdLib/BsdSocketLib/getservent.c
Fix a bug about the iSCSI DHCP dependency issue.
[mirror_edk2.git] / StdLib / BsdSocketLib / getservent.c
CommitLineData
d7ce7006 1/*\r
2 * Copyright (c) 1983, 1993\r
3 * The Regents of the University of California. All rights reserved.\r
4 *\r
5 * Redistribution and use in source and binary forms, with or without\r
6 * modification, are permitted provided that the following conditions\r
7 * are met:\r
8 * 1. Redistributions of source code must retain the above copyright\r
9 * notice, this list of conditions and the following disclaimer.\r
10 * 2. Redistributions in binary form must reproduce the above copyright\r
11 * notice, this list of conditions and the following disclaimer in the\r
12 * documentation and/or other materials provided with the distribution.\r
13 * 3. All advertising materials mentioning features or use of this software\r
14 * must display the following acknowledgement:\r
15 * This product includes software developed by the University of\r
16 * California, Berkeley and its contributors.\r
17 * 4. Neither the name of the University nor the names of its contributors\r
18 * may be used to endorse or promote products derived from this software\r
19 * without specific prior written permission.\r
20 *\r
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
31 * SUCH DAMAGE.\r
32 */\r
33\r
34#if defined(LIBC_SCCS) && !defined(lint)\r
35static char sccsid[] = "@(#)getservent.c 8.1 (Berkeley) 6/4/93";\r
36#endif /* LIBC_SCCS and not lint */\r
37\r
38#include <sys/types.h>\r
39#include <sys/socket.h>\r
40#include <netdb.h>\r
41#include <stdio.h>\r
42#include <string.h>\r
43#include <stdlib.h>\r
44#ifdef YP\r
45#include <rpc/rpc.h>\r
46#include <rpcsvc/yp_prot.h>\r
47#include <rpcsvc/ypclnt.h>\r
48static int serv_stepping_yp = 0;\r
49extern int _yp_check __P(( char ** ));\r
50#endif\r
51\r
52\r
53#define MAXALIASES 35\r
54\r
55static FILE *servf = NULL;\r
56static char line[BUFSIZ+1];\r
57static struct servent serv;\r
58static char *serv_aliases[MAXALIASES];\r
59int _serv_stayopen;\r
60\r
61#ifdef YP\r
62char *___getservbyname_yp = NULL;\r
63char *___getservbyproto_yp = NULL;\r
64int ___getservbyport_yp = 0;\r
65static char *yp_domain = NULL;\r
66\r
67static int\r
68_getservbyport_yp(line)\r
69 char *line;\r
70{\r
71 char *result;\r
72 int resultlen;\r
73 char buf[YPMAXRECORD + 2];\r
74 int rv;\r
75\r
76 snprintf(buf, sizeof(buf), "%d/%s", ntohs(___getservbyport_yp),\r
77 ___getservbyproto_yp);\r
78\r
79 ___getservbyport_yp = 0;\r
80 ___getservbyproto_yp = NULL;\r
81\r
82 if(!yp_domain) {\r
83 if(yp_get_default_domain(&yp_domain))\r
84 return (0);\r
85 }\r
86\r
87 /*\r
88 * We have to be a little flexible here. Ideally you're supposed\r
89 * to have both a services.byname and a services.byport map, but\r
90 * some systems have only services.byname. FreeBSD cheats a little\r
91 * by putting the services.byport information in the same map as\r
92 * services.byname so that either case will work. We allow for both\r
93 * possibilities here: if there is no services.byport map, we try\r
94 * services.byname instead.\r
95 */\r
96 if ((rv = yp_match(yp_domain, "services.byport", buf, strlen(buf),\r
97 &result, &resultlen))) {\r
98 if (rv == YPERR_MAP) {\r
99 if (yp_match(yp_domain, "services.byname", buf,\r
100 strlen(buf), &result, &resultlen))\r
101 return(0);\r
102 } else\r
103 return(0);\r
104 }\r
105 \r
106 /* getservent() expects lines terminated with \n -- make it happy */\r
107 snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);\r
108\r
109 free(result);\r
110 return(1);\r
111}\r
112\r
113static int\r
114_getservbyname_yp(line)\r
115 char *line;\r
116{\r
117 char *result;\r
118 int resultlen;\r
119 char buf[YPMAXRECORD + 2];\r
120\r
121 if(!yp_domain) {\r
122 if(yp_get_default_domain(&yp_domain))\r
123 return (0);\r
124 }\r
125\r
126 snprintf(buf, sizeof(buf), "%s/%s", ___getservbyname_yp,\r
127 ___getservbyproto_yp);\r
128\r
129 ___getservbyname_yp = 0;\r
130 ___getservbyproto_yp = NULL;\r
131\r
132 if (yp_match(yp_domain, "services.byname", buf, strlen(buf),\r
133 &result, &resultlen)) {\r
134 return(0);\r
135 }\r
136 \r
137 /* getservent() expects lines terminated with \n -- make it happy */\r
138 snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);\r
139\r
140 free(result);\r
141 return(1);\r
142}\r
143\r
144static int\r
145_getservent_yp(line)\r
146 char *line;\r
147{\r
148 static char *key = NULL;\r
149 static int keylen;\r
150 char *lastkey, *result;\r
151 int resultlen;\r
152 int rv;\r
153\r
154 if(!yp_domain) {\r
155 if(yp_get_default_domain(&yp_domain))\r
156 return (0);\r
157 }\r
158\r
159 if (!serv_stepping_yp) {\r
160 if (key)\r
161 free(key);\r
162 if ((rv = yp_first(yp_domain, "services.byname", &key, &keylen,\r
163 &result, &resultlen))) {\r
164 serv_stepping_yp = 0;\r
165 return(0);\r
166 }\r
167 serv_stepping_yp = 1;\r
168 } else {\r
169 lastkey = key;\r
170 rv = yp_next(yp_domain, "services.byname", key, keylen, &key,\r
171 &keylen, &result, &resultlen);\r
172 free(lastkey);\r
173 if (rv) {\r
174 serv_stepping_yp = 0;\r
175 return (0);\r
176 }\r
177 }\r
178\r
179 /* getservent() expects lines terminated with \n -- make it happy */\r
180 snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);\r
181\r
182 free(result);\r
183\r
184 return(1);\r
185}\r
186#endif\r
187\r
188void\r
189setservent(int f)\r
190{\r
191 if (servf == NULL)\r
192 servf = fopen(_PATH_SERVICES, "r" );\r
193 else\r
194 rewind(servf);\r
195 _serv_stayopen |= f;\r
196}\r
197\r
198void\r
199endservent()\r
200{\r
201 if (servf) {\r
202 fclose(servf);\r
203 servf = NULL;\r
204 }\r
205 _serv_stayopen = 0;\r
206}\r
207\r
208struct servent *\r
209getservent()\r
210{\r
211 char *p;\r
212 register char *cp, **q;\r
213\r
214#ifdef YP\r
215 if (serv_stepping_yp && _getservent_yp(line)) {\r
216 p = (char *)&line;\r
217 goto unpack;\r
218 }\r
219tryagain:\r
220#endif\r
221 if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL)\r
222 return (NULL);\r
223again:\r
224 if ((p = fgets(line, BUFSIZ, servf)) == NULL)\r
225 return (NULL);\r
226#ifdef YP\r
227 if (*p == '+' && _yp_check(NULL)) {\r
228 if (___getservbyname_yp != NULL) {\r
229 if (!_getservbyname_yp(line))\r
230 goto tryagain;\r
231 } \r
232 else if (___getservbyport_yp != 0) {\r
233 if (!_getservbyport_yp(line))\r
234 goto tryagain;\r
235 }\r
236 else if (!_getservent_yp(line))\r
237 goto tryagain;\r
238 }\r
239unpack:\r
240#endif\r
241 if (*p == '#')\r
242 goto again;\r
243 cp = strpbrk(p, "#\n");\r
244 if (cp == NULL)\r
245 goto again;\r
246 *cp = '\0';\r
247 serv.s_name = p;\r
248 p = strpbrk(p, " \t");\r
249 if (p == NULL)\r
250 goto again;\r
251 *p++ = '\0';\r
252 while (*p == ' ' || *p == '\t')\r
253 p++;\r
254 cp = strpbrk(p, ",/");\r
255 if (cp == NULL)\r
256 goto again;\r
257 *cp++ = '\0';\r
258 serv.s_port = htons((u_short)atoi(p));\r
259 serv.s_proto = cp;\r
260 q = serv.s_aliases = serv_aliases;\r
261 cp = strpbrk(cp, " \t");\r
262 if (cp != NULL)\r
263 *cp++ = '\0';\r
264 while (cp && *cp) {\r
265 if (*cp == ' ' || *cp == '\t') {\r
266 cp++;\r
267 continue;\r
268 }\r
269 if (q < &serv_aliases[MAXALIASES - 1])\r
270 *q++ = cp;\r
271 cp = strpbrk(cp, " \t");\r
272 if (cp != NULL)\r
273 *cp++ = '\0';\r
274 }\r
275 *q = NULL;\r
276 return (&serv);\r
277}\r