#include <stdlib.h>
#include <mach/mach.h>
#include <stdio.h>
#include <string.h>
#include <aliasdb.h>
#include <pthread.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 struct aliasent *
copy_alias(struct aliasent *in)
{
if (in == NULL) return NULL;
return (struct aliasent *)LI_ils_create("s4*4", in->alias_name, in->alias_members_len, in->alias_members, in->alias_local);
}
static void *
extract_alias(kvarray_t *in)
{
struct aliasent tmp;
uint32_t d, k, kcount;
char *empty[1];
if (in == NULL) return NULL;
d = in->curr;
in->curr++;
if (d >= in->count) return NULL;
empty[0] = NULL;
memset(&tmp, 0, ENTRY_SIZE);
kcount = in->dict[d].kcount;
for (k = 0; k < kcount; k++)
{
if (!strcmp(in->dict[d].key[k], "alias_name"))
{
if (tmp.alias_name != NULL) continue;
if (in->dict[d].vcount[k] == 0) continue;
tmp.alias_name = (char *)in->dict[d].val[k][0];
}
else if (!strcmp(in->dict[d].key[k], "alias_members"))
{
if (tmp.alias_members != NULL) continue;
if (in->dict[d].vcount[k] == 0) continue;
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"))
{
if (in->dict[d].vcount[k] == 0) continue;
tmp.alias_local = atoi(in->dict[d].val[k][0]);
}
}
if (tmp.alias_name == NULL) tmp.alias_name = "";
if (tmp.alias_members == NULL) tmp.alias_members = empty;
return copy_alias(&tmp);
}
static struct aliasent *
ds_alias_getbyname(const char *name)
{
static int proc = -1;
return (struct aliasent *)LI_getone("alias_getbyname", &proc, extract_alias, "name", name);
}
static void
ds_alias_endent(void)
{
LI_data_free_kvarray(LI_data_find_key(ENTRY_KEY));
}
static void
ds_alias_setent(void)
{
ds_alias_endent();
}
static struct aliasent *
ds_alias_getent(void)
{
static int proc = -1;
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 li_thread_info *tdata;
tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
if (tdata == NULL) return NULL;
if (_ds_running())
{
res = ds_alias_getbyname(name);
}
else
{
pthread_mutex_lock(&_alias_lock);
res = copy_alias(_old_alias_getbyname(name));
pthread_mutex_unlock(&_alias_lock);
}
LI_data_recycle(tdata, res, ENTRY_SIZE);
return (struct aliasent *)tdata->li_entry;
}
struct aliasent *
alias_getent(void)
{
struct aliasent *res = NULL;
struct li_thread_info *tdata;
tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
if (tdata == NULL) return NULL;
if (_ds_running())
{
res = ds_alias_getent();
}
else
{
pthread_mutex_lock(&_alias_lock);
res = copy_alias(_old_alias_getent());
pthread_mutex_unlock(&_alias_lock);
}
LI_data_recycle(tdata, res, ENTRY_SIZE);
return (struct aliasent *)tdata->li_entry;
}
void
alias_setent(void)
{
if (_ds_running()) ds_alias_setent();
else _old_alias_setent();
}
void
alias_endent(void)
{
if (_ds_running()) ds_alias_endent();
else _old_alias_endent();
}