source: rtems/cpukit/libnetworking/libc/getservent.c @ 9d647dfc

4.104.114.84.95
Last change on this file since 9d647dfc was 68a368fc, checked in by Joel Sherrill <joel.sherrill@…>, on 08/09/02 at 12:45:10

2002-08-09 Joel Sherrill <joel@…>

  • libc/getservent.c: Per PR265, add #include <netinet/in.h> for ntohl() function.
  • Property mode set to 100644
File size: 6.6 KB
Line 
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 *  $Id$
34 */
35
36#if defined(LIBC_SCCS) && !defined(lint)
37static char sccsid[] = "@(#)getservent.c        8.1 (Berkeley) 6/4/93";
38#endif /* LIBC_SCCS and not lint */
39
40#include <sys/types.h>
41#include <sys/socket.h>
42#include <netinet/in.h>
43#include <netdb.h>
44#include <stdio.h>
45#include <string.h>
46#include <stdlib.h>
47#ifdef YP
48#include <rpc/rpc.h>
49#include <rpcsvc/yp_prot.h>
50#include <rpcsvc/ypclnt.h>
51static int serv_stepping_yp = 0;
52extern int _yp_check __P(( char ** ));
53#endif
54
55
56#define MAXALIASES      35
57
58static FILE *servf = NULL;
59static char line[BUFSIZ+1];
60static struct servent serv;
61static char *serv_aliases[MAXALIASES];
62int _serv_stayopen;
63
64#ifdef YP
65char *___getservbyname_yp = NULL;
66char *___getservbyproto_yp = NULL;
67int ___getservbyport_yp = 0;
68static char *yp_domain = NULL;
69
70static int
71_getservbyport_yp(line)
72        char *line;
73{
74        char *result;
75        int resultlen;
76        char buf[YPMAXRECORD + 2];
77        int rv;
78
79        snprintf(buf, sizeof(buf), "%d/%s", ntohs(___getservbyport_yp),
80                                                ___getservbyproto_yp);
81
82        ___getservbyport_yp = 0;
83        ___getservbyproto_yp = NULL;
84
85        if(!yp_domain) {
86                if(yp_get_default_domain(&yp_domain))
87                        return (0);
88        }
89
90        /*
91         * We have to be a little flexible here. Ideally you're supposed
92         * to have both a services.byname and a services.byport map, but
93         * some systems have only services.byname. FreeBSD cheats a little
94         * by putting the services.byport information in the same map as
95         * services.byname so that either case will work. We allow for both
96         * possibilities here: if there is no services.byport map, we try
97         * services.byname instead.
98         */
99        if ((rv = yp_match(yp_domain, "services.byport", buf, strlen(buf),
100                                                &result, &resultlen))) {
101                if (rv == YPERR_MAP) {
102                        if (yp_match(yp_domain, "services.byname", buf,
103                                        strlen(buf), &result, &resultlen))
104                        return(0);
105                } else
106                        return(0);
107        }
108               
109        /* getservent() expects lines terminated with \n -- make it happy */
110        snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);
111
112        free(result);
113        return(1);
114}
115
116static int
117_getservbyname_yp(line)
118        char *line;
119{
120        char *result;
121        int resultlen;
122        char buf[YPMAXRECORD + 2];
123
124        if(!yp_domain) {
125                if(yp_get_default_domain(&yp_domain))
126                        return (0);
127        }
128
129        snprintf(buf, sizeof(buf), "%s/%s", ___getservbyname_yp,
130                                                ___getservbyproto_yp);
131
132        ___getservbyname_yp = 0;
133        ___getservbyproto_yp = NULL;
134
135        if (yp_match(yp_domain, "services.byname", buf, strlen(buf),
136                                                &result, &resultlen)) {
137                return(0);
138        }
139               
140        /* getservent() expects lines terminated with \n -- make it happy */
141        snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);
142
143        free(result);
144        return(1);
145}
146
147static int
148_getservent_yp(line)
149        char *line;
150{
151        static char *key = NULL;
152        static int keylen;
153        char *lastkey, *result;
154        int resultlen;
155        int rv;
156
157        if(!yp_domain) {
158                if(yp_get_default_domain(&yp_domain))
159                        return (0);
160        }
161
162        if (!serv_stepping_yp) {
163                if (key)
164                        free(key);
165                if ((rv = yp_first(yp_domain, "services.byname", &key, &keylen,
166                             &result, &resultlen))) {
167                        serv_stepping_yp = 0;
168                        return(0);
169                }
170                serv_stepping_yp = 1;
171        } else {
172                lastkey = key;
173                rv = yp_next(yp_domain, "services.byname", key, keylen, &key,
174                             &keylen, &result, &resultlen);
175                free(lastkey);
176                if (rv) {
177                        serv_stepping_yp = 0;
178                        return (0);
179                }
180        }
181
182        /* getservent() expects lines terminated with \n -- make it happy */
183        snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);
184
185        free(result);
186
187        return(1);
188}
189#endif
190
191void
192setservent(f)
193        int f;
194{
195        if (servf == NULL)
196                servf = fopen(_PATH_SERVICES, "r" );
197        else
198                rewind(servf);
199        _serv_stayopen |= f;
200}
201
202void
203endservent()
204{
205        if (servf) {
206                fclose(servf);
207                servf = NULL;
208        }
209        _serv_stayopen = 0;
210}
211
212struct servent *
213getservent()
214{
215        char *p;
216        register char *cp, **q;
217
218#ifdef YP
219        if (serv_stepping_yp && _getservent_yp(line)) {
220                p = (char *)&line;
221                goto unpack;
222        }
223tryagain:
224#endif
225        if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL)
226                return (NULL);
227again:
228        if ((p = fgets(line, BUFSIZ, servf)) == NULL)
229                return (NULL);
230#ifdef YP
231        if (*p == '+' && _yp_check(NULL)) {
232                if (___getservbyname_yp != NULL) {
233                        if (!_getservbyname_yp(line))
234                                goto tryagain;
235                }
236                else if (___getservbyport_yp != 0) {
237                        if (!_getservbyport_yp(line))
238                                goto tryagain;
239                }
240                else if (!_getservent_yp(line))
241                        goto tryagain;
242        }
243unpack:
244#endif
245        if (*p == '#')
246                goto again;
247        cp = strpbrk(p, "#\n");
248        if (cp == NULL)
249                goto again;
250        *cp = '\0';
251        serv.s_name = p;
252        p = strpbrk(p, " \t");
253        if (p == NULL)
254                goto again;
255        *p++ = '\0';
256        while (*p == ' ' || *p == '\t')
257                p++;
258        cp = strpbrk(p, ",/");
259        if (cp == NULL)
260                goto again;
261        *cp++ = '\0';
262        serv.s_port = htons((u_short)atoi(p));
263        serv.s_proto = cp;
264        q = serv.s_aliases = serv_aliases;
265        cp = strpbrk(cp, " \t");
266        if (cp != NULL)
267                *cp++ = '\0';
268        while (cp && *cp) {
269                if (*cp == ' ' || *cp == '\t') {
270                        cp++;
271                        continue;
272                }
273                if (q < &serv_aliases[MAXALIASES - 1])
274                        *q++ = cp;
275                cp = strpbrk(cp, " \t");
276                if (cp != NULL)
277                        *cp++ = '\0';
278        }
279        *q = NULL;
280        return (&serv);
281}
Note: See TracBrowser for help on using the repository browser.