commands and aliases go from horrible hashtable code to dictionary... try 1
This commit is contained in:
parent
c98390004f
commit
8ac7552983
4 changed files with 48 additions and 190 deletions
|
@ -32,15 +32,6 @@
|
||||||
struct Message;
|
struct Message;
|
||||||
struct Client;
|
struct Client;
|
||||||
|
|
||||||
struct MessageHash
|
|
||||||
{
|
|
||||||
char *cmd;
|
|
||||||
struct Message *msg;
|
|
||||||
struct MessageHash *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MAX_MSG_HASH 387
|
|
||||||
|
|
||||||
extern void parse(struct Client *, char *, char *);
|
extern void parse(struct Client *, char *, char *);
|
||||||
extern void handle_encap(struct Client *, struct Client *,
|
extern void handle_encap(struct Client *, struct Client *,
|
||||||
const char *, int, const char *parv[]);
|
const char *, int, const char *parv[]);
|
||||||
|
@ -49,6 +40,6 @@ extern void mod_add_cmd(struct Message *msg);
|
||||||
extern void mod_del_cmd(struct Message *msg);
|
extern void mod_del_cmd(struct Message *msg);
|
||||||
extern void report_messages(struct Client *);
|
extern void report_messages(struct Client *);
|
||||||
|
|
||||||
extern dlink_list alias_hash_table[MAX_MSG_HASH];
|
extern struct Dictionary *alias_dict;
|
||||||
|
|
||||||
#endif /* INCLUDED_parse_h_h */
|
#endif /* INCLUDED_parse_h_h */
|
||||||
|
|
|
@ -1580,20 +1580,6 @@ conf_set_service_name(void *data)
|
||||||
target_p->flags |= FLAGS_SERVICE;
|
target_p->flags |= FLAGS_SERVICE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
alias_hash(const char *p)
|
|
||||||
{
|
|
||||||
int hash_val = 0;
|
|
||||||
|
|
||||||
while (*p)
|
|
||||||
{
|
|
||||||
hash_val += ((int) (*p) & 0xDF);
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (hash_val % MAX_MSG_HASH);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
conf_begin_alias(struct TopConf *tc)
|
conf_begin_alias(struct TopConf *tc)
|
||||||
{
|
{
|
||||||
|
@ -1611,8 +1597,6 @@ conf_begin_alias(struct TopConf *tc)
|
||||||
static int
|
static int
|
||||||
conf_end_alias(struct TopConf *tc)
|
conf_end_alias(struct TopConf *tc)
|
||||||
{
|
{
|
||||||
int hashval;
|
|
||||||
|
|
||||||
if (yy_alias == NULL)
|
if (yy_alias == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -1634,9 +1618,10 @@ conf_end_alias(struct TopConf *tc)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
hashval = alias_hash(yy_alias->name);
|
if (!alias_dict)
|
||||||
|
alias_dict = irc_dictionary_create(alias_dict);
|
||||||
|
|
||||||
dlinkAddAlloc(yy_alias, &alias_hash_table[hashval]);
|
irc_dictionary_add(alias_dict, yy_alias->name, yy_alias);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
166
src/parse.c
166
src/parse.c
|
@ -1,10 +1,11 @@
|
||||||
/*
|
/*
|
||||||
* ircd-ratbox: A slightly useful ircd.
|
* charybdis: an advanced ircd.
|
||||||
* parse.c: The message parser.
|
* parse.c: The message parser.
|
||||||
*
|
*
|
||||||
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||||
* Copyright (C) 1996-2002 Hybrid Development Team
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||||
* Copyright (C) 2002-2005 ircd-ratbox development team
|
* Copyright (C) 2002-2005 ircd-ratbox development team
|
||||||
|
* Copyright (C) 2007 William Pitcock
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -43,6 +44,9 @@
|
||||||
#include "s_serv.h"
|
#include "s_serv.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
|
|
||||||
|
static struct Dictionary *cmd_dict = NULL;
|
||||||
|
struct Dictionary *alias_dict = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE: parse() should not be called recursively by other functions!
|
* NOTE: parse() should not be called recursively by other functions!
|
||||||
*/
|
*/
|
||||||
|
@ -60,15 +64,9 @@ static void do_alias(struct alias_entry *, struct Client *, char *);
|
||||||
static int handle_command(struct Message *, struct Client *, struct Client *, int, const char**);
|
static int handle_command(struct Message *, struct Client *, struct Client *, int, const char**);
|
||||||
|
|
||||||
static int cmd_hash(const char *p);
|
static int cmd_hash(const char *p);
|
||||||
static struct Message *hash_parse(const char *);
|
|
||||||
static struct alias_entry *alias_parse(const char *);
|
|
||||||
|
|
||||||
struct MessageHash *msg_hash_table[MAX_MSG_HASH];
|
|
||||||
|
|
||||||
static char buffer[1024];
|
static char buffer[1024];
|
||||||
|
|
||||||
dlink_list alias_hash_table[MAX_MSG_HASH];
|
|
||||||
|
|
||||||
/* turn a string into a parc/parv pair */
|
/* turn a string into a parc/parv pair */
|
||||||
|
|
||||||
|
|
||||||
|
@ -220,7 +218,7 @@ parse(struct Client *client_p, char *pbuffer, char *bufend)
|
||||||
if((s = strchr(ch, ' ')))
|
if((s = strchr(ch, ' ')))
|
||||||
*s++ = '\0';
|
*s++ = '\0';
|
||||||
|
|
||||||
mptr = hash_parse(ch);
|
mptr = irc_dictionary_retrieve(cmd_dict, mptr);
|
||||||
|
|
||||||
/* no command or its encap only, error */
|
/* no command or its encap only, error */
|
||||||
if(!mptr || !mptr->cmd)
|
if(!mptr || !mptr->cmd)
|
||||||
|
@ -240,7 +238,7 @@ parse(struct Client *client_p, char *pbuffer, char *bufend)
|
||||||
{
|
{
|
||||||
if (IsPerson(client_p))
|
if (IsPerson(client_p))
|
||||||
{
|
{
|
||||||
struct alias_entry *aptr = alias_parse(ch);
|
struct alias_entry *aptr = irc_dictionary_retrieve(alias_dict, ch);
|
||||||
if (aptr != NULL)
|
if (aptr != NULL)
|
||||||
{
|
{
|
||||||
do_alias(aptr, client_p, s);
|
do_alias(aptr, client_p, s);
|
||||||
|
@ -391,7 +389,7 @@ handle_encap(struct Client *client_p, struct Client *source_p,
|
||||||
|
|
||||||
parv[0] = source_p->name;
|
parv[0] = source_p->name;
|
||||||
|
|
||||||
mptr = hash_parse(command);
|
mptr = irc_dictionary_retrieve(cmd_dict, command);
|
||||||
|
|
||||||
if(mptr == NULL || mptr->cmd == NULL)
|
if(mptr == NULL || mptr->cmd == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -418,7 +416,7 @@ handle_encap(struct Client *client_p, struct Client *source_p,
|
||||||
void
|
void
|
||||||
clear_hash_parse()
|
clear_hash_parse()
|
||||||
{
|
{
|
||||||
memset(msg_hash_table, 0, sizeof(msg_hash_table));
|
cmd_dict = irc_dictionary_create(strcasecmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mod_add_cmd
|
/* mod_add_cmd
|
||||||
|
@ -433,38 +431,18 @@ clear_hash_parse()
|
||||||
void
|
void
|
||||||
mod_add_cmd(struct Message *msg)
|
mod_add_cmd(struct Message *msg)
|
||||||
{
|
{
|
||||||
struct MessageHash *ptr;
|
|
||||||
struct MessageHash *last_ptr = NULL;
|
|
||||||
struct MessageHash *new_ptr;
|
|
||||||
int msgindex;
|
|
||||||
|
|
||||||
s_assert(msg != NULL);
|
s_assert(msg != NULL);
|
||||||
if(msg == NULL)
|
if(msg == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
msgindex = cmd_hash(msg->cmd);
|
if (irc_dictionary_find(cmd_dict, msg->cmd) != NULL)
|
||||||
|
return;
|
||||||
for (ptr = msg_hash_table[msgindex]; ptr; ptr = ptr->next)
|
|
||||||
{
|
|
||||||
if(strcasecmp(msg->cmd, ptr->cmd) == 0)
|
|
||||||
return; /* Its already added */
|
|
||||||
last_ptr = ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
new_ptr = (struct MessageHash *) MyMalloc(sizeof(struct MessageHash));
|
|
||||||
|
|
||||||
new_ptr->next = NULL;
|
|
||||||
DupString(new_ptr->cmd, msg->cmd);
|
|
||||||
new_ptr->msg = msg;
|
|
||||||
|
|
||||||
msg->count = 0;
|
msg->count = 0;
|
||||||
msg->rcount = 0;
|
msg->rcount = 0;
|
||||||
msg->bytes = 0;
|
msg->bytes = 0;
|
||||||
|
|
||||||
if(last_ptr == NULL)
|
irc_dictionary_add(cmd_dict, msg->cmd, msg);
|
||||||
msg_hash_table[msgindex] = new_ptr;
|
|
||||||
else
|
|
||||||
last_ptr->next = new_ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mod_del_cmd
|
/* mod_del_cmd
|
||||||
|
@ -476,101 +454,11 @@ mod_add_cmd(struct Message *msg)
|
||||||
void
|
void
|
||||||
mod_del_cmd(struct Message *msg)
|
mod_del_cmd(struct Message *msg)
|
||||||
{
|
{
|
||||||
struct MessageHash *ptr;
|
|
||||||
struct MessageHash *last_ptr = NULL;
|
|
||||||
int msgindex;
|
|
||||||
|
|
||||||
s_assert(msg != NULL);
|
s_assert(msg != NULL);
|
||||||
if(msg == NULL)
|
if(msg == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
msgindex = cmd_hash(msg->cmd);
|
irc_dictionary_delete(cmd_dict, msg->cmd);
|
||||||
|
|
||||||
for (ptr = msg_hash_table[msgindex]; ptr; ptr = ptr->next)
|
|
||||||
{
|
|
||||||
if(strcasecmp(msg->cmd, ptr->cmd) == 0)
|
|
||||||
{
|
|
||||||
MyFree(ptr->cmd);
|
|
||||||
if(last_ptr != NULL)
|
|
||||||
last_ptr->next = ptr->next;
|
|
||||||
else
|
|
||||||
msg_hash_table[msgindex] = ptr->next;
|
|
||||||
MyFree(ptr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
last_ptr = ptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* hash_parse
|
|
||||||
*
|
|
||||||
* inputs - command name
|
|
||||||
* output - pointer to struct Message
|
|
||||||
* side effects -
|
|
||||||
*/
|
|
||||||
static struct Message *
|
|
||||||
hash_parse(const char *cmd)
|
|
||||||
{
|
|
||||||
struct MessageHash *ptr;
|
|
||||||
int msgindex;
|
|
||||||
|
|
||||||
msgindex = cmd_hash(cmd);
|
|
||||||
|
|
||||||
for (ptr = msg_hash_table[msgindex]; ptr; ptr = ptr->next)
|
|
||||||
{
|
|
||||||
if(strcasecmp(cmd, ptr->cmd) == 0)
|
|
||||||
return (ptr->msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* alias_parse
|
|
||||||
*
|
|
||||||
* inputs - command name
|
|
||||||
* output - pointer to struct Message
|
|
||||||
* side effects -
|
|
||||||
*/
|
|
||||||
static struct alias_entry *
|
|
||||||
alias_parse(const char *cmd)
|
|
||||||
{
|
|
||||||
dlink_node *ptr;
|
|
||||||
int msgindex;
|
|
||||||
|
|
||||||
msgindex = cmd_hash(cmd);
|
|
||||||
|
|
||||||
DLINK_FOREACH(ptr, alias_hash_table[msgindex].head)
|
|
||||||
{
|
|
||||||
struct alias_entry *ent = (struct alias_entry *) ptr->data;
|
|
||||||
|
|
||||||
if(strcasecmp(cmd, ent->name) == 0)
|
|
||||||
return ent;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* hash
|
|
||||||
*
|
|
||||||
* inputs - char string
|
|
||||||
* output - hash index
|
|
||||||
* side effects - NONE
|
|
||||||
*
|
|
||||||
* BUGS - This a HORRIBLE hash function
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
cmd_hash(const char *p)
|
|
||||||
{
|
|
||||||
int hash_val = 0;
|
|
||||||
|
|
||||||
while (*p)
|
|
||||||
{
|
|
||||||
hash_val += ((int) (*p) & 0xDF);
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (hash_val % MAX_MSG_HASH);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -583,33 +471,25 @@ cmd_hash(const char *p)
|
||||||
void
|
void
|
||||||
report_messages(struct Client *source_p)
|
report_messages(struct Client *source_p)
|
||||||
{
|
{
|
||||||
int i;
|
struct DictionaryIter iter;
|
||||||
struct MessageHash *ptr;
|
struct Message *msg;
|
||||||
dlink_node *pptr;
|
struct alias_entry *amsg;
|
||||||
|
|
||||||
for (i = 0; i < MAX_MSG_HASH; i++)
|
IRC_DICTIONARY_FOREACH(msg, &iter, cmd_dict)
|
||||||
{
|
{
|
||||||
for (ptr = msg_hash_table[i]; ptr; ptr = ptr->next)
|
s_assert(msg->cmd != NULL);
|
||||||
{
|
|
||||||
s_assert(ptr->msg != NULL);
|
|
||||||
s_assert(ptr->cmd != NULL);
|
|
||||||
|
|
||||||
sendto_one_numeric(source_p, RPL_STATSCOMMANDS,
|
sendto_one_numeric(source_p, RPL_STATSCOMMANDS,
|
||||||
form_str(RPL_STATSCOMMANDS),
|
form_str(RPL_STATSCOMMANDS),
|
||||||
ptr->cmd, ptr->msg->count,
|
msg->cmd, msg->count,
|
||||||
ptr->msg->bytes, ptr->msg->rcount);
|
msg->bytes, msg->rcount);
|
||||||
}
|
}
|
||||||
|
|
||||||
DLINK_FOREACH(pptr, alias_hash_table[i].head)
|
IRC_DICTIONARY_FOREACH(amsg, &iter, alias_dict)
|
||||||
{
|
{
|
||||||
struct alias_entry *aptr = (struct alias_entry *) pptr->data;
|
s_assert(amsg->name != NULL);
|
||||||
|
|
||||||
s_assert(aptr->name != NULL);
|
|
||||||
|
|
||||||
sendto_one_numeric(source_p, RPL_STATSCOMMANDS,
|
sendto_one_numeric(source_p, RPL_STATSCOMMANDS,
|
||||||
form_str(RPL_STATSCOMMANDS),
|
form_str(RPL_STATSCOMMANDS),
|
||||||
aptr->name, aptr->hits, 0, 0);
|
amsg->name, amsg->hits, 0, 0);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
28
src/s_conf.c
28
src/s_conf.c
|
@ -1199,6 +1199,19 @@ read_conf_files(int cold)
|
||||||
fclose(conf_fbfile_in);
|
fclose(conf_fbfile_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* free an alias{} entry.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
free_alias_cb(struct DictionaryElement *ptr, void *unused)
|
||||||
|
{
|
||||||
|
struct alias_entry *aptr = ptr->data;
|
||||||
|
|
||||||
|
MyFree(aptr->name);
|
||||||
|
MyFree(aptr->target);
|
||||||
|
MyFree(aptr);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* clear_out_old_conf
|
* clear_out_old_conf
|
||||||
*
|
*
|
||||||
|
@ -1269,19 +1282,8 @@ clear_out_old_conf(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove any aliases... -- nenolod */
|
/* remove any aliases... -- nenolod */
|
||||||
for (i = 0; i < MAX_MSG_HASH; i++)
|
irc_dictionary_destroy(alias_dict, free_alias_cb, NULL);
|
||||||
{
|
alias_dict = NULL;
|
||||||
DLINK_FOREACH_SAFE(ptr, next_ptr, alias_hash_table[i].head)
|
|
||||||
{
|
|
||||||
struct alias_entry *aptr = ptr->data;
|
|
||||||
|
|
||||||
MyFree(aptr->name);
|
|
||||||
MyFree(aptr->target);
|
|
||||||
MyFree(aptr);
|
|
||||||
|
|
||||||
dlinkDestroy(ptr, &alias_hash_table[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
destroy_blacklists();
|
destroy_blacklists();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue