]> git.saurik.com Git - apple/libinfo.git/blobdiff - lookup.subproj/lu_alias.c
Libinfo-278.tar.gz
[apple/libinfo.git] / lookup.subproj / lu_alias.c
index cb62a7c636886b32f8e2fdeb10f1b0a03ecc2497..5c7d28ac48bb626469c299edeac28ffb2384059b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include <mach/mach.h>
 #include <stdio.h>
 #include <string.h>
-#include <rpc/types.h>
-#include <rpc/xdr.h>
 #include <aliasdb.h>
 #include <pthread.h>
-
-#include "_lu_types.h"
-#include "lookup.h"
 #include "lu_utils.h"
 #include "lu_overrides.h"
 
+#define ENTRY_SIZE sizeof(struct aliasent)
+#define ENTRY_KEY _li_data_key_alias
+
 static pthread_mutex_t _alias_lock = PTHREAD_MUTEX_INITIALIZER;
 
-static void 
-free_alias_data(struct aliasent *a)
+static struct aliasent *
+copy_alias(struct aliasent *in)
 {
-       int i;
-
-       if (a == NULL) return;
-
-       if (a->alias_name != NULL) free(a->alias_name);
-       for (i = 0; i < a->alias_members_len; i++) free(a->alias_members[i]);
-       if (a->alias_members != NULL) free(a->alias_members);
-}
+       if (in == NULL) return NULL;
 
-static void 
-free_alias(struct aliasent *a)
-{
-       if (a == NULL) return;
-       free_alias_data(a);
-       free(a);
+       return (struct aliasent *)LI_ils_create("s4*4", in->alias_name, in->alias_members_len, in->alias_members, in->alias_local);
 }
 
-static void
-free_lu_thread_info_alias(void *x)
+/*
+ * Extract the next alias entry from a kvarray.
+ */
+static void *
+extract_alias(kvarray_t *in)
 {
-       struct lu_thread_info *tdata;
-
-       if (x == NULL) return;
-
-       tdata = (struct lu_thread_info *)x;
-       
-       if (tdata->lu_entry != NULL)
-       {
-               free_alias((struct aliasent *)tdata->lu_entry);
-               tdata->lu_entry = NULL;
-       }
+       struct aliasent tmp;
+       uint32_t d, k, kcount;
+       char *empty[1];
 
-       _lu_data_free_vm_xdr(tdata);
-
-       free(tdata);
-}
+       if (in == NULL) return NULL;
 
-static struct aliasent *
-extract_alias(XDR *xdr)
-{
-       int i, j, nkeys, nvals, status;
-       char *key, **vals;
-       struct aliasent *a;
+       d = in->curr;
+       in->curr++;
 
-       if (xdr == NULL) return NULL;
+       if (d >= in->count) return NULL;
 
-       if (!xdr_int(xdr, &nkeys)) return NULL;
+       empty[0] = NULL;
+       memset(&tmp, 0, ENTRY_SIZE);
 
-       a = (struct aliasent *)calloc(1, sizeof(struct aliasent));
+       kcount = in->dict[d].kcount;
 
-       for (i = 0; i < nkeys; i++)
+       for (k = 0; k < kcount; k++)
        {
-               key = NULL;
-               vals = NULL;
-               nvals = 0;
-
-               status = _lu_xdr_attribute(xdr, &key, &vals, &nvals);
-               if (status < 0)
+               if (!strcmp(in->dict[d].key[k], "alias_name"))
                {
-                       free_alias(a);
-                       return NULL;
-               }
+                       if (tmp.alias_name != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
 
-               if (nvals == 0)
-               {
-                       free(key);
-                       continue;
+                       tmp.alias_name = (char *)in->dict[d].val[k][0];
                }
-
-               j = 0;
-
-               if ((a->alias_name == NULL) && (!strcmp("name", key)))
-               {
-                       a->alias_name = vals[0];
-                       j = 1;
-               }
-               else if (!strcmp("alias_local", key))
+               else if (!strcmp(in->dict[d].key[k], "alias_members"))
                {
-                       a->alias_local = atoi(vals[0]);
-               }
-               else if ((a->alias_members == NULL) && (!strcmp("members", key)))
-               {
-                       a->alias_members_len = nvals;
-                       a->alias_members = vals;
-                       j = nvals;
-                       vals = NULL;
-               }
+                       if (tmp.alias_members != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
 
-               free(key);
-               if (vals != NULL)
+                       tmp.alias_members_len = in->dict[d].vcount[k];
+                       tmp.alias_members = (char **)in->dict[d].val[k];
+               }
+               else if (!strcmp(in->dict[d].key[k], "alias_local"))
                {
-                       for (; j < nvals; j++) free(vals[j]);
-                       free(vals);
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       tmp.alias_local = atoi(in->dict[d].val[k][0]);
                }
        }
 
-       if (a->alias_name == NULL) a->alias_name = strdup("");
-       if (a->alias_members == NULL) a->alias_members = (char **)calloc(1, sizeof(char *));
+       if (tmp.alias_name == NULL) tmp.alias_name = "";
+       if (tmp.alias_members == NULL) tmp.alias_members = empty;
 
-       return a;
+       return copy_alias(&tmp);
 }
 
+/*
+ * Send a query to the system information daemon.
+ */
 static struct aliasent *
-copy_alias(struct aliasent *in)
-{
-       int i;
-       struct aliasent *a;
-
-       if (in == NULL) return NULL;
-
-       a = (struct aliasent *)calloc(1, sizeof(struct aliasent));
-
-       a->alias_name = LU_COPY_STRING(in->alias_name);
-
-       a->alias_members_len = in->alias_members_len;
-
-       if (a->alias_members_len == 0)
-       {
-               a->alias_members = (char **)calloc(1, sizeof(char *));
-       }
-       else
-       {
-               a->alias_members = (char **)calloc(a->alias_members_len, sizeof(char *));
-       }
-
-       for (i = 0; i < a->alias_members_len; i++)
-       {
-               a->alias_members[i] = strdup(in->alias_members[i]);
-       }
-
-       a->alias_local = in->alias_local;
-
-       return a;
-}
-
-static void
-recycle_alias(struct lu_thread_info *tdata, struct aliasent *in)
-{
-       struct aliasent *a;
-
-       if (tdata == NULL) return;
-       a = (struct aliasent *)tdata->lu_entry;
-
-       if (in == NULL)
-       {
-               free_alias(a);
-               tdata->lu_entry = NULL;
-       }
-
-       if (tdata->lu_entry == NULL)
-       {
-               tdata->lu_entry = in;
-               return;
-       }
-
-       free_alias_data(a);
-
-       a->alias_name = in->alias_name;
-       a->alias_members_len = in->alias_members_len;
-       a->alias_members = in->alias_members;
-       a->alias_local = in->alias_local;
-
-       free(in);
-}
-
-static struct aliasent *
-lu_alias_getbyname(const char *name)
+ds_alias_getbyname(const char *name)
 {
-       struct aliasent *a;
-       unsigned int datalen;
-       char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT];
-       char *lookup_buf;
-       XDR outxdr;
-       XDR inxdr;
        static int proc = -1;
-       int count;
-
-       if (proc < 0)
-       {
-               if (_lookup_link(_lu_port, "alias_getbyname", &proc) != KERN_SUCCESS)
-               {
-                       return NULL;
-               }
-       }
 
-       xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE);
-       if (!xdr__lu_string(&outxdr, (_lu_string *)&name))
-       {
-               xdr_destroy(&outxdr);
-               return NULL;
-       }
-       
-       datalen = 0;
-       lookup_buf = NULL;
-       
-       if (_lookup_all(_lu_port, proc, (unit *)namebuf,
-               xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, &lookup_buf, &datalen)
-               != KERN_SUCCESS)
-       {
-               xdr_destroy(&outxdr);
-               return NULL;
-       }
-
-       xdr_destroy(&outxdr);
-
-       datalen *= BYTES_PER_XDR_UNIT;
-       if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
-
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
-
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       a = extract_alias(&inxdr);
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-
-       return a;
+       return (struct aliasent *)LI_getone("alias_getbyname", &proc, extract_alias, "name", name);
 }
 
+/*
+ * Clean up / initialize / reinitialize the kvarray used to hold a list of all rpc entries.
+ */
 static void
-lu_alias_endent(void)
+ds_alias_endent(void)
 {
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_alias, free_lu_thread_info_alias);
-       _lu_data_free_vm_xdr(tdata);
+       LI_data_free_kvarray(LI_data_find_key(ENTRY_KEY));
 }
 
 static void
-lu_alias_setent(void)
+ds_alias_setent(void)
 {
-       lu_alias_endent();
+       ds_alias_endent();
 }
 
