added cmd_extscript
authorpk910 <philipp@zoelle1.de>
Mon, 17 Oct 2011 22:45:31 +0000 (00:45 +0200)
committerpk910 <philipp@zoelle1.de>
Mon, 17 Oct 2011 23:28:31 +0000 (01:28 +0200)
Makefile.am
src/bot_NeonServ.c
src/cmd_neonserv.h
src/cmd_neonserv_extscript.c [new file with mode: 0644]

index 2970deebddd1b9ef8a97f0d18e89d9ae22a4f73b..f437aeabc0643722b0bf426bc05df3e59db1d939 100644 (file)
@@ -105,6 +105,7 @@ neonserv_SOURCES = src/version.c \
       src/cmd_neonserv_info.c \
       src/cmd_neonserv_rename.c \
       src/cmd_neonserv_unvisited.c \
+      src/cmd_neonserv_extscript.c \
       src/lib/ini.c
 
 neonserv_LDADD = $(MYSQL_LIBS) $(WINSOCK_LIBS)
index 362d999101469ef22663feccae7442cffda3d27c..9bb2acf6b1e382233d1c931e1934fe2af187515f 100644 (file)
@@ -312,6 +312,7 @@ static const struct default_language_entry msgtab[] = {
     {"NS_INFO_OWNERCHANGE", " from %s to %s on %s"},
     {"NS_RENAME_DONE", "Renamed $b%s$b to $b%s$b."},
     {"NS_RENAME_FAIL", "Failed renaming $b%s$b."},
+    {"NS_FUN_DISABLED", "Fun commands are disabled in %s."},
     {NULL, NULL}
 };
 
@@ -510,6 +511,7 @@ void init_NeonServ() {
     USER_COMMAND("events",       neonserv_cmd_events,    0, "1",                    CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH);
     USER_COMMAND("command",      neonserv_cmd_command,   1, NULL,                   0);
     USER_COMMAND("info",         neonserv_cmd_info,      0, NULL,                   CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN);
+    USER_COMMAND("extscript",    neonserv_cmd_extscript, 0, NULL,                   CMDFLAG_EMPTY_ARGS);
     #undef USER_COMMAND
     
     #define OPER_COMMAND(NAME,FUNCTION,PARAMCOUNT,GACCESS,FLAGS) register_command(BOTID, NAME, FUNCTION, PARAMCOUNT, NULL, GACCESS, FLAGS)
index 658751c8dd822efb6a97b78afc72d4191e4f067f..5042cbb4406d356e30a1d8797728fe90306c5efc 100644 (file)
@@ -63,6 +63,7 @@ CMD_BIND(neonserv_cmd_down);
 CMD_BIND(neonserv_cmd_downall);
 CMD_BIND(neonserv_cmd_emote);
 CMD_BIND(neonserv_cmd_events);
+CMD_BIND(neonserv_cmd_extscript);
 CMD_BIND(neonserv_cmd_giveowner);
 CMD_BIND(neonserv_cmd_god);
 CMD_BIND(neonserv_cmd_help);
diff --git a/src/cmd_neonserv_extscript.c b/src/cmd_neonserv_extscript.c
new file mode 100644 (file)
index 0000000..53b173d
--- /dev/null
@@ -0,0 +1,127 @@
+/* cmd_neonserv_extscript.c - NeonServ v5.1
+ * Copyright (C) 2011  Philipp Kreil (pk910)
+ * 
+ * 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. 
+ */
+
+#include "cmd_neonserv.h"
+
+/*
+* argv[0]      'toys' if it's a toy command (check if toys are enabled)
+* argv[0-*]    script name & parameter patterns
+* argv[argc-1] all arguments passed to the command
+*/
+
+CMD_BIND(neonserv_cmd_extscript) {
+    int i, j;
+    char *args[MAXNUMPARAMS];
+    int argpos = 0;
+    char *next, *curr;
+    char command[1024];
+    int commandpos = 0;
+    char part[MAXLEN];
+    int partpos;
+    int answere_channel = 0;
+    //check first arg
+    if(argc && !stricmp(argv[0], "toys")) {
+        if(!chan) return; //toys are not allowed via query
+        MYSQL_RES *res;
+        MYSQL_ROW row;
+        printf_mysql_query("SELECT `channel_toys` FROM `channels` WHERE `channel_name` = '%s'", escape_string(chan->name));
+        res = mysql_use();
+        row = mysql_fetch_row(res);
+        if(!row || !strcmp(row[0], "0")) {
+            //disabled
+            reply(getTextBot(), user, "NS_FUN_DISABLED", chan->name);
+            return;
+        } else if(!strcmp(row[0], "2"))
+            answere_channel = 1;
+        argc--;
+        argv++;
+    }
+    //parse arguments
+    if(argc < 2) return;
+    curr = argv[argc-1];
+    while(curr) {
+        next = strstr(curr, " ");
+        args[argpos++] = curr;
+        if(next) {
+            *next = '\0';
+            curr = next+1;
+        } else
+            curr = NULL;
+    }
+    //parse command pattern and build command
+    commandpos = sprintf(command, "%s", argv[0]);
+    for(i = 1; i < argc-1; i++) {
+        partpos = 0;
+        if(argv[i][0] == '$') {
+            argv[i]++;
+            if(argv[i][strlen(argv[i])-1] == '-') {
+                argv[i][strlen(argv[i])-1] = '\0';
+                j = atoi(argv[i]);
+                if(j <= argpos)
+                    partpos = sprintf(part, "%s", merge_argv(args, j-1, argpos));
+            } else if((j = atoi(argv[i])) > 0) {
+                if(j <= argpos)
+                    partpos = sprintf(part, "%s", args[j-1]);
+            } else if(!strcmp(argv[i], "c")) {
+                partpos = sprintf(part, "%s", (chan ? chan->name : ""));
+            } else if(!strcmp(argv[i], "n")) {
+                partpos = sprintf(part, "%s", user->nick);
+            } else if(!strcmp(argv[i], "a")) {
+                partpos = sprintf(part, "%s", ((user->flags & USERFLAG_ISAUTHED) ? user->auth : ""));
+            } else if(!strcmp(argv[i], "access")) {
+                if(chan)
+                    partpos = sprintf(part, "%d", getChannelAccess(user, chan, 0));
+            }
+        } else {
+            partpos = sprintf(part, "%s", argv[i]);
+        }
+        //escape shell argument
+        command[commandpos++] = ' ';
+        command[commandpos++] = '\'';
+        for(j = 0; j < partpos; j++) {
+            if(part[j] == '\'') {
+                command[commandpos++] = '\'';
+                command[commandpos++] = '\\';
+                command[commandpos++] = '\'';
+                command[commandpos++] = '\'';
+            } else
+                command[commandpos++] = part[j];
+        }
+        command[commandpos++] = '\'';
+    }
+    command[commandpos] = '\0';
+    //we should now have a valid command
+    FILE *fp;
+    fp = popen(command, "r");
+    if (fp) {
+        char *a;
+        while (fgets(command, 1024, fp) != NULL) {
+            if((a = strchr(command, '\n'))) 
+                *a = '\0';
+            if(answere_channel) {
+                putsock(client, "PRIVMSG %s :%s", chan->name, command);
+            } else
+                reply(getTextBot(), user, "%s", command);
+        }
+        pclose(fp);
+    } else {
+        //error
+        reply(getTextBot(), user, "internal bot error - please contact an administrator!");
+        return;
+    }
+}
+