2 * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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
22 * @APPLE_LICENSE_HEADER_END@
26 * Copyright (C) 1989 by NeXT, Inc.
32 #include <mach/mach.h>
35 #include <netinet/in.h>
38 #include "_lu_types.h"
41 #include "lu_overrides.h"
43 static pthread_mutex_t _rpc_lock
= PTHREAD_MUTEX_INITIALIZER
;
45 #define RPC_GET_NAME 1
50 free_rpc_data(struct rpcent
*r
)
54 if (r
== NULL
) return;
56 if (r
->r_name
!= NULL
) free(r
->r_name
);
58 aliases
= r
->r_aliases
;
61 while (*aliases
!= NULL
) free(*aliases
++);
67 free_rpc(struct rpcent
*r
)
69 if (r
== NULL
) return;
75 free_lu_thread_info_rpc(void *x
)
77 struct lu_thread_info
*tdata
;
79 if (x
== NULL
) return;
81 tdata
= (struct lu_thread_info
*)x
;
83 if (tdata
->lu_entry
!= NULL
)
85 free_rpc((struct rpcent
*)tdata
->lu_entry
);
86 tdata
->lu_entry
= NULL
;
89 _lu_data_free_vm_xdr(tdata
);
94 static struct rpcent
*
98 int i
, j
, nvals
, nkeys
, status
;
101 if (xdr
== NULL
) return NULL
;
103 if (!xdr_int(xdr
, &nkeys
)) return NULL
;
105 r
= (struct rpcent
*)calloc(1, sizeof(struct rpcent
));
107 for (i
= 0; i
< nkeys
; i
++)
113 status
= _lu_xdr_attribute(xdr
, &key
, &vals
, &nvals
);
128 if ((r
->r_name
== NULL
) && (!strcmp("name", key
)))
133 r
->r_aliases
= (char **)calloc(nvals
, sizeof(char *));
134 for (j
= 1; j
< nvals
; j
++) r
->r_aliases
[j
-1] = vals
[j
];
138 else if (!strcmp("number", key
))
140 r
->r_number
= atoi(vals
[0]);
146 for (; j
< nvals
; j
++) free(vals
[j
]);
151 if (r
->r_name
== NULL
) r
->r_name
= strdup("");
152 if (r
->r_aliases
== NULL
) r
->r_aliases
= (char **)calloc(1, sizeof(char *));
157 static struct rpcent
*
158 copy_rpc(struct rpcent
*in
)
163 if (in
== NULL
) return NULL
;
165 r
= (struct rpcent
*)calloc(1, sizeof(struct rpcent
));
167 r
->r_name
= LU_COPY_STRING(in
->r_name
);
170 if (in
->r_aliases
!= NULL
)
172 for (len
= 0; in
->r_aliases
[len
] != NULL
; len
++);
175 r
->r_aliases
= (char **)calloc(len
+ 1, sizeof(char *));
176 for (i
= 0; i
< len
; i
++)
178 r
->r_aliases
[i
] = strdup(in
->r_aliases
[i
]);
181 r
->r_number
= in
->r_number
;
187 recycle_rpc(struct lu_thread_info
*tdata
, struct rpcent
*in
)
191 if (tdata
== NULL
) return;
192 r
= (struct rpcent
*)tdata
->lu_entry
;
197 tdata
->lu_entry
= NULL
;
200 if (tdata
->lu_entry
== NULL
)
202 tdata
->lu_entry
= in
;
208 r
->r_name
= in
->r_name
;
209 r
->r_aliases
= in
->r_aliases
;
210 r
->r_number
= in
->r_number
;
215 static struct rpcent
*
216 lu_getrpcbynumber(long number
)
221 static int proc
= -1;
227 if (_lookup_link(_lu_port
, "getrpcbynumber", &proc
) != KERN_SUCCESS
)
233 number
= htonl(number
);
237 if (_lookup_all(_lu_port
, proc
, (unit
*)&number
, 1, &lookup_buf
, &datalen
)
243 datalen
*= BYTES_PER_XDR_UNIT
;
244 if ((lookup_buf
== NULL
) || (datalen
== 0)) return NULL
;
246 xdrmem_create(&inxdr
, lookup_buf
, datalen
, XDR_DECODE
);
249 if (!xdr_int(&inxdr
, &count
))
252 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
259 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
263 r
= extract_rpc(&inxdr
);
265 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
270 static struct rpcent
*
271 lu_getrpcbyname(const char *name
)
275 char namebuf
[_LU_MAXLUSTRLEN
+ BYTES_PER_XDR_UNIT
];
277 static int proc
= -1;
283 if (_lookup_link(_lu_port
, "getrpcbyname", &proc
) != KERN_SUCCESS
)
289 xdrmem_create(&outxdr
, namebuf
, sizeof(namebuf
), XDR_ENCODE
);
290 if (!xdr__lu_string(&outxdr
, (_lu_string
*)&name
))
292 xdr_destroy(&outxdr
);
299 if (_lookup_all(_lu_port
, proc
, (unit
*)namebuf
,
300 xdr_getpos(&outxdr
) / BYTES_PER_XDR_UNIT
, &lookup_buf
, &datalen
)
303 xdr_destroy(&outxdr
);
307 xdr_destroy(&outxdr
);
309 datalen
*= BYTES_PER_XDR_UNIT
;
310 if ((lookup_buf
== NULL
) || (datalen
== 0)) return NULL
;
312 xdrmem_create(&inxdr
, lookup_buf
, datalen
, XDR_DECODE
);
315 if (!xdr_int(&inxdr
, &count
))
318 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
325 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
329 r
= extract_rpc(&inxdr
);
331 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
339 struct lu_thread_info
*tdata
;
341 tdata
= _lu_data_create_key(_lu_data_key_rpc
, free_lu_thread_info_rpc
);
342 _lu_data_free_vm_xdr(tdata
);
351 static struct rpcent
*
355 static int proc
= -1;
356 struct lu_thread_info
*tdata
;
358 tdata
= _lu_data_create_key(_lu_data_key_rpc
, free_lu_thread_info_rpc
);
361 tdata
= (struct lu_thread_info
*)calloc(1, sizeof(struct lu_thread_info
));
362 _lu_data_set_key(_lu_data_key_rpc
, tdata
);
365 if (tdata
->lu_vm
== NULL
)
369 if (_lookup_link(_lu_port
, "getrpcent", &proc
) != KERN_SUCCESS
)
376 if (_lookup_all(_lu_port
, proc
, NULL
, 0, &(tdata
->lu_vm
), &(tdata
->lu_vm_length
)) != KERN_SUCCESS
)
382 /* mig stubs measure size in words (4 bytes) */
383 tdata
->lu_vm_length
*= 4;
385 if (tdata
->lu_xdr
!= NULL
)
387 xdr_destroy(tdata
->lu_xdr
);
390 tdata
->lu_xdr
= (XDR
*)calloc(1, sizeof(XDR
));
392 xdrmem_create(tdata
->lu_xdr
, tdata
->lu_vm
, tdata
->lu_vm_length
, XDR_DECODE
);
393 if (!xdr_int(tdata
->lu_xdr
, &tdata
->lu_vm_cursor
))
400 if (tdata
->lu_vm_cursor
== 0)
406 r
= extract_rpc(tdata
->lu_xdr
);
413 tdata
->lu_vm_cursor
--;
418 static struct rpcent
*
419 getrpc(const char *name
, long number
, int source
)
421 struct rpcent
*res
= NULL
;
422 struct lu_thread_info
*tdata
;
424 tdata
= _lu_data_create_key(_lu_data_key_rpc
, free_lu_thread_info_rpc
);
427 tdata
= (struct lu_thread_info
*)calloc(1, sizeof(struct lu_thread_info
));
428 _lu_data_set_key(_lu_data_key_rpc
, tdata
);
436 res
= lu_getrpcbyname(name
);
439 res
= lu_getrpcbynumber(number
);
442 res
= lu_getrpcent();
449 pthread_mutex_lock(&_rpc_lock
);
453 res
= copy_rpc(_old_getrpcbyname(name
));
456 res
= copy_rpc(_old_getrpcbynumber(number
));
459 res
= copy_rpc(_old_getrpcent());
463 pthread_mutex_unlock(&_rpc_lock
);
466 recycle_rpc(tdata
, res
);
467 return (struct rpcent
*)tdata
->lu_entry
;
471 getrpcbyname(const char *name
)
473 return getrpc(name
, -2, RPC_GET_NAME
);
477 getrpcbynumber(long number
)
479 return getrpc(NULL
, number
, RPC_GET_NUM
);
485 return getrpc(NULL
, -2, RPC_GET_ENT
);
489 setrpcent(int stayopen
)
491 if (_lu_running()) lu_setrpcent();
492 else _old_setrpcent(stayopen
);
498 if (_lu_running()) lu_endrpcent();
499 else _old_endrpcent();