added possibility for subcommands
authorpk910 <philipp@zoelle1.de>
Thu, 10 Nov 2011 13:57:54 +0000 (14:57 +0100)
committerpk910 <philipp@zoelle1.de>
Thu, 10 Nov 2011 14:18:13 +0000 (15:18 +0100)
src/EventLogger.c
src/EventLogger.h
src/commands.c
src/modcmd.c
src/modcmd.h

index 097ac955c965971e5757ff21fee4a59bb2e1e130..a71722eb6ec03c8158afd224b0c4b541f41c3704 100644 (file)
@@ -24,7 +24,7 @@
 
 static struct Event *first_event = NULL, *last_event = NULL;
 
-struct Event *createEvent(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *command, char **args, int argc, int flags) {
+struct Event *createEvent(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct cmd_binding *command, char **args, int argc, int flags) {
     struct Event *event = malloc(sizeof(*event));
     if (!event)
     {
@@ -35,7 +35,7 @@ struct Event *createEvent(struct ClientSocket *client, struct UserNode *user, st
     event->user = user;
     event->chan = chan;
     event->event_time = time(0);
-    event->command = strdup(command);
+    event->command = command;
     char arguments[MAXLEN];
     int argpos = 0;
     int i;
@@ -57,7 +57,7 @@ struct Event *createEvent(struct ClientSocket *client, struct UserNode *user, st
 
 void logEvent(struct Event *event) {
     char fullcmd[MAXLEN];
-    sprintf(fullcmd, "%s %s", event->command, event->arguments);
+    sprintf(fullcmd, "%s %s", event->command->func->name, event->arguments);
     if((event->flags & CMDFLAG_LOG) && event->chan) {
         char *auth = ((event->user->flags & USERFLAG_ISAUTHED) ? event->user->auth : "*");
         loadChannelSettings(event->chan);
@@ -92,7 +92,6 @@ static void destroyEvent(struct Event *event) {
             if(last->next == NULL) break;
         last_event = last;
     }
-    free(event->command);
     free(event->arguments);
     free(event);
 }
index 3bc730a69b522a2afd5563b307099fb0495375d3..b28c2a5fe20f2ff38e16eaa1266fc5082310bdba 100644 (file)
 struct ClientSocket;
 struct UserNode;
 struct ChanNode;
+struct cmd_binding;
 
 struct Event {
     struct ClientSocket *client;
     struct UserNode *user;
     struct ChanNode *chan;
     time_t event_time;
-    char *command;
+    struct cmd_binding *command;
     char *arguments;
     unsigned int flags; /* defined in modcmd.h */
     
     struct Event *next;
 };
 
-struct Event *createEvent(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *command, char **args, int argc, int flags);
+struct Event *createEvent(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct cmd_binding *command, char **args, int argc, int flags);
 void logEvent(struct Event *event);
 void destroyEvents();
 
index 07adfac104709cdb19973c49ed2d607ce891ad0b..cece07df07e5d5585372f0626608a89cb09b1732 100644 (file)
@@ -29,7 +29,7 @@ void register_commands() {
     USER_COMMAND("version",      global_cmd_version,   0, NULL,                   0);
     USER_COMMAND("netinfo",      global_cmd_netinfo,   0, NULL,                   0);
     USER_COMMAND("commands",     global_cmd_commands,  0, NULL,                   0);
-    USER_COMMAND("command",      global_cmd_command,   1, NULL,                   0);
+    USER_COMMAND("command",      global_cmd_command,   1, NULL,                   CMDFLAG_ESCAPE_ARGS);
     USER_COMMAND("staff",        global_cmd_staff,     0, NULL,                   0);
     USER_COMMAND("motd",         global_cmd_motd,      0, NULL,                   0);
     #undef USER_COMMAND
@@ -44,8 +44,8 @@ void register_commands() {
     OPER_COMMAND("raw",          global_cmd_raw,       1,     800,  CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
     OPER_COMMAND("god",          global_cmd_god,       0,     1,    CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
     OPER_COMMAND("reloadlang",   global_cmd_reloadlang,1,     500,  CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
-    OPER_COMMAND("bind",         global_cmd_bind,      2,     900,  CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG | CMDFLAG_REQUIRED);
-    OPER_COMMAND("unbind",       global_cmd_unbind,    1,     900,  CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG | CMDFLAG_REQUIRED);
+    OPER_COMMAND("bind",         global_cmd_bind,      2,     900,  CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG | CMDFLAG_REQUIRED | CMDFLAG_ESCAPE_ARGS);
+    OPER_COMMAND("unbind",       global_cmd_unbind,    1,     900,  CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG | CMDFLAG_REQUIRED | CMDFLAG_ESCAPE_ARGS);
     OPER_COMMAND("setaccess",    global_cmd_setaccess, 2,     1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG);
     OPER_COMMAND("bots",         global_cmd_bots,      0,     1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
     #undef OPER_COMMAND
index 931c508df83daaca0d0751e056effa8720d0c28c..f6ff75fca8e6fffb7e6b31cbdb54c96eb1905b1f 100644 (file)
@@ -68,6 +68,7 @@ static const struct default_language_entry msgtab[] = {
     {"MODCMD_PRIVILEGED",       "$b%s$b is a privileged command."}, /* {ARGS: "god"} */
     {"MODCMD_PUBCMD",           "Public commands in $b%s$b are restricted."}, /* {ARGS: "#TestChan"} */
     {"MODCMD_ACCESS_DENIED",    "Access denied."},
+    {"MODCMD_SUBCOMMANDS",      "Subcommands of %s: %s"}, /* {ARGS: "bot", "ADD, DEL, EDIT"} */
     {NULL, NULL}
 };
 
@@ -132,6 +133,11 @@ static USERAUTH_CALLBACK(command_checked_auth) {
     free(cache);
 }
 
+static CMD_BIND(modcmd_linker) {
+    //fake command for subcommands
+    //just empty
+}
+
 static void handle_command(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *message) {
     struct ChanNode *sent_chan = chan;
     if(message[0] == '#') {
@@ -155,6 +161,38 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s
     struct cmd_binding *cbind;
     for(cbind = cmd_binds[bind_index]; cbind; cbind = cbind->next) {
         if(cbind->botid == client->botid && stricmp(cbind->cmd, message) == 0) {
+            if(cbind->func->func == modcmd_linker) {
+                //links subcommands
+                char command[MAXLEN];
+                struct cmd_binding *parent_bind = cbind;
+                if(args) {
+                    char *subcmd = args;
+                    args = strstr(args, " ");
+                    if(args) {
+                        *args = '\0';
+                        args++;
+                    }
+                    sprintf(command, "%s %s", parent_bind->cmd, subcmd);
+                    for(cbind = cmd_binds[bind_index]; cbind; cbind = cbind->next) {
+                        if(cbind->botid == client->botid && stricmp(cbind->cmd, command) == 0)
+                            break;
+                    }
+                    if(!cbind)
+                        break;
+                } else {
+                    //list all sub commands
+                    int commandlen = sprintf(command, "%s ", parent_bind->cmd);
+                    char subcommands[MAXLEN];
+                    int subcompos = 0;
+                    for(cbind = cmd_binds[bind_index]; cbind; cbind = cbind->next) {
+                        if(cbind->botid == client->botid && stricmplen(cbind->cmd, command, commandlen) == 0) {
+                            subcompos += sprintf(subcommands + subcompos, (subcompos ? ", %s" : "%s"), cbind->cmd + commandlen);
+                        }
+                    }
+                    reply(tmp_text_client, user, "MODCMD_SUBCOMMANDS", parent_bind->cmd, subcommands);
+                    break;
+                }
+            }
             if(statistics_enabled)
                 statistics_commands++;
             total_triggered++;
@@ -170,6 +208,8 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s
             char *arga[MAXNUMPARAMS];
             char **argv;
             int argc = 0;
+            int escape = 0;
+            int offset = 0;
             if(args) {
                 while(*args) {
                     //skip leading spaces
@@ -178,8 +218,22 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s
                     arga[argc++] = args;
                     if (argc >= MAXNUMPARAMS)
                         break;
-                    while (*args != ' ' && *args)
+                    while ((escape || *args != ' ') && *args) {
+                        if((cbind->func->flags & CMDFLAG_ESCAPE_ARGS) && *args == '\\') {
+                            escape = 1;
+                            offset++;
+                        } else if(escape)
+                            escape = 0;
+                        if(!escape && offset) {
+                            args[0 - offset] = args[0];
+                        }
                         args++;
+                        
+                    }
+                    if(offset) {
+                        args[0-offset] = '\0';
+                        offset = 0;
+                    }
                 }
             }
             argv = arga;
@@ -428,7 +482,7 @@ static void handle_command_async(struct ClientSocket *client, struct UserNode *u
         reply(tmp_text_client, user, "MODCMD_PRIVILEGED", cbind->cmd);
         return;
     }
-    struct Event *event = createEvent(client, user, chan, cbind->func->name, argv, argc, eventflags);
+    struct Event *event = createEvent(client, user, chan, cbind, argv, argc, eventflags);
     cbind->func->func(client, user, chan, argv, argc, event);
 }
 
@@ -645,6 +699,7 @@ void init_modcmd() {
     bind_chanmsg(got_chanmsg);
     bind_privmsg(got_privmsg);
     register_default_language_table(msgtab);
+    register_command(0, "linker", modcmd_linker, 0, 0, 0, 0); //fake command for subcommands
 }
 
 void free_modcmd() {
index e84453788700b65625516043d842617adac68330..44333b53e22c9b80075427e66dc8707a132a721d 100644 (file)
@@ -34,6 +34,7 @@
 #define CMDFLAG_REQUIRED                0x0800
 #define CMDFLAG_TEMPONARY_BIND          0x1000
 #define CMDFLAG_FUNCMD                  0x2000
+#define CMDFLAG_ESCAPE_ARGS             0x4000
 
 struct ClientSocket;
 struct UserNode;