Use addr, not p for inet_pton call.
[kopensolaris-gnu/glibc.git] / nis / nss_nis / nis-rpc.c
1 /* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Library General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    License, or (at your option) any later version.
9
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    Library General Public License for more details.
14
15    You should have received a copy of the GNU Library General Public
16    License along with the GNU C Library; see the file COPYING.LIB.  If not,
17    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18    Boston, MA 02111-1307, USA.  */
19
20 #include <nss.h>
21 #include <netdb.h>
22 #include <ctype.h>
23 #include <errno.h>
24 #include <string.h>
25 #include <libc-lock.h>
26 #include <rpcsvc/yp.h>
27 #include <rpcsvc/ypclnt.h>
28
29 #include "nss-nis.h"
30
31 /* Get the declaration of the parser function.  */
32 #define ENTNAME rpcent
33 #define EXTERN_PARSER
34 #include <nss/nss_files/files-parse.c>
35
36 __libc_lock_define_initialized (static, lock)
37
38 struct response_t
39 {
40   char *val;
41   struct response_t *next;
42 };
43
44 struct intern_t
45 {
46   struct response_t *start;
47   struct response_t *next;
48 };
49 typedef struct intern_t intern_t;
50
51 static intern_t intern = {NULL, NULL};
52
53 static int
54 saveit (int instatus, char *inkey, int inkeylen, char *inval,
55         int invallen, char *indata)
56 {
57   intern_t *intern = (intern_t *)indata;
58
59   if (instatus != YP_TRUE)
60     return instatus;
61
62   if (inkey && inkeylen > 0 && inval && invallen > 0)
63     {
64       if (intern->start == NULL)
65         {
66           intern->start = malloc (sizeof (struct response_t));
67           intern->next = intern->start;
68         }
69       else
70         {
71           intern->next->next = malloc (sizeof (struct response_t));
72           intern->next = intern->next->next;
73         }
74       intern->next->next = NULL;
75       intern->next->val = malloc (invallen + 1);
76       strncpy (intern->next->val, inval, invallen);
77       intern->next->val[invallen] = '\0';
78     }
79
80   return 0;
81 }
82
83 static enum nss_status
84 internal_nis_setrpcent (intern_t *intern)
85 {
86   char *domainname;
87   struct ypall_callback ypcb;
88   enum nss_status status;
89
90   if (yp_get_default_domain (&domainname))
91     return NSS_STATUS_UNAVAIL;
92
93   while (intern->start != NULL)
94     {
95       if (intern->start->val != NULL)
96         free (intern->start->val);
97       intern->next = intern->start;
98       intern->start = intern->start->next;
99       free (intern->next);
100     }
101   intern->start = NULL;
102
103   ypcb.foreach = saveit;
104   ypcb.data = (char *)intern;
105   status = yperr2nss (yp_all(domainname, "rpc.bynumber", &ypcb));
106   intern->next = intern->start;
107
108   return status;
109 }
110
111 enum nss_status
112 _nss_nis_setrpcent (void)
113 {
114   enum nss_status status;
115
116   __libc_lock_lock (lock);
117
118   status = internal_nis_setrpcent (&intern);
119
120   __libc_lock_unlock (lock);
121
122   return status;
123 }
124
125 static enum nss_status
126 internal_nis_endrpcent (intern_t *intern)
127 {
128   while (intern->start != NULL)
129     {
130       if (intern->start->val != NULL)
131         free (intern->start->val);
132       intern->next = intern->start;
133       intern->start = intern->start->next;
134       free (intern->next);
135     }
136   intern->start = NULL;
137
138   return NSS_STATUS_SUCCESS;
139 }
140
141 enum nss_status
142 _nss_nis_endrpcent (void)
143 {
144   enum nss_status status;
145
146   __libc_lock_lock (lock);
147
148   status = internal_nis_endrpcent (&intern);
149
150   __libc_lock_unlock (lock);
151
152   return status;
153 }
154
155 static enum nss_status
156 internal_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen,
157                           intern_t *data)
158 {
159   struct parser_data *pdata = (void *) buffer;
160   int parse_res;
161   char *p;
162
163   if (data->start == NULL)
164     internal_nis_setrpcent (data);
165
166   /* Get the next entry until we found a correct one. */
167   do
168     {
169       if (data->next == NULL)
170         return NSS_STATUS_NOTFOUND;
171       p = strcpy (buffer, data->next->val);
172       data->next = data->next->next;
173       while (isspace (*p))
174         ++p;
175
176       parse_res = _nss_files_parse_rpcent (p, rpc, pdata, buflen);
177       if (!parse_res && errno == ERANGE)
178         return NSS_STATUS_TRYAGAIN;
179     }
180   while (!parse_res);
181
182   return NSS_STATUS_SUCCESS;
183 }
184
185 enum nss_status
186 _nss_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen)
187 {
188   enum nss_status status;
189
190   __libc_lock_lock (lock);
191
192   status = internal_nis_getrpcent_r (rpc, buffer, buflen, &intern);
193
194   __libc_lock_unlock (lock);
195
196   return status;
197 }
198
199 enum nss_status
200 _nss_nis_getrpcbyname_r (const char *name, struct rpcent *rpc,
201                          char *buffer, size_t buflen)
202 {
203   intern_t data = {NULL, NULL};
204   enum nss_status status;
205   int found;
206
207   if (name == NULL)
208     {
209       __set_errno (EINVAL);
210       return NSS_STATUS_UNAVAIL;
211     }
212
213   status = internal_nis_setrpcent (&data);
214   if (status != NSS_STATUS_SUCCESS)
215     return status;
216
217   found = 0;
218   while (!found &&
219          ((status = internal_nis_getrpcent_r (rpc, buffer, buflen, &data))
220           == NSS_STATUS_SUCCESS))
221     {
222       if (strcmp (rpc->r_name, name) == 0)
223         found = 1;
224       else
225         {
226           int i = 0;
227
228           while (rpc->r_aliases[i] != NULL)
229             {
230               if (strcmp (rpc->r_aliases[i], name) == 0)
231                 {
232                   found = 1;
233                   break;
234                 }
235               else
236                 ++i;
237             }
238         }
239     }
240
241   internal_nis_endrpcent (&data);
242
243   if (!found && status == NSS_STATUS_SUCCESS)
244     return NSS_STATUS_NOTFOUND;
245   else
246     return status;
247 }
248
249 enum nss_status
250 _nss_nis_getrpcbynumber_r (int number, struct rpcent *rpc,
251                            char *buffer, size_t buflen)
252 {
253   struct parser_data *data = (void *) buffer;
254   enum nss_status retval;
255   char *domain, *result, *p;
256   int len, nlen, parse_res;
257   char buf[32];
258
259   if (yp_get_default_domain (&domain))
260     return NSS_STATUS_UNAVAIL;
261
262   nlen = sprintf (buf, "%d", number);
263
264   retval = yperr2nss (yp_match (domain, "rpc.bynumber", buf,
265                                  nlen, &result, &len));
266
267   if (retval != NSS_STATUS_SUCCESS)
268     {
269       if (retval == NSS_STATUS_TRYAGAIN)
270         __set_errno (EAGAIN);
271       return retval;
272     }
273
274   if ((size_t) (len + 1) > buflen)
275     {
276       free (result);
277       __set_errno (ERANGE);
278       return NSS_STATUS_TRYAGAIN;
279     }
280
281   p = strncpy (buffer, result, len);
282   buffer[len] = '\0';
283   while (isspace (*p))
284     ++p;
285   free (result);
286
287   parse_res = _nss_files_parse_rpcent (p, rpc, data, buflen);
288
289   if (!parse_res)
290     {
291       if (errno == ERANGE)
292         return NSS_STATUS_TRYAGAIN;
293       else
294         return NSS_STATUS_NOTFOUND;
295     }
296   else
297     return NSS_STATUS_SUCCESS;
298 }