2 * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
27 * Copyright (C) 1989 by NeXT, Inc.
33 #include <mach/mach.h>
36 #include <netinet/in.h>
39 #include "_lu_types.h"
42 #include "lu_overrides.h"
44 static pthread_mutex_t _rpc_lock
= PTHREAD_MUTEX_INITIALIZER
;
46 #define RPC_GET_NAME 1
51 free_rpc_data(struct rpcent
*r
)
55 if (r
== NULL
) return;
57 if (r
->r_name
!= NULL
) free(r
->r_name
);
59 aliases
= r
->r_aliases
;
62 while (*aliases
!= NULL
) free(*aliases
++);
68 free_rpc(struct rpcent
*r
)
70 if (r
== NULL
) return;
76 free_lu_thread_info_rpc(void *x
)
78 struct lu_thread_info
*tdata
;
80 if (x
== NULL
) return;
82 tdata
= (struct lu_thread_info
*)x
;
84 if (tdata
->lu_entry
!= NULL
)
86 free_rpc((struct rpcent
*)tdata
->lu_entry
);
87 tdata
->lu_entry
= NULL
;
90 _lu_data_free_vm_xdr(tdata
);
95 static struct rpcent
*
99 int i
, j
, nvals
, nkeys
, status
;
102 if (xdr
== NULL
) return NULL
;
104 if (!xdr_int(xdr
, &nkeys
)) return NULL
;
106 r
= (struct rpcent
*)calloc(1, sizeof(struct rpcent
));
108 for (i
= 0; i
< nkeys
; i
++)
114 status
= _lu_xdr_attribute(xdr
, &key
, &vals
, &nvals
);
129 if ((r
->r_name
== NULL
) && (!strcmp("name", key
)))
134 r
->r_aliases
= (char **)calloc(nvals
, sizeof(char *));
135 for (j
= 1; j
< nvals
; j
++) r
->r_aliases
[j
-1] = vals
[j
];
139 else if (!strcmp("number", key
))
141 r
->r_number
= atoi(vals
[0]);
147 for (; j
< nvals
; j
++) free(vals
[j
]);
152 if (r
->r_name
== NULL
) r
->r_name
= strdup("");
153 if (r
->r_aliases
== NULL
) r
->r_aliases
= (char **)calloc(1, sizeof(char *));
158 static struct rpcent
*
159 copy_rpc(struct rpcent
*in
)
164 if (in
== NULL
) return NULL
;
166 r
= (struct rpcent
*)calloc(1, sizeof(struct rpcent
));
168 r
->r_name
= LU_COPY_STRING(in
->r_name
);
171 if (in
->r_aliases
!= NULL
)
173 for (len
= 0; in
->r_aliases
[len
] != NULL
; len
++);
176 r
->r_aliases
= (char **)calloc(len
+ 1, sizeof(char *));
177 for (i
= 0; i
< len
; i
++)
179 r
->r_aliases
[i
] = strdup(in
->r_aliases
[i
]);
182 r
->r_number
= in
->r_number
;
188 recycle_rpc(struct lu_thread_info
*tdata
, struct rpcent
*in
)
192 if (tdata
== NULL
) return;
193 r
= (struct rpcent
*)tdata
->lu_entry
;
198 tdata
->lu_entry
= NULL
;
201 if (tdata
->lu_entry
== NULL
)
203 tdata
->lu_entry
= in
;
209 r
->r_name
= in
->r_name
;
210 r
->r_aliases
= in
->r_aliases
;
211 r
->r_number
= in
->r_number
;
216 static struct rpcent
*
217 lu_getrpcbynumber(long number
)
222 static int proc
= -1;
228 if (_lookup_link(_lu_port
, "getrpcbynumber", &proc
) != KERN_SUCCESS
)
234 number
= htonl(number
);
238 if (_lookup_all(_lu_port
, proc
, (unit
*)&number
, 1, &lookup_buf
, &datalen
)
244 datalen
*= BYTES_PER_XDR_UNIT
;
245 if ((lookup_buf
== NULL
) || (datalen
== 0)) return NULL
;
247 xdrmem_create(&inxdr
, lookup_buf
, datalen
, XDR_DECODE
);
250 if (!xdr_int(&inxdr
, &count
))
253 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
260 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
264 r
= extract_rpc(&inxdr
);
266 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
271 static struct rpcent
*
272 lu_getrpcbyname(const char *name
)
276 char namebuf
[_LU_MAXLUSTRLEN
+ BYTES_PER_XDR_UNIT
];
278 static int proc
= -1;
284 if (_lookup_link(_lu_port
, "getrpcbyname", &proc
) != KERN_SUCCESS
)
290 xdrmem_create(&outxdr
, namebuf
, sizeof(namebuf
), XDR_ENCODE
);
291 if (!xdr__lu_string(&outxdr
, (_lu_string
*)&name
))
293 xdr_destroy(&outxdr
);
300 if (_lookup_all(_lu_port
, proc
, (unit
*)namebuf
,
301 xdr_getpos(&outxdr
) / BYTES_PER_XDR_UNIT
, &lookup_buf
, &datalen
)
304 xdr_destroy(&outxdr
);
308 xdr_destroy(&outxdr
);
310 datalen
*= BYTES_PER_XDR_UNIT
;
311 if ((lookup_buf
== NULL
) || (datalen
== 0)) return NULL
;
313 xdrmem_create(&inxdr
, lookup_buf
, datalen
, XDR_DECODE
);
316 if (!xdr_int(&inxdr
, &count
))
319 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
326 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
330 r
= extract_rpc(&inxdr
);
332 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
340 struct lu_thread_info
*tdata
;
342 tdata
= _lu_data_create_key(_lu_data_key_rpc
, free_lu_thread_info_rpc
);
343 _lu_data_free_vm_xdr(tdata
);
352 static struct rpcent
*
356 static int proc
= -1;
357 struct lu_thread_info
*tdata
;
359 tdata
= _lu_data_create_key(_lu_data_key_rpc
, free_lu_thread_info_rpc
);
362 tdata
= (struct lu_thread_info
*)calloc(1, sizeof(struct lu_thread_info
));
363 _lu_data_set_key(_lu_data_key_rpc
, tdata
);
366 if (tdata
->lu_vm
== NULL
)
370 if (_lookup_link(_lu_port
, "getrpcent", &proc
) != KERN_SUCCESS
)
377 if (_lookup_all(_lu_port
, proc
, NULL
, 0, &(tdata
->lu_vm
), &(tdata
->lu_vm_length
)) != KERN_SUCCESS
)
383 /* mig stubs measure size in words (4 bytes) */
384 tdata
->lu_vm_length
*= 4;
386 if (tdata
->lu_xdr
!= NULL
)
388 xdr_destroy(tdata
->lu_xdr
);
391 tdata
->lu_xdr
= (XDR
*)calloc(1, sizeof(XDR
));
393 xdrmem_create(tdata
->lu_xdr
, tdata
->lu_vm
, tdata
->lu_vm_length
, XDR_DECODE
);
394 if (!xdr_int(tdata
->lu_xdr
, &tdata
->lu_vm_cursor
))
401 if (tdata
->lu_vm_cursor
== 0)
407 r
= extract_rpc(tdata
->lu_xdr
);
414 tdata
->lu_vm_cursor
--;
419 static struct rpcent
*
420 getrpc(const char *name
, long number
, int source
)
422 struct rpcent
*res
= NULL
;
423 struct lu_thread_info
*tdata
;
425 tdata
= _lu_data_create_key(_lu_data_key_rpc
, free_lu_thread_info_rpc
);
428 tdata
= (struct lu_thread_info
*)calloc(1, sizeof(struct lu_thread_info
));
429 _lu_data_set_key(_lu_data_key_rpc
, tdata
);
437 res
= lu_getrpcbyname(name
);
440 res
= lu_getrpcbynumber(number
);
443 res
= lu_getrpcent();
450 pthread_mutex_lock(&_rpc_lock
);
454 res
= copy_rpc(_old_getrpcbyname(name
));
457 res
= copy_rpc(_old_getrpcbynumber(number
));
460 res
= copy_rpc(_old_getrpcent());
464 pthread_mutex_unlock(&_rpc_lock
);
467 recycle_rpc(tdata
, res
);
468 return (struct rpcent
*)tdata
->lu_entry
;
472 getrpcbyname(const char *name
)
474 return getrpc(name
, -2, RPC_GET_NAME
);
478 getrpcbynumber(long number
)
480 return getrpc(NULL
, number
, RPC_GET_NUM
);
486 return getrpc(NULL
, -2, RPC_GET_ENT
);
490 setrpcent(int stayopen
)
492 if (_lu_running()) lu_setrpcent();
493 else _old_setrpcent(stayopen
);
499 if (_lu_running()) lu_endrpcent();
500 else _old_endrpcent();