1 /* $Id: commands.c 448 2010-08-22 09:20:48Z tsaviran $
2 * -------------------------------------------------------
3 * Copyright (C) 2003-2005 Tommi Saviranta <wnd@iki.fi>
4 * (C) 2002 Lee Hardy <lee@leeh.co.uk>
5 * -------------------------------------------------------
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17 #ifdef HAVE_CONFIG_H
18 #include <config.h>
19 #endif /* ifdef HAVE_CONFIG_H */
20
21 #include "commands.h"
22 #include "common.h"
23
24
25
26 static struct commandhash *cmd_hash[MAX_CMD];
27 static int command_hash(const char *p);
28 void command_add(const char *p, int cmdvalue);
29
30
31
32 /* The struct for the command hash table. */
33 struct commandhash {
34 const char *cmd;
35 int cmdvalue;
36 struct commandhash *next;
37 };
38
39
40
41 /* The struct for the table below. */
42 struct commandaddstruct {
43 char *cmd;
44 int mask;
45 };
46
47
48
49 /*
50 * The table of commands that we need to add at startup, and their relevant
51 * bitmasks, as defined in commands.h.
52 */
53 static struct commandaddstruct cmd_add_table[] =
54 {
55 /* command, bitmask, */
56 {"PING", CMD_PING, },
57 {"PONG", CMD_PONG, },
58 {"MODE", CMD_MODE, },
59 {"NICK", CMD_NICK, },
60 {"NOTICE", CMD_NOTICE, },
61 {"KICK", CMD_KICK, },
62 {"JOIN", CMD_JOIN, },
63 {"PART", CMD_PART, },
64 {"TOPIC", CMD_TOPIC, },
65 {"KILL", CMD_KILL, },
66 {"PRIVMSG", CMD_PRIVMSG, },
67 {"QUIT", CMD_QUIT, },
68 {NULL, CMD_NONE, }
69 };
70
71
72
73 /*
74 * Hashes a command to a value.
75 */
76 static int
command_hash(const char * p)77 command_hash(const char *p)
78 {
79 int hash_val = 0;
80
81 while (*p) {
82 hash_val += ((int) (*p) & 0xDF);
83 p++;
84 }
85
86 return (hash_val % MAX_CMD);
87 } /* static int command_hash(const char *p) */
88
89
90
91 /*
92 * Searches for a command in the command hash table.
93 */
94 int
command_find(char * p)95 command_find(char *p)
96 {
97 struct commandhash *ptr;
98 int cmdindex;
99
100 cmdindex = command_hash(p);
101
102 for (ptr = cmd_hash[cmdindex]; ptr; ptr = ptr->next) {
103 if (xstrcasecmp(p, ptr->cmd) == 0) {
104 return ptr->cmdvalue;
105 }
106 }
107
108 return 0;
109 } /* int command_find(char *p) */
110
111
112
113 /*
114 * Adds a command to the command hash table.
115 */
116 void
command_add(const char * cmd,int cmdvalue)117 command_add(const char *cmd, int cmdvalue)
118 {
119 struct commandhash *ptr;
120 struct commandhash *temp_ptr;
121 struct commandhash *last_ptr = NULL;
122 int cmdindex;
123
124 cmdindex = command_hash(cmd);
125
126 /* command exists */
127 for (temp_ptr = cmd_hash[cmdindex]; temp_ptr;
128 temp_ptr = temp_ptr->next) {
129 if (xstrcasecmp(cmd, temp_ptr->cmd) == 0) {
130 return;
131 }
132
133 last_ptr = temp_ptr;
134 }
135
136 ptr = (struct commandhash *) xcalloc(1, sizeof(struct commandhash));
137
138 ptr->cmd = cmd;
139 ptr->cmdvalue = cmdvalue;
140
141 if (last_ptr) {
142 last_ptr->next = ptr;
143 } else {
144 cmd_hash[cmdindex] = ptr;
145 }
146 } /* void command_add(const char *cmd, int cmdvalue) */
147
148
149
150 /*
151 * Walks the commandsadd table and adds all the entries.
152 */
153 void
command_setup(void)154 command_setup(void)
155 {
156 int i;
157
158 for (i = 0; i < MAX_CMD; i++) {
159 cmd_hash[i] = NULL;
160 }
161
162 for (i = 0; cmd_add_table[i].cmd; i++) {
163 command_add(cmd_add_table[i].cmd, cmd_add_table[i].mask);
164 }
165 } /* void command_setup(void) */
166
167
168
169 /*
170 * Free memore allocated by command-hash.
171 */
172 void
command_free(void)173 command_free(void)
174 {
175 int i;
176 struct commandhash *ptr;
177 struct commandhash *next = NULL;
178
179 for (i = 0; i < MAX_CMD; i++) {
180 for (ptr = cmd_hash[i]; ptr != NULL; ptr = next) {
181 next = ptr->next;
182 xfree(ptr);
183 }
184 }
185 } /* void command_free(void) */
186