Libinfo-78.tar.gz
[apple/libinfo.git] / lookup.subproj / lu_rpc.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24 /*
25 * RPC lookup
26 * Copyright (C) 1989 by NeXT, Inc.
27 */
28
29 #include <rpc/rpc.h>
30 #include <netdb.h>
31 #include <stdlib.h>
32 #include <mach/mach.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <netinet/in.h>
36
37 #include "_lu_types.h"
38 #include "lookup.h"
39 #include "lu_utils.h"
40 #include "lu_overrides.h"
41
42 static lookup_state r_state = LOOKUP_CACHE;
43 static struct rpcent global_r;
44 static int global_free = 1;
45 static char *r_data = NULL;
46 static unsigned r_datalen;
47 static int r_nentries;
48 static int r_start = 1;
49 static XDR r_xdr;
50
51 static void
52 freeold(void)
53 {
54 char **aliases;
55
56 if (global_free == 1) return;
57
58 free(global_r.r_name);
59
60 aliases = global_r.r_aliases;
61 if (aliases != NULL)
62 {
63 while (*aliases != NULL) free(*aliases++);
64 free(global_r.r_aliases);
65 }
66
67 global_free = 1;
68 }
69
70 static void
71 convert_r(_lu_rpcent *lu_r)
72 {
73 int i, len;
74
75 freeold();
76
77 global_r.r_name = strdup(lu_r->r_names.r_names_val[0]);
78
79 len = lu_r->r_names.r_names_len - 1;
80 global_r.r_aliases = (char **)malloc((len + 1) * sizeof(char *));
81
82 for (i = 0; i < len; i++)
83 {
84 global_r.r_aliases[i] = strdup(lu_r->r_names.r_names_val[i+1]);
85 }
86
87 global_r.r_aliases[len] = NULL;
88
89 global_r.r_number = lu_r->r_number;
90
91 global_free = 0;
92 }
93
94
95
96 static struct rpcent *
97 lu_getrpcbynumber(long number)
98 {
99 unsigned datalen;
100 _lu_rpcent_ptr lu_r;
101 XDR xdr;
102 static int proc = -1;
103 unit lookup_buf[MAX_INLINE_UNITS];
104
105 if (proc < 0)
106 {
107 if (_lookup_link(_lu_port, "getrpcbynumber", &proc) != KERN_SUCCESS)
108 {
109 return (NULL);
110 }
111 }
112
113 number = htonl(number);
114 datalen = MAX_INLINE_UNITS;
115 if (_lookup_one(_lu_port, proc, (unit *)&number, 1, lookup_buf, &datalen)
116 != KERN_SUCCESS)
117 {
118 return (NULL);
119 }
120
121 datalen *= BYTES_PER_XDR_UNIT;
122 xdrmem_create(&xdr, lookup_buf, datalen, XDR_DECODE);
123 lu_r = NULL;
124 if (!xdr__lu_rpcent_ptr(&xdr, &lu_r) || lu_r == NULL)
125 {
126 xdr_destroy(&xdr);
127 return (NULL);
128 }
129
130 xdr_destroy(&xdr);
131
132 convert_r(lu_r);
133 xdr_free(xdr__lu_rpcent_ptr, &lu_r);
134 return (&global_r);
135 }
136
137 static struct rpcent *
138 lu_getrpcbyname(const char *name)
139 {
140 unsigned datalen;
141 char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT];
142 XDR outxdr;
143 XDR inxdr;
144 _lu_rpcent_ptr lu_r;
145 static int proc = -1;
146 unit lookup_buf[MAX_INLINE_UNITS];
147
148 if (proc < 0)
149 {
150 if (_lookup_link(_lu_port, "getrpcbyname", &proc) != KERN_SUCCESS)
151 {
152 return (NULL);
153 }
154 }
155
156 xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE);
157 if (!xdr__lu_string(&outxdr, &name))
158 {
159 xdr_destroy(&outxdr);
160 return (NULL);
161 }
162
163 datalen = MAX_INLINE_UNITS;
164 if (_lookup_one(_lu_port, proc, (unit *)namebuf,
165 xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, lookup_buf, &datalen)
166 != KERN_SUCCESS)
167 {
168 xdr_destroy(&outxdr);
169 return (NULL);
170 }
171
172 xdr_destroy(&outxdr);
173
174 datalen *= BYTES_PER_XDR_UNIT;
175 xdrmem_create(&inxdr, lookup_buf, datalen,
176 XDR_DECODE);
177 lu_r = NULL;
178 if (!xdr__lu_rpcent_ptr(&inxdr, &lu_r) || (lu_r == NULL))
179 {
180 xdr_destroy(&inxdr);
181 return (NULL);
182 }
183
184 xdr_destroy(&inxdr);
185
186 convert_r(lu_r);
187 xdr_free(xdr__lu_rpcent_ptr, &lu_r);
188 return (&global_r);
189 }
190
191 static void
192 lu_endrpcent(void)
193 {
194 r_nentries = 0;
195 if (r_data != NULL)
196 {
197 freeold();
198 vm_deallocate(mach_task_self(), (vm_address_t)r_data, r_datalen);
199 r_data = NULL;
200 }
201 }
202
203 static int
204 lu_setrpcent(int stayopen)
205 {
206 lu_endrpcent();
207 r_start = 1;
208 return (1);
209 }
210
211 static struct rpcent *
212 lu_getrpcent()
213 {
214 static int proc = -1;
215 _lu_rpcent lu_r;
216
217 if (r_start == 1)
218 {
219 r_start = 0;
220
221 if (proc < 0)
222 {
223 if (_lookup_link(_lu_port, "getrpcent", &proc) != KERN_SUCCESS)
224 {
225 lu_endrpcent();
226 return (NULL);
227 }
228 }
229
230 if (_lookup_all(_lu_port, proc, NULL, 0, &r_data, &r_datalen)
231 != KERN_SUCCESS)
232 {
233 lu_endrpcent();
234 return (NULL);
235 }
236
237 #ifdef NOTDEF
238 /* NOTDEF because OOL buffers are counted in bytes with untyped IPC */
239 r_datalen *= BYTES_PER_XDR_UNIT;
240 #endif
241
242 xdrmem_create(&r_xdr, r_data, r_datalen,
243 XDR_DECODE);
244 if (!xdr_int(&r_xdr, &r_nentries))
245 {
246 xdr_destroy(&r_xdr);
247 lu_endrpcent();
248 return (NULL);
249 }
250 }
251
252 if (r_nentries == 0)
253 {
254 xdr_destroy(&r_xdr);
255 lu_endrpcent();
256 return (NULL);
257 }
258
259 bzero(&lu_r, sizeof(lu_r));
260 if (!xdr__lu_rpcent(&r_xdr, &lu_r))
261 {
262 xdr_destroy(&r_xdr);
263 lu_endrpcent();
264 return (NULL);
265 }
266
267 r_nentries--;
268 convert_r(&lu_r);
269 xdr_free(xdr__lu_rpcent, &lu_r);
270 return (&global_r);
271 }
272
273 struct rpcent *
274 getrpcbynumber(long number)
275 {
276 LOOKUP1(lu_getrpcbynumber, _old_getrpcbynumber, number, struct rpcent);
277 }
278
279 struct rpcent *
280 getrpcbyname(const char *name)
281 {
282 LOOKUP1(lu_getrpcbyname, _old_getrpcbyname, name, struct rpcent);
283 }
284
285 struct rpcent *
286 getrpcent(void)
287 {
288 GETENT(lu_getrpcent, _old_getrpcent, &r_state, struct rpcent);
289 }
290
291 void
292 setrpcent(int stayopen)
293 {
294 SETSTATE(lu_setrpcent, _old_setrpcent, &r_state, stayopen);
295 }
296
297 void
298 endrpcent(void)
299 {
300 UNSETSTATE(lu_endrpcent, _old_endrpcent, &r_state);
301 }