106a99fe3SHajimu UMEMOTO /*- 206a99fe3SHajimu UMEMOTO * Copyright (c) 2005 Michael Bushkov <bushman@rsu.ru> 306a99fe3SHajimu UMEMOTO * All rights reserved. 406a99fe3SHajimu UMEMOTO * 506a99fe3SHajimu UMEMOTO * Redistribution and use in source and binary forms, with or without 606a99fe3SHajimu UMEMOTO * modification, are permitted provided that the following conditions 706a99fe3SHajimu UMEMOTO * are met: 806a99fe3SHajimu UMEMOTO * 1. Redistributions of source code must retain the above copyright 906a99fe3SHajimu UMEMOTO * notice, this list of conditions and the following disclaimer. 1006a99fe3SHajimu UMEMOTO * 2. Redistributions in binary form must reproduce the above copyright 1106a99fe3SHajimu UMEMOTO * notice, this list of conditions and the following disclaimer in the 1206a99fe3SHajimu UMEMOTO * documentation and/or other materials provided with the distribution. 1306a99fe3SHajimu UMEMOTO * 1406a99fe3SHajimu UMEMOTO * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1506a99fe3SHajimu UMEMOTO * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1606a99fe3SHajimu UMEMOTO * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1706a99fe3SHajimu UMEMOTO * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1806a99fe3SHajimu UMEMOTO * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1906a99fe3SHajimu UMEMOTO * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2006a99fe3SHajimu UMEMOTO * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2106a99fe3SHajimu UMEMOTO * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2206a99fe3SHajimu UMEMOTO * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2306a99fe3SHajimu UMEMOTO * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2406a99fe3SHajimu UMEMOTO * SUCH DAMAGE. 2506a99fe3SHajimu UMEMOTO * 2606a99fe3SHajimu UMEMOTO */ 2706a99fe3SHajimu UMEMOTO 2806a99fe3SHajimu UMEMOTO #include <sys/cdefs.h> 2906a99fe3SHajimu UMEMOTO __FBSDID("$FreeBSD$"); 3006a99fe3SHajimu UMEMOTO 3106a99fe3SHajimu UMEMOTO #include <assert.h> 3206a99fe3SHajimu UMEMOTO #include <stdlib.h> 33a5a5d924SDag-Erling Smørgrav #include <string.h> 34a5a5d924SDag-Erling Smørgrav 3506a99fe3SHajimu UMEMOTO #include "agent.h" 3606a99fe3SHajimu UMEMOTO #include "debug.h" 3706a99fe3SHajimu UMEMOTO 3806a99fe3SHajimu UMEMOTO static int 3906a99fe3SHajimu UMEMOTO agent_cmp_func(const void *a1, const void *a2) 4006a99fe3SHajimu UMEMOTO { 4106a99fe3SHajimu UMEMOTO struct agent const *ap1 = *((struct agent const **)a1); 4206a99fe3SHajimu UMEMOTO struct agent const *ap2 = *((struct agent const **)a2); 4306a99fe3SHajimu UMEMOTO int res; 4406a99fe3SHajimu UMEMOTO 4506a99fe3SHajimu UMEMOTO res = strcmp(ap1->name, ap2->name); 4606a99fe3SHajimu UMEMOTO if (res == 0) { 4706a99fe3SHajimu UMEMOTO if (ap1->type == ap2->type) 4806a99fe3SHajimu UMEMOTO res = 0; 4906a99fe3SHajimu UMEMOTO else if (ap1->type < ap2->type) 5006a99fe3SHajimu UMEMOTO res = -1; 5106a99fe3SHajimu UMEMOTO else 5206a99fe3SHajimu UMEMOTO res = 1; 5306a99fe3SHajimu UMEMOTO } 5406a99fe3SHajimu UMEMOTO 5506a99fe3SHajimu UMEMOTO return (res); 5606a99fe3SHajimu UMEMOTO } 5706a99fe3SHajimu UMEMOTO 5806a99fe3SHajimu UMEMOTO struct agent_table * 5934ecf97aSDag-Erling Smørgrav init_agent_table(void) 6006a99fe3SHajimu UMEMOTO { 6106a99fe3SHajimu UMEMOTO struct agent_table *retval; 6206a99fe3SHajimu UMEMOTO 6306a99fe3SHajimu UMEMOTO TRACE_IN(init_agent_table); 648eeaaffaSDag-Erling Smørgrav retval = calloc(1, sizeof(*retval)); 6506a99fe3SHajimu UMEMOTO assert(retval != NULL); 6606a99fe3SHajimu UMEMOTO 6706a99fe3SHajimu UMEMOTO TRACE_OUT(init_agent_table); 6806a99fe3SHajimu UMEMOTO return (retval); 6906a99fe3SHajimu UMEMOTO } 7006a99fe3SHajimu UMEMOTO 7106a99fe3SHajimu UMEMOTO void 7206a99fe3SHajimu UMEMOTO register_agent(struct agent_table *at, struct agent *a) 7306a99fe3SHajimu UMEMOTO { 7406a99fe3SHajimu UMEMOTO struct agent **new_agents; 7506a99fe3SHajimu UMEMOTO size_t new_agents_num; 7606a99fe3SHajimu UMEMOTO 7706a99fe3SHajimu UMEMOTO TRACE_IN(register_agent); 7806a99fe3SHajimu UMEMOTO assert(at != NULL); 7906a99fe3SHajimu UMEMOTO assert(a != NULL); 8006a99fe3SHajimu UMEMOTO new_agents_num = at->agents_num + 1; 818eeaaffaSDag-Erling Smørgrav new_agents = malloc(sizeof(*new_agents) * 8206a99fe3SHajimu UMEMOTO new_agents_num); 8306a99fe3SHajimu UMEMOTO assert(new_agents != NULL); 8406a99fe3SHajimu UMEMOTO memcpy(new_agents, at->agents, at->agents_num * sizeof(struct agent *)); 8506a99fe3SHajimu UMEMOTO new_agents[new_agents_num - 1] = a; 8606a99fe3SHajimu UMEMOTO qsort(new_agents, new_agents_num, sizeof(struct agent *), 8706a99fe3SHajimu UMEMOTO agent_cmp_func); 8806a99fe3SHajimu UMEMOTO 8906a99fe3SHajimu UMEMOTO free(at->agents); 9006a99fe3SHajimu UMEMOTO at->agents = new_agents; 9106a99fe3SHajimu UMEMOTO at->agents_num = new_agents_num; 9206a99fe3SHajimu UMEMOTO TRACE_OUT(register_agent); 9306a99fe3SHajimu UMEMOTO } 9406a99fe3SHajimu UMEMOTO 9506a99fe3SHajimu UMEMOTO struct agent * 9606a99fe3SHajimu UMEMOTO find_agent(struct agent_table *at, const char *name, enum agent_type type) 9706a99fe3SHajimu UMEMOTO { 9806a99fe3SHajimu UMEMOTO struct agent **res; 9906a99fe3SHajimu UMEMOTO struct agent model, *model_p; 10006a99fe3SHajimu UMEMOTO 10106a99fe3SHajimu UMEMOTO TRACE_IN(find_agent); 10206a99fe3SHajimu UMEMOTO model.name = (char *)name; 10306a99fe3SHajimu UMEMOTO model.type = type; 10406a99fe3SHajimu UMEMOTO model_p = &model; 10506a99fe3SHajimu UMEMOTO res = bsearch(&model_p, at->agents, at->agents_num, 10606a99fe3SHajimu UMEMOTO sizeof(struct agent *), agent_cmp_func); 10706a99fe3SHajimu UMEMOTO 10806a99fe3SHajimu UMEMOTO TRACE_OUT(find_agent); 10906a99fe3SHajimu UMEMOTO return ( res == NULL ? NULL : *res); 11006a99fe3SHajimu UMEMOTO } 11106a99fe3SHajimu UMEMOTO 11206a99fe3SHajimu UMEMOTO void 11306a99fe3SHajimu UMEMOTO destroy_agent_table(struct agent_table *at) 11406a99fe3SHajimu UMEMOTO { 11506a99fe3SHajimu UMEMOTO size_t i; 11606a99fe3SHajimu UMEMOTO 11706a99fe3SHajimu UMEMOTO TRACE_IN(destroy_agent_table); 11806a99fe3SHajimu UMEMOTO assert(at != NULL); 11906a99fe3SHajimu UMEMOTO for (i = 0; i < at->agents_num; ++i) { 12006a99fe3SHajimu UMEMOTO free(at->agents[i]->name); 12106a99fe3SHajimu UMEMOTO free(at->agents[i]); 12206a99fe3SHajimu UMEMOTO } 12306a99fe3SHajimu UMEMOTO 12406a99fe3SHajimu UMEMOTO free(at->agents); 12506a99fe3SHajimu UMEMOTO free(at); 12606a99fe3SHajimu UMEMOTO TRACE_OUT(destroy_agent_table); 12706a99fe3SHajimu UMEMOTO } 128