1 /* $Id: commands.c,v 1.8 2005/10/06 13:08:28 sys-op Exp $
2  * -------------------------------------------------------
3  * Copyright (c) 2002 Lee Hardy <lee@leeh.co.uk>
4  * -------------------------------------------------------
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  */
15 
16 #include <string.h>
17 #include <stdio.h>
18 #include "commands.h"
19 #include "common.h"
20 
21 static struct CommandHash *cmd_hash[MAX_CMD];
22 static int hash_command(const char *p);
23 static void add_command(const char *p, int cmdvalue);
24 
25 /* the struct for the command hash table */
26 struct CommandHash
27 {
28     const char *cmd;
29     int cmdvalue;
30     struct CommandHash *next;
31 };
32 
33 /* the struct for the table below */
34 struct CommandAddStruct
35 {
36     char *cmd;
37     int mask;
38 };
39 
40 /* cmd_add_table[]
41  *
42  * the table of commands that we need to add at startup, and their
43  * relevant bitmasks, as defined in commands.h
44  */
45 static struct CommandAddStruct cmd_add_table[] =
46 {
47     /* command,		bitmask,	*/
48     { "PING",		CMD_PING,	},
49     { "PONG",		CMD_PONG,	},
50     { "MODE",		CMD_MODE,	},
51     { "NICK",		CMD_NICK,	},
52     { "NOTICE",		CMD_NOTICE,	},
53     { "KICK",		CMD_KICK,	},
54     { "JOIN",		CMD_JOIN,	},
55     { "PART",		CMD_PART,	},
56     { "TOPIC",		CMD_TOPIC,	},
57     { "KILL",		CMD_KILL,	},
58     { "PRIVMSG",	CMD_PRIVMSG,	},
59     { "QUIT",		CMD_QUIT,	},
60     { NULL,		CMD_NONE,	}
61 };
62 
63 /* hash_command()
64  *
65  * hashes a command to a value
66  */
hash_command(const char * p)67 static int hash_command(const char *p)
68 {
69     int hash_val = 0;
70 
71     while(*p)
72     {
73         hash_val += ((int)(*p)&0xDF);
74         p++;
75     }
76 
77     return(hash_val % MAX_CMD);
78 }
79 
80 /* find_command()
81  *
82  * searches for a command in the command hash table
83  */
find_command(char * p)84 int find_command(char *p)
85 {
86     struct CommandHash *ptr;
87     int cmdindex;
88 
89     cmdindex = hash_command(p);
90 
91     for(ptr = cmd_hash[cmdindex]; ptr; ptr = ptr->next)
92     {
93         if(xstrcasecmp(p, ptr->cmd) == 0)
94             return ptr->cmdvalue;
95     }
96 
97     return 0;
98 }
99 
100 /* add_command()
101  *
102  * adds a command to the command hash table
103  */
add_command(const char * cmd,int cmdvalue)104 void add_command(const char *cmd, int cmdvalue)
105 {
106     struct CommandHash *ptr;
107     struct CommandHash *temp_ptr;
108     struct CommandHash *last_ptr = NULL;
109     int cmdindex;
110 
111     cmdindex = hash_command(cmd);
112 
113     /* command exists */
114     for(temp_ptr = cmd_hash[cmdindex]; temp_ptr; temp_ptr = temp_ptr->next)
115     {
116 	if(xstrcasecmp(cmd, temp_ptr->cmd) == 0)
117             return;
118 
119 	last_ptr = temp_ptr;
120     }
121 
122     ptr = (struct CommandHash *)xcalloc(1, sizeof(struct CommandHash));
123 
124     ptr->cmd = cmd;
125     ptr->cmdvalue = cmdvalue;
126 
127     if(last_ptr)
128 	last_ptr->next = ptr;
129     else
130 	cmd_hash[cmdindex] = ptr;
131 }
132 
133 /* setup_commands()
134  *
135  * walks the commandsadd table and adds all the entries
136  */
setup_commands()137 void setup_commands()
138 {
139     int i;
140 
141     for(i = 0; cmd_add_table[i].cmd; i++)
142 	add_command(cmd_add_table[i].cmd, cmd_add_table[i].mask);
143 }
144