1/*-
2 * Copyright (c) 2005 Michael Bushkov <bushman@rsu.ru>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD$");
30
31#include <assert.h>
32#include <stdlib.h>
33#include <string.h>
34
35#include "agent.h"
36#include "debug.h"
37
38static int
39agent_cmp_func(const void *a1, const void *a2)
40{
41   	struct agent const *ap1 = *((struct agent const **)a1);
42	struct agent const *ap2 = *((struct agent const **)a2);
43	int res;
44
45	res = strcmp(ap1->name, ap2->name);
46	if (res == 0) {
47		if (ap1->type == ap2->type)
48			res = 0;
49		else if (ap1->type < ap2->type)
50			res = -1;
51		else
52			res = 1;
53	}
54
55	return (res);
56}
57
58struct agent_table *
59init_agent_table(void)
60{
61   	struct agent_table	*retval;
62
63	TRACE_IN(init_agent_table);
64	retval = calloc(1, sizeof(*retval));
65	assert(retval != NULL);
66
67	TRACE_OUT(init_agent_table);
68	return (retval);
69}
70
71void
72register_agent(struct agent_table *at, struct agent *a)
73{
74	struct agent **new_agents;
75    	size_t new_agents_num;
76
77	TRACE_IN(register_agent);
78	assert(at != NULL);
79	assert(a != NULL);
80	new_agents_num = at->agents_num + 1;
81	new_agents = malloc(sizeof(*new_agents) *
82		new_agents_num);
83	assert(new_agents != NULL);
84	memcpy(new_agents, at->agents, at->agents_num * sizeof(struct agent *));
85	new_agents[new_agents_num - 1] = a;
86	qsort(new_agents, new_agents_num, sizeof(struct agent *),
87		agent_cmp_func);
88
89	free(at->agents);
90	at->agents = new_agents;
91	at->agents_num = new_agents_num;
92    	TRACE_OUT(register_agent);
93}
94
95struct agent *
96find_agent(struct agent_table *at, const char *name, enum agent_type type)
97{
98	struct agent **res;
99	struct agent model, *model_p;
100
101	TRACE_IN(find_agent);
102	model.name = (char *)name;
103	model.type = type;
104	model_p = &model;
105	res = bsearch(&model_p, at->agents, at->agents_num,
106		sizeof(struct agent *), agent_cmp_func);
107
108	TRACE_OUT(find_agent);
109	return ( res == NULL ? NULL : *res);
110}
111
112void
113destroy_agent_table(struct agent_table *at)
114{
115    	size_t i;
116
117	TRACE_IN(destroy_agent_table);
118	assert(at != NULL);
119	for (i = 0; i < at->agents_num; ++i) {
120		free(at->agents[i]->name);
121		free(at->agents[i]);
122	}
123
124	free(at->agents);
125	free(at);
126	TRACE_OUT(destroy_agent_table);
127}
128