diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 493c5760..99a43515 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -11,14 +11,6 @@ if DO_PERL perldir = perl endif -#if DO_TCL -#tcldir = tcl -#endif - -#if DO_SASL -#sasldir = sasl -#endif - if DO_DOAT doatdir = doat endif @@ -35,5 +27,5 @@ if DO_SYSINFO sysinfodir = sysinfo endif -#SUBDIRS = . $(pythondir) $(perldir) mailcheck xdcc $(tcldir) $(sasldir) +#SUBDIRS = . $(pythondir) $(perldir) mailcheck xdcc SUBDIRS = . $(pythondir) $(perldir) $(checksumdir) $(doatdir) $(fishlimdir) $(sysinfodir) diff --git a/plugins/lua/lua-xp.vcxproj b/plugins/lua/lua-xp.vcxproj deleted file mode 100644 index ba32e574..00000000 --- a/plugins/lua/lua-xp.vcxproj +++ /dev/null @@ -1,133 +0,0 @@ - - - - - Release - Win32 - - - Release - x64 - - - - {646B4316-C8B8-4DB6-B6AE-E586929E5729} - Win32Proj - lua - lua - - - - DynamicLibrary - false - true - MultiByte - WDK7 - - - DynamicLibrary - false - true - MultiByte - WDK7 - - - - - - - - - - - - - - - false - $(LuaOutput) - $(HexChatBin) - $(HexChatObj)$(ProjectName)\ - - - false - $(LuaOutput) - $(HexChatBin) - $(HexChatObj)$(ProjectName)\ - - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;LUA_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions) - $(DepsRoot)\include;..\..\src\common;$(Glib);%(AdditionalIncludeDirectories) - - - Windows - true - true - true - $(DepsRoot)\lib;$(OutDir);%(AdditionalLibraryDirectories) - "$(LuaLib).lib";%(AdditionalDependencies) - - - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;LUA_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions) - $(DepsRoot)\include;..\..\src\common;$(Glib);%(AdditionalIncludeDirectories) - - - Windows - true - true - true - $(DepsRoot)\lib;$(OutDir);%(AdditionalLibraryDirectories) - "$(LuaLib).lib";%(AdditionalDependencies) - - - - - "$(LuaLib).lib";$(DepLibs);%(AdditionalDependencies) - - - - - "$(LuaLib).lib";$(DepLibs);%(AdditionalDependencies) - - - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;$(OwnFlags);snprintf=g_snprintf;%(PreprocessorDefinitions) - true - - - lua.def - - - - - WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;$(OwnFlags);snprintf=g_snprintf;%(PreprocessorDefinitions) - true - - - lua.def - - - - - - - - - - - - \ No newline at end of file diff --git a/plugins/lua/lua-xp.vcxproj.filters b/plugins/lua/lua-xp.vcxproj.filters deleted file mode 100644 index 9c7e3d89..00000000 --- a/plugins/lua/lua-xp.vcxproj.filters +++ /dev/null @@ -1,23 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Resource Files - - - - - Source Files - - - \ No newline at end of file diff --git a/plugins/lua/lua.c b/plugins/lua/lua.c deleted file mode 100644 index 0908f6cb..00000000 --- a/plugins/lua/lua.c +++ /dev/null @@ -1,1886 +0,0 @@ -/* - * X-Chat 2.0 LUA Plugin - * - * Copyright (c) 2007 Hanno Hecker - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ -/* - * $Id: lua.c 91 2007-06-09 18:44:03Z vetinari $ - * $Revision: 91 $ - * $Date: 2007-06-09 20:44:03 +0200 (Szo, 09 jún. 2007) $ - */ -/* - * TODO: - * * compile (was OK)/run on IRIX - * ? localize error msgs? ... maybe later - * ? make xchat.print() like print() which does an tostring() on - * everything it gets? - * ? add /LUA -s ? ... add a new script from cmdline... this state - * is not removed after the pcall(), but prints a name, which may - * be used to unload this virtual script. ... no xchat_register(), - * xchat_init() should be needed - * ... don't disable xchat.hook_* for this - * ? timer name per state/script and not per plugin? - */ -#define LXC_NAME "Lua" -#define LXC_DESC "Lua scripting interface" -#define LXC_VERSION "0.7 (r91)" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef _WIN32 -#include /* for getcwd */ -#include "../../src/dirent/dirent-win32.h" -#include "../../src/common/typedef.h" -#endif - -#if !( defined(_WIN32) || defined(LXC_XCHAT_GETTEXT) ) -# include -#endif - -#ifndef PATH_MAX /* hurd */ -# define PATH_MAX 1024 -#endif - -#include -#include -#include - -#define lua_pop(L,n) lua_settop(L, -(n)-1) - -#include "hexchat-plugin.h" - -static hexchat_plugin *ph; /* plugin handle */ - -#define LXC_STRIP_COLOR 1 -#define LXC_STRIP_ATTR 2 -#define LXC_STRIP_ALL (LXC_STRIP_COLOR|LXC_STRIP_ATTR) - -/* registered hooks */ -struct lxc_hooks { - const char *name; - hexchat_hook *hook; - struct lxc_hooks *next; -}; - -/* single linked list of all lua states^Wscripts ;-) */ -struct lxc_States { - lua_State *state; /* the lua state of the script */ - char file[PATH_MAX+1]; /* the file name of the script */ - struct lxc_hooks *hooks; /* all hooks this script registered */ - void *gui; /* the gui entry in windows->plugins and scripts... */ - struct lxc_States *next; -}; - -static struct lxc_States *lxc_states = NULL; - -/* user/script supplied data for a callback */ -struct lxc_userdata { - int idx; /* table index */ - int type; /* lua type: */ - const char *string; /* only strings, ... */ - double num; /* numbers and booleans are supported */ - struct lxc_userdata *next; -}; - -/* callback data */ -struct lxc_cbdata { - lua_State *state; - const char *func; - hexchat_hook *hook; /* timer ... */ - struct lxc_userdata *data; -}; - -static char lxc_event_name[1024] = "\0"; - -static int lxc_run_hook(char *word[], char *word_eol[], void *data); -static int lxc_run_print(char *word[], void *data); -static int lxc_run_timer(void *data); - -static int lxc_hook_command(lua_State *L); -static int lxc_hook_server(lua_State *L); -static int lxc_hook_print(lua_State *L); -static int lxc_event(lua_State *L); -static int lxc_hook_timer(lua_State *L); -static int lxc_unhook(lua_State *L); - -static int lxc_command(lua_State *L); -static int lxc_print(lua_State *L); -static int lxc_emit_print(lua_State *L); -static int lxc_send_modes(lua_State *L); -static int lxc_find_context(lua_State *L); -static int lxc_get_context(lua_State *L); -static int lxc_get_info(lua_State *L); -static int lxc_get_prefs(lua_State *L); -static int lxc_set_context(lua_State *L); -static int lxc_nickcmp(lua_State *L); - -static int lxc_list_get(lua_State *L); -static int lxc_list_fields(lua_State *L); -static int lxc_gettext(lua_State *L); - -static int lxc_bits(lua_State *L); - -static luaL_reg lxc_functions[] = { - {"hook_command", lxc_hook_command }, -/* TODO: - {"hook_fd", lxc_hook_fd }, -*/ - {"hook_print", lxc_hook_print }, - {"hook_server", lxc_hook_server }, - {"hook_timer", lxc_hook_timer }, - {"unhook", lxc_unhook }, - - {"event", lxc_event }, - - {"command", lxc_command }, - {"print", lxc_print }, - {"emit_print", lxc_emit_print }, - {"send_modes", lxc_send_modes }, - {"find_context", lxc_find_context }, - {"get_context", lxc_get_context }, - {"get_info", lxc_get_info }, - {"get_prefs", lxc_get_prefs }, - {"set_context", lxc_set_context }, - - {"nickcmp", lxc_nickcmp }, - - {"list_get", lxc_list_get }, - {"list_fields", lxc_list_fields }, - - {"gettext", lxc_gettext}, -/* helper function for bit flags */ - {"bits", lxc_bits }, - {NULL, NULL} -}; - -static struct { - const char *name; - long value; -} lxc_consts[] = { - {"EAT_NONE", HEXCHAT_EAT_NONE}, - {"EAT_XCHAT", HEXCHAT_EAT_HEXCHAT}, - {"EAT_PLUGIN", HEXCHAT_EAT_PLUGIN}, - {"EAT_ALL", HEXCHAT_EAT_ALL}, - -/* unused until hook_fd is done - {"FD_READ", HEXCHAT_FD_READ}, - {"FD_WRITE", HEXCHAT_FD_WRITE}, - {"FD_EXCEPTION", HEXCHAT_FD_EXCEPTION}, - {"FD_NOTSOCKET", HEXCHAT_FD_NOTSOCKET}, - */ - - {"PRI_HIGHEST", HEXCHAT_PRI_HIGHEST}, - {"PRI_HIGH", HEXCHAT_PRI_HIGH}, - {"PRI_NORM", HEXCHAT_PRI_NORM}, - {"PRI_LOW", HEXCHAT_PRI_LOW}, - {"PRI_LOWEST", HEXCHAT_PRI_LOWEST}, - - /* for: clean = xchat.strip(dirty, xchat.STRIP_ALL) */ - {"STRIP_COLOR", LXC_STRIP_COLOR}, - {"STRIP_ATTR", LXC_STRIP_ATTR}, - {"STRIP_ALL", LXC_STRIP_ALL}, - - /* for xchat.commandf("GUI COLOR %d", xchat.TAB_HILIGHT) */ - {"TAB_DEFAULT", 0}, - {"TAB_NEWDATA", 1}, - {"TAB_NEWMSG", 2}, - {"TAB_HILIGHT", 3}, - - {NULL, 0} -}; - - -#ifdef DEBUG -static void stackDump (lua_State *L, const char *msg) { - int i, t; - int top = lua_gettop(L); - - fprintf(stderr, "%s\n", msg); - for (i = 1; i <= top; i++) { /* repeat for each level */ - t = lua_type(L, i); - switch (t) { - - case LUA_TSTRING: /* strings */ - fprintf(stderr, "`%s'", lua_tostring(L, i)); - break; - - case LUA_TBOOLEAN: /* booleans */ - fprintf(stderr, lua_toboolean(L, i) ? "true" : "false"); - break; - - case LUA_TNUMBER: /* numbers */ - fprintf(stderr, "%g", lua_tonumber(L, i)); - break; - - default: /* other values */ - fprintf(stderr, "%s", lua_typename(L, t)); - break; - - } - fprintf(stderr, " "); /* put a separator */ - } - fprintf(stderr, "\n"); /* end the listing */ -} -#endif /* DEBUG */ - -static int lxc__newindex(lua_State *L) -{ - int i; - const char *name = lua_tostring(L, 2); - - luaL_getmetatable(L, "xchat"); /* 4 */ - - lua_pushnil(L); /* 5 */ - while (lua_next(L, 4) != 0) { - if ((lua_type(L, -2) == LUA_TSTRING) - && strcmp("__index", lua_tostring(L, -2)) == 0) - break; /* now __index is 5, table 6 */ - lua_pop(L, 1); - } - - lua_pushnil(L); - while (lua_next(L, 6) != 0) { - if ((lua_type(L, -2) == LUA_TSTRING) - && strcmp(name, lua_tostring(L, -2)) == 0) { - for (i=0; lxc_consts[i].name; i++) { - if (strcmp(name, lxc_consts[i].name) == 0) { - luaL_error(L, - "`xchat.%s' is a readonly constant", lua_tostring(L, 2)); - return 0; - } - } - } - lua_pop(L, 1); - } - - lua_pushvalue(L, 2); - lua_pushvalue(L, 3); - lua_rawset(L, 6); - - lua_settop(L, 1); - return 0; -} - -static int luaopen_xchat(lua_State *L) -{ - int i; -/* - * wrappers for xchat.printf() and xchat.commandf() - * ... xchat.strip - */ -#define LXC_WRAPPERS "function xchat.printf(...)\n" \ - " xchat.print(string.format(unpack(arg)))\n" \ - "end\n" \ - "function xchat.commandf(...)\n" \ - " xchat.command(string.format(unpack(arg)))\n" \ - "end\n" \ - "function xchat.strip(str, flags)\n" \ - " if flags == nil then\n" \ - " flags = xchat.STRIP_ALL\n" \ - " end\n" \ - " local bits = xchat.bits(flags)\n" \ - " if bits[1] then\n" \ - " str = string.gsub(\n" \ - " string.gsub(str, \"\\3%d%d?,%d%d?\", \"\"),\n" \ - " \"\\3%d%d?\", \"\")\n" \ - " end\n" \ - " if bits[2] then\n" \ - " -- bold, beep, reset, reverse, underline\n" \ - " str = string.gsub(str,\n" \ - " \"[\\2\\7\\15\\22\\31]\", \"\")\n" \ - " end\n" \ - " return str\n" \ - "end\n" - -#if defined(LUA_VERSION_NUM) && (LUA_VERSION_NUM >= 501) - luaL_register(L, "xchat", lxc_functions); - (void)luaL_dostring(L, LXC_WRAPPERS); -#else - luaL_openlib(L, "xchat", lxc_functions, 0); - lua_dostring(L, LXC_WRAPPERS); -#endif - - luaL_newmetatable(L, "xchat"); - - lua_pushliteral(L, "__index"); - lua_newtable(L); - - lua_pushstring(L, "ARCH"); -#ifdef _WIN32 - lua_pushstring(L, "Windows"); -#else - lua_pushstring(L, "Unix"); -#endif - lua_settable(L, -3); /* add to table __index */ - - for (i=0; lxc_consts[i].name; i++) { - lua_pushstring(L, lxc_consts[i].name); - lua_pushnumber(L, lxc_consts[i].value); - lua_settable(L, -3); /* add to table __index */ - } - lua_settable(L, -3); /* add to metatable */ - - lua_pushliteral(L, "__newindex"); - lua_pushcfunction(L, lxc__newindex); - lua_settable(L, -3); -/* - lua_pushliteral(L, "__metatable"); - lua_pushstring(L, "nothing to see here, move along"); - lua_settable(L, -3); -*/ - lua_setmetatable(L, -2); - lua_pop(L, 1); - return 1; -} - -lua_State *lxc_new_state() -{ -#if defined(LUA_VERSION_NUM) && (LUA_VERSION_NUM >= 501) - lua_State *L = luaL_newstate(); /* opens Lua */ - luaL_openlibs(L); -#else - lua_State *L = lua_open(); /* opens Lua */ - luaopen_base(L); /* opens the basic library */ - luaopen_table(L); /* opens the table library */ - luaopen_io(L); /* opens the I/O library */ - luaopen_string(L); /* opens the string lib. */ - luaopen_math(L); /* opens the math lib. */ -#endif - - luaopen_xchat(L); - return L; -} - -static int -lxc_load_file(const char *script) -{ - lua_State *L; - struct lxc_States *state; /* pointer to lua states list */ - struct lxc_States *st; /* pointer to lua states list */ - - L = lxc_new_state(); - state = malloc(sizeof(struct lxc_States)); - if (state == NULL) { - hexchat_printf(ph, "malloc() failed: %s\n", strerror(errno)); - lua_close(L); - return 0; - } - - state->state = L; - snprintf(state->file, PATH_MAX, script); - state->next = NULL; - state->hooks = NULL; - state->gui = NULL; - - if (luaL_loadfile(L, script) || lua_pcall(L, 0, 0, 0)) { - hexchat_printf(ph, "Lua plugin: error loading script %s", - lua_tostring(L, -1)); - lua_close(L); - free(state); - return 0; - } - - if (!lxc_states) - lxc_states = state; - else { - st = lxc_states; - while (st->next) - st = st->next; - st->next = state; - } - - return 1; -} - -static void -lxc_autoload_from_path(const char *path) -{ - DIR *dir; - struct dirent *ent; - char *file; - int len; - /* hexchat_printf(ph, "loading from %s\n", path); */ - dir = opendir(path); - if (dir) { - while ((ent = readdir(dir))) { - len = strlen(ent->d_name); - if (len > 4 && strcasecmp(".lua", ent->d_name + len - 4) == 0) { - file = malloc(len + strlen(path) + 2); - if (file == NULL) { - hexchat_printf(ph, "lxc_autoload_from_path(): malloc failed: %s", - strerror(errno)); - break; - } - sprintf(file, "%s" G_DIR_SEPARATOR_S "%s", path, ent->d_name); - (void)lxc_load_file((const char *)file); - free(file); - } - } - closedir(dir); - } -} - -void lxc_unload_script(struct lxc_States *state) -{ - struct lxc_hooks *hooks, *h; - struct lxc_cbdata *cb; - struct lxc_userdata *ud, *u; - lua_State *L = state->state; - - lua_pushstring(L, "xchat_unload"); - lua_gettable(L, LUA_GLOBALSINDEX); - if (lua_type(L, -1) == LUA_TFUNCTION) { - if (lua_pcall(L, 0, 0, 0)) { - hexchat_printf(ph, "Lua plugin: error while unloading script %s", - lua_tostring(L, -1)); - lua_pop(L, 1); - } - } - - if (state->gui) - hexchat_plugingui_remove(ph, state->gui); - state->gui = NULL; - - hooks = state->hooks; - while (hooks) { - h = hooks; - hooks = hooks->next; - - cb = hexchat_unhook(ph, h->hook); - if (cb) { - ud = cb->data; - while (ud) { - u = ud; - ud = ud->next; - free(u); - } - free(cb); - } - - free(h); - } - lua_close(state->state); -} - - -static int lxc_cb_load(char *word[], char *word_eol[], void *userdata) -{ - int len; - struct lxc_States *state; - lua_State *L; - const char *name, *desc, *vers; - const char *xdir = ""; - char *buf; - char file[PATH_MAX+1]; - struct stat *st; - - if (word_eol[2][0] == 0) - return HEXCHAT_EAT_NONE; - - buf = malloc(PATH_MAX + 1); - if (!buf) { - hexchat_printf(ph, "malloc() failed: %s\n", strerror(errno)); - return HEXCHAT_EAT_NONE; - } - - st = malloc(sizeof(struct stat)); - if (!st) { - hexchat_printf(ph, "malloc() failed: %s\n", strerror(errno)); - free(buf); - return HEXCHAT_EAT_NONE; - } - - len = strlen(word[2]); - if (len > 4 && strcasecmp (".lua", word[2] + len - 4) == 0) { - if (strrchr(word[2], G_DIR_SEPARATOR) != NULL) - strncpy(file, word[2], PATH_MAX); - else - { - if (stat(word[2], st) == 0) - { - xdir = getcwd (buf, PATH_MAX); - snprintf (file, PATH_MAX, "%s" G_DIR_SEPARATOR_S "%s", xdir, word[2]); - } - else - { - xdir = hexchat_get_info (ph, "configdir"); - snprintf (file, PATH_MAX, "%s" G_DIR_SEPARATOR_S "addons" G_DIR_SEPARATOR_S "%s", xdir, word[2]); - } - } - - if (lxc_load_file((const char *)file) == 0) { - free(st); - free(buf); - return HEXCHAT_EAT_ALL; - } - - state = lxc_states; - while (state) { - if (state->next == NULL) { - L = state->state; - - lua_pushstring(L, "xchat_register"); - lua_gettable(L, LUA_GLOBALSINDEX); - if (lua_pcall(L, 0, 3, 0)) { - hexchat_printf(ph, "Lua plugin: error registering script %s", - lua_tostring(L, -1)); - lua_pop(L, 1); - free(st); - free(buf); - return HEXCHAT_EAT_ALL; - } - - name = lua_tostring(L, -3); - desc = lua_tostring(L, -2); - vers = lua_tostring(L, -1); - lua_pop(L, 4); /* func + 3 ret value */ - state->gui = hexchat_plugingui_add(ph, state->file, - name, desc, vers, NULL - ); - - lua_pushstring(L, "xchat_init"); - lua_gettable(L, LUA_GLOBALSINDEX); - if (lua_type(L, -1) != LUA_TFUNCTION) - lua_pop(L, 1); - else { - if (lua_pcall(L, 0, 0, 0)) { - hexchat_printf(ph, - "Lua plugin: error calling xchat_init() %s", - lua_tostring(L, -1)); - lua_pop(L, 1); - } - } - free(st); - free(buf); - return HEXCHAT_EAT_ALL; - } - state = state->next; - } - } - free(st); - free(buf); - return HEXCHAT_EAT_NONE; -} - -static int lxc_cb_unload(char *word[], char *word_eol[], void *userdata) -{ - int len; - struct lxc_States *state; - struct lxc_States *prev = NULL; - char *file; - - if (word_eol[2][0] == 0) - return HEXCHAT_EAT_NONE; - - len = strlen(word[2]); - if (len > 4 && strcasecmp(".lua", word[2] + len - 4) == 0) { - state = lxc_states; - while (state) { - /* - * state->file is the full or relative path, always with a '/' inside, - * even if loaded via '/LOAD script.lua'. So strrchr() will never - * be NULL. - * ... we just inspect the script name w/o path to see if it's the - * right one to unload - */ - file = strrchr(state->file, '/') + 1; - if ((strcmp(state->file, word[2]) == 0) - || (strcasecmp(file, word[2]) == 0)) { - lxc_unload_script(state); - if (prev) - prev->next = state->next; - else - lxc_states = state->next; - hexchat_printf(ph, "Lua script %s unloaded", file); - free(state); - return HEXCHAT_EAT_ALL; - } - prev = state; - state = state->next; - } - } - return HEXCHAT_EAT_NONE; -} - -static int lxc_cb_lua(char *word[], char *word_eol[], void *userdata) -{ - lua_State *L = lxc_new_state(); - if (word[2][0] == '\0') { - hexchat_printf(ph, "LUA: Usage: /LUA LUA_CODE... execute LUA_CODE"); - return HEXCHAT_EAT_ALL; - } - if (luaL_loadbuffer(L, word_eol[2], strlen(word_eol[2]), "/LUA")) { - hexchat_printf(ph, "LUA: error loading line %s", lua_tostring(L, -1)); - lua_pop(L, 1); - } - -#define LXC_HOOK_DISABLE "xchat.hook_command = nil\n" \ - "xchat.hook_server = nil\n" \ - "xchat.hook_print = nil\n" \ - "xchat.hook_timer = nil\n" - -#if defined(LUA_VERSION_NUM) && (LUA_VERSION_NUM >= 501) - (void)luaL_dostring(L, LXC_HOOK_DISABLE); -#else - lua_dostring(L, LXC_HOOK_DISABLE); -#endif - - if (lua_pcall(L, 0, 0, 0)) { - hexchat_printf(ph, "LUA: error executing line %s", lua_tostring(L, -1)); - lua_pop(L, 1); - } - - lua_close(L); - return HEXCHAT_EAT_ALL; -} - -int hexchat_plugin_init(hexchat_plugin *plugin_handle, - char **plugin_name, - char **plugin_desc, - char **plugin_version, - char *arg) -{ - struct lxc_States *state; - lua_State *L; - const char *xdir; - const char *name, *desc, *vers; - char *xsubdir; - /* we need to save this for use with any xchat_* functions */ - ph = plugin_handle; - - /* tell xchat our info */ - *plugin_name = LXC_NAME; - *plugin_desc = LXC_DESC; - *plugin_version = LXC_VERSION; - - hexchat_hook_command(ph, "LOAD", HEXCHAT_PRI_NORM, lxc_cb_load, NULL, NULL); - hexchat_hook_command(ph, "UNLOAD", HEXCHAT_PRI_NORM, lxc_cb_unload, NULL, NULL); - hexchat_hook_command(ph, "LUA", HEXCHAT_PRI_NORM, lxc_cb_lua, "Usage: LUA , executes in a new lua state", NULL); - - xdir = hexchat_get_info (ph, "configdir"); - xsubdir = g_build_filename (xdir, "addons", NULL); - lxc_autoload_from_path (xsubdir); - g_free (xsubdir); - - /* put this here, otherwise it's only displayed when a script is autoloaded upon start */ - hexchat_printf(ph, "Lua interface loaded"); - - if (!lxc_states) /* no scripts loaded */ - return 1; - - state = lxc_states; - while (state) { - L = state->state; - lua_pushstring(L, "xchat_register"); - lua_gettable(L, LUA_GLOBALSINDEX); - if (lua_pcall(L, 0, 3, 0)) { - hexchat_printf(ph, "Lua plugin: error registering script %s", - lua_tostring(L, -1)); - lua_pop(L, 1); - state = state->next; - continue; - } - - name = lua_tostring(L, -3); - desc = lua_tostring(L, -2); - vers = lua_tostring(L, -1); - lua_pop(L, 4); /* func + 3 ret value */ - state->gui = hexchat_plugingui_add(ph, state->file, name, desc, vers, NULL); - - lua_pushstring(L, "xchat_init"); - lua_gettable(L, LUA_GLOBALSINDEX); - if (lua_type(L, -1) != LUA_TFUNCTION) - lua_pop(L, 1); - else { - if (lua_pcall(L, 0, 0, 0)) { - hexchat_printf(ph, "Lua plugin: error calling xchat_init() %s", - lua_tostring(L, -1)); - lua_pop(L, 1); - } - } - state = state->next; - } - return 1; -} - -int hexchat_plugin_deinit(hexchat_plugin *plug_handle) -{ - struct lxc_States *state, *st; - - state = lxc_states; - while (state) { - lxc_unload_script(state); - hexchat_printf(ph, "Lua script %s unloaded", state->file); - st = state; - state = state->next; - free(st); - } - hexchat_printf(plug_handle, "Lua interface unloaded"); - return 1; -} - -/* - * lua: func_name(word, word_eol, data) - * desc: your previously hooked callback function for hook_command() and - * hook_server(), you must return one of the xchat.EAT_* constants - * ret: none - * args: - * * word (table): the incoming line split into words (max 32) - * * word_eol (table): - * for both see - * http://xchat.org/docs/plugin20.html#word - * * data (table): the data table you passed to the hook_command() / - * hook_server() as 5th arg - */ -static int lxc_run_hook(char *word[], char *word_eol[], void *data) -{ - struct lxc_cbdata *cb = data; - lua_State *L = cb->state; - struct lxc_userdata *ud = cb->data; - struct lxc_userdata *u; - int i; - lua_pushstring(L, cb->func); - lua_gettable(L, LUA_GLOBALSINDEX); - - strcpy(lxc_event_name, word[0]); - lua_newtable(L); - for (i=1; i<=31 && word[i][0]; i++) { - lua_pushnumber(L, i); - lua_pushstring(L, word[i]); - lua_settable(L, -3); - } - - lua_newtable(L); - for (i=1; i<=31 && word_eol[i][0]; i++) { - lua_pushnumber(L, i); - lua_pushstring(L, word_eol[i]); - lua_settable(L, -3); - } - - lua_newtable(L); - u = ud; - while (u) { - lua_pushnumber(L, u->idx); - switch (u->type) { - case LUA_TSTRING: - lua_pushstring(L, u->string); - break; - case LUA_TNUMBER: - lua_pushnumber(L, u->num); - break; - case LUA_TBOOLEAN: - lua_pushboolean(L, (((int)u->num == 0) ? 0 : 1)); - break; - default: /* LUA_TNIL or others */ - lua_pushnil(L); - break; - } - lua_settable(L, -3); - u = u->next; - } - - if (lua_pcall(L, 3, 1, 0)) { - hexchat_printf(ph, "failed to call callback for '%s': %s", - word[1], lua_tostring(L, -1) - ); - lua_pop(L, 1); - return HEXCHAT_EAT_NONE; - } - - if (lua_type(L, -1) != LUA_TNUMBER) { - hexchat_printf(ph, "callback for '%s' did not return number...", word[1]); - return HEXCHAT_EAT_NONE; - } - - i = (int)lua_tonumber(L, -1); - lua_pop(L, 1); - return i; -} - -static int lxc_get_userdata(int pos, struct lxc_cbdata *cb) -{ - struct lxc_userdata *ud, *u; - lua_State *L = cb->state; - int i, t; - - t = lua_type(L, pos); - if (t == LUA_TNIL) - return 1; - if (t != LUA_TTABLE) - return 0; - - i = 1; - while (1) { - lua_pushnumber(L, i); - lua_gettable(L, -2); - - t = lua_type(L, -1); - if (t == LUA_TNIL) { - lua_pop(L, 1); - break; - } - - ud = malloc(sizeof(struct lxc_userdata)); - if (!ud) { - hexchat_printf(ph, "lxc_get_userdata(): failed to malloc: %s", - strerror(errno)); - if (cb->data != NULL) { - ud = cb->data; - while (ud) { - u = ud; - ud = ud->next; - free(u); - } - } - /* free(cb); NO! */ - lua_pushnil(L); - return 0; - } - ud->idx = i; - ud->next = NULL; - switch (t) { - case LUA_TSTRING: - ud->string = lua_tostring(L, -1); - ud->type = LUA_TSTRING; - break; - case LUA_TNUMBER: - ud->num = lua_tonumber(L, -1); - ud->type = LUA_TNUMBER; - break; - case LUA_TBOOLEAN: - ud->num = (double)lua_toboolean(L, -1); - ud->type = LUA_TBOOLEAN; - break; - default: - ud->type = LUA_TNIL; - break; - } - lua_pop(L, 1); - - if (cb->data == NULL) - cb->data = ud; - else { - u = cb->data; - while (u->next) - u = u->next; - u->next = ud; - } - i++; - } /* END while (1) */ - return 1; -} - -/* - * lua: xchat.hook_command(name, func_name, prio, help_str, data) - * desc: Adds a new /command. This allows your program to handle commands - * entered at the input box. To capture text without a "/" at the start - * (non-commands), you may hook a special name of "". i.e - * xchat.hook_command( "", ...) - * Starting from version 2.6.8, commands hooked that begin with a - * period ('.') will be hidden in /HELP and /HELP -l. - * ret: true... or false if something went wrong while registering hook - * args: - * * name (string): the name of the new command - * * func_name (string): the lua function to be called when command is - * entered - * * prio (number): use one of the xchat.PRIO_* - * * help_str (string): help for the new command... use nil for no help - * * data (table): table with strings, numbers and booleans, which will - * be passed to func_name as last argument. - */ -static int lxc_hook_command(lua_State *L) -{ - hexchat_hook *hook; - const char *help, *command, *func; - double prio; - struct lxc_hooks *hooks, *h; - struct lxc_States *st; - struct lxc_cbdata *cb; - - - if (lua_gettop(L) < 5) /* expand to five args if necessary */ - lua_settop(L, 5); - - cb = malloc(sizeof(struct lxc_cbdata)); - if (!cb) { - hexchat_printf(ph, "lxc_hook_command(): failed to malloc: %s", - strerror(errno)); - lua_pushboolean(L, 0); - return 1; - } - - cb->state = L; - cb->data = NULL; - - command = luaL_checkstring(L, 1); - func = luaL_checkstring(L, 2); - cb->func = func; - cb->hook = NULL; - - if (lua_type(L, 3) == LUA_TNIL) - prio = HEXCHAT_PRI_NORM; - else - prio = luaL_checknumber(L, 3); - - if (lua_type(L, 4) == LUA_TSTRING) { - help = luaL_checkstring(L, 4); - if (strlen(help) == 0) - help = NULL; - } - else - help = NULL; - - if (lxc_get_userdata(5, cb) == 0) - lua_pushboolean(L, 0); - else { - h = malloc(sizeof(struct lxc_hooks)); - if (!h) { - hexchat_printf(ph, "lxc_hook_command(): failed to malloc: %s", - strerror(errno)); - lua_pushboolean(L, 0); - return 1; - } - hook = hexchat_hook_command(ph, command, prio, lxc_run_hook, help, cb); - h->hook = hook; - h->name = command; - h->next = NULL; - st = lxc_states; - while (st) { - if (st->state == L) { - if (!st->hooks) - st->hooks = h; - else { - hooks = st->hooks; - while (hooks->next) - hooks = hooks->next; - hooks->next = h; - } - break; - } - st = st->next; - } - lua_pushboolean(L, 1); - } - return 1; -} - -/* - * lua: func_name(word, data) - * desc: your previously hooked callback function for hook_print(), - * you must return one of the xchat.EAT_* constants - * ret: none - * args: - * * word (table): the incoming line split into words (max 32) - * (see http://xchat.org/docs/plugin20.html#word) - * * data (table): the data table you passed to the hook_print() / - * as 4th arg - */ -static int lxc_run_print(char *word[], void *data) -{ - struct lxc_cbdata *cb = data; - lua_State *L = cb->state; - int i; - - lua_pushstring(L, cb->func); - lua_gettable(L, LUA_GLOBALSINDEX); - - strcpy(lxc_event_name, word[0]); - lua_newtable(L); - for (i=1; i<=31 && word[i][0]; i++) { - lua_pushnumber(L, i); - lua_pushstring(L, word[i]); - lua_settable(L, -3); - } - - if (lua_pcall(L, 1, 1, 0)) { - hexchat_printf(ph, "failed to call callback for '%s': %s", - word[1], lua_tostring(L, -1)); - lua_pop(L, 1); - return 0; - } - - if (lua_type(L, -1) != LUA_TNUMBER) { - hexchat_printf(ph, "callback for '%s' didn't return number...", word[1]); - return HEXCHAT_EAT_NONE; - } - i = (int)lua_tonumber(L, -1); - lua_pop(L, 1); - return i; -} - -/* - * lua: xchat.hook_print(name, func_name, prio, data) - * desc: Registers a function to trap any print events. The event names may - * be any available in the "Advanced > Text Events" window. There are - * also some extra "special" events you may hook using this function, - * see: http://xchat.org/docs/plugin20.html#hexchat_hook_print - * ret: true... or false if something went wrong while registering hook - * args: - * * name (string): the name of the new command - * * prio (number): use one of the xchat.PRIO_* - * * func_name (string): the lua function to be called when command is - * entered - * * data (table): table with strings, numbers and booleans, which will - * be passed to func_name as last argument. - */ -static int lxc_hook_print(lua_State *L) -{ - hexchat_hook *hook; - struct lxc_hooks *hooks, *h; - struct lxc_States *st; - struct lxc_cbdata *cb = malloc(sizeof(struct lxc_cbdata)); - const char *name, *func; - double prio; - - if (!cb) { - luaL_error(L, "lxc_hook_print(): failed to malloc: %s", strerror(errno)); - return 0; - } - - if (lua_gettop(L) < 4) /* expand to 4 args if necessary */ - lua_settop(L, 4); - - name = luaL_checkstring(L, 1); - func = luaL_checkstring(L, 2); - if (lua_type(L, 3) == LUA_TNIL) - prio = HEXCHAT_PRI_NORM; - else - prio = luaL_checknumber(L, 3); - - cb->state = L; - cb->func = func; - cb->data = NULL; - cb->hook = NULL; - - if (lxc_get_userdata(4, cb) == 0) - lua_pushboolean(L, 0); - else { - h = malloc(sizeof(struct lxc_hooks)); - if (!h) { - hexchat_printf(ph, "lxc_hook_print(): failed to malloc: %s", - strerror(errno)); - lua_pushboolean(L, 0); - return 1; - } - hook = hexchat_hook_print(ph, name, prio, lxc_run_print, cb); - h->hook = hook; - h->name = name; - h->next = NULL; - st = lxc_states; - while (st) { - if (st->state == L) { - if (!st->hooks) - st->hooks = h; - else { - hooks = st->hooks; - while (hooks->next) - hooks = hooks->next; - hooks->next = h; - } - break; - } - st = st->next; - } - lua_pushboolean(L, 1); - } - return 1; -} - -/* - * lua: xchat.hook_server(name, func_name, prio, data) - * desc: Registers a function to be called when a certain server event - * occurs. You can use this to trap PRIVMSG, NOTICE, PART, a server - * numeric etc... If you want to hook every line that comes from the - * IRC server, you may use the special name of "RAW LINE". - * ret: true... or false if something went wrong while registering - * args: - * * name (string): the event name / numeric (yes, also as a string) - * * prio (number): one of the xchat.PRIO_* constants - * * func_name (string): the function to be called, when the event - * happens - * * data (table)... see xchat.hook_command() - */ -static int lxc_hook_server(lua_State *L) -{ - hexchat_hook *hook; - struct lxc_hooks *hooks, *h; - struct lxc_States *st; - const char *name, *func; - double prio; - - struct lxc_cbdata *cb = malloc(sizeof(struct lxc_cbdata)); - if (!cb) { - hexchat_printf(ph, "lxc_hook_server(): failed to malloc: %s", - strerror(errno)); - lua_pushnil(L); - return 1; - } - - if (lua_gettop(L) < 4) /* expand to 4 args if necessary */ - lua_settop(L, 4); - - name = luaL_checkstring(L, 1); - func = luaL_checkstring(L, 2); - if (lua_type(L, 3) == LUA_TNIL) - prio = HEXCHAT_PRI_NORM; - else - prio = luaL_checknumber(L, 3); - - cb->state = L; - cb->func = func; - cb->data = NULL; - cb->hook = NULL; - - if (lxc_get_userdata(4, cb) == 0) - lua_pushboolean(L, 0); - else { - h = malloc(sizeof(struct lxc_hooks)); - if (!h) { - hexchat_printf(ph, "lxc_hook_server(): failed to malloc: %s", - strerror(errno)); - lua_pushboolean(L, 0); - return 1; - } - hook = hexchat_hook_server(ph, name, prio, lxc_run_hook, cb); - h->hook = hook; - h->name = name; - h->next = NULL; - st = lxc_states; - while (st) { - if (st->state == L) { - if (!st->hooks) - st->hooks = h; - else { - hooks = st->hooks; - while (hooks->next) - hooks = hooks->next; - hooks->next = h; - } - break; - } - st = st->next; - } - lua_pushboolean(L, 1); - } - return 1; -} - -/* - * lua: xchat.hook_timer(timeout, func_name, data) - * desc: Registers a function to be called every "timeout" milliseconds. - * ret: true (or false on error while registering) - * args: - * * timeout (number): Timeout in milliseconds (1000 is 1 second). - * * func_name (string): Callback function. This will be called - * every "timeout" milliseconds. - * * data (table): see xchat.hook_command() - */ - -static unsigned long long lxc_timer_count = 0; - -static int lxc_hook_timer(lua_State *L) -{ - hexchat_hook *hook; - struct lxc_hooks *hooks, *h; - struct lxc_States *st; - double timeout; - const char *func; - char name[32]; - - struct lxc_cbdata *cb = malloc(sizeof(struct lxc_cbdata)); - if (!cb) { - luaL_error(L, "lxc_hook_timer(): failed to malloc: %s", strerror(errno)); - lua_pushnil(L); - return 1; - } - - if (lua_gettop(L) < 3) /* expand to 3 args if necessary */ - lua_settop(L, 3); - - timeout = luaL_checknumber(L, 1); - func = luaL_checkstring(L, 2); - - cb->state = L; - cb->func = func; - cb->data = NULL; - - if (lxc_get_userdata(3, cb) == 0) - lua_pushnil(L); - else { - h = malloc(sizeof(struct lxc_hooks)); - if (!h) { - luaL_error(L, "lxc_hook_timer(): failed to malloc: %s", - strerror(errno)); - return 0; - } - hook = hexchat_hook_timer(ph, timeout, lxc_run_timer, cb); - cb->hook = hook; - h->hook = hook; - h->next = NULL; - snprintf(name, 31, "timer%llu", lxc_timer_count++); - h->name = name; - lua_pushstring(L, name); - - st = lxc_states; - while (st) { - if (st->state == L) { - if (!st->hooks) - st->hooks = h; - else { - hooks = st->hooks; - while (hooks->next) - hooks = hooks->next; - hooks->next = h; - } - break; - } - st = st->next; - } - } - return 1; -} - -static void lxc_unhook_timer(lua_State *L, hexchat_hook *hook) -{ - struct lxc_States *state; - struct lxc_hooks *hooks, *h, *prev_hook; - struct lxc_cbdata *cb; - struct lxc_userdata *ud, *u; - - prev_hook = NULL; - state = lxc_states; - while (state) { - if (state->state == L) { - hooks = state->hooks; - while (hooks) { - if (hooks->hook == hook) { - h = hooks; - if (prev_hook) - prev_hook->next = hooks->next; - else - state->hooks = hooks->next; - - cb = hexchat_unhook(ph, h->hook); - if (cb) { - ud = cb->data; - while (ud) { - u = ud; - ud = ud->next; - free(u); - } - free(cb); - } - - free(h); - return; - } - prev_hook = hooks; - hooks = hooks->next; - } - break; - } - state = state->next; - } -} - -/* - * lua: func_name(data) - * desc: the callback function for the registered timer hook, return - * true to keep this timer going, false to stop it - * ret: none - * args: - * * data (table): the table you gave the hook_timer() as last - * argument - */ - static int lxc_run_timer(void *data) -{ - int ret; - struct lxc_cbdata *cb = data; - hexchat_hook *hook = cb->hook; - lua_State *L = cb->state; - - lua_pushstring(L, cb->func); - lua_gettable(L, LUA_GLOBALSINDEX); - - if (lua_pcall(L, 0, 1, 0)) { - hexchat_printf(ph, "failed to call timer callback for '%s': %s", - cb->func, lua_tostring(L, -1)); - lua_pop(L, 1); - lxc_unhook_timer(L, hook); - return 0; - } - - if (lua_type(L, -1) != LUA_TBOOLEAN) { - hexchat_printf(ph, - "timer callback for '%s' didn't return a boolean", cb->func); - lua_pop(L, 1); - lxc_unhook_timer(L, hook); - return 0; - } - - ret = (lua_toboolean(L, -1) == 0) ? 0 : 1; - lua_pop(L, 1); - - if (ret == 0) - lxc_unhook_timer(L, hook); - - return ret; -} - -/* - * lua: xchat.unhook(name) - * desc: unhooks a previously hooked hook - * ret: true if the hook existed, else false.. - * args: - * * name (string): name of a registered hook (e.g. with - * xchat.hook_command("whois", ... ) you would unhook "whois" - * ... see timer warnings... there's currently just one "timer" - * to unhook - */ -static int lxc_unhook(lua_State *L) -{ - struct lxc_States *state; - struct lxc_hooks *hooks, *h, *prev_hook; - struct lxc_cbdata *cb; - struct lxc_userdata *ud, *u; - int done = 0; - const char *name = luaL_checkstring(L, 1); - - prev_hook = NULL; - state = lxc_states; - while (state) { - if (state->state == L) { - hooks = state->hooks; - while (hooks) { - if (strcasecmp(hooks->name, name) == 0) { - h = hooks; - if (prev_hook) - prev_hook->next = hooks->next; - else - state->hooks = hooks->next; - - cb = hexchat_unhook(ph, h->hook); - if (cb) { - ud = cb->data; - while (ud) { - u = ud; - ud = ud->next; - free(u); - } - free(cb); - } - - free(h); - done = 1; - break; - } - prev_hook = hooks; - hooks = hooks->next; - } - break; - } - state = state->next; - } - lua_pushboolean(L, done); - return 1; -} - -static int lxc_event(lua_State *L) -{ - lua_pushstring(L, lxc_event_name); - return 1; -} - -/* - * lua: xchat.command(command) - * desc: executes a command as if it were typed in xchat's input box. - * ret: none - * args: - * * command (string): command to execute, without the forward slash "/". - */ -static int lxc_command(lua_State *L) -{ - const char *command = luaL_checkstring(L, 1); - hexchat_command(ph, command); - return 0; -} - -/* - * lua: xchat.print(text) - * desc: Prints some text to the current tab/window. - * ret: none - * args: - * * text (string): the text to print - */ -static int lxc_print(lua_State *L) -{ - const char *txt = luaL_checkstring(L, 1); - // FIXME? const char *txt = lua_tostring(L, 1); - hexchat_print(ph, txt); - return 0; -} - -/* - * lua: xchat.emit_print(event, text, [text2, ...]) - * desc: Generates a print event. This can be any event found in the - * Preferences > Advanced > Text Events window. The vararg parameter - * list MUST be no longer than four (4) parameters. - * Special care should be taken when calling this function inside a - * print callback (from xchat.hook_print()), as not to cause endless - * recursion. - * ret: true on success, false on error - * args: - * * event (string): the event name from the references > Advanced > - * Text Events window - * * text (string) - * text2 (string) - * ... (string(s)): - * parameters for the given event - */ -static int lxc_emit_print(lua_State *L) -{ - - int n = lua_gettop(L); - const char *text[5]; - const char *event; - int i = 2; - - if (n > 6) - luaL_error(L, "too many arguments to xchat.emit_print()"); - - event = luaL_checkstring(L, 1); - while (i <= n) { - text[i-2] = luaL_checkstring(L, i); - i++; - } - switch (n-1) { - case 0: - i = hexchat_emit_print(ph, event, NULL); - break; - case 1: - i = hexchat_emit_print(ph, event, text[0], NULL); - break; - case 2: - i = hexchat_emit_print(ph, event, text[0], text[1], NULL); - break; - case 3: - i = hexchat_emit_print(ph, event, text[0], text[1], text[2], NULL); - break; - case 4: - i = hexchat_emit_print(ph, event, text[0], text[1], text[2], text[3], NULL); - break; - } - lua_pushboolean(L, (i == 0) ? 0 : 1); - return 1; -} - -/* - * lua: xchat.send_modes(targets, sign, mode [, modes_per_line]) - * desc: Sends a number of channel mode changes to the current channel. - * For example, you can Op a whole group of people in one go. It may - * send multiple MODE lines if the request doesn't fit on one. Pass 0 - * for modes_per_line to use the current server's maximum possible. - * This function should only be called while in a channel context. - * ret: none - * args: - * * targets (table): list of names - * * sign (string): mode sign, i.e. "+" or "-", only the first char of - * this is used (currently unchecked if it's really "+" or "-") - * * mode (string): mode char, i.e. "o" for opping, only the first - * char of this is used (currently unchecked, what char) - * * modes_per_line (number): [optional] number of modes per line - */ -static int lxc_send_modes(lua_State *L) -{ - int i = 1; - const char *name, *mode, *sign; - const char *targets[4096]; - int num = 0; /* modes per line */ - - if (!lua_istable(L, 1)) { - luaL_error(L, - "xchat.send_modes(): first argument is not a table: %s", - lua_typename(L, lua_type(L, 1))); - return 0; - } - - while (1) { - lua_pushnumber(L, i); /* push index on stack */ - lua_gettable(L, 1); /* and get the element @ index */ - if (lua_isnil(L, -1)) { /* end of table */ - lua_pop(L, 1); - break; - } - - if (lua_type(L, -1) != LUA_TSTRING) { /* oops, something wrong */ - luaL_error(L, - "lua: xchat.send_modes(): table element #%d not a string: %s", - i, lua_typename(L, lua_type(L, -1))); - lua_pop(L, 1); - return 0; - } - - name = lua_tostring(L, -1); - if (name == NULL) { /* this should not happen, but... */ - lua_pop(L, 1); - break; - } - - targets[i-1] = name; - lua_pop(L, 1); /* take index from stack */ - ++i; - } - - sign = luaL_checkstring(L, 2); - if (sign[0] == '\0' || sign[1] != '\0') { - luaL_error(L, "argument #2 (mode sign) does not have length 1"); - return 0; - } - if ((sign[0] != '+') && (sign[0] != '-')) { - luaL_error(L, "argument #2 (mode sign) is not '+' or '-'"); - return 0; - } - - mode = luaL_checkstring(L, 3); - if (mode[0] == '\0' || mode[1] != '\0') { - luaL_error(L, "argument #3 (mode char) does not have length 1"); - return 0; - } - if (!isalpha((int)mode[0]) || !isascii((int)mode[0])) { - luaL_error(L, "argument #3 is not a valid mode character"); - return 0; - } - - if (lua_gettop(L) == 4) - num = luaL_checknumber(L, 4); - - hexchat_send_modes(ph, targets, i-1, num, sign[0], mode[0]); - return 0; -} - -/* - * lua: xchat.find_context(srv, chan) - * desc: Finds a context based on a channel and servername. If servname is nil, - * it finds any channel (or query) by the given name. If channel is nil, - * it finds the front-most tab/window of the given servname. If nil is - * given for both arguments, the currently focused tab/window will be - * returned. - * Changed in 2.6.1. If servname is nil, it finds the channel (or query) - * by the given name in the same server group as the current context. - * If that doesn't exists then find any by the given name. - * ret: context number (DON'T modify) - * args: - * * srv (string or nil): server name - * * chan (string or nil): channel / query name - */ -static int lxc_find_context(lua_State *L) -{ - const char *srv, *chan; - long ctx; - hexchat_context *ptr; - - if (lua_type(L, 1) == LUA_TSTRING) { - srv = lua_tostring(L, 1); - if (srv[0] == '\0') - srv = NULL; - } - else - srv = NULL; - - if (lua_type(L, 2) == LUA_TSTRING) { - chan = lua_tostring(L, 2); - if (chan[0] == '\0') - chan = NULL; - } - else - chan = NULL; - - ptr = hexchat_find_context(ph, srv, chan); - ctx = (long)ptr; -#ifdef DEBUG - fprintf(stderr, "find_context(): %#lx\n", (long)ptr); -#endif - lua_pushnumber(L, (double)ctx); - return 1; -} - -/* - * lua: xchat.get_context() - * desc: Returns the current context for your plugin. You can use this later - * with hexchat_set_context. - * ret: context number ... DON'T modifiy - * args: none - */ -static int lxc_get_context(lua_State *L) -{ - long ptr; - hexchat_context *ctx = hexchat_get_context(ph); - ptr = (long)ctx; -#ifdef DEBUG - fprintf(stderr, "get_context(): %#lx\n", ptr); -#endif - lua_pushnumber(L, (double)ptr); - return 1; -} - -/* - * lua: xchat.get_info(id) - * desc: Returns information based on your current context. - * ret: the requested string or nil on error - * args: - * * id (string): the wanted information - */ -static int lxc_get_info(lua_State *L) -{ - const char *id = luaL_checkstring(L, 1); - const char *value = hexchat_get_info(ph, id); - if (value == NULL) - lua_pushnil(L); - else - lua_pushstring(L, value); - return 1; -} - -/* - * lua: hexchat.get_prefs(name) - * desc: Provides xchat's setting information (that which is available - * through the /set command). A few extra bits of information are - * available that don't appear in the /set list, currently they are: - * * state_cursor: Current input-box cursor position (characters, - * not bytes). Since 2.4.2. - * *id: Unique server id. Since 2.6.1. - * ret: returns the string/number/boolean for the given config var - * or nil on error - * args: - * * name (string): the wanted setting's name - */ -static int lxc_get_prefs(lua_State *L) -{ - int i; - const char *str; - const char *name = luaL_checkstring(L, 1); - /* - * luckily we can store anything in a lua var... this makes the - * xchat lua api more user friendly ;-) - */ - switch (hexchat_get_prefs(ph, name, &str, &i)) { - case 0: /* request failed */ - lua_pushnil(L); - break; - case 1: - lua_pushstring(L, str); - break; - case 2: - lua_pushnumber(L, (double)i); - break; - case 3: - lua_pushboolean(L, i); - break; - default: /* doesn't happen if xchat's C-API doesn't change ;-) */ - lua_pushnil(L); - break; - } - return 1; -} - -/* - * lua: xchat.set_context(ctx) - * desc: Changes your current context to the one given. - * ret: true or false - * args: - * * ctx (number): the context (e.g. from xchat.get_context()) - */ -static int lxc_set_context(lua_State *L) -{ - double ctx = luaL_checknumber(L, 1); -#ifdef DEBUG - fprintf(stderr, "set_context(): %#lx\n", (long)ctx); -#endif - hexchat_context *xc = (void *)(long)ctx; - lua_pushboolean(L, hexchat_set_context(ph, xc)); - return 1; -} - -/* - * lua: xchat.nickcmp(name1, name2) - * desc: Performs a nick name comparision, based on the current server - * connection. This might be a RFC1459 compliant string compare, or - * plain ascii (in the case of DALNet). Use this to compare channels - * and nicknames. The function works the same way as strcasecmp. - * ret: number ess than, equal to, or greater than zero if name1 is found, - * respectively, to be less than, to match, or be greater than name2. - * args: - * * name1 (string): nick or channel name - * * name2 (string): nick or channel name - */ -static int lxc_nickcmp(lua_State *L) -{ - const char *n1 = luaL_checkstring(L, 1); - const char *n2 = luaL_checkstring(L, 2); - lua_pushnumber(L, (double)hexchat_nickcmp(ph, n1, n2)); - return 1; -} - -/* - * lua: xchat.list_get(name) - * desc: http://xchat.org/docs/plugin20.html#lists :) - * time_t values are stored as number => e.g. - * os.date("%Y-%m-%d, %H:%M:%S", time_t_value) - * pointers (channel -> context) as number... untested if this works - * ret: table with tables with all keys=Name, value=(Type)... or nil on error - * args: - * * name (string): the wanted list - */ -static int lxc_list_get(lua_State *L) -{ - const char *name = luaL_checkstring(L, 1); - int i; /* item index */ - int l; /* list index */ - const char *str; - double num; - time_t date; - long ptr; - const char *const *fields = hexchat_list_fields(ph, name); - hexchat_list *list = hexchat_list_get(ph, name); - - if (!list) { - lua_pushnil(L); - return 1; - } - lua_newtable(L); - /* this is like the perl plugin does it ;-) */ - l = 1; - while (hexchat_list_next(ph, list)) { - i = 0; - lua_pushnumber(L, l); - lua_newtable(L); - while (fields[i] != NULL) { - switch (fields[i][0]) { - case 's': - str = hexchat_list_str(ph, list, fields [i] + 1); - lua_pushstring(L, fields[i]+1); - if (str != NULL) - lua_pushstring(L, str); - else - lua_pushnil(L); - lua_settable(L, -3); - break; - case 'p': - ptr = (long)hexchat_list_str(ph, list, fields [i] + 1); - num = (double)ptr; - lua_pushstring(L, fields[i]+1); - lua_pushnumber(L, num); - lua_settable(L, -3); - break; - case 'i': - num = (double)hexchat_list_int(ph, list, fields[i] + 1); - lua_pushstring(L, fields[i]+1); - lua_pushnumber(L, num); - lua_settable(L, -3); - break; - case 't': - date = hexchat_list_time(ph, list, fields[i] + 1); - lua_pushstring(L, fields[i]+1); - lua_pushnumber(L, (double)date); - lua_settable(L, -3); - break; - } - i++; - } - lua_settable(L, -3); - l++; - } - hexchat_list_free(ph, list); - return 1; -} - -/* - * lua: xchat.list_fields(name) - * desc: returns the possible keys for name as table - * ret: table ;-> - * args: - * * name (string): name of the wanted list ("channels", "dcc", - * "ignore", "notify", "users") - */ -static int lxc_list_fields(lua_State *L) -{ - const char *name = luaL_checkstring(L, 1); - const char *const *fields = hexchat_list_fields(ph, name); - int i; - - lua_newtable(L); - i = 0; - while (fields[i] != NULL) { - lua_pushnumber(L, i); - /* first char is the type ... */ - lua_pushstring(L, fields[i]+1); - lua_settable(L, -3); - } - return 1; -} - -/* - * lua: xchat.gettext(str) - * desc: - */ -static int lxc_gettext(lua_State *L) -{ -#if defined(_WIN32) || defined(LXC_XCHAT_GETTEXT) - lua_pushstring(L, hexchat_gettext(ph, luaL_checkstring(L, 1))); -#else - const char *dom; - const char *msgid = luaL_checkstring(L, 1); - if (lua_type(L,2) == LUA_TSTRING) - dom = lua_tostring(L, 2); - else - dom = "xchat"; - lua_pushstring(L, dgettext(dom, msgid)); -#endif - return 1; -} - -/* - * lua: xchat.bits(flags) - * desc: returns a table of booleans if the bit at index (err... index-1) is - * set - * ret: table of booleans - * args: - * * flags (number) - */ -static int lxc_bits(lua_State *L) -{ - int flags = luaL_checknumber(L, 1); - int i; - lua_pop(L, 1); - lua_newtable(L); - for (i=0; i<16; i++) { /* at time of writing, the highest index was 9 ... */ - lua_pushnumber(L, i+1); - lua_pushboolean(L, ((1< - - - - Release - Win32 - - - Release - x64 - - - - {646B4316-C8B8-4DB6-B6AE-E586929E5729} - Win32Proj - lua - - - - DynamicLibrary - false - true - MultiByte - - - DynamicLibrary - false - true - MultiByte - - - - - - - - - - - - - - - false - $(LuaOutput) - $(HexChatBin) - $(HexChatObj)$(ProjectName)\ - - - false - $(LuaOutput) - $(HexChatBin) - $(HexChatObj)$(ProjectName)\ - - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;LUA_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions) - $(DepsRoot)\include;..\..\src\common;$(Glib);%(AdditionalIncludeDirectories) - - - Windows - true - true - true - $(DepsRoot)\lib;$(OutDir);%(AdditionalLibraryDirectories) - "$(LuaLib).lib";%(AdditionalDependencies) - - - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;LUA_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions) - $(DepsRoot)\include;..\..\src\common;$(Glib);%(AdditionalIncludeDirectories) - - - Windows - true - true - true - $(DepsRoot)\lib;$(OutDir);%(AdditionalLibraryDirectories) - "$(LuaLib).lib";%(AdditionalDependencies) - - - - - "$(LuaLib).lib";$(DepLibs);%(AdditionalDependencies) - - - - - "$(LuaLib).lib";$(DepLibs);%(AdditionalDependencies) - - - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;$(OwnFlags);snprintf=g_snprintf;%(PreprocessorDefinitions) - true - - - lua.def - - - - - WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;$(OwnFlags);snprintf=g_snprintf;%(PreprocessorDefinitions) - true - - - lua.def - - - - - - - - - - - - \ No newline at end of file diff --git a/plugins/lua/lua.vcxproj.filters b/plugins/lua/lua.vcxproj.filters deleted file mode 100644 index 9c7e3d89..00000000 --- a/plugins/lua/lua.vcxproj.filters +++ /dev/null @@ -1,23 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Resource Files - - - - - Source Files - - - \ No newline at end of file diff --git a/plugins/tcl/Makefile.am b/plugins/tcl/Makefile.am deleted file mode 100644 index 24228ce8..00000000 --- a/plugins/tcl/Makefile.am +++ /dev/null @@ -1,10 +0,0 @@ - -EXTRA_DIST=printevents.h tclplugin.h README - -libdir = $(hexchatlibdir)/plugins - -lib_LTLIBRARIES = tcl.la -tcl_la_SOURCES = tclplugin.c -tcl_la_LDFLAGS = -avoid-version -module -tcl_la_LIBADD = $(TCL_LIBS) -AM_CPPFLAGS = $(TCL_CFLAGS) $(COMMON_CFLAGS) -I$(srcdir)/../../src/common diff --git a/plugins/tcl/printevents.h b/plugins/tcl/printevents.h deleted file mode 100644 index 09937b2b..00000000 --- a/plugins/tcl/printevents.h +++ /dev/null @@ -1,319 +0,0 @@ -/*************************************************************************** - printevents.h - TCL plugin header file - ------------------------------------------------- - begin : Sat Nov 9 17:31:20 MST 2002 - copyright : Copyright 2002-2007 Daniel P. Stasinski - copyright : Copyright 2002-2012 Daniel P. Stasinski - email : daniel@GenericInbox.com - ***************************************************************************/ - -/*************************************************************************** - * * - * 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. * - * * - ***************************************************************************/ - -typedef struct { - char *event; - char *emit; - int argc; - hexchat_hook *hook; -} print_event; - -enum -{ - CHAT, - XC_APPFOCUS, - XC_TABOPEN, - XC_TABCLOSE, - XC_TABFOCUS, - XC_KEYPRESS, - XC_ADDNOTIFY, - XC_BANLIST, - XC_BANNED, - XC_BEEP, - XC_CHANGENICK, - XC_CHANACTION, - XC_HCHANACTION, - XC_CHANBAN, - XC_CHANDATE, - XC_CHANDEHOP, - XC_CHANDEOP, - XC_CHANDEVOICE, - XC_CHANEXEMPT, - XC_CHANHOP, - XC_CHANINVITE, - XC_CHANLISTHEAD, - XC_CHANMSG, - XC_CHANMODEGEN, - XC_CHANMODES, - XC_HCHANMSG, - XC_CHANNOTICE, - XC_CHANOP, - XC_CHANRMEXEMPT, - XC_CHANRMINVITE, - XC_CHANRMKEY, - XC_CHANRMLIMIT, - XC_CHANSETKEY, - XC_CHANSETLIMIT, - XC_CHANUNBAN, - XC_CHANVOICE, - XC_CONNECTED, - XC_CONNECT, - XC_CONNFAIL, - XC_CTCPGEN, - XC_CTCPGENC, - XC_CTCPSEND, - XC_CTCPSND, - XC_CTCPSNDC, - XC_DCCCHATABORT, - XC_DCCCONCHAT, - XC_DCCCHATF, - XC_DCCCHATOFFER, - XC_DCCCHATOFFERING, - XC_DCCCHATREOFFER, - XC_DCCCONFAIL, - XC_DCCGENERICOFFER, - XC_DCCHEAD, - XC_MALFORMED, - XC_DCCOFFER, - XC_DCCIVAL, - XC_DCCRECVABORT, - XC_DCCRECVCOMP, - XC_DCCCONRECV, - XC_DCCRECVERR, - XC_DCCFILEERR, - XC_DCCRENAME, - XC_DCCRESUMEREQUEST, - XC_DCCSENDABORT, - XC_DCCSENDCOMP, - XC_DCCCONSEND, - XC_DCCSENDFAIL, - XC_DCCSENDOFFER, - XC_DCCSTALL, - XC_DCCTOUT, - XC_DELNOTIFY, - XC_DISCON, - XC_FOUNDIP, - XC_GENMSG, - XC_IGNOREADD, - XC_IGNORECHANGE, - XC_IGNOREFOOTER, - XC_IGNOREHEADER, - XC_IGNOREREMOVE, - XC_IGNOREEMPTY, - XC_INVITE, - XC_INVITED, - XC_JOIN, - XC_KEYWORD, - XC_KICK, - XC_KILL, - XC_MSGSEND, - XC_MOTD, - XC_MOTDSKIP, - XC_NICKCLASH, - XC_NICKFAIL, - XC_NODCC, - XC_NOCHILD, - XC_NOTICE, - XC_NOTICESEND, - XC_NOTIFYEMPTY, - XC_NOTIFYHEAD, - XC_NOTIFYNUMBER, - XC_NOTIFYOFFLINE, - XC_NOTIFYONLINE, - XC_OPENDIALOG, - XC_PART, - XC_PARTREASON, - XC_PINGREP, - XC_PINGTIMEOUT, - XC_PRIVMSG, - XC_DPRIVMSG, - XC_ALREADYPROCESS, - XC_QUIT, - XC_RAWMODES, - XC_WALLOPS, - XC_RESOLVINGUSER, - XC_SERVERCONNECTED, - XC_SERVERERROR, - XC_SERVERLOOKUP, - XC_SERVNOTICE, - XC_SERVTEXT, - XC_STOPCONNECT, - XC_TOPIC, - XC_NEWTOPIC, - XC_TOPICDATE, - XC_UKNHOST, - XC_USERLIMIT, - XC_USERSONCHAN, - XC_WHOIS_AUTH, - XC_WHOIS5, - XC_WHOIS2, - XC_WHOIS6, - XC_WHOIS_ID, - XC_WHOIS4, - XC_WHOIS4T, - XC_WHOIS1, - XC_WHOIS_REALHOST, - XC_WHOIS3, - XC_WHOIS_SPECIAL, - XC_UJOIN, - XC_UKICK, - XC_UPART, - XC_UPARTREASON, - XC_UACTION, - XC_UINVITE, - XC_UCHANMSG, - XC_UCHANGENICK, - XC_SIZE -}; - -static print_event xc[] = { - { "CHAT", "DCC Chat Text", -1, NULL }, - { "XC_APPFOCUS", "Focus Window", -3, NULL }, - { "XC_TABOPEN", "Open Context", -2, NULL }, - { "XC_TABCLOSE", "Close Context", -2, NULL }, - { "XC_TABFOCUS", "Focus Tab", -2, NULL }, - { "XC_KEYPRESS", "Key Press", 4, NULL }, - { "XC_ADDNOTIFY", "Add Notify", 1, NULL }, - { "XC_BANLIST", "Ban List", 4, NULL }, - { "XC_BANNED", "Banned", 1, NULL }, - { "XC_BEEP", "Beep", 0, NULL }, - { "XC_CHANGENICK", "Change Nick", 2, NULL }, - { "XC_CHANACTION", "Channel Action", 3, NULL }, - { "XC_HCHANACTION", "Channel Action Hilight", 3, NULL }, - { "XC_CHANBAN", "Channel Ban", 2, NULL }, - { "XC_CHANDATE", "Channel Creation", 2, NULL }, - { "XC_CHANDEHOP", "Channel DeHalfOp", 2, NULL }, - { "XC_CHANDEOP", "Channel DeOp", 2, NULL }, - { "XC_CHANDEVOICE", "Channel DeVoice", 2, NULL }, - { "XC_CHANEXEMPT", "Channel Exempt", 2, NULL }, - { "XC_CHANHOP", "Channel Half-Operator", 2, NULL }, - { "XC_CHANINVITE", "Channel INVITE", 2, NULL }, - { "XC_CHANLISTHEAD", "Channel List", 0, NULL }, - { "XC_CHANMSG", "Channel Message", 4, NULL }, - { "XC_CHANMODEGEN", "Channel Mode Generic", 4, NULL }, - { "XC_CHANMODES", "Channel Modes", 2, NULL }, - { "XC_HCHANMSG", "Channel Msg Hilight", 4, NULL }, - { "XC_CHANNOTICE", "Channel Notice", 3, NULL }, - { "XC_CHANOP", "Channel Operator", 2, NULL }, - { "XC_CHANRMEXEMPT", "Channel Remove Exempt", 2, NULL }, - { "XC_CHANRMINVITE", "Channel Remove Invite", 2, NULL }, - { "XC_CHANRMKEY", "Channel Remove Keyword", 1, NULL }, - { "XC_CHANRMLIMIT", "Channel Remove Limit", 1, NULL }, - { "XC_CHANSETKEY", "Channel Set Key", 2, NULL }, - { "XC_CHANSETLIMIT", "Channel Set Limit", 2, NULL }, - { "XC_CHANUNBAN", "Channel UnBan", 2, NULL }, - { "XC_CHANVOICE", "Channel Voice", 2, NULL }, - { "XC_CONNECTED", "Connected", 0, NULL }, - { "XC_CONNECT", "Connecting", 3, NULL }, - { "XC_CONNFAIL", "Connection Failed", 1, NULL }, - { "XC_CTCPGEN", "CTCP Generic", 2, NULL }, - { "XC_CTCPGENC", "CTCP Generic to Channel", 3, NULL }, - { "XC_CTCPSEND", "CTCP Send", 2, NULL }, - { "XC_CTCPSND", "CTCP Sound", 2, NULL }, - { "XC_CTCPSNDC", "CTCP Sound to Channel", 3, NULL }, - { "XC_DCCCHATABORT", "DCC CHAT Abort", 1, NULL }, - { "XC_DCCCONCHAT", "DCC CHAT Connect", 2, NULL }, - { "XC_DCCCHATF", "DCC CHAT Failed", 4, NULL }, - { "XC_DCCCHATOFFER", "DCC CHAT Offer", 1, NULL }, - { "XC_DCCCHATOFFERING", "DCC CHAT Offering", 1, NULL }, - { "XC_DCCCHATREOFFER", "DCC CHAT Reoffer", 1, NULL }, - { "XC_DCCCONFAIL", "DCC Conection Failed", 3, NULL }, - { "XC_DCCGENERICOFFER", "DCC Generic Offer", 2, NULL }, - { "XC_DCCHEAD", "DCC Header", 0, NULL }, - { "XC_MALFORMED", "DCC Malformed", 2, NULL }, - { "XC_DCCOFFER", "DCC Offer", 3, NULL }, - { "XC_DCCIVAL", "DCC Offer Not Valid", 0, NULL }, - { "XC_DCCRECVABORT", "DCC RECV Abort", 2, NULL }, - { "XC_DCCRECVCOMP", "DCC RECV Complete", 4, NULL }, - { "XC_DCCCONRECV", "DCC RECV Connect", 3, NULL }, - { "XC_DCCRECVERR", "DCC RECV Failed", 4, NULL }, - { "XC_DCCFILEERR", "DCC RECV File Open Error", 2, NULL }, - { "XC_DCCRENAME", "DCC Rename", 2, NULL }, - { "XC_DCCRESUMEREQUEST", "DCC RESUME Request", 3, NULL }, - { "XC_DCCSENDABORT", "DCC SEND Abort", 2, NULL }, - { "XC_DCCSENDCOMP", "DCC SEND Complete", 3, NULL }, - { "XC_DCCCONSEND", "DCC SEND Connect", 3, NULL }, - { "XC_DCCSENDFAIL", "DCC SEND Failed", 3, NULL }, - { "XC_DCCSENDOFFER", "DCC SEND Offer", 4, NULL }, - { "XC_DCCSTALL", "DCC Stall", 3, NULL }, - { "XC_DCCTOUT", "DCC Timeout", 3, NULL }, - { "XC_DELNOTIFY", "Delete Notify", 1, NULL }, - { "XC_DISCON", "Disconnected", 1, NULL }, - { "XC_FOUNDIP", "Found IP", 1, NULL }, - { "XC_GENMSG", "Generic Message", 2, NULL }, - { "XC_IGNOREADD", "Ignore Add", 1, NULL }, - { "XC_IGNORECHANGE", "Ignore Changed", 1, NULL }, - { "XC_IGNOREFOOTER", "Ignore Footer", 0, NULL }, - { "XC_IGNOREHEADER", "Ignore Header", 0, NULL }, - { "XC_IGNOREREMOVE", "Ignore Remove", 1, NULL }, - { "XC_IGNOREEMPTY", "Ignorelist Empty", 0, NULL }, - { "XC_INVITE", "Invite", 1, NULL }, - { "XC_INVITED", "Invited", 3, NULL }, - { "XC_JOIN", "Join", 3, NULL }, - { "XC_KEYWORD", "Keyword", 1, NULL }, - { "XC_KICK", "Kick", 4, NULL }, - { "XC_KILL", "Killed", 2, NULL }, - { "XC_MSGSEND", "Message Send", 2, NULL }, - { "XC_MOTD", "Motd", 1, NULL }, - { "XC_MOTDSKIP", "MOTD Skipped", 0, NULL }, - { "XC_NICKCLASH", "Nick Clash", 2, NULL }, - { "XC_NICKFAIL", "Nick Failed", 0, NULL }, - { "XC_NODCC", "No DCC", 0, NULL }, - { "XC_NOCHILD", "No Running Process", 0, NULL }, - { "XC_NOTICE", "Notice", 2, NULL }, - { "XC_NOTICESEND", "Notice Send", 2, NULL }, - { "XC_NOTIFYEMPTY", "Notify Empty", 0, NULL }, - { "XC_NOTIFYHEAD", "Notify Header", 0, NULL }, - { "XC_NOTIFYNUMBER", "Notify Number", 1, NULL }, - { "XC_NOTIFYOFFLINE", "Notify Offline", 3, NULL }, - { "XC_NOTIFYONLINE", "Notify Online", 3, NULL }, - { "XC_OPENDIALOG", "Open Dialog", 0, NULL }, - { "XC_PART", "Part", 3, NULL }, - { "XC_PARTREASON", "Part with Reason", 4, NULL }, - { "XC_PINGREP", "Ping Reply", 2, NULL }, - { "XC_PINGTIMEOUT", "Ping Timeout", 1, NULL }, - { "XC_PRIVMSG", "Private Message", 3, NULL }, - { "XC_DPRIVMSG", "Private Message to Dialog", 3, NULL }, - { "XC_ALREADYPROCESS", "Process Already Running", 0, NULL }, - { "XC_QUIT", "Quit", 3, NULL }, - { "XC_RAWMODES", "Raw Modes", 2, NULL }, - { "XC_WALLOPS", "Receive Wallops", 2, NULL }, - { "XC_RESOLVINGUSER", "Resolving User", 2, NULL }, - { "XC_SERVERCONNECTED", "Server Connected", 0, NULL }, - { "XC_SERVERERROR", "Server Error", 1, NULL }, - { "XC_SERVERLOOKUP", "Server Lookup", 1, NULL }, - { "XC_SERVNOTICE", "Server Notice", 2, NULL }, - { "XC_SERVTEXT", "Server Text", 2, NULL }, - { "XC_STOPCONNECT", "Stop Connection", 1, NULL }, - { "XC_TOPIC", "Topic", 2, NULL }, - { "XC_NEWTOPIC", "Topic Change", 3, NULL }, - { "XC_TOPICDATE", "Topic Creation", 3, NULL }, - { "XC_UKNHOST", "Unknown Host", 0, NULL }, - { "XC_USERLIMIT", "User Limit", 1, NULL }, - { "XC_USERSONCHAN", "Users On Channel", 2, NULL }, - { "XC_WHOIS_AUTH", "WhoIs Authenticated", 3, NULL }, - { "XC_WHOIS5", "WhoIs Away Line", 2, NULL }, - { "XC_WHOIS2", "WhoIs Channel/Oper Line", 2, NULL }, - { "XC_WHOIS6", "WhoIs End", 1, NULL }, - { "XC_WHOIS_ID", "WhoIs Identified", 2, NULL }, - { "XC_WHOIS4", "WhoIs Idle Line", 2, NULL }, - { "XC_WHOIS4T", "WhoIs Idle Line with Signon", 3, NULL }, - { "XC_WHOIS1", "WhoIs Name Line", 4, NULL }, - { "XC_WHOIS_REALHOST", "WhoIs Real Host", 4, NULL }, - { "XC_WHOIS3", "WhoIs Server Line", 2, NULL }, - { "XC_WHOIS_SPECIAL", "WhoIs Special", 3, NULL }, - { "XC_UJOIN", "You Join", 3, NULL }, - { "XC_UKICK", "You Kicked", 4, NULL }, - { "XC_UPART", "You Part", 3, NULL }, - { "XC_UPARTREASON", "You Part with Reason", 4, NULL }, - { "XC_UACTION", "Your Action", 3, NULL }, - { "XC_UINVITE", "Your Invitation", 3, NULL }, - { "XC_UCHANMSG", "Your Message", 4, NULL }, - { "XC_UCHANGENICK", "Your Nick Changing", 2, NULL } -}; - diff --git a/plugins/tcl/tcl-xp.vcxproj b/plugins/tcl/tcl-xp.vcxproj deleted file mode 100644 index 504f8216..00000000 --- a/plugins/tcl/tcl-xp.vcxproj +++ /dev/null @@ -1,113 +0,0 @@ - - - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - {2773666A-8CFC-4533-A043-EAD59F16A1C7} - Win32Proj - tcl - tcl - - - - DynamicLibrary - false - true - MultiByte - WDK7 - - - DynamicLibrary - false - true - MultiByte - WDK7 - - - - - - - - - - - - - - - false - $(TclOutput) - $(HexChatBin) - $(HexChatObj)$(ProjectName)\ - - - false - $(TclOutput) - $(HexChatBin) - $(HexChatObj)$(ProjectName)\ - - - - NotUsing - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;TCL_EXPORTS;TCL_DLL="$(TclLib).dll";$(OwnFlags);%(PreprocessorDefinitions) - $(TclPath)\include;..\..\src\common;%(AdditionalIncludeDirectories) - true - - - Windows - true - true - true - $(TclPath)\lib;%(AdditionalLibraryDirectories) - "$(TclLib).lib";%(AdditionalDependencies) - tcl.def - $(TclLib).dll;%(DelayLoadDLLs) - - - - - NotUsing - MaxSpeed - true - true - WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;TCL_EXPORTS;TCL_DLL="$(TclLib).dll";$(OwnFlags);%(PreprocessorDefinitions) - $(TclPath)\include;..\..\src\common;%(AdditionalIncludeDirectories) - true - - - Windows - true - true - true - $(TclPath)\lib;%(AdditionalLibraryDirectories) - "$(TclLib).lib";%(AdditionalDependencies) - tcl.def - $(TclLib).dll;%(DelayLoadDLLs) - - - - - - \ No newline at end of file diff --git a/plugins/tcl/tcl-xp.vcxproj.filters b/plugins/tcl/tcl-xp.vcxproj.filters deleted file mode 100644 index 43f63d84..00000000 --- a/plugins/tcl/tcl-xp.vcxproj.filters +++ /dev/null @@ -1,35 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - - - Source Files - - - - - Resource Files - - - \ No newline at end of file diff --git a/plugins/tcl/tcl.def b/plugins/tcl/tcl.def deleted file mode 100644 index 6ce04e98..00000000 --- a/plugins/tcl/tcl.def +++ /dev/null @@ -1,4 +0,0 @@ -EXPORTS -hexchat_plugin_init -hexchat_plugin_deinit -hexchat_plugin_get_info diff --git a/plugins/tcl/tcl.vcxproj b/plugins/tcl/tcl.vcxproj deleted file mode 100644 index 955f8736..00000000 --- a/plugins/tcl/tcl.vcxproj +++ /dev/null @@ -1,110 +0,0 @@ - - - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - {2773666A-8CFC-4533-A043-EAD59F16A1C7} - Win32Proj - tcl - - - - DynamicLibrary - false - true - MultiByte - - - DynamicLibrary - false - true - MultiByte - - - - - - - - - - - - - - - false - $(TclOutput) - $(HexChatBin) - $(HexChatObj)$(ProjectName)\ - - - false - $(TclOutput) - $(HexChatBin) - $(HexChatObj)$(ProjectName)\ - - - - NotUsing - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;TCL_EXPORTS;TCL_DLL="$(TclLib).dll";$(OwnFlags);%(PreprocessorDefinitions) - $(TclPath)\include;..\..\src\common;%(AdditionalIncludeDirectories) - true - - - Windows - true - true - true - $(TclPath)\lib;%(AdditionalLibraryDirectories) - "$(TclLib).lib";%(AdditionalDependencies) - tcl.def - $(TclLib).dll;%(DelayLoadDLLs) - - - - - NotUsing - MaxSpeed - true - true - WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;TCL_EXPORTS;TCL_DLL="$(TclLib).dll";$(OwnFlags);%(PreprocessorDefinitions) - $(TclPath)\include;..\..\src\common;%(AdditionalIncludeDirectories) - true - - - Windows - true - true - true - $(TclPath)\lib;%(AdditionalLibraryDirectories) - "$(TclLib).lib";%(AdditionalDependencies) - tcl.def - $(TclLib).dll;%(DelayLoadDLLs) - - - - - - \ No newline at end of file diff --git a/plugins/tcl/tcl.vcxproj.filters b/plugins/tcl/tcl.vcxproj.filters deleted file mode 100644 index 43f63d84..00000000 --- a/plugins/tcl/tcl.vcxproj.filters +++ /dev/null @@ -1,35 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - - - Source Files - - - - - Resource Files - - - \ No newline at end of file diff --git a/plugins/tcl/tclplugin.c b/plugins/tcl/tclplugin.c deleted file mode 100644 index b03e7bac..00000000 --- a/plugins/tcl/tclplugin.c +++ /dev/null @@ -1,2294 +0,0 @@ -/*************************************************************************** - tclplugin.c - Tcl plugin for xchat 1.9.x / 2.x.x - -------------------------------------------------s - begin : Sat Nov 19 17:31:20 MST 2002 - copyright : Copyright 2002-2012 Daniel P. Stasinski - email : daniel@GenericInbox.com - ***************************************************************************/ - -/*************************************************************************** - * * - * 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. * - * * - ***************************************************************************/ - -static char RCSID[] = "$Id: tclplugin.c,v 1.65 2012/07/26 20:02:12 mooooooo Exp $"; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef WIN32 -#include -#include "../../src/common/typedef.h" -#define bzero(mem, sz) memset((mem), 0, (sz)) -#define bcopy(src, dest, count) memmove((dest), (src), (count)) -#else -#include -#endif - -#include "hexchat-plugin.h" -#include "tclplugin.h" -#include "printevents.h" - -static int nexttimerid = 0; -static int nexttimerindex = 0; -static timer timers[MAX_TIMERS]; - -static char VERSION[16]; - -static int initialized = 0; -static int reinit_tried = 0; -static Tcl_Interp *interp = NULL; -static hexchat_plugin *ph; -static hexchat_hook *raw_line_hook; -static hexchat_hook *Command_TCL_hook; -static hexchat_hook *Command_Source_hook; -static hexchat_hook *Command_Reload_hook; -static hexchat_hook *Command_Load_hook; -static hexchat_hook *Event_Handler_hook; -static hexchat_hook *Null_Command_hook; - -static int complete_level = 0; -static t_complete complete[MAX_COMPLETES + 1]; -static Tcl_HashTable cmdTablePtr; -static Tcl_HashTable aliasTablePtr; - -static int nextprocid = 0x1000; -#define PROCPREFIX "__xctcl_" - -static char unknown[] = { -"rename unknown iunknown\n" -"proc ::unknown {args} {\n" -" global errorInfo errorCode\n" -" if { [string index [lindex $args 0] 0] == \"/\" } {\n" -" command \"[string range [join $args \" \"] 1 end]\"\n" -" } else {\n" -" set code [catch {uplevel iunknown $args} msg]\n" -" if {$code == 1} {\n" -" set new [split $errorInfo \\n]\n" -" set new [join [lrange $new 0 [expr {[llength $new] - 8}]] \\n]\n" -" return -code error -errorcode $errorCode -errorinfo $new $msg\n" -" } else {\n" -" return -code $code $msg\n" -" }\n" -" }\n" -"}\n" -"proc unsupported0 {from to {bytes \"\"}} {\n" -" set b [expr {$bytes == \"\" ? \"\" : \"-size [list $bytes]\"}]\n" -" eval [list fcopy $from $to] $b\n" -"}\n" -}; - -/* don't pollute the filesystem with script files, this only causes misuse of the folders - * only use ~/.config/hexchat/addons/ and %APPDATA%\HexChat\addons */ -static char sourcedirs[] = { - "set files [lsort [glob -nocomplain -directory [configdir] \"/addons/*.tcl\"]]\n" - "set init [lsearch -glob $files \"*/init.tcl\"]\n" - "if { $init > 0 } {\n" - "set initfile [lindex $files $init]\n" - "set files [lreplace $files $init $init]\n" - "set files [linsert $files 0 $initfile]\n" "}\n" "foreach f $files {\n" "if { [catch { source $f } errMsg] } {\n" "puts \"Tcl plugin\\tError sourcing \\\"$f\\\" ($errMsg)\"\n" "} else {\n" "puts \"Tcl plugin\\tSourced \\\"$f\\\"\"\n" "}\n" "}\n" -}; - -static char inlinetcl[] = { -"proc splitsrc { } {\n" -"uplevel \"scan \\$_src \\\"%\\\\\\[^!\\\\\\]!%\\\\\\[^@\\\\\\]@%s\\\" _nick _ident _host\"\n" -"}\n" - -"proc ::exit { } {\n" -"puts \"Using 'exit' is bad\"\n" -"}\n" - -"proc ::away { args } { return [eval [join [list getinfo $args away]]] }\n" -"proc ::channel { args } { return [eval [join [list getinfo $args channel]]] }\n" -"proc ::tab { args } { return [eval [join [list getinfo $args channel]]] }\n" -"proc ::charset { args } { return [eval [join [list getinfo $args charset]]] }\n" -"proc ::host { args } { return [eval [join [list getinfo $args host]]] }\n" -"proc ::inputbox { args } { return [eval [join [list getinfo $args inputbox]]] }\n" -"proc ::libdirfs { args } { return [eval [join [list getinfo $args libdirfs]]] }\n" -"proc ::network { args } { return [eval [join [list getinfo $args network]]] }\n" -"proc ::nickserv { args } { return [eval [join [list getinfo $args nickserv]]] }\n" -"proc ::server { args } { return [eval [join [list getinfo $args server]]] }\n" -"proc ::version { args } { return [eval [join [list getinfo $args version]]] }\n" -"proc ::win_status { args } { return [eval [join [list getinfo $args win_status]]] }\n" -"proc ::configdir { args } { return [eval [join [list getinfo $args configdir]]] }\n" - -"proc ::color { {arg {}} } { return \"\\003$arg\" }\n" -"proc ::bold { } { return \"\\002\" }\n" -"proc ::underline { } { return \"\\037\" }\n" -"proc ::reverse { } { return \"\\026\" }\n" -"proc ::reset { } { return \"\\017\" }\n" - -"proc ::__xctcl_errorInfo { } {\n" -" set text [split $::errorInfo \\n]\n" -" puts [string trim [join [lrange $text 0 [expr {[llength $text] - 4}]] \\n]]\n" -"}\n" - -"proc ::bgerror { message } {\n" -" set text [split $::errorInfo \\n]\n" -" puts [string trim [join [lrange $text 0 [expr {[llength $text] - 4}]] \\n]]\n" -"}\n" -}; - -static void NiceErrorInfo () -{ - Tcl_Eval(interp, "::__xctcl_errorInfo"); -} - -static void Tcl_MyDStringAppend(Tcl_DString * ds, char *string) -{ - Tcl_DStringAppend(ds, string, strlen(string)); -} - -static char *InternalProcName(int value) -{ - static char result[32]; - sprintf(result, "%s%08x", PROCPREFIX, value); - return result; -} - -static int SourceInternalProc(int id, const char *args, const char *source) -{ - Tcl_DString ds; - int result; - Tcl_DStringInit(&ds); - - Tcl_MyDStringAppend(&ds, "proc "); - Tcl_MyDStringAppend(&ds, InternalProcName(id)); - Tcl_MyDStringAppend(&ds, " { "); - Tcl_MyDStringAppend(&ds, args); - Tcl_MyDStringAppend(&ds, " } {\n"); - Tcl_MyDStringAppend(&ds, source); - Tcl_MyDStringAppend(&ds, "\n}\n\n"); - - result = Tcl_Eval(interp, ds.string); - - Tcl_DStringFree(&ds); - - return result; -} - -static int EvalInternalProc(const char *procname, int ct, ...) -{ - Tcl_DString ds; - int result; - va_list ap; - char *buf; - - Tcl_DStringInit(&ds); - - Tcl_MyDStringAppend(&ds, procname); - - if (ct) { - va_start(ap, ct); - while (ct--) { - if ((buf = va_arg(ap, char *)) != NULL) - Tcl_DStringAppendElement(&ds, buf); - else - Tcl_MyDStringAppend(&ds, " \"\""); - } - va_end(ap); - } - - result = Tcl_Eval(interp, ds.string); - - Tcl_DStringFree(&ds); - - return result; -} - - -static void DeleteInternalProc(const char *proc) -{ - Tcl_DString ds; - - Tcl_DStringInit(&ds); - Tcl_MyDStringAppend(&ds, "rename "); - Tcl_MyDStringAppend(&ds, proc); - Tcl_MyDStringAppend(&ds, " {}"); - Tcl_Eval(interp, ds.string); - Tcl_DStringFree(&ds); -} - -static char *StrDup(const char *string, int *length) -{ - char *result; - - if (string == NULL) - return NULL; - - *length = strlen(string); - result = Tcl_Alloc(*length + 1); - strncpy(result, string, *length); - result[*length] = 0; - - return result; -} - -static char *myitoa(long value) -{ - static char result[32]; - sprintf(result, "%ld", value); - return result; -} - -static hexchat_context *atoctx(const char *nptr) -{ - int isnum = 1; - int x = 0; - - if (!nptr) - return NULL; - - while (isnum && nptr[x]) { - if (!isdigit(nptr[x++])) - isnum--; - } - - if (isnum && x) - return (hexchat_context *) atol(nptr); - else - return NULL; -} - -static hexchat_context *xchat_smart_context(const char *arg1, const char *arg2) -{ - const char *server, *s, *n; - hexchat_context *result = NULL; - hexchat_context *ctx = NULL; - hexchat_context *actx = NULL; - hexchat_list *list; - - if (arg1 == NULL) - return hexchat_get_context(ph);; - - if (arg1 && arg2) { - result = hexchat_find_context(ph, arg1, arg2); - if (result == NULL) - result = hexchat_find_context(ph, arg2, arg1); - return result; - } else { - - actx = atoctx(arg1); - - server = hexchat_get_info(ph, "server"); - - list = hexchat_list_get(ph, "channels"); - - if (list != NULL) { - - while (hexchat_list_next(ph, list)) { - - ctx = (hexchat_context *)hexchat_list_str(ph, list, "context"); - - if (actx) { - if (ctx == actx) { - result = ctx; - break; - } - } else { - - s = hexchat_list_str(ph, list, "server"); - - if (hexchat_list_int(ph, list, "type") == 1) { - if (strcasecmp(arg1, s) == 0) { - result = ctx; - break; - } - n = hexchat_list_str(ph, list, "network"); - if (n) { - if (strcasecmp(arg1, n) == 0) { - result = ctx; - break; - } - } - } else { - if ((strcasecmp(server, s) == 0) && (strcasecmp(arg1, hexchat_list_str(ph, list, "channel")) == 0)) { - result = ctx; - break; - } - } - } - } - - hexchat_list_free(ph, list); - } - - } - - return result; -} - -static void queue_nexttimer() -{ - int x; - time_t then; - - nexttimerindex = 0; - then = (time_t) 0x7fffffff; - - for (x = 1; x < MAX_TIMERS; x++) { - if (timers[x].timerid) { - if (timers[x].timestamp < then) { - then = timers[x].timestamp; - nexttimerindex = x; - } - } - } -} - -static int insert_timer(int seconds, int count, const char *script) -{ - int x; - int dummy; - time_t now; - int id; - - if (script == NULL) - return (-1); - - id = (nextprocid++ % INT_MAX) + 1; - - now = time(NULL); - - for (x = 1; x < MAX_TIMERS; x++) { - if (timers[x].timerid == 0) { - if (SourceInternalProc(id, "", script) == TCL_ERROR) { - hexchat_printf(ph, "\0039TCL plugin\003\tERROR (timer %d) ", timers[x].timerid); - NiceErrorInfo (); - return (-1); - } - timers[x].timerid = (nexttimerid++ % INT_MAX) + 1; - timers[x].timestamp = now + seconds; - timers[x].count = count; - timers[x].seconds = seconds; - timers[x].procPtr = StrDup(InternalProcName(id), &dummy); - queue_nexttimer(); - return (timers[x].timerid); - } - } - - return (-1); -} - -static void do_timer() -{ - hexchat_context *origctx; - time_t now; - int index; - - if (!nexttimerindex) - return; - - now = time(NULL); - - if (now < timers[nexttimerindex].timestamp) - return; - - index = nexttimerindex; - origctx = hexchat_get_context(ph); - if (EvalInternalProc(timers[index].procPtr, 0) == TCL_ERROR) { - hexchat_printf(ph, "\0039TCL plugin\003\tERROR (timer %d) ", timers[index].timerid); - NiceErrorInfo (); - } - hexchat_set_context(ph, origctx); - - if (timers[index].count != -1) - timers[index].count--; - - if (timers[index].count == 0) { - timers[index].timerid = 0; - if (timers[index].procPtr != NULL) { - DeleteInternalProc(timers[index].procPtr); - Tcl_Free(timers[index].procPtr); - } - timers[index].procPtr = NULL; - } else { - timers[index].timestamp += timers[index].seconds; - } - - queue_nexttimer(); - - return; - -} - -static int Server_raw_line(char *word[], char *word_eol[], void *userdata) -{ - char *src, *cmd, *dest, *rest; - char *chancmd = NULL; - char *procList; - Tcl_HashEntry *entry = NULL; - hexchat_context *origctx; - int len; - int dummy; - char *string = NULL; - int ctcp = 0; - int count; - int list_argc, proc_argc; - const char **list_argv, **proc_argv; - int private = 0; - - if (word[0][0] == 0) - return HEXCHAT_EAT_NONE; - - if (complete_level == MAX_COMPLETES) - return HEXCHAT_EAT_NONE; - - complete_level++; - complete[complete_level].defresult = HEXCHAT_EAT_NONE; /* HEXCHAT_EAT_PLUGIN; */ - complete[complete_level].result = HEXCHAT_EAT_NONE; - complete[complete_level].word = word; - complete[complete_level].word_eol = word_eol; - - if (word[1][0] == ':') { - src = word[1]; - cmd = word[2]; - dest = word[3]; - rest = word_eol[4]; - } else { - src = ""; - cmd = word[1]; - if (word_eol[2][0] == ':') { - dest = ""; - rest = word_eol[2]; - } else { - dest = word[2]; - rest = word_eol[3]; - } - } - - if (src[0] == ':') - src++; - if (dest[0] == ':') - dest++; - if (rest[0] == ':') - rest++; - - if (rest[0] == 0x01) { - rest++; - if (strcasecmp("PRIVMSG", cmd) == 0) { - if (strncasecmp(rest, "ACTION ", 7) == 0) { - cmd = "ACTION"; - rest += 7; - } else - cmd = "CTCP"; - } else if (!strcasecmp("NOTICE", cmd)) - cmd = "CTCR"; - ctcp = 1; - } else if (!strcasecmp("NOTICE", cmd) && (strchr(src, '!') == NULL)) { - cmd = "SNOTICE"; - } else if (rest[0] == '!') { - chancmd = word[4] + 1; - } - - if (chancmd != NULL) { - string = StrDup(chancmd, &dummy); - Tcl_UtfToUpper(string); - if ((entry = Tcl_FindHashEntry(&cmdTablePtr, string)) == NULL) { - Tcl_Free(string); - } else { - cmd = chancmd; - rest = word_eol[5]; - } - } - - if (entry == NULL) { - string = StrDup(cmd, &dummy); - Tcl_UtfToUpper(string); - entry = Tcl_FindHashEntry(&cmdTablePtr, string); - } - - if (entry != NULL) { - - procList = Tcl_GetHashValue(entry); - - if (isalpha(dest[0])) - private = 1; - - rest = StrDup(rest, &len); - if (ctcp) { - if (rest != NULL) { - if ((len > 1) && (rest[len - 1] == 0x01)) - rest[len - 1] = 0; - } - } - - if (Tcl_SplitList(interp, procList, &list_argc, &list_argv) == TCL_OK) { - - for (count = 0; count < list_argc; count++) { - - if (Tcl_SplitList(interp, list_argv[count], &proc_argc, &proc_argv) != TCL_OK) - continue; - - origctx = hexchat_get_context(ph); - if (EvalInternalProc(proc_argv[1], 7, src, dest, cmd, rest, word_eol[1], proc_argv[0], myitoa(private)) == TCL_ERROR) { - hexchat_printf(ph, "\0039TCL plugin\003\tERROR (on %s %s) ", cmd, proc_argv[0]); - NiceErrorInfo (); - } - hexchat_set_context(ph, origctx); - - Tcl_Free((char *) proc_argv); - - if ((complete[complete_level].result == HEXCHAT_EAT_PLUGIN) || (complete[complete_level].result == HEXCHAT_EAT_ALL)) - break; - - } - - Tcl_Free((char *) list_argv); - - } - - Tcl_Free(rest); - - } - - if (string) - Tcl_Free(string); - - return complete[complete_level--].result; - -} - -static int Print_Hook(char *word[], void *userdata) -{ - char *procList; - Tcl_HashEntry *entry; - hexchat_context *origctx; - int count; - int list_argc, proc_argc; - const char **list_argv, **proc_argv; - Tcl_DString ds; - int x; - - if (complete_level == MAX_COMPLETES) - return HEXCHAT_EAT_NONE; - - complete_level++; - complete[complete_level].defresult = HEXCHAT_EAT_NONE; /* HEXCHAT_EAT_PLUGIN; */ - complete[complete_level].result = HEXCHAT_EAT_NONE; - complete[complete_level].word = word; - complete[complete_level].word_eol = word; - - if ((entry = Tcl_FindHashEntry(&cmdTablePtr, xc[(int) userdata].event)) != NULL) { - - procList = Tcl_GetHashValue(entry); - - if (Tcl_SplitList(interp, procList, &list_argc, &list_argv) == TCL_OK) { - - for (count = 0; count < list_argc; count++) { - - if (Tcl_SplitList(interp, list_argv[count], &proc_argc, &proc_argv) != TCL_OK) - continue; - - origctx = hexchat_get_context(ph); - - Tcl_DStringInit(&ds); - - if ((int) userdata == CHAT) { - Tcl_DStringAppend(&ds, word[3], strlen(word[3])); - Tcl_DStringAppend(&ds, "!*@", 3); - Tcl_DStringAppend(&ds, word[1], strlen(word[1])); - if (EvalInternalProc(proc_argv[1], 7, ds.string, word[2], xc[(int) userdata].event, word[4], "", proc_argv[0], "0") == TCL_ERROR) { - hexchat_printf(ph, "\0039TCL plugin\003\tERROR (on %s %s) ", xc[(int) userdata].event, proc_argv[0]); - NiceErrorInfo (); - } - } else { - if (xc[(int) userdata].argc > 0) { - for (x = 0; x <= xc[(int) userdata].argc; x++) - Tcl_DStringAppendElement(&ds, word[x]); - } - if (EvalInternalProc(proc_argv[1], 7, "", "", xc[(int) userdata].event, "", ds.string, proc_argv[0], "0") == TCL_ERROR) { - hexchat_printf(ph, "\0039Tcl plugin\003\tERROR (on %s %s) ", xc[(int) userdata].event, proc_argv[0]); - NiceErrorInfo (); - } - } - - Tcl_DStringFree(&ds); - - hexchat_set_context(ph, origctx); - - Tcl_Free((char *) proc_argv); - - if ((complete[complete_level].result == HEXCHAT_EAT_PLUGIN) || (complete[complete_level].result == HEXCHAT_EAT_ALL)) - break; - - } - - Tcl_Free((char *) list_argv); - - } - } - - return complete[complete_level--].result; -} - - -static int tcl_timerexists(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - int x; - int timerid; - - BADARGS(2, 2, " schedid"); - - if (Tcl_GetInt(irp, argv[1], &timerid) != TCL_OK) { - Tcl_AppendResult(irp, "Invalid timer id", NULL); - return TCL_ERROR; - } - - if (timerid) { - for (x = 1; x < MAX_TIMERS; x++) { - if (timers[x].timerid == timerid) { - Tcl_AppendResult(irp, "1", NULL); - return TCL_OK; - } - } - } - - Tcl_AppendResult(irp, "0", NULL); - - return TCL_OK; -} - -static int tcl_killtimer(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - int x; - int timerid; - - BADARGS(2, 2, " timerid"); - - if (Tcl_GetInt(irp, argv[1], &timerid) != TCL_OK) { - Tcl_AppendResult(irp, "Invalid timer id", NULL); - return TCL_ERROR; - } - - if (timerid) { - for (x = 1; x < MAX_TIMERS; x++) { - if (timers[x].timerid == timerid) { - timers[x].timerid = 0; - if (timers[x].procPtr != NULL) { - DeleteInternalProc(timers[x].procPtr); - Tcl_Free(timers[x].procPtr); - } - timers[x].procPtr = NULL; - break; - } - } - } - - queue_nexttimer(); - - return TCL_OK; -} - -static int tcl_timers(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - int x; - Tcl_DString ds; - time_t now; - - BADARGS(1, 1, ""); - - now = time(NULL); - - Tcl_DStringInit(&ds); - - for (x = 1; x < MAX_TIMERS; x++) { - if (timers[x].timerid) { - Tcl_DStringStartSublist(&ds); - Tcl_DStringAppendElement(&ds, myitoa((long)timers[x].timerid)); - Tcl_DStringAppendElement(&ds, myitoa((long)timers[x].timestamp - now)); - Tcl_DStringAppendElement(&ds, timers[x].procPtr); - Tcl_DStringAppendElement(&ds, myitoa((long)timers[x].seconds)); - Tcl_DStringAppendElement(&ds, myitoa((long)timers[x].count)); - Tcl_DStringEndSublist(&ds); - } - } - - Tcl_AppendResult(interp, ds.string, NULL); - Tcl_DStringFree(&ds); - - return TCL_OK; -} - -static int tcl_timer(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - int seconds; - int timerid; - int repeat = 0; - int count = 0; - int first = 1; - char reply[32]; - - BADARGS(3, 6, " ?-repeat? ?-count times? seconds {script | procname ?args?}"); - - while (argc--) { - if (strcasecmp(argv[first], "-repeat") == 0) { - repeat++; - } else if (strcasecmp(argv[first], "-count") == 0) { - if (Tcl_GetInt(irp, argv[++first], &count) != TCL_OK) - return TCL_ERROR; - } else { - break; - } - first++; - } - - if (repeat && !count) - count = -1; - - if (!count) - count = 1; - - if (Tcl_GetInt(irp, argv[first++], &seconds) != TCL_OK) - return TCL_ERROR; - - if ((timerid = insert_timer(seconds, count, argv[first++])) == -1) { - Tcl_AppendResult(irp, "0", NULL); - return TCL_ERROR; - } - - sprintf(reply, "%d", timerid); - - Tcl_AppendResult(irp, reply, NULL); - - queue_nexttimer(); - - return TCL_OK; -} - -static int tcl_on(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - int newentry; - char *procList; - Tcl_HashEntry *entry; - char *token; - int dummy; - Tcl_DString ds; - int index; - int count; - int list_argc, proc_argc; - int id; - const char **list_argv, **proc_argv; - - BADARGS(4, 4, " token label {script | procname ?args?}"); - - id = (nextprocid++ % INT_MAX) + 1; - - if (SourceInternalProc(id, "_src _dest _cmd _rest _raw _label _private", argv[3]) == TCL_ERROR) { - hexchat_printf(ph, "\0039Tcl plugin\003\tERROR (on %s:%s) ", argv[1], argv[2]); - NiceErrorInfo (); - return TCL_OK; - } - - token = StrDup(argv[1], &dummy); - Tcl_UtfToUpper(token); - - Tcl_DStringInit(&ds); - - entry = Tcl_CreateHashEntry(&cmdTablePtr, token, &newentry); - if (!newentry) { - procList = Tcl_GetHashValue(entry); - if (Tcl_SplitList(interp, procList, &list_argc, &list_argv) == TCL_OK) { - for (count = 0; count < list_argc; count++) { - if (Tcl_SplitList(interp, list_argv[count], &proc_argc, &proc_argv) != TCL_OK) - continue; - if (strcmp(proc_argv[0], argv[2])) { - Tcl_DStringStartSublist(&ds); - Tcl_DStringAppendElement(&ds, proc_argv[0]); - Tcl_DStringAppendElement(&ds, proc_argv[1]); - Tcl_DStringEndSublist(&ds); - } else { - DeleteInternalProc(proc_argv[1]); - } - Tcl_Free((char *) proc_argv); - } - Tcl_Free((char *) list_argv); - } - Tcl_Free(procList); - } - - Tcl_DStringStartSublist(&ds); - Tcl_DStringAppendElement(&ds, argv[2]); - Tcl_DStringAppendElement(&ds, InternalProcName(id)); - Tcl_DStringEndSublist(&ds); - - procList = StrDup(ds.string, &dummy); - - Tcl_SetHashValue(entry, procList); - - if ((strncmp(token, "XC_", 3) == 0) || (strcmp(token, "CHAT") == 0)) { - for (index = 0; index < XC_SIZE; index++) { - if (strcmp(xc[index].event, token) == 0) { - if (xc[index].hook == NULL) { - xc[index].hook = hexchat_hook_print(ph, xc[index].emit, HEXCHAT_PRI_NORM, Print_Hook, (void *) index); - break; - } - } - } - } - - Tcl_Free(token); - Tcl_DStringFree(&ds); - - return TCL_OK; -} - -static int tcl_off(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - char *procList; - Tcl_HashEntry *entry; - char *token; - int dummy; - Tcl_DString ds; - int index; - int count; - int list_argc, proc_argc; - const char **list_argv, **proc_argv; - - BADARGS(2, 3, " token ?label?"); - - token = StrDup(argv[1], &dummy); - Tcl_UtfToUpper(token); - - Tcl_DStringInit(&ds); - - if ((entry = Tcl_FindHashEntry(&cmdTablePtr, token)) != NULL) { - - procList = Tcl_GetHashValue(entry); - - if (argc == 3) { - if (Tcl_SplitList(interp, procList, &list_argc, &list_argv) == TCL_OK) { - for (count = 0; count < list_argc; count++) { - if (Tcl_SplitList(interp, list_argv[count], &proc_argc, &proc_argv) != TCL_OK) - continue; - if (strcmp(proc_argv[0], argv[2])) { - Tcl_DStringStartSublist(&ds); - Tcl_DStringAppendElement(&ds, proc_argv[0]); - Tcl_DStringAppendElement(&ds, proc_argv[1]); - Tcl_DStringEndSublist(&ds); - } else - DeleteInternalProc(proc_argv[1]); - Tcl_Free((char *) proc_argv); - } - Tcl_Free((char *) list_argv); - } - } - - Tcl_Free(procList); - - if (ds.length) { - procList = StrDup(ds.string, &dummy); - Tcl_SetHashValue(entry, procList); - } else { - Tcl_DeleteHashEntry(entry); - } - - if (!ds.length) { - if ((strncmp(token, "XC_", 3) == 0) || (strcmp(token, "CHAT") == 0)) { - for (index = 0; index < XC_SIZE; index++) { - if (strcmp(xc[index].event, token) == 0) { - if (xc[index].hook != NULL) { - hexchat_unhook(ph, xc[index].hook); - xc[index].hook = NULL; - break; - } - } - } - } - } - } - - Tcl_Free(token); - Tcl_DStringFree(&ds); - - return TCL_OK; -} - -static int tcl_alias(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - int newentry; - alias *aliasPtr; - Tcl_HashEntry *entry; - char *string; - const char *help = NULL; - int dummy; - int id; - - BADARGS(3, 4, " name ?help? {script | procname ?args?}"); - - string = StrDup(argv[1], &dummy); - Tcl_UtfToUpper(string); - - if (strlen(argv[argc - 1])) { - - if (argc == 4) - help = argv[2]; - - id = (nextprocid++ % INT_MAX) + 1; - - if (SourceInternalProc(id, "_cmd _rest", argv[argc - 1]) == TCL_ERROR) { - hexchat_printf(ph, "\0039Tcl plugin\003\tERROR (alias %s) ", argv[1]); - NiceErrorInfo (); - return TCL_OK; - } - - entry = Tcl_CreateHashEntry(&aliasTablePtr, string, &newentry); - if (newentry) { - aliasPtr = (alias *) Tcl_Alloc(sizeof(alias)); - if (string[0] == '@') - aliasPtr->hook = NULL; - else - aliasPtr->hook = hexchat_hook_command(ph, string, HEXCHAT_PRI_NORM, Command_Alias, help, 0); - } else { - aliasPtr = Tcl_GetHashValue(entry); - DeleteInternalProc(aliasPtr->procPtr); - Tcl_Free(aliasPtr->procPtr); - } - - aliasPtr->procPtr = StrDup(InternalProcName(id), &dummy); - - Tcl_SetHashValue(entry, aliasPtr); - - } else { - - if ((entry = Tcl_FindHashEntry(&aliasTablePtr, string)) != NULL) { - aliasPtr = Tcl_GetHashValue(entry); - DeleteInternalProc(aliasPtr->procPtr); - Tcl_Free(aliasPtr->procPtr); - if (aliasPtr->hook) - hexchat_unhook(ph, aliasPtr->hook); - Tcl_Free((char *) aliasPtr); - Tcl_DeleteHashEntry(entry); - } - } - - Tcl_Free(string); - - return TCL_OK; -} - -static int tcl_complete(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - BADARGS(1, 2, " ?EAT_NONE|EAT_XCHAT|EAT_PLUGIN|EAT_ALL?"); - - if (argc == 2) { - if (Tcl_GetInt(irp, argv[1], &complete[complete_level].result) != TCL_OK) { - if (strcasecmp("EAT_NONE", argv[1]) == 0) - complete[complete_level].result = HEXCHAT_EAT_NONE; - else if (strcasecmp("EAT_XCHAT", argv[1]) == 0) - complete[complete_level].result = HEXCHAT_EAT_HEXCHAT; - else if (strcasecmp("EAT_PLUGIN", argv[1]) == 0) - complete[complete_level].result = HEXCHAT_EAT_PLUGIN; - else if (strcasecmp("EAT_ALL", argv[1]) == 0) - complete[complete_level].result = HEXCHAT_EAT_ALL; - else - BADARGS(1, 2, " ?EAT_NONE|EAT_XCHAT|EAT_PLUGIN|EAT_ALL?"); - } - } else - complete[complete_level].result = complete[complete_level].defresult; - - return TCL_RETURN; -} - -static int tcl_command(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - hexchat_context *origctx; - hexchat_context *ctx = NULL; - const char *string = NULL; - - BADARGS(2, 4, " ?server|network|context? ?#channel|nick? text"); - - origctx = hexchat_get_context(ph); - - switch (argc) { - case 2: - ctx = origctx; - break; - case 3: - ctx = xchat_smart_context(argv[1], NULL); - break; - case 4: - ctx = xchat_smart_context(argv[1], argv[2]); - break; - default:; - } - - CHECKCTX(ctx); - - string = argv[argc - 1]; - - if (string[0] == '/') - string++; - - hexchat_set_context(ph, ctx); - hexchat_command(ph, string); - hexchat_set_context(ph, origctx); - - return TCL_OK; -} - -static int tcl_raw(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - hexchat_context *origctx; - hexchat_context *ctx = NULL; - const char *string = NULL; - - BADARGS(2, 4, " ?server|network|context? ?#channel|nick? text"); - - origctx = hexchat_get_context(ph); - - switch (argc) { - case 2: - ctx = origctx; - break; - case 3: - ctx = xchat_smart_context(argv[1], NULL); - break; - case 4: - ctx = xchat_smart_context(argv[1], argv[2]); - break; - default:; - } - - CHECKCTX(ctx); - - string = argv[argc - 1]; - - hexchat_set_context(ph, ctx); - hexchat_commandf(ph, "RAW %s", string); - hexchat_set_context(ph, origctx); - - return TCL_OK; -} - - -static int tcl_prefs(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - int i; - const char *str; - - BADARGS(2, 2, " name"); - - switch (hexchat_get_prefs (ph, argv[1], &str, &i)) { - case 1: - Tcl_AppendResult(irp, str, NULL); - break; - case 2: - case 3: - Tcl_AppendResult(irp, myitoa(i), NULL); - break; - default: - Tcl_AppendResult(irp, NULL); - } - - return TCL_OK; -} - -static int tcl_info(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[], char *id) -{ - char *result; - int max_argc; - hexchat_context *origctx, *ctx; - - if (id == NULL) { - BADARGS(2, 3, " ?server|network|context? id"); - max_argc = 3; - } else { - BADARGS(1, 2, " ?server|network|context?"); - max_argc = 2; - } - - origctx = hexchat_get_context(ph); - - if (argc == max_argc) { - ctx = xchat_smart_context(argv[1], NULL); - CHECKCTX(ctx); - hexchat_set_context(ph, ctx); - } - - if (id == NULL) - id = argv[argc-1]; - - if ((result = hexchat_get_info(ph, id)) == NULL) - result = ""; - - Tcl_AppendResult(irp, result, NULL); - - hexchat_set_context(ph, origctx); - - return TCL_OK; -} - -static int tcl_me(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - return tcl_info(cd, irp, argc, argv, "nick"); -} - -static int tcl_getinfo(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - return tcl_info(cd, irp, argc, argv, NULL); -} - -static int tcl_getlist(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - hexchat_list *list = NULL; - const char *name = NULL; - const char * const *fields; - const char *field; - const char *sattr; - int iattr; - int i; - time_t t; - Tcl_DString ds; - hexchat_context *origctx; - hexchat_context *ctx = NULL; - - origctx = hexchat_get_context(ph); - - BADARGS(1, 2, " list"); - - Tcl_DStringInit(&ds); - - fields = hexchat_list_fields(ph, "lists"); - - if (argc == 1) { - for (i = 0; fields[i] != NULL; i++) { - Tcl_DStringAppendElement(&ds, fields[i]); - } - goto done; - } - - for (i = 0; fields[i] != NULL; i++) { - if (strcmp(fields[i], argv[1]) == 0) { - name = fields[i]; - break; - } - } - - if (name == NULL) - goto done; - - list = hexchat_list_get(ph, name); - if (list == NULL) - goto done; - - fields = hexchat_list_fields(ph, name); - - Tcl_DStringStartSublist(&ds); - for (i = 0; fields[i] != NULL; i++) { - field = fields[i] + 1; - Tcl_DStringAppendElement(&ds, field); - } - Tcl_DStringEndSublist(&ds); - - while (hexchat_list_next(ph, list)) { - - Tcl_DStringStartSublist(&ds); - - for (i = 0; fields[i] != NULL; i++) { - - field = fields[i] + 1; - - switch (fields[i][0]) { - case 's': - sattr = hexchat_list_str(ph, list, (char *) field); - Tcl_DStringAppendElement(&ds, sattr); - break; - case 'i': - iattr = hexchat_list_int(ph, list, (char *) field); - Tcl_DStringAppendElement(&ds, myitoa((long)iattr)); - break; - case 't': - t = hexchat_list_time(ph, list, (char *) field); - Tcl_DStringAppendElement(&ds, myitoa((long)t)); - break; - case 'p': - sattr = hexchat_list_str(ph, list, (char *) field); - if (strcmp(field, "context") == 0) { - ctx = (hexchat_context *) sattr; - Tcl_DStringAppendElement(&ds, myitoa((long)ctx)); - } else - Tcl_DStringAppendElement(&ds, "*"); - break; - default: - Tcl_DStringAppendElement(&ds, "*"); - break; - } - } - - Tcl_DStringEndSublist(&ds); - - } - - hexchat_list_free(ph, list); - - done: - - hexchat_set_context(ph, origctx); - - Tcl_AppendResult(irp, ds.string, NULL); - - Tcl_DStringFree(&ds); - - return TCL_OK; -} - -/* - * tcl_xchat_puts - stub for tcl puts command - * This is modified from the original internal "puts" command. It redirects - * stdout to the current context, while still allowing all normal puts features - */ - -static int tcl_xchat_puts(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - Tcl_Channel chan; - const char *string; - int newline; - const char *channelId = NULL; - int result; - int mode; - int trap_stdout = 0; - - switch (argc) { - - case 2: - string = argv[1]; - newline = 1; - trap_stdout = 1; - break; - - case 3: - if (strcmp(argv[1], "-nonewline") == 0) { - newline = 0; - trap_stdout = 1; - } else { - newline = 1; - channelId = argv[1]; - } - string = argv[2]; - break; - - case 4: - if (strcmp(argv[1], "-nonewline") == 0) { - channelId = argv[2]; - string = argv[3]; - } else { - if (strcmp(argv[3], "nonewline") != 0) { - Tcl_AppendResult(interp, "bad argument \"", argv[3], "\": should be \"nonewline\"", (char *) NULL); - return TCL_ERROR; - } - channelId = argv[1]; - string = argv[2]; - } - newline = 0; - break; - - default: - Tcl_AppendResult(interp, argv, "?-nonewline? ?channelId? string", NULL); - return TCL_ERROR; - } - - if (!trap_stdout && (strcmp(channelId, "stdout") == 0)) - trap_stdout = 1; - - if (trap_stdout) { - if (newline) - hexchat_printf(ph, "%s\n", string); - else - hexchat_print(ph, string); - return TCL_OK; - } - - chan = Tcl_GetChannel(interp, channelId, &mode); - if (chan == (Tcl_Channel) NULL) { - return TCL_ERROR; - } - if ((mode & TCL_WRITABLE) == 0) { - Tcl_AppendResult(interp, "channel \"", channelId, "\" wasn't opened for writing", (char *) NULL); - return TCL_ERROR; - } - - result = Tcl_Write(chan, string, strlen(string)); - if (result < 0) { - goto error; - } - if (newline != 0) { - result = Tcl_WriteChars(chan, "\n", 1); - if (result < 0) { - goto error; - } - } - return TCL_OK; - - error: - Tcl_AppendResult(interp, "error writing \"", channelId, "\": ", Tcl_PosixError(interp), (char *) NULL); - - return TCL_ERROR; -} - -static int tcl_print(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - hexchat_context *origctx; - hexchat_context *ctx = NULL; - const char *string = NULL; - - BADARGS(2, 4, " ?server|network|context? ?#channel|nick? text"); - - origctx = hexchat_get_context(ph); - - switch (argc) { - case 2: - ctx = origctx; - break; - case 3: - ctx = xchat_smart_context(argv[1], NULL); - break; - case 4: - ctx = xchat_smart_context(argv[1], argv[2]); - break; - default:; - } - - CHECKCTX(ctx); - - string = argv[argc - 1]; - - hexchat_set_context(ph, ctx); - hexchat_print(ph, string); - hexchat_set_context(ph, origctx); - - return TCL_OK; -} - -static int tcl_setcontext(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - hexchat_context *ctx = NULL; - - BADARGS(2, 2, " context"); - - ctx = xchat_smart_context(argv[1], NULL); - - CHECKCTX(ctx); - - hexchat_set_context(ph, ctx); - - return TCL_OK; -} - -static int tcl_findcontext(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - hexchat_context *ctx = NULL; - - BADARGS(1, 3, " ?server|network|context? ?channel?"); - - switch (argc) { - case 1: - ctx = hexchat_find_context(ph, NULL, NULL); - break; - case 2: - ctx = xchat_smart_context(argv[1], NULL); - break; - case 3: - ctx = xchat_smart_context(argv[1], argv[2]); - break; - default:; - } - - CHECKCTX(ctx); - - Tcl_AppendResult(irp, myitoa((long)ctx), NULL); - - return TCL_OK; -} - -static int tcl_getcontext(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - hexchat_context *ctx = NULL; - - BADARGS(1, 1, ""); - - ctx = hexchat_get_context(ph); - - Tcl_AppendResult(irp, myitoa((long)ctx), NULL); - - return TCL_OK; -} - -static int tcl_channels(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - const char *server, *channel; - hexchat_list *list; - Tcl_DString ds; - hexchat_context *origctx; - hexchat_context *ctx; - - origctx = hexchat_get_context(ph); - - BADARGS(1, 2, " ?server|network|context?"); - - if (argc == 2) { - ctx = xchat_smart_context(argv[1], NULL); - CHECKCTX(ctx); - hexchat_set_context(ph, ctx); - } - - server = (char *) hexchat_get_info(ph, "server"); - - Tcl_DStringInit(&ds); - - list = hexchat_list_get(ph, "channels"); - - if (list != NULL) { - while (hexchat_list_next(ph, list)) { - if (hexchat_list_int(ph, list, "type") != 2) - continue; - if (strcasecmp(server, hexchat_list_str(ph, list, "server")) != 0) - continue; - channel = hexchat_list_str(ph, list, "channel"); - Tcl_DStringAppendElement(&ds, channel); - } - hexchat_list_free(ph, list); - } - - Tcl_AppendResult(irp, ds.string, NULL); - - Tcl_DStringFree(&ds); - - hexchat_set_context(ph, origctx); - - return TCL_OK; -} - -static int tcl_servers(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - const char *server; - hexchat_list *list; - Tcl_DString ds; - - BADARGS(1, 1, ""); - - Tcl_DStringInit(&ds); - - list = hexchat_list_get(ph, "channels"); - - if (list != NULL) { - while (hexchat_list_next(ph, list)) { - if (hexchat_list_int(ph, list, "type") == 1) { - server = hexchat_list_str(ph, list, "server"); - Tcl_DStringAppendElement(&ds, server); - } - } - hexchat_list_free(ph, list); - } - - Tcl_AppendResult(irp, ds.string, NULL); - - Tcl_DStringFree(&ds); - - return TCL_OK; -} - -static int tcl_queries(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - const char *server, *channel; - hexchat_list *list; - Tcl_DString ds; - hexchat_context *origctx; - hexchat_context *ctx; - - origctx = hexchat_get_context(ph); - - BADARGS(1, 2, " ?server|network|context?"); - - if (argc == 2) { - ctx = xchat_smart_context(argv[1], NULL); - CHECKCTX(ctx); - hexchat_set_context(ph, ctx); - } - - server = (char *) hexchat_get_info(ph, "server"); - - Tcl_DStringInit(&ds); - - list = hexchat_list_get(ph, "channels"); - - if (list != NULL) { - while (hexchat_list_next(ph, list)) { - if (hexchat_list_int(ph, list, "type") != 3) - continue; - if (strcasecmp(server, hexchat_list_str(ph, list, "server")) != 0) - continue; - channel = hexchat_list_str(ph, list, "channel"); - Tcl_DStringAppendElement(&ds, channel); - } - hexchat_list_free(ph, list); - } - - Tcl_AppendResult(irp, ds.string, NULL); - - Tcl_DStringFree(&ds); - - hexchat_set_context(ph, origctx); - - return TCL_OK; -} - -static int tcl_users(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - hexchat_context *origctx, *ctx = NULL; - hexchat_list *list; - Tcl_DString ds; - - BADARGS(1, 3, " ?server|network|context? ?channel?"); - - origctx = hexchat_get_context(ph); - - switch (argc) { - case 1: - ctx = origctx; - break; - case 2: - ctx = xchat_smart_context(argv[1], NULL); - break; - case 3: - ctx = xchat_smart_context(argv[1], argv[2]); - break; - default:; - } - - CHECKCTX(ctx); - - hexchat_set_context(ph, ctx); - - Tcl_DStringInit(&ds); - - list = hexchat_list_get(ph, "users"); - - if (list != NULL) { - - Tcl_DStringStartSublist(&ds); - Tcl_DStringAppendElement(&ds, "nick"); - Tcl_DStringAppendElement(&ds, "host"); - Tcl_DStringAppendElement(&ds, "prefix"); - Tcl_DStringAppendElement(&ds, "away"); - Tcl_DStringAppendElement(&ds, "lasttalk"); - Tcl_DStringAppendElement(&ds, "selected"); - Tcl_DStringEndSublist(&ds); - - while (hexchat_list_next(ph, list)) { - Tcl_DStringStartSublist(&ds); - Tcl_DStringAppendElement(&ds, (const char *) hexchat_list_str(ph, list, "nick")); - Tcl_DStringAppendElement(&ds, (const char *) hexchat_list_str(ph, list, "host")); - Tcl_DStringAppendElement(&ds, (const char *) hexchat_list_str(ph, list, "prefix")); - Tcl_DStringAppendElement(&ds, myitoa((long)hexchat_list_int(ph, list, "away"))); - Tcl_DStringAppendElement(&ds, myitoa((long)hexchat_list_time(ph, list, "lasttalk"))); - Tcl_DStringAppendElement(&ds, myitoa((long)hexchat_list_int(ph, list, "selected"))); - Tcl_DStringEndSublist(&ds); - } - - hexchat_list_free(ph, list); - } - - Tcl_AppendResult(irp, ds.string, NULL); - - Tcl_DStringFree(&ds); - - hexchat_set_context(ph, origctx); - - return TCL_OK; -} - -static int tcl_notifylist(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - hexchat_list *list; - Tcl_DString ds; - - BADARGS(1, 1, ""); - - Tcl_DStringInit(&ds); - - list = hexchat_list_get(ph, "notify"); - - if (list != NULL) { - - Tcl_DStringStartSublist(&ds); - Tcl_DStringAppendElement(&ds, "nick"); - Tcl_DStringAppendElement(&ds, "flags"); - Tcl_DStringAppendElement(&ds, "on"); - Tcl_DStringAppendElement(&ds, "off"); - Tcl_DStringAppendElement(&ds, "seen"); - Tcl_DStringAppendElement(&ds, "networks"); - Tcl_DStringEndSublist(&ds); - - while (hexchat_list_next(ph, list)) { - Tcl_DStringStartSublist(&ds); - Tcl_DStringAppendElement(&ds, (const char *) hexchat_list_str(ph, list, "nick")); - Tcl_DStringAppendElement(&ds, (const char *) hexchat_list_str(ph, list, "flags")); - Tcl_DStringAppendElement(&ds, myitoa((long)hexchat_list_time(ph, list, "on"))); - Tcl_DStringAppendElement(&ds, myitoa((long)hexchat_list_time(ph, list, "off"))); - Tcl_DStringAppendElement(&ds, myitoa((long)hexchat_list_time(ph, list, "seen"))); - Tcl_DStringAppendElement(&ds, (const char *) hexchat_list_str(ph, list, "networks")); - Tcl_DStringEndSublist(&ds); - } - - hexchat_list_free(ph, list); - - } - - Tcl_AppendResult(irp, ds.string, NULL); - - Tcl_DStringFree(&ds); - - return TCL_OK; -} - -static int tcl_chats(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - hexchat_list *list; - Tcl_DString ds; - - BADARGS(1, 1, ""); - - Tcl_DStringInit(&ds); - - list = hexchat_list_get(ph, "dcc"); - - if (list != NULL) { - while (hexchat_list_next(ph, list)) { - switch (hexchat_list_int(ph, list, "type")) { - case 2: - case 3: - if (hexchat_list_int(ph, list, "status") == 1) - Tcl_DStringAppendElement(&ds, (const char *) hexchat_list_str(ph, list, "nick")); - break; - } - } - hexchat_list_free(ph, list); - } - - Tcl_AppendResult(irp, ds.string, NULL); - - Tcl_DStringFree(&ds); - - return TCL_OK; -} - -static int tcl_ignores(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - hexchat_list *list; - Tcl_DString ds; - int flags; - - BADARGS(1, 1, ""); - - Tcl_DStringInit(&ds); - - list = hexchat_list_get(ph, "ignore"); - - if (list != NULL) { - - while (hexchat_list_next(ph, list)) { - Tcl_DStringStartSublist(&ds); - Tcl_DStringAppendElement(&ds, (const char *) hexchat_list_str(ph, list, "mask")); - Tcl_DStringStartSublist(&ds); - flags = hexchat_list_int(ph, list, "flags"); - if (flags & 1) - Tcl_DStringAppendElement(&ds, "PRIVMSG"); - if (flags & 2) - Tcl_DStringAppendElement(&ds, "NOTICE"); - if (flags & 4) - Tcl_DStringAppendElement(&ds, "CHANNEL"); - if (flags & 8) - Tcl_DStringAppendElement(&ds, "CTCP"); - if (flags & 16) - Tcl_DStringAppendElement(&ds, "INVITE"); - if (flags & 32) - Tcl_DStringAppendElement(&ds, "UNIGNORE"); - if (flags & 64) - Tcl_DStringAppendElement(&ds, "NOSAVE"); - Tcl_DStringEndSublist(&ds); - Tcl_DStringEndSublist(&ds); - } - hexchat_list_free(ph, list); - } - - Tcl_AppendResult(irp, ds.string, NULL); - - Tcl_DStringFree(&ds); - - return TCL_OK; -} - -static int tcl_dcclist(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - hexchat_list *list; - Tcl_DString ds; - int dcctype; - - BADARGS(1, 1, ""); - - Tcl_DStringInit(&ds); - - list = hexchat_list_get(ph, "dcc"); - - if (list != NULL) { - - while (hexchat_list_next(ph, list)) { - Tcl_DStringStartSublist(&ds); - dcctype = hexchat_list_int(ph, list, "type"); - switch (dcctype) { - case 0: - Tcl_DStringAppendElement(&ds, "filesend"); - break; - case 1: - Tcl_DStringAppendElement(&ds, "filerecv"); - break; - case 2: - Tcl_DStringAppendElement(&ds, "chatrecv"); - break; - case 3: - Tcl_DStringAppendElement(&ds, "chatsend"); - break; - } - switch (hexchat_list_int(ph, list, "status")) { - case 0: - Tcl_DStringAppendElement(&ds, "queued"); - break; - case 1: - Tcl_DStringAppendElement(&ds, "active"); - break; - case 2: - Tcl_DStringAppendElement(&ds, "failed"); - break; - case 3: - Tcl_DStringAppendElement(&ds, "done"); - break; - case 4: - Tcl_DStringAppendElement(&ds, "connecting"); - break; - case 5: - Tcl_DStringAppendElement(&ds, "aborted"); - break; - } - - Tcl_DStringAppendElement(&ds, (const char *) hexchat_list_str(ph, list, "nick")); - - switch (dcctype) { - case 0: - Tcl_DStringAppendElement(&ds, (const char *) hexchat_list_str(ph, list, "file")); - break; - case 1: - Tcl_DStringAppendElement(&ds, (const char *) hexchat_list_str(ph, list, "destfile")); - break; - } - - Tcl_DStringAppendElement(&ds, myitoa((long)hexchat_list_int(ph, list, "size"))); - Tcl_DStringAppendElement(&ds, myitoa((long)hexchat_list_int(ph, list, "resume"))); - Tcl_DStringAppendElement(&ds, myitoa((long)hexchat_list_int(ph, list, "pos"))); - Tcl_DStringAppendElement(&ds, myitoa((long)hexchat_list_int(ph, list, "cps"))); - Tcl_DStringAppendElement(&ds, myitoa((long)hexchat_list_int(ph, list, "address32"))); - Tcl_DStringAppendElement(&ds, myitoa((long)hexchat_list_int(ph, list, "port"))); - Tcl_DStringEndSublist(&ds); - } - hexchat_list_free(ph, list); - } - - Tcl_AppendResult(irp, ds.string, NULL); - - Tcl_DStringFree(&ds); - - return TCL_OK; -} - - -static int tcl_strip(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - char *new_text; - int flags = 1 | 2; - - BADARGS(2, 3, " text ?flags?"); - - if (argc == 3) { - if (Tcl_GetInt(irp, argv[2], &flags) != TCL_OK) - return TCL_ERROR; - } - - new_text = hexchat_strip(ph, argv[1], -1, flags); - - if(new_text) { - Tcl_AppendResult(irp, new_text, NULL); - hexchat_free(ph, new_text); - } - - return TCL_OK; -} - -static int tcl_topic(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - hexchat_context *origctx, *ctx = NULL; - BADARGS(1, 3, " ?server|network|context? ?channel?"); - - origctx = hexchat_get_context(ph); - - switch (argc) { - case 1: - ctx = origctx; - break; - case 2: - ctx = xchat_smart_context(argv[1], NULL); - break; - case 3: - ctx = xchat_smart_context(argv[1], argv[2]); - break; - default:; - } - - CHECKCTX(ctx); - - hexchat_set_context(ph, ctx); - Tcl_AppendResult(irp, hexchat_get_info(ph, "topic"), NULL); - hexchat_set_context(ph, origctx); - - return TCL_OK; -} - -static int tcl_hexchat_nickcmp(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - BADARGS(3, 3, " string1 string2"); - Tcl_AppendResult(irp, myitoa((long)hexchat_nickcmp(ph, argv[1], argv[2])), NULL); - return TCL_OK; -} - -static int tcl_word(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - int index; - - BADARGS(2, 2, " index"); - - if (Tcl_GetInt(irp, argv[1], &index) != TCL_OK) - return TCL_ERROR; - - if (!index || (index > 31)) - Tcl_AppendResult(interp, "", NULL); - else - Tcl_AppendResult(interp, complete[complete_level].word[index], NULL); - - return TCL_OK; -} - -static int tcl_word_eol(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]) -{ - int index; - - BADARGS(2, 2, " index"); - - if (Tcl_GetInt(irp, argv[1], &index) != TCL_OK) - return TCL_ERROR; - - if (!index || (index > 31)) - Tcl_AppendResult(interp, "", NULL); - else - Tcl_AppendResult(interp, complete[complete_level].word_eol[index], NULL); - - return TCL_OK; -} - -static int Command_Alias(char *word[], char *word_eol[], void *userdata) -{ - alias *aliasPtr; - Tcl_HashEntry *entry; - hexchat_context *origctx; - int dummy; - char *string; - - if (complete_level == MAX_COMPLETES) - return HEXCHAT_EAT_NONE; - - complete_level++; - complete[complete_level].defresult = HEXCHAT_EAT_ALL; - complete[complete_level].result = HEXCHAT_EAT_NONE; - complete[complete_level].word = word; - complete[complete_level].word_eol = word_eol; - - string = StrDup(word[1], &dummy); - - Tcl_UtfToUpper(string); - - if ((entry = Tcl_FindHashEntry(&aliasTablePtr, string)) != NULL) { - aliasPtr = Tcl_GetHashValue(entry); - origctx = hexchat_get_context(ph); - if (EvalInternalProc(aliasPtr->procPtr, 2, string, word_eol[2]) == TCL_ERROR) { - hexchat_printf(ph, "\0039Tcl plugin\003\tERROR (alias %s) ", string); - NiceErrorInfo (); - } - hexchat_set_context(ph, origctx); - } - - Tcl_Free(string); - - return complete[complete_level--].result; -} - -static int Null_Command_Alias(char *word[], char *word_eol[], void *userdata) -{ - alias *aliasPtr; - Tcl_HashEntry *entry; - hexchat_context *origctx; - int dummy; - const char *channel; - char *string; - Tcl_DString ds; - static int recurse = 0; - - if (recurse) - return HEXCHAT_EAT_NONE; - - if (complete_level == MAX_COMPLETES) - return HEXCHAT_EAT_NONE; - - complete_level++; - complete[complete_level].defresult = HEXCHAT_EAT_ALL; - complete[complete_level].result = HEXCHAT_EAT_NONE; - complete[complete_level].word = word; - complete[complete_level].word_eol = word_eol; - - recurse++; - - channel = hexchat_get_info(ph, "channel"); - Tcl_DStringInit(&ds); - Tcl_DStringAppend(&ds, "@", 1); - Tcl_DStringAppend(&ds, channel, strlen(channel)); - string = StrDup(ds.string, &dummy); - Tcl_DStringFree(&ds); - - Tcl_UtfToUpper(string); - - if ((entry = Tcl_FindHashEntry(&aliasTablePtr, string)) != NULL) { - aliasPtr = Tcl_GetHashValue(entry); - origctx = hexchat_get_context(ph); - if (EvalInternalProc(aliasPtr->procPtr, 2, string, word_eol[1]) == TCL_ERROR) { - hexchat_printf(ph, "\0039Tcl plugin\003\tERROR (alias %s) ", string); - NiceErrorInfo (); - } - hexchat_set_context(ph, origctx); - } - - Tcl_Free(string); - - recurse--; - - return complete[complete_level--].result; -} - -static int Command_TCL(char *word[], char *word_eol[], void *userdata) -{ - const char *errorInfo; - - complete_level++; - complete[complete_level].word = word; - complete[complete_level].word_eol = word_eol; - - if (Tcl_Eval(interp, word_eol[2]) == TCL_ERROR) { - errorInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY); - hexchat_printf(ph, "\0039Tcl plugin\003\tERROR: %s ", errorInfo); - } else - hexchat_printf(ph, "\0039Tcl plugin\003\tRESULT: %s ", Tcl_GetStringResult(interp)); - - complete_level--; - - return HEXCHAT_EAT_ALL; -} - -static int Command_Source(char *word[], char *word_eol[], void *userdata) -{ - const char *hexchatdir; - Tcl_DString ds; - struct stat dummy; - int len; - const char *errorInfo; - - if (!strlen(word_eol[2])) - return HEXCHAT_EAT_NONE; - - complete_level++; - complete[complete_level].word = word; - complete[complete_level].word_eol = word_eol; - - len = strlen(word[2]); - - if (len > 4 && strcasecmp(".tcl", word[2] + len - 4) == 0) { - - hexchatdir = hexchat_get_info(ph, "configdir"); - - Tcl_DStringInit(&ds); - - if (stat(word_eol[2], &dummy) == 0) { - Tcl_DStringAppend(&ds, word_eol[2], strlen(word_eol[2])); - } else { - if (!strchr(word_eol[2], '/')) { - Tcl_DStringAppend(&ds, hexchatdir, strlen(hexchatdir)); - Tcl_DStringAppend(&ds, "/addons/", 8); - Tcl_DStringAppend(&ds, word_eol[2], strlen(word_eol[2])); - } - } - - if (Tcl_EvalFile(interp, ds.string) == TCL_ERROR) { - errorInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY); - hexchat_printf(ph, "\0039Tcl plugin\003\tERROR: %s ", errorInfo); - } else - hexchat_printf(ph, "\0039Tcl plugin\003\tSourced %s\n", ds.string); - - Tcl_DStringFree(&ds); - - complete_level--; - - return HEXCHAT_EAT_HEXCHAT; - - } else { - complete_level--; - return HEXCHAT_EAT_NONE; - } - -} - -static int Command_Reloadall(char *word[], char *word_eol[], void *userdata) -{ - Tcl_Plugin_DeInit(); - Tcl_Plugin_Init(); - - hexchat_print(ph, "\0039Tcl plugin\003\tRehashed\n"); - - return HEXCHAT_EAT_ALL; -} - -static int TCL_Event_Handler(void *userdata) -{ - Tcl_DoOneEvent(TCL_DONT_WAIT); - do_timer(); - return 1; -} - -static void Tcl_Plugin_Init() -{ - int x; - const char *hexchatdir; - - interp = Tcl_CreateInterp(); - - Tcl_FindExecutable(NULL); - - Tcl_Init(interp); - - nextprocid = 0x1000; - - Tcl_CreateCommand(interp, "alias", tcl_alias, NULL, NULL); - Tcl_CreateCommand(interp, "channels", tcl_channels, NULL, NULL); - Tcl_CreateCommand(interp, "chats", tcl_chats, NULL, NULL); - Tcl_CreateCommand(interp, "command", tcl_command, NULL, NULL); - Tcl_CreateCommand(interp, "complete", tcl_complete, NULL, NULL); - Tcl_CreateCommand(interp, "dcclist", tcl_dcclist, NULL, NULL); - Tcl_CreateCommand(interp, "notifylist", tcl_notifylist, NULL, NULL); - Tcl_CreateCommand(interp, "findcontext", tcl_findcontext, NULL, NULL); - Tcl_CreateCommand(interp, "getcontext", tcl_getcontext, NULL, NULL); - Tcl_CreateCommand(interp, "getinfo", tcl_getinfo, NULL, NULL); - Tcl_CreateCommand(interp, "getlist", tcl_getlist, NULL, NULL); - Tcl_CreateCommand(interp, "ignores", tcl_ignores, NULL, NULL); - Tcl_CreateCommand(interp, "killtimer", tcl_killtimer, NULL, NULL); - Tcl_CreateCommand(interp, "me", tcl_me, NULL, NULL); - Tcl_CreateCommand(interp, "on", tcl_on, NULL, NULL); - Tcl_CreateCommand(interp, "off", tcl_off, NULL, NULL); - Tcl_CreateCommand(interp, "nickcmp", tcl_hexchat_nickcmp, NULL, NULL); - Tcl_CreateCommand(interp, "print", tcl_print, NULL, NULL); - Tcl_CreateCommand(interp, "prefs", tcl_prefs, NULL, NULL); - Tcl_CreateCommand(interp, "::puts", tcl_xchat_puts, NULL, NULL); - Tcl_CreateCommand(interp, "queries", tcl_queries, NULL, NULL); - Tcl_CreateCommand(interp, "raw", tcl_raw, NULL, NULL); - Tcl_CreateCommand(interp, "servers", tcl_servers, NULL, NULL); - Tcl_CreateCommand(interp, "setcontext", tcl_setcontext, NULL, NULL); - Tcl_CreateCommand(interp, "strip", tcl_strip, NULL, NULL); - Tcl_CreateCommand(interp, "timer", tcl_timer, NULL, NULL); - Tcl_CreateCommand(interp, "timerexists", tcl_timerexists, NULL, NULL); - Tcl_CreateCommand(interp, "timers", tcl_timers, NULL, NULL); - Tcl_CreateCommand(interp, "topic", tcl_topic, NULL, NULL); - Tcl_CreateCommand(interp, "users", tcl_users, NULL, NULL); - Tcl_CreateCommand(interp, "word", tcl_word, NULL, NULL); - Tcl_CreateCommand(interp, "word_eol", tcl_word_eol, NULL, NULL); - - Tcl_InitHashTable(&cmdTablePtr, TCL_STRING_KEYS); - Tcl_InitHashTable(&aliasTablePtr, TCL_STRING_KEYS); - - bzero(timers, sizeof(timers)); - nexttimerid = 0; - nexttimerindex = 0; - - for (x = 0; x < XC_SIZE; x++) - xc[x].hook = NULL; - - hexchatdir = hexchat_get_info(ph, "configdir"); - - if (Tcl_Eval(interp, unknown) == TCL_ERROR) { - hexchat_printf(ph, "Error sourcing internal 'unknown' (%s)\n", Tcl_GetStringResult(interp)); - } - - if (Tcl_Eval(interp, inlinetcl) == TCL_ERROR) { - hexchat_printf(ph, "Error sourcing internal 'inlinetcl' (%s)\n", Tcl_GetStringResult(interp)); - } - - if (Tcl_Eval(interp, sourcedirs) == TCL_ERROR) { - hexchat_printf(ph, "Error sourcing internal 'sourcedirs' (%s)\n", Tcl_GetStringResult(interp)); - } - -} - -static void Tcl_Plugin_DeInit() -{ - int x; - char *procPtr; - alias *aliasPtr; - Tcl_HashEntry *entry; - Tcl_HashSearch search; - - /* Be sure to free all the memory for ON and ALIAS entries */ - - entry = Tcl_FirstHashEntry(&cmdTablePtr, &search); - while (entry != NULL) { - procPtr = Tcl_GetHashValue(entry); - Tcl_Free(procPtr); - entry = Tcl_NextHashEntry(&search); - } - - Tcl_DeleteHashTable(&cmdTablePtr); - - entry = Tcl_FirstHashEntry(&aliasTablePtr, &search); - while (entry != NULL) { - aliasPtr = Tcl_GetHashValue(entry); - Tcl_Free(aliasPtr->procPtr); - if (aliasPtr->hook) - hexchat_unhook(ph, aliasPtr->hook); - Tcl_Free((char *) aliasPtr); - entry = Tcl_NextHashEntry(&search); - } - - Tcl_DeleteHashTable(&aliasTablePtr); - - for (x = 1; x < MAX_TIMERS; x++) { - if (timers[x].timerid) { - timers[x].timerid = 0; - if (timers[x].procPtr != NULL) - Tcl_Free(timers[x].procPtr); - timers[x].procPtr = NULL; - break; - } - } - - for (x = 0; x < XC_SIZE; x++) { - if (xc[x].hook != NULL) { - hexchat_unhook(ph, xc[x].hook); - xc[x].hook = NULL; - } - } - - Tcl_DeleteInterp(interp); -} - -static void banner() -{ -#if 0 - hexchat_printf(ph, "Tcl plugin for HexChat - Version %s\n", VERSION); - hexchat_print(ph, "Copyright 2002-2012 Daniel P. Stasinski\n"); - hexchat_print(ph, "http://www.scriptkitties.com/tclplugin/\n"); -#endif -} - -int hexchat_plugin_init(hexchat_plugin * plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg) -{ -#ifdef WIN32 - HINSTANCE lib; -#endif - - strncpy(VERSION, &RCSID[19], 5); - - ph = plugin_handle; - -#ifdef WIN32 - lib = LoadLibraryA(TCL_DLL); - if (!lib) { - hexchat_print(ph, "You must have ActiveTCL 8.5 installed in order to run Tcl scripts.\n" "http://www.activestate.com/activetcl/downloads\n" "Make sure Tcl's bin directory is in your PATH.\n"); - return 0; - } - FreeLibrary(lib); -#endif - - if (initialized != 0) { - banner(); - hexchat_print(ph, "Tcl interface already loaded"); - reinit_tried++; - return 0; - } - initialized = 1; - - *plugin_name = "Tcl"; - *plugin_desc = "Tcl scripting interface"; - *plugin_version = VERSION; - - Tcl_Plugin_Init(); - - raw_line_hook = hexchat_hook_server(ph, "RAW LINE", HEXCHAT_PRI_NORM, Server_raw_line, NULL); - Command_TCL_hook = hexchat_hook_command(ph, "tcl", HEXCHAT_PRI_NORM, Command_TCL, 0, 0); - Command_Source_hook = hexchat_hook_command(ph, "source", HEXCHAT_PRI_NORM, Command_Source, 0, 0); - Command_Reload_hook = hexchat_hook_command(ph, "reloadall", HEXCHAT_PRI_NORM, Command_Reloadall, 0, 0); - Command_Load_hook = hexchat_hook_command(ph, "LOAD", HEXCHAT_PRI_NORM, Command_Source, 0, 0); - Event_Handler_hook = hexchat_hook_timer(ph, 100, TCL_Event_Handler, 0); - Null_Command_hook = hexchat_hook_command(ph, "", HEXCHAT_PRI_NORM, Null_Command_Alias, "", 0); - - banner(); - hexchat_print(ph, "Tcl interface loaded\n"); - - return 1; /* return 1 for success */ -} - -int hexchat_plugin_deinit() -{ - if (reinit_tried) { - reinit_tried--; - return 1; - } - - hexchat_unhook(ph, raw_line_hook); - hexchat_unhook(ph, Command_TCL_hook); - hexchat_unhook(ph, Command_Source_hook); - hexchat_unhook(ph, Command_Reload_hook); - hexchat_unhook(ph, Command_Load_hook); - hexchat_unhook(ph, Event_Handler_hook); - hexchat_unhook(ph, Null_Command_hook); - - Tcl_Plugin_DeInit(); - - hexchat_print(ph, "Tcl interface unloaded\n"); - initialized = 0; - - return 1; -} - -void hexchat_plugin_get_info(char **name, char **desc, char **version, void **reserved) -{ - strncpy(VERSION, &RCSID[19], 5); - *name = "tclplugin"; - *desc = "Tcl plugin for HexChat"; - *version = VERSION; - if (reserved) - *reserved = NULL; -} - diff --git a/plugins/tcl/tclplugin.h b/plugins/tcl/tclplugin.h deleted file mode 100644 index 0b82fbcd..00000000 --- a/plugins/tcl/tclplugin.h +++ /dev/null @@ -1,98 +0,0 @@ -/*************************************************************************** - tclplugin.h - TCL plugin header file - ------------------------------------------------- - begin : Sat Nov 9 17:31:20 MST 2002 - copyright : Copyright 2002-2012 Daniel P. Stasinski - email : daniel@GenericInbox.com - ***************************************************************************/ - -/*************************************************************************** - * * - * 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. * - * * - ***************************************************************************/ - -#define BADARGS(nl,nh,example) \ - if ((argc<(nl)) || (argc>(nh))) { \ - Tcl_AppendResult(irp,"wrong # args: should be \"",argv[0], \ - (example),"\"",NULL); \ - return TCL_ERROR; \ - } - -#define CHECKCTX(ctx) \ - if (ctx == NULL) { \ - Tcl_AppendResult(irp, "No such server/channel/nick", NULL); \ - return TCL_ERROR; \ - } - -typedef struct { - char *procPtr; - hexchat_hook *hook; -} alias; - -typedef struct { - int timerid; - time_t timestamp; - char *procPtr; - int count; - int seconds; -} timer; - -typedef struct { - int result; - int defresult; - char **word; - char **word_eol; -} t_complete; - -#define MAX_TIMERS 512 -#define MAX_COMPLETES 128 - -static char *StrDup(const char *string, int *length); -static char *myitoa(long value); -static hexchat_context *xchat_smart_context(const char *arg1, const char *arg2); -static void queue_nexttimer(); -static int insert_timer(int seconds, int count, const char *script); -static void do_timer(); -static int Server_raw_line(char *word[], char *word_eol[], void *userdata); -static int Print_Hook(char *word[], void *userdata); -static int tcl_timerexists(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_killtimer(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_timers(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_timer(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_on(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_off(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_alias(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_complete(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_raw(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_command(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_xchat_puts(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_print(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_channels(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_servers(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_queries(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_users(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_chats(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_ignores(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_dcclist(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_me(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_hexchat_nickcmp(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_strip(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_topic(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_word(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_word_eol(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int tcl_notifylist(ClientData cd, Tcl_Interp * irp, int argc, const char *argv[]); -static int Command_Alias(char *word[], char *word_eol[], void *userdata); -static int Null_Command_Alias(char *word[], char *word_eol[], void *userdata); -static int Command_TCL(char *word[], char *word_eol[], void *userdata); -static int Command_Source(char *word[], char *word_eol[], void *userdata); -/* static int Command_Reload(char *word[], char *word_eol[], void *userdata); */ -static int TCL_Event_Handler(void *userdata); -static void Tcl_Plugin_Init(); -static void Tcl_Plugin_DeInit(); -static void banner(); -int hexchat_plugin_init(hexchat_plugin * plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg); -int hexchat_plugin_deinit(); diff --git a/win32/hexchat.props b/win32/hexchat.props index 61a664e8..8ba5527f 100644 --- a/win32/hexchat.props +++ b/win32/hexchat.props @@ -17,11 +17,6 @@ $(YourDepsPath)\$(PlatformName) $(YourGendefPath) $(YourMsgfmtPath) -