summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSebastien Helleu <flashcode@flashtux.org>2003-11-16 19:40:36 +0000
committerSebastien Helleu <flashcode@flashtux.org>2003-11-16 19:40:36 +0000
commitd4ec2e46aafd0064b62f4bbc8b1bc23565881c0c (patch)
tree5b827b62e780c342111da241e04a8da6d9de07b7 /src
parentfd9512bbbcc2857cd1a3a309d9883d199d60122b (diff)
downloadweechat-d4ec2e46aafd0064b62f4bbc8b1bc23565881c0c.zip
Perl plugin support
Diffstat (limited to 'src')
-rw-r--r--src/common/command.c77
-rw-r--r--src/common/command.h3
-rw-r--r--src/common/weechat.c15
-rw-r--r--src/common/weechat.h2
-rw-r--r--src/common/weeconfig.c4
-rw-r--r--src/gui/curses/Makefile.am3
-rw-r--r--src/gui/curses/gui-display.c2
-rw-r--r--src/gui/gtk/Makefile.am3
-rw-r--r--src/gui/gtk/gui-display.c2
-rw-r--r--src/gui/gui-common.c4
-rw-r--r--src/irc/irc-server.c18
-rw-r--r--src/plugins/Makefile.am11
-rw-r--r--src/plugins/perl/Makefile.am3
-rw-r--r--src/plugins/perl/wee-perl.c302
-rw-r--r--src/plugins/perl/wee-perl.h44
-rw-r--r--src/plugins/plugins.c105
-rw-r--r--src/plugins/plugins.h36
17 files changed, 598 insertions, 36 deletions
diff --git a/src/common/command.c b/src/common/command.c
index 1b0f13464..a427cc7d7 100644
--- a/src/common/command.c
+++ b/src/common/command.c
@@ -34,6 +34,7 @@
#include "weeconfig.h"
#include "../irc/irc.h"
#include "../gui/gui.h"
+#include "../plugins/plugins.h"
/* WeeChat internal commands */
@@ -59,6 +60,12 @@ t_weechat_command weechat_commands[] =
{ "help", N_("display help about commands"),
N_("[command]"), N_("command: name of a WeeChat or IRC command"),
0, 1, weechat_cmd_help, NULL },
+ { "perl", N_("list/load/unload Perl scripts"),
+ N_("[load filename] | [unload scriptname]"),
+ N_("filename: Perl script (file) to load\n"
+ "scriptname: name of script to unload\n"
+ "Without argument, /perl command lists all loaded Perl scripts."),
+ 0, 2, weechat_cmd_perl, NULL },
{ "server", N_("list, add or remove servers"),
N_("[list] | "
"[servername hostname port [-auto | -noauto] [-pwd password] [-nicks nick1 "
@@ -531,7 +538,7 @@ exec_weechat_command (t_irc_server *server, char *string)
gui_printf (NULL,
_("%s wrong argument count for %s command \"%s\" "
"(expected: %d arg%s)\n"),
- WEECHAT_ERROR, PACKAGE_NAME,
+ WEECHAT_ERROR, PACKAGE_NAME,
command + 1,
weechat_commands[i].max_arg,
(weechat_commands[i].max_arg >
@@ -974,6 +981,64 @@ weechat_cmd_help (int argc, char **argv)
}
/*
+ * weechat_cmd_perl: list/load/unload Perl scripts
+ */
+
+int
+weechat_cmd_perl (int argc, char **argv)
+{
+ #ifdef PLUGIN_PERL
+ switch (argc)
+ {
+ case 0:
+ /* list all Perl scripts */
+ /* TODO: get list and display it */
+ break;
+ case 2:
+ if (strcmp (argv[0], "load") == 0)
+ {
+ /* load Perl script */
+ plugins_load (PLUGIN_PERL, argv[1]);
+ }
+ else
+ {
+ if (strcmp (argv[0], "unload") == 0)
+ {
+ /* unload Perl script */
+ }
+ else
+ {
+ gui_printf (NULL,
+ _("%s unknown option for \"%s\" command\n"),
+ WEECHAT_ERROR, "perl");
+ }
+ }
+ break;
+ default:
+ gui_printf (NULL,
+ _("%s wrong argument count for \"%s\" command\n"),
+ WEECHAT_ERROR, "perl");
+ }
+ #else
+ gui_printf (NULL,
+ _("WeeChat was build without Perl support.\n"
+ "Please rebuild WeeChat with "
+ "\"--enable-perl\" option for ./configure script\n");
+ #endif
+ return 0;
+}
+
+/*
+ * weechat_cmd_save: save options to disk
+ */
+
+int
+weechat_cmd_save (int argc, char **argv)
+{
+ return (config_write ((argc == 1) ? argv[0] : NULL));
+}
+
+/*
* weechat_cmd_server: list, add or remove server(s)
*/
@@ -1279,16 +1344,6 @@ weechat_cmd_server (int argc, char **argv)
}
/*
- * weechat_cmd_save: set options
- */
-
-int
-weechat_cmd_save (int argc, char **argv)
-{
- return (config_write ((argc == 1) ? argv[0] : NULL));
-}
-
-/*
* weechat_cmd_set: set options
*/
diff --git a/src/common/command.h b/src/common/command.h
index 2be48eded..59183f70d 100644
--- a/src/common/command.h
+++ b/src/common/command.h
@@ -72,8 +72,9 @@ extern int weechat_cmd_clear (int, char **);
extern int weechat_cmd_connect (int, char **);
extern int weechat_cmd_disconnect (int, char **);
extern int weechat_cmd_help (int, char **);
-extern int weechat_cmd_server (int, char **);
+extern int weechat_cmd_perl (int, char **);
extern int weechat_cmd_save (int, char **);
+extern int weechat_cmd_server (int, char **);
extern int weechat_cmd_set (int, char **);
extern int weechat_cmd_unalias (char *);
diff --git a/src/common/weechat.c b/src/common/weechat.c
index 1fb831987..2efadda8a 100644
--- a/src/common/weechat.c
+++ b/src/common/weechat.c
@@ -56,6 +56,7 @@
#include "command.h"
#include "../irc/irc.h"
#include "../gui/gui.h"
+#include "../plugins/plugins.h"
/* char *display_name; */
@@ -65,11 +66,11 @@ FILE *log_file; /* WeeChat log file (~/.weechat/weechat.log */
/*
- * log_printf: displays a message in WeeChat log (~/.weechat/weechat.log)
+ * wee_log_printf: displays a message in WeeChat log (~/.weechat/weechat.log)
*/
void
-log_printf (char *message, ...)
+wee_log_printf (char *message, ...)
{
static char buffer[4096];
va_list argptr;
@@ -271,6 +272,9 @@ main (int argc, char *argv[])
/* init gui */
gui_init ();
+ /* init plugin interface(s) */
+ plugins_init ();
+
/* Welcome message - yeah! */
if (cfg_look_startup_logo)
{
@@ -315,7 +319,14 @@ main (int argc, char *argv[])
irc_login (ptr_server);
}
}
+
+ /* WeeChat main loop */
gui_main_loop ();
+
+ /* end plugin interface(s) */
+ plugins_end ();
+
+ /* disconnect from all servers */
server_disconnect_all ();
/* save config file */
diff --git a/src/common/weechat.h b/src/common/weechat.h
index 75fd56d88..c7a9e63da 100644
--- a/src/common/weechat.h
+++ b/src/common/weechat.h
@@ -97,7 +97,7 @@ int quit_weechat;
extern int quit_weechat;
-extern void log_printf (char *, ...);
+extern void wee_log_printf (char *, ...);
extern void wee_shutdown ();
#endif /* weechat.h */
diff --git a/src/common/weeconfig.c b/src/common/weeconfig.c
index 3a58da127..062735d50 100644
--- a/src/common/weeconfig.c
+++ b/src/common/weeconfig.c
@@ -948,7 +948,7 @@ config_create_default ()
}
printf (_("%s: creating default config file...\n"), PACKAGE_NAME);
- log_printf (_("creating default config file\n"));
+ wee_log_printf (_("creating default config file\n"));
current_time = time (NULL);
sprintf (line, _("#\n# %s configuration file, created by "
@@ -1081,7 +1081,7 @@ config_write (char *config_name)
return -1;
}
- log_printf (_("saving config to disk\n"));
+ wee_log_printf (_("saving config to disk\n"));
current_time = time (NULL);
sprintf (line, _("#\n# %s configuration file, created by "
diff --git a/src/gui/curses/Makefile.am b/src/gui/curses/Makefile.am
index e8edd5005..e49e7e9bf 100644
--- a/src/gui/curses/Makefile.am
+++ b/src/gui/curses/Makefile.am
@@ -19,7 +19,8 @@ bin_PROGRAMS = weechat-curses
weechat_curses_LDADD = ../../common/lib_weechat_main.a \
../../irc/lib_weechat_irc.a \
- $(CURSES_LIBS) $(PLUGIN_LIBS)
+ $(CURSES_LIBS) \
+ ../../plugins/lib_weechat_plugins.a $(PLUGINS_LIBS)
weechat_curses_SOURCES = ../gui.h \
../gui-common.c \
diff --git a/src/gui/curses/gui-display.c b/src/gui/curses/gui-display.c
index 1a64b3a0b..8bda74609 100644
--- a/src/gui/curses/gui-display.c
+++ b/src/gui/curses/gui-display.c
@@ -1519,7 +1519,7 @@ gui_printf_color_type (t_gui_window *window, int type, int color, char *message,
if (window == NULL)
{
- log_printf ("gui_printf without window! this is a bug, please send to developers - thanks\n");
+ wee_log_printf ("gui_printf without window! this is a bug, please send to developers - thanks\n");
return;
}
}
diff --git a/src/gui/gtk/Makefile.am b/src/gui/gtk/Makefile.am
index 6a84f264a..36bae7ed3 100644
--- a/src/gui/gtk/Makefile.am
+++ b/src/gui/gtk/Makefile.am
@@ -21,7 +21,8 @@ INCLUDES = $(GTK_CFLAGS)
weechat_gtk_LDADD = ../../common/lib_weechat_main.a \
../../irc/lib_weechat_irc.a \
- $(GTK_LIBS) $(PLUGIN_LIBS)
+ $(GTK_LIBS) \
+ ../../plugins/lib_weechat_plugins.a $(PLUGINS_LIBS)
weechat_gtk_SOURCES = ../gui.h \
../gui-common.c \
diff --git a/src/gui/gtk/gui-display.c b/src/gui/gtk/gui-display.c
index 77e983482..29c3a4690 100644
--- a/src/gui/gtk/gui-display.c
+++ b/src/gui/gtk/gui-display.c
@@ -710,7 +710,7 @@ gui_printf_color_type (t_gui_window *window, int type, int color, char *message,
if (window == NULL)
{
- log_printf ("gui_printf without window! this is a bug, please send to developers - thanks\n");
+ wee_log_printf ("gui_printf without window! this is a bug, please send to developers - thanks\n");
return;
}
}
diff --git a/src/gui/gui-common.c b/src/gui/gui-common.c
index 453e75835..723c19fe5 100644
--- a/src/gui/gui-common.c
+++ b/src/gui/gui-common.c
@@ -264,7 +264,7 @@ gui_new_line (t_gui_window *window)
}
else
{
- log_printf (_("%s not enough memory for new line!\n"));
+ wee_log_printf (_("%s not enough memory for new line!\n"));
return NULL;
}
return new_line;
@@ -291,7 +291,7 @@ gui_new_message (t_gui_window *window)
}
else
{
- log_printf (_("not enough memory!\n"));
+ wee_log_printf (_("not enough memory!\n"));
return NULL;
}
return new_message;
diff --git a/src/irc/irc-server.c b/src/irc/irc-server.c
index fdbc3d3a5..25928eeb5 100644
--- a/src/irc/irc-server.c
+++ b/src/irc/irc-server.c
@@ -205,13 +205,13 @@ server_new (char *name, int autoconnect, char *address, int port,
return NULL;
#ifdef DEBUG
- log_printf ("creating new server (name:%s, address:%s, port:%d, pwd:%s, "
- "nick1:%s, nick2:%s, nick3:%s, username:%s, realname:%s, "
- "command:%s, autojoin:%s)\n",
- name, address, port, (password) ? password : "",
- (nick1) ? nick1 : "", (nick2) ? nick2 : "", (nick3) ? nick3 : "",
- (username) ? username : "", (realname) ? realname : "",
- (command) ? command : "", (autojoin) ? autojoin : "");
+ wee_log_printf ("creating new server (name:%s, address:%s, port:%d, pwd:%s, "
+ "nick1:%s, nick2:%s, nick3:%s, username:%s, realname:%s, "
+ "command:%s, autojoin:%s)\n",
+ name, address, port, (password) ? password : "",
+ (nick1) ? nick1 : "", (nick2) ? nick2 : "", (nick3) ? nick3 : "",
+ (username) ? username : "", (realname) ? realname : "",
+ (command) ? command : "", (autojoin) ? autojoin : "");
#endif
if ((new_server = server_alloc ()))
@@ -480,8 +480,8 @@ server_connect (t_irc_server *server)
gui_printf (server->window,
_("%s: connecting to %s:%d...\n"),
PACKAGE_NAME, server->address, server->port);
- log_printf (_("connecting to server %s:%d...\n"),
- server->address, server->port);
+ wee_log_printf (_("connecting to server %s:%d...\n"),
+ server->address, server->port);
server->is_connected = 0;
/* create pipe */
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 7dda77abf..1d9104d4a 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -16,16 +16,21 @@
#
if PLUGIN_PERL
-perl_dir=perl
+perl_dir = perl
endif
# if PLUGIN_PYTHON
-# python_dir=python
+# python_dir = python
# endif
# if PLUGIN_RUBY
-# ruby_dir=ruby
+# ruby_dir = ruby
# endif
# SUBDIRS = $(perl_dir) $(python_dir) $(ruby_dir)
SUBDIRS = $(perl_dir)
+
+noinst_LIBRARIES = lib_weechat_plugins.a
+
+lib_weechat_plugins_a_SOURCES = plugins.h \
+ plugins.c
diff --git a/src/plugins/perl/Makefile.am b/src/plugins/perl/Makefile.am
index 213912f3a..e94d51fb1 100644
--- a/src/plugins/perl/Makefile.am
+++ b/src/plugins/perl/Makefile.am
@@ -19,4 +19,5 @@ INCLUDES = $(PERL_CFLAGS)
noinst_LIBRARIES = lib_weechat_perl.a
-lib_weechat_perl_a_SOURCES = perl.c
+lib_weechat_perl_a_SOURCES = wee-perl.h \
+ wee-perl.c
diff --git a/src/plugins/perl/wee-perl.c b/src/plugins/perl/wee-perl.c
new file mode 100644
index 000000000..709f575ad
--- /dev/null
+++ b/src/plugins/perl/wee-perl.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org>
+ * Bounga <bounga@altern.org>
+ * Xahlexx <xahlexx@tuxisland.org>
+ * See README for License detail.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* wee-perl.c: Perl plugin support for WeeChat */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <EXTERN.h>
+#include <perl.h>
+#include <XSUB.h>
+#include "../../common/weechat.h"
+#include "wee-perl.h"
+#include "../../gui/gui.h"
+
+
+static PerlInterpreter *my_perl = NULL;
+static t_perl_script *perl_scripts = NULL;
+
+extern void boot_DynaLoader (pTHX_ CV* cv);
+
+
+/*
+ * IRC::register: startup function for all WeeChat Perl scripts
+ */
+
+static XS (XS_IRC_register)
+{
+ char *name, *version, *shutdown_func, *description;
+ int integer;
+ t_perl_script *new_perl_script;
+ dXSARGS;
+
+ name = SvPV (ST (0), integer);
+ version = SvPV (ST (1), integer);
+ shutdown_func = SvPV (ST (2), integer);
+ description = SvPV (ST (3), integer);
+
+ new_perl_script = (t_perl_script *)malloc (sizeof (t_perl_script));
+ if (new_perl_script)
+ {
+ new_perl_script->name = strdup (name);
+ new_perl_script->version = strdup (version);
+ new_perl_script->shutdown_func = strdup (shutdown_func);
+ new_perl_script->description = strdup (description);
+ new_perl_script->next_script = perl_scripts;
+ perl_scripts = new_perl_script;
+ wee_log_printf (_("registered Perl script: \"%s\"\n"), name);
+ }
+ else
+ gui_printf (NULL,
+ _("%s unable to load Perl script \"%s\"\n"),
+ WEECHAT_ERROR, name);
+ XST_mPV (0, VERSION);
+ XSRETURN (1);
+}
+
+/*
+ * IRC::print: print message to current window
+ */
+
+static XS (XS_IRC_print)
+{
+ int i, integer;
+ char *message;
+ dXSARGS;
+
+ for (i = 0; i < items; i++)
+ {
+ message = SvPV (ST (i), integer);
+ gui_printf (NULL, "%s\n", message);
+ }
+
+ XSRETURN_EMPTY;
+}
+
+/*
+ * xs_init: initialize subroutines
+ */
+
+void
+xs_init (pTHX)
+{
+ newXS ("DynaLoader::boot_DynaLoader", boot_DynaLoader, __FILE__);
+ newXS ("IRC::register", XS_IRC_register, "IRC");
+ newXS ("IRC::print", XS_IRC_print, "IRC");
+}
+
+/*
+ * wee_perl_init: initialize Perl interface for WeeChat
+ */
+
+void
+wee_perl_init ()
+{
+ char *perl_args[] = { "", "-e", "0" };
+ /* This Perl code is extracted/modified from X-Chat IRC client */
+ /* X-Chat is (c) 1998-2002 Peter Zelezny */
+ char *weechat_perl_func =
+ {
+ "sub wee_perl_load_file"
+ "{"
+ " my $filename = shift;"
+ " local $/ = undef;"
+ " open FILE, $filename or return \"__WEECHAT_ERROR__\";"
+ " $_ = <FILE>;"
+ " close FILE;"
+ " return $_;"
+ "}"
+ "sub wee_perl_load_eval_file"
+ "{"
+ " my $filename = shift;"
+ " my $content = wee_perl_load_file ($filename);"
+ " if ($content eq \"__WEECHAT_ERROR__\")"
+ " {"
+ " IRC::print \"" WEECHAT_ERROR " Perl script '$filename' not found.\\n\";"
+ " return 1;"
+ " }"
+ " eval $content;"
+ " if ($@)"
+ " {"
+ " IRC::print \"" WEECHAT_ERROR " unable to load Perl script '$filename':\\n\";"
+ " IRC::print \"$@\\n\";"
+ " return 2;"
+ " }"
+ " return 0;"
+ "}"
+ "$SIG{__WARN__} = sub { IRC::print \"$_[0]\n\"; };"
+ };
+
+ my_perl = perl_alloc ();
+ perl_construct (my_perl);
+ perl_parse (my_perl, xs_init, 3, perl_args, NULL);
+ eval_pv (weechat_perl_func, TRUE);
+}
+
+/*
+ * wee_perl_search: search a (loaded) Perl script by name
+ */
+
+t_perl_script *
+wee_perl_search (char *name)
+{
+ t_perl_script *ptr_perl_script;
+
+ for (ptr_perl_script = perl_scripts; ptr_perl_script;
+ ptr_perl_script = ptr_perl_script->next_script)
+ {
+ if (strcmp (ptr_perl_script->name, name) == 0)
+ return ptr_perl_script;
+ }
+
+ /* script not found */
+ return NULL;
+}
+
+/*
+ * wee_perl_exec: execute a Perl script
+ */
+
+int
+wee_perl_exec (char *function, char *arguments)
+{
+ char *argv[2];
+ int count, return_code;
+ SV *sv;
+
+ /* call Perl function */
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(sp);
+ argv[0] = arguments;
+ argv[1] = NULL;
+ count = perl_call_argv (function, G_EVAL | G_SCALAR, argv);
+ SPAGAIN;
+
+ /* check if ok */
+ sv = GvSV (gv_fetchpv ("@", TRUE, SVt_PV));
+ return_code = 1;
+ if (SvTRUE (sv))
+ {
+ gui_printf (NULL,
+ _("Perl error: %s\n"),
+ SvPV (sv, count));
+ POPs;
+ }
+ else
+ {
+ if (count != 1)
+ {
+ gui_printf (NULL,
+ _("Perl error: too much values from \"%s\" (%d). Expected: 1.\n"),
+ function, count);
+ }
+ else
+ return_code = POPi;
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+
+ return return_code;
+}
+
+/*
+ * wee_perl_load: load a Perl script
+ */
+
+int
+wee_perl_load (char *filename)
+{
+ /* execute Perl script */
+ wee_log_printf (_("loading Perl script \"%s\"\n"), filename);
+ return wee_perl_exec ("wee_perl_load_eval_file", filename);
+}
+
+/*
+ * wee_perl_unload: unload a Perl script
+ */
+
+void
+wee_perl_unload (t_perl_script *ptr_perl_script)
+{
+ if (ptr_perl_script)
+ {
+ wee_log_printf (_("unloading Perl script \"%s\"\n"),
+ ptr_perl_script->name);
+
+ /* call shutdown callback function */
+ if (ptr_perl_script->shutdown_func[0])
+ wee_perl_exec (ptr_perl_script->shutdown_func, "");
+
+ /* free data */
+ if (ptr_perl_script->name)
+ free (ptr_perl_script->name);
+ if (ptr_perl_script->version)
+ free (ptr_perl_script->version);
+ if (ptr_perl_script->shutdown_func)
+ free (ptr_perl_script->shutdown_func);
+ if (ptr_perl_script->description)
+ free (ptr_perl_script->description);
+ }
+}
+
+/*
+ * wee_perl_unload_all: unload all Perl scripts
+ */
+
+void
+wee_perl_unload_all ()
+{
+ t_perl_script *ptr_perl_script;
+
+ while (perl_scripts)
+ {
+ wee_perl_unload (perl_scripts);
+ ptr_perl_script = perl_scripts->next_script;
+ free (perl_scripts);
+ perl_scripts = ptr_perl_script;
+ }
+}
+
+/*
+ * wee_perl_end: shutdown Perl interface
+ */
+
+void
+wee_perl_end ()
+{
+ /* unload all scripts */
+ wee_perl_unload_all ();
+
+ /* free Perl interpreter */
+ if (my_perl)
+ {
+ perl_destruct (my_perl);
+ perl_free (my_perl);
+ }
+}
diff --git a/src/plugins/perl/wee-perl.h b/src/plugins/perl/wee-perl.h
new file mode 100644
index 000000000..31a40481b
--- /dev/null
+++ b/src/plugins/perl/wee-perl.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org>
+ * Bounga <bounga@altern.org>
+ * Xahlexx <xahlexx@tuxisland.org>
+ * See README for License detail.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef __WEECHAT_PERL_H
+#define __WEECHAT_PERL_H 1
+
+typedef struct t_perl_script t_perl_script;
+
+struct t_perl_script
+{
+ char *name; /* name of script */
+ char *version; /* version of script */
+ char *shutdown_func; /* function when script ends */
+ char *description; /* description of script */
+ t_perl_script *next_script; /* link to next Perl script */
+};
+
+extern void wee_perl_init ();
+extern t_perl_script *wee_perl_search (char *);
+extern int wee_perl_load (char *);
+extern void wee_perl_unload (t_perl_script *);
+extern void wee_perl_unload_all ();
+extern void wee_perl_end ();
+
+#endif /* wee-perl.h */
diff --git a/src/plugins/plugins.c b/src/plugins/plugins.c
new file mode 100644
index 000000000..50b8e60ef
--- /dev/null
+++ b/src/plugins/plugins.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org>
+ * Bounga <bounga@altern.org>
+ * Xahlexx <xahlexx@tuxisland.org>
+ * See README for License detail.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* plugins.c: manages WeeChat plugins (Perl and/or Python and/or Ruby) */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include "plugins.h"
+
+#ifdef PLUGIN_PERL
+#include "perl/wee-perl.h"
+#endif
+
+
+/*
+ * plugins_init: initialize all plugins
+ */
+
+void
+plugins_init ()
+{
+ #ifdef PLUGIN_PERL
+ wee_perl_init();
+ #endif
+}
+
+/*
+ * plugins_load: load a plugin
+ */
+
+void
+plugins_load (int plugin_type, char *filename)
+{
+ switch (plugin_type)
+ {
+ case PLUGIN_PERL:
+ #ifdef PLUGIN_PERL
+ wee_perl_load (filename);
+ #endif
+ break;
+ case PLUGIN_PYTHON:
+ /* TODO: load Python script */
+ break;
+ case PLUGIN_RUBY:
+ /* TODO: load Ruby script */
+ break;
+ }
+}
+
+/*
+ * plugins_unload: unload a plugin
+ */
+
+void
+plugins_unload (int plugin_type, char *scriptname)
+{
+ switch (plugin_type)
+ {
+ case PLUGIN_PERL:
+ #ifdef PLUGIN_PERL
+ wee_perl_unload (wee_perl_search (scriptname));
+ #endif
+ break;
+ case PLUGIN_PYTHON:
+ /* TODO: load Python script */
+ break;
+ case PLUGIN_RUBY:
+ /* TODO: load Ruby script */
+ break;
+ }
+}
+
+/*
+ * plugins_end: shutdown plugin interface
+ */
+
+void
+plugins_end ()
+{
+ #ifdef PLUGIN_PERL
+ wee_perl_end();
+ #endif
+}
diff --git a/src/plugins/plugins.h b/src/plugins/plugins.h
new file mode 100644
index 000000000..fcd6309f7
--- /dev/null
+++ b/src/plugins/plugins.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org>
+ * Bounga <bounga@altern.org>
+ * Xahlexx <xahlexx@tuxisland.org>
+ * See README for License detail.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef __WEECHAT_PLUGIN_H
+#define __WEECHAT_PLUGIN_H 1
+
+#define PLUGIN_UNKNOWN 0
+#define PLUGIN_PERL 1
+#define PLUGIN_PYTHON 2
+#define PLUGIN_RUBY 3
+
+extern void plugins_init ();
+extern void plugins_load (int, char *);
+extern void plugins_unload (int, char *);
+extern void plugins_end ();
+
+#endif /* plugins.h */