X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=src%2Fmodcmd.c;h=3f51761a0f30bbf5e3e47abdc3b82027fcffe0ba;hb=c575e458c6257e75b97884847143b20965a5dfda;hp=5476d5e00a9798fff30610f4f01c2f5f70a4465c;hpb=0f1dc61921eef1db8e404a5a82372e2d1cd55daa;p=NeonServV5.git diff --git a/src/modcmd.c b/src/modcmd.c index 5476d5e..3f51761 100644 --- a/src/modcmd.c +++ b/src/modcmd.c @@ -1,3 +1,19 @@ +/* modcmd.c - NeonServ v5.2 + * 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 "modcmd.h" #include "IRCEvents.h" @@ -25,7 +41,7 @@ struct command_check_user_cache { struct ChanNode *chan, *sent_chan; char **argv; int argc; - char *message; + char *message, *args_buffer; struct cmd_binding *cbind; }; @@ -53,12 +69,16 @@ static int get_binds_index(char first_char) { } struct ClientSocket* get_prefered_bot(int botid) { - struct ClientSocket *client; + struct ClientSocket *client, *lowbot = NULL; for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) { - if(client->botid == botid && (client->flags & SOCKET_FLAG_PREFERRED)) - return client; + if(client->botid == botid) { + if((client->flags & SOCKET_FLAG_PREFERRED)) + return client; + else + lowbot = client; + } } - return NULL; + return lowbot; } static char* get_channel_trigger(int botid, struct ChanNode *chan) { @@ -96,6 +116,9 @@ static USERAUTH_CALLBACK(command_checked_auth) { tmp_text_client = cache->textclient; handle_command_async(cache->client, user, cache->chan, cache->sent_chan, cache->cbind, cache->argv, cache->argc); free(cache->message); + if(cache->args_buffer) + free(cache->args_buffer); + free(cache->argv); free(cache); } @@ -114,6 +137,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_buffer = NULL; //we need this to save a possible pointer to a allocation we need to free if(args) { *args = '\0'; args++; @@ -148,47 +172,69 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s chan = chan2; } } - if(cbind->parameters) { + if(cbind->paramcount) { //userdefined parameters... + args_buffer = malloc(MAXLEN * 2 * sizeof(*args_buffer)); + int args_pos = 0; char *uargs[MAXNUMPARAMS]; int uargc = 0; - char *a,*b = cbind->parameters; + char *b; + int i; int allargs, argi; - do { - a = strstr(b, " "); - if(a) *a = '\0'; + for(i = 0; i < cbind->paramcount; i++) { + b = cbind->parameters[i]; if(b[0] == '%') { b++; if(b[strlen(b)-1] == '-') { + allargs = strlen(b)-1; + b[allargs] = '\0'; + argi = atoi(b); + b[allargs] = '-'; allargs = 1; - b[strlen(b)-1] = '\0'; + } else if(b[strlen(b)-1] == '+') { + allargs = strlen(b)-1; + b[allargs] = '\0'; argi = atoi(b); - b[strlen(b)-1] = '-'; + b[allargs] = '+'; + allargs = 2; } else { allargs = 0; argi = atoi(b); } if(argi > 0) { if(argi <= argc) { - uargs[uargc++] = argv[argi-1]; - if(allargs) { - for(argi++; argi <= argc; argi++) - uargs[uargc++] = argv[argi-1]; + uargs[uargc++] = args_buffer + args_pos; + if(allargs == 0) { + args_pos += sprintf(args_buffer + args_pos, "%s", argv[argi-1]) + 1; + } else if(allargs == 1) { + args_pos += sprintf(args_buffer + args_pos, "%s", argv[argi-1]) + 1; + for(argi++; argi <= argc; argi++) { + uargs[uargc++] = args_buffer + args_pos; + args_pos += sprintf(args_buffer + args_pos, "%s", argv[argi-1]) + 1; + } + } else if(allargs == 2) { + for(;argi <= argc; argi++) { + args_pos += sprintf(args_buffer + args_pos, (allargs ? "%s" : " %s"), argv[argi-1]); + allargs = 0; + } + args_pos++; } + } else if((cbind->func->flags & CMDFLAG_EMPTY_ARGS)) { + uargs[uargc++] = args_buffer + args_pos; + args_buffer[args_pos++] = '\0'; } } else if(!strcmp(b, "c")) { - uargs[uargc++] = (chan ? chan->name : NULL); + uargs[uargc++] = args_buffer + args_pos; + args_pos += sprintf(args_buffer + args_pos, "%s", (chan ? chan->name : "")) + 1; } else if(!strcmp(b, "n")) { - uargs[uargc++] = user->nick; + uargs[uargc++] = args_buffer + args_pos; + args_pos += sprintf(args_buffer + args_pos, "%s", user->nick) + 1; } } else { - uargs[uargc++] = b; + uargs[uargc++] = args_buffer + args_pos; + args_pos += sprintf(args_buffer + args_pos, "%s", b) + 1; } - if(a) { - *a = ' '; - b = a+1; - } - } while(a); + } argv = uargs; argc = uargc; } @@ -216,6 +262,7 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s data->chan = chan; data->sent_chan = sent_chan; data->message = message; + data->args_buffer = args_buffer; data->cbind = cbind; data->textclient = tmp_text_client; get_userauth(user, command_checked_auth, data); @@ -226,6 +273,8 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s } } free(message); + if(args_buffer) + free(args_buffer); } static void handle_command_async(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct ChanNode *sent_chan, struct cmd_binding *cbind, char **argv, int argc) { @@ -468,7 +517,7 @@ 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->paramcount = 0; cbind->global_access = 0; cbind->channel_access = NULL; cbind->flags = 0; @@ -499,7 +548,7 @@ 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->paramcount = 0; cbind->global_access = 0; cbind->channel_access = NULL; cbind->flags = 0; @@ -517,8 +566,11 @@ int unbind_cmd(int botid, char *cmd) { else cmd_binds[bind_index] = cbind->next; free(cbind->cmd); - if(cbind->parameters) - free(cbind->parameters); + if(cbind->paramcount) { + int i; + for(i = 0; i < cbind->paramcount; i++) + free(cbind->parameters[i]); + } free(cbind); return 1; } else @@ -554,8 +606,11 @@ void free_modcmd() { for(cbind = cmd_binds[i]; cbind; cbind = next) { next = cbind->next; free(cbind->cmd); - if(cbind->parameters) - free(cbind->parameters); + if(cbind->paramcount) { + int j; + for(j = 0; j < cbind->paramcount; j++) + free(cbind->parameters[j]); + } if(cbind->channel_access) free(cbind->channel_access); free(cbind); @@ -582,9 +637,19 @@ void bind_set_parameters(int botid, char *cmd, char *parameters) { struct cmd_binding *cbind; for(cbind = cmd_binds[bind_index]; cbind; cbind = cbind->next) { if(cbind->botid == botid && strcmp(cbind->cmd, cmd) == 0) { - if(cbind->parameters) - free(cbind->parameters); - cbind->parameters = strdup(parameters); + if(cbind->paramcount) { + int i; + for(i = 0; i < cbind->paramcount; i++) + free(cbind->parameters[i]); + cbind->paramcount = 0; + } + char *a, *b = parameters; + do { + a = strstr(b, " "); + if(a) *a = '\0'; + cbind->parameters[cbind->paramcount++] = strdup(b); + if(a) b = a+1; + } while(a); return; } }