* sysdeps/unix/sysv/linux/dl-osinfo.h: Remove unnecessary include.
[glibc.git] / nis / nss_nis / nis-rpc.c
blobe7049ffa9f78baa6ab5154446500e2eeac503f19
1 /* Copyright (C) 1996-1998,2000,2002,2003,2004,2006
2 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C 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 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
21 #include <nss.h>
22 #include <netdb.h>
23 #include <ctype.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <bits/libc-lock.h>
27 #include <rpcsvc/yp.h>
28 #include <rpcsvc/ypclnt.h>
30 #include "nss-nis.h"
32 /* Get the declaration of the parser function. */
33 #define ENTNAME rpcent
34 #define EXTERN_PARSER
35 #include <nss/nss_files/files-parse.c>
37 __libc_lock_define_initialized (static, lock)
39 static intern_t intern;
42 static void
43 internal_nis_endrpcent (intern_t *intern)
45 struct response_t *curr = intern->next;
47 while (curr != NULL)
49 struct response_t *last = curr;
50 curr = curr->next;
51 free (last);
54 intern->next = intern->start = NULL;
57 static enum nss_status
58 internal_nis_setrpcent (intern_t *intern)
60 char *domainname;
61 struct ypall_callback ypcb;
62 enum nss_status status;
64 if (yp_get_default_domain (&domainname))
65 return NSS_STATUS_UNAVAIL;
67 internal_nis_endrpcent (intern);
69 ypcb.foreach = _nis_saveit;
70 ypcb.data = (char *) intern;
71 status = yperr2nss (yp_all (domainname, "rpc.bynumber", &ypcb));
73 /* Mark the last buffer as full. */
74 if (intern->next != NULL)
75 intern->next->size = intern->offset;
77 intern->next = intern->start;
78 intern->offset = 0;
80 return status;
83 enum nss_status
84 _nss_nis_setrpcent (int stayopen)
86 enum nss_status status;
88 __libc_lock_lock (lock);
90 status = internal_nis_setrpcent (&intern);
92 __libc_lock_unlock (lock);
94 return status;
97 enum nss_status
98 _nss_nis_endrpcent (void)
100 __libc_lock_lock (lock);
102 internal_nis_endrpcent (&intern);
104 __libc_lock_unlock (lock);
106 return NSS_STATUS_SUCCESS;
109 static enum nss_status
110 internal_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen,
111 int *errnop, intern_t *intern)
113 struct parser_data *pdata = (void *) buffer;
114 int parse_res;
115 char *p;
117 if (intern->start == NULL)
118 internal_nis_setrpcent (intern);
120 /* Get the next entry until we found a correct one. */
123 struct response_t *bucket = intern->next;
125 if (__builtin_expect (intern->offset >= bucket->size, 0))
127 if (bucket->next == NULL)
128 return NSS_STATUS_NOTFOUND;
130 /* We look at all the content in the current bucket. Go on
131 to the next. */
132 bucket = intern->next = bucket->next;
133 intern->offset = 0;
136 for (p = &bucket->mem[intern->offset]; isspace (*p); ++p)
137 ++intern->offset;
139 size_t len = strlen (p) + 1;
140 if (__builtin_expect (len > buflen, 0))
142 *errnop = ERANGE;
143 return NSS_STATUS_TRYAGAIN;
146 /* We unfortunately have to copy the data in the user-provided
147 buffer because that buffer might be around for a very long
148 time and the servent structure must remain valid. If we would
149 rely on the BUCKET memory the next 'setservent' or 'endservent'
150 call would destroy it.
152 The important thing is that it is a single NUL-terminated
153 string. This is what the parsing routine expects. */
154 p = memcpy (buffer, &bucket->mem[intern->offset], len);
156 parse_res = _nss_files_parse_rpcent (p, rpc, pdata, buflen, errnop);
157 if (__builtin_expect (parse_res == -1, 0))
158 return NSS_STATUS_TRYAGAIN;
160 intern->offset += len;
162 while (!parse_res);
164 return NSS_STATUS_SUCCESS;
167 enum nss_status
168 _nss_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen,
169 int *errnop)
171 enum nss_status status;
173 __libc_lock_lock (lock);
175 status = internal_nis_getrpcent_r (rpc, buffer, buflen, errnop, &intern);
177 __libc_lock_unlock (lock);
179 return status;
182 enum nss_status
183 _nss_nis_getrpcbyname_r (const char *name, struct rpcent *rpc,
184 char *buffer, size_t buflen, int *errnop)
186 if (name == NULL)
188 *errnop = EINVAL;
189 return NSS_STATUS_UNAVAIL;
192 intern_t data = { NULL, NULL, 0 };
193 enum nss_status status = internal_nis_setrpcent (&data);
194 if (__builtin_expect (status != NSS_STATUS_SUCCESS, 0))
195 return status;
197 int found = 0;
198 while (!found &&
199 ((status = internal_nis_getrpcent_r (rpc, buffer, buflen, errnop,
200 &data)) == NSS_STATUS_SUCCESS))
202 if (strcmp (rpc->r_name, name) == 0)
203 found = 1;
204 else
206 int i = 0;
208 while (rpc->r_aliases[i] != NULL)
210 if (strcmp (rpc->r_aliases[i], name) == 0)
212 found = 1;
213 break;
215 else
216 ++i;
221 internal_nis_endrpcent (&data);
223 if (__builtin_expect (!found && status == NSS_STATUS_SUCCESS, 0))
224 return NSS_STATUS_NOTFOUND;
226 return status;
229 enum nss_status
230 _nss_nis_getrpcbynumber_r (int number, struct rpcent *rpc,
231 char *buffer, size_t buflen, int *errnop)
233 char *domain;
234 if (__builtin_expect (yp_get_default_domain (&domain), 0))
235 return NSS_STATUS_UNAVAIL;
237 char buf[32];
238 int nlen = snprintf (buf, sizeof (buf), "%d", number);
240 char *result;
241 int len;
242 int yperr = yp_match (domain, "rpc.bynumber", buf, nlen, &result, &len);
244 if (__builtin_expect (yperr != YPERR_SUCCESS, 0))
246 enum nss_status retval = yperr2nss (yperr);
248 if (retval == NSS_STATUS_TRYAGAIN)
249 *errnop = errno;
250 return retval;
253 if (__builtin_expect ((size_t) (len + 1) > buflen, 0))
255 free (result);
256 *errnop = ERANGE;
257 return NSS_STATUS_TRYAGAIN;
260 char *p = strncpy (buffer, result, len);
261 buffer[len] = '\0';
262 while (isspace (*p))
263 ++p;
264 free (result);
266 int parse_res = _nss_files_parse_rpcent (p, rpc, (void *) buffer, buflen,
267 errnop);
268 if (__builtin_expect (parse_res < 1, 0))
270 if (parse_res == -1)
271 return NSS_STATUS_TRYAGAIN;
272 else
273 return NSS_STATUS_NOTFOUND;
275 else
276 return NSS_STATUS_SUCCESS;