agent.c revision 194104
1296781Sdes/*-
298675Sdes * Copyright (c) 2005 Michael Bushkov <bushman@rsu.ru>
398675Sdes * All rights reserved.
498675Sdes *
598675Sdes * Redistribution and use in source and binary forms, with or without
698675Sdes * modification, are permitted provided that the following conditions
798675Sdes * are met:
898675Sdes * 1. Redistributions of source code must retain the above copyright
998675Sdes *    notice, this list of conditions and the following disclaimer.
1098675Sdes * 2. Redistributions in binary form must reproduce the above copyright
1198675Sdes *    notice, this list of conditions and the following disclaimer in the
1298675Sdes *    documentation and/or other materials provided with the distribution.
1398675Sdes *
1498675Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1598675Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1698675Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1798675Sdes * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1898675Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1998675Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2098675Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2198675Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2298675Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2398675Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2498675Sdes * SUCH DAMAGE.
2598675Sdes *
2698675Sdes */
2798675Sdes
28162852Sdes#include <sys/cdefs.h>
29162852Sdes__FBSDID("$FreeBSD: head/usr.sbin/nscd/agent.c 194104 2009-06-13 13:07:56Z des $");
30248619Sdes
31162852Sdes#include <assert.h>
32248619Sdes#include <stdlib.h>
33181111Sdes#include <string.h>
34248619Sdes
35248619Sdes#include "agent.h"
36248619Sdes#include "debug.h"
37162852Sdes
38248619Sdesstatic int
39162852Sdesagent_cmp_func(const void *a1, const void *a2)
40162852Sdes{
41204917Sdes   	struct agent const *ap1 = *((struct agent const **)a1);
42204917Sdes	struct agent const *ap2 = *((struct agent const **)a2);
43181111Sdes	int res;
44295367Sdes
45162852Sdes	res = strcmp(ap1->name, ap2->name);
46162852Sdes	if (res == 0) {
47146998Sdes		if (ap1->type == ap2->type)
4898675Sdes			res = 0;
4998675Sdes		else if (ap1->type < ap2->type)
5098675Sdes			res = -1;
5198675Sdes		else
52295367Sdes			res = 1;
5398675Sdes	}
5498675Sdes
55162852Sdes	return (res);
56162852Sdes}
5798675Sdes
5898675Sdesstruct agent_table *
5998675Sdesinit_agent_table(void)
6098675Sdes{
6198675Sdes   	struct agent_table	*retval;
62162852Sdes
63162852Sdes	TRACE_IN(init_agent_table);
64162852Sdes	retval = calloc(1, sizeof(*retval));
6598675Sdes	assert(retval != NULL);
66204917Sdes
67215116Sdes	TRACE_OUT(init_agent_table);
68295367Sdes	return (retval);
69295367Sdes}
70295367Sdes
7198675Sdesvoid
7298675Sdesregister_agent(struct agent_table *at, struct agent *a)
7398675Sdes{
7498675Sdes	struct agent **new_agents;
75124208Sdes    	size_t new_agents_num;
7698675Sdes
7798675Sdes	TRACE_IN(register_agent);
7898675Sdes	assert(at != NULL);
7998675Sdes	assert(a != NULL);
8098675Sdes	new_agents_num = at->agents_num + 1;
8198675Sdes	new_agents = malloc(sizeof(*new_agents) *
82296781Sdes		new_agents_num);
8398675Sdes	assert(new_agents != NULL);
8498675Sdes	memcpy(new_agents, at->agents, at->agents_num * sizeof(struct agent *));
8598675Sdes	new_agents[new_agents_num - 1] = a;
8698675Sdes	qsort(new_agents, new_agents_num, sizeof(struct agent *),
8798675Sdes		agent_cmp_func);
8898675Sdes
89296781Sdes	free(at->agents);
9098675Sdes	at->agents = new_agents;
9198675Sdes	at->agents_num = new_agents_num;
9298675Sdes    	TRACE_OUT(register_agent);
9398675Sdes}
94296781Sdes
9598675Sdesstruct agent *
9698675Sdesfind_agent(struct agent_table *at, const char *name, enum agent_type type)
9798675Sdes{
9898675Sdes	struct agent **res;
9998675Sdes	struct agent model, *model_p;
10098675Sdes
10198675Sdes	TRACE_IN(find_agent);
10298675Sdes	model.name = (char *)name;
10398675Sdes	model.type = type;
10498675Sdes	model_p = &model;
10598675Sdes	res = bsearch(&model_p, at->agents, at->agents_num,
10698675Sdes		sizeof(struct agent *), agent_cmp_func);
10798675Sdes
10898675Sdes	TRACE_OUT(find_agent);
109296781Sdes	return ( res == NULL ? NULL : *res);
110296781Sdes}
11198675Sdes
11298675Sdesvoid
11398675Sdesdestroy_agent_table(struct agent_table *at)
11498675Sdes{
115296781Sdes    	size_t i;
11698675Sdes
11798675Sdes	TRACE_IN(destroy_agent_table);
11898675Sdes	assert(at != NULL);
119296781Sdes	for (i = 0; i < at->agents_num; ++i) {
120296781Sdes		free(at->agents[i]->name);
12198675Sdes		free(at->agents[i]);
12298675Sdes	}
123262566Sdes
124262566Sdes	free(at->agents);
125262566Sdes	free(at);
126262566Sdes	TRACE_OUT(destroy_agent_table);
127262566Sdes}
128262566Sdes