X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/blobdiff_plain/f42e9cebeea0101a5193ca6ac0c5a7689d49f95b..ac408af6cba5a230c66186d4389e60766c3a74a4:/src/parse.c diff --git a/src/parse.c b/src/parse.c index 6f24d51..37d0c88 100644 --- a/src/parse.c +++ b/src/parse.c @@ -1,10 +1,11 @@ /* - * ircd-ratbox: A slightly useful ircd. + * charybdis: an advanced ircd. * parse.c: The message parser. * * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center * Copyright (C) 1996-2002 Hybrid 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 * it under the terms of the GNU General Public License as published by @@ -30,25 +31,26 @@ #include "channel.h" #include "common.h" #include "hash.h" -#include "irc_string.h" -#include "sprintf_irc.h" +#include "match.h" #include "ircd.h" #include "numeric.h" -#include "s_log.h" +#include "logger.h" #include "s_stats.h" #include "send.h" #include "msg.h" #include "s_conf.h" -#include "memory.h" #include "s_serv.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! */ static char *sender; -/* parv[0] == source, and parv[LAST] == NULL */ +/* parv[0] is not used, and parv[LAST] == NULL */ static char *para[MAXPARA + 2]; static void cancel_clients(struct Client *, struct Client *, char *); @@ -59,16 +61,8 @@ 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 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]; -dlink_list alias_hash_table[MAX_MSG_HASH]; - /* turn a string into a parc/parv pair */ @@ -110,7 +104,7 @@ string_to_array(char *string, char **parv) if(*buf == '\0') return x; } - /* we can go upto parv[MAXPARA], as parv[0] is taken by source */ + /* we can go upto parv[MAXPARA], as parv[0] is skipped */ while (x < MAXPARA); if(*p == ':') @@ -137,7 +131,7 @@ parse(struct Client *client_p, char *pbuffer, char *bufend) struct Message *mptr; s_assert(MyConnect(client_p)); - s_assert(client_p->localClient->fd >= 0); + s_assert(client_p->localClient->F->fd >= 0); if(IsAnyDead(client_p)) return; @@ -167,7 +161,7 @@ parse(struct Client *client_p, char *pbuffer, char *bufend) /* didnt find any matching client, issue a kill */ if(from == NULL) { - ServerStats->is_unpf++; + ServerStats.is_unpf++; remove_unknown(client_p, sender, pbuffer); return; } @@ -177,7 +171,7 @@ parse(struct Client *client_p, char *pbuffer, char *bufend) /* fake direction, hmm. */ if(from->from != client_p) { - ServerStats->is_wrdi++; + ServerStats.is_wrdi++; cancel_clients(client_p, from, pbuffer); return; } @@ -188,7 +182,7 @@ parse(struct Client *client_p, char *pbuffer, char *bufend) if(*ch == '\0') { - ServerStats->is_empt++; + ServerStats.is_empt++; return; } @@ -209,7 +203,7 @@ parse(struct Client *client_p, char *pbuffer, char *bufend) { mptr = NULL; numeric = ch; - ServerStats->is_num++; + ServerStats.is_num++; s = ch + 3; /* I know this is ' ' from above if */ *s++ = '\0'; /* blow away the ' ', and point s to next part */ } @@ -220,7 +214,7 @@ parse(struct Client *client_p, char *pbuffer, char *bufend) if((s = strchr(ch, ' '))) *s++ = '\0'; - mptr = hash_parse(ch); + mptr = irc_dictionary_retrieve(cmd_dict, ch); /* no command or its encap only, error */ if(!mptr || !mptr->cmd) @@ -240,7 +234,7 @@ parse(struct Client *client_p, char *pbuffer, char *bufend) { if (IsPerson(client_p)) { - struct alias_entry *aptr = alias_parse(ch); + struct alias_entry *aptr = irc_dictionary_retrieve(alias_dict, ch); if (aptr != NULL) { do_alias(aptr, client_p, s); @@ -253,7 +247,7 @@ parse(struct Client *client_p, char *pbuffer, char *bufend) me.name, from->name, ch); } } - ServerStats->is_unco++; + ServerStats.is_unco++; return; } @@ -370,7 +364,7 @@ handle_command(struct Message *mptr, struct Client *client_p, ilog(L_SERVER, "Insufficient parameters (%d < %d) for command '%s' from %s.", i, ehandler.min_para, mptr->cmd, client_p->name); - snprintf(squitreason, sizeof squitreason, + rb_snprintf(squitreason, sizeof squitreason, "Insufficient parameters (%d < %d) for command '%s'", i, ehandler.min_para, mptr->cmd); exit_client(client_p, client_p, client_p, squitreason); @@ -391,7 +385,7 @@ handle_encap(struct Client *client_p, struct Client *source_p, parv[0] = source_p->name; - mptr = hash_parse(command); + mptr = irc_dictionary_retrieve(cmd_dict, command); if(mptr == NULL || mptr->cmd == NULL) return; @@ -418,7 +412,7 @@ handle_encap(struct Client *client_p, struct Client *source_p, void clear_hash_parse() { - memset(msg_hash_table, 0, sizeof(msg_hash_table)); + cmd_dict = irc_dictionary_create(strcasecmp); } /* mod_add_cmd @@ -433,38 +427,18 @@ clear_hash_parse() void mod_add_cmd(struct Message *msg) { - struct MessageHash *ptr; - struct MessageHash *last_ptr = NULL; - struct MessageHash *new_ptr; - int msgindex; - s_assert(msg != NULL); if(msg == NULL) return; - msgindex = cmd_hash(msg->cmd); - - 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; + if (irc_dictionary_find(cmd_dict, msg->cmd) != NULL) + return; msg->count = 0; msg->rcount = 0; msg->bytes = 0; - if(last_ptr == NULL) - msg_hash_table[msgindex] = new_ptr; - else - last_ptr->next = new_ptr; + irc_dictionary_add(cmd_dict, msg->cmd, msg); } /* mod_del_cmd @@ -476,101 +450,11 @@ mod_add_cmd(struct Message *msg) void mod_del_cmd(struct Message *msg) { - struct MessageHash *ptr; - struct MessageHash *last_ptr = NULL; - int msgindex; - s_assert(msg != NULL); if(msg == NULL) return; - msgindex = cmd_hash(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); + irc_dictionary_delete(cmd_dict, msg->cmd); } /* @@ -583,33 +467,25 @@ cmd_hash(const char *p) void report_messages(struct Client *source_p) { - int i; - struct MessageHash *ptr; - dlink_node *pptr; + struct DictionaryIter iter; + struct Message *msg; + struct alias_entry *amsg; - for (i = 0; i < MAX_MSG_HASH; i++) + DICTIONARY_FOREACH(msg, &iter, cmd_dict) { - for (ptr = msg_hash_table[i]; ptr; ptr = ptr->next) - { - s_assert(ptr->msg != NULL); - s_assert(ptr->cmd != NULL); - - sendto_one_numeric(source_p, RPL_STATSCOMMANDS, - form_str(RPL_STATSCOMMANDS), - ptr->cmd, ptr->msg->count, - ptr->msg->bytes, ptr->msg->rcount); - } - - DLINK_FOREACH(pptr, alias_hash_table[i].head) - { - struct alias_entry *aptr = (struct alias_entry *) pptr->data; - - s_assert(aptr->name != NULL); + s_assert(msg->cmd != NULL); + sendto_one_numeric(source_p, RPL_STATSCOMMANDS, + form_str(RPL_STATSCOMMANDS), + msg->cmd, msg->count, + msg->bytes, msg->rcount); + } - sendto_one_numeric(source_p, RPL_STATSCOMMANDS, - form_str(RPL_STATSCOMMANDS), - aptr->name, aptr->hits, 0, 0); - } + DICTIONARY_FOREACH(amsg, &iter, alias_dict) + { + s_assert(amsg->name != NULL); + sendto_one_numeric(source_p, RPL_STATSCOMMANDS, + form_str(RPL_STATSCOMMANDS), + amsg->name, amsg->hits, 0, 0); } } @@ -632,7 +508,7 @@ cancel_clients(struct Client *client_p, struct Client *source_p, char *cmd) sendto_realops_snomask(SNO_DEBUG, L_ALL, "Message for %s[%s] from %s", source_p->name, source_p->from->name, - get_server_name(client_p, SHOW_IP)); + client_p->name); } else { @@ -642,7 +518,7 @@ cancel_clients(struct Client *client_p, struct Client *source_p, char *cmd) source_p->username, source_p->host, source_p->from->name, - get_server_name(client_p, SHOW_IP)); + client_p->name); } } @@ -657,7 +533,7 @@ remove_unknown(struct Client *client_p, char *lsender, char *lbuffer) { int slen = strlen(lsender); - /* meepfoo is a nickname (KILL) + /* meepfoo is a nickname (ignore) * #XXXXXXXX is a UID (KILL) * #XX is a SID (SQUIT) * meep.foo is a server (SQUIT) @@ -667,14 +543,14 @@ remove_unknown(struct Client *client_p, char *lsender, char *lbuffer) { sendto_realops_snomask(SNO_DEBUG, L_ALL, "Unknown prefix (%s) from %s, Squitting %s", - lbuffer, get_server_name(client_p, SHOW_IP), lsender); + lbuffer, client_p->name, lsender); sendto_one(client_p, ":%s SQUIT %s :(Unknown prefix (%s) from %s)", get_id(&me, client_p), lsender, lbuffer, client_p->name); } - else + else if(IsDigit(lsender[0])) sendto_one(client_p, ":%s KILL %s :%s (Unknown Client)", get_id(&me, client_p), lsender, me.name); } @@ -684,7 +560,6 @@ remove_unknown(struct Client *client_p, char *lsender, char *lbuffer) /* * * parc number of arguments ('sender' counted as one!) - * parv[0] pointer to 'sender' (may point to empty string) (not used) * parv[1]..parv[parc-1] * pointers to additional parameters, this is a NULL * terminated list (parv[parc] == NULL). @@ -722,10 +597,10 @@ do_numeric(char numeric[], struct Client *client_p, struct Client *source_p, int int tl; /* current length of presently being built string in t */ for (i = 2; i < (parc - 1); i++) { - tl = ircsprintf(t, " %s", parv[i]); + tl = rb_sprintf(t, " %s", parv[i]); t += tl; } - ircsprintf(t, " :%s", parv[parc - 1]); + rb_sprintf(t, " :%s", parv[parc - 1]); } if((target_p = find_client(parv[1])) != NULL) @@ -780,9 +655,9 @@ do_numeric(char numeric[], struct Client *client_p, struct Client *source_p, int return; } else if((chptr = find_channel(parv[1])) != NULL) - sendto_channel_local(ALL_MEMBERS, chptr, - ":%s %s %s %s", - source_p->name, numeric, chptr->chname, buffer); + sendto_channel_flags(client_p, ALL_MEMBERS, source_p, chptr, + "%s %s%s", + numeric, chptr->chname, buffer); } static void do_alias(struct alias_entry *aptr, struct Client *source_p, char *text)