From 582559d29a6428cc4db86bb251514ddb1f4066a5 Mon Sep 17 00:00:00 2001 From: pk910 Date: Mon, 15 Aug 2011 05:54:40 +0200 Subject: [PATCH] added get_userauth to WHOHandler.c and continues modcmd --- IRCParser.c | 4 ++ IRCParser.h | 5 ++- WHOHandler.c | 30 +++++++++++++- WHOHandler.h | 4 ++ bot_NeonServ.c | 15 ++++--- modcmd.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++- modcmd.h | 12 +++++- 7 files changed, 166 insertions(+), 12 deletions(-) diff --git a/IRCParser.c b/IRCParser.c index 682cdf0..4280866 100644 --- a/IRCParser.c +++ b/IRCParser.c @@ -366,3 +366,7 @@ void free_parser() { } } +void reply(struct ClientSocket *client, struct UserNode *user, const char *text, ...) { + //following +} + diff --git a/IRCParser.h b/IRCParser.h index ef3600a..fb41e55 100644 --- a/IRCParser.h +++ b/IRCParser.h @@ -2,7 +2,9 @@ #define _IRCParser_h #include "main.h" -#include "ClientSocket.h" + +struct ClientSocket; +struct UserNode; #define IRC_CMD(NAME) int NAME(struct ClientSocket *client, UNUSED_ARG(const char *from), UNUSED_ARG(char **argv), UNUSED_ARG(unsigned int argc)) typedef IRC_CMD(irc_cmd_t); @@ -17,5 +19,6 @@ int parse_lines(struct ClientSocket *client, char *lines, int len); void bot_disconnect(struct ClientSocket *client); void init_parser(); void free_parser(); +void reply(struct ClientSocket *client, struct UserNode *user, const char *text, ...) PRINTF_LIKE(3, 4); #endif \ No newline at end of file diff --git a/WHOHandler.c b/WHOHandler.c index 38e0ce7..994f288 100644 --- a/WHOHandler.c +++ b/WHOHandler.c @@ -7,6 +7,7 @@ #define WHOQUEUETYPE_ISONQUEUE 0x01 #define WHOQUEUETYPE_USERLIST 0x02 +#define WHOQUEUETYPE_USERAUTH 0x04 struct WHOQueueEntry { char type; @@ -14,7 +15,7 @@ struct WHOQueueEntry { struct ChanNode *chan; struct UserNode *user; struct WHOQueueEntry *next; - userlist_callback_t *callback; + void *callback; void *data; }; @@ -68,6 +69,22 @@ void get_userlist(struct ChanNode *chan, userlist_callback_t callback, void *dat putsock(bot, "WHO %s,%d %%tuhnaf,%d", chan->name, entry->type, entry->type); } +void get_userauth(struct UserNode *user, userauth_callback_t callback, void *data) { + struct ClientSocket *bot; + for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) { + if(isUserOnChan(bot->user, chan)) + break; + } + if(bot == NULL) return; + struct WHOQueueEntry* entry = addWHOQueueEntry(bot); + entry->type = WHOQUEUETYPE_ISONQUEUE | WHOQUEUETYPE_USERAUTH; + entry->user = user; + entry->callback = callback; + entry->data = data; + //WHO ".$user->getNick().",".$id." %tuhna,".$id + putsock(bot, "WHO %s,%d %%tuhna,%d", user->nick, entry->type, entry->type); +} + void recv_whohandler_354(struct ClientSocket *client, char **argv, unsigned int argc) { int i; if(argc < 2) return; @@ -115,6 +132,14 @@ void recv_whohandler_354(struct ClientSocket *client, char **argv, unsigned int strcpy(user->auth, argv[6]); user->flags |= USERFLAG_ISAUTHED; } + } else if(type & WHOQUEUETYPE_USERAUTH) { + //:OGN2.OnlineGamesNet.net 354 Skynet 1 pk910 2001:41d0:2:1d3b::babe Skynet pk910 + if(!strcmp(argv[5], "0") && !(entry->user->flags & USERFLAG_ISAUTHED)) { + strcpy(entry->user->auth, argv[5]); + entry->user->flags |= USERFLAG_ISAUTHED; + } + userauth_callback_t *callback = entry->callback; + callback(client, entry->user, entry->data); } } @@ -128,7 +153,8 @@ void recv_whohandler_315(struct ClientSocket *client, char **argv, unsigned int if(type & WHOQUEUETYPE_USERLIST) { //:OGN2.OnlineGamesNet.net 315 skynet #pk910,1 :End of /WHO list. entry->chan->flags |= CHANFLAG_RECEIVED_USERLIST; - entry->callback(client, entry->chan, entry->data); + userlist_callback_t *callback = entry->callback; + callback(client, entry->chan, entry->data); } free(entry); } diff --git a/WHOHandler.h b/WHOHandler.h index aa04f9c..50a611b 100644 --- a/WHOHandler.h +++ b/WHOHandler.h @@ -9,9 +9,13 @@ struct ChanNode; #define USERLIST_CALLBACK(NAME) void NAME(UNUSED_ARG(struct ClientSocket *client), UNUSED_ARG(struct ChanNode *chan), UNUSED_ARG(void *data)) typedef USERLIST_CALLBACK(userlist_callback_t); +#define USERAUTH_CALLBACK(NAME) void NAME(UNUSED_ARG(struct ClientSocket *client), UNUSED_ARG(struct UserNode *user), UNUSED_ARG(void *data)) +typedef USERAUTH_CALLBACK(userauth_callback_t); + void recv_whohandler_354(struct ClientSocket *client, char **argv, unsigned int argc); void recv_whohandler_315(struct ClientSocket *client, char **argv, unsigned int argc); void get_userlist(struct ChanNode *chan, userlist_callback_t callback, void *data); +void get_userauth(struct UserNode *user, userauth_callback_t callback, void *data); void free_whoqueue(); #endif \ No newline at end of file diff --git a/bot_NeonServ.c b/bot_NeonServ.c index 60b5d87..6d7f44c 100644 --- a/bot_NeonServ.c +++ b/bot_NeonServ.c @@ -45,7 +45,7 @@ static void neonserv_trigger_callback(struct ChanNode *chan, char *trigger) { static void start_bots() { struct UserNode *user; struct ClientSocket *client; - MYSQL_RES *res; + MYSQL_RES *res, *res2; MYSQL_ROW row; printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `whoisbot`, `id` FROM `bots` WHERE `botclass` = '%s' AND `active` = '1'", escape_string(CLASSNAME)); @@ -62,20 +62,23 @@ static void start_bots() { client->botid = BOTID; client->clientid = atoi(row[7]); connect_socket(client); - + printf_mysql_query("SELECT `command`, `function`, `parameters`, `global_access` FROM `bot_binds` WHERE `botid` = '%d'", client->clientid); + res2 = mysql_use(); + while ((row = mysql_fetch_row(res2)) != NULL) { + + } } } void init_NeonServ() { check_mysql(); - start_bots(); - bind_bot_ready(neonserv_bot_ready); - set_trigger_callback(BOTID, neonserv_trigger_callback); - register_command(BOTID, "users", neonserv_cmd_users); register_command(BOTID, "modes", neonserv_cmd_modes); + start_bots(); + bind_bot_ready(neonserv_bot_ready); + set_trigger_callback(BOTID, neonserv_trigger_callback); bind_cmd_to_command(BOTID, "users", "users"); bind_cmd_to_command(BOTID, "modes", "modes"); } diff --git a/modcmd.c b/modcmd.c index 6db797b..07820af 100644 --- a/modcmd.c +++ b/modcmd.c @@ -13,6 +13,16 @@ struct trigger_callback { struct trigger_callback *next; }; +struct command_check_user_cache { + struct ClientSocket *client; + struct UserNode *user; + struct ChanNode *chan; + char **argv; + int argc; + char *message; + struct cmd_binding *cbind; +}; + static struct cmd_binding **cmd_binds; static struct cmd_function *cmd_functions = NULL; static struct trigger_callback *trigger_callbacks = NULL; @@ -61,6 +71,20 @@ static char* get_channel_trigger(int botid, struct ChanNode *chan) { return trigger->trigger; } +static USERAUTH_CALLBACK(command_checked_auth) { + struct command_check_user_cache *cache = data; + int execute_cmd = 1; + if((cbind->func->flags & CMDFLAG_REQUIRE_AUTH) && !(user->flags & USERFLAG_ISAUTHED)) { + //AUTH_REQUIRED + execute_cmd = 0; + } + if(execute_cmd) { + cbind->func->func(cache->client, user, cache->chan, cache->argv, cache->argc); + } + free(cache->message); + free(cache); +} + static void handle_command(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *message) { if(message[0] == '#') { char *chanName = message; @@ -72,6 +96,7 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s if(chan2) chan = chan2; } + message = strdup(message); int bind_index = get_binds_index(message[0]); char *args = strstr(message, " "); if(args) { @@ -106,10 +131,79 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s chan = chan2; } } + if(cbind->func->parameters) { + //userdefined parameters... + char *uarga[MAXNUMPARAMS]; + char params[strlen(cbind->func->parameters)+1]; + strcpy(params, cbind->func->parameters); + int uargpos = 0, argi, allargs = 0; + char *ppos = params, *prev_ppos = params; + while(ppos = strstr(ppos, " ")) { + ppos = '\0'; + if(prev_ppos[0] == '%') { + prev_ppos++; + if(prev_ppos[strlen(prev_ppos)-1] == '-') { + allargs = 1; + prev_ppos[strlen(prev_ppos)-1] = '\0'; + } else + allargs = 0; + if((argi = atoi(prev_ppos)) > 0) { + if(argi <= argc) continue; + uarga[uargpos++] = argv[argi-1] + if(allargs) { + for(;argi < argc; argi++) + uarga[uargpos++] = argv[argi-1] + } + } else if(!strcmp(prev_ppos, "c")) + uarga[uargpos++] = (chan ? chan->name : NULL); + else if(!strcmp(prev_ppos, "n")) + uarga[uargpos++] = user->nick; + } else { + uarga[uargpos++] = prev_ppos; + } + ppos = ' '; + ppos++; + prev_ppos = ppos; + } + argv = uarga; + argc = uargpos; + } + if(argc < cbind->func->paramcount) { + //LESS_PARAM_COUNT + break; + } + if((cbind->func->flags & CMDFLAG_REQUIRE_CHAN) && !chan) { + //CHAN_REQUIRED + break; + } + if((cbind->func->flags & CMDFLAG_CHECK_AUTH) && !(user->flags & USERFLAG_ISAUTHED)) { + //check auth... + struct command_check_user_cache *data = malloc(sizeof(*data)); + char **temp_argv = malloc(argc*sizeof(*temp_argv)); + if (!data || !temp_argv) { + perror("malloc() failed"); + break; + } + memcpy(temp_argv, argv, argc*sizeof(*temp_argv)); + data->argv = temp_argv; + data->argc = argc; + data->client = client; + data->user = user; + data->chan = chan; + data->message = message; + data->cbind = cbind; + get_userauth(user, command_checked_auth, data) + return; + } + if((cbind->func->flags & CMDFLAG_REQUIRE_AUTH) && !(user->flags & USERFLAG_ISAUTHED)) { + //AUTH_REQUIRED + break; + } cbind->func->func(client, user, chan, argv, argc); - return; + break; } } + free(message); } static void got_chanmsg(struct UserNode *user, struct ChanNode *chan, char *message) { @@ -146,7 +240,7 @@ static void got_privmsg(struct UserNode *user, struct UserNode *target, char *me } } -int register_command(int botid, char *name, cmd_bind_t *func) { +int register_command(int botid, char *name, cmd_bind_t *func, int paramcount, unsigned int flags) { struct cmd_function *cmdfunc; for(cmdfunc = cmd_functions; cmdfunc; cmdfunc = cmdfunc->next) { if(cmdfunc->botid == botid && strcmp(cmdfunc->name, name) == 0) @@ -160,6 +254,8 @@ int register_command(int botid, char *name, cmd_bind_t *func) { cmdfunc->botid = botid; cmdfunc->name = strdup(name); cmdfunc->func = func; + cmdfunc->flags = 0; + cmdfunc->paramcount = paramcount; cmdfunc->next = cmd_functions; cmd_functions = cmdfunc; return 1; @@ -212,6 +308,8 @@ int bind_cmd_to_function(int botid, char *cmd, struct cmd_function *func) { cbind->botid = botid; cbind->cmd = strdup(cmd); cbind->func = func; + cbind->parameters = NULL; + cbind->flags = 0; cbind->next = cmd_binds[bind_index]; cmd_binds[bind_index] = cbind; return 1; @@ -239,6 +337,8 @@ int bind_cmd_to_command(int botid, char *cmd, char *func) { cbind->cmd = strdup(cmd); cbind->func = cmdfunc; cbind->next = cmd_binds[bind_index]; + cbind->parameters = NULL; + cbind->flags = 0; cmd_binds[bind_index] = cbind; return 1; } @@ -253,6 +353,8 @@ int unbind_cmd(int botid, char *cmd) { else cmd_binds[bind_index] = cbind->next; free(cbind->cmd); + if(cbind->parameters) + free(cbind->parameters); free(cbind); return 1; } else @@ -274,6 +376,8 @@ void free_modcmd() { for(cbind = cmd_binds[i]; cbind; cbind = next) { next = cbind->next; free(cbind->cmd); + if(cbind->parameters) + free(cbind->parameters); free(cbind); } } diff --git a/modcmd.h b/modcmd.h index 6f9ff85..5c76a6a 100644 --- a/modcmd.h +++ b/modcmd.h @@ -2,6 +2,12 @@ #define _modcmd_h #include "main.h" +#define CMDFLAG_REQUIRE_CHAN 0x01 +#define CMDFLAG_REQUIRE_AUTH 0x02 +#define CMDFLAG_REQUIRE_GOD 0x04 +#define CMDFLAG_CHECK_AUTH 0x08 +#define CMDFLAG_OVERRIDE_ACCESS 0x10 + struct ClientSocket; struct UserNode; struct ChanNode; @@ -14,6 +20,8 @@ struct cmd_function { char *name; int botid; cmd_bind_t *func; + unsigned int flags; + int paramcount; struct cmd_function *next; }; @@ -22,6 +30,8 @@ struct cmd_binding { char *cmd; int botid; struct cmd_function *func; + unsigned int flags; + char *parameters; struct cmd_binding *next; }; @@ -36,7 +46,7 @@ struct trigger_cache { void init_modcmd(); void free_modcmd(); struct ClientSocket* get_prefered_bot(int botid); -int register_command(int botid, char *name, cmd_bind_t *func); +int register_command(int botid, char *name, cmd_bind_t *func, int paramcount, unsigned int flags); int set_trigger_callback(int botid, trigger_callback_t *func); int changeChannelTrigger(int botid, struct ChanNode *chan, char *new_trigger); int bind_cmd_to_function(int botid, char *cmd, struct cmd_function *func); -- 2.20.1