added get_userauth to WHOHandler.c and continues modcmd
authorpk910 <philipp@zoelle1.de>
Mon, 15 Aug 2011 03:54:40 +0000 (05:54 +0200)
committerpk910 <philipp@zoelle1.de>
Mon, 15 Aug 2011 03:54:40 +0000 (05:54 +0200)
IRCParser.c
IRCParser.h
WHOHandler.c
WHOHandler.h
bot_NeonServ.c
modcmd.c
modcmd.h

index 682cdf0fc811e170969388315791f34a5ef689d1..4280866facdfd06475c12fa5bf92d358063b3c65 100644 (file)
@@ -366,3 +366,7 @@ void free_parser() {
     }
 }
 
+void reply(struct ClientSocket *client, struct UserNode *user, const char *text, ...) {
+    //following
+}
+
index ef3600a778f248caf7ee4bf0f5ca5f3bf5f2a3bc..fb41e555cd2bdc1946130e3ed4745c9800e5d498 100644 (file)
@@ -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
index 38e0ce745b28a37281d953850816aa014318264a..994f288aa399fc3edfe462bb897679b8a10bd389 100644 (file)
@@ -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);
 }
index aa04f9c6d8588d5e15b822523ebdfefd0240948c..50a611bc75e7e89848f2795b7d90a05654473919 100644 (file)
@@ -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
index 60b5d87d1e4e84d09c028e80be49eade7c8752f5..6d7f44c05dfbf32a170c95c3af0a42888411a4a3 100644 (file)
@@ -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");
 }
index 6db797b257733afaa03b4061cd45054f7c7b06f4..07820afdd7989c836168e732bc6f361d49248b65 100644 (file)
--- 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);
         }
     }
index 6f9ff85d383c826d2afc9db6e77ee316a5d57f27..5c76a6ad5e94b31fd8cb62ecf90cabe88918f788 100644 (file)
--- 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);