diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/scripts/lua/weechat-lua.c | 103 | ||||
-rw-r--r-- | src/plugins/scripts/perl/weechat-perl.c | 103 | ||||
-rw-r--r-- | src/plugins/scripts/python/weechat-python.c | 112 | ||||
-rw-r--r-- | src/plugins/scripts/ruby/weechat-ruby.c | 103 | ||||
-rw-r--r-- | src/plugins/scripts/script.c | 282 | ||||
-rw-r--r-- | src/plugins/scripts/script.h | 18 | ||||
-rw-r--r-- | src/plugins/scripts/tcl/weechat-tcl.c | 103 |
7 files changed, 765 insertions, 59 deletions
diff --git a/src/plugins/scripts/lua/weechat-lua.c b/src/plugins/scripts/lua/weechat-lua.c index 943b4cf43..46ca1e4b8 100644 --- a/src/plugins/scripts/lua/weechat-lua.c +++ b/src/plugins/scripts/lua/weechat-lua.c @@ -49,6 +49,20 @@ struct t_plugin_script *lua_current_script = NULL; const char *lua_current_script_filename = NULL; lua_State *lua_current_interpreter = NULL; +/* string used to execute action "install": + when signal "lua_install_script" is received, name of string + is added to this string, to be installed later by a timer (when nothing is + running in script) +*/ +char *lua_action_install_list = NULL; + +/* string used to execute action "remove": + when signal "lua_remove_script" is received, name of string + is added to this string, to be removed later by a timer (when nothing is + running in script) +*/ +char *lua_action_remove_list = NULL; + /* * weechat_lua_exec: execute a Lua script @@ -407,8 +421,8 @@ weechat_lua_command_cb (void *data, struct t_gui_buffer *buffer, else if (weechat_strcasecmp (argv[1], "load") == 0) { /* load Lua script */ - path_script = script_search_full_name (weechat_lua_plugin, - argv_eol[2]); + path_script = script_search_path (weechat_lua_plugin, + argv_eol[2]); weechat_lua_load ((path_script) ? path_script : argv_eol[2]); if (path_script) free (path_script); @@ -474,12 +488,12 @@ weechat_lua_infolist_cb (void *data, const char *infolist_name, } /* - * weechat_lua_debug_dump_cb: dump Lua plugin data in WeeChat log file + * weechat_lua_signal_debug_dump_cb: dump Lua plugin data in WeeChat log file */ int -weechat_lua_debug_dump_cb (void *data, const char *signal, - const char *type_data, void *signal_data) +weechat_lua_signal_debug_dump_cb (void *data, const char *signal, + const char *type_data, void *signal_data) { /* make C compiler happy */ (void) data; @@ -493,12 +507,12 @@ weechat_lua_debug_dump_cb (void *data, const char *signal, } /* - * weechat_lua_buffer_closed_cb: callback called when a buffer is closed + * weechat_lua_signal_buffer_closed_cb: callback called when a buffer is closed */ int -weechat_lua_buffer_closed_cb (void *data, const char *signal, - const char *type_data, void *signal_data) +weechat_lua_signal_buffer_closed_cb (void *data, const char *signal, + const char *type_data, void *signal_data) { /* make C compiler happy */ (void) data; @@ -512,6 +526,74 @@ weechat_lua_buffer_closed_cb (void *data, const char *signal, } /* + * weechat_lua_timer_action_cb: timer for executing actions + */ + +int +weechat_lua_timer_action_cb (void *data, int remaining_calls) +{ + /* make C compiler happy */ + (void) remaining_calls; + + if (data) + { + if (data == &lua_action_install_list) + { + script_action_install (weechat_lua_plugin, + lua_scripts, + &weechat_lua_unload, + &weechat_lua_load, + &lua_action_install_list); + } + else if (data == &lua_action_remove_list) + { + script_action_remove (weechat_lua_plugin, + lua_scripts, + &weechat_lua_unload, + &lua_action_remove_list); + } + } + + return WEECHAT_RC_OK; +} + +/* + * weechat_lua_signal_script_action_cb: callback called when a script action + * is asked (install/remove a script) + */ + +int +weechat_lua_signal_script_action_cb (void *data, const char *signal, + const char *type_data, + void *signal_data) +{ + /* make C compiler happy */ + (void) data; + + if (strcmp (type_data, WEECHAT_HOOK_SIGNAL_STRING) == 0) + { + if (strcmp (signal, "lua_script_install") == 0) + { + script_action_add (&lua_action_install_list, + (const char *)signal_data); + weechat_hook_timer (1, 0, 1, + &weechat_lua_timer_action_cb, + &lua_action_install_list); + } + else if (strcmp (signal, "lua_script_remove") == 0) + { + script_action_add (&lua_action_remove_list, + (const char *)signal_data); + weechat_hook_timer (1, 0, 1, + &weechat_lua_timer_action_cb, + &lua_action_remove_list); + } + } + + return WEECHAT_RC_OK; +} + +/* * weechat_plugin_init: initialize Lua plugin */ @@ -529,8 +611,9 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[]) &weechat_lua_command_cb, &weechat_lua_completion_cb, &weechat_lua_infolist_cb, - &weechat_lua_debug_dump_cb, - &weechat_lua_buffer_closed_cb, + &weechat_lua_signal_debug_dump_cb, + &weechat_lua_signal_buffer_closed_cb, + &weechat_lua_signal_script_action_cb, &weechat_lua_load_cb); lua_quiet = 0; diff --git a/src/plugins/scripts/perl/weechat-perl.c b/src/plugins/scripts/perl/weechat-perl.c index 50fcc8a83..281f6c176 100644 --- a/src/plugins/scripts/perl/weechat-perl.c +++ b/src/plugins/scripts/perl/weechat-perl.c @@ -46,6 +46,20 @@ struct t_plugin_script *last_perl_script = NULL; struct t_plugin_script *perl_current_script = NULL; const char *perl_current_script_filename = NULL; +/* string used to execute action "install": + when signal "perl_install_script" is received, name of string + is added to this string, to be installed later by a timer (when nothing is + running in script) +*/ +char *perl_action_install_list = NULL; + +/* string used to execute action "remove": + when signal "perl_remove_script" is received, name of string + is added to this string, to be removed later by a timer (when nothing is + running in script) +*/ +char *perl_action_remove_list = NULL; + #ifdef NO_PERL_MULTIPLICITY #undef MULTIPLICITY #endif @@ -552,8 +566,8 @@ weechat_perl_command_cb (void *data, struct t_gui_buffer *buffer, else if (weechat_strcasecmp (argv[1], "load") == 0) { /* load Perl script */ - path_script = script_search_full_name (weechat_perl_plugin, - argv_eol[2]); + path_script = script_search_path (weechat_perl_plugin, + argv_eol[2]); weechat_perl_load ((path_script) ? path_script : argv_eol[2]); if (path_script) free (path_script); @@ -619,12 +633,12 @@ weechat_perl_infolist_cb (void *data, const char *infolist_name, } /* - * weechat_perl_debug_dump_cb: dump Perl plugin data in WeeChat log file + * weechat_perl_signal_debug_dump_cb: dump Perl plugin data in WeeChat log file */ int -weechat_perl_debug_dump_cb (void *data, const char *signal, - const char *type_data, void *signal_data) +weechat_perl_signal_debug_dump_cb (void *data, const char *signal, + const char *type_data, void *signal_data) { /* make C compiler happy */ (void) data; @@ -638,12 +652,12 @@ weechat_perl_debug_dump_cb (void *data, const char *signal, } /* - * weechat_perl_buffer_closed_cb: callback called when a buffer is closed + * weechat_perl_signal_buffer_closed_cb: callback called when a buffer is closed */ int -weechat_perl_buffer_closed_cb (void *data, const char *signal, - const char *type_data, void *signal_data) +weechat_perl_signal_buffer_closed_cb (void *data, const char *signal, + const char *type_data, void *signal_data) { /* make C compiler happy */ (void) data; @@ -657,6 +671,74 @@ weechat_perl_buffer_closed_cb (void *data, const char *signal, } /* + * weechat_perl_timer_action_cb: timer for executing actions + */ + +int +weechat_perl_timer_action_cb (void *data, int remaining_calls) +{ + /* make C compiler happy */ + (void) remaining_calls; + + if (data) + { + if (data == &perl_action_install_list) + { + script_action_install (weechat_perl_plugin, + perl_scripts, + &weechat_perl_unload, + &weechat_perl_load, + &perl_action_install_list); + } + else if (data == &perl_action_remove_list) + { + script_action_remove (weechat_perl_plugin, + perl_scripts, + &weechat_perl_unload, + &perl_action_remove_list); + } + } + + return WEECHAT_RC_OK; +} + +/* + * weechat_perl_signal_script_action_cb: callback called when a script action + * is asked (install/remove a script) + */ + +int +weechat_perl_signal_script_action_cb (void *data, const char *signal, + const char *type_data, + void *signal_data) +{ + /* make C compiler happy */ + (void) data; + + if (strcmp (type_data, WEECHAT_HOOK_SIGNAL_STRING) == 0) + { + if (strcmp (signal, "perl_script_install") == 0) + { + script_action_add (&perl_action_install_list, + (const char *)signal_data); + weechat_hook_timer (1, 0, 1, + &weechat_perl_timer_action_cb, + &perl_action_install_list); + } + else if (strcmp (signal, "perl_script_remove") == 0) + { + script_action_add (&perl_action_remove_list, + (const char *)signal_data); + weechat_hook_timer (1, 0, 1, + &weechat_perl_timer_action_cb, + &perl_action_remove_list); + } + } + + return WEECHAT_RC_OK; +} + +/* * weechat_plugin_init: initialize Perl plugin */ @@ -705,8 +787,9 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[]) &weechat_perl_command_cb, &weechat_perl_completion_cb, &weechat_perl_infolist_cb, - &weechat_perl_debug_dump_cb, - &weechat_perl_buffer_closed_cb, + &weechat_perl_signal_debug_dump_cb, + &weechat_perl_signal_buffer_closed_cb, + &weechat_perl_signal_script_action_cb, &weechat_perl_load_cb); perl_quiet = 0; diff --git a/src/plugins/scripts/python/weechat-python.c b/src/plugins/scripts/python/weechat-python.c index 134e5b1ec..02f09bcc1 100644 --- a/src/plugins/scripts/python/weechat-python.c +++ b/src/plugins/scripts/python/weechat-python.c @@ -45,6 +45,20 @@ struct t_plugin_script *python_current_script = NULL; const char *python_current_script_filename = NULL; PyThreadState *python_mainThreadState = NULL; +/* string used to execute action "install": + when signal "python_install_script" is received, name of string + is added to this string, to be installed later by a timer (when nothing is + running in script) +*/ +char *python_action_install_list = NULL; + +/* string used to execute action "remove": + when signal "python_remove_script" is received, name of string + is added to this string, to be removed later by a timer (when nothing is + running in script) +*/ +char *python_action_remove_list = NULL; + char python_buffer_output[128]; @@ -637,8 +651,8 @@ weechat_python_command_cb (void *data, struct t_gui_buffer *buffer, else if (weechat_strcasecmp (argv[1], "load") == 0) { /* load Python script */ - path_script = script_search_full_name (weechat_python_plugin, - argv_eol[2]); + path_script = script_search_path (weechat_python_plugin, + argv_eol[2]); weechat_python_load ((path_script) ? path_script : argv_eol[2]); if (path_script) free (path_script); @@ -705,12 +719,13 @@ weechat_python_infolist_cb (void *data, const char *infolist_name, } /* - * weechat_python_debug_dump_cb: dump Python plugin data in WeeChat log file + * weechat_python_signal_debug_dump_cb: dump Python plugin data in WeeChat log + * file */ int -weechat_python_debug_dump_cb (void *data, const char *signal, - const char *type_data, void *signal_data) +weechat_python_signal_debug_dump_cb (void *data, const char *signal, + const char *type_data, void *signal_data) { /* make C compiler happy */ (void) data; @@ -724,12 +739,14 @@ weechat_python_debug_dump_cb (void *data, const char *signal, } /* - * weechat_python_buffer_closed_cb: callback called when a buffer is closed + * weechat_python_signal_buffer_closed_cb: callback called when a buffer is + * closed */ int -weechat_python_buffer_closed_cb (void *data, const char *signal, - const char *type_data, void *signal_data) +weechat_python_signal_buffer_closed_cb (void *data, const char *signal, + const char *type_data, + void *signal_data) { /* make C compiler happy */ (void) data; @@ -743,6 +760,74 @@ weechat_python_buffer_closed_cb (void *data, const char *signal, } /* + * weechat_python_timer_action_cb: timer for executing actions + */ + +int +weechat_python_timer_action_cb (void *data, int remaining_calls) +{ + /* make C compiler happy */ + (void) remaining_calls; + + if (data) + { + if (data == &python_action_install_list) + { + script_action_install (weechat_python_plugin, + python_scripts, + &weechat_python_unload, + &weechat_python_load, + &python_action_install_list); + } + else if (data == &python_action_remove_list) + { + script_action_remove (weechat_python_plugin, + python_scripts, + &weechat_python_unload, + &python_action_remove_list); + } + } + + return WEECHAT_RC_OK; +} + +/* + * weechat_python_signal_script_action_cb: callback called when a script action + * is asked (install/remove a script) + */ + +int +weechat_python_signal_script_action_cb (void *data, const char *signal, + const char *type_data, + void *signal_data) +{ + /* make C compiler happy */ + (void) data; + + if (strcmp (type_data, WEECHAT_HOOK_SIGNAL_STRING) == 0) + { + if (strcmp (signal, "python_script_install") == 0) + { + script_action_add (&python_action_install_list, + (const char *)signal_data); + weechat_hook_timer (1, 0, 1, + &weechat_python_timer_action_cb, + &python_action_install_list); + } + else if (strcmp (signal, "python_script_remove") == 0) + { + script_action_add (&python_action_remove_list, + (const char *)signal_data); + weechat_hook_timer (1, 0, 1, + &weechat_python_timer_action_cb, + &python_action_remove_list); + } + } + + return WEECHAT_RC_OK; +} + +/* * weechat_plugin_init: initialize Python plugin */ @@ -787,8 +872,9 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[]) &weechat_python_command_cb, &weechat_python_completion_cb, &weechat_python_infolist_cb, - &weechat_python_debug_dump_cb, - &weechat_python_buffer_closed_cb, + &weechat_python_signal_debug_dump_cb, + &weechat_python_signal_buffer_closed_cb, + &weechat_python_signal_script_action_cb, &weechat_python_load_cb); python_quiet = 0; @@ -829,5 +915,11 @@ weechat_plugin_end (struct t_weechat_plugin *plugin) weechat_prefix ("error"), PYTHON_PLUGIN_NAME); } + /* free some data */ + if (python_action_install_list) + free (python_action_install_list); + if (python_action_remove_list) + free (python_action_remove_list); + return WEECHAT_RC_OK; } diff --git a/src/plugins/scripts/ruby/weechat-ruby.c b/src/plugins/scripts/ruby/weechat-ruby.c index 78a3965a4..836f68602 100644 --- a/src/plugins/scripts/ruby/weechat-ruby.c +++ b/src/plugins/scripts/ruby/weechat-ruby.c @@ -47,6 +47,20 @@ struct t_plugin_script *last_ruby_script = NULL; struct t_plugin_script *ruby_current_script = NULL; const char *ruby_current_script_filename = NULL; +/* string used to execute action "install": + when signal "ruby_install_script" is received, name of string + is added to this string, to be installed later by a timer (when nothing is + running in script) +*/ +char *ruby_action_install_list = NULL; + +/* string used to execute action "remove": + when signal "ruby_remove_script" is received, name of string + is added to this string, to be removed later by a timer (when nothing is + running in script) +*/ +char *ruby_action_remove_list = NULL; + VALUE ruby_mWeechat, ruby_mWeechatOutputs; #define MOD_NAME_PREFIX "WeechatRubyModule" @@ -606,8 +620,8 @@ weechat_ruby_command_cb (void *data, struct t_gui_buffer *buffer, else if (weechat_strcasecmp (argv[1], "load") == 0) { /* load Ruby script */ - path_script = script_search_full_name (weechat_ruby_plugin, - argv_eol[2]); + path_script = script_search_path (weechat_ruby_plugin, + argv_eol[2]); weechat_ruby_load ((path_script) ? path_script : argv_eol[2]); if (path_script) free (path_script); @@ -673,12 +687,12 @@ weechat_ruby_infolist_cb (void *data, const char *infolist_name, } /* - * weechat_ruby_debug_dump_cb: dump Ruby plugin data in WeeChat log file + * weechat_ruby_signal_debug_dump_cb: dump Ruby plugin data in WeeChat log file */ int -weechat_ruby_debug_dump_cb (void *data, const char *signal, - const char *type_data, void *signal_data) +weechat_ruby_signal_debug_dump_cb (void *data, const char *signal, + const char *type_data, void *signal_data) { /* make C compiler happy */ (void) data; @@ -692,12 +706,12 @@ weechat_ruby_debug_dump_cb (void *data, const char *signal, } /* - * weechat_ruby_buffer_closed_cb: callback called when a buffer is closed + * weechat_ruby_signal_buffer_closed_cb: callback called when a buffer is closed */ int -weechat_ruby_buffer_closed_cb (void *data, const char *signal, - const char *type_data, void *signal_data) +weechat_ruby_signal_buffer_closed_cb (void *data, const char *signal, + const char *type_data, void *signal_data) { /* make C compiler happy */ (void) data; @@ -711,6 +725,74 @@ weechat_ruby_buffer_closed_cb (void *data, const char *signal, } /* + * weechat_ruby_timer_action_cb: timer for executing actions + */ + +int +weechat_ruby_timer_action_cb (void *data, int remaining_calls) +{ + /* make C compiler happy */ + (void) remaining_calls; + + if (data) + { + if (data == &ruby_action_install_list) + { + script_action_install (weechat_ruby_plugin, + ruby_scripts, + &weechat_ruby_unload, + &weechat_ruby_load, + &ruby_action_install_list); + } + else if (data == &ruby_action_remove_list) + { + script_action_remove (weechat_ruby_plugin, + ruby_scripts, + &weechat_ruby_unload, + &ruby_action_remove_list); + } + } + + return WEECHAT_RC_OK; +} + +/* + * weechat_ruby_signal_script_action_cb: callback called when a script action + * is asked (install/remove a script) + */ + +int +weechat_ruby_signal_script_action_cb (void *data, const char *signal, + const char *type_data, + void *signal_data) +{ + /* make C compiler happy */ + (void) data; + + if (strcmp (type_data, WEECHAT_HOOK_SIGNAL_STRING) == 0) + { + if (strcmp (signal, "ruby_script_install") == 0) + { + script_action_add (&ruby_action_install_list, + (const char *)signal_data); + weechat_hook_timer (1, 0, 1, + &weechat_ruby_timer_action_cb, + &ruby_action_install_list); + } + else if (strcmp (signal, "ruby_script_remove") == 0) + { + script_action_add (&ruby_action_remove_list, + (const char *)signal_data); + weechat_hook_timer (1, 0, 1, + &weechat_ruby_timer_action_cb, + &ruby_action_remove_list); + } + } + + return WEECHAT_RC_OK; +} + +/* * weechat_plugin_init: initialize Ruby plugin */ @@ -810,8 +892,9 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[]) &weechat_ruby_command_cb, &weechat_ruby_completion_cb, &weechat_ruby_infolist_cb, - &weechat_ruby_debug_dump_cb, - &weechat_ruby_buffer_closed_cb, + &weechat_ruby_signal_debug_dump_cb, + &weechat_ruby_signal_buffer_closed_cb, + &weechat_ruby_signal_script_action_cb, &weechat_ruby_load_cb); ruby_quiet = 0; diff --git a/src/plugins/scripts/script.c b/src/plugins/scripts/script.c index ede725dcd..32343879f 100644 --- a/src/plugins/scripts/script.c +++ b/src/plugins/scripts/script.c @@ -20,7 +20,10 @@ #include <stdlib.h> +#include <unistd.h> #include <stdio.h> +#include <errno.h> +#include <libgen.h> #include <string.h> #include <ctype.h> #include <sys/types.h> @@ -95,12 +98,15 @@ script_init (struct t_weechat_plugin *weechat_plugin, const char *type_data, void *signal_data), int (*callback_signal_buffer_closed)(void *data, const char *signal, - const char *type_data, - void *signal_data), + const char *type_data, + void *signal_data), + int (*callback_signal_script_action)(void *data, const char *signal, + const char *type_data, + void *signal_data), void (*callback_load_file)(void *data, const char *filename)) { char *string, *completion = "list|listfull|load|autoload|reload|unload %f"; - char infolist_description[512]; + char infolist_description[512], signal_name[128]; int length; /* read script configuration */ @@ -171,6 +177,14 @@ script_init (struct t_weechat_plugin *weechat_plugin, /* add signal for "buffer_closed" */ weechat_hook_signal ("buffer_closed", callback_signal_buffer_closed, NULL); + /* add signal for a script action (install/remove) */ + snprintf (signal_name, sizeof (signal_name), "%s_script_install", + weechat_plugin->name); + weechat_hook_signal (signal_name, callback_signal_script_action, NULL); + snprintf (signal_name, sizeof (signal_name), "%s_script_remove", + weechat_plugin->name); + weechat_hook_signal (signal_name, callback_signal_script_action, NULL); + /* autoload scripts */ script_auto_load (weechat_plugin, callback_load_file); } @@ -267,7 +281,7 @@ script_auto_load (struct t_weechat_plugin *weechat_plugin, } /* - * script_search: search a script in list + * script_search: search a script in list (by registered name) */ struct t_plugin_script * @@ -288,12 +302,45 @@ script_search (struct t_weechat_plugin *weechat_plugin, } /* - * script_search_full_name: search the full path name of a script + * script_search_by_full_name: search a script in list (by full name, for + * example "weeget.py") + */ + +struct t_plugin_script * +script_search_by_full_name (struct t_plugin_script *scripts, + const char *full_name) +{ + char *full_name_copy, *base_name; + struct t_plugin_script *ptr_script; + + full_name_copy = strdup (full_name); + + if (full_name_copy) + { + for (ptr_script = scripts; ptr_script; + ptr_script = ptr_script->next_script) + { + base_name = basename (ptr_script->filename); + if (strcmp (base_name, full_name) == 0) + { + free (full_name_copy); + return ptr_script; + } + } + free (full_name_copy); + } + + /* script not found */ + return NULL; +} + +/* + * script_search_path: search path name of a script */ char * -script_search_full_name (struct t_weechat_plugin *weechat_plugin, - const char *filename) +script_search_path (struct t_weechat_plugin *weechat_plugin, + const char *filename) { char *final_name; const char *dir_home, *dir_system; @@ -644,6 +691,227 @@ script_completion (struct t_weechat_plugin *weechat_plugin, } /* + * script_action_add: add script name for a plugin action + */ + +void +script_action_add (char **action_list, const char *name) +{ + int length; + + length = strlen (name); + + if (!(*action_list)) + { + *action_list = malloc (length + 1); + if (*action_list) + strcpy (*action_list, name); + } + else + { + *action_list = realloc (*action_list, + strlen (*action_list) + 1 + length + 1); + if (*action_list) + { + strcat (*action_list, ","); + strcat (*action_list, name); + } + } +} + +/* + * script_remove_file: remove script file(s) from disk + */ + +void +script_remove_file (struct t_weechat_plugin *weechat_plugin, const char *name, + int display_error_if_no_script_removed) +{ + int num_found, i; + char *path_script; + + num_found = 0; + i = 0; + while (i < 2) + { + path_script = script_search_path (weechat_plugin, name); + /* script not found? */ + if (!path_script || (strcmp (path_script, name) == 0)) + break; + num_found++; + if (unlink (path_script) == 0) + { + weechat_printf (NULL, _("%s: script removed: %s"), + weechat_plugin->name, + path_script); + } + else + { + weechat_printf (NULL, + _("%s%s: failed to remove script: %s " + "(%s)"), + weechat_prefix ("error"), + weechat_plugin->name, + path_script, + strerror (errno)); + break; + } + free (path_script); + i++; + } + if ((num_found == 0) && display_error_if_no_script_removed) + { + weechat_printf (NULL, + _("%s: script \"%s\" not found, nothing " + "was removed"), + weechat_plugin->name, + name); + } +} + +/* + * script_action_install: install some scripts (using comma separated list) + * this function does following tasks: + * 1. unload script (if script is loaded) + * 2. remove script file(s) + * 3. move script file from "install" dir to language dir + * 4. make link in autoload dir + * 5. load script + */ + +void +script_action_install (struct t_weechat_plugin *weechat_plugin, + struct t_plugin_script *scripts, + void (*script_unload)(struct t_plugin_script *script), + int (*script_load)(const char *filename), + char **list) +{ + char **argv, *name, *base_name, *new_path, *autoload_path, *symlink_path; + const char *dir_home, *dir_separator; + int argc, i, length; + struct t_plugin_script *ptr_script; + + if (*list) + { + argv = weechat_string_explode (*list, ",", 0, 0, &argc); + if (argv) + { + for (i = 0; i < argc; i++) + { + name = strdup (argv[i]); + if (name) + { + base_name = basename (name); + + /* unload script, if script is loaded */ + ptr_script = script_search_by_full_name (scripts, argv[i]); + if (ptr_script) + (*script_unload) (ptr_script); + + /* remove script file(s) */ + script_remove_file (weechat_plugin, argv[i], 0); + + /* move file from install dir to language dir */ + dir_home = weechat_info_get ("weechat_dir", ""); + length = strlen (dir_home) + strlen (weechat_plugin->name) + + strlen (base_name) + 16; + new_path = malloc (length); + if (new_path) + { + snprintf (new_path, length, "%s/%s/%s", + dir_home, weechat_plugin->name, base_name); + if (rename (name, new_path) == 0) + { + /* make link in autoload dir */ + length = strlen (dir_home) + + strlen (weechat_plugin->name) + 8 + + strlen (base_name) + 16; + autoload_path = malloc (length); + if (autoload_path) + { + snprintf (autoload_path, length, + "%s/%s/autoload/%s", + dir_home, weechat_plugin->name, + base_name); + dir_separator = weechat_info_get ("dir_separator", ""); + length = 2 + strlen (dir_separator) + + strlen (base_name) + 1; + symlink_path = malloc (length); + if (symlink_path) + { + snprintf (symlink_path, length, "..%s%s", + dir_separator, base_name); + symlink (symlink_path, autoload_path); + free (symlink_path); + } + free (autoload_path); + } + + /* load script */ + (*script_load) (new_path); + } + else + { + weechat_printf (NULL, + _("%s%s: failed to move script %s " + "to %s (%s)"), + weechat_prefix ("error"), + weechat_plugin->name, + name, + new_path, + strerror (errno)); + } + free (new_path); + } + } + } + weechat_string_free_exploded (argv); + } + free (*list); + *list = NULL; + } +} + +/* + * script_action_remove: remove some scripts (using comma separated list) + * this function does following tasks: + * 1. unload script (if script is loaded) + * 2. remove script file(s) + */ + +void +script_action_remove (struct t_weechat_plugin *weechat_plugin, + struct t_plugin_script *scripts, + void (*script_unload)(struct t_plugin_script *script), + char **list) +{ + char **argv; + int argc, i; + struct t_plugin_script *ptr_script; + + if (*list) + { + argv = weechat_string_explode (*list, ",", 0, 0, &argc); + if (argv) + { + for (i = 0; i < argc; i++) + { + /* unload script, if script is loaded */ + ptr_script = script_search_by_full_name (scripts, argv[i]); + if (ptr_script) + (*script_unload) (ptr_script); + + /* remove script file(s) */ + script_remove_file (weechat_plugin, argv[i], 1); + } + weechat_string_free_exploded (argv); + } + free (*list); + *list = NULL; + } +} + +/* * script_display_list: print list of scripts */ diff --git a/src/plugins/scripts/script.h b/src/plugins/scripts/script.h index 159519749..94f9c318c 100644 --- a/src/plugins/scripts/script.h +++ b/src/plugins/scripts/script.h @@ -77,6 +77,10 @@ extern void script_init (struct t_weechat_plugin *weechat_plugin, const char *signal, const char *type_data, void *signal_data), + int (*callback_signal_script_action)(void *data, + const char *signal, + const char *type_data, + void *signal_data), void (*callback_load_file)(void *data, const char *filename)); extern int script_valid (struct t_plugin_script *scripts, struct t_plugin_script *script); @@ -87,8 +91,8 @@ extern void script_auto_load (struct t_weechat_plugin *weechat_plugin, extern struct t_plugin_script *script_search (struct t_weechat_plugin *weechat_plugin, struct t_plugin_script *scripts, const char *name); -extern char *script_search_full_name (struct t_weechat_plugin *weechat_plugin, - const char *filename); +extern char *script_search_path (struct t_weechat_plugin *weechat_plugin, + const char *filename); extern struct t_plugin_script *script_add (struct t_weechat_plugin *weechat_plugin, struct t_plugin_script **scripts, struct t_plugin_script **last_script, @@ -105,6 +109,16 @@ extern void script_remove (struct t_weechat_plugin *weechat_plugin, extern void script_completion (struct t_weechat_plugin *weechat_plugin, struct t_gui_completion *completion, struct t_plugin_script *scripts); +extern void script_action_add (char **action_list, const char *name); +extern void script_action_install (struct t_weechat_plugin *weechat_plugin, + struct t_plugin_script *scripts, + void (*script_unload)(struct t_plugin_script *script), + int (*script_load)(const char *filename), + char **list); +extern void script_action_remove (struct t_weechat_plugin *weechat_plugin, + struct t_plugin_script *scripts, + void (*script_unload)(struct t_plugin_script *script), + char **list); extern void script_display_list (struct t_weechat_plugin *weechat_plugin, struct t_plugin_script *scripts, const char *name, int full); diff --git a/src/plugins/scripts/tcl/weechat-tcl.c b/src/plugins/scripts/tcl/weechat-tcl.c index f1c9da394..47563c13b 100644 --- a/src/plugins/scripts/tcl/weechat-tcl.c +++ b/src/plugins/scripts/tcl/weechat-tcl.c @@ -49,6 +49,20 @@ struct t_plugin_script *last_tcl_script = NULL; struct t_plugin_script *tcl_current_script = NULL; const char *tcl_current_script_filename = NULL; +/* string used to execute action "install": + when signal "tcl_install_script" is received, name of string + is added to this string, to be installed later by a timer (when nothing is + running in script) +*/ +char *tcl_action_install_list = NULL; + +/* string used to execute action "remove": + when signal "tcl_remove_script" is received, name of string + is added to this string, to be removed later by a timer (when nothing is + running in script) +*/ +char *tcl_action_remove_list = NULL; + Tcl_Interp* cinterp; @@ -347,8 +361,8 @@ weechat_tcl_command_cb (void *data, struct t_gui_buffer *buffer, else if (weechat_strcasecmp (argv[1], "load") == 0) { /* load Tcl script */ - path_script = script_search_full_name (weechat_tcl_plugin, - argv_eol[2]); + path_script = script_search_path (weechat_tcl_plugin, + argv_eol[2]); weechat_tcl_load ((path_script) ? path_script : argv_eol[2]); if (path_script) free (path_script); @@ -414,12 +428,12 @@ weechat_tcl_infolist_cb (void *data, const char *infolist_name, } /* - * weechat_tcl_debug_dump_cb: dump Tcl plugin data in WeeChat log file + * weechat_tcl_signal_debug_dump_cb: dump Tcl plugin data in WeeChat log file */ int -weechat_tcl_debug_dump_cb (void *data, const char *signal, - const char *type_data, void *signal_data) +weechat_tcl_signal_debug_dump_cb (void *data, const char *signal, + const char *type_data, void *signal_data) { /* make C compiler happy */ (void) data; @@ -433,12 +447,12 @@ weechat_tcl_debug_dump_cb (void *data, const char *signal, } /* - * weechat_tcl_buffer_closed_cb: callback called when a buffer is closed + * weechat_tcl_signal_buffer_closed_cb: callback called when a buffer is closed */ int -weechat_tcl_buffer_closed_cb (void *data, const char *signal, - const char *type_data, void *signal_data) +weechat_tcl_signal_buffer_closed_cb (void *data, const char *signal, + const char *type_data, void *signal_data) { /* make C compiler happy */ (void) data; @@ -452,6 +466,74 @@ weechat_tcl_buffer_closed_cb (void *data, const char *signal, } /* + * weechat_tcl_timer_action_cb: timer for executing actions + */ + +int +weechat_tcl_timer_action_cb (void *data, int remaining_calls) +{ + /* make C compiler happy */ + (void) remaining_calls; + + if (data) + { + if (data == &tcl_action_install_list) + { + script_action_install (weechat_tcl_plugin, + tcl_scripts, + &weechat_tcl_unload, + &weechat_tcl_load, + &tcl_action_install_list); + } + else if (data == &tcl_action_remove_list) + { + script_action_remove (weechat_tcl_plugin, + tcl_scripts, + &weechat_tcl_unload, + &tcl_action_remove_list); + } + } + + return WEECHAT_RC_OK; +} + +/* + * weechat_tcl_signal_script_action_cb: callback called when a script action + * is asked (install/remove a script) + */ + +int +weechat_tcl_signal_script_action_cb (void *data, const char *signal, + const char *type_data, + void *signal_data) +{ + /* make C compiler happy */ + (void) data; + + if (strcmp (type_data, WEECHAT_HOOK_SIGNAL_STRING) == 0) + { + if (strcmp (signal, "tcl_script_install") == 0) + { + script_action_add (&tcl_action_install_list, + (const char *)signal_data); + weechat_hook_timer (1, 0, 1, + &weechat_tcl_timer_action_cb, + &tcl_action_install_list); + } + else if (strcmp (signal, "tcl_script_remove") == 0) + { + script_action_add (&tcl_action_remove_list, + (const char *)signal_data); + weechat_hook_timer (1, 0, 1, + &weechat_tcl_timer_action_cb, + &tcl_action_remove_list); + } + } + + return WEECHAT_RC_OK; +} + +/* * weechat_plugin_init: initialize Tcl plugin */ @@ -469,8 +551,9 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[]) &weechat_tcl_command_cb, &weechat_tcl_completion_cb, &weechat_tcl_infolist_cb, - &weechat_tcl_debug_dump_cb, - &weechat_tcl_buffer_closed_cb, + &weechat_tcl_signal_debug_dump_cb, + &weechat_tcl_signal_buffer_closed_cb, + &weechat_tcl_signal_script_action_cb, &weechat_tcl_load_cb); tcl_quiet = 0; |