source: rtems/cpukit/libnetworking/libc/getservent.c @ 96b39164

4.104.114.84.95
Last change on this file since 96b39164 was 96b39164, checked in by Joel Sherrill <joel.sherrill@…>, on 08/20/98 at 21:56:40

Added CVS Ids

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