X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=apps%2Firssi%2Fsrc%2Fcore%2Fcommands.c;fp=apps%2Firssi%2Fsrc%2Fcore%2Fcommands.c;h=0000000000000000000000000000000000000000;hb=72c2de619079457f7a68100eb13385275a424a23;hp=d9dc67af4e9d79b752a80f565aa21446045f8895;hpb=e7b6c157b80152bf9fb9266e6bdd93f9fb0db776;p=runtime.git diff --git a/apps/irssi/src/core/commands.c b/apps/irssi/src/core/commands.c deleted file mode 100644 index d9dc67af..00000000 --- a/apps/irssi/src/core/commands.c +++ /dev/null @@ -1,998 +0,0 @@ -/* - commands.c : irssi - - Copyright (C) 1999-2000 Timo Sirainen - - 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 2 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, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "module.h" -#include "signals.h" -#include "commands.h" -#include "misc.h" -#include "special-vars.h" -#include "window-item-def.h" - -#include "servers.h" -#include "channels.h" - -#include "lib-config/iconfig.h" -#include "settings.h" - -GSList *commands; -char *current_command; - -static int signal_default_command; - -static GSList *alias_runstack; - -COMMAND_REC *command_find(const char *cmd) -{ - GSList *tmp; - - g_return_val_if_fail(cmd != NULL, NULL); - - for (tmp = commands; tmp != NULL; tmp = tmp->next) { - COMMAND_REC *rec = tmp->data; - - if (g_strcasecmp(rec->cmd, cmd) == 0) - return rec; - } - - return NULL; -} - -static COMMAND_MODULE_REC *command_module_find(COMMAND_REC *rec, - const char *module) -{ - GSList *tmp; - - g_return_val_if_fail(rec != NULL, NULL); - g_return_val_if_fail(module != NULL, NULL); - - for (tmp = rec->modules; tmp != NULL; tmp = tmp->next) { - COMMAND_MODULE_REC *rec = tmp->data; - - if (g_strcasecmp(rec->name, module) == 0) - return rec; - } - - return NULL; -} - -static COMMAND_MODULE_REC * -command_module_find_and_remove(COMMAND_REC *rec, SIGNAL_FUNC func) -{ - GSList *tmp, *tmp2; - - g_return_val_if_fail(rec != NULL, NULL); - g_return_val_if_fail(func != NULL, NULL); - - for (tmp = rec->modules; tmp != NULL; tmp = tmp->next) { - COMMAND_MODULE_REC *rec = tmp->data; - - for (tmp2 = rec->callbacks; tmp2 != NULL; tmp2 = tmp2->next) { - COMMAND_CALLBACK_REC *cb = tmp2->data; - - if (cb->func == func) { - rec->callbacks = - g_slist_remove(rec->callbacks, cb); - g_free(cb); - return rec; - } - } - } - - return NULL; -} - -int command_have_sub(const char *command) -{ - GSList *tmp; - int len; - - g_return_val_if_fail(command != NULL, FALSE); - - /* find "command "s */ - len = strlen(command); - for (tmp = commands; tmp != NULL; tmp = tmp->next) { - COMMAND_REC *rec = tmp->data; - - if (g_strncasecmp(rec->cmd, command, len) == 0 && - rec->cmd[len] == ' ') - return TRUE; - } - - return FALSE; -} - -static COMMAND_MODULE_REC * -command_module_get(COMMAND_REC *rec, const char *module, int protocol) -{ - COMMAND_MODULE_REC *modrec; - - g_return_val_if_fail(rec != NULL, NULL); - - modrec = command_module_find(rec, module); - if (modrec == NULL) { - modrec = g_new0(COMMAND_MODULE_REC, 1); - modrec->name = g_strdup(module); - modrec->protocol = -1; - rec->modules = g_slist_append(rec->modules, modrec); - } - - if (protocol != -1) - modrec->protocol = protocol; - - return modrec; -} - -void command_bind_full(const char *module, int priority, const char *cmd, - int protocol, const char *category, SIGNAL_FUNC func, - void *user_data) -{ - COMMAND_REC *rec; - COMMAND_MODULE_REC *modrec; - COMMAND_CALLBACK_REC *cb; - char *str; - - g_return_if_fail(module != NULL); - g_return_if_fail(cmd != NULL); - - rec = command_find(cmd); - if (rec == NULL) { - rec = g_new0(COMMAND_REC, 1); - rec->cmd = g_strdup(cmd); - rec->category = category == NULL ? NULL : g_strdup(category); - commands = g_slist_append(commands, rec); - } - modrec = command_module_get(rec, module, protocol); - - cb = g_new0(COMMAND_CALLBACK_REC, 1); - cb->func = func; - cb->user_data = user_data; - modrec->callbacks = g_slist_append(modrec->callbacks, cb); - - if (func != NULL) { - str = g_strconcat("command ", cmd, NULL); - signal_add_full(module, priority, str, func, user_data); - g_free(str); - } - - signal_emit("commandlist new", 1, rec); -} - -static void command_free(COMMAND_REC *rec) -{ - commands = g_slist_remove(commands, rec); - signal_emit("commandlist remove", 1, rec); - - g_free_not_null(rec->category); - g_strfreev(rec->options); - g_free(rec->cmd); - g_free(rec); -} - -static void command_module_free(COMMAND_MODULE_REC *modrec, COMMAND_REC *rec) -{ - rec->modules = g_slist_remove(rec->modules, modrec); - - g_slist_foreach(modrec->callbacks, (GFunc) g_free, NULL); - g_slist_free(modrec->callbacks); - g_free(modrec->name); - g_free_not_null(modrec->options); - g_free(modrec); -} - -static void command_module_destroy(COMMAND_REC *rec, - COMMAND_MODULE_REC *modrec) -{ - GSList *tmp, *freelist; - - command_module_free(modrec, rec); - - /* command_set_options() might have added module declaration of it's - own without any signals .. check if they're the only ones left - and if so, destroy them. */ - freelist = NULL; - for (tmp = rec->modules; tmp != NULL; tmp = tmp->next) { - COMMAND_MODULE_REC *rec = tmp->data; - - if (rec->callbacks == NULL) - freelist = g_slist_append(freelist, rec); - else { - g_slist_free(freelist); - freelist = NULL; - break; - } - } - - g_slist_foreach(freelist, (GFunc) command_module_free, rec); - g_slist_free(freelist); - - if (rec->modules == NULL) - command_free(rec); -} - -void command_unbind_full(const char *cmd, SIGNAL_FUNC func, void *user_data) -{ - COMMAND_REC *rec; - COMMAND_MODULE_REC *modrec; - char *str; - - g_return_if_fail(cmd != NULL); - g_return_if_fail(func != NULL); - - rec = command_find(cmd); - if (rec != NULL) { - modrec = command_module_find_and_remove(rec, func); - g_return_if_fail(modrec != NULL); - - if (modrec->callbacks == NULL) - command_module_destroy(rec, modrec); - } - - str = g_strconcat("command ", cmd, NULL); - signal_remove_data(str, func, user_data); - g_free(str); -} - -/* Expand `cmd' - returns `cmd' if not found, NULL if more than one - match is found */ -static const char *command_expand(char *cmd) -{ - GSList *tmp; - const char *match; - int len, multiple; - - g_return_val_if_fail(cmd != NULL, NULL); - - multiple = FALSE; - match = NULL; - len = strlen(cmd); - for (tmp = commands; tmp != NULL; tmp = tmp->next) { - COMMAND_REC *rec = tmp->data; - - if (g_strncasecmp(rec->cmd, cmd, len) == 0 && - strchr(rec->cmd+len, ' ') == NULL) { - if (rec->cmd[len] == '\0') { - /* full match */ - return rec->cmd; - } - - if (match != NULL) { - /* multiple matches, we still need to check - if there's some command left that is a - full match.. */ - multiple = TRUE; - } - - /* check that this is the only match */ - match = rec->cmd; - } - } - - if (multiple) { - signal_emit("error command", 2, - GINT_TO_POINTER(CMDERR_AMBIGUOUS), cmd); - return NULL; - } - - return match != NULL ? match : cmd; -} - -void command_runsub(const char *cmd, const char *data, - void *server, void *item) -{ - const char *newcmd; - char *orig, *subcmd, *defcmd, *args; - - g_return_if_fail(data != NULL); - - while (*data == ' ') data++; - - if (*data == '\0') { - /* no subcommand given - list the subcommands */ - signal_emit("list subcommands", 2, cmd); - return; - } - - /* get command.. */ - orig = subcmd = g_strdup_printf("command %s %s", cmd, data); - args = strchr(subcmd+8 + strlen(cmd)+1, ' '); - if (args != NULL) *args++ = '\0'; else args = ""; - while (*args == ' ') args++; - - /* check if this command can be expanded */ - newcmd = command_expand(subcmd+8); - if (newcmd == NULL) { - /* ambiguous command */ - g_free(orig); - return; - } - - subcmd = g_strconcat("command ", newcmd, NULL); - - g_strdown(subcmd); - if (!signal_emit(subcmd, 3, args, server, item)) { - defcmd = g_strdup_printf("default command %s", cmd); - if (!signal_emit(defcmd, 3, data, server, item)) { - signal_emit("error command", 2, - GINT_TO_POINTER(CMDERR_UNKNOWN), subcmd+8); - } - g_free(defcmd); - } - - g_free(subcmd); - g_free(orig); -} - -static GSList *optlist_find(GSList *optlist, const char *option) -{ - while (optlist != NULL) { - char *name = optlist->data; - if (iscmdtype(*name)) name++; - - if (g_strcasecmp(name, option) == 0) - return optlist; - - optlist = optlist->next; - } - - return NULL; -} - -int command_have_option(const char *cmd, const char *option) -{ - COMMAND_REC *rec; - char **tmp; - - g_return_val_if_fail(cmd != NULL, FALSE); - g_return_val_if_fail(option != NULL, FALSE); - - rec = command_find(cmd); - g_return_val_if_fail(rec != NULL, FALSE); - - if (rec->options == NULL) - return FALSE; - - for (tmp = rec->options; *tmp != NULL; tmp++) { - char *name = iscmdtype(**tmp) ? (*tmp)+1 : *tmp; - - if (g_strcasecmp(name, option) == 0) - return TRUE; - } - - return FALSE; -} - -static void command_calc_options(COMMAND_REC *rec, const char *options) -{ - char **optlist, **tmp, *name, *str; - GSList *list, *oldopt; - - optlist = g_strsplit(options, " ", -1); - - if (rec->options == NULL) { - /* first call - use specified args directly */ - rec->options = optlist; - return; - } - - /* save old options to linked list */ - list = NULL; - for (tmp = rec->options; *tmp != NULL; tmp++) - list = g_slist_append(list, g_strdup(*tmp)); - g_strfreev(rec->options); - - /* merge the options */ - for (tmp = optlist; *tmp != NULL; tmp++) { - name = iscmdtype(**tmp) ? (*tmp)+1 : *tmp; - - oldopt = optlist_find(list, name); - if (oldopt != NULL) { - /* already specified - overwrite old defination */ - g_free(oldopt->data); - oldopt->data = g_strdup(*tmp); - } else { - /* new option, append to list */ - list = g_slist_append(list, g_strdup(*tmp)); - } - } - g_strfreev(optlist); - - /* linked list -> string[] */ - str = gslist_to_string(list, " "); - rec->options = g_strsplit(str, " ", -1); - g_free(str); - - g_slist_foreach(list, (GFunc) g_free, NULL); - g_slist_free(list); -} - -/* recalculate options to command from options in all modules */ -static void command_update_options(COMMAND_REC *rec) -{ - GSList *tmp; - - g_strfreev(rec->options); - rec->options = NULL; - - for (tmp = rec->modules; tmp != NULL; tmp = tmp->next) { - COMMAND_MODULE_REC *modrec = tmp->data; - - if (modrec->options != NULL) - command_calc_options(rec, modrec->options); - } -} - -void command_set_options_module(const char *module, - const char *cmd, const char *options) -{ - COMMAND_REC *rec; - COMMAND_MODULE_REC *modrec; - int reload; - - g_return_if_fail(module != NULL); - g_return_if_fail(cmd != NULL); - g_return_if_fail(options != NULL); - - rec = command_find(cmd); - g_return_if_fail(rec != NULL); - modrec = command_module_get(rec, module, -1); - - reload = modrec->options != NULL; - if (reload) { - /* options already set for the module .. - we need to recalculate everything */ - g_free(modrec->options); - } - - modrec->options = g_strdup(options); - - if (reload) - command_update_options(rec); - else - command_calc_options(rec, options); -} - -char *cmd_get_param(char **data) -{ - char *pos; - - g_return_val_if_fail(data != NULL, NULL); - g_return_val_if_fail(*data != NULL, NULL); - - while (**data == ' ') (*data)++; - pos = *data; - - while (**data != '\0' && **data != ' ') (*data)++; - if (**data == ' ') *(*data)++ = '\0'; - - return pos; -} - -char *cmd_get_quoted_param(char **data) -{ - char *pos, quote; - - g_return_val_if_fail(data != NULL, NULL); - g_return_val_if_fail(*data != NULL, NULL); - - while (**data == ' ') (*data)++; - if (**data != '\'' && **data != '"') - return cmd_get_param(data); - - quote = **data; (*data)++; - - pos = *data; - while (**data != '\0' && (**data != quote || - ((*data)[1] != ' ' && (*data)[1] != '\0'))) { - if (**data == '\\' && (*data)[1] != '\0') - g_memmove(*data, (*data)+1, strlen(*data)); - (*data)++; - } - - if (**data == quote) { - *(*data)++ = '\0'; - if (**data == ' ') - (*data)++; - } - - return pos; -} - -/* Find specified option from list of options - the `option' might be - shortened version of the full command. Returns index where the - option was found, -1 if not found or -2 if there was multiple matches. */ -static int option_find(char **array, const char *option) -{ - char **tmp; - int index, found, len, multiple; - - g_return_val_if_fail(array != NULL, -1); - g_return_val_if_fail(option != NULL, -1); - - len = strlen(option); - - found = -1; index = 0; multiple = FALSE; - for (tmp = array; *tmp != NULL; tmp++, index++) { - const char *text = *tmp + iscmdtype(**tmp); - - if (g_strncasecmp(text, option, len) == 0) { - if (text[len] == '\0') { - /* full match */ - return index; - } - - if (found != -1) { - /* multiple matches - we still need to check - if there's a full match left.. */ - multiple = TRUE; - } - - /* partial match, check that it's the only one */ - found = index; - } - } - - if (multiple) - return -2; - - return found; -} - -static int get_cmd_options(char **data, int ignore_unknown, - const char *cmd, GHashTable *options) -{ - COMMAND_REC *rec; - char *option, *arg, **optlist; - int pos; - - /* get option definations */ - rec = cmd == NULL ? NULL : command_find(cmd); - optlist = rec == NULL ? NULL : rec->options; - - option = NULL; pos = -1; - for (;;) { - if (**data == '-') { - if (option != NULL && *optlist[pos] == '+') { - /* required argument missing! */ - *data = optlist[pos] + 1; - return CMDERR_OPTION_ARG_MISSING; - } - - (*data)++; - if (**data == '-' && (*data)[1] == ' ') { - /* -- option means end of options even - if next word starts with - */ - (*data)++; - while (**data == ' ') (*data)++; - break; - } - - if (**data == '\0') - option = "-"; - else if (**data != ' ') - option = cmd_get_param(data); - else { - option = "-"; - (*data)++; - } - - /* check if this option can have argument */ - pos = optlist == NULL ? -1 : - option_find(optlist, option); - - if (pos == -1 && optlist != NULL && - is_numeric(option, '\0')) { - /* check if we want - option */ - pos = option_find(optlist, "#"); - if (pos != -1) { - g_hash_table_insert(options, "#", - option); - pos = -3; - } - } - - if (pos == -1 && !ignore_unknown) { - /* unknown option! */ - *data = option; - return CMDERR_OPTION_UNKNOWN; - } - if (pos == -2 && !ignore_unknown) { - /* multiple matches */ - *data = option; - return CMDERR_OPTION_AMBIGUOUS; - } - if (pos >= 0) { - /* if we used a shortcut of parameter, put - the whole parameter name in options table */ - option = optlist[pos] + - iscmdtype(*optlist[pos]); - } - if (options != NULL && pos != -3) - g_hash_table_insert(options, option, ""); - - if (pos < 0 || !iscmdtype(*optlist[pos]) || - *optlist[pos] == '!') - option = NULL; - - while (**data == ' ') (*data)++; - continue; - } - - if (option == NULL) - break; - - if (*optlist[pos] == '@' && !i_isdigit(**data)) - break; /* expected a numeric argument */ - - /* save the argument */ - arg = cmd_get_quoted_param(data); - if (options != NULL) { - g_hash_table_remove(options, option); - g_hash_table_insert(options, option, arg); - } - option = NULL; - - while (**data == ' ') (*data)++; - } - - return 0; -} - -typedef struct { - char *data; - GHashTable *options; -} CMD_TEMP_REC; - -static const char * -get_optional_channel(WI_ITEM_REC *active_item, char **data, int require_name) -{ - CHANNEL_REC *chanrec; - const char *ret; - char *tmp, *origtmp, *channel; - - if (active_item == NULL) { - /* no active channel in window, channel required */ - return cmd_get_param(data); - } - - origtmp = tmp = g_strdup(*data); - channel = cmd_get_param(&tmp); - - if (strcmp(channel, "*") == 0 && !require_name) { - /* "*" means active channel */ - cmd_get_param(data); - ret = window_item_get_target(active_item); - } else if (!server_ischannel(active_item->server, channel)) { - /* we don't have channel parameter - use active channel */ - ret = window_item_get_target(active_item); - } else { - /* Find the channel first and use it's name if found. - This allows automatic !channel -> !XXXXXchannel replaces. */ - channel = cmd_get_param(data); - - chanrec = channel_find(active_item->server, channel); - ret = chanrec == NULL ? channel : chanrec->name; - } - - g_free(origtmp); - return ret; -} - -int cmd_get_params(const char *data, gpointer *free_me, int count, ...) -{ - WI_ITEM_REC *item; - CMD_TEMP_REC *rec; - GHashTable **opthash; - char **str, *arg, *datad; - va_list args; - int cnt, error, ignore_unknown, require_name; - - g_return_val_if_fail(data != NULL, FALSE); - - va_start(args, count); - - rec = g_new0(CMD_TEMP_REC, 1); - rec->data = g_strdup(data); - *free_me = rec; - - datad = rec->data; - error = FALSE; - - item = (count & PARAM_FLAG_OPTCHAN) == 0 ? NULL: - (WI_ITEM_REC *) va_arg(args, WI_ITEM_REC *); - - if (count & PARAM_FLAG_OPTIONS) { - arg = (char *) va_arg(args, char *); - opthash = (GHashTable **) va_arg(args, GHashTable **); - - rec->options = *opthash = - g_hash_table_new((GHashFunc) g_istr_hash, - (GCompareFunc) g_istr_equal); - - ignore_unknown = count & PARAM_FLAG_UNKNOWN_OPTIONS; - error = get_cmd_options(&datad, ignore_unknown, - arg, *opthash); - } - - if (!error) { - /* and now handle the string */ - cnt = PARAM_WITHOUT_FLAGS(count); - if (count & PARAM_FLAG_OPTCHAN) { - /* optional channel as first parameter */ - require_name = (count & PARAM_FLAG_OPTCHAN_NAME) == - PARAM_FLAG_OPTCHAN_NAME; - arg = (char *) get_optional_channel(item, &datad, require_name); - - str = (char **) va_arg(args, char **); - if (str != NULL) *str = arg; - cnt--; - } - - while (cnt-- > 0) { - if (cnt == 0 && count & PARAM_FLAG_GETREST) { - /* get rest */ - arg = datad; - } else { - arg = (count & PARAM_FLAG_NOQUOTES) ? - cmd_get_param(&datad) : - cmd_get_quoted_param(&datad); - } - - str = (char **) va_arg(args, char **); - if (str != NULL) *str = arg; - } - } - va_end(args); - - if (error) { - signal_emit("error command", 2, GINT_TO_POINTER(error), datad); - signal_stop(); - - cmd_params_free(rec); - *free_me = NULL; - } - - return !error; -} - -void cmd_params_free(void *free_me) -{ - CMD_TEMP_REC *rec = free_me; - - if (rec->options != NULL) g_hash_table_destroy(rec->options); - g_free(rec->data); - g_free(rec); -} - -static void command_module_unbind_all(COMMAND_REC *rec, - COMMAND_MODULE_REC *modrec) -{ - GSList *tmp, *next; - - for (tmp = modrec->callbacks; tmp != NULL; tmp = next) { - COMMAND_CALLBACK_REC *cb = tmp->data; - next = tmp->next; - - command_unbind_full(rec->cmd, cb->func, cb->user_data); - } - - if (g_slist_find(commands, rec) != NULL) { - /* this module might have removed some options - from command, update them. */ - command_update_options(rec); - } -} - -void commands_remove_module(const char *module) -{ - GSList *tmp, *next, *modlist; - - g_return_if_fail(module != NULL); - - for (tmp = commands; tmp != NULL; tmp = next) { - COMMAND_REC *rec = tmp->data; - - next = tmp->next; - modlist = gslist_find_string(rec->modules, module); - if (modlist != NULL) - command_module_unbind_all(rec, modlist->data); - } -} - -static int cmd_protocol_match(COMMAND_REC *cmd, SERVER_REC *server) -{ - GSList *tmp; - - for (tmp = cmd->modules; tmp != NULL; tmp = tmp->next) { - COMMAND_MODULE_REC *rec = tmp->data; - - if (rec->protocol == -1) { - /* at least one module accepts the command - without specific protocol */ - return 1; - } - - if (server != NULL && rec->protocol == server->chat_type) { - /* matching protocol found */ - return 1; - } - } - - return 0; -} - -#define alias_runstack_push(alias) \ - alias_runstack = g_slist_append(alias_runstack, alias) - -#define alias_runstack_pop(alias) \ - alias_runstack = g_slist_remove(alias_runstack, alias) - -#define alias_runstack_find(alias) \ - (gslist_find_icase_string(alias_runstack, alias) != NULL) - -static void parse_command(const char *command, int expand_aliases, - SERVER_REC *server, void *item) -{ - COMMAND_REC *rec; - const char *alias, *newcmd; - char *cmd, *orig, *args, *oldcmd; - - g_return_if_fail(command != NULL); - - cmd = orig = g_strconcat("command ", command, NULL); - args = strchr(cmd+8, ' '); - if (args != NULL) *args++ = '\0'; else args = ""; - - /* check if there's an alias for command. Don't allow - recursive aliases */ - alias = !expand_aliases || alias_runstack_find(cmd+8) ? NULL : - alias_find(cmd+8); - if (alias != NULL) { - alias_runstack_push(cmd+8); - eval_special_string(alias, args, server, item); - alias_runstack_pop(cmd+8); - g_free(orig); - return; - } - - /* check if this command can be expanded */ - newcmd = command_expand(cmd+8); - if (newcmd == NULL) { - /* ambiguous command */ - g_free(orig); - return; - } - - rec = command_find(newcmd); - if (rec != NULL && !cmd_protocol_match(rec, server)) { - g_free(orig); - - signal_emit("error command", 2, - GINT_TO_POINTER(server == NULL ? - CMDERR_NOT_CONNECTED : - CMDERR_ILLEGAL_PROTO)); - return; - } - - cmd = g_strconcat("command ", newcmd, NULL); - g_strdown(cmd); - - oldcmd = current_command; - current_command = cmd+8; - if (server != NULL) server_ref(server); - if (!signal_emit(cmd, 3, args, server, item)) { - signal_emit_id(signal_default_command, 3, - command, server, item); - } - if (server != NULL) { - if (server->connection_lost) - server_disconnect(server); - server_unref(server); - } - current_command = oldcmd; - - g_free(cmd); - g_free(orig); -} - -static void event_command(const char *line, SERVER_REC *server, void *item) -{ - char *cmdchar; - int expand_aliases = TRUE; - - g_return_if_fail(line != NULL); - - cmdchar = *line == '\0' ? NULL : - strchr(settings_get_str("cmdchars"), *line); - if (cmdchar != NULL && line[1] == ' ') { - /* "/ text" = same as sending "text" to active channel. */ - line += 2; - cmdchar = NULL; - } - if (cmdchar == NULL) { - /* non-command - let someone else handle this */ - signal_emit("send text", 3, line, server, item); - return; - } - - /* same cmdchar twice ignores aliases ignores aliases */ - line++; - if (*line == *cmdchar) { - line++; - expand_aliases = FALSE; - } - - /* ^command hides the output - we'll do this at fe-common but - we have to skip the ^ char here.. */ - if (*line == '^') line++; - - parse_command(line, expand_aliases, server, item); -} - -static int eval_recursion_depth=0; -/* SYNTAX: EVAL */ -static void cmd_eval(const char *data, SERVER_REC *server, void *item) -{ - g_return_if_fail(data != NULL); - if (eval_recursion_depth > 100) - cmd_return_error(CMDERR_EVAL_MAX_RECURSE); - - - eval_recursion_depth++; - eval_special_string(data, "", server, item); - eval_recursion_depth--; -} - -/* SYNTAX: CD */ -static void cmd_cd(const char *data) -{ - char *str; - - g_return_if_fail(data != NULL); - if (*data == '\0') return; - - str = convert_home(data); - chdir(str); - g_free(str); -} - -void commands_init(void) -{ - commands = NULL; - current_command = NULL; - alias_runstack = NULL; - - signal_default_command = signal_get_uniq_id("default command"); - - settings_add_str("misc", "cmdchars", "/"); - signal_add("send command", (SIGNAL_FUNC) event_command); - - command_bind("eval", NULL, (SIGNAL_FUNC) cmd_eval); - command_bind("cd", NULL, (SIGNAL_FUNC) cmd_cd); -} - -void commands_deinit(void) -{ - g_free_not_null(current_command); - - signal_remove("send command", (SIGNAL_FUNC) event_command); - - command_unbind("eval", (SIGNAL_FUNC) cmd_eval); - command_unbind("cd", (SIGNAL_FUNC) cmd_cd); -}