mirror of
https://github.com/weechat/weechat.git
synced 2026-06-25 04:16:38 +02:00
Improved plugin API, most functions rewritten from scratch
This commit is contained in:
@@ -14,8 +14,8 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
SET(LIB_PLUGINS_SRC weechat-plugin.h plugins.h plugins.c plugins-interface.c
|
||||
plugins-config.h plugins-config.c)
|
||||
SET(LIB_PLUGINS_SRC weechat-plugin.h plugin.c plugin.h plugin-api.c
|
||||
plugin-api.h plugin-config.h plugin-config.c plugin-list.c plugin-list.h)
|
||||
|
||||
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR})
|
||||
ADD_LIBRARY(weechat_plugins STATIC ${LIB_PLUGINS_SRC})
|
||||
@@ -24,6 +24,14 @@ INCLUDE(CheckIncludeFiles)
|
||||
INCLUDE(CheckFunctionExists)
|
||||
INCLUDE(CheckLibraryExists)
|
||||
|
||||
IF(NOT DISABLE_IRC)
|
||||
ADD_SUBDIRECTORY( irc )
|
||||
ENDIF(NOT DISABLE_IRC)
|
||||
|
||||
IF(NOT DISABLE_PERL AND NOT DISABLE_PYTHON AND NOT DISABLE_RUBY AND NOT DISABLE_LUA)
|
||||
ADD_SUBDIRECTORY( scripts )
|
||||
ENDIF(NOT DISABLE_PERL AND NOT DISABLE_PYTHON AND NOT DISABLE_RUBY AND NOT DISABLE_LUA)
|
||||
|
||||
IF(NOT DISABLE_ASPELL)
|
||||
# Check for aspell libraries
|
||||
FIND_PACKAGE(Aspell)
|
||||
@@ -32,11 +40,17 @@ IF(NOT DISABLE_ASPELL)
|
||||
ENDIF(ASPELL_FOUND)
|
||||
ENDIF(NOT DISABLE_ASPELL)
|
||||
|
||||
IF (NOT DISABLE_CHARSET)
|
||||
IF(NOT DISABLE_CHARSET)
|
||||
# Check for iconv support.
|
||||
IF(ICONV_FOUND)
|
||||
ADD_SUBDIRECTORY( charset )
|
||||
ENDIF(ICONV_FOUND)
|
||||
ENDIF(NOT DISABLE_CHARSET)
|
||||
|
||||
ADD_SUBDIRECTORY( scripts )
|
||||
IF(NOT DISABLE_FIFO)
|
||||
ADD_SUBDIRECTORY( fifo )
|
||||
ENDIF(NOT DISABLE_FIFO)
|
||||
|
||||
IF(NOT DISABLE_TRIGGER)
|
||||
ADD_SUBDIRECTORY( trigger )
|
||||
ENDIF(NOT DISABLE_TRIGGER)
|
||||
|
||||
+23
-8
@@ -16,6 +16,22 @@
|
||||
|
||||
INCLUDES = -DLOCALEDIR=\"$(datadir)/locale\"
|
||||
|
||||
noinst_LIBRARIES = lib_weechat_plugins.a
|
||||
|
||||
lib_weechat_plugins_a_SOURCES = weechat-plugin.h \
|
||||
plugin.c \
|
||||
plugin.h \
|
||||
plugin-api.c \
|
||||
plugin-api.h \
|
||||
plugin-config.c \
|
||||
plugin-config.h \
|
||||
plugin-list.c \
|
||||
plugin-list.h
|
||||
|
||||
if PLUGIN_IRC
|
||||
irc_dir = irc
|
||||
endif
|
||||
|
||||
if PLUGIN_PERL
|
||||
script_dir = scripts
|
||||
endif
|
||||
@@ -40,13 +56,12 @@ if PLUGIN_CHARSET
|
||||
charset_dir = charset
|
||||
endif
|
||||
|
||||
SUBDIRS = $(script_dir) $(aspell_dir) $(charset_dir)
|
||||
if PLUGIN_FIFO
|
||||
fifo_dir = fifo
|
||||
endif
|
||||
|
||||
noinst_LIBRARIES = lib_weechat_plugins.a
|
||||
if PLUGIN_TRIGGER
|
||||
trigger_dir = trigger
|
||||
endif
|
||||
|
||||
lib_weechat_plugins_a_SOURCES = weechat-plugin.h \
|
||||
plugins.h \
|
||||
plugins.c \
|
||||
plugins-interface.c \
|
||||
plugins-config.h \
|
||||
plugins-config.c
|
||||
SUBDIRS = . $(irc_dir) $(script_dir) $(aspell_dir) $(charset_dir) $(fifo_dir) $(trigger_dir)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2007 by FlashCode <flashcode@flashtux.org>
|
||||
* See README for License detail, AUTHORS for developers list.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __WEECHAT_PLUGIN_API_H
|
||||
#define __WEECHAT_PLUGIN_API_H 1
|
||||
|
||||
/* strings */
|
||||
extern void plugin_api_charset_set (struct t_weechat_plugin *, char *);
|
||||
extern char *plugin_api_iconv_to_internal (struct t_weechat_plugin *, char *, char *);
|
||||
extern char *plugin_api_iconv_from_internal (struct t_weechat_plugin *, char *, char *);
|
||||
extern char *plugin_api_gettext (struct t_weechat_plugin *, char *);
|
||||
extern char *plugin_api_ngettext (struct t_weechat_plugin *, char *, char *, int);
|
||||
extern int plugin_api_strcasecmp (struct t_weechat_plugin *,char *, char *);
|
||||
extern int plugin_api_strncasecmp (struct t_weechat_plugin *,char *, char *, int);
|
||||
extern char **plugin_api_explode_string (struct t_weechat_plugin *, char *, char *, int, int *);
|
||||
extern void plugin_api_free_exploded_string (struct t_weechat_plugin *, char **);
|
||||
|
||||
/* directories */
|
||||
extern int plugin_api_mkdir_home (struct t_weechat_plugin *, char *);
|
||||
extern void plugin_api_exec_on_files (struct t_weechat_plugin *, char *,
|
||||
int (*)(char *));
|
||||
|
||||
/* display */
|
||||
extern void plugin_api_printf (struct t_weechat_plugin *, void *,
|
||||
char *, ...);
|
||||
extern char *plugin_api_prefix (struct t_weechat_plugin *, char *);
|
||||
extern char *plugin_api_color (struct t_weechat_plugin *, char *);
|
||||
extern void plugin_api_print_infobar (struct t_weechat_plugin *, int,
|
||||
char *, ...);
|
||||
extern void plugin_api_infobar_remove (struct t_weechat_plugin *, int);
|
||||
|
||||
/* hooks */
|
||||
extern struct t_hook *plugin_api_hook_command (struct t_weechat_plugin *,
|
||||
char *, char *, char *, char *,
|
||||
char *, int (*)(void *, char *),
|
||||
void *);
|
||||
extern struct t_hook *plugin_api_hook_message (struct t_weechat_plugin *,
|
||||
char *, int (*)(void *, char *),
|
||||
void *);
|
||||
extern struct t_hook *plugin_api_hook_config (struct t_weechat_plugin *,
|
||||
char *, char *,
|
||||
int (*)(void *, char *, char *, char *),
|
||||
void *);
|
||||
extern struct t_hook *plugin_api_hook_timer (struct t_weechat_plugin *,
|
||||
long, int,
|
||||
int (*)(void *), void *);
|
||||
extern struct t_hook *plugin_api_hook_fd (struct t_weechat_plugin *,
|
||||
int, int, int, int,
|
||||
int (*)(void *), void *);
|
||||
extern void plugin_api_unhook (struct t_weechat_plugin *, void *);
|
||||
extern void plugin_api_unhook_all (struct t_weechat_plugin *);
|
||||
|
||||
/* buffers */
|
||||
extern struct t_gui_buffer *plugin_api_buffer_new (struct t_weechat_plugin *,
|
||||
char *, char *);
|
||||
extern struct t_gui_buffer *plugin_api_buffer_search (struct t_weechat_plugin *,
|
||||
char *, char *);
|
||||
extern void plugin_api_buffer_close (struct t_weechat_plugin *, void *);
|
||||
extern void plugin_api_buffer_set (struct t_weechat_plugin *, void *, char *,
|
||||
char *);
|
||||
extern void plugin_api_buffer_nick_add (struct t_weechat_plugin *, void *,
|
||||
char *, int, char *, char, char *);
|
||||
extern void plugin_api_buffer_nick_remove (struct t_weechat_plugin *, char *);
|
||||
|
||||
/* command */
|
||||
extern void plugin_api_command (struct t_weechat_plugin *, void *, char *);
|
||||
|
||||
/* infos */
|
||||
extern char *plugin_api_info_get (struct t_weechat_plugin *, char *);
|
||||
|
||||
/* config */
|
||||
extern char *plugin_api_config_get (struct t_weechat_plugin *, char *);
|
||||
extern int plugin_api_config_set (struct t_weechat_plugin *, char *, char *);
|
||||
extern char *plugin_api_plugin_config_get (struct t_weechat_plugin *, char *);
|
||||
extern int plugin_api_plugin_config_set (struct t_weechat_plugin *, char *, char *);
|
||||
|
||||
/* log */
|
||||
extern void plugin_api_log (struct t_weechat_plugin *, char *, char *, char *, ...);
|
||||
|
||||
#endif /* plugin-api.h */
|
||||
@@ -0,0 +1,335 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2007 by FlashCode <flashcode@flashtux.org>
|
||||
* See README for License detail, AUTHORS for developers list.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* plugin-config.c: plugin configuration */
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "../core/weechat.h"
|
||||
#include "../core/wee-config.h"
|
||||
#include "../core/wee-hook.h"
|
||||
#include "../core/wee-log.h"
|
||||
#include "../core/wee-string.h"
|
||||
#include "plugin-config.h"
|
||||
|
||||
|
||||
struct t_plugin_option *plugin_options = NULL;
|
||||
struct t_plugin_option *last_plugin_option = NULL;
|
||||
|
||||
char *plugin_config_sections[] =
|
||||
{ "plugin", NULL };
|
||||
|
||||
struct t_config_option *plugin_config_options[] =
|
||||
{ NULL, NULL };
|
||||
|
||||
t_config_func_read_option *plugin_config_read_functions[] =
|
||||
{ plugin_config_read_option, NULL };
|
||||
|
||||
t_config_func_write_options *plugin_config_write_functions[] =
|
||||
{ plugin_config_write_options, NULL };
|
||||
|
||||
|
||||
/*
|
||||
* plugin_config_search_internal: search a plugin option (internal function)
|
||||
* This function should not be called directly.
|
||||
*/
|
||||
|
||||
struct t_plugin_option *
|
||||
plugin_config_search_internal (char *option)
|
||||
{
|
||||
struct t_plugin_option *ptr_plugin_option;
|
||||
|
||||
for (ptr_plugin_option = plugin_options; ptr_plugin_option;
|
||||
ptr_plugin_option = ptr_plugin_option->next_option)
|
||||
{
|
||||
if (string_strcasecmp (ptr_plugin_option->name, option) == 0)
|
||||
{
|
||||
return ptr_plugin_option;
|
||||
}
|
||||
}
|
||||
|
||||
/* plugin option not found */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_config_search: search a plugin option
|
||||
*/
|
||||
|
||||
struct t_plugin_option *
|
||||
plugin_config_search (char *plugin_name, char *option)
|
||||
{
|
||||
char *internal_option;
|
||||
struct t_plugin_option *ptr_plugin_option;
|
||||
|
||||
internal_option = (char *)malloc (strlen (plugin_name) +
|
||||
strlen (option) + 2);
|
||||
if (!internal_option)
|
||||
return NULL;
|
||||
|
||||
strcpy (internal_option, plugin_name);
|
||||
strcat (internal_option, ".");
|
||||
strcat (internal_option, option);
|
||||
|
||||
ptr_plugin_option = plugin_config_search_internal (internal_option);
|
||||
|
||||
free (internal_option);
|
||||
|
||||
return ptr_plugin_option;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_config_find_pos: find position for a plugin option (for sorting options)
|
||||
*/
|
||||
|
||||
struct t_plugin_option *
|
||||
plugin_config_find_pos (char *name)
|
||||
{
|
||||
struct t_plugin_option *ptr_option;
|
||||
|
||||
for (ptr_option = plugin_options; ptr_option;
|
||||
ptr_option = ptr_option->next_option)
|
||||
{
|
||||
if (string_strcasecmp (name, ptr_option->name) < 0)
|
||||
return ptr_option;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_config_set_internal: set value for a plugin option (internal function)
|
||||
* This function should not be called directly.
|
||||
* Return: 1 if ok, 0 if error
|
||||
*/
|
||||
|
||||
int
|
||||
plugin_config_set_internal (char *option, char *value)
|
||||
{
|
||||
struct t_plugin_option *ptr_plugin_option, *pos_option;
|
||||
int rc;
|
||||
|
||||
rc = 0;
|
||||
|
||||
ptr_plugin_option = plugin_config_search_internal (option);
|
||||
if (ptr_plugin_option)
|
||||
{
|
||||
if (!value || !value[0])
|
||||
{
|
||||
/* remove option from list */
|
||||
if (ptr_plugin_option->prev_option)
|
||||
(ptr_plugin_option->prev_option)->next_option =
|
||||
ptr_plugin_option->next_option;
|
||||
else
|
||||
plugin_options = ptr_plugin_option->next_option;
|
||||
if (ptr_plugin_option->next_option)
|
||||
(ptr_plugin_option->next_option)->prev_option =
|
||||
ptr_plugin_option->prev_option;
|
||||
rc = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* replace old value by new one */
|
||||
if (ptr_plugin_option->value)
|
||||
free (ptr_plugin_option->value);
|
||||
ptr_plugin_option->value = strdup (value);
|
||||
rc = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value && value[0])
|
||||
{
|
||||
ptr_plugin_option = (struct t_plugin_option *)malloc (sizeof (struct t_plugin_option));
|
||||
if (ptr_plugin_option)
|
||||
{
|
||||
/* create new option */
|
||||
ptr_plugin_option->name = strdup (option);
|
||||
string_tolower (ptr_plugin_option->name);
|
||||
ptr_plugin_option->value = strdup (value);
|
||||
|
||||
if (plugin_options)
|
||||
{
|
||||
pos_option = plugin_config_find_pos (ptr_plugin_option->name);
|
||||
if (pos_option)
|
||||
{
|
||||
/* insert option into the list (before option found) */
|
||||
ptr_plugin_option->prev_option = pos_option->prev_option;
|
||||
ptr_plugin_option->next_option = pos_option;
|
||||
if (pos_option->prev_option)
|
||||
pos_option->prev_option->next_option = ptr_plugin_option;
|
||||
else
|
||||
plugin_options = ptr_plugin_option;
|
||||
pos_option->prev_option = ptr_plugin_option;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* add option to the end */
|
||||
ptr_plugin_option->prev_option = last_plugin_option;
|
||||
ptr_plugin_option->next_option = NULL;
|
||||
last_plugin_option->next_option = ptr_plugin_option;
|
||||
last_plugin_option = ptr_plugin_option;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr_plugin_option->prev_option = NULL;
|
||||
ptr_plugin_option->next_option = NULL;
|
||||
plugin_options = ptr_plugin_option;
|
||||
last_plugin_option = ptr_plugin_option;
|
||||
}
|
||||
rc = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
if (rc)
|
||||
hook_config_exec ("plugin", option, value);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_config_set: set value for a plugin option (create it if not found)
|
||||
* return: 1 if ok, 0 if error
|
||||
*/
|
||||
|
||||
int
|
||||
plugin_config_set (char *plugin_name, char *option, char *value)
|
||||
{
|
||||
char *internal_option;
|
||||
int return_code;
|
||||
|
||||
internal_option = (char *)malloc (strlen (plugin_name) +
|
||||
strlen (option) + 2);
|
||||
if (!internal_option)
|
||||
return 0;
|
||||
|
||||
strcpy (internal_option, plugin_name);
|
||||
strcat (internal_option, ".");
|
||||
strcat (internal_option, option);
|
||||
|
||||
return_code = plugin_config_set_internal (internal_option, value);
|
||||
free (internal_option);
|
||||
|
||||
return return_code;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_config_read_option: read an option in config file
|
||||
* Return: 0 = successful
|
||||
* -1 = option not found
|
||||
* -2 = bad format/value
|
||||
*/
|
||||
|
||||
int
|
||||
plugin_config_read_option (struct t_config_option *options,
|
||||
char *option_name, char *value)
|
||||
{
|
||||
char *value2;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) options;
|
||||
|
||||
if (option_name)
|
||||
{
|
||||
value2 = string_iconv_to_internal (NULL, value);
|
||||
plugin_config_set_internal (option_name,
|
||||
(value2) ? value2 : value);
|
||||
if (value2)
|
||||
free (value2);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* does nothing for new [plugin] section */
|
||||
}
|
||||
|
||||
/* all ok */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_config_read: read WeeChat plugins configuration file
|
||||
* return: 0 = successful
|
||||
* -1 = config file file not found
|
||||
* -2 = error in config file
|
||||
*/
|
||||
|
||||
int
|
||||
plugin_config_read ()
|
||||
{
|
||||
return config_file_read (plugin_config_sections, plugin_config_options,
|
||||
plugin_config_read_functions,
|
||||
plugin_config_read_option,
|
||||
NULL,
|
||||
WEECHAT_PLUGIN_CONFIG_NAME);
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_config_write_options: write plugin options in configuration file
|
||||
* Return: 0 = successful
|
||||
* -1 = write error
|
||||
*/
|
||||
|
||||
int
|
||||
plugin_config_write_options (FILE *file, char *section_name,
|
||||
struct t_config_option *options)
|
||||
{
|
||||
/* make C compiler happy */
|
||||
(void) options;
|
||||
|
||||
struct t_plugin_option *ptr_plugin_option;
|
||||
|
||||
string_iconv_fprintf (file, "\n[%s]\n", section_name);
|
||||
|
||||
for (ptr_plugin_option = plugin_options; ptr_plugin_option;
|
||||
ptr_plugin_option = ptr_plugin_option->next_option)
|
||||
{
|
||||
string_iconv_fprintf (file, "%s = \"%s\"\n",
|
||||
ptr_plugin_option->name,
|
||||
ptr_plugin_option->value);
|
||||
}
|
||||
|
||||
/* all ok */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_config_write: write WeeChat configuration file
|
||||
* return: 0 if ok
|
||||
* < 0 if error
|
||||
*/
|
||||
|
||||
int
|
||||
plugin_config_write ()
|
||||
{
|
||||
weechat_log_printf (_("Saving plugins configuration to disk\n"));
|
||||
return config_file_write (plugin_config_sections, plugin_config_options,
|
||||
plugin_config_write_functions,
|
||||
WEECHAT_PLUGIN_CONFIG_NAME);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2007 by FlashCode <flashcode@flashtux.org>
|
||||
* See README for License detail, AUTHORS for developers list.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __WEECHAT_PLUGIN_CONFIG_H
|
||||
#define __WEECHAT_PLUGIN_CONFIG_H 1
|
||||
|
||||
#include "../core/wee-config-option.h"
|
||||
|
||||
#define WEECHAT_PLUGIN_CONFIG_NAME "plugins.rc"
|
||||
|
||||
struct t_plugin_option
|
||||
{
|
||||
char *name; /* option name in config file */
|
||||
char *value; /* value of option */
|
||||
struct t_plugin_option *prev_option; /* link to previous option */
|
||||
struct t_plugin_option *next_option; /* link to next option */
|
||||
};
|
||||
|
||||
extern struct t_plugin_option *plugin_options;
|
||||
|
||||
extern struct t_plugin_option *plugin_config_search_internal (char *);
|
||||
extern struct t_plugin_option *plugin_config_search (char *, char *);
|
||||
extern int plugin_config_set_internal (char *, char *);
|
||||
extern int plugin_config_set (char *, char *, char *);
|
||||
extern int plugin_config_read_option (struct t_config_option *, char *, char *);
|
||||
extern int plugin_config_read ();
|
||||
extern int plugin_config_write_options (FILE *, char *,
|
||||
struct t_config_option *);
|
||||
extern int plugin_config_write ();
|
||||
|
||||
#endif /* plugin-config.h */
|
||||
@@ -0,0 +1,361 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2007 by FlashCode <flashcode@flashtux.org>
|
||||
* See README for License detail, AUTHORS for developers list.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* plugin-list.c: manages plugin info lists */
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../core/weechat.h"
|
||||
#include "../core/wee-log.h"
|
||||
#include "plugin-list.h"
|
||||
|
||||
|
||||
struct t_plugin_list *plugin_lists = NULL;
|
||||
struct t_plugin_list *last_plugin_list = NULL;
|
||||
|
||||
|
||||
/*
|
||||
* plugin_list_new: create a new plugin list
|
||||
*/
|
||||
|
||||
struct t_plugin_list *
|
||||
plugin_list_new ()
|
||||
{
|
||||
struct t_plugin_list *new_list;
|
||||
|
||||
new_list = (struct t_plugin_list *)malloc (sizeof (struct t_plugin_list));
|
||||
if (new_list)
|
||||
{
|
||||
new_list->items = NULL;
|
||||
new_list->last_item = NULL;
|
||||
new_list->ptr_item = NULL;
|
||||
|
||||
new_list->prev_list = last_plugin_list;
|
||||
new_list->next_list = NULL;
|
||||
if (plugin_lists)
|
||||
last_plugin_list->next_list = new_list;
|
||||
else
|
||||
plugin_lists = new_list;
|
||||
last_plugin_list = new_list;
|
||||
}
|
||||
|
||||
return new_list;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_list_new_item: create a new item in a plugin list
|
||||
*/
|
||||
|
||||
struct t_plugin_list_item *
|
||||
plugin_list_new_item (struct t_plugin_list *list)
|
||||
{
|
||||
struct t_plugin_list_item *new_item;
|
||||
|
||||
new_item = (struct t_plugin_list_item *)malloc (sizeof (struct t_plugin_list_item));
|
||||
if (new_item)
|
||||
{
|
||||
new_item->vars = NULL;
|
||||
new_item->last_var = NULL;
|
||||
|
||||
new_item->prev_item = list->last_item;
|
||||
new_item->next_item = NULL;
|
||||
if (list->items)
|
||||
list->last_item->next_item = new_item;
|
||||
else
|
||||
list->items = new_item;
|
||||
list->last_item = new_item;
|
||||
}
|
||||
|
||||
return new_item;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_list_new_var_int: create a new integer variable in an item
|
||||
*/
|
||||
|
||||
struct t_plugin_list_var *
|
||||
plugin_list_new_var_int (struct t_plugin_list_item *item,
|
||||
char *name, int value)
|
||||
{
|
||||
struct t_plugin_list_var *new_var;
|
||||
|
||||
new_var = (struct t_plugin_list_var *)malloc (sizeof (struct t_plugin_list_var));
|
||||
if (new_var)
|
||||
{
|
||||
new_var->name = strdup (name);
|
||||
new_var->value_int = value;
|
||||
new_var->value_string = NULL;
|
||||
new_var->value_pointer = NULL;
|
||||
new_var->value_time = 0;
|
||||
|
||||
new_var->prev_var = item->last_var;
|
||||
new_var->next_var = NULL;
|
||||
if (item->vars)
|
||||
item->last_var->next_var = new_var;
|
||||
else
|
||||
item->vars = new_var;
|
||||
item->last_var = new_var;
|
||||
}
|
||||
|
||||
return new_var;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_list_new_var_string: create a new string variable in an item
|
||||
*/
|
||||
|
||||
struct t_plugin_list_var *
|
||||
plugin_list_new_var_string (struct t_plugin_list_item *item,
|
||||
char *name, char *value)
|
||||
{
|
||||
struct t_plugin_list_var *new_var;
|
||||
|
||||
new_var = (struct t_plugin_list_var *)malloc (sizeof (struct t_plugin_list_var));
|
||||
if (new_var)
|
||||
{
|
||||
new_var->name = strdup (name);
|
||||
new_var->value_int = 0;
|
||||
new_var->value_string = strdup (value);
|
||||
new_var->value_time = 0;
|
||||
|
||||
new_var->prev_var = item->last_var;
|
||||
new_var->next_var = NULL;
|
||||
if (item->vars)
|
||||
item->last_var->next_var = new_var;
|
||||
else
|
||||
item->vars = new_var;
|
||||
item->last_var = new_var;
|
||||
}
|
||||
|
||||
return new_var;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_list_new_var_pointer: create a new pointer variable in an item
|
||||
*/
|
||||
|
||||
struct t_plugin_list_var *
|
||||
plugin_list_new_var_pointer (struct t_plugin_list_item *item,
|
||||
char *name, void *pointer)
|
||||
{
|
||||
struct t_plugin_list_var *new_var;
|
||||
|
||||
new_var = (struct t_plugin_list_var *)malloc (sizeof (struct t_plugin_list_var));
|
||||
if (new_var)
|
||||
{
|
||||
new_var->name = strdup (name);
|
||||
new_var->value_int = 0;
|
||||
new_var->value_string = NULL;
|
||||
new_var->value_pointer = pointer;
|
||||
new_var->value_time = 0;
|
||||
|
||||
new_var->prev_var = item->last_var;
|
||||
new_var->next_var = NULL;
|
||||
if (item->vars)
|
||||
item->last_var->next_var = new_var;
|
||||
else
|
||||
item->vars = new_var;
|
||||
item->last_var = new_var;
|
||||
}
|
||||
|
||||
return new_var;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_list_new_var_time: create a new time variable in an item
|
||||
*/
|
||||
|
||||
struct t_plugin_list_var *
|
||||
plugin_list_new_var_time (struct t_plugin_list_item *item,
|
||||
char *name, time_t time)
|
||||
{
|
||||
struct t_plugin_list_var *new_var;
|
||||
|
||||
new_var = (struct t_plugin_list_var *)malloc (sizeof (struct t_plugin_list_var));
|
||||
if (new_var)
|
||||
{
|
||||
new_var->name = strdup (name);
|
||||
new_var->value_int = 0;
|
||||
new_var->value_string = NULL;
|
||||
new_var->value_pointer = NULL;
|
||||
new_var->value_time = time;
|
||||
|
||||
new_var->prev_var = item->last_var;
|
||||
new_var->next_var = NULL;
|
||||
if (item->vars)
|
||||
item->last_var->next_var = new_var;
|
||||
else
|
||||
item->vars = new_var;
|
||||
item->last_var = new_var;
|
||||
}
|
||||
|
||||
return new_var;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_list_var_free: free a plugin list variable
|
||||
*/
|
||||
|
||||
void
|
||||
plugin_list_var_free (struct t_plugin_list_item *item,
|
||||
struct t_plugin_list_var *var)
|
||||
{
|
||||
struct t_plugin_list_var *new_vars;
|
||||
|
||||
/* remove var */
|
||||
if (item->last_var == var)
|
||||
item->last_var = var->prev_var;
|
||||
if (var->prev_var)
|
||||
{
|
||||
(var->prev_var)->next_var = var->next_var;
|
||||
new_vars = item->vars;
|
||||
}
|
||||
else
|
||||
new_vars = var->next_var;
|
||||
|
||||
if (var->next_var)
|
||||
(var->next_var)->prev_var = var->prev_var;
|
||||
|
||||
/* free data */
|
||||
if (var->name)
|
||||
free (var->name);
|
||||
if (var->value_string)
|
||||
free (var->value_string);
|
||||
|
||||
item->vars = new_vars;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_list_item_free: free a plugin list item
|
||||
*/
|
||||
|
||||
void
|
||||
plugin_list_item_free (struct t_plugin_list *list,
|
||||
struct t_plugin_list_item *item)
|
||||
{
|
||||
struct t_plugin_list_item *new_items;
|
||||
|
||||
/* remove var */
|
||||
if (list->last_item == item)
|
||||
list->last_item = item->prev_item;
|
||||
if (item->prev_item)
|
||||
{
|
||||
(item->prev_item)->next_item = item->next_item;
|
||||
new_items = list->items;
|
||||
}
|
||||
else
|
||||
new_items = item->next_item;
|
||||
|
||||
if (item->next_item)
|
||||
(item->next_item)->prev_item = item->prev_item;
|
||||
|
||||
/* free data */
|
||||
while (item->vars)
|
||||
{
|
||||
plugin_list_var_free (item, item->vars);
|
||||
}
|
||||
|
||||
list->items = new_items;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_list_free: free a plugin list
|
||||
*/
|
||||
|
||||
void
|
||||
plugin_list_free (struct t_plugin_list *list)
|
||||
{
|
||||
struct t_plugin_list *new_plugin_lists;
|
||||
|
||||
/* remove list */
|
||||
if (last_plugin_list == list)
|
||||
last_plugin_list = list->prev_list;
|
||||
if (list->prev_list)
|
||||
{
|
||||
(list->prev_list)->next_list = list->next_list;
|
||||
new_plugin_lists = plugin_lists;
|
||||
}
|
||||
else
|
||||
new_plugin_lists = list->next_list;
|
||||
|
||||
if (list->next_list)
|
||||
(list->next_list)->prev_list = list->prev_list;
|
||||
|
||||
/* free data */
|
||||
while (list->items)
|
||||
{
|
||||
plugin_list_item_free (list, list->items);
|
||||
}
|
||||
|
||||
plugin_lists = new_plugin_lists;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_list_print_log: print plugin lists infos in log (usually for crash dump)
|
||||
*/
|
||||
|
||||
void
|
||||
plugin_list_print_log ()
|
||||
{
|
||||
struct t_plugin_list *ptr_list;
|
||||
struct t_plugin_list_item *ptr_item;
|
||||
struct t_plugin_list_var *ptr_var;
|
||||
|
||||
for (ptr_list = plugin_lists; ptr_list;
|
||||
ptr_list = ptr_list->next_list)
|
||||
{
|
||||
weechat_log_printf ("\n");
|
||||
weechat_log_printf ("[plugin list (addr:0x%X)]\n", ptr_list);
|
||||
weechat_log_printf (" items. . . . . . . . . : 0x%X\n", ptr_list->items);
|
||||
weechat_log_printf (" last_item. . . . . . . : 0x%X\n", ptr_list->last_item);
|
||||
weechat_log_printf (" ptr_item . . . . . . . : 0x%X\n", ptr_list->ptr_item);
|
||||
weechat_log_printf (" prev_list. . . . . . . : 0x%X\n", ptr_list->prev_list);
|
||||
weechat_log_printf (" next_list. . . . . . . : 0x%X\n", ptr_list->next_list);
|
||||
|
||||
for (ptr_item = ptr_list->items; ptr_item;
|
||||
ptr_item = ptr_item->next_item)
|
||||
{
|
||||
weechat_log_printf ("\n");
|
||||
weechat_log_printf (" [item (addr:0x%X)]\n", ptr_item);
|
||||
weechat_log_printf (" vars . . . . . . . . . : 0x%X\n", ptr_item->vars);
|
||||
weechat_log_printf (" last_var . . . . . . . : 0x%X\n", ptr_item->last_var);
|
||||
weechat_log_printf (" prev_item. . . . . . . : 0x%X\n", ptr_item->prev_item);
|
||||
weechat_log_printf (" next_item. . . . . . . : 0x%X\n", ptr_item->next_item);
|
||||
|
||||
for (ptr_var = ptr_item->vars; ptr_var;
|
||||
ptr_var = ptr_var->next_var)
|
||||
{
|
||||
weechat_log_printf ("\n");
|
||||
weechat_log_printf (" [var (addr:0x%X)]\n", ptr_var);
|
||||
weechat_log_printf (" name . . . . . . . . : '%s'\n", ptr_var->name);
|
||||
weechat_log_printf (" type . . . . . . . . : %d\n", ptr_var->type);
|
||||
weechat_log_printf (" value_int. . . . . . : %d\n", ptr_var->value_int);
|
||||
weechat_log_printf (" value_string . . . . : '%s'\n", ptr_var->value_string);
|
||||
weechat_log_printf (" value_time . . . . . : %ld\n", ptr_var->value_time);
|
||||
weechat_log_printf (" prev_var . . . . . . : 0x%X\n", ptr_var->prev_var);
|
||||
weechat_log_printf (" next_var . . . . . . : 0x%X\n", ptr_var->next_var);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2007 by FlashCode <flashcode@flashtux.org>
|
||||
* See README for License detail, AUTHORS for developers list.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __WEECHAT_PLUGIN_LIST_H
|
||||
#define __WEECHAT_PLUGIN_LIST_H 1
|
||||
|
||||
/* list structures */
|
||||
|
||||
enum t_plugin_var_type
|
||||
{
|
||||
PLUGIN_LIST_VAR_INTEGER = 0,
|
||||
PLUGIN_LIST_VAR_STRING,
|
||||
PLUGIN_LIST_VAR_POINTER,
|
||||
PLUGIN_LIST_VAR_TIME,
|
||||
};
|
||||
|
||||
struct t_plugin_list_var
|
||||
{
|
||||
char *name; /* variable name */
|
||||
enum t_plugin_var_type type; /* type: integer, string, time */
|
||||
int value_int; /* integer value */
|
||||
char *value_string; /* string value */
|
||||
void *value_pointer; /* pointer value */
|
||||
time_t value_time; /* time value */
|
||||
struct t_plugin_list_var *prev_var; /* link to previous variable */
|
||||
struct t_plugin_list_var *next_var; /* link to next variable */
|
||||
};
|
||||
|
||||
struct t_plugin_list_item
|
||||
{
|
||||
struct t_plugin_list_var *vars; /* item variables */
|
||||
struct t_plugin_list_var *last_var; /* last variable */
|
||||
struct t_plugin_list_item *prev_item; /* link to previous item */
|
||||
struct t_plugin_list_item *next_item; /* link to next item */
|
||||
};
|
||||
|
||||
struct t_plugin_list
|
||||
{
|
||||
struct t_plugin_list_item *items; /* link to items */
|
||||
struct t_plugin_list_item *last_item; /* last variable */
|
||||
struct t_plugin_list_item *ptr_item; /* pointer to current item */
|
||||
struct t_plugin_list *prev_list; /* link to previous list */
|
||||
struct t_plugin_list *next_list; /* link to next list */
|
||||
};
|
||||
|
||||
/* list variables */
|
||||
|
||||
extern struct t_plugin_list *plugin_lists;
|
||||
extern struct t_plugin_list *last_plugin_list;
|
||||
|
||||
/* list functions */
|
||||
|
||||
extern struct t_plugin_list *plugin_list_new ();
|
||||
extern struct t_plugin_list_item *plugin_list_new_item (struct t_plugin_list *);
|
||||
extern struct t_plugin_list_var *plugin_list_new_var_int (struct t_plugin_list_item *,
|
||||
char *, int);
|
||||
extern struct t_plugin_list_var *plugin_list_new_var_string (struct t_plugin_list_item *,
|
||||
char *, char *);
|
||||
extern struct t_plugin_list_var *plugin_list_new_var_pointer (struct t_plugin_list_item *,
|
||||
char *, void *);
|
||||
extern struct t_plugin_list_var *plugin_list_new_var_time (struct t_plugin_list_item *,
|
||||
char *, time_t);
|
||||
extern void plugin_list_free (struct t_plugin_list *);
|
||||
extern void plugin_list_print_log ();
|
||||
|
||||
#endif /* plugin-list.h */
|
||||
@@ -0,0 +1,601 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2007 by FlashCode <flashcode@flashtux.org>
|
||||
* See README for License detail, AUTHORS for developers list.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* plugin.c: manages WeeChat plugins (dynamic C libraries) */
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "../core/weechat.h"
|
||||
#include "../core/wee-command.h"
|
||||
#include "../core/wee-config.h"
|
||||
#include "../core/wee-hook.h"
|
||||
#include "../core/wee-log.h"
|
||||
#include "../core/wee-string.h"
|
||||
#include "../core/wee-util.h"
|
||||
#include "../gui/gui-chat.h"
|
||||
#include "plugin.h"
|
||||
#include "plugin-api.h"
|
||||
#include "plugin-config.h"
|
||||
#include "plugin-list.h"
|
||||
|
||||
|
||||
struct t_weechat_plugin *weechat_plugins = NULL;
|
||||
struct t_weechat_plugin *last_weechat_plugin = NULL;
|
||||
|
||||
|
||||
/*
|
||||
* plugin_exec_on_files: find files in a directory and execute a
|
||||
* function on each file
|
||||
*/
|
||||
|
||||
void
|
||||
plugin_exec_on_files (struct t_weechat_plugin *plugin, char *directory,
|
||||
int (*callback)(struct t_weechat_plugin *, char *))
|
||||
{
|
||||
char complete_filename[1024];
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
struct stat statbuf;
|
||||
|
||||
dir = opendir (directory);
|
||||
if (dir)
|
||||
{
|
||||
while ((entry = readdir (dir)))
|
||||
{
|
||||
snprintf (complete_filename, sizeof (complete_filename) - 1,
|
||||
"%s/%s", directory, entry->d_name);
|
||||
lstat (complete_filename, &statbuf);
|
||||
if (!S_ISDIR(statbuf.st_mode))
|
||||
{
|
||||
(int) (*callback) (plugin, complete_filename);
|
||||
}
|
||||
}
|
||||
closedir (dir);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_search: search a plugin by name
|
||||
*/
|
||||
|
||||
struct t_weechat_plugin *
|
||||
plugin_search (char *name)
|
||||
{
|
||||
struct t_weechat_plugin *ptr_plugin;
|
||||
|
||||
for (ptr_plugin = weechat_plugins; ptr_plugin;
|
||||
ptr_plugin = ptr_plugin->next_plugin)
|
||||
{
|
||||
if (string_strcasecmp (ptr_plugin->name, name) == 0)
|
||||
return ptr_plugin;
|
||||
}
|
||||
|
||||
/* plugin not found */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_load: load a WeeChat plugin (a dynamic library)
|
||||
* return: pointer to new WeeChat plugin, NULL if error
|
||||
*/
|
||||
|
||||
struct t_weechat_plugin *
|
||||
plugin_load (char *filename)
|
||||
{
|
||||
char *full_name;
|
||||
void *handle;
|
||||
char *name, *description, *version, *charset;
|
||||
t_weechat_init_func *init_func;
|
||||
struct t_weechat_plugin *new_plugin;
|
||||
|
||||
if (!filename)
|
||||
return NULL;
|
||||
|
||||
full_name = util_search_full_lib_name (filename, "plugins");
|
||||
|
||||
if (!full_name)
|
||||
return NULL;
|
||||
|
||||
handle = dlopen (full_name, RTLD_GLOBAL | RTLD_NOW);
|
||||
if (!handle)
|
||||
{
|
||||
gui_chat_printf (NULL,
|
||||
_("%s%s unable to load plugin \"%s\": %s\n"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
WEECHAT_ERROR, full_name, dlerror());
|
||||
free (full_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* look for plugin name */
|
||||
name = dlsym (handle, "plugin_name");
|
||||
if (!name)
|
||||
{
|
||||
dlclose (handle);
|
||||
gui_chat_printf (NULL,
|
||||
_("%s%s symbol \"%s\" not found in "
|
||||
"plugin \"%s\", failed to load\n"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
WEECHAT_ERROR, "plugin_name",
|
||||
full_name);
|
||||
free (full_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* check for plugin with same name */
|
||||
if (plugin_search (name))
|
||||
{
|
||||
dlclose (handle);
|
||||
gui_chat_printf (NULL,
|
||||
_("%s%s unable to load plugin \"%s\": a plugin "
|
||||
"with same name already exists\n"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
WEECHAT_ERROR, full_name);
|
||||
free (full_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* look for plugin description */
|
||||
description = dlsym (handle, "plugin_description");
|
||||
if (!description)
|
||||
{
|
||||
dlclose (handle);
|
||||
gui_chat_printf (NULL,
|
||||
_("%s%s symbol \"%s\" not found "
|
||||
"in plugin \"%s\", failed to load\n"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
WEECHAT_ERROR, "plugin_description",
|
||||
full_name);
|
||||
free (full_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* look for plugin version */
|
||||
version = dlsym (handle, "plugin_version");
|
||||
if (!version)
|
||||
{
|
||||
dlclose (handle);
|
||||
gui_chat_printf (NULL,
|
||||
_("%s%s symbol \"%s\" not found in "
|
||||
"plugin \"%s\", failed to load\n"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
WEECHAT_ERROR, "plugin_version",
|
||||
full_name);
|
||||
free (full_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* look for plugin charset (optional) */
|
||||
charset = dlsym (handle, "plugin_charset");
|
||||
|
||||
/* look for plugin init function */
|
||||
init_func = dlsym (handle, "weechat_plugin_init");
|
||||
if (!init_func)
|
||||
{
|
||||
dlclose (handle);
|
||||
gui_chat_printf (NULL,
|
||||
_("%s%s function \"%s\" not "
|
||||
"found in plugin \"%s\", failed to load\n"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
WEECHAT_ERROR, "weechat_plugin_init",
|
||||
full_name);
|
||||
free (full_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* create new plugin */
|
||||
new_plugin = (struct t_weechat_plugin *)malloc (sizeof (struct t_weechat_plugin));
|
||||
if (new_plugin)
|
||||
{
|
||||
/* variables */
|
||||
new_plugin->filename = strdup (full_name);
|
||||
new_plugin->handle = handle;
|
||||
new_plugin->name = strdup (name);
|
||||
new_plugin->description = strdup (description);
|
||||
new_plugin->version = strdup (version);
|
||||
new_plugin->charset = (charset) ? strdup (charset) : NULL;
|
||||
|
||||
/* functions */
|
||||
new_plugin->charset_set = &plugin_api_charset_set;
|
||||
new_plugin->iconv_to_internal = &plugin_api_iconv_to_internal;
|
||||
new_plugin->iconv_from_internal = &plugin_api_iconv_from_internal;
|
||||
new_plugin->gettext = &plugin_api_gettext;
|
||||
new_plugin->ngettext = &plugin_api_ngettext;
|
||||
new_plugin->strcasecmp = &plugin_api_strcasecmp;
|
||||
new_plugin->strncasecmp = &plugin_api_strncasecmp;
|
||||
new_plugin->explode_string = &plugin_api_explode_string;
|
||||
new_plugin->free_exploded_string = &plugin_api_free_exploded_string;
|
||||
|
||||
new_plugin->mkdir_home = &plugin_api_mkdir_home;
|
||||
new_plugin->exec_on_files = &plugin_api_exec_on_files;
|
||||
|
||||
new_plugin->printf = &plugin_api_printf;
|
||||
new_plugin->prefix = &plugin_api_prefix;
|
||||
new_plugin->color = &plugin_api_color;
|
||||
new_plugin->print_infobar = &plugin_api_print_infobar;
|
||||
new_plugin->infobar_remove = &plugin_api_infobar_remove;
|
||||
|
||||
new_plugin->hook_command = &plugin_api_hook_command;
|
||||
new_plugin->hook_message = &plugin_api_hook_message;
|
||||
new_plugin->hook_config = &plugin_api_hook_config;
|
||||
new_plugin->hook_timer = &plugin_api_hook_timer;
|
||||
new_plugin->hook_fd = &plugin_api_hook_fd;
|
||||
new_plugin->unhook = &plugin_api_unhook;
|
||||
new_plugin->unhook_all = &plugin_api_unhook_all;
|
||||
|
||||
new_plugin->buffer_new = &plugin_api_buffer_new;
|
||||
new_plugin->buffer_search = &plugin_api_buffer_search;
|
||||
new_plugin->buffer_close = &plugin_api_buffer_close;
|
||||
new_plugin->buffer_set = &plugin_api_buffer_set;
|
||||
new_plugin->buffer_nick_add = &plugin_api_buffer_nick_add;
|
||||
new_plugin->buffer_nick_remove = &plugin_api_buffer_nick_remove;
|
||||
|
||||
new_plugin->command = &plugin_api_command;
|
||||
|
||||
new_plugin->info_get = &plugin_api_info_get;
|
||||
|
||||
new_plugin->config_get = &plugin_api_config_get;
|
||||
new_plugin->config_set = &plugin_api_config_set;
|
||||
new_plugin->plugin_config_get = &plugin_api_plugin_config_get;
|
||||
new_plugin->plugin_config_set = &plugin_api_plugin_config_set;
|
||||
|
||||
new_plugin->log = &plugin_api_log;
|
||||
|
||||
/* add new plugin to list */
|
||||
new_plugin->prev_plugin = last_weechat_plugin;
|
||||
new_plugin->next_plugin = NULL;
|
||||
if (weechat_plugins)
|
||||
last_weechat_plugin->next_plugin = new_plugin;
|
||||
else
|
||||
weechat_plugins = new_plugin;
|
||||
last_weechat_plugin = new_plugin;
|
||||
|
||||
gui_chat_printf (NULL,
|
||||
_("%sInitializing plugin \"%s\" %s\n"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_INFO],
|
||||
new_plugin->name, new_plugin->version);
|
||||
|
||||
/* init plugin */
|
||||
if (((t_weechat_init_func *)init_func) (new_plugin) < 0)
|
||||
{
|
||||
gui_chat_printf (NULL,
|
||||
_("%s%s unable to initialize plugin "
|
||||
"\"%s\"\n"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
WEECHAT_ERROR, full_name);
|
||||
plugin_remove (new_plugin);
|
||||
free (full_name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gui_chat_printf (NULL,
|
||||
_("%s%s unable to load plugin \"%s\" "
|
||||
"(not enough memory)\n"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
WEECHAT_ERROR, full_name);
|
||||
free (full_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gui_chat_printf (NULL,
|
||||
_("%sPlugin \"%s\" (%s) loaded.\n"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_INFO],
|
||||
name, full_name);
|
||||
|
||||
free (full_name);
|
||||
|
||||
return new_plugin;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_auto_load_file: load a file found by plugin_auto_load,
|
||||
* but only it this is really a dynamic library
|
||||
*/
|
||||
|
||||
int
|
||||
plugin_auto_load_file (struct t_weechat_plugin *plugin, char *filename)
|
||||
{
|
||||
char *pos;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) plugin;
|
||||
|
||||
if (cfg_plugins_extension && cfg_plugins_extension[0])
|
||||
{
|
||||
pos = strstr (filename, cfg_plugins_extension);
|
||||
if (pos)
|
||||
{
|
||||
if (string_strcasecmp (pos, cfg_plugins_extension) == 0)
|
||||
plugin_load (filename);
|
||||
}
|
||||
}
|
||||
else
|
||||
plugin_load (filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_auto_load: auto-load WeeChat plugins
|
||||
*/
|
||||
|
||||
void
|
||||
plugin_auto_load ()
|
||||
{
|
||||
char *ptr_home, *dir_name, *plugins_path, *plugins_path2;
|
||||
char *list_plugins, *pos, *pos2;
|
||||
|
||||
if (cfg_plugins_autoload && cfg_plugins_autoload[0])
|
||||
{
|
||||
if (string_strcasecmp (cfg_plugins_autoload, "*") == 0)
|
||||
{
|
||||
/* auto-load plugins in WeeChat home dir */
|
||||
if (cfg_plugins_path && cfg_plugins_path[0])
|
||||
{
|
||||
ptr_home = getenv ("HOME");
|
||||
plugins_path = string_replace (cfg_plugins_path, "~", ptr_home);
|
||||
plugins_path2 = string_replace ((plugins_path) ?
|
||||
plugins_path : cfg_plugins_path,
|
||||
"%h", weechat_home);
|
||||
plugin_exec_on_files (NULL,
|
||||
(plugins_path2) ?
|
||||
plugins_path2 : ((plugins_path) ?
|
||||
plugins_path : cfg_plugins_path),
|
||||
&plugin_auto_load_file);
|
||||
if (plugins_path)
|
||||
free (plugins_path);
|
||||
if (plugins_path2)
|
||||
free (plugins_path2);
|
||||
}
|
||||
|
||||
/* auto-load plugins in WeeChat global lib dir */
|
||||
dir_name = (char *)malloc (strlen (WEECHAT_LIBDIR) + 16);
|
||||
if (dir_name)
|
||||
{
|
||||
snprintf (dir_name, strlen (WEECHAT_LIBDIR) + 16,
|
||||
"%s/plugins", WEECHAT_LIBDIR);
|
||||
plugin_exec_on_files (NULL, dir_name, &plugin_auto_load_file);
|
||||
free (dir_name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
list_plugins = strdup (cfg_plugins_autoload);
|
||||
if (list_plugins)
|
||||
{
|
||||
pos = list_plugins;
|
||||
while (pos && pos[0])
|
||||
{
|
||||
pos2 = strchr (pos, ',');
|
||||
if (pos2)
|
||||
pos2[0] = '\0';
|
||||
plugin_load (pos);
|
||||
if (pos2)
|
||||
pos = pos2 + 1;
|
||||
else
|
||||
pos = NULL;
|
||||
}
|
||||
free (list_plugins);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_remove: remove a WeeChat plugin
|
||||
*/
|
||||
|
||||
void
|
||||
plugin_remove (struct t_weechat_plugin *plugin)
|
||||
{
|
||||
struct t_weechat_plugin *new_weechat_plugins;
|
||||
|
||||
/* remove plugin from list */
|
||||
if (last_weechat_plugin == plugin)
|
||||
last_weechat_plugin = plugin->prev_plugin;
|
||||
if (plugin->prev_plugin)
|
||||
{
|
||||
(plugin->prev_plugin)->next_plugin = plugin->next_plugin;
|
||||
new_weechat_plugins = weechat_plugins;
|
||||
}
|
||||
else
|
||||
new_weechat_plugins = plugin->next_plugin;
|
||||
|
||||
if (plugin->next_plugin)
|
||||
(plugin->next_plugin)->prev_plugin = plugin->prev_plugin;
|
||||
|
||||
/* remove all hooks */
|
||||
unhook_all_plugin (plugin);
|
||||
|
||||
/* free data */
|
||||
if (plugin->filename)
|
||||
free (plugin->filename);
|
||||
dlclose (plugin->handle);
|
||||
if (plugin->name)
|
||||
free (plugin->name);
|
||||
if (plugin->description)
|
||||
free (plugin->description);
|
||||
if (plugin->version)
|
||||
free (plugin->version);
|
||||
if (plugin->charset)
|
||||
free (plugin->charset);
|
||||
free (plugin);
|
||||
|
||||
weechat_plugins = new_weechat_plugins;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_unload: unload a WeeChat plugin
|
||||
*/
|
||||
|
||||
void
|
||||
plugin_unload (struct t_weechat_plugin *plugin)
|
||||
{
|
||||
t_weechat_end_func *end_func;
|
||||
char *name;
|
||||
|
||||
name = (plugin->name) ? strdup (plugin->name) : strdup ("???");
|
||||
|
||||
end_func = dlsym (plugin->handle, "weechat_plugin_end");
|
||||
if (end_func)
|
||||
(void) (end_func) (plugin);
|
||||
plugin_remove (plugin);
|
||||
|
||||
gui_chat_printf (NULL,
|
||||
_("%sPlugin \"%s\" unloaded.\n"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_INFO],
|
||||
(name) ? name : "???");
|
||||
if (name)
|
||||
free (name);
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_unload_name: unload a WeeChat plugin by name
|
||||
*/
|
||||
|
||||
void
|
||||
plugin_unload_name (char *name)
|
||||
{
|
||||
struct t_weechat_plugin *ptr_plugin;
|
||||
|
||||
ptr_plugin = plugin_search (name);
|
||||
if (ptr_plugin)
|
||||
plugin_unload (ptr_plugin);
|
||||
else
|
||||
{
|
||||
gui_chat_printf (NULL,
|
||||
_("%s%s plugin \"%s\" not found\n"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
WEECHAT_ERROR, name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_unload_all: unload all WeeChat plugins
|
||||
*/
|
||||
|
||||
void
|
||||
plugin_unload_all ()
|
||||
{
|
||||
while (weechat_plugins)
|
||||
plugin_unload (last_weechat_plugin);
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_reload_name: reload a WeeChat plugin by name
|
||||
*/
|
||||
|
||||
void
|
||||
plugin_reload_name (char *name)
|
||||
{
|
||||
struct t_weechat_plugin *ptr_plugin;
|
||||
char *filename;
|
||||
|
||||
ptr_plugin = plugin_search (name);
|
||||
if (ptr_plugin)
|
||||
{
|
||||
filename = strdup (ptr_plugin->filename);
|
||||
if (filename)
|
||||
{
|
||||
plugin_unload (ptr_plugin);
|
||||
gui_chat_printf (NULL,
|
||||
_("%sPlugin \"%s\" unloaded.\n"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_INFO],
|
||||
name);
|
||||
plugin_load (filename);
|
||||
free (filename);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gui_chat_printf (NULL,
|
||||
_("%s%s plugin \"%s\" not found\n"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
WEECHAT_ERROR, name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_init: init plugin support
|
||||
*/
|
||||
|
||||
void
|
||||
plugin_init (int auto_load)
|
||||
{
|
||||
/* read plugins options on disk */
|
||||
plugin_config_read ();
|
||||
|
||||
/* auto-load plugins if asked */
|
||||
if (auto_load)
|
||||
plugin_auto_load ();
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_end: end plugin support
|
||||
*/
|
||||
|
||||
void
|
||||
plugin_end ()
|
||||
{
|
||||
/* write plugins config options */
|
||||
plugin_config_write ();
|
||||
|
||||
/* unload all plugins */
|
||||
plugin_unload_all ();
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_print_log: print plugin infos in log (usually for crash dump)
|
||||
*/
|
||||
|
||||
void
|
||||
plugin_print_log ()
|
||||
{
|
||||
struct t_weechat_plugin *ptr_plugin;
|
||||
|
||||
for (ptr_plugin = weechat_plugins; ptr_plugin;
|
||||
ptr_plugin = ptr_plugin->next_plugin)
|
||||
{
|
||||
weechat_log_printf ("\n");
|
||||
weechat_log_printf ("[plugin (addr:0x%X)]\n", ptr_plugin);
|
||||
weechat_log_printf (" filename . . . . . . . : '%s'\n", ptr_plugin->filename);
|
||||
weechat_log_printf (" handle . . . . . . . . : 0x%X\n", ptr_plugin->handle);
|
||||
weechat_log_printf (" name . . . . . . . . . : '%s'\n", ptr_plugin->name);
|
||||
weechat_log_printf (" description. . . . . . : '%s'\n", ptr_plugin->description);
|
||||
weechat_log_printf (" version. . . . . . . . : '%s'\n", ptr_plugin->version);
|
||||
weechat_log_printf (" charset. . . . . . . . : '%s'\n", ptr_plugin->charset);
|
||||
weechat_log_printf (" prev_plugin. . . . . . : 0x%X\n", ptr_plugin->prev_plugin);
|
||||
weechat_log_printf (" next_plugin. . . . . . : 0x%X\n", ptr_plugin->next_plugin);
|
||||
}
|
||||
|
||||
plugin_list_print_log ();
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2007 by FlashCode <flashcode@flashtux.org>
|
||||
* See README for License detail, AUTHORS for developers list.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __WEECHAT_PLUGIN_H
|
||||
#define __WEECHAT_PLUGIN_H 1
|
||||
|
||||
#include "weechat-plugin.h"
|
||||
|
||||
typedef int (t_weechat_init_func) (struct t_weechat_plugin *);
|
||||
typedef void (t_weechat_end_func) (struct t_weechat_plugin *);
|
||||
|
||||
extern struct t_weechat_plugin *weechat_plugins;
|
||||
extern struct t_weechat_plugin *last_weechat_plugin;
|
||||
|
||||
//extern t_plugin_irc_color plugins_irc_colors[GUI_NUM_IRC_COLORS];
|
||||
|
||||
extern void plugin_exec_on_files (struct t_weechat_plugin *, char *,
|
||||
int (*)(struct t_weechat_plugin *, char *));
|
||||
extern struct t_weechat_plugin *plugin_search (char *);
|
||||
extern struct t_weechat_plugin *plugin_load (char *);
|
||||
extern void plugin_auto_load ();
|
||||
extern void plugin_remove (struct t_weechat_plugin *);
|
||||
extern void plugin_unload (struct t_weechat_plugin *);
|
||||
extern void plugin_unload_name (char *);
|
||||
extern void plugin_unload_all ();
|
||||
extern void plugin_reload_name (char *);
|
||||
extern void plugin_init (int);
|
||||
extern void plugin_end ();
|
||||
extern void plugin_print_log ();
|
||||
|
||||
#endif /* plugin.h */
|
||||
@@ -1,388 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2007 by FlashCode <flashcode@flashtux.org>
|
||||
* See README for License detail, AUTHORS for developers list.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* plugins-config.c: plugins configuration */
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "../common/weechat.h"
|
||||
#include "weechat-plugin.h"
|
||||
#include "plugins-config.h"
|
||||
#include "../common/util.h"
|
||||
#include "../protocols/irc/irc.h"
|
||||
|
||||
|
||||
t_plugin_option *plugin_options = NULL;
|
||||
t_plugin_option *last_plugin_option = NULL;
|
||||
|
||||
|
||||
/*
|
||||
* plugin_config_search_internal: search a plugin option (internal function)
|
||||
* This function should not be called directly.
|
||||
*/
|
||||
|
||||
t_plugin_option *
|
||||
plugin_config_search_internal (char *option)
|
||||
{
|
||||
t_plugin_option *ptr_plugin_option;
|
||||
|
||||
for (ptr_plugin_option = plugin_options; ptr_plugin_option;
|
||||
ptr_plugin_option = ptr_plugin_option->next_option)
|
||||
{
|
||||
if (ascii_strcasecmp (ptr_plugin_option->name, option) == 0)
|
||||
{
|
||||
return ptr_plugin_option;
|
||||
}
|
||||
}
|
||||
|
||||
/* plugin option not found */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_config_search: search a plugin option
|
||||
*/
|
||||
|
||||
t_plugin_option *
|
||||
plugin_config_search (t_weechat_plugin *plugin, char *option)
|
||||
{
|
||||
char *internal_option;
|
||||
t_plugin_option *ptr_plugin_option;
|
||||
|
||||
internal_option = (char *)malloc (strlen (plugin->name) +
|
||||
strlen (option) + 2);
|
||||
if (!internal_option)
|
||||
return NULL;
|
||||
|
||||
strcpy (internal_option, plugin->name);
|
||||
strcat (internal_option, ".");
|
||||
strcat (internal_option, option);
|
||||
|
||||
ptr_plugin_option = plugin_config_search_internal (internal_option);
|
||||
|
||||
free (internal_option);
|
||||
|
||||
return ptr_plugin_option;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_config_find_pos: find position for a plugin option (for sorting options)
|
||||
*/
|
||||
|
||||
t_plugin_option *
|
||||
plugin_config_find_pos (char *name)
|
||||
{
|
||||
t_plugin_option *ptr_option;
|
||||
|
||||
for (ptr_option = plugin_options; ptr_option;
|
||||
ptr_option = ptr_option->next_option)
|
||||
{
|
||||
if (ascii_strcasecmp (name, ptr_option->name) < 0)
|
||||
return ptr_option;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_config_set_internal: set value for a plugin option (internal function)
|
||||
* This function should not be called directly.
|
||||
*/
|
||||
|
||||
int
|
||||
plugin_config_set_internal (char *option, char *value)
|
||||
{
|
||||
t_plugin_option *ptr_plugin_option, *pos_option;
|
||||
|
||||
ptr_plugin_option = plugin_config_search_internal (option);
|
||||
if (ptr_plugin_option)
|
||||
{
|
||||
if (!value || !value[0])
|
||||
{
|
||||
/* remove option from list */
|
||||
if (ptr_plugin_option->prev_option)
|
||||
(ptr_plugin_option->prev_option)->next_option =
|
||||
ptr_plugin_option->next_option;
|
||||
else
|
||||
plugin_options = ptr_plugin_option->next_option;
|
||||
if (ptr_plugin_option->next_option)
|
||||
(ptr_plugin_option->next_option)->prev_option =
|
||||
ptr_plugin_option->prev_option;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* replace old value by new one */
|
||||
if (ptr_plugin_option->value)
|
||||
free (ptr_plugin_option->value);
|
||||
ptr_plugin_option->value = strdup (value);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value && value[0])
|
||||
{
|
||||
ptr_plugin_option = (t_plugin_option *)malloc (sizeof (t_plugin_option));
|
||||
if (ptr_plugin_option)
|
||||
{
|
||||
/* create new option */
|
||||
ptr_plugin_option->name = strdup (option);
|
||||
ascii_tolower (ptr_plugin_option->name);
|
||||
ptr_plugin_option->value = strdup (value);
|
||||
|
||||
if (plugin_options)
|
||||
{
|
||||
pos_option = plugin_config_find_pos (ptr_plugin_option->name);
|
||||
if (pos_option)
|
||||
{
|
||||
/* insert option into the list (before option found) */
|
||||
ptr_plugin_option->prev_option = pos_option->prev_option;
|
||||
ptr_plugin_option->next_option = pos_option;
|
||||
if (pos_option->prev_option)
|
||||
pos_option->prev_option->next_option = ptr_plugin_option;
|
||||
else
|
||||
plugin_options = ptr_plugin_option;
|
||||
pos_option->prev_option = ptr_plugin_option;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* add option to the end */
|
||||
ptr_plugin_option->prev_option = last_plugin_option;
|
||||
ptr_plugin_option->next_option = NULL;
|
||||
last_plugin_option->next_option = ptr_plugin_option;
|
||||
last_plugin_option = ptr_plugin_option;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr_plugin_option->prev_option = NULL;
|
||||
ptr_plugin_option->next_option = NULL;
|
||||
plugin_options = ptr_plugin_option;
|
||||
last_plugin_option = ptr_plugin_option;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* failed to set plugin option */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_config_set: set value for a plugin option (create it if not found)
|
||||
*/
|
||||
|
||||
int
|
||||
plugin_config_set (t_weechat_plugin *plugin, char *option, char *value)
|
||||
{
|
||||
char *internal_option;
|
||||
int return_code;
|
||||
|
||||
internal_option = (char *)malloc (strlen (plugin->name) +
|
||||
strlen (option) + 2);
|
||||
if (!internal_option)
|
||||
return 0;
|
||||
|
||||
strcpy (internal_option, plugin->name);
|
||||
strcat (internal_option, ".");
|
||||
strcat (internal_option, option);
|
||||
|
||||
return_code = plugin_config_set_internal (internal_option, value);
|
||||
free (internal_option);
|
||||
|
||||
return return_code;
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_config_read: read WeeChat plugins configuration
|
||||
*/
|
||||
|
||||
void
|
||||
plugin_config_read ()
|
||||
{
|
||||
int filename_length;
|
||||
char *filename;
|
||||
FILE *file;
|
||||
int line_number;
|
||||
char line[1024], *ptr_line, *ptr_line2, *pos, *pos2;
|
||||
|
||||
filename_length = strlen (weechat_home) +
|
||||
strlen (WEECHAT_PLUGINS_CONFIG_NAME) + 2;
|
||||
filename =
|
||||
(char *) malloc (filename_length * sizeof (char));
|
||||
if (!filename)
|
||||
return;
|
||||
snprintf (filename, filename_length, "%s%s" WEECHAT_PLUGINS_CONFIG_NAME,
|
||||
weechat_home, DIR_SEPARATOR);
|
||||
if ((file = fopen (filename, "r")) == NULL)
|
||||
return;
|
||||
|
||||
line_number = 0;
|
||||
while (!feof (file))
|
||||
{
|
||||
ptr_line = fgets (line, sizeof (line) - 1, file);
|
||||
line_number++;
|
||||
if (ptr_line)
|
||||
{
|
||||
/* encode line to internal charset */
|
||||
ptr_line2 = weechat_iconv_to_internal (NULL, ptr_line);
|
||||
if (ptr_line2)
|
||||
{
|
||||
snprintf (line, sizeof (line) - 1, "%s", ptr_line2);
|
||||
free (ptr_line2);
|
||||
}
|
||||
|
||||
/* skip spaces */
|
||||
while (ptr_line[0] == ' ')
|
||||
ptr_line++;
|
||||
/* not a comment and not an empty line */
|
||||
if ((ptr_line[0] != '#') && (ptr_line[0] != '\r')
|
||||
&& (ptr_line[0] != '\n'))
|
||||
{
|
||||
pos = strchr (line, '=');
|
||||
if (pos == NULL)
|
||||
{
|
||||
irc_display_prefix (NULL, NULL, GUI_PREFIX_ERROR);
|
||||
gui_printf (NULL,
|
||||
_("%s %s, line %d: invalid syntax, missing \"=\"\n"),
|
||||
WEECHAT_WARNING, filename, line_number);
|
||||
}
|
||||
else
|
||||
{
|
||||
pos[0] = '\0';
|
||||
pos++;
|
||||
|
||||
/* remove spaces before '=' */
|
||||
pos2 = pos - 2;
|
||||
while ((pos2 > line) && (pos2[0] == ' '))
|
||||
{
|
||||
pos2[0] = '\0';
|
||||
pos2--;
|
||||
}
|
||||
|
||||
/* skip spaces after '=' */
|
||||
while (pos[0] && (pos[0] == ' '))
|
||||
{
|
||||
pos++;
|
||||
}
|
||||
|
||||
/* remove CR/LF */
|
||||
pos2 = strchr (pos, '\r');
|
||||
if (pos2 != NULL)
|
||||
pos2[0] = '\0';
|
||||
pos2 = strchr (pos, '\n');
|
||||
if (pos2 != NULL)
|
||||
pos2[0] = '\0';
|
||||
|
||||
/* remove simple or double quotes
|
||||
and spaces at the end */
|
||||
if (strlen(pos) > 1)
|
||||
{
|
||||
pos2 = pos + strlen (pos) - 1;
|
||||
while ((pos2 > pos) && (pos2[0] == ' '))
|
||||
{
|
||||
pos2[0] = '\0';
|
||||
pos2--;
|
||||
}
|
||||
pos2 = pos + strlen (pos) - 1;
|
||||
if (((pos[0] == '\'') &&
|
||||
(pos2[0] == '\'')) ||
|
||||
((pos[0] == '"') &&
|
||||
(pos2[0] == '"')))
|
||||
{
|
||||
pos2[0] = '\0';
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
plugin_config_set_internal (ptr_line, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose (file);
|
||||
free (filename);
|
||||
}
|
||||
|
||||
/*
|
||||
* plugin_config_write: write WeeChat configurtion
|
||||
* return: 0 if ok
|
||||
* < 0 if error
|
||||
*/
|
||||
|
||||
int
|
||||
plugin_config_write ()
|
||||
{
|
||||
int filename_length;
|
||||
char *filename;
|
||||
FILE *file;
|
||||
time_t current_time;
|
||||
t_plugin_option *ptr_plugin_option;
|
||||
|
||||
filename_length = strlen (weechat_home) +
|
||||
strlen (WEECHAT_PLUGINS_CONFIG_NAME) + 2;
|
||||
filename =
|
||||
(char *) malloc (filename_length * sizeof (char));
|
||||
if (!filename)
|
||||
return -2;
|
||||
snprintf (filename, filename_length, "%s%s" WEECHAT_PLUGINS_CONFIG_NAME,
|
||||
weechat_home, DIR_SEPARATOR);
|
||||
|
||||
if ((file = fopen (filename, "w")) == NULL)
|
||||
{
|
||||
irc_display_prefix (NULL, NULL, GUI_PREFIX_ERROR);
|
||||
gui_printf (NULL, _("%s cannot create file \"%s\"\n"),
|
||||
WEECHAT_ERROR, filename);
|
||||
free (filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
current_time = time (NULL);
|
||||
weechat_iconv_fprintf (file, _("#\n# %s plugins configuration file, created by "
|
||||
"%s v%s on %s"),
|
||||
PACKAGE_NAME, PACKAGE_NAME, PACKAGE_VERSION,
|
||||
ctime (¤t_time));
|
||||
weechat_iconv_fprintf (file, _("# WARNING! Be careful when editing this file, "
|
||||
"WeeChat writes this file when options are updated.\n#\n"));
|
||||
|
||||
for (ptr_plugin_option = plugin_options; ptr_plugin_option;
|
||||
ptr_plugin_option = ptr_plugin_option->next_option)
|
||||
{
|
||||
weechat_iconv_fprintf (file, "%s = \"%s\"\n",
|
||||
ptr_plugin_option->name,
|
||||
ptr_plugin_option->value);
|
||||
}
|
||||
|
||||
fclose (file);
|
||||
chmod (filename, 0600);
|
||||
free (filename);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2007 by FlashCode <flashcode@flashtux.org>
|
||||
* See README for License detail, AUTHORS for developers list.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __WEECHAT_PLUGINS_CONFIG_H
|
||||
#define __WEECHAT_PLUGINS_CONFIG_H 1
|
||||
|
||||
#define WEECHAT_PLUGINS_CONFIG_NAME "plugins.rc"
|
||||
|
||||
typedef struct t_plugin_option t_plugin_option;
|
||||
|
||||
struct t_plugin_option
|
||||
{
|
||||
char *name; /* option name in config file */
|
||||
char *value; /* value of option */
|
||||
t_plugin_option *prev_option; /* link to previous option */
|
||||
t_plugin_option *next_option; /* link to next option */
|
||||
};
|
||||
|
||||
extern t_plugin_option *plugin_options;
|
||||
|
||||
extern t_plugin_option *plugin_config_search_internal (char *);
|
||||
extern t_plugin_option *plugin_config_search (t_weechat_plugin *, char *);
|
||||
extern int plugin_config_set_internal (char *, char *);
|
||||
extern int plugin_config_set (t_weechat_plugin *, char *, char *);
|
||||
extern void plugin_config_read ();
|
||||
extern int plugin_config_write ();
|
||||
|
||||
#endif /* plugins-config.h */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2007 by FlashCode <flashcode@flashtux.org>
|
||||
* See README for License detail, AUTHORS for developers list.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __WEECHAT_PLUGINS_H
|
||||
#define __WEECHAT_PLUGINS_H 1
|
||||
|
||||
#include "weechat-plugin.h"
|
||||
#include "plugins-config.h"
|
||||
#include "../protocols/irc/irc.h"
|
||||
#include "../gui/gui.h"
|
||||
|
||||
typedef struct t_plugin_irc_color t_plugin_irc_color;
|
||||
|
||||
struct t_plugin_irc_color
|
||||
{
|
||||
int number;
|
||||
char *name;
|
||||
};
|
||||
|
||||
typedef int (t_weechat_init_func) (t_weechat_plugin *);
|
||||
typedef void (t_weechat_end_func) (t_weechat_plugin *);
|
||||
|
||||
extern t_weechat_plugin *weechat_plugins;
|
||||
extern t_weechat_plugin *last_weechat_plugin;
|
||||
|
||||
extern t_plugin_irc_color plugins_irc_colors[GUI_NUM_IRC_COLORS];
|
||||
|
||||
extern int plugin_find_server_channel (char *, char *,
|
||||
t_irc_server **, t_irc_channel **);
|
||||
extern void plugin_exec_on_files (t_weechat_plugin *, char *,
|
||||
int (*)(t_weechat_plugin *, char *));
|
||||
extern t_weechat_plugin *plugin_search (char *);
|
||||
extern t_plugin_handler *plugin_msg_handler_add (t_weechat_plugin *, char *,
|
||||
t_plugin_handler_func *,
|
||||
char *, void *);
|
||||
extern t_plugin_handler *plugin_cmd_handler_add (t_weechat_plugin *, char *,
|
||||
char *, char *, char *,
|
||||
char *,
|
||||
t_plugin_handler_func *,
|
||||
char *, void *);
|
||||
extern t_plugin_handler *plugin_timer_handler_add (t_weechat_plugin *, int,
|
||||
t_plugin_handler_func *,
|
||||
char *, void *);
|
||||
extern t_plugin_handler *plugin_keyboard_handler_add (t_weechat_plugin *,
|
||||
t_plugin_handler_func *,
|
||||
char *, void *);
|
||||
extern t_plugin_handler *plugin_event_handler_add (t_weechat_plugin *, char *,
|
||||
t_plugin_handler_func *,
|
||||
char *, void *);
|
||||
extern int plugin_msg_handler_exec (char *, char *, char *);
|
||||
extern int plugin_cmd_handler_exec (char *, char *, char *);
|
||||
extern int plugin_timer_handler_exec ();
|
||||
extern int plugin_keyboard_handler_exec (char *, char *, char *);
|
||||
extern int plugin_event_handler_exec (char *, int, char **);
|
||||
extern void plugin_handler_remove (t_weechat_plugin *,
|
||||
t_plugin_handler *);
|
||||
extern void plugin_handler_remove_all (t_weechat_plugin *);
|
||||
extern t_plugin_modifier *plugin_modifier_add (t_weechat_plugin *,
|
||||
char *, char *,
|
||||
t_plugin_modifier_func *,
|
||||
char *, void *);
|
||||
extern char *plugin_modifier_exec (t_plugin_modifier_type, char *, char *);
|
||||
extern void plugin_modifier_remove (t_weechat_plugin *,
|
||||
t_plugin_modifier *);
|
||||
extern void plugin_modifier_remove_all (t_weechat_plugin *);
|
||||
extern t_weechat_plugin *plugin_load (char *);
|
||||
extern void plugin_auto_load ();
|
||||
extern void plugin_remove (t_weechat_plugin *);
|
||||
extern void plugin_unload (t_weechat_plugin *);
|
||||
extern void plugin_unload_name (char *);
|
||||
extern void plugin_unload_all ();
|
||||
extern void plugin_reload_name (char *);
|
||||
extern void plugin_init (int);
|
||||
extern void plugin_end ();
|
||||
extern void plugin_print_log (t_weechat_plugin *);
|
||||
|
||||
#endif /* plugins.h */
|
||||
+145
-399
@@ -24,431 +24,177 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
/* return codes for init function and handlers */
|
||||
#define PLUGIN_RC_KO -1 /* function/handler failed */
|
||||
#define PLUGIN_RC_OK 0 /* function/handler ok */
|
||||
#define PLUGIN_RC_FAILED -1 /* function/handler failed */
|
||||
#define PLUGIN_RC_SUCCESS 0 /* function/handler ok */
|
||||
|
||||
/* return codes specific to message handlers: messages can be discarded for
|
||||
WeeChat, for plugins, or both */
|
||||
#define PLUGIN_RC_OK_IGNORE_WEECHAT 1 /* ignore WeeChat for this message */
|
||||
#define PLUGIN_RC_OK_IGNORE_PLUGINS 2 /* ignore other plugins for this msg*/
|
||||
#define PLUGIN_RC_OK_IGNORE_ALL (PLUGIN_RC_OK_IGNORE_WEECHAT \
|
||||
| PLUGIN_RC_OK_IGNORE_PLUGINS)
|
||||
/* ignore WeeChat and other plugins */
|
||||
#define PLUGIN_RC_OK_WITH_HIGHLIGHT 4 /* ok and ask for highlight */
|
||||
/* (for message handler only) */
|
||||
|
||||
#define WEECHAT_IRC_COLOR_WHITE 0
|
||||
#define WEECHAT_IRC_COLOR_BLACK 1
|
||||
#define WEECHAT_IRC_COLOR_BLUE 2
|
||||
#define WEECHAT_IRC_COLOR_GREEN 3
|
||||
#define WEECHAT_IRC_COLOR_LIGHTRED 4
|
||||
#define WEECHAT_IRC_COLOR_RED 5
|
||||
#define WEECHAT_IRC_COLOR_MAGENTA 6
|
||||
#define WEECHAT_IRC_COLOR_BROWN 7
|
||||
#define WEECHAT_IRC_COLOR_YELLOW 8
|
||||
#define WEECHAT_IRC_COLOR_LIGHTGREEN 9
|
||||
#define WEECHAT_IRC_COLOR_CYAN 10
|
||||
#define WEECHAT_IRC_COLOR_LIGHTCYAN 11
|
||||
#define WEECHAT_IRC_COLOR_LIGHTBLUE 12
|
||||
#define WEECHAT_IRC_COLOR_LIGHTMAGENTA 13
|
||||
#define WEECHAT_IRC_COLOR_GRAY 14
|
||||
#define WEECHAT_IRC_COLOR_LIGHTGRAY 15
|
||||
|
||||
typedef struct t_plugin_dcc_info t_plugin_dcc_info;
|
||||
|
||||
struct t_plugin_dcc_info
|
||||
{
|
||||
char *server; /* irc server */
|
||||
char *channel; /* irc channel (for DCC chat only) */
|
||||
int type; /* DCC type (send or receive) */
|
||||
int status; /* DCC status (waiting, sending, ..) */
|
||||
time_t start_time; /* the time when DCC started */
|
||||
time_t start_transfer; /* the time when DCC transfer started */
|
||||
unsigned long addr; /* IP address */
|
||||
int port; /* port */
|
||||
char *nick; /* remote nick */
|
||||
char *filename; /* filename (given by sender) */
|
||||
char *local_filename; /* local filename (with path) */
|
||||
int filename_suffix; /* suffix (.1 for ex) if renaming file */
|
||||
unsigned long size; /* file size */
|
||||
unsigned long pos; /* number of bytes received/sent */
|
||||
unsigned long start_resume; /* start of resume (in bytes) */
|
||||
unsigned long bytes_per_sec; /* bytes per second */
|
||||
t_plugin_dcc_info *prev_dcc; /* link to previous dcc file/chat */
|
||||
t_plugin_dcc_info *next_dcc; /* link to next dcc file/chat */
|
||||
};
|
||||
|
||||
typedef struct t_plugin_server_info t_plugin_server_info;
|
||||
|
||||
struct t_plugin_server_info
|
||||
{
|
||||
char *name; /* name of server (only for display) */
|
||||
int autoconnect; /* = 1 if auto connect at startup */
|
||||
int autoreconnect; /* = 1 if auto reco when disconnected */
|
||||
int autoreconnect_delay; /* delay before trying again reconnect */
|
||||
int temp_server; /* server was given on command line */
|
||||
char *address; /* address of server (IP or name) */
|
||||
int port; /* port for server (6667 by default) */
|
||||
int ipv6; /* use IPv6 protocol */
|
||||
int ssl; /* SSL protocol */
|
||||
char *password; /* password for server */
|
||||
char *nick1; /* first nickname for the server */
|
||||
char *nick2; /* alternate nickname */
|
||||
char *nick3; /* 2nd alternate nickname */
|
||||
char *username; /* user name */
|
||||
char *realname; /* real name */
|
||||
char *command; /* command to run once connected */
|
||||
int command_delay; /* delay after execution of command */
|
||||
char *autojoin; /* channels to automatically join */
|
||||
int autorejoin; /* auto rejoin channels when kicked */
|
||||
char *notify_levels; /* channels notify levels */
|
||||
int is_connected; /* 1 if WeeChat is connected to server */
|
||||
int ssl_connected; /* = 1 if connected with SSL */
|
||||
char *nick; /* current nickname */
|
||||
char *nick_modes; /* nick modes */
|
||||
int is_away; /* 1 is user is marker as away */
|
||||
time_t away_time; /* time() when user marking as away */
|
||||
int lag; /* lag (in milliseconds) */
|
||||
t_plugin_server_info *prev_server; /* link to previous server info */
|
||||
t_plugin_server_info *next_server; /* link to next server info */
|
||||
};
|
||||
|
||||
typedef struct t_plugin_channel_info t_plugin_channel_info;
|
||||
|
||||
struct t_plugin_channel_info
|
||||
{
|
||||
int type; /* channel type */
|
||||
char *name; /* name of channel (exemple: "#abc") */
|
||||
char *topic; /* topic of channel (host for private) */
|
||||
char *modes; /* channel modes */
|
||||
int limit; /* user limit (0 is limit not set) */
|
||||
char *key; /* channel key (NULL if no key is set) */
|
||||
int nicks_count; /* # nicks on channel (0 if dcc/pv) */
|
||||
t_plugin_channel_info *prev_channel; /* link to previous channel info */
|
||||
t_plugin_channel_info *next_channel; /* link to next channel info */
|
||||
};
|
||||
|
||||
typedef struct t_plugin_nick_info t_plugin_nick_info;
|
||||
|
||||
struct t_plugin_nick_info
|
||||
{
|
||||
char *nick; /* nickname */
|
||||
int flags; /* chanowner/chanadmin (unrealircd), */
|
||||
char *host; /* hostname */
|
||||
/* op, halfop, voice, away */
|
||||
t_plugin_nick_info *prev_nick; /* link to previous nick */
|
||||
t_plugin_nick_info *next_nick; /* link to next nick */
|
||||
};
|
||||
|
||||
typedef struct t_plugin_window_info t_plugin_window_info;
|
||||
|
||||
struct t_plugin_window_info
|
||||
{
|
||||
int win_x, win_y; /* position of window */
|
||||
int win_width, win_height; /* window geometry */
|
||||
int win_width_pct; /* % of width (compared to parent win) */
|
||||
int win_height_pct; /* % of height (compared to parent win) */
|
||||
int num_buffer; /* # of displayed buffer */
|
||||
t_plugin_window_info *prev_window; /* link to previous window */
|
||||
t_plugin_window_info *next_window; /* link to next window */
|
||||
};
|
||||
|
||||
typedef struct t_plugin_buffer_info t_plugin_buffer_info;
|
||||
|
||||
struct t_plugin_buffer_info
|
||||
{
|
||||
int type; /* buffer type (0=standard,1=dcc,2=raw) */
|
||||
int number; /* buffer number */
|
||||
int num_displayed; /* number of windows displaying buffer */
|
||||
char *server_name; /* server name for buffer (may be NULL) */
|
||||
char *channel_name; /* channel name for buffer (may be NULL)*/
|
||||
int notify_level; /* notify level for buffer */
|
||||
char *log_filename; /* log filename (NULL is disabled) */
|
||||
t_plugin_buffer_info *prev_buffer; /* link to previous buffer */
|
||||
t_plugin_buffer_info *next_buffer; /* link to next buffer */
|
||||
};
|
||||
|
||||
typedef struct t_plugin_buffer_line t_plugin_buffer_line;
|
||||
|
||||
struct t_plugin_buffer_line
|
||||
{
|
||||
time_t date; /* date */
|
||||
char *nick; /* nick */
|
||||
char *data; /* line data */
|
||||
t_plugin_buffer_line *prev_line; /* link to previous line */
|
||||
t_plugin_buffer_line *next_line; /* link to next line */
|
||||
};
|
||||
|
||||
typedef struct t_weechat_plugin t_weechat_plugin;
|
||||
|
||||
/* handlers */
|
||||
|
||||
typedef int (t_plugin_handler_func) (t_weechat_plugin *, int, char **, char *, void *);
|
||||
|
||||
typedef enum t_plugin_handler_type t_plugin_handler_type;
|
||||
|
||||
enum t_plugin_handler_type
|
||||
{
|
||||
PLUGIN_HANDLER_MESSAGE = 0, /* IRC message handler */
|
||||
PLUGIN_HANDLER_COMMAND, /* command handler */
|
||||
PLUGIN_HANDLER_TIMER, /* timer handler */
|
||||
PLUGIN_HANDLER_KEYBOARD, /* keyboard handler */
|
||||
PLUGIN_HANDLER_EVENT /* event handler */
|
||||
};
|
||||
|
||||
typedef struct t_plugin_handler t_plugin_handler;
|
||||
|
||||
struct t_plugin_handler
|
||||
{
|
||||
t_plugin_handler_type type; /* handler type */
|
||||
|
||||
/* data for message handler */
|
||||
char *irc_command; /* name of IRC command (PRIVMSG, ..) */
|
||||
|
||||
/* data for command handler */
|
||||
char *command; /* name of command (without first '/') */
|
||||
char *description; /* (for /help) short cmd description */
|
||||
char *arguments; /* (for /help) command arguments */
|
||||
char *arguments_description; /* (for /help) args long description */
|
||||
char *completion_template; /* template for completion */
|
||||
|
||||
/* data for timer handler */
|
||||
int interval; /* interval between two calls to fct */
|
||||
int remaining; /* seconds remaining before next call */
|
||||
|
||||
/* data for event handler */
|
||||
char *event; /* event to catch */
|
||||
|
||||
/* data common to all handlers */
|
||||
t_plugin_handler_func *handler; /* pointer to handler */
|
||||
char *handler_args; /* arguments sent to handler */
|
||||
void *handler_pointer; /* pointer sent to handler */
|
||||
|
||||
/* for internal use */
|
||||
int running; /* 1 if currently running */
|
||||
/* (used to prevent circular call) */
|
||||
t_plugin_handler *prev_handler; /* link to previous handler */
|
||||
t_plugin_handler *next_handler; /* link to next handler */
|
||||
};
|
||||
|
||||
/* modifiers */
|
||||
|
||||
typedef char * (t_plugin_modifier_func) (t_weechat_plugin *, int, char **, char *, void *);
|
||||
|
||||
typedef enum t_plugin_modifier_type t_plugin_modifier_type;
|
||||
|
||||
enum t_plugin_modifier_type
|
||||
{
|
||||
PLUGIN_MODIFIER_IRC_IN = 0, /* incoming IRC msg (server > user) */
|
||||
PLUGIN_MODIFIER_IRC_USER, /* outgoing IRC msg (user > server) */
|
||||
/* after user input (before 'out' mod.) */
|
||||
PLUGIN_MODIFIER_IRC_OUT /* outgoing IRC msg (user > server) */
|
||||
/* immediately before sending to server */
|
||||
};
|
||||
|
||||
#define PLUGIN_MODIFIER_IRC_IN_STR "irc_in"
|
||||
#define PLUGIN_MODIFIER_IRC_USER_STR "irc_user"
|
||||
#define PLUGIN_MODIFIER_IRC_OUT_STR "irc_out"
|
||||
|
||||
typedef struct t_plugin_modifier t_plugin_modifier;
|
||||
|
||||
struct t_plugin_modifier
|
||||
{
|
||||
t_plugin_modifier_type type; /* modifier type */
|
||||
|
||||
/* data for IRC modifier */
|
||||
char *command; /* IRC command */
|
||||
|
||||
/* data common to all modifiers */
|
||||
t_plugin_modifier_func *modifier; /* pointer to modifier */
|
||||
char *modifier_args; /* arguments sent to modifier */
|
||||
void *modifier_pointer; /* pointer sent to modifier */
|
||||
|
||||
/* for internal use */
|
||||
int running; /* 1 if currently running */
|
||||
/* (used to prevent circular call) */
|
||||
t_plugin_modifier *prev_modifier; /* link to previous modifier */
|
||||
t_plugin_modifier *next_modifier; /* link to next modifier */
|
||||
};
|
||||
|
||||
/* plugin, a WeeChat plugin, which is a dynamic library */
|
||||
#define PLUGIN_RC_IGNORE_WEECHAT 1 /* ignore WeeChat for this message */
|
||||
#define PLUGIN_RC_IGNORE_PLUGINS 2 /* ignore other plugins for msg */
|
||||
#define PLUGIN_RC_IGNORE_ALL (PLUGIN_RC_OK_IGNORE_WEECHAT \
|
||||
| PLUGIN_RC_OK_IGNORE_PLUGINS)
|
||||
/* ignore WeeChat and other plugins*/
|
||||
#define PLUGIN_RC_WITH_HIGHLIGHT 4 /* ok and ask for highlight */
|
||||
/* (for message handler only) */
|
||||
|
||||
struct t_weechat_plugin
|
||||
{
|
||||
/* plugin variables */
|
||||
char *filename; /* name of plugin on disk */
|
||||
void *handle; /* handle of plugin (given by dlopen) */
|
||||
char *name; /* plugin name */
|
||||
char *description; /* plugin description */
|
||||
char *version; /* plugin version */
|
||||
char *charset; /* charset used by plugin */
|
||||
|
||||
/* plugin handlers */
|
||||
t_plugin_handler *handlers; /* pointer to first handler */
|
||||
t_plugin_handler *last_handler; /* pointer to last handler */
|
||||
|
||||
/* plugin modifiers */
|
||||
t_plugin_modifier *modifiers; /* pointer to first modifier */
|
||||
t_plugin_modifier *last_modifier; /* pointer to last modifier */
|
||||
|
||||
/* links to previous/next plugins */
|
||||
t_weechat_plugin *prev_plugin; /* link to previous plugin */
|
||||
t_weechat_plugin *next_plugin; /* link to next plugin */
|
||||
char *filename; /* name of plugin on disk */
|
||||
void *handle; /* handle of plugin (given by dlopen)*/
|
||||
char *name; /* plugin name */
|
||||
char *description; /* plugin description */
|
||||
char *version; /* plugin version */
|
||||
char *charset; /* charset used by plugin */
|
||||
struct t_weechat_plugin *prev_plugin; /* link to previous plugin */
|
||||
struct t_weechat_plugin *next_plugin; /* link to next plugin */
|
||||
|
||||
/* plugin functions (interface) */
|
||||
|
||||
/* IMPORTANT NOTE for WeeChat developers: always add new interface functions
|
||||
at the END of functions, for keeping backward compatibility with
|
||||
existing plugins */
|
||||
|
||||
int (*ascii_strcasecmp) (t_weechat_plugin *, char *, char *);
|
||||
int (*ascii_strncasecmp) (t_weechat_plugin *, char *, char *, int);
|
||||
char **(*explode_string) (t_weechat_plugin *, char *, char *, int, int *);
|
||||
void (*free_exploded_string) (t_weechat_plugin *, char **);
|
||||
int (*mkdir_home) (t_weechat_plugin *, char *);
|
||||
void (*exec_on_files) (t_weechat_plugin *, char *,
|
||||
int (*)(t_weechat_plugin *, char *));
|
||||
|
||||
void (*print) (t_weechat_plugin *, char *, char *, char *, ...);
|
||||
void (*print_server) (t_weechat_plugin *, char *, ...);
|
||||
void (*print_infobar) (t_weechat_plugin *, int, char *, ...);
|
||||
void (*infobar_remove) (t_weechat_plugin *, int);
|
||||
|
||||
t_plugin_handler *(*msg_handler_add) (t_weechat_plugin *, char *,
|
||||
t_plugin_handler_func *,
|
||||
char *, void *);
|
||||
t_plugin_handler *(*cmd_handler_add) (t_weechat_plugin *, char *,
|
||||
char *, char *, char *,
|
||||
char *,
|
||||
t_plugin_handler_func *,
|
||||
char *, void *);
|
||||
t_plugin_handler *(*timer_handler_add) (t_weechat_plugin *, int,
|
||||
t_plugin_handler_func *,
|
||||
char *, void *);
|
||||
t_plugin_handler *(*keyboard_handler_add) (t_weechat_plugin *,
|
||||
t_plugin_handler_func *,
|
||||
char *, void *);
|
||||
t_plugin_handler *(*event_handler_add) (t_weechat_plugin *, char *,
|
||||
t_plugin_handler_func *,
|
||||
char *, void *);
|
||||
void (*handler_remove) (t_weechat_plugin *, t_plugin_handler *);
|
||||
void (*handler_remove_all) (t_weechat_plugin *);
|
||||
|
||||
t_plugin_modifier *(*modifier_add) (t_weechat_plugin *, char *, char *,
|
||||
t_plugin_modifier_func *,
|
||||
char *, void *);
|
||||
void (*modifier_remove) (t_weechat_plugin *, t_plugin_modifier *);
|
||||
void (*modifier_remove_all) (t_weechat_plugin *);
|
||||
|
||||
void (*exec_command) (t_weechat_plugin *, char *, char *, char *);
|
||||
char *(*get_info) (t_weechat_plugin *, char *, char *);
|
||||
t_plugin_dcc_info *(*get_dcc_info) (t_weechat_plugin *);
|
||||
void (*free_dcc_info) (t_weechat_plugin *, t_plugin_dcc_info *);
|
||||
char *(*get_config) (t_weechat_plugin *, char *);
|
||||
int (*set_config) (t_weechat_plugin *, char *, char *);
|
||||
char *(*get_plugin_config) (t_weechat_plugin *, char *);
|
||||
int (*set_plugin_config) (t_weechat_plugin *, char *, char *);
|
||||
t_plugin_server_info *(*get_server_info) (t_weechat_plugin *);
|
||||
void (*free_server_info) (t_weechat_plugin *, t_plugin_server_info *);
|
||||
t_plugin_channel_info *(*get_channel_info) (t_weechat_plugin *, char *);
|
||||
void (*free_channel_info) (t_weechat_plugin *, t_plugin_channel_info *);
|
||||
t_plugin_nick_info *(*get_nick_info) (t_weechat_plugin *, char*, char*);
|
||||
void (*free_nick_info) (t_weechat_plugin *, t_plugin_nick_info *);
|
||||
|
||||
void (*log) (t_weechat_plugin *, char *, char *, char *, ...);
|
||||
|
||||
void (*input_color) (t_weechat_plugin *, int, int, int);
|
||||
/* strings */
|
||||
void (*charset_set) (struct t_weechat_plugin *, char *);
|
||||
char *(*iconv_to_internal) (struct t_weechat_plugin *, char *, char *);
|
||||
char *(*iconv_from_internal) (struct t_weechat_plugin *, char *, char *);
|
||||
char *(*gettext) (struct t_weechat_plugin *, char *);
|
||||
char *(*ngettext) (struct t_weechat_plugin *, char *, char *, int);
|
||||
int (*strcasecmp) (struct t_weechat_plugin *, char *, char *);
|
||||
int (*strncasecmp) (struct t_weechat_plugin *, char *, char *, int);
|
||||
char **(*explode_string) (struct t_weechat_plugin *, char *, char *, int,
|
||||
int *);
|
||||
void (*free_exploded_string) (struct t_weechat_plugin *, char **);
|
||||
|
||||
int (*get_irc_color) (t_weechat_plugin *, char *);
|
||||
/* directories */
|
||||
int (*mkdir_home) (struct t_weechat_plugin *, char *);
|
||||
void (*exec_on_files) (struct t_weechat_plugin *, char *,
|
||||
int (*)(char *));
|
||||
|
||||
t_plugin_window_info *(*get_window_info) (t_weechat_plugin *);
|
||||
void (*free_window_info) (t_weechat_plugin *, t_plugin_window_info *);
|
||||
t_plugin_buffer_info *(*get_buffer_info) (t_weechat_plugin *);
|
||||
void (*free_buffer_info) (t_weechat_plugin *, t_plugin_buffer_info *);
|
||||
t_plugin_buffer_line *(*get_buffer_data) (t_weechat_plugin *, char *, char *);
|
||||
void (*free_buffer_data) (t_weechat_plugin *, t_plugin_buffer_line *);
|
||||
/* display */
|
||||
void (*printf) (struct t_weechat_plugin *, void *, char *, ...);
|
||||
char *(*prefix) (struct t_weechat_plugin *, char *);
|
||||
char *(*color) (struct t_weechat_plugin *, char *);
|
||||
void (*print_infobar) (struct t_weechat_plugin *, int, char *, ...);
|
||||
void (*infobar_remove) (struct t_weechat_plugin *, int);
|
||||
|
||||
void (*set_charset) (t_weechat_plugin *, char *);
|
||||
char *(*iconv_to_internal) (t_weechat_plugin *, char *, char *);
|
||||
char *(*iconv_from_internal) (t_weechat_plugin *, char *, char *);
|
||||
/* hooks */
|
||||
struct t_hook *(*hook_command) (struct t_weechat_plugin *, char *, char *,
|
||||
char *, char *, char *,
|
||||
int (*)(void *, char *),void *);
|
||||
struct t_hook *(*hook_message) (struct t_weechat_plugin *, char *,
|
||||
int (*)(void *, char *), void *);
|
||||
struct t_hook *(*hook_config) (struct t_weechat_plugin *, char *, char *,
|
||||
int (*)(void *, char *, char *, char *),
|
||||
void *);
|
||||
struct t_hook *(*hook_timer) (struct t_weechat_plugin *, long, int,
|
||||
int (*)(void *), void *);
|
||||
struct t_hook *(*hook_fd) (struct t_weechat_plugin *, int, int, int, int,
|
||||
int (*)(void *), void *);
|
||||
void (*unhook) (struct t_weechat_plugin *, void *);
|
||||
void (*unhook_all) (struct t_weechat_plugin *);
|
||||
|
||||
/* buffers */
|
||||
struct t_gui_buffer *(*buffer_new) (struct t_weechat_plugin *,
|
||||
char *, char *);
|
||||
struct t_gui_buffer *(*buffer_search) (struct t_weechat_plugin *,
|
||||
char *, char *);
|
||||
void (*buffer_close) (struct t_weechat_plugin *, void *);
|
||||
void (*buffer_set) (struct t_weechat_plugin *, void *, char *, char *);
|
||||
void (*buffer_nick_add) (struct t_weechat_plugin *, void *, char *, int,
|
||||
char *, char, char *);
|
||||
void (*buffer_nick_remove) (struct t_weechat_plugin *, char *);
|
||||
|
||||
/* command */
|
||||
void (*command) (struct t_weechat_plugin *, void *, char *);
|
||||
|
||||
/* infos */
|
||||
char *(*info_get) (struct t_weechat_plugin *, char *);
|
||||
|
||||
/* lists */
|
||||
struct t_plugin_list *(*list_get) (struct t_weechat_plugin *, char *,
|
||||
void *);
|
||||
void (*list_free) (struct t_weechat_plugin *, void *);
|
||||
|
||||
|
||||
/* config */
|
||||
char *(*config_get) (struct t_weechat_plugin *, char *);
|
||||
int (*config_set) (struct t_weechat_plugin *, char *, char *);
|
||||
char *(*plugin_config_get) (struct t_weechat_plugin *, char *);
|
||||
int (*plugin_config_set) (struct t_weechat_plugin *, char *, char *);
|
||||
|
||||
/* log */
|
||||
void (*log) (struct t_weechat_plugin *, char *, char *, char *, ...);
|
||||
|
||||
/* WeeChat developers: ALWAYS add new functions at the end */
|
||||
};
|
||||
|
||||
/* general useful functions */
|
||||
extern int weechat_ascii_strcasecmp (t_weechat_plugin *,char *, char *);
|
||||
extern int weechat_ascii_strncasecmp (t_weechat_plugin *,char *, char *, int);
|
||||
extern char **weechat_explode_string (t_weechat_plugin *, char *, char *, int, int *);
|
||||
extern void weechat_free_exploded_string (t_weechat_plugin *, char **);
|
||||
extern int weechat_plugin_mkdir_home (t_weechat_plugin *, char *);
|
||||
extern void weechat_plugin_exec_on_files (t_weechat_plugin *, char *,
|
||||
int (*)(t_weechat_plugin *, char *));
|
||||
/* macros for easy call to plugin API */
|
||||
|
||||
/* display functions */
|
||||
extern void weechat_plugin_print (t_weechat_plugin *, char *, char *, char *, ...);
|
||||
extern void weechat_plugin_print_server (t_weechat_plugin *, char *, ...);
|
||||
extern void weechat_plugin_print_infobar (t_weechat_plugin *, int, char *, ...);
|
||||
extern void weechat_plugin_infobar_remove (t_weechat_plugin *, int);
|
||||
#ifndef __WEECHAT_H
|
||||
#define _(string) weechat_plugin->gettext(weechat_plugin, string)
|
||||
#define N_(string) (string)
|
||||
#define NG_(single,plural,number) \
|
||||
weechat_plugin->ngettext(weechat_plugin, single, plural, number)
|
||||
#endif
|
||||
#define weechat_strcasecmp(string1, string2) \
|
||||
weechat_plugin->strcasecmp(weechat_plugin, string1, string2)
|
||||
#define weechat_strncasecmp(string1, string2, max) \
|
||||
weechat_plugin->strncasecmp(weechat_plugin, string1, string2, max)
|
||||
|
||||
/* log functions */
|
||||
extern void weechat_plugin_log (t_weechat_plugin *, char *, char *, char *, ...);
|
||||
#define weechat_printf(buffer, argz...) \
|
||||
weechat_plugin->printf(weechat_plugin, buffer, ##argz)
|
||||
#define weechat_prefix(prefix_name) \
|
||||
weechat_plugin->prefix(weechat_plugin, prefix_name)
|
||||
#define weechat_color(color_name) \
|
||||
weechat_plugin->color(weechat_plugin, color_name)
|
||||
|
||||
/* handler functions */
|
||||
extern t_plugin_handler *weechat_plugin_msg_handler_add (t_weechat_plugin *, char *,
|
||||
t_plugin_handler_func *,
|
||||
char *, void *);
|
||||
extern t_plugin_handler *weechat_plugin_cmd_handler_add (t_weechat_plugin *, char *,
|
||||
char *, char *, char *,
|
||||
char *,
|
||||
t_plugin_handler_func *,
|
||||
char *, void *);
|
||||
extern t_plugin_handler *weechat_plugin_timer_handler_add (t_weechat_plugin *, int,
|
||||
t_plugin_handler_func *,
|
||||
char *, void *);
|
||||
extern t_plugin_handler *weechat_plugin_keyboard_handler_add (t_weechat_plugin *,
|
||||
t_plugin_handler_func *,
|
||||
char *, void *);
|
||||
extern t_plugin_handler *weechat_plugin_event_handler_add (t_weechat_plugin *, char *,
|
||||
t_plugin_handler_func *,
|
||||
char *, void *);
|
||||
extern void weechat_plugin_handler_remove (t_weechat_plugin *, t_plugin_handler *);
|
||||
extern void weechat_plugin_handler_remove_all (t_weechat_plugin *);
|
||||
#define weechat_hook_command(command, description, args, args_desc, \
|
||||
completion, callback, data) \
|
||||
weechat_plugin->hook_command(weechat_plugin, command, description, \
|
||||
args, args_desc, completion, callback, \
|
||||
data)
|
||||
#define weechat_hook_message(msg, callback, data) \
|
||||
weechat_plugin->hook_message(weechat_plugin, msg, callback, data)
|
||||
#define weechat_hook_config(type, option, callback, data) \
|
||||
weechat_plugin->hook_config(weechat_plugin, type, option, \
|
||||
callback, data)
|
||||
#define weechat_hook_timer(interval, max_calls, callback, data) \
|
||||
weechat_plugin->hook_timer(weechat_plugin, interval, max_calls, \
|
||||
callback, data)
|
||||
#define weechat_hook_fd(fd, flag_read, flag_write, flag_exception, \
|
||||
callback, data) \
|
||||
weechat_plugin->hook_fd(weechat_plugin, fd, flag_read, flag_write, \
|
||||
flag_exception, callback, data)
|
||||
#define weechat_unhook(hook) \
|
||||
weechat_plugin->unhook(weechat_plugin, hook)
|
||||
#define weechat_unhook_all() \
|
||||
weechat_plugin->unhook(weechat_plugin)
|
||||
|
||||
/* modifier functions */
|
||||
extern t_plugin_modifier *weechat_plugin_modifier_add (t_weechat_plugin *,
|
||||
char *, char *,
|
||||
t_plugin_modifier_func *,
|
||||
char *, void *);
|
||||
extern void weechat_plugin_modifier_remove (t_weechat_plugin *, t_plugin_modifier *);
|
||||
extern void weechat_plugin_modifier_remove_all (t_weechat_plugin *);
|
||||
#define weechat_buffer_new(category, name) \
|
||||
weechat_plugin->buffer_new(weechat_plugin, category, name)
|
||||
#define weechat_buffer_search(category, name) \
|
||||
weechat_plugin->buffer_search(weechat_plugin, category, name)
|
||||
#define weechat_buffer_close(ptr_buffer) \
|
||||
weechat_plugin->buffer_close(weechat_plugin, ptr_buffer)
|
||||
#define weechat_buffer_set(ptr_buffer, property, value) \
|
||||
weechat_plugin->buffer_set(weechat_plugin, ptr_buffer, \
|
||||
property, value)
|
||||
|
||||
/* other functions */
|
||||
extern void weechat_plugin_exec_command (t_weechat_plugin *, char *, char *, char *);
|
||||
extern char *weechat_plugin_get_info (t_weechat_plugin *, char *, char *);
|
||||
extern t_plugin_dcc_info *weechat_plugin_get_dcc_info (t_weechat_plugin *);
|
||||
extern void weechat_plugin_free_dcc_info (t_weechat_plugin *, t_plugin_dcc_info *);
|
||||
extern char *weechat_plugin_get_config (t_weechat_plugin *, char *);
|
||||
extern int weechat_plugin_set_config (t_weechat_plugin *, char *, char *);
|
||||
extern char *weechat_plugin_get_plugin_config (t_weechat_plugin *, char *);
|
||||
extern int weechat_plugin_set_plugin_config (t_weechat_plugin *, char *, char *);
|
||||
extern t_plugin_server_info *weechat_plugin_get_server_info (t_weechat_plugin *);
|
||||
extern void weechat_plugin_free_server_info (t_weechat_plugin *, t_plugin_server_info *);
|
||||
extern t_plugin_channel_info *weechat_plugin_get_channel_info (t_weechat_plugin *, char *);
|
||||
extern void weechat_plugin_free_channel_info (t_weechat_plugin *, t_plugin_channel_info *);
|
||||
extern t_plugin_nick_info *weechat_plugin_get_nick_info (t_weechat_plugin *, char *, char *);
|
||||
extern void weechat_plugin_free_nick_info (t_weechat_plugin *, t_plugin_nick_info *);
|
||||
extern void weechat_plugin_input_color (t_weechat_plugin *, int, int, int);
|
||||
extern int weechat_plugin_get_irc_color (t_weechat_plugin *, char *);
|
||||
extern t_plugin_window_info *weechat_plugin_get_window_info (t_weechat_plugin *);
|
||||
extern void weechat_plugin_free_window_info (t_weechat_plugin *, t_plugin_window_info *);
|
||||
extern t_plugin_buffer_info *weechat_plugin_get_buffer_info (t_weechat_plugin *);
|
||||
extern void weechat_plugin_free_buffer_info (t_weechat_plugin *, t_plugin_buffer_info *);
|
||||
extern t_plugin_buffer_line *weechat_plugin_get_buffer_data (t_weechat_plugin *, char *, char *);
|
||||
extern void weechat_plugin_free_buffer_data (t_weechat_plugin *, t_plugin_buffer_line *);
|
||||
#define weechat_command(buffer, cmd) \
|
||||
weechat_plugin->command(weechat_plugin, buffer, cmd)
|
||||
|
||||
/* iconv functions */
|
||||
extern void weechat_plugin_set_charset (t_weechat_plugin *, char *);
|
||||
extern char *weechat_plugin_iconv_to_internal (t_weechat_plugin *, char *, char *);
|
||||
extern char *weechat_plugin_iconv_from_internal (t_weechat_plugin *, char *, char *);
|
||||
#define weechat_info_get(infoname) \
|
||||
weechat_plugin->info_get(weechat_plugin, infoname)
|
||||
|
||||
#define weechat_config_get(option) \
|
||||
weechat_plugin->config_get(weechat_plugin, option)
|
||||
#define weechat_config_set(option, value) \
|
||||
weechat_plugin->config_set(weechat_plugin, option, value)
|
||||
#define weechat_plugin_config_get(option) \
|
||||
weechat_plugin->plugin_config_get(weechat_plugin, option)
|
||||
#define weechat_plugin_config_set(option, value) \
|
||||
weechat_plugin->plugin_config_set(weechat_plugin, option, value)
|
||||
|
||||
#endif /* weechat-plugin.h */
|
||||
|
||||
Reference in New Issue
Block a user