1158115Sume/*-
2158115Sume * Copyright (c) 2005 Michael Bushkov <bushman@rsu.ru>
3158115Sume * All rights reserved.
4158115Sume *
5158115Sume * Redistribution and use in source and binary forms, with or without
6158115Sume * modification, are permitted provided that the following conditions
7158115Sume * are met:
8158115Sume * 1. Redistributions of source code must retain the above copyright
9158115Sume *    notice, this list of conditions and the following disclaimer.
10158115Sume * 2. Redistributions in binary form must reproduce the above copyright
11158115Sume *    notice, this list of conditions and the following disclaimer in the
12158115Sume *    documentation and/or other materials provided with the distribution.
13158115Sume *
14158115Sume * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15158115Sume * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16158115Sume * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17158115Sume * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18158115Sume * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19158115Sume * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20158115Sume * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21158115Sume * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22158115Sume * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23158115Sume * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24158115Sume * SUCH DAMAGE.
25158115Sume *
26158115Sume */
27158115Sume
28158115Sume#include <sys/cdefs.h>
29158115Sume__FBSDID("$FreeBSD$");
30158115Sume
31158115Sume#include <assert.h>
32194093Sdes#include <stdlib.h>
33158115Sume#include <string.h>
34194093Sdes
35158115Sume#include "agent.h"
36158115Sume#include "debug.h"
37158115Sume
38158115Sumestatic int
39158115Sumeagent_cmp_func(const void *a1, const void *a2)
40158115Sume{
41158115Sume   	struct agent const *ap1 = *((struct agent const **)a1);
42158115Sume	struct agent const *ap2 = *((struct agent const **)a2);
43158115Sume	int res;
44158115Sume
45158115Sume	res = strcmp(ap1->name, ap2->name);
46158115Sume	if (res == 0) {
47158115Sume		if (ap1->type == ap2->type)
48158115Sume			res = 0;
49158115Sume		else if (ap1->type < ap2->type)
50158115Sume			res = -1;
51158115Sume		else
52158115Sume			res = 1;
53158115Sume	}
54158115Sume
55158115Sume	return (res);
56158115Sume}
57158115Sume
58158115Sumestruct agent_table *
59194087Sdesinit_agent_table(void)
60158115Sume{
61158115Sume   	struct agent_table	*retval;
62158115Sume
63158115Sume	TRACE_IN(init_agent_table);
64194104Sdes	retval = calloc(1, sizeof(*retval));
65158115Sume	assert(retval != NULL);
66158115Sume
67158115Sume	TRACE_OUT(init_agent_table);
68158115Sume	return (retval);
69158115Sume}
70158115Sume
71158115Sumevoid
72158115Sumeregister_agent(struct agent_table *at, struct agent *a)
73158115Sume{
74158115Sume	struct agent **new_agents;
75158115Sume    	size_t new_agents_num;
76158115Sume
77158115Sume	TRACE_IN(register_agent);
78158115Sume	assert(at != NULL);
79158115Sume	assert(a != NULL);
80158115Sume	new_agents_num = at->agents_num + 1;
81194104Sdes	new_agents = malloc(sizeof(*new_agents) *
82158115Sume		new_agents_num);
83158115Sume	assert(new_agents != NULL);
84158115Sume	memcpy(new_agents, at->agents, at->agents_num * sizeof(struct agent *));
85158115Sume	new_agents[new_agents_num - 1] = a;
86158115Sume	qsort(new_agents, new_agents_num, sizeof(struct agent *),
87158115Sume		agent_cmp_func);
88158115Sume
89158115Sume	free(at->agents);
90158115Sume	at->agents = new_agents;
91158115Sume	at->agents_num = new_agents_num;
92158115Sume    	TRACE_OUT(register_agent);
93158115Sume}
94158115Sume
95158115Sumestruct agent *
96158115Sumefind_agent(struct agent_table *at, const char *name, enum agent_type type)
97158115Sume{
98158115Sume	struct agent **res;
99158115Sume	struct agent model, *model_p;
100158115Sume
101158115Sume	TRACE_IN(find_agent);
102158115Sume	model.name = (char *)name;
103158115Sume	model.type = type;
104158115Sume	model_p = &model;
105158115Sume	res = bsearch(&model_p, at->agents, at->agents_num,
106158115Sume		sizeof(struct agent *), agent_cmp_func);
107158115Sume
108158115Sume	TRACE_OUT(find_agent);
109158115Sume	return ( res == NULL ? NULL : *res);
110158115Sume}
111158115Sume
112158115Sumevoid
113158115Sumedestroy_agent_table(struct agent_table *at)
114158115Sume{
115158115Sume    	size_t i;
116158115Sume
117158115Sume	TRACE_IN(destroy_agent_table);
118158115Sume	assert(at != NULL);
119158115Sume	for (i = 0; i < at->agents_num; ++i) {
120158115Sume		free(at->agents[i]->name);
121158115Sume		free(at->agents[i]);
122158115Sume	}
123158115Sume
124158115Sume	free(at->agents);
125158115Sume	free(at);
126158115Sume	TRACE_OUT(destroy_agent_table);
127158115Sume}
128