.
[glibc/history.git] / nis / nss_nis / nis-rpc.c
blob2fdb16dddef66d67753a698ab002d096cf9dc79e
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 if (intern->next == NULL)
121 /* Not one entry in the map. */
122 return NSS_STATUS_NOTFOUND;
124 /* Get the next entry until we found a correct one. */
127 struct response_t *bucket = intern->next;
129 if (__builtin_expect (intern->offset >= bucket->size, 0))
131 if (bucket->next == NULL)
132 return NSS_STATUS_NOTFOUND;
134 /* We look at all the content in the current bucket. Go on
135 to the next. */
136 bucket = intern->next = bucket->next;
137 intern->offset = 0;
140 for (p = &bucket->mem[intern->offset]; isspace (*p); ++p)
141 ++intern->offset;
143 size_t len = strlen (p) + 1;
144 if (__builtin_expect (len > buflen, 0))
146 *errnop = ERANGE;
147 return NSS_STATUS_TRYAGAIN;
150 /* We unfortunately have to copy the data in the user-provided
151 buffer because that buffer might be around for a very long
152 time and the servent structure must remain valid. If we would
153 rely on the BUCKET memory the next 'setservent' or 'endservent'
154 call would destroy it.
156 The important thing is that it is a single NUL-terminated
157 string. This is what the parsing routine expects. */
158 p = memcpy (buffer, &bucket->mem[intern->offset], len);
160 parse_res = _nss_files_parse_rpcent (p, rpc, pdata, buflen, errnop);
161 if (__builtin_expect (parse_res == -1, 0))
162 return NSS_STATUS_TRYAGAIN;
164 intern->offset += len;
166 while (!parse_res);
168 return NSS_STATUS_SUCCESS;
171 enum nss_status
172 _nss_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen,
173 int *errnop)
175 enum nss_status status;
177 __libc_lock_lock (lock);
179 status = internal_nis_getrpcent_r (rpc, buffer, buflen, errnop, &intern);
181 __libc_lock_unlock (lock);
183 return status;
186 enum nss_status
187 _nss_nis_getrpcbyname_r (const char *name, struct rpcent *rpc,
188 char *buffer, size_t buflen, int *errnop)
190 if (name == NULL)
192 *errnop = EINVAL;
193 return NSS_STATUS_UNAVAIL;
196 intern_t data = { NULL, NULL, 0 };
197 enum nss_status status = internal_nis_setrpcent (&data);
198 if (__builtin_expect (status != NSS_STATUS_SUCCESS, 0))
199 return status;
201 int found = 0;
202 while (!found &&
203 ((status = internal_nis_getrpcent_r (rpc, buffer, buflen, errnop,
204 &data)) == NSS_STATUS_SUCCESS))
206 if (strcmp (rpc->r_name, name) == 0)
207 found = 1;
208 else
210 int i = 0;
212 while (rpc->r_aliases[i] != NULL)
214 if (strcmp (rpc->r_aliases[i], name) == 0)
216 found = 1;
217 break;
219 else
220 ++i;
225 internal_nis_endrpcent (&data);
227 if (__builtin_expect (!found && status == NSS_STATUS_SUCCESS, 0))
228 return NSS_STATUS_NOTFOUND;
230 return status;
233 enum nss_status
234 _nss_nis_getrpcbynumber_r (int number, struct rpcent *rpc,
235 char *buffer, size_t buflen, int *errnop)
237 char *domain;
238 if (__builtin_expect (yp_get_default_domain (&domain), 0))
239 return NSS_STATUS_UNAVAIL;
241 char buf[32];
242 int nlen = snprintf (buf, sizeof (buf), "%d", number);
244 char *result;
245 int len;
246 int yperr = yp_match (domain, "rpc.bynumber", buf, nlen, &result, &len);
248 if (__builtin_expect (yperr != YPERR_SUCCESS, 0))
250 enum nss_status retval = yperr2nss (yperr);
252 if (retval == NSS_STATUS_TRYAGAIN)
253 *errnop = errno;
254 return retval;
257 if (__builtin_expect ((size_t) (len + 1) > buflen, 0))
259 free (result);
260 *errnop = ERANGE;
261 return NSS_STATUS_TRYAGAIN;
264 char *p = strncpy (buffer, result, len);
265 buffer[len] = '\0';
266 while (isspace (*p))
267 ++p;
268 free (result);
270 int parse_res = _nss_files_parse_rpcent (p, rpc, (void *) buffer, buflen,
271 errnop);
272 if (__builtin_expect (parse_res < 1, 0))
274 if (parse_res == -1)
275 return NSS_STATUS_TRYAGAIN;
276 else
277 return NSS_STATUS_NOTFOUND;
279 else
280 return NSS_STATUS_SUCCESS;