Merge branch 'development'
[NeonServV5.git] / src / modcmd.c
index cbc30afc665e4a014c6e2dfecb5b1ca1dfb89520..8ec2517ef9c640bcbeb3f909a306980c02800d94 100644 (file)
@@ -1,4 +1,4 @@
-/* modcmd.c - NeonServ v5.5
+/* modcmd.c - NeonServ v5.6
  * Copyright (C) 2011-2012  Philipp Kreil (pk910)
  * 
  * This program is free software: you can redistribute it and/or modify
@@ -27,6 +27,8 @@
 #include "mysqlConn.h"
 #include "DBHelper.h"
 #include "EventLogger.h"
+#include "tools.h"
+#include "log.h"
 
 struct trigger_callback {
     int botid;
@@ -112,7 +114,7 @@ static char* get_channel_trigger(int botid, int clientid, struct ChanNode *chan)
         triggerStr[0] = '\0';
     trigger = malloc(sizeof(*trigger));
     if (!trigger) {
-        perror("malloc() failed");
+        printf_log("main", LOG_ERROR, "%s:%d malloc() failed", __FILE__, __LINE__);
         return 0;
     }
     trigger->botid = botid;
@@ -179,6 +181,36 @@ static struct cmd_binding *modcmd_linker_command(struct ClientSocket *client, st
     }
 }
 
+static struct cmd_binding *modcmd_sub_linker_command(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct cmd_binding *cbind, int bind_index, char **args_ptr) {
+    //links subcommands
+    char command[MAXLEN];
+    struct cmd_binding *parent_bind = cbind;
+    char *args = *args_ptr;
+    if(args) {
+        char *subcmd = args;
+        args = strchr(args, ' ');
+        if(args) {
+            *args = '\0';
+            args++;
+        }
+        sprintf(command, "%s %s", parent_bind->cmd, subcmd);
+        if(args)
+            args[-1] = ' ';
+        for(cbind = cmd_binds[bind_index]; cbind; cbind = cbind->next) {
+            if(cbind->botid == client->botid && (cbind->botid || cbind->clientid == client->clientid) && stricmp(cbind->cmd, command) == 0)
+                break;
+        }
+        if(cbind) {
+            *args_ptr = args;
+            if(cbind->func->func == modcmd_linker)
+                parent_bind = modcmd_linker_command(client, textclient, user, cbind, bind_index, args_ptr);
+            else
+                parent_bind = cbind;
+        }
+    }
+    return parent_bind;
+}
+
 static void handle_command(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *message) {
     struct ChanNode *sent_chan = chan;
     if(message[0] == '#') {
@@ -193,7 +225,7 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s
     }
     message = strdup(message);
     int bind_index = get_binds_index(message[0]);
-    char *args = strstr(message, " ");
+    char *args = strchr(message, ' ');
     char *args_buffer = NULL; //we need this to save a possible pointer to a allocation we need to free
     if(args) {
         *args = '\0';
@@ -209,9 +241,9 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s
             if(cbind->func->func == modcmd_linker) {
                 cbind = modcmd_linker_command(client, textclient, user, cbind, bind_index, &args);
                 if(cbind == NULL) break;
-            }
-            if(statistics_enabled)
-                statistics_commands++;
+            } else if(cbind->flags & CMDFLAG_SUB_LINKER)
+                cbind = modcmd_sub_linker_command(client, textclient, user, cbind, bind_index, &args);
+            statistics_commands++;
             total_triggered++;
             cbind->triggered++;
             if((BIND_FLAGS(cbind) & CMDFLAG_FUNCMD)) {
@@ -353,7 +385,7 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s
                 struct command_check_user_cache *data = malloc(sizeof(*data));
                 char **temp_argv = malloc(argc*sizeof(*temp_argv));
                 if (!data || !temp_argv) {
-                    perror("malloc() failed");
+                    printf_log("main", LOG_ERROR, "%s:%d malloc() failed", __FILE__, __LINE__);
                     break;
                 }
                 memcpy(temp_argv, argv, argc*sizeof(*temp_argv));
@@ -603,7 +635,7 @@ int register_command(int botid, char *name, int module_id, cmd_bind_t *func, int
     }
     cmdfunc = malloc(sizeof(*cmdfunc));
     if (!cmdfunc) {
-        perror("malloc() failed");
+        printf_log("main", LOG_ERROR, "%s:%d malloc() failed", __FILE__, __LINE__);
         return 0;
     }
     cmdfunc->botid = botid;
@@ -628,7 +660,7 @@ int set_trigger_callback(int botid, int module_id, trigger_callback_t *func) {
     if(!cb) {
         cb = malloc(sizeof(*cb));
         if (!cb) {
-            perror("malloc() failed");
+            printf_log("main", LOG_ERROR, "%s:%d malloc() failed", __FILE__, __LINE__);
             return 0;
         }
         cb->botid = botid;
@@ -682,7 +714,7 @@ int bind_botwise_cmd_to_function(int botid, int clientid, char *cmd, struct cmd_
     }
     cbind = malloc(sizeof(*cbind));
     if (!cbind) {
-        perror("malloc() failed");
+        printf_log("main", LOG_ERROR, "%s:%d malloc() failed", __FILE__, __LINE__);
         return 0;
     }
     cbind->botid = botid;
@@ -728,7 +760,7 @@ int bind_botwise_cmd_to_command(int botid, int clientid, char *cmd, char *func)
     }
     cbind = malloc(sizeof(*cbind));
     if (!cbind) {
-        perror("malloc() failed");
+        printf_log("main", LOG_ERROR, "%s:%d malloc() failed", __FILE__, __LINE__);
         return 0;
     }
     cbind->botid = botid;
@@ -982,7 +1014,7 @@ void register_command_alias(int botid, char *alias) {
     }
     botalias = malloc(sizeof(*botalias));
     if (!botalias) {
-        perror("malloc() failed");
+        printf_log("main", LOG_ERROR, "%s:%d malloc() failed", __FILE__, __LINE__);
         return;
     }
     botalias->botid = botid;