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)
{
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;
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);
if(last->next == NULL) break;
last_event = last;
}
- free(event->command);
free(event->arguments);
free(event);
}
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();
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
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
{"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}
};
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] == '#') {
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++;
char *arga[MAXNUMPARAMS];
char **argv;
int argc = 0;
+ int escape = 0;
+ int offset = 0;
if(args) {
while(*args) {
//skip leading spaces
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;
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);
}
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() {
#define CMDFLAG_REQUIRED 0x0800
#define CMDFLAG_TEMPONARY_BIND 0x1000
#define CMDFLAG_FUNCMD 0x2000
+#define CMDFLAG_ESCAPE_ARGS 0x4000
struct ClientSocket;
struct UserNode;