summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common.h2
-rw-r--r--src/core/expandos.c9
-rw-r--r--src/core/modules-load.c26
-rw-r--r--src/core/modules.h1
-rw-r--r--src/fe-common/core/fe-modules.c4
-rw-r--r--src/fe-common/core/module-formats.c1
-rw-r--r--src/fe-common/core/module-formats.h1
-rw-r--r--src/irc/proxy/proxy.c5
-rw-r--r--src/perl/module.h2
-rw-r--r--src/perl/perl-core.c5
-rw-r--r--src/perl/perl-fe.c5
11 files changed, 59 insertions, 2 deletions
diff --git a/src/common.h b/src/common.h
index 0cf951b3..966e28d0 100644
--- a/src/common.h
+++ b/src/common.h
@@ -6,6 +6,8 @@
#define IRSSI_GLOBAL_CONFIG "irssi.conf" /* config file name in /etc/ */
#define IRSSI_HOME_CONFIG "config" /* config file name in ~/.irssi/ */
+#define IRSSI_ABI_VERSION 1
+
#define DEFAULT_SERVER_ADD_PORT 6667
#ifdef HAVE_CONFIG_H
diff --git a/src/core/expandos.c b/src/core/expandos.c
index 1fc517af..67aea837 100644
--- a/src/core/expandos.c
+++ b/src/core/expandos.c
@@ -414,6 +414,13 @@ static char *expando_releasetime(SERVER_REC *server, void *item, int *free_ret)
return g_strdup_printf("%04d", IRSSI_VERSION_TIME);
}
+/* client abi */
+static char *expando_abiversion(SERVER_REC *server, void *item, int *free_ret)
+{
+ *free_ret = TRUE;
+ return g_strdup_printf("%d", IRSSI_ABI_VERSION);
+}
+
/* current working directory */
static char *expando_workdir(SERVER_REC *server, void *item, int *free_ret)
{
@@ -658,6 +665,8 @@ void expandos_init(void)
"", EXPANDO_NEVER, NULL);
expando_create("versiontime", expando_releasetime,
"", EXPANDO_NEVER, NULL);
+ expando_create("abiversion", expando_abiversion,
+ "", EXPANDO_NEVER, NULL);
expando_create("W", expando_workdir, NULL);
expando_create("Y", expando_realname,
"window changed", EXPANDO_ARG_NONE,
diff --git a/src/core/modules-load.c b/src/core/modules-load.c
index 6086d9ae..9baac1d7 100644
--- a/src/core/modules-load.c
+++ b/src/core/modules-load.c
@@ -160,11 +160,14 @@ static int module_load_name(const char *path, const char *rootmodule,
{
void (*module_init) (void);
void (*module_deinit) (void);
+ void (*module_version) (int *);
GModule *gmodule;
MODULE_REC *module;
MODULE_FILE_REC *rec;
+ gpointer value_version = NULL;
gpointer value1, value2 = NULL;
- char *initfunc, *deinitfunc;
+ char *versionfunc, *initfunc, *deinitfunc;
+ int module_abi_version = 0;
int found;
gmodule = module_open(path, &found);
@@ -176,6 +179,27 @@ static int module_load_name(const char *path, const char *rootmodule,
return found ? 0 : -1;
}
+ /* get the module's irssi abi version and bail out on mismatch */
+ versionfunc = module_get_func(rootmodule, submodule, "abicheck");
+ if (!g_module_symbol(gmodule, versionfunc, &value_version)) {
+ g_free(versionfunc);
+ module_error(MODULE_ERROR_VERSION_MISMATCH, "0",
+ rootmodule, submodule);
+ g_module_close(gmodule);
+ return 0;
+ }
+ g_free(versionfunc);
+ module_version = value_version;
+ module_version(&module_abi_version);
+ if (module_abi_version != IRSSI_ABI_VERSION) {
+ char *module_abi_versionstr = g_strdup_printf("%d", module_abi_version);
+ module_error(MODULE_ERROR_VERSION_MISMATCH, module_abi_versionstr,
+ rootmodule, submodule);
+ g_free(module_abi_versionstr);
+ g_module_close(gmodule);
+ return 0;
+ }
+
/* get the module's init() and deinit() functions */
initfunc = module_get_func(rootmodule, submodule, "init");
deinitfunc = module_get_func(rootmodule, submodule, "deinit");
diff --git a/src/core/modules.h b/src/core/modules.h
index 75a77c77..b2fa2fa4 100644
--- a/src/core/modules.h
+++ b/src/core/modules.h
@@ -27,6 +27,7 @@
enum {
MODULE_ERROR_ALREADY_LOADED,
MODULE_ERROR_LOAD,
+ MODULE_ERROR_VERSION_MISMATCH,
MODULE_ERROR_INVALID
};
diff --git a/src/fe-common/core/fe-modules.c b/src/fe-common/core/fe-modules.c
index df97ceb1..27b6b4c1 100644
--- a/src/fe-common/core/fe-modules.c
+++ b/src/fe-common/core/fe-modules.c
@@ -43,6 +43,10 @@ static void sig_module_error(void *number, const char *data,
printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
TXT_MODULE_LOAD_ERROR, rootmodule, submodule, data);
break;
+ case MODULE_ERROR_VERSION_MISMATCH:
+ printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
+ TXT_MODULE_VERSION_MISMATCH, rootmodule, submodule, data);
+ break;
case MODULE_ERROR_INVALID:
printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
TXT_MODULE_INVALID, rootmodule, submodule);
diff --git a/src/fe-common/core/module-formats.c b/src/fe-common/core/module-formats.c
index 4ae26950..e6d32b6d 100644
--- a/src/fe-common/core/module-formats.c
+++ b/src/fe-common/core/module-formats.c
@@ -196,6 +196,7 @@ FORMAT_REC fecommon_core_formats[] = {
{ "module_already_loaded", "Module {hilight $0/$1} already loaded", 2, { 0, 0 } },
{ "module_not_loaded", "Module {hilight $0/$1} is not loaded", 2, { 0, 0 } },
{ "module_load_error", "Error loading module {hilight $0/$1}: $2", 3, { 0, 0, 0 } },
+ { "module_version_mismatch", "{hilight $0/$1} is ABI version $2 but Irssi is version $abiversion, cannot load", 3, { 0, 0, 0 } },
{ "module_invalid", "{hilight $0/$1} isn't Irssi module", 2, { 0, 0 } },
{ "module_loaded", "Loaded module {hilight $0/$1}", 2, { 0, 0 } },
{ "module_unloaded", "Unloaded module {hilight $0/$1}", 2, { 0, 0 } },
diff --git a/src/fe-common/core/module-formats.h b/src/fe-common/core/module-formats.h
index 18bf91f5..3f06bb97 100644
--- a/src/fe-common/core/module-formats.h
+++ b/src/fe-common/core/module-formats.h
@@ -166,6 +166,7 @@ enum {
TXT_MODULE_ALREADY_LOADED,
TXT_MODULE_NOT_LOADED,
TXT_MODULE_LOAD_ERROR,
+ TXT_MODULE_VERSION_MISMATCH,
TXT_MODULE_INVALID,
TXT_MODULE_LOADED,
TXT_MODULE_UNLOADED,
diff --git a/src/irc/proxy/proxy.c b/src/irc/proxy/proxy.c
index ce79e2b7..50a41b21 100644
--- a/src/irc/proxy/proxy.c
+++ b/src/irc/proxy/proxy.c
@@ -108,3 +108,8 @@ void irc_proxy_deinit(void)
{
proxy_listen_deinit();
}
+
+void irc_proxy_abicheck(int *version)
+{
+ *version = IRSSI_ABI_VERSION;
+}
diff --git a/src/perl/module.h b/src/perl/module.h
index 2fd15137..3cbdf3d5 100644
--- a/src/perl/module.h
+++ b/src/perl/module.h
@@ -17,4 +17,4 @@ extern PerlInterpreter *my_perl; /* must be called my_perl or some perl implemen
/* Change this every time when some API changes between irssi's perl module
(or irssi itself) and irssi's perl libraries. */
-#define IRSSI_PERL_API_VERSION 20011214
+#define IRSSI_PERL_API_VERSION (20011214 + IRSSI_ABI_VERSION)
diff --git a/src/perl/perl-core.c b/src/perl/perl-core.c
index 1a864ef7..cb690906 100644
--- a/src/perl/perl-core.c
+++ b/src/perl/perl-core.c
@@ -479,3 +479,8 @@ void perl_core_deinit(void)
signal_remove("script error", (SIGNAL_FUNC) sig_script_error);
PERL_SYS_TERM();
}
+
+void perl_core_abicheck(int *version)
+{
+ *version = IRSSI_ABI_VERSION;
+}
diff --git a/src/perl/perl-fe.c b/src/perl/perl-fe.c
index 2abc75c0..04305b63 100644
--- a/src/perl/perl-fe.c
+++ b/src/perl/perl-fe.c
@@ -278,3 +278,8 @@ void fe_perl_deinit(void)
perl_core_print_script_error(TRUE);
}
+
+void fe_perl_abicheck(int *version)
+{
+ *version = IRSSI_ABI_VERSION;
+}