OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [uClibc/] [libc/] [inet/] [getservice.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1325 phoenix
/*
2
** services.c                           /etc/services access functions
3
**
4
** This file is part of the NYS Library.
5
**
6
** The NYS Library is free software; you can redistribute it and/or
7
** modify it under the terms of the GNU Library General Public License as
8
** published by the Free Software Foundation; either version 2 of the
9
** License, or (at your option) any later version.
10
**
11
** The NYS Library is distributed in the hope that it will be useful,
12
** but WITHOUT ANY WARRANTY; without even the implied warranty of
13
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
** Library General Public License for more details.
15
**
16
** You should have received a copy of the GNU Library General Public
17
** License along with the NYS Library; see the file COPYING.LIB.  If
18
** not, write to the Free Software Foundation, Inc., 675 Mass Ave,
19
** Cambridge, MA 02139, USA.
20
**
21
**
22
** Copyright (c) 1983 Regents of the University of California.
23
** All rights reserved.
24
**
25
** Redistribution and use in source and binary forms, with or without
26
** modification, are permitted provided that the following conditions
27
** are met:
28
** 1. Redistributions of source code must retain the above copyright
29
**    notice, this list of conditions and the following disclaimer.
30
** 2. Redistributions in binary form must reproduce the above copyright
31
**    notice, this list of conditions and the following disclaimer in the
32
**    documentation and/or other materials provided with the distribution.
33
** 3. All advertising materials mentioning features or use of this software
34
**    must display the following acknowledgement:
35
**      This product includes software developed by the University of
36
**      California, Berkeley and its contributors.
37
** 4. Neither the name of the University nor the names of its contributors
38
**    may be used to endorse or promote products derived from this software
39
**    without specific prior written permission.
40
**
41
** THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
42
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
** ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
45
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
** SUCH DAMAGE.
52
*/
53
 
54
 
55
#define __FORCE_GLIBC
56
#define _GNU_SOURCE
57
#include <features.h>
58
#include <sys/types.h>
59
#include <sys/socket.h>
60
#include <netdb.h>
61
#include <stdio.h>
62
#include <string.h>
63
#include <stdlib.h>
64
#include <netinet/in.h>
65
#include <arpa/inet.h>
66
#include <errno.h>
67
 
68
 
69
 
70
#ifdef __UCLIBC_HAS_THREADS__
71
#include <pthread.h>
72
static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
73
# define LOCK   __pthread_mutex_lock(&mylock)
74
# define UNLOCK __pthread_mutex_unlock(&mylock);
75
#else
76
# define LOCK
77
# define UNLOCK
78
#endif
79
 
80
 
81
 
82
 
83
#define MAXALIASES      35
84
 
85
static FILE *servf = NULL;
86
static struct servent serv;
87
static char buf[BUFSIZ+1 + sizeof(char *)*MAXALIASES];
88
static int serv_stayopen;
89
 
90
void setservent(int f)
91
{
92
    LOCK;
93
    if (servf == NULL)
94
        servf = fopen(_PATH_SERVICES, "r" );
95
    else
96
        rewind(servf);
97
    serv_stayopen |= f;
98
    UNLOCK;
99
}
100
 
101
void endservent(void)
102
{
103
    LOCK;
104
    if (servf) {
105
        fclose(servf);
106
        servf = NULL;
107
    }
108
    serv_stayopen = 0;
109
    UNLOCK;
110
}
111
 
112
struct servent * getservent(void)
113
{
114
    struct servent *result;
115
    getservent_r(&serv, buf, sizeof(buf), &result);
116
    return result;
117
}
118
 
119
 
120
struct servent *getservbyname(const char *name, const char *proto)
121
{
122
    struct servent *result;
123
    getservbyname_r(name, proto, &serv, buf, sizeof(buf), &result);
124
    return result;
125
}
126
 
127
 
128
struct servent * getservbyport(int port, const char *proto)
129
{
130
    struct servent *result;
131
    getservbyport_r(port, proto, &serv, buf, sizeof(buf), &result);
132
    return result;
133
}
134
 
135
int getservent_r(struct servent * result_buf,
136
                 char * buf, size_t buflen,
137
                 struct servent ** result)
138
{
139
    char *p;
140
    register char *cp, **q;
141
    char **serv_aliases;
142
    char *line;
143
 
144
    *result=NULL;
145
 
146
    if (buflen < sizeof(*serv_aliases)*MAXALIASES) {
147
        errno=ERANGE;
148
        return errno;
149
    }
150
    LOCK;
151
    serv_aliases=(char **)buf;
152
    buf+=sizeof(*serv_aliases)*MAXALIASES;
153
    buflen-=sizeof(*serv_aliases)*MAXALIASES;
154
 
155
    if (buflen < BUFSIZ+1) {
156
        UNLOCK;
157
        errno=ERANGE;
158
        return errno;
159
    }
160
    line=buf;
161
    buf+=BUFSIZ+1;
162
    buflen-=BUFSIZ+1;
163
 
164
    if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL) {
165
        UNLOCK;
166
        errno=EIO;
167
        return errno;
168
    }
169
again:
170
    if ((p = fgets(line, BUFSIZ, servf)) == NULL) {
171
        UNLOCK;
172
        errno=EIO;
173
        return errno;
174
    }
175
    if (*p == '#')
176
        goto again;
177
    cp = strpbrk(p, "#\n");
178
    if (cp == NULL)
179
        goto again;
180
    *cp = '\0';
181
    result_buf->s_name = p;
182
    p = strpbrk(p, " \t");
183
    if (p == NULL)
184
        goto again;
185
    *p++ = '\0';
186
    while (*p == ' ' || *p == '\t')
187
        p++;
188
    cp = strpbrk(p, ",/");
189
    if (cp == NULL)
190
        goto again;
191
    *cp++ = '\0';
192
    result_buf->s_port = htons((u_short)atoi(p));
193
    result_buf->s_proto = cp;
194
    q = result_buf->s_aliases = serv_aliases;
195
    cp = strpbrk(cp, " \t");
196
    if (cp != NULL)
197
        *cp++ = '\0';
198
    while (cp && *cp) {
199
        if (*cp == ' ' || *cp == '\t') {
200
            cp++;
201
            continue;
202
        }
203
        if (q < &serv_aliases[MAXALIASES - 1])
204
            *q++ = cp;
205
        cp = strpbrk(cp, " \t");
206
        if (cp != NULL)
207
            *cp++ = '\0';
208
    }
209
    *q = NULL;
210
    *result=result_buf;
211
    UNLOCK;
212
    return 0;
213
}
214
 
