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