+/*
+ * Get an entry from the getrpcent 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.
+ */
 static struct aliasent *
-lu_alias_getent(void)
+ds_alias_getent(void)
 {
        static int proc = -1;
-       struct lu_thread_info *tdata;
-       struct aliasent *a;
-
-       tdata = _lu_data_create_key(_lu_data_key_alias, free_lu_thread_info_alias);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_alias, tdata);
-       }
-
-       if (tdata->lu_vm == NULL)
-       {
-               if (proc < 0)
-               {
-                       if (_lookup_link(_lu_port, "alias_getent", &proc) != KERN_SUCCESS)
-                       {
-                               lu_alias_endent();
-                               return NULL;
-                       }
-               }
-
-               if (_lookup_all(_lu_port, proc, NULL, 0, &(tdata->lu_vm), &(tdata->lu_vm_length)) != KERN_SUCCESS)
-               {
-                       lu_alias_endent();
-                       return NULL;
-               }
-
-               /* mig stubs measure size in words (4 bytes) */
-               tdata->lu_vm_length *= 4;
-
-               if (tdata->lu_xdr != NULL)
-               {
-                       xdr_destroy(tdata->lu_xdr);
-                       free(tdata->lu_xdr);
-               }
-               tdata->lu_xdr = (XDR *)calloc(1, sizeof(XDR));
 
-               xdrmem_create(tdata->lu_xdr, tdata->lu_vm, tdata->lu_vm_length, XDR_DECODE);
-               if (!xdr_int(tdata->lu_xdr, &tdata->lu_vm_cursor))
-               {
-                       lu_alias_endent();
-                       return NULL;
-               }
-       }
-
-       if (tdata->lu_vm_cursor == 0)
-       {
-               lu_alias_endent();
-               return NULL;
-       }
-
-
-       a = extract_alias(tdata->lu_xdr);
-       if (a == NULL)
-       {
-               lu_alias_endent();
-               return NULL;
-       }
-
-       tdata->lu_vm_cursor--;
-       
-       return a;
+       return (struct aliasent *)LI_getent("alias_getent", &proc, extract_alias, ENTRY_KEY, ENTRY_SIZE);
 }
 
 struct aliasent *
 alias_getbyname(const char *name)
 {
        struct aliasent *res = NULL;
-       struct lu_thread_info *tdata;
+       struct li_thread_info *tdata;
 
-       tdata = _lu_data_create_key(_lu_data_key_alias, free_lu_thread_info_alias);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_alias, tdata);
-       }
+       tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
+       if (tdata == NULL) return NULL;
 
-       if (_lu_running())
+       if (_ds_running())
        {
-               res = lu_alias_getbyname(name);
+               res = ds_alias_getbyname(name);
        }
        else
        {
@@ -384,8 +159,8 @@ alias_getbyname(const char *name)
                pthread_mutex_unlock(&_alias_lock);
        }
 
-       recycle_alias(tdata, res);
-       return (struct aliasent *)tdata->lu_entry;
+       LI_data_recycle(tdata, res, ENTRY_SIZE);
+       return (struct aliasent *)tdata->li_entry;
 
 }
 
@@ -393,18 +168,14 @@ struct aliasent *
 alias_getent(void)
 {
        struct aliasent *res = NULL;
-       struct lu_thread_info *tdata;
+       struct li_thread_info *tdata;
 
-       tdata = _lu_data_create_key(_lu_data_key_alias, free_lu_thread_info_alias);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_alias, tdata);
-       }
+       tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
+       if (tdata == NULL) return NULL;
 
-       if (_lu_running())
+       if (_ds_running())
        {
-               res = lu_alias_getent();
+               res = ds_alias_getent();
        }
        else
        {
@@ -413,21 +184,21 @@ alias_getent(void)
                pthread_mutex_unlock(&_alias_lock);
        }
 
-       recycle_alias(tdata, res);
-       return (struct aliasent *)tdata->lu_entry;
+       LI_data_recycle(tdata, res, ENTRY_SIZE);
+       return (struct aliasent *)tdata->li_entry;
 
 }
 
 void
 alias_setent(void)
 {
-       if (_lu_running()) lu_alias_setent();
+       if (_ds_running()) ds_alias_setent();
        else _old_alias_setent();
 }
 
 void
 alias_endent(void)
 {
-       if (_lu_running()) lu_alias_endent();
+       if (_ds_running()) ds_alias_endent();
        else _old_alias_endent();
 }