215
int getservbyname_r(const char *name, const char *proto,
216
        struct servent * result_buf, char * buf, size_t buflen,
217
        struct servent ** result)
218
{
219
    register char **cp;
220
    int ret;
221
 
222
    LOCK;
223
    setservent(serv_stayopen);
224
    while (!(ret=getservent_r(result_buf, buf, buflen, result))) {
225
        if (strcmp(name, result_buf->s_name) == 0)
226
            goto gotname;
227
        for (cp = result_buf->s_aliases; *cp; cp++)
228
            if (strcmp(name, *cp) == 0)
229
                goto gotname;
230
        continue;
231
gotname:
232
        if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
233
            break;
234
    }
235
    if (!serv_stayopen)
236
        endservent();
237
    UNLOCK;
238
    return *result?0:ret;
239
}
240
 
241
int getservbyport_r(int port, const char *proto,
242
        struct servent * result_buf, char * buf,
243
        size_t buflen, struct servent ** result)
244
{
245
    int ret;
246
 
247
    LOCK;
248
    setservent(serv_stayopen);
249
    while (!(ret=getservent_r(result_buf, buf, buflen, result))) {
250
        if (result_buf->s_port != port)
251
            continue;
252
        if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
253
            break;
254
    }
255
    if (!serv_stayopen)
256
        endservent();
257
    UNLOCK;
258
    return *result?0:ret;
259
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.