diff --git a/Changes b/Changes index 81a6c8779..7ab633066 100644 --- a/Changes +++ b/Changes @@ -339,3 +339,4 @@ - Changed license of m_dummy.c (dummy module, skeleton), so people can do closed source modules. - Moved m_setname to a .so +- Started work on the new improved command hashing system diff --git a/include/h.h b/include/h.h index 4952a5a54..6c0530439 100644 --- a/include/h.h +++ b/include/h.h @@ -130,7 +130,7 @@ extern int R_do_socks, R_good_socks, R_no_socks; #endif #endif -extern inline aCommand *find_Command(char *cmd, int token); +extern inline aCommand *find_Command(char *cmd, short token, int flags); extern aChannel *find_channel PROTO((char *, aChannel *)); extern Member *find_member_link PROTO((Member *, aClient *)); extern void remove_user_from_channel PROTO((aClient *, aChannel *)); @@ -400,7 +400,7 @@ extern char *inetntop(int af, const void *in, char *local_dummy, */ extern aCommand *CommandHash[256]; void init_CommandHash(void); -void add_Command_backend(char *cmd, int (*func)(), unsigned char parameters, unsigned char token); +void add_Command_backend(char *cmd, int (*func)(), unsigned char parameters, unsigned char token, int flags); void add_Command(char *cmd, char *token, int (*func)(), unsigned char parameters); void add_Command_to_list(aCommand *item, aCommand **list); aCommand *del_Command_from_list(aCommand *item, aCommand **list); diff --git a/include/struct.h b/include/struct.h index c58fad67e..66f5d6664 100644 --- a/include/struct.h +++ b/include/struct.h @@ -722,11 +722,16 @@ struct Server { #endif }; +#define M_UNREGISTERED 0x0001 +#define M_USER 0x0002 +#define M_SERVER 0x0004 + struct Command { aCommand *next; aCommand *prev; char *cmd; int (*func) (); + int flags; unsigned int count; unsigned parameters : 5; unsigned token : 1; diff --git a/src/modules/m_setname.c b/src/modules/m_setname.c new file mode 100644 index 000000000..abe5db36a --- /dev/null +++ b/src/modules/m_setname.c @@ -0,0 +1,147 @@ +/* + * IRC - Internet Relay Chat, src/modules/m_setname.c + * (c) 1999-2001 Dominick Meglio (codemastr) + * + * See file AUTHORS in IRC package for additional names of + * the programmers. + * + * 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 + * the Free Software Foundation; either version 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include "config.h" +#include "struct.h" +#include "common.h" +#include "sys.h" +#include "numeric.h" +#include "msg.h" +#include "channel.h" +#include "userload.h" +#include +#include +#include +#include +#include +#ifdef _WIN32 +#include +#endif +#include +#include "h.h" +#ifdef STRIPBADWORDS +#include "badwords.h" +#endif +#ifdef _WIN32 +#include "version.h" +#endif + +DLLFUNC int m_setname(aClient *cptr, aClient *sptr, int parc, char *parv[]); + +/* Place includes here */ +#define MSG_SETNAME "SETNAME" /* setname */ +#define TOK_SETNAME "AE" + + +ModuleInfo m_setname_info + = { + 1, + "setname", /* Name of module */ + "$Id$", /* Version */ + "command /setname", /* Short description of module */ + NULL, /* Pointer to our dlopen() return value */ + NULL + }; + +/* + * The purpose of these ifdefs, are that we can "static" link the ircd if we + * want to +*/ + +#ifdef DYNAMIC_LINKING +DLLFUNC void mod_init(void) +#else +void m_setname_init(void) +#endif +{ + /* extern variable to export m_setname_info to temporary + ModuleInfo *modulebuffer; + the module_load() will use this to add to the modules linked + list + */ + module_buffer = &m_setname_info; + /* + * We call our add_Command crap here + */ + add_Command(MSG_SETNAME, TOK_SETNAME, m_setname, 1); +} + +#ifdef DYNAMIC_LINKING +DLLFUNC void mod_unload(void) +#else +void m_setname_unload(void) +#endif +{ + if (del_Command(MSG_SETNAME, TOK_SETNAME, m_setname) < 0) + { + sendto_realops("Failed to delete commands when unloading %s", + m_setname_info.name); + } +} + +/* m_setname - 12/05/1999 - Stskeeps + * :prefix SETNAME :gecos + * parv[0] - sender + * parv[1] - gecos + * D: This will set your gecos to be (like (/setname :The lonely wanderer)) + yes it is experimental but anyways ;P + FREEDOM TO THE USERS! ;) +*/ +DLLFUNC int m_setname(aClient *cptr, aClient *sptr, int parc, char *parv[]) { + if (parc < 2) + return; + if (strlen(parv[1]) > (REALLEN)) + { + if (MyConnect(sptr)) + { + sendto_one(sptr, + ":%s NOTICE %s :*** /SetName Error: \"Real names\" may maximum be %i characters of length", + me.name, sptr->name, REALLEN); + } + return 0; + } + if (strlen(parv[1]) < 1) + { + sendto_one(sptr, + ":%s NOTICE %s :Couldn't change realname - Nothing in parameter", + me.name, sptr->name); + return 0; + } + /* set the new name before we check, but don't send to servers unless it is ok */ + else + ircsprintf(sptr->info, "%s", parv[1]); + /* Check for n:lines here too */ + if (!IsAnOper(sptr) && Find_ban(sptr->info, CONF_BAN_REALNAME)) + { + int xx; + xx = + exit_client(cptr, sptr, &me, + "Your GECOS (real name) is banned from this server"); + return xx; + } + sendto_serv_butone_token(cptr, sptr->name, MSG_SETNAME, TOK_SETNAME, + ":%s", parv[1]); + if (MyConnect(sptr)) + sendto_one(sptr, + ":%s NOTICE %s :Your \"real name\" is now set to be %s - you have to set it manually to undo it", + me.name, parv[0], parv[1]); + return 0; +} diff --git a/src/packet.c b/src/packet.c index f33326aa9..4cf8bc149 100644 --- a/src/packet.c +++ b/src/packet.c @@ -43,6 +43,8 @@ aCommand *CommandHash[256]; ** with cptr of "local" variation, which contains all the ** necessary fields (buffer etc..) */ +void add_CommandX(char *cmd, char *token, int (*func)(), unsigned char parameters, int flags) ; + int dopacket(cptr, buffer, length) aClient *cptr; char *buffer; @@ -134,15 +136,15 @@ void init_CommandHash(void) add_Command(MSG_PRIVATE, TOK_PRIVATE, m_private, MAXPARA); add_Command(MSG_NOTICE, TOK_NOTICE, m_notice, MAXPARA); add_Command(MSG_MODE, TOK_MODE, m_mode, MAXPARA); - add_Command(MSG_NICK, TOK_NICK, m_nick, MAXPARA); - add_Command(MSG_JOIN, TOK_JOIN, m_join, MAXPARA); + add_CommandX(MSG_NICK, TOK_NICK, m_nick, MAXPARA, M_UNREGISTERED); + add_CommandX(MSG_JOIN, TOK_JOIN, m_join, MAXPARA, M_USER); add_Command(MSG_PING, TOK_PING, m_ping, MAXPARA); add_Command(MSG_WHOIS, TOK_WHOIS, m_whois, MAXPARA); add_Command(MSG_ISON, TOK_ISON, m_ison, 1); - add_Command(MSG_USER, TOK_USER, m_user, MAXPARA); - add_Command(MSG_PONG, TOK_PONG, m_pong, MAXPARA); - add_Command(MSG_PART, TOK_PART, m_part, MAXPARA); - add_Command(MSG_QUIT, TOK_QUIT, m_quit, MAXPARA); + add_CommandX(MSG_USER, TOK_USER, m_user, MAXPARA, M_UNREGISTERED); + add_CommandX(MSG_PONG, TOK_PONG, m_pong, MAXPARA, M_UNREGISTERED); + add_CommandX(MSG_PART, TOK_PART, m_part, MAXPARA, M_USER); + add_CommandX(MSG_QUIT, TOK_QUIT, m_quit, MAXPARA, M_UNREGISTERED); add_Command(MSG_WATCH, TOK_WATCH, m_watch, 1); add_Command(MSG_USERHOST, TOK_USERHOST, m_userhost, 1); add_Command(MSG_SVSNICK, TOK_SVSNICK, m_svsnick, MAXPARA); @@ -154,25 +156,25 @@ void init_CommandHash(void) add_Command(MSG_INVITE, TOK_INVITE, m_invite, MAXPARA); add_Command(MSG_KICK, TOK_KICK, m_kick, MAXPARA); add_Command(MSG_WALLOPS, TOK_WALLOPS, m_wallops, 1); - add_Command(MSG_ERROR, TOK_ERROR, m_error, MAXPARA); + add_CommandX(MSG_ERROR, TOK_ERROR, m_error, MAXPARA, M_UNREGISTERED); add_Command(MSG_KILL, TOK_KILL, m_kill, MAXPARA); - add_Command(MSG_PROTOCTL, TOK_PROTOCTL, m_protoctl, MAXPARA); + add_CommandX(MSG_PROTOCTL, TOK_PROTOCTL, m_protoctl, MAXPARA, M_UNREGISTERED); add_Command(MSG_AWAY, TOK_AWAY, m_away, MAXPARA); - add_Command(MSG_SERVER, TOK_SERVER, m_server, MAXPARA); + add_CommandX(MSG_SERVER, TOK_SERVER, m_server, MAXPARA, M_UNREGISTERED); add_Command(MSG_SQUIT, TOK_SQUIT, m_squit, MAXPARA); add_Command(MSG_WHO, TOK_WHO, m_who, MAXPARA); add_Command(MSG_WHOWAS, TOK_WHOWAS, m_whowas, MAXPARA); add_Command(MSG_LIST, TOK_LIST, m_list, MAXPARA); add_Command(MSG_NAMES, TOK_NAMES, m_names, MAXPARA); add_Command(MSG_TRACE, TOK_TRACE, m_trace, MAXPARA); - add_Command(MSG_PASS, TOK_PASS, m_pass, MAXPARA); + add_CommandX(MSG_PASS, TOK_PASS, m_pass, MAXPARA, M_UNREGISTERED); add_Command(MSG_TIME, TOK_TIME, m_time, MAXPARA); add_Command(MSG_OPER, TOK_OPER, m_oper, MAXPARA); add_Command(MSG_CONNECT, TOK_CONNECT, m_connect, MAXPARA); - add_Command(MSG_VERSION, TOK_VERSION, m_version, MAXPARA); + add_CommandX(MSG_VERSION, TOK_VERSION, m_version, MAXPARA, M_UNREGISTERED); add_Command(MSG_STATS, TOK_STATS, m_stats, MAXPARA); add_Command(MSG_LINKS, TOK_LINKS, m_links, MAXPARA); - add_Command(MSG_ADMIN, TOK_ADMIN, m_admin, MAXPARA); + add_CommandX(MSG_ADMIN, TOK_ADMIN, m_admin, MAXPARA, M_UNREGISTERED); add_Command(MSG_SUMMON, TOK_SUMMON, m_summon, 1); add_Command(MSG_USERS, TOK_USERS, m_users, MAXPARA); add_Command(MSG_SAMODE, TOK_SAMODE, m_samode, MAXPARA); @@ -279,7 +281,7 @@ void init_CommandHash(void) #endif } -void add_Command_backend(char *cmd, int (*func)(), unsigned char parameters, unsigned char token) +void add_Command_backend(char *cmd, int (*func)(), unsigned char parameters, unsigned char token, int flags) { aCommand *newcmd = (aCommand *) MyMalloc(sizeof(aCommand)); @@ -289,6 +291,7 @@ void add_Command_backend(char *cmd, int (*func)(), unsigned char parameters, uns newcmd->parameters = parameters; newcmd->token = token; newcmd->func = func; + newcmd->flags = flags; /* Add in hash with hash value = first byte */ add_Command_to_list(newcmd, &CommandHash[toupper(*cmd)]); @@ -296,8 +299,14 @@ void add_Command_backend(char *cmd, int (*func)(), unsigned char parameters, uns void add_Command(char *cmd, char *token, int (*func)(), unsigned char parameters) { - add_Command_backend(cmd, func, parameters, 0); - add_Command_backend(token, func, parameters, 1); + add_Command_backend(cmd, func, parameters, 0, 0); + add_Command_backend(token, func, parameters, 1, 0); +} + +void add_CommandX(char *cmd, char *token, int (*func)(), unsigned char parameters, int flags) +{ + add_Command_backend(cmd, func, parameters, 0, flags); + add_Command_backend(token, func, parameters, 1, flags); } void add_Command_to_list(aCommand *item, aCommand **list) @@ -377,11 +386,19 @@ int del_Command(char *cmd, char *token, int (*func)()) return i; } -inline aCommand *find_Command(char *cmd, int token) +inline aCommand *find_Command(char *cmd, short token, int flags) { aCommand *p; - for (p = CommandHash[toupper(*cmd)]; p; p = p->next) + for (p = CommandHash[toupper(*cmd)]; p; p = p->next) { + if (p->flags != 0) { + if ((flags & M_UNREGISTERED) && !(p->flags & M_UNREGISTERED)) + continue; + if ((flags & M_USER) && !(p->flags & M_USER)) + continue; + if ((flags & M_SERVER) && !(p->flags & M_SERVER)) + continue; + } if (p->token && token) { if (!strcmp(p->cmd, cmd)) @@ -390,5 +407,6 @@ inline aCommand *find_Command(char *cmd, int token) else if (!match(p->cmd, cmd)) return (p); + } return NULL; } diff --git a/src/parse.c b/src/parse.c index 549b5ef1c..6356894fc 100644 --- a/src/parse.c +++ b/src/parse.c @@ -324,10 +324,16 @@ int parse(cptr, buffer, bufend) } else { + int flags = 0; if (s) *s++ = '\0'; - - cmptr = find_Command(ch, IsServer(cptr) ? 1 : 0); + if (!IsRegistered(cptr)) + flags |= M_UNREGISTERED; + if (IsPerson(cptr)) + flags |= M_USER; + if (IsServer(cptr)) + flags |= M_SERVER; + cmptr = find_Command(ch, IsServer(cptr) ? 1 : 0, flags); if (!cmptr) { @@ -342,6 +348,11 @@ int parse(cptr, buffer, bufend) ** Hm, when is the buffer empty -- if a command ** code has been found ?? -Armin */ + if (!IsRegistered(cptr)) { + sendto_one(from, ":%s %d %s :You have not registered", + me.name, ERR_NOTREGISTERED, ch); + return -1; + } if (buffer[0] != '\0') { if (IsPerson(from)) @@ -422,7 +433,7 @@ int parse(cptr, buffer, bufend) && (cmptr->func != m_pong)) return -4; - if ((!IsRegistered(cptr)) && +/* if ((!IsRegistered(cptr)) && (((cmptr->func != m_user) && (cmptr->func != m_nick) && (cmptr->func != m_server) && (cmptr->func != m_pong) && (cmptr->func != m_pass) && (cmptr->func != m_quit) && @@ -430,11 +441,8 @@ int parse(cptr, buffer, bufend) (cmptr->func != m_admin) && (cmptr->func != m_version) ))) { - sendto_one(from, ":%s %d %s :You have not registered", - me.name, ERR_NOTREGISTERED, ch); - return -1; } - +*/ cmptr->count++; if (IsRegisteredUser(cptr) && cmptr->func == m_private) from->user->last = TStime();