From 09378f3830dc76e8c02b7a5eb515ae4875395b48 Mon Sep 17 00:00:00 2001 From: pk910 Date: Tue, 18 Oct 2011 00:45:31 +0200 Subject: [PATCH] added cmd_extscript --- Makefile.am | 1 + src/bot_NeonServ.c | 2 + src/cmd_neonserv.h | 1 + src/cmd_neonserv_extscript.c | 127 +++++++++++++++++++++++++++++++++++ 4 files changed, 131 insertions(+) create mode 100644 src/cmd_neonserv_extscript.c diff --git a/Makefile.am b/Makefile.am index 2970dee..f437aea 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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) diff --git a/src/bot_NeonServ.c b/src/bot_NeonServ.c index 362d999..9bb2acf 100644 --- a/src/bot_NeonServ.c +++ b/src/bot_NeonServ.c @@ -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) diff --git a/src/cmd_neonserv.h b/src/cmd_neonserv.h index 658751c..5042cbb 100644 --- a/src/cmd_neonserv.h +++ b/src/cmd_neonserv.h @@ -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 index 0000000..53b173d --- /dev/null +++ b/src/cmd_neonserv_extscript.c @@ -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 . + */ + +#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; + } +} + -- 2.20.1