]> git.saurik.com Git - apple/libinfo.git/blobdiff - lookup.subproj/lu_utils.c
Libinfo-324.tar.gz
[apple/libinfo.git] / lookup.subproj / lu_utils.c
diff --git a/lookup.subproj/lu_utils.c b/lookup.subproj/lu_utils.c
deleted file mode 100644 (file)
index 02e8d14..0000000
+++ /dev/null
@@ -1,2461 +0,0 @@
-/*
- * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <mach/mach.h>
-#include <servers/bootstrap.h>
-#include <pthread.h>
-#include <errno.h>
-#include <notify.h>
-#include <syslog.h>
-#include <unistd.h>
-#ifdef DEBUG
-#include <asl.h>
-#endif
-#include "lu_utils.h"
-#include "netdb_async.h"
-#include "DSlibinfoMIG.h"
-#include "DSlibinfoMIGAsyncReply.h"
-
-#define MAX_LOOKUP_ATTEMPTS 10
-#define _LU_MAXLUSTRLEN 256
-#define QBUF_SIZE 16384
-#define KVBUF_START_SIZE 128
-
-#define LI_MESSAGE_SEND_ID  4241776
-#define LI_MESSAGE_REPLY_ID 4241876
-
-#define ILS_MAGIC_SIZE 8
-#define ILS_MAGIC "ILSMAGIC"
-
-#define L1_CACHE_NOTIFICATION_KEY_GLOBAL  "com.apple.system.DirectoryService.InvalidateCache"
-#define L1_CACHE_NOTIFICATION_KEY_GROUP   "com.apple.system.DirectoryService.InvalidateCache.group"
-#define L1_CACHE_NOTIFICATION_KEY_HOST    "com.apple.system.DirectoryService.InvalidateCache.host"
-#define L1_CACHE_NOTIFICATION_KEY_SERVICE "com.apple.system.DirectoryService.InvalidateCache.service"
-#define L1_CACHE_NOTIFICATION_KEY_USER    "com.apple.system.DirectoryService.InvalidateCache.user"
-
-/* GLOBAL */
-uint32_t gL1CacheEnabled = 1;
-
-static const uint32_t align_32[] = { 0, 1, 2, 0, 4, 0, 0, 0, 4 };
-static const uint32_t align_64[] = { 0, 1, 2, 0, 4, 0, 0, 0, 8 };
-
-static pthread_key_t _info_key = 0;
-static pthread_once_t _info_key_initialized = PTHREAD_ONCE_INIT;
-
-static pthread_mutex_t _notify_lock = PTHREAD_MUTEX_INITIALIZER;
-static int _L1_notify_token[] =
-{
-       -1, /* global */
-       -1, /* group */
-       -1, /* host */
-       -1, /* service */
-       -1  /* user */
-};
-
-struct _li_data_s
-{
-       uint32_t icount;
-       uint32_t *ikey;
-       void **idata;
-};
-
-typedef struct _li_async_request_s
-{
-       mach_port_t reply_port;
-       uint32_t retry;
-       uint32_t proc;
-       void *context;
-       void *callback;
-       char request[MAX_MIG_INLINE_DATA];
-       mach_msg_type_number_t requestCnt;
-       char reply[MAX_MIG_INLINE_DATA];
-       mach_msg_type_number_t replyCnt;
-       vm_address_t ooreply;
-       mach_msg_type_number_t ooreplyCnt;
-       security_token_t token;
-       struct _li_async_request_s *next;
-} _li_async_request_t;
-
-static pthread_mutex_t _li_worklist_lock = PTHREAD_MUTEX_INITIALIZER;
-static _li_async_request_t *_li_worklist = NULL;
-
-/* Send an asynchronous query message. */
-static kern_return_t
-_LI_async_send(_li_async_request_t *r)
-{
-       mach_msg_return_t status;
-       mach_vm_address_t cb;
-
-       if (r == NULL) return KERN_FAILURE;
-
-       if (r->retry == 0) return MIG_SERVER_DIED;
-       r->retry--;
-
-       cb = (mach_vm_address_t)(r->callback);
-       status = libinfoDSmig_Query_async(_ds_port, r->reply_port, r->proc, r->request, r->requestCnt, cb);
-
-       if (status == MACH_SEND_INVALID_REPLY)
-       {
-               mach_port_mod_refs(mach_task_self(), r->reply_port, MACH_PORT_RIGHT_RECEIVE, -1);
-               r->reply_port = MACH_PORT_NULL;
-       }
-
-       return status;
-}
-
-static _li_async_request_t *
-_LI_worklist_remove(mach_port_t p)
-{
-       _li_async_request_t *r, *n;
-
-       if (p == MACH_PORT_NULL) return NULL;
-       if (_li_worklist == NULL) return NULL;
-
-       pthread_mutex_lock(&_li_worklist_lock);
-
-       if (_li_worklist->reply_port == p)
-       {
-               r = _li_worklist;
-               _li_worklist = r->next;
-               pthread_mutex_unlock(&_li_worklist_lock);
-               return r;
-       }
-
-       for (r = _li_worklist; r != NULL; r = r->next)
-       {
-               n = r->next;
-               if (n == NULL) break;
-
-               if (n->reply_port == p)
-               {
-                       r->next = n->next;
-                       pthread_mutex_unlock(&_li_worklist_lock);
-                       return n;
-               }
-       }
-
-       pthread_mutex_unlock(&_li_worklist_lock);
-       return NULL;
-}
-
-static _li_async_request_t *
-_LI_worklist_find(mach_port_t p)
-{
-       _li_async_request_t *r;
-
-       if (p == MACH_PORT_NULL) return NULL;
-       if (_li_worklist == NULL) return NULL;
-
-       pthread_mutex_lock(&_li_worklist_lock);
-
-       for (r = _li_worklist; r != NULL; r = r->next)
-       {
-               if (r->reply_port == p)
-               {
-                       pthread_mutex_unlock(&_li_worklist_lock);
-                       return r;
-               }
-       }
-
-       pthread_mutex_unlock(&_li_worklist_lock);
-       return NULL;
-}
-
-static void
-_LI_free_request(_li_async_request_t *r)
-{
-       if (r == NULL) return;
-
-       if (r->reply_port != MACH_PORT_NULL) mach_port_mod_refs(mach_task_self(), r->reply_port, MACH_PORT_RIGHT_RECEIVE, -1);
-       r->reply_port = MACH_PORT_NULL;
-
-       free(r);
-}
-
-/*
- * This is a callback for DSLibinfoMIGAsyncReplyServer.c
- */
-__private_extern__ kern_return_t
-libinfoDSmig_do_Response_async(mach_port_t server, char *reply, mach_msg_type_number_t replyCnt, vm_offset_t ooreply, mach_msg_type_number_t ooreplyCnt, mach_vm_address_t callbackAddr, security_token_t servertoken)
-{
-       _li_async_request_t *r;
-
-       r = _LI_worklist_find(server);
-
-       if (r != NULL)
-       {
-               r->ooreply = ooreply;
-               r->ooreplyCnt = ooreplyCnt;
-               if (replyCnt > 0) memcpy(r->reply, reply, replyCnt);
-               r->replyCnt = replyCnt;
-               r->token = servertoken;
-       }
-       else if (ooreplyCnt != 0)
-       {
-               vm_deallocate(mach_task_self(), ooreply, ooreplyCnt);
-       }
-
-       return KERN_SUCCESS;
-}
-
-/* Receive an asynchronous reply message. */
-kern_return_t
-LI_async_receive(mach_port_t p, kvarray_t **reply)
-{
-       kern_return_t status;
-       _li_async_request_t *r;
-       kvbuf_t *out;
-       int flags;
-
-       flags = MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) | MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0);
-
-       /* use mach_msg_server_once to do the work here */
-       status = mach_msg_server_once(DSlibinfoMIGAsyncReply_server, 65536, p, flags);
-
-       if (status != KERN_SUCCESS) return status;
-
-       r = _LI_worklist_remove(p);
-       if (r == NULL) return KERN_FAILURE;
-
-       out = (kvbuf_t *)calloc(1, sizeof(kvbuf_t));
-       if (out == NULL)
-       {
-               if (r->ooreplyCnt > 0) vm_deallocate(mach_task_self(), r->ooreply, r->ooreplyCnt);
-               return KERN_FAILURE;
-       }
-
-       if (r->ooreplyCnt > 0)
-       {
-               out->datalen = r->ooreplyCnt;
-               out->databuf = malloc(r->ooreplyCnt);
-               if (out->databuf == NULL)
-               {
-                       free(out);
-                       *reply = NULL;
-                       vm_deallocate(mach_task_self(), r->ooreply, r->ooreplyCnt);
-                       return KERN_FAILURE;
-               }
-
-               memcpy(out->databuf, (char *)r->ooreply, r->ooreplyCnt);
-               vm_deallocate(mach_task_self(), r->ooreply, r->ooreplyCnt);
-       }
-       else if (r->replyCnt > 0)
-       {
-               out->datalen = r->replyCnt;
-               out->databuf = malloc(r->replyCnt);
-               if (out->databuf == NULL)
-               {
-                       free(out);
-                       *reply = NULL;
-                       return KERN_FAILURE;
-               }
-
-               memcpy(out->databuf, r->reply, r->replyCnt);
-       }
-
-       *reply = kvbuf_decode(out);
-       if (*reply == NULL)
-       {
-               /* DS returned no data */
-               free(out->databuf);
-               free(out);
-       }
-       
-       _LI_free_request(r);
-
-       return KERN_SUCCESS;
-}
-
-static void
-_LI_worklist_append(_li_async_request_t *r)
-{
-       _li_async_request_t *p;
-
-       if (r == NULL) return;
-
-       pthread_mutex_lock(&_li_worklist_lock);
-
-       if (_li_worklist == NULL)
-       {
-               _li_worklist = r;
-               pthread_mutex_unlock(&_li_worklist_lock);
-               return;
-       }
-
-       for (p = _li_worklist; p->next != NULL; p = p->next);
-       p->next = r;
-
-       pthread_mutex_unlock(&_li_worklist_lock);
-}
-
-void
-LI_async_call_cancel(mach_port_t p, void **context)
-{
-       _li_async_request_t *req;
-
-       req = _LI_worklist_remove(p);
-
-       if (req != NULL)
-       {
-               if (context != NULL) *context = req->context;
-               _LI_free_request(req);
-       }
-       else if (p != MACH_PORT_NULL)
-       {
-               mach_port_mod_refs(mach_task_self(), p, MACH_PORT_RIGHT_RECEIVE, -1);
-       }
-}
-
-void
-lu_async_call_cancel(mach_port_t p)
-{
-       LI_async_call_cancel(p, NULL);
-}
-
-static _li_async_request_t *
-_LI_create_request(uint32_t proc, kvbuf_t *query, void *callback, void *context)
-{
-       _li_async_request_t *r;
-       kern_return_t status;
-       mach_port_t target;
-
-       if (_ds_running() == 0) return NULL;
-       if (query == NULL) return NULL;
-       if (query->datalen > MAX_MIG_INLINE_DATA) return NULL;
-
-       r = (_li_async_request_t *)calloc(1, sizeof(_li_async_request_t));
-       if (r == NULL) return NULL;
-
-       status = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &(r->reply_port));
-       if (status != KERN_SUCCESS)
-       {
-               _LI_free_request(r);
-               return NULL;
-       }
-
-       target = MACH_PORT_NULL;
-
-       /* Request no-senders notification so we can tell when server dies */
-       mach_port_request_notification(mach_task_self(), r->reply_port, MACH_NOTIFY_NO_SENDERS, 1, r->reply_port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &target);
-
-       r->retry = MAX_LOOKUP_ATTEMPTS;
-
-       r->context = context;
-       r->callback = callback;
-       r->proc = proc;
-
-       memcpy(r->request, query->databuf, query->datalen);
-       r->requestCnt = query->datalen;
-
-       r->next = NULL;
-
-       return r;
-}
-
-kern_return_t
-LI_async_start(mach_port_t *p, uint32_t proc, kvbuf_t *query, void *callback, void *context)
-{
-       _li_async_request_t *r;
-       kern_return_t status;
-       uint32_t retry;
-
-       if (p == NULL) return KERN_FAILURE;
-
-       *p = MACH_PORT_NULL;
-
-       if (_ds_running() == 0) return KERN_FAILURE;
-       if (_ds_port == MACH_PORT_NULL) return KERN_FAILURE;
-
-       /* Make a request struct to keep track */
-       r = _LI_create_request(proc, query, callback, context);
-       if (r == NULL) return KERN_FAILURE;
-
-       status = MIG_SERVER_DIED;
-       for (retry = 0; (status == MIG_SERVER_DIED) && (retry < MAX_LOOKUP_ATTEMPTS); retry++)
-       {
-               status = _LI_async_send(r);
-       }
-
-       if (status != KERN_SUCCESS)
-       {
-               _LI_free_request(r);
-               return status;
-       }
-
-       /* Add request to worklist */
-       _LI_worklist_append(r);
-
-       *p = r->reply_port;
-
-       return KERN_SUCCESS;
-}
-
-kern_return_t
-LI_async_send(mach_port_t *p, uint32_t proc, kvbuf_t *query)
-{
-       return LI_async_start(p, proc, query, NULL, NULL);
-}
-
-kern_return_t
-LI_async_handle_reply(mach_msg_header_t *msg, kvarray_t **reply, void **callback, void **context)
-{
-       _li_async_request_t *req;
-       kvbuf_t *out;
-       kern_return_t status;
-       uint32_t retry;
-       mig_reply_error_t *bufReply;
-
-       if (msg == NULL) return -1;
-
-       /* If reply status was an error, resend */
-       if (msg->msgh_id == MACH_NOTIFY_NO_SENDERS)
-       {
-               /* if server died */
-               req = _LI_worklist_find(msg->msgh_local_port);
-               if (req == NULL) return -1;
-
-               status = MIG_SERVER_DIED;
-               for (retry = 0; (status == MIG_SERVER_DIED) && (retry < MAX_LOOKUP_ATTEMPTS); retry++)
-               {
-                       /* send message */
-                       status = _LI_async_send(req);
-               }
-
-               if (status != KERN_SUCCESS) return -1;
-
-               return MIG_REPLY_MISMATCH;
-       }
-
-       /* need to implement the msg_server_once type code here */
-       mach_msg_size_t reply_alloc = round_page(65536 + MAX_TRAILER_SIZE);
-
-       status = vm_allocate(mach_task_self(), (vm_address_t *) &bufReply, reply_alloc, VM_MAKE_TAG(VM_MEMORY_MACH_MSG) | TRUE);
-       if (status != KERN_SUCCESS) return status;
-
-       status = DSlibinfoMIGAsyncReply_server(msg, (mach_msg_header_t *)bufReply);
-
-       /* we just destroy the reply, because there isn't one */
-       if (bufReply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) mach_msg_destroy(&bufReply->Head);
-
-       vm_deallocate(mach_task_self(), (vm_address_t) bufReply, reply_alloc);
-
-       if (status == FALSE) return KERN_FAILURE;
-
-       req = _LI_worklist_remove(msg->msgh_local_port);
-       if (req == NULL) return KERN_FAILURE;
-
-       *callback = req->callback;
-       *context = req->context;
-       out = (kvbuf_t *)calloc(1, sizeof(kvbuf_t));
-       if (out == NULL)
-       {
-               if (req->ooreplyCnt > 0) vm_deallocate(mach_task_self(), req->ooreply, req->ooreplyCnt);
-               return KERN_FAILURE;
-       }
-
-       if (req->ooreplyCnt > 0)
-       {
-               out->datalen = req->ooreplyCnt;
-               out->databuf = malloc(req->ooreplyCnt);
-               if (out->databuf == NULL)
-               {
-                       free(out);
-                       *reply = NULL;
-                       vm_deallocate(mach_task_self(), req->ooreply, req->ooreplyCnt);
-                       return KERN_FAILURE;
-               }
-
-               memcpy(out->databuf, (char *)req->ooreply, req->ooreplyCnt);
-               vm_deallocate(mach_task_self(), req->ooreply, req->ooreplyCnt);
-       }
-       else if (req->replyCnt > 0)
-       {
-               out->datalen = req->replyCnt;
-               out->databuf = malloc(req->replyCnt);
-               if (out->databuf == NULL)
-               {
-                       free(out);
-                       *reply = NULL;
-                       return KERN_FAILURE;
-               }
-
-               memcpy(out->databuf, req->reply, req->replyCnt);
-       }
-
-       *reply = kvbuf_decode(out);
-       if (*reply == NULL)
-       {
-               /* DS returned no data */
-               free(out->databuf);
-               free(out);
-       }
-       
-       _LI_free_request(req);
-
-       return KERN_SUCCESS;
-}
-
-static void
-_LI_thread_info_free(void *x)
-{
-       struct li_thread_info *tdata;
-
-       if (x == NULL) return;
-
-       tdata = (struct li_thread_info *)x;
-       LI_ils_free(tdata->li_entry, tdata->li_entry_size);
-       LI_data_free_kvarray(tdata);
-
-       free(tdata);
-}
-
-static void
-_LI_data_free(void *x)
-{
-       struct _li_data_s *t;
-       int i;
-
-       if (x == NULL) return;
-
-       t = (struct _li_data_s *)x;
-
-       for (i = 0; i < t->icount; i++)
-       {
-               _LI_thread_info_free(t->idata[i]);
-               t->idata[i] = NULL;
-       }
-
-       if (t->ikey != NULL) free(t->ikey);
-       t->ikey = NULL;
-
-       if (t->idata != NULL) free(t->idata);
-       t->idata = NULL;
-
-       free(t);
-}
-
-static void
-_LI_data_init()
-{
-       pthread_key_create(&_info_key, _LI_data_free);
-       return;
-}
-
-static struct _li_data_s *
-_LI_data_get()
-{
-       struct _li_data_s *libinfo_data;
-
-       /*
-        * Only one thread should create the _info_key
-        */
-       pthread_once(&_info_key_initialized, _LI_data_init);
-
-       /* Check if this thread already created libinfo_data */
-       libinfo_data = pthread_getspecific(_info_key);
-       if (libinfo_data != NULL) return libinfo_data;
-
-       libinfo_data = (struct _li_data_s *)calloc(1, sizeof(struct _li_data_s));
-       if (libinfo_data == NULL) return NULL;
-
-       pthread_setspecific(_info_key, libinfo_data);
-       return libinfo_data;
-}
-
-__private_extern__ void *
-LI_data_find_key(uint32_t key)
-{
-       struct _li_data_s *libinfo_data;
-       uint32_t i;
-
-       libinfo_data = _LI_data_get();
-       if (libinfo_data == NULL) return NULL;
-
-       for (i = 0; i < libinfo_data->icount; i++)
-       {
-               if (libinfo_data->ikey[i] == key) return libinfo_data->idata[i];
-       }
-
-       return NULL;
-}
-
-__private_extern__ void *
-LI_data_create_key(uint32_t key, size_t esize)
-{
-       struct _li_data_s *libinfo_data;
-       struct li_thread_info *tdata;
-       uint32_t i, n;
-
-       libinfo_data = _LI_data_get();
-       if (libinfo_data == NULL) return NULL;
-
-       for (i = 0; i < libinfo_data->icount; i++)
-       {
-               if (libinfo_data->ikey[i] == key) return libinfo_data->idata[i];
-       }
-
-       i = libinfo_data->icount;
-       n = i + 1;
-
-       if (i == 0)
-       {
-               libinfo_data->ikey = (uint32_t *)malloc(sizeof(uint32_t));
-               libinfo_data->idata = (void **)malloc(sizeof(void *));
-       }
-       else
-       {
-               libinfo_data->ikey = (uint32_t *)reallocf(libinfo_data->ikey, n * sizeof(uint32_t));
-               libinfo_data->idata = (void **)reallocf(libinfo_data->idata, n * sizeof(void *));
-       }
-
-       if ((libinfo_data->ikey == NULL) || (libinfo_data->idata == NULL))
-       {
-               if (libinfo_data->ikey != NULL) free(libinfo_data->ikey);
-               libinfo_data->ikey = NULL;
-
-               if (libinfo_data->idata != NULL) free(libinfo_data->idata);
-               libinfo_data->idata = NULL;
-
-               return NULL;
-       }
-
-       tdata = (struct li_thread_info *)calloc(1, sizeof(struct li_thread_info));
-       if (tdata == NULL) return NULL;
-
-       tdata->li_entry_size = esize;
-
-       libinfo_data->ikey[i] = key;
-       libinfo_data->idata[i] = tdata;
-       libinfo_data->icount++;
-
-       return tdata;
-}
-
-static uint32_t
-_LI_data_index(uint32_t key, struct _li_data_s *libinfo_data)
-{
-       uint32_t i;
-
-       if (libinfo_data == NULL) return (uint32_t)-1;
-
-       for (i = 0; i < libinfo_data->icount; i++)
-       {
-               if (libinfo_data->ikey[i] == key) return i;
-       }
-
-       return (uint32_t)-1;
-}
-
-void
-_LI_data_set_key(uint32_t key, void *data)
-{
-       struct _li_data_s *libinfo_data;
-       uint32_t i;
-
-       libinfo_data = _LI_data_get();
-       if (libinfo_data == NULL) return;
-
-       i = _LI_data_index(key, libinfo_data);
-       if (i == (uint32_t)-1) return;
-
-       libinfo_data->idata[i] = data;
-}
-
-void *
-_LI_data_get_key(uint32_t key)
-{
-       struct _li_data_s *libinfo_data;
-       uint32_t i;
-
-       libinfo_data = _LI_data_get();
-       if (libinfo_data == NULL) return NULL;
-
-       i = _LI_data_index(key, libinfo_data);
-       if (i == (uint32_t)-1) return NULL;
-
-       return libinfo_data->idata[i];
-}
-
-__private_extern__ void
-LI_data_free_kvarray(struct li_thread_info *tdata)
-{
-       if (tdata == NULL) return;
-       if (tdata->li_vm == NULL) return;
-
-       kvarray_free((kvarray_t *)tdata->li_vm);
-       tdata->li_vm = NULL;
-}
-
-__private_extern__ void
-LI_data_recycle(struct li_thread_info *tdata, void *entry, size_t entrysize)
-{
-       if (tdata == NULL) return;
-
-       LI_ils_free(tdata->li_entry, entrysize);
-       tdata->li_entry = entry;
-}
-
-#define KVBUF_CHUNK 256
-
-/*
- * kvbuf_t is a list of key/value dictionaries.
- *
- * First 4 bytes are the number of dictionaries.
- * For each dictionary, first 4 bytes is the key / value list count.
- * For each value list, first 4 bytes is the list length.
- * Keys and values are a 4-byte length followed by a nul-terminated string
- *
- * When the databuf needs to grow, we add memory in KVBUF_CHUNK size
- * increments to reduce malloc / realloc activity.
- * The _size variable stores the actual allocated size.
- * The datalen variable stores the used data size.
- *
- * The _dict variable holds an offset from the start of the buffer
- * to the "current" dictionary.  kvbuf_reset() resets this,
- * and kvbuf_next_dict() bumps the offset so that databuf + _dict
- * points to the next dictionary.
- *
- * The _key variable holds an offset from the start of the buffer
- * to the "current" key.  kvbuf_reset() resets this, and
- * kvbuf_next_key() bumps the offset so that databuf + _key
- * points to the next key.
- *
- * The _val variable holds an offset from the start of the buffer
- * to the "current" value.  kvbuf_reset() resets this, and
- * kvbuf_next_val() bumps the offset so that databuf + _val
- * points to the next value.
- *
- * The cache_entry_list_to_kvbuf() routine contains the only
- * code that builds an array.
- * 
- */
-
-/*
- * kvbuf_query is a simple utility for constructing a
- * kvbuf with a single dictionary.  The format string may
- * contain the chars "k", "s", "i", and "u".  "k" denotes a key
- * (keys are always strings), "s" denotes a string value,
- * "i" denotes a 32 bit signed int, and "u" denotes an unsigned.
- */
-__private_extern__ kvbuf_t *
-kvbuf_query(char *fmt, ...)
-{
-       va_list ap;
-       char *arg, *f, str[32];
-       int32_t iarg;
-       uint32_t uarg;
-       kvbuf_t *kv;
-
-       if (fmt == NULL) return NULL;
-
-       kv = kvbuf_new();
-       if (kv == NULL) return NULL;
-
-       kvbuf_add_dict(kv);
-
-       va_start(ap, fmt);
-       for (f = fmt; (*f) != '\0'; f++)
-       {
-               if (*f == 'k')
-               {
-                       arg = va_arg(ap, char *);
-                       kvbuf_add_key(kv, arg);
-               }
-               else if (*f == 's')
-               {
-                       arg = va_arg(ap, char *);
-                       kvbuf_add_val(kv, arg);
-               }
-               else if (*f == 'i')
-               {
-                       iarg = va_arg(ap, int32_t);
-                       snprintf(str, sizeof(str), "%d", iarg);
-                       kvbuf_add_val(kv, str);
-               }
-               else if (*f == 'u')
-               {
-                       uarg = va_arg(ap,uint32_t);
-                       snprintf(str, sizeof(str), "%u", uarg);
-                       kvbuf_add_val(kv, str);
-               }
-       }
-       va_end(ap);
-
-       return kv;
-}
-
-__private_extern__ kvbuf_t *
-kvbuf_query_key_val(const char *key, const char *val)
-{
-       kvbuf_t *kv;
-       uint32_t x, kl, vl, vc;
-       char *p;
-
-       if (key == NULL) return NULL;
-
-       kl = strlen(key) + 1;
-
-       vl = 0;
-       vc = 0;
-
-       if (val != NULL) 
-       {
-               vl = strlen(val) + 1;
-               vc = 1;
-       }
-
-       kv = (kvbuf_t *)calloc(1, sizeof(kvbuf_t));
-       if (kv == NULL) return NULL;
-
-       kv->_size = (5 * sizeof(uint32_t)) + kl + vl;
-       kv->datalen = kv->_size;
-
-       kv->databuf = calloc(1, kv->_size);
-       if (kv->databuf == NULL)
-       {
-               free(kv);
-               return NULL;
-       }
-
-       p = kv->databuf;
-
-       /* 1 dict */
-       x = htonl(1);
-       memcpy(p, &x, sizeof(uint32_t));
-       p += sizeof(uint32_t);
-
-       /* 1 key */
-       memcpy(p, &x, sizeof(uint32_t));
-       p += sizeof(uint32_t);
-
-       /* key length */
-       x = htonl(kl);
-       memcpy(p, &x, sizeof(uint32_t));
-       p += sizeof(uint32_t);
-
-       /* key */
-       memcpy(p, key, kl);
-       p += kl;
-
-       /* number of values */
-       x = htonl(vc);
-       memcpy(p, &x, sizeof(uint32_t));
-       p += sizeof(uint32_t);
-
-       if (vc > 0)
-       {
-               /* value length */
-               x = htonl(vl);
-               memcpy(p, &x, sizeof(uint32_t));
-               p += sizeof(uint32_t);
-
-               /* value */
-               memcpy(p, val, vl);
-       }
-
-       return kv;
-}
-
-__private_extern__ kvbuf_t *
-kvbuf_query_key_int(const char *key, int32_t i)
-{
-       char str[32];
-
-       snprintf(str, sizeof(str), "%d", i);
-       return kvbuf_query_key_val(key, str);
-}
-
-__private_extern__ kvbuf_t *
-kvbuf_query_key_uint(const char *key, uint32_t u)
-{
-       char str[32];
-
-       snprintf(str, sizeof(str), "%u", u);
-       return kvbuf_query_key_val(key, str);
-}
-
-kvbuf_t *
-kvbuf_new(void)
-{
-       kvbuf_t *kv;
-
-       kv = (kvbuf_t *)calloc(1, sizeof(kvbuf_t));
-       if (kv == NULL) return NULL;
-
-       kv->_size = KVBUF_START_SIZE;
-       kv->databuf = calloc(1, kv->_size);
-       if (kv->databuf == NULL)
-       {
-               free(kv);
-               return NULL;
-       }
-
-       kv->datalen = sizeof(uint32_t);
-       kv->_dict = kv->datalen;
-
-       return kv;
-}
-
-kvbuf_t *
-kvbuf_init(char *buffer, uint32_t length)
-{
-       kvbuf_t *kv;
-
-       kv = (kvbuf_t *)calloc(1, sizeof(kvbuf_t));
-       if (kv == NULL) return NULL;
-
-       kv->_size = length;
-       kv->datalen = length;
-       kv->databuf = calloc(1, length);
-       if (kv->databuf == NULL)
-       {
-               free(kv);
-               kv = NULL;
-       }
-       else
-       {
-               memcpy(kv->databuf, buffer, length);
-       }
-
-       return kv;
-}
-
-static void
-kvbuf_grow(kvbuf_t *kv, uint32_t delta)
-{
-       uint32_t newlen, n;
-       char *p;
-
-       if (kv == NULL) return;
-       if (delta == 0) return;
-
-       if (kv->databuf == NULL) delta += sizeof(uint32_t);
-
-       n = (delta + KVBUF_CHUNK - 1) / KVBUF_CHUNK;
-       newlen = kv->datalen + (n * KVBUF_CHUNK);
-
-       if (newlen <= kv->_size) return;
-
-       kv->_size = newlen;
-
-       if (kv->databuf == NULL)
-       {
-               kv->databuf = calloc(1, kv->_size);
-               if (kv->databuf == NULL)
-               {
-                       memset(kv, 0, sizeof(kvbuf_t));
-                       return;
-               }
-
-               kv->datalen = sizeof(uint32_t);
-               kv->_dict = sizeof(uint32_t);
-       }
-       else
-       {
-               kv->databuf = reallocf(kv->databuf, kv->_size);
-               if (kv->databuf == NULL)
-               {
-                       memset(kv, 0, sizeof(kvbuf_t));
-                       return;
-               }
-
-               p = kv->databuf + kv->datalen;
-               memset(p, 0, kv->_size - kv->datalen);
-       }
-}
-
-void
-kvbuf_add_dict(kvbuf_t *kv)
-{
-       char *p;
-       uint32_t x, dict_count;
-
-       if (kv == NULL) return;
-
-       /* Add a key count */
-       kvbuf_grow(kv, sizeof(uint32_t));
-       if (kv->databuf == NULL) return;
-
-       kv->_dict = kv->datalen;
-       kv->datalen += sizeof(uint32_t);
-
-       kv->_key = kv->datalen;
-       kv->_vlist = 0;
-       kv->_val = 0;
-
-       /* increment and rewrite the dict count */
-       p = kv->databuf;
-
-       x = 0;
-       memcpy(&x, p, sizeof(uint32_t));
-       dict_count = ntohl(x);
-
-       dict_count++;
-       x = htonl(dict_count);
-       memcpy(p, &x, sizeof(uint32_t));
-}
-
-void
-kvbuf_add_key(kvbuf_t *kv, const char *key)
-{
-       uint32_t kl, x, key_count, delta;
-       char *p;
-
-       if (kv == NULL) return;
-       if (key == NULL) return;
-
-       kl = strlen(key) + 1;
-
-       /* Grow to hold key len, key, and value list count. */
-       delta = (2 * sizeof(uint32_t)) + kl;
-       kvbuf_grow(kv, delta);
-
-       if (kv->databuf == NULL) return;
-
-       /* increment and rewrite the key count for the current dictionary */
-       p = kv->databuf + kv->_dict;
-
-       x = 0;
-       memcpy(&x, p, sizeof(uint32_t));
-       key_count = ntohl(x);
-
-       if (key_count == 0) kv->_key = kv->_dict + sizeof(uint32_t);
-       else kv->_key = kv->datalen;
-
-       key_count++;
-       x = htonl(key_count);
-       memcpy(p, &x, sizeof(uint32_t));
-
-       /* append key to data buffer */
-       p = kv->databuf + kv->datalen;
-
-       x = htonl(kl);
-       memcpy(p, &x, sizeof(uint32_t));
-       p += sizeof(uint32_t);
-       memcpy(p, key, kl);
-       p += kl;
-
-       kv->_vlist = kv->datalen + sizeof(uint32_t) + kl;
-
-       x = 0;
-       memcpy(p, &x, sizeof(uint32_t));
-
-       kv->datalen += delta;
-       kv->_val = kv->datalen;
-}
-
-void
-kvbuf_add_val_len(kvbuf_t *kv, const char *val, uint32_t len)
-{
-       uint32_t x, val_count, delta;
-       char *p;
-
-       if (kv == NULL) return;
-       if (val == NULL) return;
-       if (len == 0) return;
-
-       /* Grow to hold val len and value. */
-       delta = sizeof(uint32_t) + len;
-       kvbuf_grow(kv, delta);
-
-       if (kv->databuf == NULL) return;
-
-       /* increment and rewrite the value count for the value_list dictionary */
-       p = kv->databuf + kv->_vlist;
-
-       x = 0;
-       memcpy(&x, p, sizeof(uint32_t));
-       val_count = ntohl(x);
-       val_count++;
-       x = htonl(val_count);
-       memcpy(p, &x, sizeof(uint32_t));
-
-       /* append val to data buffer */
-       p = kv->databuf + kv->_val;
-
-       x = htonl(len);
-       memcpy(p, &x, sizeof(uint32_t));
-       p += sizeof(uint32_t);
-       memcpy(p, val, len);
-       p += len;
-
-       kv->datalen += delta;
-       kv->_val = kv->datalen;
-}
-
-/* 
- * WARNING!  Kludge Alert!
- *
- * This call just looks for the buffer length encoded into a serialized kvbuf_t,
- * which preceeds a pointer to a key or value.  Obviously, calling it with anything
- * other than a pointer value which is embedded in a kvbuf_t is asking for trouble.
- */
-uint32_t
-kvbuf_get_len(const char *p)
-{
-       uint32_t x;
-
-       x = 0;
-       memcpy(&x, p - sizeof(uint32_t), sizeof(uint32_t));
-       return ntohl(x);
-}
-
-void
-kvbuf_add_val(kvbuf_t *kv, const char *val)
-{
-       if (kv == NULL) return;
-       if (val == NULL) return;
-
-       kvbuf_add_val_len(kv, val, strlen(val) + 1);
-}
-
-void
-kvbuf_free(kvbuf_t *kv)
-{
-       if (kv == NULL) return;
-       if (kv->databuf != NULL) free(kv->databuf);
-       memset(kv, 0, sizeof(kvbuf_t));
-       free(kv);
-}
-
-/* appends a kvbuf to an existing kvbuf */
-void
-kvbuf_append_kvbuf(kvbuf_t *kv, const kvbuf_t *kv2)
-{
-       uint32_t curr_count, new_count, temp;
-
-       if (kv == NULL) return;
-       if (kv2 == NULL) return;
-
-       curr_count = 0;
-       new_count = 0;
-
-       memcpy(&temp, kv->databuf, sizeof(uint32_t));
-       curr_count = ntohl(temp);
-
-       memcpy(&temp, kv2->databuf, sizeof(uint32_t));
-       new_count = ntohl(temp);
-
-       /* nothing to do */
-       if (new_count == 0) return;
-
-       /* add the dictionary count to the current dictionary counts */
-       curr_count += new_count; 
-
-       temp = htonl(curr_count);
-       memcpy(kv->databuf, &temp, sizeof(uint32_t));
-
-       /* grow the current buffer so we can append the new buffer */
-       temp = kv2->datalen - sizeof(uint32_t);
-
-       kvbuf_grow(kv, temp);
-
-       memcpy(kv->databuf + kv->datalen, kv2->databuf + sizeof(uint32_t), temp);
-       kv->datalen += temp;
-}
-
-/* returns number of dictionaries */
-uint32_t
-kvbuf_reset(kvbuf_t *kv)
-{
-       uint32_t x;
-
-       if (kv == NULL) return 0;
-       if (kv->databuf == NULL) return 0;
-
-       kv->_dict = 0;
-       kv->_key = 0;
-       kv->_vlist = 0;
-       kv->_val = 0;
-
-       if (kv->datalen < sizeof(uint32_t)) return 0;
-
-       x = 0;
-       memcpy(&x, kv->databuf, sizeof(uint32_t));
-       return ntohl(x);
-}
-
-/* advance to next dictionary, returns key count */
-uint32_t
-kvbuf_next_dict(kvbuf_t *kv)
-{
-       uint32_t x, k, v, kcount, vcount, kl, vl;
-       char *p;
-
-       if (kv == NULL) return 0;
-       if (kv->databuf == NULL) return 0;
-
-       kv->_key = 0;
-       kv->_vlist = 0;
-       kv->_val = 0;
-
-       if (kv->_dict == 0)
-       {
-               /* first dict */
-               if (kv->datalen < sizeof(uint32_t)) return 0;
-               kv->_dict = sizeof(uint32_t);
-
-               if (kv->datalen < (kv->_dict + sizeof(uint32_t))) return 0;
-
-               p = kv->databuf + kv->_dict;
-               x = 0;
-               memcpy(&x, p, sizeof(uint32_t));
-               kcount = ntohl(x);
-
-               return kcount;
-       }
-
-       p = kv->databuf + kv->_dict;
-
-       x = 0;
-       memcpy(&x, p, sizeof(uint32_t));
-       p += sizeof(uint32_t);
-       kv->_dict += sizeof(uint32_t);
-       kcount = ntohl(x);
-
-       for (k = 0; k < kcount; k++)
-       {
-               x = 0;
-               memcpy(&x, p, sizeof(uint32_t));
-               p += sizeof(uint32_t);
-               kv->_dict += sizeof(uint32_t);
-               kl = ntohl(x);
-               p += kl;
-               kv->_dict += kl;
-
-               x = 0;
-               memcpy(&x, p, sizeof(uint32_t));
-               p += sizeof(uint32_t);
-               kv->_dict += sizeof(uint32_t);
-               vcount = ntohl(x);
-
-               for (v = 0; v < vcount; v++)
-               {
-                       x = 0;
-                       memcpy(&x, p, sizeof(uint32_t));
-                       p += sizeof(uint32_t);
-                       kv->_dict += sizeof(uint32_t);
-                       vl = ntohl(x);
-                       p += vl;
-                       kv->_dict += vl;
-               }
-       }
-
-       if (kv->datalen < (kv->_dict + sizeof(uint32_t))) return 0;
-
-       p = kv->databuf + kv->_dict;
-       x = 0;
-       memcpy(&x, p, sizeof(uint32_t));
-       kcount = ntohl(x);
-
-       return kcount;
-}
-
-/* advance to next key, returns key and sets val_count */
-char *
-kvbuf_next_key(kvbuf_t *kv, uint32_t *val_count)
-{
-       uint32_t x, kl, v, vl, vc;
-       char *p, *out;
-
-       if (kv == NULL) return NULL;
-       if (val_count == NULL) return NULL;
-
-       *val_count = 0;
-
-       if (kv->databuf == NULL) return NULL;
-       if (kv->_dict == 0) return NULL;
-
-       kv->_vlist = 0;
-       kv->_val = 0;
-
-       if (kv->_key == 0)
-       {
-               /* first key */
-               if (kv->datalen < (kv->_dict +  sizeof(uint32_t))) return NULL;
-               kv->_key = kv->_dict + sizeof(uint32_t);
-       }
-       else
-       {
-               p = kv->databuf + kv->_key;
-
-               x = 0;
-               memcpy(&x, p, sizeof(uint32_t));
-               kl = ntohl(x);
-
-               if (kv->datalen < (kv->_key + sizeof(uint32_t) + kl)) return NULL;
-
-               p += (sizeof(uint32_t) + kl);
-               kv->_key += (sizeof(uint32_t) + kl);
-
-               /* skip over values */
-               if (kv->datalen < (kv->_key + sizeof(uint32_t))) return NULL;
-
-               x = 0;
-               memcpy(&x, p, sizeof(uint32_t));
-               vc = ntohl(x);
-
-               p += sizeof(uint32_t);
-               kv->_key += sizeof(uint32_t);
-
-               for (v = 0; v < vc; v++)
-               {
-                       if (kv->datalen < (kv->_key + sizeof(uint32_t))) return NULL;
-
-                       x = 0;
-                       memcpy(&x, p, sizeof(uint32_t));
-                       vl = ntohl(x);
-
-                       if (kv->datalen < (kv->_key + kl)) return NULL;
-
-                       p += (sizeof(uint32_t) + vl);
-                       kv->_key += (sizeof(uint32_t) + vl);
-               }
-       }
-
-       if (kv->datalen < (kv->_key + sizeof(uint32_t))) return NULL;
-
-       p = kv->databuf + kv->_key;
-       x = 0;
-       memcpy(&x, p, sizeof(uint32_t));
-       kl = ntohl(x);
-
-       p += sizeof(uint32_t);
-       out = p;
-
-       kv->_vlist = kv->_key + sizeof(uint32_t) + kl;
-       if (kv->datalen < (kv->_vlist + sizeof(uint32_t)))
-       {
-               kv->_vlist = 0;
-               return NULL;
-       }
-
-       p = kv->databuf + kv->_vlist;
-       x = 0;
-       memcpy(&x, p, sizeof(uint32_t));
-       *val_count = ntohl(x);
-
-       return out;
-}
-
-char *
-kvbuf_next_val(kvbuf_t *kv)
-{
-       return kvbuf_next_val_len(kv, NULL);
-}
-
-char *
-kvbuf_next_val_len(kvbuf_t *kv, uint32_t *len)
-{
-       uint32_t x = 0;
-       uint32_t vltemp = 0;
-       char *p;
-
-       if (kv == NULL) return NULL;
-       if (kv->databuf == NULL) return NULL;
-       if (kv->_vlist == 0) return NULL;
-
-       if (kv->_val == 0)
-       {
-               /* first val */
-               if (kv->datalen < (kv->_vlist +  sizeof(uint32_t))) return NULL;
-               kv->_val = kv->_vlist + sizeof(uint32_t);
-
-               p = kv->databuf + kv->_val;
-
-               memcpy(&x, p, sizeof(uint32_t));
-               vltemp = ntohl(x);
-       }
-       else
-       {
-               p = kv->databuf + kv->_val;
-
-               memcpy(&x, p, sizeof(uint32_t));
-               vltemp = ntohl(x);
-
-               if (kv->datalen < (kv->_val + sizeof(uint32_t) + vltemp)) return NULL;
-
-               p += (sizeof(uint32_t) + vltemp);
-               kv->_val += (sizeof(uint32_t) + vltemp);
-       }
-
-       if (kv->datalen < (kv->_val + sizeof(uint32_t))) return NULL;
-
-       if (len != NULL) (*len) = vltemp;
-       p = kv->databuf + kv->_val + sizeof(uint32_t);
-       return p;
-}
-
-/*
- * Builds a kvarray_t / kvdict_t structure on top of a kvbuf_t. 
- * It allocates the appropriate number of kvdict_t structures
- * for the array, sets all the counters, and fills in pointers
- * for keys and valuse.  The pointers are NOT to newly allocated
- * strings: they just point into the kvbuf data buffer.
- *
- * To dispose of the kvarray_t and all of the associated
- * memory AND to free the original kvbuf, clients only
- * need to call kvarray_free().
- */
-kvarray_t *
-kvbuf_decode(kvbuf_t *kv)
-{
-       kvarray_t *a;
-       uint32_t x, d, k, v;
-       char *p;
-
-       if (kv == NULL) return NULL;
-       if (kv->databuf == NULL) return NULL;
-
-       if (kv->datalen < sizeof(uint32_t)) return NULL;
-
-       p = kv->databuf;
-       kv->_size = kv->datalen;
-
-       /* array count */
-       x = 0;
-       memcpy(&x, p, sizeof(uint32_t));
-       p += sizeof(uint32_t);
-       kv->_size -= sizeof(uint32_t);
-       x = ntohl(x);
-
-       if (x == 0) return NULL;
-
-       a = (kvarray_t *)calloc(1, sizeof(kvarray_t));
-       if (a == NULL) return NULL;
-
-       a->count = x;
-       a->dict = (kvdict_t *)calloc(a->count, sizeof(kvdict_t));
-       if (a->dict == NULL)
-       {
-               free(a);
-               return NULL;
-       }
-
-       for (d = 0; d < a->count; d++)
-       {
-               if (kv->_size < sizeof(uint32_t))
-               {
-                       kvarray_free(a);
-                       return NULL;
-               }
-
-               /* key count */
-               x = 0;
-               memcpy(&x, p, sizeof(uint32_t));
-               p += sizeof(uint32_t);
-               kv->_size -= sizeof(uint32_t);
-               a->dict[d].kcount = ntohl(x);
-
-               if (a->dict[d].kcount > 0)
-               {
-                       a->dict[d].key = (const char **)calloc(a->dict[d].kcount, sizeof(const char *));
-                       if (a->dict[d].key == NULL)
-                       {
-                               kvarray_free(a);
-                               return NULL;
-                       }
-
-                       a->dict[d].vcount = (uint32_t *)calloc(a->dict[d].kcount, sizeof(uint32_t));
-                       if (a->dict[d].vcount == NULL)
-                       {
-                               kvarray_free(a);
-                               return NULL;
-                       }
-
-                       a->dict[d].val = (const char ***)calloc(a->dict[d].kcount, sizeof(char **));
-                       if (a->dict[d].val == NULL)
-                       {
-                               kvarray_free(a);
-                               return NULL;
-                       }
-               }
-
-               for (k = 0; k < a->dict[d].kcount; k++)
-               {
-                       /* get key */
-                       if (kv->_size < sizeof(uint32_t))
-                       {
-                               kvarray_free(a);
-                               return NULL;
-                       }
-
-                       /* key length */
-                       x = 0;
-                       memcpy(&x, p, sizeof(uint32_t));
-                       p += sizeof(uint32_t);
-                       kv->_size -= sizeof(uint32_t);
-                       x = ntohl(x);
-
-                       if (kv->_size < x)
-                       {
-                               kvarray_free(a);
-                               return NULL;
-                       }
-
-                       /* key data */
-                       a->dict[d].key[k] = p;
-
-                       p += x;
-                       kv->_size -= x;
-
-                       if (kv->_size < sizeof(uint32_t))
-                       {
-                               kvarray_free(a);
-                               return NULL;
-                       }
-
-                       /* val count */
-                       x = 0;
-                       memcpy(&x, p, sizeof(uint32_t));
-                       p += sizeof(uint32_t);
-                       kv->_size -= sizeof(uint32_t);
-                       a->dict[d].vcount[k] = ntohl(x);
-
-                       if (a->dict[d].vcount[k] > 0)
-                       {
-                               /* N.B. we add a NULL pointer at the end of the list */
-                               a->dict[d].val[k] = (const char **)calloc(a->dict[d].vcount[k] + 1, sizeof(const char *));
-                               if (a->dict[d].val[k] == NULL)
-                               {
-                                       kvarray_free(a);
-                                       return NULL;
-                               }
-                       }
-
-                       for (v = 0; v < a->dict[d].vcount[k]; v++)
-                       {
-                               /* get val */
-                               if (kv->_size < sizeof(uint32_t))
-                               {
-                                       kvarray_free(a);
-                                       return NULL;
-                               }
-
-                               /* val length */
-                               x = 0;
-                               memcpy(&x, p, sizeof(uint32_t));
-                               p += sizeof(uint32_t);
-                               kv->_size -= sizeof(uint32_t);
-                               x = ntohl(x);
-
-                               if (kv->_size < x)
-                               {
-                                       kvarray_free(a);
-                                       return NULL;
-                               }
-
-                               /* val data */
-                               a->dict[d].val[k][v] = p;
-
-                               p += x;
-                               kv->_size -= x;
-                       }
-               }
-       }
-
-       a->kv = kv;
-       return a;
-}
-
-void
-kvarray_free(kvarray_t *a)
-{
-       uint32_t d, k;
-
-       if (a == NULL) return;
-
-       for (d = 0; d < a->count; d++)
-       {
-               for (k = 0; k < a->dict[d].kcount; k++)
-               {
-                       if (a->dict[d].val == NULL) continue;
-                       if (a->dict[d].val[k] != NULL) free(a->dict[d].val[k]);
-               }
-
-               if (a->dict[d].key != NULL) free(a->dict[d].key);
-               if (a->dict[d].vcount != NULL) free(a->dict[d].vcount);
-               if (a->dict[d].val != NULL) free(a->dict[d].val);
-       }
-
-       a->count = 0;
-
-       if (a->dict != NULL) free(a->dict);
-       a->dict = NULL;
-
-       if (a->kv != NULL) kvbuf_free(a->kv);
-       a->kv = NULL;
-
-       free(a);
-}
-
-kern_return_t
-LI_DSLookupGetProcedureNumber(const char *name, int32_t *procno)
-{
-       kern_return_t status;
-       security_token_t token;
-       uint32_t n, len;
-
-       if (name == NULL) return KERN_FAILURE;
-
-       len = strlen(name) + 1;
-       if (len == 1) return KERN_FAILURE;
-
-       token.val[0] = -1;
-       token.val[1] = -1;
-
-       if (_ds_running() == 0) return KERN_FAILURE;
-       if (_ds_port == MACH_PORT_NULL) return KERN_FAILURE;
-
-       status = MIG_SERVER_DIED;
-       for (n = 0; (_ds_port != MACH_PORT_NULL) && (status == MIG_SERVER_DIED) && (n < MAX_LOOKUP_ATTEMPTS); n++)
-       {
-               status = libinfoDSmig_GetProcedureNumber(_ds_port, (char *)name, procno, &token);
-
-               if (status == MACH_SEND_INVALID_DEST)
-               {
-                       mach_port_mod_refs(mach_task_self(), _ds_port, MACH_PORT_RIGHT_SEND, -1);
-                       status = bootstrap_look_up(bootstrap_port, kDSStdMachDSLookupPortName, &_ds_port);
-                       if ((status != BOOTSTRAP_SUCCESS) && (status != BOOTSTRAP_UNKNOWN_SERVICE)) _ds_port = MACH_PORT_NULL;
-                       status = MIG_SERVER_DIED;
-               }
-       }
-
-       if (status != KERN_SUCCESS)
-       {
-#ifdef DEBUG
-               asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "_DSLookupGetProcedureNumber %s status %u", name, status);
-#endif
-               return status;
-       }
-
-       if (token.val[0] != 0)
-       {
-#ifdef DEBUG
-               asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "_DSLookupGetProcedureNumber %s auth failure uid=%d", name, token.val[0]);
-#endif
-               return KERN_FAILURE;
-       }
-
-#ifdef DEBUG
-       asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "_DSLookupGetProcedureNumber %s = %d", name, *procno);
-#endif
-       return status;
-}
-
-__private_extern__ kern_return_t
-LI_DSLookupQuery(int32_t procno, kvbuf_t *request, kvarray_t **reply)
-{
-       kern_return_t status;
-       security_token_t token;
-       uint32_t n;
-       mach_msg_type_number_t illen, oolen;
-       char ilbuf[MAX_MIG_INLINE_DATA];
-       vm_offset_t oobuf;
-       kvbuf_t *out;
-
-       if (reply == NULL) return KERN_FAILURE;
-       if ((request != NULL) && ((request->databuf == NULL) || (request->datalen == 0))) return KERN_FAILURE;
-
-       token.val[0] = -1;
-       token.val[1] = -1;
-       *reply = NULL;
-
-       if (_ds_running() == 0) return KERN_FAILURE;
-       if (_ds_port == MACH_PORT_NULL) return KERN_FAILURE;
-
-       status = MIG_SERVER_DIED;
-       for (n = 0; (_ds_port != MACH_PORT_NULL) && (status == MIG_SERVER_DIED) && (n < MAX_LOOKUP_ATTEMPTS); n++)
-       {
-               illen = 0;
-               oolen = 0;
-               oobuf = 0;
-
-               if (request != NULL)
-               {
-                       status = libinfoDSmig_Query(_ds_port, procno, request->databuf, request->datalen, ilbuf, &illen, &oobuf, &oolen, &token);
-               }
-               else
-               {
-                       status = libinfoDSmig_Query(_ds_port, procno, "", 0, ilbuf, &illen, &oobuf, &oolen, &token);
-               }
-
-               if (status == MACH_SEND_INVALID_DEST)
-               {
-                       mach_port_mod_refs(mach_task_self(), _ds_port, MACH_PORT_RIGHT_SEND, -1);
-                       status = bootstrap_look_up(bootstrap_port, kDSStdMachDSLookupPortName, &_ds_port);
-                       if ((status != BOOTSTRAP_SUCCESS) && (status != BOOTSTRAP_UNKNOWN_SERVICE)) _ds_port = MACH_PORT_NULL;
-                       status = MIG_SERVER_DIED;
-               }
-       }
-
-       if (status != KERN_SUCCESS)
-       {
-#ifdef DEBUG
-               asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "_DSLookupQuery %d status %u", procno, status);
-#endif
-               return status;
-       }
-
-       if (token.val[0] != 0)
-       {
-#ifdef DEBUG
-               asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "_DSLookupQuery %d auth failure uid=%d", procno, token.val[0]);
-#endif
-               if (oolen > 0) vm_deallocate(mach_task_self(), (vm_address_t)oobuf, oolen);
-               return KERN_FAILURE;
-       }
-
-       out = (kvbuf_t *)calloc(1, sizeof(kvbuf_t));
-       if (out == NULL)
-       {
-               if (oolen > 0) vm_deallocate(mach_task_self(), (vm_address_t)oobuf, oolen);
-               return KERN_FAILURE;
-       }
-
-       if (oolen > 0)
-       {
-               out->datalen = oolen;
-               out->databuf = malloc(oolen);
-               if (out->databuf == NULL)
-               {
-                       free(out);
-                       *reply = NULL;
-                       vm_deallocate(mach_task_self(), (vm_address_t)oobuf, oolen);
-                       return KERN_FAILURE;
-               }
-
-               memcpy(out->databuf, (char *)oobuf, oolen);
-               vm_deallocate(mach_task_self(), (vm_address_t)oobuf, oolen);
-       }
-       else if (illen > 0)
-       {
-               out->datalen = illen;
-               out->databuf = malloc(illen);
-               if (out->databuf == NULL)
-               {
-                       free(out);
-                       *reply = NULL;
-                       return KERN_FAILURE;
-               }
-
-               memcpy(out->databuf, ilbuf, illen);
-       }
-
-       *reply = kvbuf_decode(out);
-       if (*reply == NULL)
-       {
-               /* DS returned no data */
-               free(out->databuf);
-               free(out);
-       }
-
-#ifdef DEBUG
-       asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "_DSLookupQuery %d status OK", procno);
-#endif
-       return status;
-}
-
-/*
- * Get an entry from a kvarray.
- * Calls the system information daemon if the list doesn't exist (first call),
- * or extracts the next entry if the list has been fetched.
- */
-__private_extern__ void *
-LI_getent(const char *procname, int *procnum, void *(*extract)(kvarray_t *), int tkey, size_t esize)
-{
-       void *entry;
-       struct li_thread_info *tdata;
-       kvarray_t *reply;
-       kern_return_t status;
-
-       tdata = LI_data_create_key(tkey, esize);
-       if (tdata == NULL) return NULL;
-
-       if (tdata->li_vm == NULL)
-       {
-               if (*procnum < 0)
-               {
-                       status = LI_DSLookupGetProcedureNumber(procname, procnum);
-                       if (status != KERN_SUCCESS)
-                       {
-                               LI_data_free_kvarray(tdata);
-                               tdata->li_vm = NULL;
-                               return NULL;
-                       }
-               }
-
-               reply = NULL;
-               status = LI_DSLookupQuery(*procnum, NULL, &reply);
-
-               if (status != KERN_SUCCESS)
-               {
-                       LI_data_free_kvarray(tdata);
-                       tdata->li_vm = NULL;
-                       return NULL;
-               }
-
-               tdata->li_vm = (char *)reply;
-       }
-
-       entry = extract((kvarray_t *)(tdata->li_vm));
-       if (entry == NULL)
-       {
-               LI_data_free_kvarray(tdata);
-               tdata->li_vm = NULL;
-               return NULL;
-       }
-
-       return entry;
-}
-
-__private_extern__ void *
-LI_getone(const char *procname, int *procnum, void *(*extract)(kvarray_t *), const char *key, const char *val)
-{
-       void *entry;
-       kvbuf_t *request;
-       kvarray_t *reply;
-       kern_return_t status;
-
-       if (*procnum < 0)
-       {
-               status = LI_DSLookupGetProcedureNumber(procname, procnum);
-               if (status != KERN_SUCCESS) return NULL;
-       }
-
-       request = kvbuf_query_key_val(key, val);
-       if (request == NULL) return NULL;
-
-       reply = NULL;
-       status = LI_DSLookupQuery(*procnum, request, &reply);
-       kvbuf_free(request);
-
-       if (status != KERN_SUCCESS) return NULL;
-
-       entry = extract(reply);
-       kvarray_free(reply);
-
-       return entry;
-}
-
-__private_extern__
-int LI_L1_cache_check(int tkey)
-{
-       int check, x;
-       const char *notify_key;
-
-       /* check if L1 cache is disabled */
-       if (gL1CacheEnabled == 0) return LI_L1_CACHE_DISABLED;
-
-       /* Initialize on first call */
-       if (_L1_notify_token[0] == -1)
-       {
-               pthread_mutex_lock(&_notify_lock);
-               if (_L1_notify_token[0] == -1) notify_register_check(L1_CACHE_NOTIFICATION_KEY_GLOBAL, &(_L1_notify_token[0]));
-               pthread_mutex_unlock(&_notify_lock);
-       }
-
-       if (_L1_notify_token[0] == -1) return LI_L1_CACHE_FAILED;
-
-       check = 1;
-       if (notify_check(_L1_notify_token[0], &check) != 0) return LI_L1_CACHE_FAILED;
-       if (check == 1) return LI_L1_CACHE_STALE;
-
-       x = 0;
-       notify_key = NULL;
-
-       switch (tkey)
-       {
-               case _li_data_key_group:
-               {
-                       x = 1;
-                       notify_key = L1_CACHE_NOTIFICATION_KEY_GROUP;
-                       break;
-               }
-               case _li_data_key_host:
-               {
-                       x = 2;
-                       notify_key = L1_CACHE_NOTIFICATION_KEY_HOST;
-                       break;
-               }
-               case _li_data_key_service:
-               {
-                       x = 3;
-                       notify_key = L1_CACHE_NOTIFICATION_KEY_SERVICE;
-                       break;
-               }
-               case _li_data_key_user:
-               {
-                       x = 4;
-                       notify_key = L1_CACHE_NOTIFICATION_KEY_USER;
-                       break;
-               }
-               default: break;
-       }
-
-       if ((x != 0) && (notify_key != NULL))
-       {
-               /* Initialize on first call */
-               if (_L1_notify_token[x] == -1)
-               {
-                       pthread_mutex_lock(&_notify_lock);
-                       if (_L1_notify_token[x] == -1) notify_register_check(notify_key, &(_L1_notify_token[x]));
-                       pthread_mutex_unlock(&_notify_lock);
-               }
-
-               if (_L1_notify_token[x] == -1) return LI_L1_CACHE_FAILED;
-
-               check = 1;
-               if (notify_check(_L1_notify_token[x], &check) != 0) return LI_L1_CACHE_FAILED;
-               if (check == 1) return LI_L1_CACHE_STALE;
-       }
-
-       return LI_L1_CACHE_OK;
-}
-
-static uint32_t
-padsize(size_t curr, size_t item, const uint32_t *align)
-{
-       uint32_t na, diff;
-
-       if (item > 8) item = 8;
-
-       na = align[item];
-       if (na == 0) return 0;
-
-       diff = curr % na;
-       if (diff == 0) return 0;
-
-       return na - diff;
-}
-
-
-/*
- * Create a structure using in-line memory (i.e. all one blob).
- * This reduces malloc/free workload.
- *
- * Structutre components may be strings, 1, 2, 4, or 8-byte values,  
- * lists of strings, or lists of 4, 8, or 16-byte values.
- *
- * Format keys:
- *     s       NUL terminated string
- *     1       1 byte value
- *     2       2 byte value
- *     4       4 byte value
- *     8       8 byte value
- *     L       long (32 or 64 bits, depending on architecture)
- *     *       NULL-terminated list of strings
- *     a       NULL-terminated list of 4-byte values
- *     b       NULL-terminated list of 8-byte values
- *     c       NULL-terminated list of 16-byte values
- *
- */
-__private_extern__ void *
-LI_ils_create(char *fmt, ...)
-{
-       va_list ap;
-       char *arg, *f;
-       char **list;
-       void *hp, *dp, *lp, *ils;
-       uint8_t u8;
-       uint16_t u16;
-       uint32_t u32, i, pad;
-       uint64_t u64;
-       unsigned long l;
-       size_t memsize, hsize, csize, slen, largest;
-       const uint32_t *align;
-
-       if (fmt == NULL) return NULL;
-
-       largest = 0;
-       align = align_32;
-       if (sizeof(char *) == 8) align = align_64;
-
-       /* first pass: calculate size */
-       memsize = ILS_MAGIC_SIZE;
-       hsize = 0;
-
-       va_start(ap, fmt);
-
-       for (f = fmt; (*f) != '\0'; f++)
-       {
-               csize = 0;
-               slen = 0;
-
-               if (*f == 's')
-               {
-                       if (largest < sizeof(char *)) largest = sizeof(char *);
-
-                       csize = sizeof(char *) + padsize(hsize, sizeof(char *), align);
-                       arg = va_arg(ap, char *);
-                       if (arg != NULL) slen = strlen(arg) + 1;
-               }
-               else if (*f == '1')
-               {
-                       if (largest < 1) largest = 1;
-
-                       csize = 1;
-                       u8 = va_arg(ap, int);
-               }
-               else if (*f == '2')
-               {
-                       if (largest < 2) largest = 2;
-
-                       csize = 2 + padsize(hsize, 2, align);
-                       u16 = va_arg(ap, int);
-               }
-               else if (*f == '4')
-               {
-                       if (largest < 4) largest = 4;
-
-                       csize = 4 + padsize(hsize, 4, align);
-                       u32 = va_arg(ap, uint32_t);
-               }
-               else if (*f == '8')
-               {
-                       if (largest < 8) largest = 8;
-
-                       csize = 8 + padsize(hsize, 8, align);
-                       u64 = va_arg(ap, uint64_t);
-               }
-               else if (*f == 'L')
-               {
-                       if (largest < sizeof(unsigned long)) largest = sizeof(unsigned long);
-
-                       csize = sizeof(unsigned long) + padsize(hsize, sizeof(unsigned long), align);
-                       l = va_arg(ap, unsigned long);
-               }
-               else if (*f == '*')
-               {
-                       /* NULL-terminated list of strings */
-                       if (largest < sizeof(char *)) largest = sizeof(char *);
-
-                       csize = sizeof(char *) + padsize(hsize, sizeof(char *), align);
-                       list = va_arg(ap, char **);
-                       if (list != NULL)
-                       {
-                               for (i = 0; list[i] != NULL; i++)
-                               {
-                                       slen += sizeof(char *);
-                                       slen += (strlen(list[i]) + 1);
-                               }
-
-                               slen += sizeof(char *);
-                       }
-               }
-               else if (*f == 'a')
-               {
-                       /* NULL-terminated list of 4-byte values */
-                       if (largest < sizeof(char *)) largest = sizeof(char *);
-
-                       csize = sizeof(char *) + padsize(hsize, sizeof(char *), align);
-                       list = va_arg(ap, char **);
-                       if (list != NULL)
-                       {
-                               for (i = 0; list[i] != NULL; i++)
-                               {
-                                       slen += sizeof(char *);
-                                       slen += 4;
-                               }
-
-                               slen += sizeof(char *);
-                       }
-               }
-               else if (*f == 'b')
-               {
-                       /* NULL-terminated list of 8-byte values */
-                       if (largest < sizeof(char *)) largest = sizeof(char *);
-
-                       csize = sizeof(char *) + padsize(hsize, sizeof(char *), align);
-                       list = va_arg(ap, char **);
-                       if (list != NULL)
-                       {
-                               for (i = 0; list[i] != NULL; i++)
-                               {
-                                       slen += sizeof(char *);
-                                       slen += 8;
-                               }
-
-                               slen += sizeof(char *);
-                       }
-               }
-               else if (*f == 'c')
-               {
-                       /* NULL-terminated list of 16-byte values */
-                       if (largest < sizeof(char *)) largest = sizeof(char *);
-
-                       csize = sizeof(char *) + padsize(hsize, sizeof(char *), align);
-                       list = va_arg(ap, char **);
-                       if (list != NULL)
-                       {
-                               for (i = 0; list[i] != NULL; i++)
-                               {
-                                       slen += sizeof(char *);
-                                       slen += 16;
-                               }
-
-                               slen += sizeof(char *);
-                       }
-               }
-               else return NULL;
-
-               memsize += csize;
-               memsize += slen;
-               hsize += csize;
-       }
-
-       va_end(ap);
-
-       pad = padsize(hsize, largest, align);
-       memsize += pad;
-       hsize += pad;
-
-       ils = malloc(memsize);
-       if (ils == NULL)
-       {
-               errno = ENOMEM;
-               return NULL;
-       }
-
-       /* insert magic cookie */
-       dp = ils + hsize;
-       memcpy(dp, ILS_MAGIC, ILS_MAGIC_SIZE);
-       dp += ILS_MAGIC_SIZE;
-
-       hp = ils;
-       hsize = 0;
-
-       /* second pass: copy data */
-       va_start(ap, fmt);
-       for (f = fmt; (*f) != '\0'; f++)
-       {
-               if (*f == 's')
-               {
-                       pad = padsize(hsize, sizeof(char *), align);
-                       if (pad != 0)
-                       {
-                               memset(hp, 0, pad);
-                               hp += pad;
-                               hsize += pad;
-                       }
-
-                       arg = va_arg(ap, char *);
-                       if (arg == NULL)
-                       {
-                               memset(hp, 0, sizeof(char *));
-                       }
-                       else
-                       {
-                               memcpy(hp, &dp, sizeof(char *));
-                               slen = strlen(arg) + 1;
-                               memcpy(dp, arg, slen);
-                               dp += slen;
-                       }
-
-                       hp += sizeof(char *);
-                       hsize += sizeof(char *);
-               }
-               else if (*f == '1')
-               {
-                       u8 = va_arg(ap, int);
-                       memcpy(hp, &u8, sizeof(uint8_t));
-                       hp += sizeof(uint8_t);
-               }
-               else if (*f == '2')
-               {
-                       pad = padsize(hsize, 2, align);
-                       if (pad != 0)
-                       {
-                               memset(hp, 0, pad);
-                               hp += pad;
-                               hsize += pad;
-                       }
-
-                       u16 = va_arg(ap, int);
-                       memcpy(hp, &u16, sizeof(uint16_t));
-
-                       hp += sizeof(uint16_t);
-                       hsize += sizeof(uint16_t);
-               }
-               else if (*f == '4')
-               {
-                       pad = padsize(hsize, 4, align);
-                       if (pad != 0)
-                       {
-                               memset(hp, 0, pad);
-                               hp += pad;
-                               hsize += pad;
-                       }
-
-                       u32 = va_arg(ap, uint32_t);
-                       memcpy(hp, &u32, sizeof(uint32_t));
-
-                       hp += sizeof(uint32_t);
-                       hsize += sizeof(uint32_t);
-               }
-               else if (*f == '8')
-               {
-                       pad = padsize(hsize, 8, align);
-                       if (pad != 0)
-                       {
-                               memset(hp, 0, pad);
-                               hp += pad;
-                               hsize += pad;
-                       }
-
-                       u64 = va_arg(ap, uint64_t);
-                       memcpy(hp, &u64, sizeof(uint64_t));
-
-                       hp += sizeof(uint64_t);
-                       hsize += sizeof(uint64_t);
-               }
-               else if (*f == 'L')
-               {
-                       pad = padsize(hsize, sizeof(unsigned long), align);
-                       if (pad != 0)
-                       {
-                               memset(hp, 0, pad);
-                               hp += pad;
-                               hsize += pad;
-                       }
-
-                       l = va_arg(ap, unsigned long);
-                       memcpy(hp, &l, sizeof(unsigned long));
-
-                       hp += sizeof(unsigned long);
-                       hsize += sizeof(unsigned long);
-               }
-               else if (*f == '*')
-               {
-                       pad = padsize(hsize, sizeof(char *), align);
-                       if (pad != 0)
-                       {
-                               memset(hp, 0, pad);
-                               hp += pad;
-                               hsize += pad;
-                       }
-
-                       list = va_arg(ap, char **);
-
-                       if (list == NULL)
-                       {
-                               memset(hp, 0, sizeof(char *));
-                       }
-                       else
-                       {
-                               memcpy(hp, &dp, sizeof(char *));
-
-                               for (i = 0; list[i] != NULL; i++);
-
-                               lp = dp;
-                               dp += ((i + 1) * sizeof(char *));
-
-                               for (i = 0; list[i] != NULL; i++)
-                               {
-                                       memcpy(lp, &dp, sizeof(char *));
-                                       lp += sizeof(char *);
-                                       slen = strlen(list[i]) + 1;
-                                       memcpy(dp, list[i], slen);
-                                       dp += slen;
-                               }
-
-                               memset(lp, 0, sizeof(char *));
-                       }
-
-                       hp += sizeof(char *);
-                       hsize += sizeof(char *);
-               }
-               else if (*f == 'a')
-               {
-                       pad = padsize(hsize, sizeof(char *), align);
-                       if (pad != 0)
-                       {
-                               memset(hp, 0, pad);
-                               hp += pad;
-                               hsize += pad;
-                       }
-
-                       list = va_arg(ap, char **);
-
-                       if (list == NULL)
-                       {
-                               memset(hp, 0, sizeof(char *));
-                       }
-                       else
-                       {
-                               memcpy(hp, &dp, sizeof(char *));
-
-                               for (i = 0; list[i] != NULL; i++);
-
-                               lp = dp;
-                               dp += ((i + 1) * sizeof(char *));
-
-                               for (i = 0; list[i] != NULL; i++)
-                               {
-                                       memcpy(lp, &dp, sizeof(char *));
-                                       lp += sizeof(char *);
-                                       slen = 4;
-                                       memcpy(dp, list[i], slen);
-                                       dp += slen;
-                               }
-
-                               memset(lp, 0, sizeof(char *));
-                       }
-
-                       hp += sizeof(char *);
-                       hsize += sizeof(char *);
-               }
-               else if (*f == 'b')
-               {
-                       pad = padsize(hsize, sizeof(char *), align);
-                       if (pad != 0)
-                       {
-                               memset(hp, 0, pad);
-                               hp += pad;
-                               hsize += pad;
-                       }
-
-                       list = va_arg(ap, char **);
-
-                       if (list == NULL)
-                       {
-                               memset(hp, 0, sizeof(char *));
-                       }
-                       else
-                       {
-                               memcpy(hp, &dp, sizeof(char *));
-
-                               for (i = 0; list[i] != NULL; i++);
-
-                               lp = dp;
-                               dp += ((i + 1) * sizeof(char *));
-
-                               for (i = 0; list[i] != NULL; i++)
-                               {
-                                       memcpy(lp, &dp, sizeof(char *));
-                                       lp += sizeof(char *);
-                                       slen = 8;
-                                       memcpy(dp, list[i], slen);
-                                       dp += slen;
-                               }
-
-                               memset(lp, 0, sizeof(char *));
-                       }
-
-                       hp += sizeof(char *);
-                       hsize += sizeof(char *);
-               }
-               else if (*f == 'c')
-               {
-                       pad = padsize(hsize, sizeof(char *), align);
-                       if (pad != 0)
-                       {
-                               memset(hp, 0, pad);
-                               hp += pad;
-                               hsize += pad;
-                       }
-
-                       list = va_arg(ap, char **);
-
-                       if (list == NULL)
-                       {
-                               memset(hp, 0, sizeof(char *));
-                       }
-                       else
-                       {
-                               memcpy(hp, &dp, sizeof(char *));
-
-                               for (i = 0; list[i] != NULL; i++);
-
-                               lp = dp;
-                               dp += ((i + 1) * sizeof(char *));
-
-                               for (i = 0; list[i] != NULL; i++)
-                               {
-                                       memcpy(lp, &dp, sizeof(char *));
-                                       lp += sizeof(char *);
-                                       slen = 16;
-                                       memcpy(dp, list[i], slen);
-                                       dp += slen;
-                               }
-
-                               memset(lp, 0, sizeof(char *));
-                       }
-
-                       hp += sizeof(char *);
-                       hsize += sizeof(char *);
-               }
-       }
-
-       va_end(ap);
-
-       pad = padsize(hsize, largest, align);
-       if (pad > 0) memset(hp, 0, pad);
-
-       return ils;
-}
-
-__private_extern__ int
-LI_ils_free(void *ils, size_t len)
-{
-       char *p;
-
-       if (ils == NULL) return 0;
-
-       p = ils + len;
-       if (memcmp(p, ILS_MAGIC, ILS_MAGIC_SIZE) != 0) return -1;
-
-       free(ils);
-
-       return 0;
-}
-
-kern_return_t 
-_lookup_link(mach_port_t server, char *name, int *procno)
-{
-       syslog(LOG_ERR, "RED ALERT!   lookupd call %s from pid %u", name, getpid());
-       return KERN_FAILURE;
-}
-
-kern_return_t 
-_lookup_one(mach_port_t server, int proc, char *indata, mach_msg_type_number_t indataCnt, char *outdata, mach_msg_type_number_t *outdataCnt)
-{
-       return KERN_FAILURE;
-}
-
-kern_return_t 
-_lookup_all(mach_port_t server, int proc, char *indata, mach_msg_type_number_t indataCnt, char **outdata, mach_msg_type_number_t *outdataCnt)
-{
-       return KERN_FAILURE;
-}
-
-kern_return_t 
-_lookup_ooall(mach_port_t server, int proc, char *indata, mach_msg_type_number_t indataCnt, char **outdata, mach_msg_type_number_t *outdataCnt)
-{
-       return KERN_FAILURE;
-}