summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/plugins/scripts/lua/weechat-lua.c103
-rw-r--r--src/plugins/scripts/perl/weechat-perl.c103
-rw-r--r--src/plugins/scripts/python/weechat-python.c112
-rw-r--r--src/plugins/scripts/ruby/weechat-ruby.c103
-rw-r--r--src/plugins/scripts/script.c282
-rw-r--r--src/plugins/scripts/script.h18
-rw-r--r--src/plugins/scripts/tcl/weechat-tcl.c103
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;