1 /* Copyright (C) 1996-2015 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
24 #include <libc-lock.h>
25 #include <rpcsvc/yp.h>
26 #include <rpcsvc/ypclnt.h>
30 /* Get the declaration of the parser function. */
31 #define ENTNAME rpcent
33 #include <nss/nss_files/files-parse.c>
35 __libc_lock_define_initialized (static, lock
)
37 static intern_t intern
;
41 internal_nis_endrpcent (intern_t
*intern
)
43 struct response_t
*curr
= intern
->next
;
47 struct response_t
*last
= curr
;
52 intern
->next
= intern
->start
= NULL
;
55 static enum nss_status
56 internal_nis_setrpcent (intern_t
*intern
)
59 struct ypall_callback ypcb
;
60 enum nss_status status
;
62 if (yp_get_default_domain (&domainname
))
63 return NSS_STATUS_UNAVAIL
;
65 internal_nis_endrpcent (intern
);
67 ypcb
.foreach
= _nis_saveit
;
68 ypcb
.data
= (char *) intern
;
69 status
= yperr2nss (yp_all (domainname
, "rpc.bynumber", &ypcb
));
71 /* Mark the last buffer as full. */
72 if (intern
->next
!= NULL
)
73 intern
->next
->size
= intern
->offset
;
75 intern
->next
= intern
->start
;
82 _nss_nis_setrpcent (int stayopen
)
84 enum nss_status status
;
86 __libc_lock_lock (lock
);
88 status
= internal_nis_setrpcent (&intern
);
90 __libc_lock_unlock (lock
);
96 _nss_nis_endrpcent (void)
98 __libc_lock_lock (lock
);
100 internal_nis_endrpcent (&intern
);
102 __libc_lock_unlock (lock
);
104 return NSS_STATUS_SUCCESS
;
107 static enum nss_status
108 internal_nis_getrpcent_r (struct rpcent
*rpc
, char *buffer
, size_t buflen
,
109 int *errnop
, intern_t
*intern
)
111 struct parser_data
*pdata
= (void *) buffer
;
115 if (intern
->start
== NULL
)
116 internal_nis_setrpcent (intern
);
118 if (intern
->next
== NULL
)
119 /* Not one entry in the map. */
120 return NSS_STATUS_NOTFOUND
;
122 /* Get the next entry until we found a correct one. */
125 struct response_t
*bucket
= intern
->next
;
127 if (__glibc_unlikely (intern
->offset
>= bucket
->size
))
129 if (bucket
->next
== NULL
)
130 return NSS_STATUS_NOTFOUND
;
132 /* We look at all the content in the current bucket. Go on
134 bucket
= intern
->next
= bucket
->next
;
138 for (p
= &bucket
->mem
[intern
->offset
]; isspace (*p
); ++p
)
141 size_t len
= strlen (p
) + 1;
142 if (__glibc_unlikely (len
> buflen
))
145 return NSS_STATUS_TRYAGAIN
;
148 /* We unfortunately have to copy the data in the user-provided
149 buffer because that buffer might be around for a very long
150 time and the servent structure must remain valid. If we would
151 rely on the BUCKET memory the next 'setservent' or 'endservent'
152 call would destroy it.
154 The important thing is that it is a single NUL-terminated
155 string. This is what the parsing routine expects. */
156 p
= memcpy (buffer
, &bucket
->mem
[intern
->offset
], len
);
158 parse_res
= _nss_files_parse_rpcent (p
, rpc
, pdata
, buflen
, errnop
);
159 if (__glibc_unlikely (parse_res
== -1))
160 return NSS_STATUS_TRYAGAIN
;
162 intern
->offset
+= len
;
166 return NSS_STATUS_SUCCESS
;
170 _nss_nis_getrpcent_r (struct rpcent
*rpc
, char *buffer
, size_t buflen
,
173 enum nss_status status
;
175 __libc_lock_lock (lock
);
177 status
= internal_nis_getrpcent_r (rpc
, buffer
, buflen
, errnop
, &intern
);
179 __libc_lock_unlock (lock
);
185 _nss_nis_getrpcbyname_r (const char *name
, struct rpcent
*rpc
,
186 char *buffer
, size_t buflen
, int *errnop
)
191 return NSS_STATUS_UNAVAIL
;
194 intern_t data
= { NULL
, NULL
, 0 };
195 enum nss_status status
= internal_nis_setrpcent (&data
);
196 if (__glibc_unlikely (status
!= NSS_STATUS_SUCCESS
))
201 ((status
= internal_nis_getrpcent_r (rpc
, buffer
, buflen
, errnop
,
202 &data
)) == NSS_STATUS_SUCCESS
))
204 if (strcmp (rpc
->r_name
, name
) == 0)
210 while (rpc
->r_aliases
[i
] != NULL
)
212 if (strcmp (rpc
->r_aliases
[i
], name
) == 0)
223 internal_nis_endrpcent (&data
);
225 if (__glibc_unlikely (!found
&& status
== NSS_STATUS_SUCCESS
))
226 return NSS_STATUS_NOTFOUND
;
232 _nss_nis_getrpcbynumber_r (int number
, struct rpcent
*rpc
,
233 char *buffer
, size_t buflen
, int *errnop
)
236 if (__glibc_unlikely (yp_get_default_domain (&domain
)))
237 return NSS_STATUS_UNAVAIL
;
240 int nlen
= snprintf (buf
, sizeof (buf
), "%d", number
);
244 int yperr
= yp_match (domain
, "rpc.bynumber", buf
, nlen
, &result
, &len
);
246 if (__glibc_unlikely (yperr
!= YPERR_SUCCESS
))
248 enum nss_status retval
= yperr2nss (yperr
);
250 if (retval
== NSS_STATUS_TRYAGAIN
)
255 if (__glibc_unlikely ((size_t) (len
+ 1) > buflen
))
259 return NSS_STATUS_TRYAGAIN
;
262 char *p
= strncpy (buffer
, result
, len
);
268 int parse_res
= _nss_files_parse_rpcent (p
, rpc
, (void *) buffer
, buflen
,
270 if (__glibc_unlikely (parse_res
< 1))
273 return NSS_STATUS_TRYAGAIN
;
275 return NSS_STATUS_NOTFOUND
;
278 return NSS_STATUS_SUCCESS
;