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@
27 #include <mach/mach.h>
32 #include "_lu_types.h"
35 #include "netdb_async.h"
37 #define MAX_LOOKUP_ATTEMPTS 10
38 #define _LU_MAXLUSTRLEN 256
39 #define QBUF_SIZE 4096
41 #define LU_MESSAGE_SEND_ID 4241776
42 #define LU_MESSAGE_REPLY_ID 4241876
44 static pthread_key_t _info_key
= 0;
45 static pthread_once_t _info_key_initialized
= PTHREAD_ONCE_INIT
;
52 void (**idata_destructor
)(void *);
55 typedef struct _lu_async_request_s
57 mach_port_t reply_port
;
62 ooline_data request_buffer
;
63 mach_msg_type_number_t request_buffer_len
;
64 struct _lu_async_request_s
*next
;
65 } _lu_async_request_t
;
69 mach_msg_header_t head
;
72 mach_msg_type_number_t query_data_len
;
73 unit query_data
[QBUF_SIZE
];
78 mach_msg_header_t head
;
79 mach_msg_body_t msgh_body
;
80 mach_msg_ool_descriptor_t reply_data
;
82 mach_msg_type_number_t reply_data_len
;
83 mach_msg_format_0_trailer_t trailer
;
86 static pthread_mutex_t _lu_worklist_lock
= PTHREAD_MUTEX_INITIALIZER
;
87 static _lu_async_request_t
*_lu_worklist
= NULL
;
89 /* Send an asynchronous query message to lookupd */
91 _lu_async_send(_lu_async_request_t
*r
)
94 register _lu_query_msg_t
*inp
= &in
;
95 mach_msg_return_t status
;
96 unsigned int msgh_size
;
98 if (r
== NULL
) return KERN_FAILURE
;
100 if (r
->retry
== 0) return MIG_SERVER_DIED
;
103 if (r
->request_buffer_len
> QBUF_SIZE
) return MIG_ARRAY_TOO_LARGE
;
105 msgh_size
= (sizeof(_lu_query_msg_t
) - 16384) + ((4 * r
->request_buffer_len
));
106 inp
->head
.msgh_bits
= MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE
);
107 inp
->head
.msgh_remote_port
= _lu_port
;
108 inp
->head
.msgh_local_port
= r
->reply_port
;
109 inp
->head
.msgh_id
= LU_MESSAGE_SEND_ID
;
110 inp
->NDR
= NDR_record
;
112 inp
->query_data_len
= r
->request_buffer_len
;
113 memcpy(inp
->query_data
, r
->request_buffer
, 4 * r
->request_buffer_len
);
115 status
= mach_msg(&inp
->head
, MACH_SEND_MSG
, msgh_size
, 0, MACH_PORT_NULL
, MACH_MSG_TIMEOUT_NONE
, MACH_PORT_NULL
);
116 if (status
== MACH_MSG_SUCCESS
) return KERN_SUCCESS
;
118 if (status
== MACH_SEND_INVALID_REPLY
)
120 mach_port_mod_refs(mach_task_self(), r
->reply_port
, MACH_PORT_RIGHT_RECEIVE
, -1);
121 r
->reply_port
= MACH_PORT_NULL
;
127 static _lu_async_request_t
*
128 _lu_worklist_remove(mach_port_t p
)
130 _lu_async_request_t
*r
, *n
;
132 if (p
== MACH_PORT_NULL
) return NULL
;
133 if (_lu_worklist
== NULL
) return NULL
;
135 pthread_mutex_lock(&_lu_worklist_lock
);
137 if (_lu_worklist
->reply_port
== p
)
140 _lu_worklist
= r
->next
;
141 pthread_mutex_unlock(&_lu_worklist_lock
);
145 for (r
= _lu_worklist
; r
!= NULL
; r
= r
->next
)
148 if (n
== NULL
) break;
150 if (n
->reply_port
== p
)
153 pthread_mutex_unlock(&_lu_worklist_lock
);
158 pthread_mutex_unlock(&_lu_worklist_lock
);
162 static _lu_async_request_t
*
163 _lu_worklist_find(mach_port_t p
)
165 _lu_async_request_t
*r
;
167 if (p
== MACH_PORT_NULL
) return NULL
;
168 if (_lu_worklist
== NULL
) return NULL
;
170 pthread_mutex_lock(&_lu_worklist_lock
);
172 for (r
= _lu_worklist
; r
!= NULL
; r
= r
->next
)
174 if (r
->reply_port
== p
)
176 pthread_mutex_unlock(&_lu_worklist_lock
);
181 pthread_mutex_unlock(&_lu_worklist_lock
);
186 _lu_free_request(_lu_async_request_t
*r
)
188 if (r
== NULL
) return;
190 if (r
->request_buffer
!= NULL
) free(r
->request_buffer
);
191 r
->request_buffer
= NULL
;
193 if (r
->reply_port
!= MACH_PORT_NULL
) mach_port_destroy(mach_task_self(), r
->reply_port
);
194 r
->reply_port
= MACH_PORT_NULL
;
199 /* Receive an asynchronous reply message from lookupd */
201 lu_async_receive(mach_port_t p
, char **buf
, uint32_t *len
)
204 kern_return_t status
;
206 _lu_async_request_t
*req
;
207 boolean_t msgh_simple
;
209 size
= sizeof(_lu_reply_msg_t
);
211 r
= (_lu_reply_msg_t
*)calloc(1, size
);
212 if (r
== NULL
) return KERN_RESOURCE_SHORTAGE
;
214 r
->head
.msgh_local_port
= p
;
215 r
->head
.msgh_size
= size
;
216 status
= mach_msg(&(r
->head
), MACH_RCV_MSG
, 0, size
, r
->head
.msgh_local_port
, 0, MACH_PORT_NULL
);
217 if (status
!= KERN_SUCCESS
)
223 msgh_simple
= !(r
->head
.msgh_bits
& MACH_MSGH_BITS_COMPLEX
);
225 req
= _lu_worklist_remove(r
->head
.msgh_local_port
);
232 if (msgh_simple
&& ((mig_reply_error_t
*) r
)->RetCode
!= KERN_SUCCESS
)
234 _lu_free_request(req
);
235 status
= ((mig_reply_error_t
*) r
)->RetCode
;
240 *buf
= r
->reply_data
.address
;
241 *len
= r
->reply_data
.size
;
245 _lu_free_request(req
);
250 _lu_worklist_append(_lu_async_request_t
*r
)
252 _lu_async_request_t
*p
;
254 if (r
== NULL
) return;
256 pthread_mutex_lock(&_lu_worklist_lock
);
258 if (_lu_worklist
== NULL
)
261 pthread_mutex_unlock(&_lu_worklist_lock
);
265 for (p
= _lu_worklist
; p
->next
!= NULL
; p
= p
->next
);
268 pthread_mutex_unlock(&_lu_worklist_lock
);
272 lu_async_call_cancel(mach_port_t p
)
274 _lu_async_request_t
*req
;
276 req
= _lu_worklist_remove(p
);
277 if (req
!= NULL
) _lu_free_request(req
);
278 else if (p
!= MACH_PORT_NULL
) mach_port_destroy(mach_task_self(), p
);
281 static _lu_async_request_t
*
282 _lu_create_request(uint32_t proc
, const char *buf
, uint32_t len
, void *callback
, void *context
)
284 _lu_async_request_t
*r
;
285 kern_return_t status
;
287 if (_lu_port
== MACH_PORT_NULL
) return NULL
;
289 r
= (_lu_async_request_t
*)calloc(1, sizeof(_lu_async_request_t
));
290 if (r
== NULL
) return NULL
;
292 status
= mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE
, &(r
->reply_port
));
293 if (status
!= KERN_SUCCESS
)
299 r
->retry
= MAX_LOOKUP_ATTEMPTS
;
301 r
->context
= context
;
302 r
->callback
= callback
;
305 r
->request_buffer
= malloc(len
* BYTES_PER_XDR_UNIT
);
306 if (r
->request_buffer
== NULL
)
312 memcpy(r
->request_buffer
, buf
, len
* BYTES_PER_XDR_UNIT
);
313 r
->request_buffer_len
= len
;
321 lu_async_start(mach_port_t
*p
, uint32_t proc
, const char *buf
, uint32_t len
, void *callback
, void *context
)
323 _lu_async_request_t
*r
;
324 kern_return_t status
;
327 if (p
== NULL
) return KERN_FAILURE
;
331 if (!_lu_running()) return KERN_FAILURE
;
333 /* Make a request struct to keep track */
334 r
= _lu_create_request(proc
, buf
, len
, callback
, context
);
335 if (r
== NULL
) return KERN_FAILURE
;
337 status
= MIG_SERVER_DIED
;
338 for (retry
= 0; (status
== MIG_SERVER_DIED
) && (retry
< MAX_LOOKUP_ATTEMPTS
); retry
++)
340 /* send to lookupd */
341 status
= _lu_async_send(r
);
344 if (status
!= KERN_SUCCESS
)
350 /* Add request to worklist */
351 _lu_worklist_append(r
);
358 lu_async_send(mach_port_t
*p
, uint32_t proc
, const char *buf
, uint32_t len
)
360 return lu_async_start(p
, proc
, buf
, len
, NULL
, NULL
);
364 lu_async_handle_reply(void *msg
, char **buf
, uint32_t *len
, void **callback
, void **context
)
367 _lu_async_request_t
*req
;
368 kern_return_t status
;
370 boolean_t msgh_simple
;
372 if (msg
== NULL
) return -1;
373 r
= (_lu_reply_msg_t
*)msg
;
375 /* If reply status was an error, resend */
376 if (r
->head
.msgh_id
!= LU_MESSAGE_REPLY_ID
)
378 if (r
->head
.msgh_id
== MACH_NOTIFY_SEND_ONCE
)
380 /* if MiG server (lookupd) died */
381 req
= _lu_worklist_find(r
->head
.msgh_local_port
);
382 if (req
== NULL
) return -1;
384 status
= MIG_SERVER_DIED
;
385 for (retry
= 0; (status
== MIG_SERVER_DIED
) && (retry
< MAX_LOOKUP_ATTEMPTS
); retry
++)
387 /* send to lookupd */
388 status
= _lu_async_send(req
);
391 if (status
!= KERN_SUCCESS
) return -1;
393 return MIG_REPLY_MISMATCH
;
396 msgh_simple
= !(r
->head
.msgh_bits
& MACH_MSGH_BITS_COMPLEX
);
398 req
= _lu_worklist_remove(r
->head
.msgh_local_port
);
399 if (req
== NULL
) return -1;
401 *callback
= req
->callback
;
402 *context
= req
->context
;
403 _lu_free_request(req
);
405 if (msgh_simple
&& ((mig_reply_error_t
*) r
)->RetCode
!= KERN_SUCCESS
)
407 return ((mig_reply_error_t
*) r
)->RetCode
;
410 *buf
= r
->reply_data
.address
;
411 *len
= r
->reply_data
.size
;
417 _lookupd_xdr_dictionary(XDR
*inxdr
)
419 int i
, nkeys
, j
, nvals
;
423 if (!xdr_int(inxdr
, &nkeys
)) return NULL
;
425 l
= (ni_proplist
*)malloc(sizeof(ni_proplist
));
426 if (l
== NULL
) return NULL
;
430 l
->ni_proplist_len
= nkeys
;
431 l
->ni_proplist_val
= NULL
;
434 l
->ni_proplist_val
= (ni_property
*)calloc(nkeys
, sizeof(ni_property
));
435 if (l
->ni_proplist_val
== NULL
)
442 for (i
= 0; i
< nkeys
; i
++)
445 if (!xdr_string(inxdr
, &key
, -1))
451 l
->ni_proplist_val
[i
].nip_name
= key
;
453 if (!xdr_int(inxdr
, &nvals
))
459 l
->ni_proplist_val
[i
].nip_val
.ni_namelist_len
= nvals
;
462 l
->ni_proplist_val
[i
].nip_val
.ni_namelist_val
= (ni_name
*)calloc(nvals
, sizeof(ni_name
));
463 if (l
->ni_proplist_val
[i
].nip_val
.ni_namelist_val
== NULL
)
470 for (j
= 0; j
< nvals
; j
++)
473 if (!xdr_string(inxdr
, &val
, -1))
479 l
->ni_proplist_val
[i
].nip_val
.ni_namelist_val
[j
] = val
;
487 lookupd_query(ni_proplist
*l
, ni_proplist
***out
)
494 char databuf
[_LU_MAXLUSTRLEN
* BYTES_PER_XDR_UNIT
];
496 kern_return_t status
;
499 if (l
== NULL
) return 0;
500 if (out
== NULL
) return 0;
502 if (_lu_port
== MACH_PORT_NULL
) return 0;
504 status
= _lookup_link(_lu_port
, "query", &proc
);
505 if (status
!= KERN_SUCCESS
) return 0;
507 xdrmem_create(&outxdr
, databuf
, sizeof(databuf
), XDR_ENCODE
);
509 na
= l
->ni_proplist_len
;
511 /* Encode attribute count */
512 if (!xdr_int(&outxdr
, &na
))
514 xdr_destroy(&outxdr
);
518 for (i
= 0; i
< l
->ni_proplist_len
; i
++)
520 p
= &(l
->ni_proplist_val
[i
]);
522 if (!xdr_string(&outxdr
, &s
, _LU_MAXLUSTRLEN
))
524 xdr_destroy(&outxdr
);
528 if (!xdr_int(&outxdr
, &(p
->nip_val
.ni_namelist_len
)))
530 xdr_destroy(&outxdr
);
534 for (j
= 0; j
< p
->nip_val
.ni_namelist_len
; j
++)
536 s
= p
->nip_val
.ni_namelist_val
[j
];
537 if (!xdr_string(&outxdr
, &s
, _LU_MAXLUSTRLEN
))
539 xdr_destroy(&outxdr
);
548 n
= xdr_getpos(&outxdr
);
549 status
= _lookup_all(_lu_port
, proc
, (void *)databuf
, n
, &listbuf
, &datalen
);
550 if (status
!= KERN_SUCCESS
)
552 xdr_destroy(&outxdr
);
556 xdr_destroy(&outxdr
);
557 datalen
*= BYTES_PER_XDR_UNIT
;
558 xdrmem_create(&inxdr
, listbuf
, datalen
, XDR_DECODE
);
560 if (!xdr_int(&inxdr
, &n
))
572 *out
= (ni_proplist
**)malloc(n
* sizeof(ni_proplist
*));
579 for (i
= 0; i
< n
; i
++)
581 (*out
)[i
] = _lookupd_xdr_dictionary(&inxdr
);
586 vm_deallocate(mach_task_self(), (vm_address_t
)listbuf
, datalen
);
592 lookupd_make_query(char *cat
, char *fmt
, ...)
600 if (fmt
== NULL
) return NULL
;
601 if (fmt
[0] != 'k') return NULL
;
603 l
= (ni_proplist
*)malloc(sizeof(ni_proplist
));
604 if (l
== NULL
) return NULL
;
613 l
->ni_proplist_val
= (ni_property
*)malloc(sizeof(ni_property
));
614 if (l
->ni_proplist_val
== NULL
)
620 p
= &(l
->ni_proplist_val
[0]);
621 arg
= "_lookup_category";
622 p
->nip_name
= strdup(arg
);
623 if (p
->nip_name
== NULL
)
629 p
->nip_val
.ni_namelist_len
= 1;
630 p
->nip_val
.ni_namelist_val
= (ni_name
*)malloc(sizeof(ni_name
));
631 if (p
->nip_val
.ni_namelist_val
== NULL
)
637 p
->nip_val
.ni_namelist_val
[0] = strdup(cat
);
638 if (p
->nip_val
.ni_namelist_val
[0] == NULL
)
644 l
->ni_proplist_len
++;
649 for (f
= fmt
; (*f
) != '\0'; f
++)
651 arg
= va_arg(ap
, char *);
654 l
->ni_proplist_val
= (ni_property
*)reallocf(l
->ni_proplist_val
, (l
->ni_proplist_len
+ 1) * sizeof(ni_property
));
655 if (l
->ni_proplist_val
== NULL
)
661 p
= &(l
->ni_proplist_val
[l
->ni_proplist_len
]);
662 p
->nip_name
= strdup(arg
);
663 if (p
->nip_name
== NULL
)
669 p
->nip_val
.ni_namelist_len
= 0;
670 p
->nip_val
.ni_namelist_val
= NULL
;
672 l
->ni_proplist_len
++;
677 p
= &(l
->ni_proplist_val
[x
]);
678 if (p
->nip_val
.ni_namelist_len
== 0)
680 p
->nip_val
.ni_namelist_val
= (ni_name
*)malloc(sizeof(ni_name
));
684 p
->nip_val
.ni_namelist_val
= (ni_name
*)reallocf(p
->nip_val
.ni_namelist_val
, (p
->nip_val
.ni_namelist_len
+ 1) * sizeof(ni_name
));
687 if (p
->nip_val
.ni_namelist_val
== NULL
)
693 p
->nip_val
.ni_namelist_val
[p
->nip_val
.ni_namelist_len
] = strdup(arg
);
694 if (p
->nip_val
.ni_namelist_val
[p
->nip_val
.ni_namelist_len
] == NULL
)
700 p
->nip_val
.ni_namelist_len
++;
709 ni_property_merge(ni_property
*a
, ni_property
*b
)
713 if (a
== NULL
) return;
714 if (b
== NULL
) return;
716 for (j
= 0; j
< b
->nip_val
.ni_namelist_len
; j
++)
719 for (i
= 0; i
< (a
->nip_val
.ni_namelist_len
) && (addme
== 1); i
++)
721 if (!strcmp(a
->nip_val
.ni_namelist_val
[i
], b
->nip_val
.ni_namelist_val
[j
])) addme
= 0;
726 a
->nip_val
.ni_namelist_val
= (ni_name
*)reallocf(a
->nip_val
.ni_namelist_val
, (a
->nip_val
.ni_namelist_len
+ 1) * sizeof(ni_name
));
727 if (a
->nip_val
.ni_namelist_val
== NULL
) return;
729 a
->nip_val
.ni_namelist_val
[a
->nip_val
.ni_namelist_len
] = strdup(b
->nip_val
.ni_namelist_val
[j
]);
730 if (a
->nip_val
.ni_namelist_val
[a
->nip_val
.ni_namelist_len
] == NULL
)
732 free(a
->nip_val
.ni_namelist_val
);
733 a
->nip_val
.ni_namelist_val
= NULL
;
737 a
->nip_val
.ni_namelist_len
++;
743 ni_proplist_merge(ni_proplist
*a
, ni_proplist
*b
)
748 if (a
== NULL
) return;
749 if (b
== NULL
) return;
751 for (wb
= 0; wb
< b
->ni_proplist_len
; wb
++)
754 for (wa
= 0; (wa
< a
->ni_proplist_len
) && (addme
== 1) ; wa
++)
756 if (!strcmp(a
->ni_proplist_val
[wa
].nip_name
, b
->ni_proplist_val
[wb
].nip_name
)) addme
= 0;
760 a
->ni_proplist_val
= (ni_property
*)reallocf(a
->ni_proplist_val
, (a
->ni_proplist_len
+ 1) * sizeof(ni_property
));
761 if (a
->ni_proplist_val
== NULL
) return;
763 a
->ni_proplist_val
[a
->ni_proplist_len
].nip_name
= strdup(b
->ni_proplist_val
[wb
].nip_name
);
764 if (a
->ni_proplist_val
[a
->ni_proplist_len
].nip_name
== NULL
)
766 free(a
->ni_proplist_val
);
767 a
->ni_proplist_val
= NULL
;
771 a
->ni_proplist_val
[a
->ni_proplist_len
].nip_val
.ni_namelist_len
= 0;
772 a
->ni_proplist_val
[a
->ni_proplist_len
].nip_val
.ni_namelist_val
= NULL
;
773 a
->ni_proplist_len
++;
777 for (wb
= 0; wb
< b
->ni_proplist_len
; wb
++)
779 for (wa
= 0; wa
< a
->ni_proplist_len
; wa
++)
781 if (!strcmp(a
->ni_proplist_val
[wa
].nip_name
, b
->ni_proplist_val
[wb
].nip_name
))
783 ni_property_merge(&(a
->ni_proplist_val
[wa
]), &(b
->ni_proplist_val
[wb
]));
790 _lu_data_free(void *x
)
792 struct _lu_data_s
*t
;
795 if (x
== NULL
) return;
797 t
= (struct _lu_data_s
*)x
;
799 for (i
= 0; i
< t
->icount
; i
++)
801 if ((t
->idata
[i
] != NULL
) && (t
->idata_destructor
[i
] != NULL
))
803 (*(t
->idata_destructor
[i
]))(t
->idata
[i
]);
807 t
->idata_destructor
[i
] = NULL
;
810 if (t
->ikey
!= NULL
) free(t
->ikey
);
813 if (t
->idata
!= NULL
) free(t
->idata
);
816 if (t
->idata_destructor
!= NULL
) free(t
->idata_destructor
);
817 t
->idata_destructor
= NULL
;
825 pthread_key_create(&_info_key
, _lu_data_free
);
829 static struct _lu_data_s
*
832 struct _lu_data_s
*libinfo_data
;
835 * Only one thread should create the _info_key
837 pthread_once(&_info_key_initialized
, _lu_data_init
);
839 /* Check if this thread already created libinfo_data */
840 libinfo_data
= pthread_getspecific(_info_key
);
841 if (libinfo_data
!= NULL
) return libinfo_data
;
843 libinfo_data
= (struct _lu_data_s
*)calloc(1, sizeof(struct _lu_data_s
));
844 if (libinfo_data
== NULL
) return NULL
;
846 pthread_setspecific(_info_key
, libinfo_data
);
851 _lu_data_create_key(unsigned int key
, void (*destructor
)(void *))
853 struct _lu_data_s
*libinfo_data
;
856 libinfo_data
= _lu_data_get();
857 if (libinfo_data
== NULL
) return NULL
;
859 for (i
= 0; i
< libinfo_data
->icount
; i
++)
861 if (libinfo_data
->ikey
[i
] == key
) return libinfo_data
->idata
[i
];
864 i
= libinfo_data
->icount
;
869 libinfo_data
->ikey
= (unsigned int *)malloc(sizeof(unsigned int));
870 libinfo_data
->idata
= (void **)malloc(sizeof(void *));
871 libinfo_data
->idata_destructor
= (void (**)(void *))malloc(sizeof(void (*)(void *)));
875 libinfo_data
->ikey
= (unsigned int *)reallocf(libinfo_data
->ikey
, n
* sizeof(unsigned int));
876 libinfo_data
->idata
= (void **)reallocf(libinfo_data
->idata
, n
* sizeof(void *));
877 libinfo_data
->idata_destructor
= (void (**)(void *))reallocf(libinfo_data
->idata_destructor
, n
* sizeof(void (*)(void *)));
880 if ((libinfo_data
->ikey
== NULL
) || (libinfo_data
->idata
== NULL
) || (libinfo_data
->idata_destructor
== NULL
))
882 if (libinfo_data
->ikey
!= NULL
) free(libinfo_data
->ikey
);
883 if (libinfo_data
->idata
!= NULL
) free(libinfo_data
->idata
);
884 if (libinfo_data
->idata_destructor
!= NULL
) free(libinfo_data
->idata_destructor
);
888 libinfo_data
->ikey
[i
] = key
;
889 libinfo_data
->idata
[i
] = NULL
;
890 libinfo_data
->idata_destructor
[i
] = destructor
;
891 libinfo_data
->icount
++;
897 _lu_data_index(unsigned int key
, struct _lu_data_s
*libinfo_data
)
901 if (libinfo_data
== NULL
) return (unsigned int)-1;
903 for (i
= 0; i
< libinfo_data
->icount
; i
++)
905 if (libinfo_data
->ikey
[i
] == key
) return i
;
908 return (unsigned int)-1;
912 _lu_data_set_key(unsigned int key
, void *data
)
914 struct _lu_data_s
*libinfo_data
;
917 libinfo_data
= _lu_data_get();
918 if (libinfo_data
== NULL
) return;
920 i
= _lu_data_index(key
, libinfo_data
);
921 if (i
== (unsigned int)-1) return;
923 libinfo_data
->idata
[i
] = data
;
927 _lu_data_get_key(unsigned int key
)
929 struct _lu_data_s
*libinfo_data
;
932 libinfo_data
= _lu_data_get();
933 if (libinfo_data
== NULL
) return NULL
;
935 i
= _lu_data_index(key
, libinfo_data
);
936 if (i
== (unsigned int)-1) return NULL
;
938 return libinfo_data
->idata
[i
];
942 _lu_data_free_vm_xdr(struct lu_thread_info
*tdata
)
944 if (tdata
== NULL
) return;
946 if (tdata
->lu_vm
!= NULL
)
948 vm_deallocate(mach_task_self(), (vm_address_t
)tdata
->lu_vm
, tdata
->lu_vm_length
);
951 tdata
->lu_vm_length
= 0;
952 tdata
->lu_vm_cursor
= 0;
954 if (tdata
->lu_xdr
!= NULL
)
956 xdr_destroy(tdata
->lu_xdr
);
958 tdata
->lu_xdr
= NULL
;
963 _lu_xdr_attribute(XDR
*xdr
, char **key
, char ***val
, unsigned int *count
)
965 unsigned int i
, j
, len
;
968 if (xdr
== NULL
) return -1;
969 if (key
== NULL
) return -1;
970 if (val
== NULL
) return -1;
971 if (count
== NULL
) return -1;
977 if (!xdr_string(xdr
, key
, -1)) return -1;
979 if (!xdr_int(xdr
, &len
))
986 if (len
== 0) return 0;
989 x
= (char **)calloc(len
+ 1, sizeof(char *));
990 if (x
== NULL
) return -1;
994 for (i
= 0; i
< len
; i
++)
997 if (!xdr_string(xdr
, &s
, -1))
999 for (j
= 0; j
< i
; j
++) free(x
[j
]);
1016 _lookup_link(mach_port_t server
, lookup_name name
, int *procno
)
1018 kern_return_t status
;
1019 security_token_t token
;
1025 status
= MIG_SERVER_DIED
;
1026 for (n
= 0; (status
== MIG_SERVER_DIED
) && (n
< MAX_LOOKUP_ATTEMPTS
); n
++)
1028 status
= _lookup_link_secure(server
, name
, procno
, &token
);
1031 if (status
!= KERN_SUCCESS
)
1034 syslog(LOG_DEBUG
, "pid %u _lookup_link %s status %u", getpid(), name
, status
);
1039 if (token
.val
[0] != 0)
1042 syslog(LOG_DEBUG
, "pid %u _lookup_link %s auth failure uid=%d", getpid(), name
, token
.val
[0]);
1044 return KERN_FAILURE
;
1048 syslog(LOG_DEBUG
, "pid %u _lookup_link %s = %d", getpid(), name
, *procno
);
1054 _lookup_one(mach_port_t server
, int proc
, inline_data indata
, mach_msg_type_number_t indataCnt
, inline_data outdata
, mach_msg_type_number_t
*outdataCnt
)
1056 kern_return_t status
;
1057 security_token_t token
;
1063 status
= MIG_SERVER_DIED
;
1064 for (n
= 0; (status
== MIG_SERVER_DIED
) && (n
< MAX_LOOKUP_ATTEMPTS
); n
++)
1066 status
= _lookup_one_secure(server
, proc
, indata
, indataCnt
, outdata
, outdataCnt
, &token
);
1069 if (status
!= KERN_SUCCESS
)
1072 syslog(LOG_DEBUG
, "pid %u _lookup_one %d status %u", getpid(), proc
, status
);
1077 if (token
.val
[0] != 0)
1080 syslog(LOG_DEBUG
, "pid %u _lookup_one %d auth failure uid=%d", getpid(), proc
, token
.val
[0]);
1082 return KERN_FAILURE
;
1086 syslog(LOG_DEBUG
, "pid %u _lookup_one %d", getpid(), proc
);
1092 _lookup_all(mach_port_t server
, int proc
, inline_data indata
, mach_msg_type_number_t indataCnt
, ooline_data
*outdata
, mach_msg_type_number_t
*outdataCnt
)
1094 kern_return_t status
;
1095 security_token_t token
;
1101 status
= MIG_SERVER_DIED
;
1102 for (n
= 0; (status
== MIG_SERVER_DIED
) && (n
< MAX_LOOKUP_ATTEMPTS
); n
++)
1104 status
= _lookup_all_secure(server
, proc
, indata
, indataCnt
, outdata
, outdataCnt
, &token
);
1107 if (status
!= KERN_SUCCESS
)
1110 syslog(LOG_DEBUG
, "pid %u _lookup_all %d status %u", getpid(), proc
, status
);
1115 if (token
.val
[0] != 0)
1118 syslog(LOG_DEBUG
, "pid %u _lookup_all %d auth failure uid=%d", getpid(), proc
, token
.val
[0]);
1120 return KERN_FAILURE
;
1124 syslog(LOG_DEBUG
, "pid %u _lookup_all %d", getpid(), proc
);
1130 _lookup_ooall(mach_port_t server
, int proc
, ooline_data indata
, mach_msg_type_number_t indataCnt
, ooline_data
*outdata
, mach_msg_type_number_t
*outdataCnt
)
1132 kern_return_t status
;
1133 security_token_t token
;
1139 status
= MIG_SERVER_DIED
;
1140 for (n
= 0; (status
== MIG_SERVER_DIED
) && (n
< MAX_LOOKUP_ATTEMPTS
); n
++)
1142 status
= _lookup_ooall_secure(server
, proc
, indata
, indataCnt
, outdata
, outdataCnt
, &token
);
1145 if (status
!= KERN_SUCCESS
)
1148 syslog(LOG_DEBUG
, "pid %u _lookup_ooall %d status %u", getpid(), proc
, status
);
1153 if (token
.val
[0] != 0)
1156 syslog(LOG_DEBUG
, "pid %u _lookup_ooall %d auth failure uid=%d", getpid(), proc
, token
.val
[0]);
1158 return KERN_FAILURE
;
1162 syslog(LOG_DEBUG
, "pid %u _lookup_ooall %d", getpid(), proc
);