1
0
mirror of https://github.com/profanity-im/profanity.git synced 2024-06-09 21:30:42 +00:00

Added C plugin code from plugins branch

This commit is contained in:
James Booth 2016-02-14 22:28:55 +00:00
parent f887a35c0c
commit 41fe8c22b1
70 changed files with 2668 additions and 287 deletions

2
.gitignore vendored
View File

@ -33,9 +33,11 @@ m4/
src/config.h
src/config.h.in
src/config.h.in~
src/prof_config.h
src/gitversion.h
src/gitversion.h.in
src/stamp-h1
src/plugins/profapi.lo
# binaries
profanity

View File

@ -4,6 +4,7 @@ install:
- uname -a
- sudo apt-get update
- sudo apt-get -y install libssl-dev libexpat1-dev libncursesw5-dev libglib2.0-dev libnotify-dev libcurl3-dev libxss-dev libotr2-dev libgpgme11-dev expect-dev tcl-dev
- sudo apt-get -y install autoconf-archive libtool
- git clone git://github.com/boothj5/libmesode.git
- cd libmesode
- mkdir m4
@ -33,4 +34,4 @@ install:
- cd ..
- rm -rf stabber
- ./bootstrap.sh
script: ./configure && make && make check
script: ./configure --enable-c-plugins && make && make check

View File

@ -41,7 +41,11 @@ core_sources = \
src/config/account.c src/config/account.h \
src/config/preferences.c src/config/preferences.h \
src/config/theme.c src/config/theme.h \
src/config/scripts.c src/config/scripts.h
src/config/scripts.c src/config/scripts.h \
src/plugins/plugins.h src/plugins/plugins.c \
src/plugins/api.h src/plugins/api.c \
src/plugins/callbacks.h src/plugins/callbacks.c \
src/plugins/autocompleters.c src/plugins/autocompleters.h
unittest_sources = \
src/contact.c src/contact.h src/common.c \
@ -69,6 +73,10 @@ unittest_sources = \
src/config/theme.c src/config/theme.h \
src/config/scripts.c src/config/scripts.h \
src/config/conflists.c src/config/conflists.h \
src/plugins/plugins.h src/plugins/plugins.c \
src/plugins/api.h src/plugins/api.c \
src/plugins/callbacks.h src/plugins/callbacks.c \
src/plugins/autocompleters.c src/plugins/autocompleters.h \
src/window_list.c src/window_list.h \
src/event/server_events.c src/event/server_events.h \
src/event/client_events.c src/event/client_events.h \
@ -120,6 +128,10 @@ functionaltest_sources = \
main_source = src/main.c
c_sources = \
src/plugins/c_plugins.h src/plugins/c_plugins.c \
src/plugins/c_api.h src/plugins/c_api.c
git_include = src/gitversion.h
pgp_sources = \
@ -134,6 +146,11 @@ otr3_sources = \
otr4_sources = \
src/otr/otrlib.h src/otr/otrlibv4.c src/otr/otr.h src/otr/otr.c
if BUILD_C_API
core_sources += $(c_sources)
unittest_sources += $(c_sources)
endif
otr_unittest_sources = \
tests/unittests/otr/stub_otr.c
@ -168,6 +185,15 @@ if INCLUDE_GIT_VERSION
BUILT_SOURCES = $(git_include)
endif
if BUILD_C_API
lib_LTLIBRARIES = libprofanity.la
libprofanity_la_LDFLAGS=-avoid-version -shared
libprofanity_la_SOURCES = src/plugins/profapi.c
library_includedir=$(includedir)
library_include_HEADERS = src/plugins/profapi.h
endif
TESTS = tests/unittests/unittests
check_PROGRAMS = tests/unittests/unittests
tests_unittests_unittests_SOURCES = $(unittest_sources)

View File

@ -1,3 +1,3 @@
#!/bin/sh
autoreconf --install
autoreconf -fiv

View File

@ -2,14 +2,16 @@
# Process this file with autoconf to produce a configure script.
AC_INIT([profanity], [0.5.0], [boothj5web@gmail.com])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([src/main.c])
AC_CONFIG_HEADERS([src/config.h])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([foreign subdir-objects])
AX_PREFIX_CONFIG_H([src/prof_config.h], [PROF], [src/config.h])
### Checks for programs.
AC_PROG_CC
AC_PROG_LIBTOOL
## Check for LFS
AC_SYS_LARGEFILE
@ -43,6 +45,10 @@ AS_IF([test "x$PLATFORM" = xosx],
### Options
AC_ARG_ENABLE([notifications],
[AS_HELP_STRING([--enable-notifications], [enable desktop notifications])])
AC_ARG_ENABLE([c-plugins],
[AS_HELP_STRING([--enable-c-plugins], [enable C plugins])])
AC_ARG_ENABLE([plugins],
[AS_HELP_STRING([--enable-plugins], [enable plugins])])
AC_ARG_ENABLE([otr],
[AS_HELP_STRING([--enable-otr], [enable otr encryption])])
AC_ARG_ENABLE([pgp],
@ -52,6 +58,23 @@ AC_ARG_WITH([xscreensaver],
AC_ARG_WITH([themes],
[AS_HELP_STRING([--with-themes[[=PATH]]], [install themes (default yes)])])
### plugins
# c
LT_INIT
if test "x$enable_plugins" = xno; then
AM_CONDITIONAL([BUILD_C_API], [false])
elif test "x$enable_c_plugins" != xno; then
AC_CHECK_LIB([dl], [main],
[AM_CONDITIONAL([BUILD_C_API], [true]) LIBS="$LIBS -ldl" AC_DEFINE([HAVE_C], [1], [C support])],
[AS_IF(
[test "x$enable_c_plugins" = xyes],
[AC_MSG_ERROR([dl library needed to run C plugins])],
[AM_CONDITIONAL([BUILD_C_API], [false])])
])
else
AM_CONDITIONAL([BUILD_C_API], [false])
fi
### Check for libmesode, fall back to libstrophe
PKG_CHECK_MODULES([libmesode], [libmesode],
[LIBS="$libmesode_LIBS $LIBS" CFLAGS="$CFLAGS $libmesode_CFLAGS" AC_DEFINE([HAVE_LIBMESODE], [1], [libmesode])],
@ -208,10 +231,12 @@ AC_CHECK_HEADERS([ncurses.h], [], [])
AM_CFLAGS="-Wall -Wno-deprecated-declarations"
AS_IF([test "x$PACKAGE_STATUS" = xdevelopment],
[AM_CFLAGS="$AM_CFLAGS -Wunused -Werror"])
AM_LDFLAGS="$AM_LDFLAGS -export-dynamic"
AM_CPPFLAGS="$AM_CPPFLAGS $glib_CFLAGS $curl_CFLAGS $libnotify_CFLAGS"
AM_CPPFLAGS="$AM_CPPFLAGS -DTHEMES_PATH=\"\\\"$THEMES_PATH\\\"\""
LIBS="$glib_LIBS $curl_LIBS $libnotify_LIBS $LIBS"
AC_SUBST(AM_LDFLAGS)
AC_SUBST(AM_CFLAGS)
AC_SUBST(AM_CPPFLAGS)
@ -226,6 +251,7 @@ echo "PLATFORM : $host_os"
echo "PACKAGE_STATUS : $PACKAGE_STATUS"
echo "AM_CFLAGS : $AM_CFLAGS"
echo "AM_CPPFLAGS : $AM_CPPFLAGS"
echo "AM_LDFLAGS : $AM_LDFLAGS"
echo "LIBS : $LIBS"
echo "XML Parser : $PARSER"
echo "Install themes : $THEMES_INSTALL"

View File

@ -32,7 +32,7 @@
*
*/
#include "config.h"
#include "prof_config.h"
#include <assert.h>
#include <errno.h>
@ -58,10 +58,11 @@
#include "xmpp/form.h"
#include "log.h"
#include "muc.h"
#ifdef HAVE_LIBOTR
#include "plugins/plugins.h"
#ifdef PROF_HAVE_LIBOTR
#include "otr/otr.h"
#endif
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
#include "pgp/gpg.h"
#endif
#include "profanity.h"
@ -1733,6 +1734,17 @@ static struct cmd_t command_defs[] =
"/account rename me gtalk")
},
{ "/plugins",
cmd_plugins, parse_args, 0, 0, NULL,
CMD_NOTAGS
CMD_SYN(
"/plugins")
CMD_DESC(
"Show currently installed plugins. ")
CMD_NOARGS
CMD_NOEXAMPLES
},
{ "/prefs",
cmd_prefs, parse_args, 0, 1, NULL,
CMD_NOTAGS
@ -2641,7 +2653,7 @@ cmd_exists(char *cmd)
}
void
cmd_autocomplete_add(char *value)
cmd_autocomplete_add(const char *const value)
{
if (commands_ac) {
autocomplete_add(commands_ac, value);
@ -2687,7 +2699,7 @@ cmd_autocomplete_remove_form_fields(DataForm *form)
}
void
cmd_autocomplete_remove(char *value)
cmd_autocomplete_remove(const char *const value)
{
if (commands_ac) {
autocomplete_remove(commands_ac, value);
@ -2756,7 +2768,7 @@ cmd_reset_autocomplete(ProfWin *window)
tlscerts_reset_ac();
prefs_reset_boolean_choice();
presence_reset_sub_request_search();
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
p_gpg_autocomplete_key_reset();
#endif
autocomplete_reset(help_ac);
@ -2867,6 +2879,7 @@ cmd_reset_autocomplete(ProfWin *window)
prefs_reset_room_trigger_ac();
win_reset_search_attempts();
win_close_reset_search_attempts();
plugins_reset_autocomplete();
}
gboolean
@ -2968,6 +2981,8 @@ _cmd_execute(ProfWin *window, const char *const command, const char *const inp)
g_strfreev(args);
return result;
}
} else if (plugins_run_command(inp)) {
return TRUE;
} else {
gboolean ran_alias = FALSE;
gboolean alias_result = cmd_execute_alias(window, inp, &ran_alias);
@ -3128,6 +3143,11 @@ _cmd_complete_parameters(ProfWin *window, const char *const input)
}
g_hash_table_destroy(ac_funcs);
result = plugins_autocomplete(input);
if (result) {
return result;
}
if (g_str_has_prefix(input, "/field")) {
result = _form_field_autocomplete(window, input);
if (result) {
@ -3190,7 +3210,7 @@ _who_autocomplete(ProfWin *window, const char *const input)
}
}
return NULL;
return result;
}
static char*
@ -3647,7 +3667,7 @@ _pgp_autocomplete(ProfWin *window, const char *const input)
return found;
}
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
gboolean result;
gchar **args = parse_args(input, 2, 3, &result);
if ((strncmp(input, "/pgp", 4) == 0) && (result == TRUE)) {
@ -4568,7 +4588,7 @@ _account_autocomplete(ProfWin *window, const char *const input)
if (found) {
return found;
}
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
} else if ((g_strv_length(args) > 3) && (g_strcmp0(args[2], "pgpkeyid")) == 0) {
g_string_append(beginning, " ");
g_string_append(beginning, args[2]);

View File

@ -47,8 +47,8 @@ void cmd_uninit(void);
char* cmd_autocomplete(ProfWin *window, const char *const input);
void cmd_reset_autocomplete(ProfWin *window);
void cmd_autocomplete_add(char *value);
void cmd_autocomplete_remove(char *value);
void cmd_autocomplete_add(const char *const value);
void cmd_autocomplete_remove(const char *const value);
void cmd_autocomplete_add_form_fields(DataForm *form);
void cmd_autocomplete_remove_form_fields(DataForm *form);
void cmd_alias_add(char *value);

View File

@ -32,7 +32,7 @@
*
*/
#include "config.h"
#include "prof_config.h"
#include <string.h>
#include <stdlib.h>
@ -61,13 +61,14 @@
#include "jid.h"
#include "log.h"
#include "muc.h"
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
#include "otr/otr.h"
#endif
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
#include "pgp/gpg.h"
#endif
#include "profanity.h"
#include "plugins/plugins.h"
#include "tools/autocomplete.h"
#include "tools/parser.h"
#include "tools/tinyurl.h"
@ -100,12 +101,19 @@ cmd_execute_default(ProfWin *window, const char *inp)
return TRUE;
}
// handle non commands in non chat windows
if (window->type != WIN_CHAT && window->type != WIN_MUC && window->type != WIN_PRIVATE) {
// handle non commands in non chat or plugin windows
if (window->type != WIN_CHAT && window->type != WIN_MUC && window->type != WIN_PRIVATE && window->type != WIN_PLUGIN) {
cons_show("Unknown command: %s", inp);
return TRUE;
}
// handle plugin window
if (window->type == WIN_PLUGIN) {
ProfPluginWin *pluginwin = (ProfPluginWin*)window;
plugins_win_process_line(pluginwin->tag, inp);
return TRUE;
}
jabber_conn_status_t status = jabber_get_connection_status();
if (status != JABBER_CONNECTED) {
ui_current_print_line("You are not currently connected.");
@ -167,7 +175,7 @@ gboolean
cmd_tls(ProfWin *window, const char *const command, gchar **args)
{
if (g_strcmp0(args[0], "certpath") == 0) {
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
if (g_strcmp0(args[1], "set") == 0) {
if (args[2] == NULL) {
cons_bad_cmd_usage(command);
@ -203,7 +211,7 @@ cmd_tls(ProfWin *window, const char *const command, gchar **args)
return TRUE;
#endif
} else if (g_strcmp0(args[0], "trust") == 0) {
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
jabber_conn_status_t conn_status = jabber_get_connection_status();
if (conn_status != JABBER_CONNECTED) {
cons_show("You are not currently connected.");
@ -232,7 +240,7 @@ cmd_tls(ProfWin *window, const char *const command, gchar **args)
return TRUE;
#endif
} else if (g_strcmp0(args[0], "trusted") == 0) {
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
GList *certs = tlscerts_list();
GList *curr = certs;
@ -255,7 +263,7 @@ cmd_tls(ProfWin *window, const char *const command, gchar **args)
return TRUE;
#endif
} else if (g_strcmp0(args[0], "revoke") == 0) {
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
if (args[1] == NULL) {
cons_bad_cmd_usage(command);
} else {
@ -274,7 +282,7 @@ cmd_tls(ProfWin *window, const char *const command, gchar **args)
} else if (g_strcmp0(args[0], "show") == 0) {
return _cmd_set_boolean_preference(args[1], command, "TLS titlebar indicator", PREF_TLS_SHOW);
} else if (g_strcmp0(args[0], "cert") == 0) {
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
if (args[1]) {
TLSCertificate *cert = tlscerts_get_trusted(args[1]);
if (!cert) {
@ -654,7 +662,7 @@ cmd_account(ProfWin *window, const char *const command, gchar **args)
}
cons_show("");
} else if (strcmp(property, "pgpkeyid") == 0) {
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
char *err_str = NULL;
if (!p_gpg_valid_key(value, &err_str)) {
cons_show("Invalid PGP key ID specified: %s, see /pgp keys", err_str);
@ -1886,7 +1894,7 @@ cmd_msg(ProfWin *window, const char *const command, gchar **args)
if (msg) {
cl_ev_send_msg(chatwin, msg);
} else {
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
if (otr_is_secure(barejid)) {
chatwin_otr_secured(chatwin, otr_is_trusted(barejid));
}
@ -2774,7 +2782,7 @@ cmd_resource(ProfWin *window, const char *const command, gchar **args)
return TRUE;
}
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
if (otr_is_secure(chatwin->barejid)) {
cons_show("Cannot choose resource during an OTR session.");
return TRUE;
@ -5602,10 +5610,31 @@ cmd_xa(ProfWin *window, const char *const command, gchar **args)
return TRUE;
}
gboolean
cmd_plugins(ProfWin *window, const char *const command, gchar **args)
{
GSList *plugins = plugins_get_list();
GSList *curr = plugins;
if (curr == NULL) {
cons_show("No plugins installed.");
} else {
cons_show("Installed plugins:");
while (curr) {
ProfPlugin *plugin = curr->data;
char *lang = plugins_get_lang_string(plugin);
cons_show(" %s (%s)", plugin->name, lang);
curr = g_slist_next(curr);
}
}
g_slist_free(curr);
return TRUE;
}
gboolean
cmd_pgp(ProfWin *window, const char *const command, gchar **args)
{
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
if (args[0] == NULL) {
cons_bad_cmd_usage(command);
return TRUE;
@ -5837,13 +5866,12 @@ cmd_pgp(ProfWin *window, const char *const command, gchar **args)
cons_show("This version of Profanity has not been built with PGP support enabled");
return TRUE;
#endif
}
gboolean
cmd_otr(ProfWin *window, const char *const command, gchar **args)
{
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
if (args[0] == NULL) {
cons_bad_cmd_usage(command);
return TRUE;

View File

@ -153,6 +153,7 @@ gboolean cmd_script(ProfWin *window, const char *const command, gchar **args);
gboolean cmd_export(ProfWin *window, const char *const command, gchar **args);
gboolean cmd_charset(ProfWin *window, const char *const command, gchar **args);
gboolean cmd_console(ProfWin *window, const char *const command, gchar **args);
gboolean cmd_plugins(ProfWin *window, const char *const command, gchar **args);
gboolean cmd_form_field(ProfWin *window, char *tag, gchar **args);

View File

@ -31,7 +31,7 @@
* source files in the program, then also delete it here.
*
*/
#include "config.h"
#include "prof_config.h"
#include <sys/select.h>
#include <assert.h>
@ -46,6 +46,12 @@
#include <curl/easy.h>
#include <glib.h>
#ifdef PROF_HAVE_NCURSESW_NCURSES_H
#include <ncursesw/ncurses.h>
#elif PROF_HAVE_NCURSES_H
#include <ncurses.h>
#endif
#include "tools/p_sha1.h"
#include "log.h"
@ -341,7 +347,7 @@ release_is_new(char *found_version)
{
int curr_maj, curr_min, curr_patch, found_maj, found_min, found_patch;
int parse_curr = sscanf(PACKAGE_VERSION, "%d.%d.%d", &curr_maj, &curr_min,
int parse_curr = sscanf(PROF_PACKAGE_VERSION, "%d.%d.%d", &curr_maj, &curr_min,
&curr_patch);
int parse_found = sscanf(found_version, "%d.%d.%d", &found_maj, &found_min,
&found_patch);
@ -651,10 +657,10 @@ is_notify_enabled(void)
{
gboolean notify_enabled = FALSE;
#ifdef HAVE_OSXNOTIFY
#ifdef PROF_HAVE_OSXNOTIFY
notify_enabled = TRUE;
#endif
#ifdef HAVE_LIBNOTIFY
#ifdef PROF_HAVE_LIBNOTIFY
notify_enabled = TRUE;
#endif
#ifdef PLATFORM_CYGWIN

View File

@ -32,7 +32,7 @@
*
*/
#include "config.h"
#include "prof_config.h"
#include <stdlib.h>
#include <stdio.h>
@ -591,6 +591,19 @@ prefs_set_autoxa_time(gint value)
_save_prefs();
}
gchar **
prefs_get_plugins(void)
{
if (!g_key_file_has_group(prefs, "plugins")) {
return NULL;
}
if (!g_key_file_has_key(prefs, "plugins", "load", NULL)) {
return NULL;
}
return g_key_file_get_string_list(prefs, "plugins", "load", NULL, NULL);
}
void
prefs_set_occupants_size(gint value)
{

View File

@ -35,7 +35,7 @@
#ifndef PREFERENCES_H
#define PREFERENCES_H
#include "config.h"
#include "prof_config.h"
#include <glib.h>
@ -183,6 +183,8 @@ void prefs_set_autoaway_time(gint value);
gint prefs_get_autoxa_time(void);
void prefs_set_autoxa_time(gint value);
gchar** prefs_get_plugins(void);
char prefs_get_otr_char(void);
void prefs_set_otr_char(char ch);
char prefs_get_pgp_char(void);

View File

@ -32,15 +32,15 @@
*
*/
#include "config.h"
#include "prof_config.h"
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#ifdef HAVE_NCURSESW_NCURSES_H
#ifdef PROF_HAVE_NCURSESW_NCURSES_H
#include <ncursesw/ncurses.h>
#elif HAVE_NCURSES_H
#elif PROF_HAVE_NCURSES_H
#include <ncurses.h>
#endif

View File

@ -35,7 +35,7 @@
#ifndef THEME_H
#define THEME_H
#include "config.h"
#include "prof_config.h"
#include <glib.h>

View File

@ -32,7 +32,7 @@
*
*/
#include "config.h"
#include "prof_config.h"
#include <stdlib.h>
#include <glib.h>
@ -43,10 +43,11 @@
#include "xmpp/xmpp.h"
#include "roster_list.h"
#include "chat_session.h"
#ifdef HAVE_LIBOTR
#include "plugins/plugins.h"
#ifdef PROF_HAVE_LIBOTR
#include "otr/otr.h"
#endif
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
#include "pgp/gpg.h"
#endif
@ -80,7 +81,7 @@ cl_ev_disconnect(void)
muc_invites_clear();
chat_sessions_clear();
tlscerts_clear_current();
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
p_gpg_on_disconnect();
#endif
}
@ -90,7 +91,7 @@ cl_ev_presence_send(const resource_presence_t presence_type, const char *const m
{
char *signed_status = NULL;
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
char *account_name = jabber_get_account_name();
ProfAccount *account = accounts_get_account(account_name);
if (account->pgp_keyid) {
@ -108,21 +109,22 @@ void
cl_ev_send_msg(ProfChatWin *chatwin, const char *const msg)
{
chat_state_active(chatwin->state);
char *plugin_msg = plugins_pre_chat_message_send(chatwin->barejid, msg);
// OTR suported, PGP supported
#ifdef HAVE_LIBOTR
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBOTR
#ifdef PROF_HAVE_LIBGPGME
if (chatwin->pgp_send) {
char *id = message_send_chat_pgp(chatwin->barejid, msg);
chat_log_pgp_msg_out(chatwin->barejid, msg);
chatwin_outgoing_msg(chatwin, msg, id, PROF_MSG_PGP);
char *id = message_send_chat_pgp(chatwin->barejid, plugin_msg);
chat_log_pgp_msg_out(chatwin->barejid, plugin_msg);
chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_PGP);
free(id);
} else {
gboolean handled = otr_on_message_send(chatwin, msg);
gboolean handled = otr_on_message_send(chatwin, plugin_msg);
if (!handled) {
char *id = message_send_chat(chatwin->barejid, msg);
chat_log_msg_out(chatwin->barejid, msg);
chatwin_outgoing_msg(chatwin, msg, id, PROF_MSG_PLAIN);
char *id = message_send_chat(chatwin->barejid, plugin_msg);
chat_log_msg_out(chatwin->barejid, plugin_msg);
chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_PLAIN);
free(id);
}
}
@ -131,13 +133,13 @@ cl_ev_send_msg(ProfChatWin *chatwin, const char *const msg)
#endif
// OTR supported, PGP unsupported
#ifdef HAVE_LIBOTR
#ifndef HAVE_LIBGPGME
gboolean handled = otr_on_message_send(chatwin, msg);
#ifdef PROF_HAVE_LIBOTR
#ifndef PROF_HAVE_LIBGPGME
gboolean handled = otr_on_message_send(chatwin, plugin_msg);
if (!handled) {
char *id = message_send_chat(chatwin->barejid, msg);
chat_log_msg_out(chatwin->barejid, msg);
chatwin_outgoing_msg(chatwin, msg, id, PROF_MSG_PLAIN);
char *id = message_send_chat(chatwin->barejid, plugin_msg);
chat_log_msg_out(chatwin->barejid, plugin_msg);
chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_PLAIN);
free(id);
}
return;
@ -145,17 +147,17 @@ cl_ev_send_msg(ProfChatWin *chatwin, const char *const msg)
#endif
// OTR unsupported, PGP supported
#ifndef HAVE_LIBOTR
#ifdef HAVE_LIBGPGME
#ifndef PROF_HAVE_LIBOTR
#ifdef PROF_HAVE_LIBGPGME
if (chatwin->pgp_send) {
char *id = message_send_chat_pgp(chatwin->barejid, msg);
chat_log_pgp_msg_out(chatwin->barejid, msg);
chatwin_outgoing_msg(chatwin, msg, id, PROF_MSG_PGP);
char *id = message_send_chat_pgp(chatwin->barejid, plugin_msg);
chat_log_pgp_msg_out(chatwin->barejid, plugin_msg);
chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_PGP);
free(id);
} else {
char *id = message_send_chat(chatwin->barejid, msg);
chat_log_msg_out(chatwin->barejid, msg);
chatwin_outgoing_msg(chatwin, msg, id, PROF_MSG_PLAIN);
char *id = message_send_chat(chatwin->barejid, plugin_msg);
chat_log_msg_out(chatwin->barejid, plugin_msg);
chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_PLAIN);
free(id);
}
return;
@ -163,21 +165,29 @@ cl_ev_send_msg(ProfChatWin *chatwin, const char *const msg)
#endif
// OTR unsupported, PGP unsupported
#ifndef HAVE_LIBOTR
#ifndef HAVE_LIBGPGME
char *id = message_send_chat(chatwin->barejid, msg);
chat_log_msg_out(chatwin->barejid, msg);
chatwin_outgoing_msg(chatwin, msg, id, PROF_MSG_PLAIN);
#ifndef PROF_HAVE_LIBOTR
#ifndef PROF_HAVE_LIBGPGME
char *id = message_send_chat(chatwin->barejid, plugin_msg);
chat_log_msg_out(chatwin->barejid, plugin_msg);
chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_PLAIN);
free(id);
return;
#endif
#endif
plugins_post_chat_message_send(chatwin->barejid, plugin_msg);
free(plugin_msg);
}
void
cl_ev_send_muc_msg(ProfMucWin *mucwin, const char *const msg)
{
message_send_groupchat(mucwin->roomjid, msg);
char *plugin_msg = plugins_pre_room_message_send(mucwin->roomjid, msg);
message_send_groupchat(mucwin->roomjid, plugin_msg);
plugins_post_room_message_send(mucwin->roomjid, plugin_msg);
free(plugin_msg);
}
void
@ -188,7 +198,12 @@ cl_ev_send_priv_msg(ProfPrivateWin *privwin, const char *const msg)
} else if (privwin->room_left) {
privwin_message_left_room(privwin);
} else {
message_send_private(privwin->fulljid, msg);
privwin_outgoing_msg(privwin, msg);
char *plugin_msg = plugins_pre_priv_message_send(privwin->fulljid, msg);
message_send_private(privwin->fulljid, plugin_msg);
privwin_outgoing_msg(privwin, plugin_msg);
plugins_post_priv_message_send(privwin->fulljid, plugin_msg);
free(plugin_msg);
}
}

View File

@ -32,7 +32,7 @@
*
*/
#include "config.h"
#include "prof_config.h"
#include <string.h>
#include <stdlib.h>
@ -45,15 +45,16 @@
#include "config/account.h"
#include "config/scripts.h"
#include "roster_list.h"
#include "plugins/plugins.h"
#include "window_list.h"
#include "config/tlscerts.h"
#include "profanity.h"
#include "event/client_events.h"
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
#include "otr/otr.h"
#endif
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
#include "pgp/gpg.h"
#endif
@ -66,11 +67,11 @@ sv_ev_login_account_success(char *account_name, int secured)
roster_create();
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
otr_on_connect(account);
#endif
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
p_gpg_on_connect(account->jid);
#endif
@ -106,7 +107,7 @@ sv_ev_roster_received(void)
char *account_name = jabber_get_account_name();
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
// check pgp key valid if specified
ProfAccount *account = accounts_get_account(account_name);
if (account && account->pgp_keyid) {
@ -146,6 +147,9 @@ sv_ev_roster_received(void)
} else {
cl_ev_presence_send(conn_presence, NULL, 0);
}
const char *fulljid = jabber_get_fulljid();
plugins_on_connect(account_name, fulljid);
}
void
@ -153,7 +157,7 @@ sv_ev_lost_connection(void)
{
cons_show_error("Lost connection.");
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
GSList *recipients = wins_get_chat_recipients();
GSList *curr = recipients;
while (curr) {
@ -174,7 +178,7 @@ sv_ev_lost_connection(void)
chat_sessions_clear();
ui_disconnected();
roster_destroy();
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
p_gpg_on_disconnect();
#endif
}
@ -226,7 +230,10 @@ sv_ev_room_history(const char *const room_jid, const char *const nick,
{
ProfMucWin *mucwin = wins_get_muc(room_jid);
if (mucwin) {
mucwin_history(mucwin, nick, timestamp, message);
char *new_message = plugins_pre_room_message_display(room_jid, nick, message);
mucwin_history(mucwin, nick, timestamp, new_message);
plugins_post_room_message_display(room_jid, nick, new_message);
free(new_message);
}
}
@ -244,10 +251,11 @@ sv_ev_room_message(const char *const room_jid, const char *const nick, const cha
return;
}
char *new_message = plugins_pre_room_message_display(room_jid, nick, message);
char *mynick = muc_nick(mucwin->roomjid);
gboolean mention = FALSE;
char *message_lower = g_utf8_strdown(message, -1);
char *message_lower = g_utf8_strdown(new_message, -1);
char *mynick_lower = g_utf8_strdown(mynick, -1);
if (g_strrstr(message_lower, mynick_lower)) {
mention = TRUE;
@ -255,9 +263,9 @@ sv_ev_room_message(const char *const room_jid, const char *const nick, const cha
g_free(message_lower);
g_free(mynick_lower);
GList *triggers = prefs_message_get_triggers(message);
GList *triggers = prefs_message_get_triggers(new_message);
mucwin_message(mucwin, nick, message, mention, triggers);
mucwin_message(mucwin, nick, new_message, mention, triggers);
ProfWin *window = (ProfWin*)mucwin;
int num = wins_get_num(window);
@ -292,9 +300,9 @@ sv_ev_room_message(const char *const room_jid, const char *const nick, const cha
}
}
if (prefs_do_room_notify(is_current, mucwin->roomjid, mynick, nick, message, mention, triggers != NULL)) {
if (prefs_do_room_notify(is_current, mucwin->roomjid, mynick, nick, new_message, mention, triggers != NULL)) {
Jid *jidp = jid_create(mucwin->roomjid);
notify_room_message(nick, jidp->localpart, num, message);
notify_room_message(nick, jidp->localpart, num, new_message);
jid_destroy(jidp);
}
@ -303,29 +311,44 @@ sv_ev_room_message(const char *const room_jid, const char *const nick, const cha
}
rosterwin_roster();
plugins_post_room_message_display(room_jid, nick, new_message);
free(new_message);
}
void
sv_ev_incoming_private_message(const char *const fulljid, char *message)
{
char *plugin_message = plugins_pre_priv_message_display(fulljid, message);
ProfPrivateWin *privatewin = wins_get_private(fulljid);
if (privatewin == NULL) {
ProfWin *window = wins_new_private(fulljid);
privatewin = (ProfPrivateWin*)window;
}
privwin_incoming_msg(privatewin, message, NULL);
privwin_incoming_msg(privatewin, plugin_message, NULL);
plugins_post_priv_message_display(fulljid, plugin_message);
free(plugin_message);
rosterwin_roster();
}
void
sv_ev_delayed_private_message(const char *const fulljid, char *message, GDateTime *timestamp)
{
char *new_message = plugins_pre_priv_message_display(fulljid, message);
ProfPrivateWin *privatewin = wins_get_private(fulljid);
if (privatewin == NULL) {
ProfWin *window = wins_new_private(fulljid);
privatewin = (ProfPrivateWin*)window;
}
privwin_incoming_msg(privatewin, message, timestamp);
privwin_incoming_msg(privatewin, new_message, timestamp);
plugins_post_priv_message_display(fulljid, new_message);
free(new_message);
}
void
@ -356,7 +379,7 @@ sv_ev_incoming_carbon(char *barejid, char *resource, char *message)
chat_log_msg_in(barejid, message, NULL);
}
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
static void
_sv_ev_incoming_pgp(ProfChatWin *chatwin, gboolean new_win, char *barejid, char *resource, char *message, char *pgp_message, GDateTime *timestamp)
{
@ -374,7 +397,7 @@ _sv_ev_incoming_pgp(ProfChatWin *chatwin, gboolean new_win, char *barejid, char
}
#endif
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
static void
_sv_ev_incoming_otr(ProfChatWin *chatwin, gboolean new_win, char *barejid, char *resource, char *message, GDateTime *timestamp)
{
@ -394,7 +417,7 @@ _sv_ev_incoming_otr(ProfChatWin *chatwin, gboolean new_win, char *barejid, char
}
#endif
#ifndef HAVE_LIBOTR
#ifndef PROF_HAVE_LIBOTR
static void
_sv_ev_incoming_plain(ProfChatWin *chatwin, gboolean new_win, char *barejid, char *resource, char *message, GDateTime *timestamp)
{
@ -416,8 +439,8 @@ sv_ev_incoming_message(char *barejid, char *resource, char *message, char *pgp_m
}
// OTR suported, PGP supported
#ifdef HAVE_LIBOTR
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBOTR
#ifdef PROF_HAVE_LIBGPGME
if (pgp_message) {
if (chatwin->is_otr) {
win_println((ProfWin*)chatwin, 0, "PGP encrypted message received whilst in OTR session.");
@ -433,8 +456,8 @@ sv_ev_incoming_message(char *barejid, char *resource, char *message, char *pgp_m
#endif
// OTR supported, PGP unsupported
#ifdef HAVE_LIBOTR
#ifndef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBOTR
#ifndef PROF_HAVE_LIBGPGME
_sv_ev_incoming_otr(chatwin, new_win, barejid, resource, message, timestamp);
rosterwin_roster();
return;
@ -442,8 +465,8 @@ sv_ev_incoming_message(char *barejid, char *resource, char *message, char *pgp_m
#endif
// OTR unsupported, PGP supported
#ifndef HAVE_LIBOTR
#ifdef HAVE_LIBGPGME
#ifndef PROF_HAVE_LIBOTR
#ifdef PROF_HAVE_LIBGPGME
if (pgp_message) {
_sv_ev_incoming_pgp(chatwin, new_win, barejid, resource, message, pgp_message, timestamp);
} else {
@ -455,8 +478,8 @@ sv_ev_incoming_message(char *barejid, char *resource, char *message, char *pgp_m
#endif
// OTR unsupported, PGP unsupported
#ifndef HAVE_LIBOTR
#ifndef HAVE_LIBGPGME
#ifndef PROF_HAVE_LIBOTR
#ifndef PROF_HAVE_LIBGPGME
_sv_ev_incoming_plain(chatwin, new_win, barejid, resource, message, timestamp);
rosterwin_roster();
return;
@ -568,7 +591,7 @@ sv_ev_contact_offline(char *barejid, char *resource, char *status)
ui_contact_offline(barejid, resource, status);
}
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
ProfChatWin *chatwin = wins_get_chat(barejid);
if (chatwin && otr_is_secure(barejid)) {
chatwin_otr_unsecured(chatwin);
@ -589,7 +612,7 @@ sv_ev_contact_online(char *barejid, Resource *resource, GDateTime *last_activity
ui_contact_online(barejid, resource, last_activity);
}
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
if (pgpsig) {
p_gpg_verify(barejid, pgpsig);
}

View File

@ -32,12 +32,12 @@
*
*/
#include "config.h"
#include "prof_config.h"
#include <string.h>
#include <glib.h>
#ifdef HAVE_GIT_VERSION
#ifdef PROF_HAVE_GIT_VERSION
#include "gitversion.h"
#endif
@ -52,7 +52,7 @@ static char *account_name = NULL;
int
main(int argc, char **argv)
{
if (argc == 2 && g_strcmp0(argv[1], "docgen") == 0 && g_strcmp0(PACKAGE_STATUS, "development") == 0) {
if (argc == 2 && g_strcmp0(argv[1], "docgen") == 0 && g_strcmp0(PROF_PACKAGE_STATUS, "development") == 0) {
command_docgen();
return 0;
}
@ -80,17 +80,17 @@ main(int argc, char **argv)
g_option_context_free(context);
if (version == TRUE) {
if (strcmp(PACKAGE_STATUS, "development") == 0) {
#ifdef HAVE_GIT_VERSION
g_print("Profanity, version %sdev.%s.%s\n", PACKAGE_VERSION, PROF_GIT_BRANCH, PROF_GIT_REVISION);
if (strcmp(PROF_PACKAGE_STATUS, "development") == 0) {
#ifdef PROF_HAVE_GIT_VERSION
g_print("Profanity, version %sdev.%s.%s\n", PROF_PACKAGE_VERSION, PROF_GIT_BRANCH, PROF_GIT_REVISION);
#else
g_print("Profanity, version %sdev\n", PACKAGE_VERSION);
g_print("Profanity, version %sdev\n", PROF_PACKAGE_VERSION);
#endif
} else {
g_print("Profanity, version %s\n", PACKAGE_VERSION);
g_print("Profanity, version %s\n", PROF_PACKAGE_VERSION);
}
g_print("Copyright (C) 2012 - 2015 James Booth <%s>.\n", PACKAGE_BUGREPORT);
g_print("Copyright (C) 2012 - 2015 James Booth <%s>.\n", PROF_PACKAGE_BUGREPORT);
g_print("License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n");
g_print("\n");
g_print("This is free software; you are free to change and redistribute it.\n");
@ -99,10 +99,10 @@ main(int argc, char **argv)
g_print("Build information:\n");
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
g_print("XMPP library: libmesode\n");
#endif
#ifdef HAVE_LIBSTROPHE
#ifdef PROF_HAVE_LIBSTROPHE
g_print("XMPP library: libstrophe\n");
#endif
@ -112,13 +112,13 @@ main(int argc, char **argv)
g_print("Desktop notification support: Disabled\n");
}
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
g_print("OTR support: Enabled\n");
#else
g_print("OTR support: Disabled\n");
#endif
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
g_print("PGP support: Enabled\n");
#else
g_print("PGP support: Disabled\n");

View File

@ -32,7 +32,7 @@
*
*/
#include "config.h"
#include "prof_config.h"
#include <locale.h>
#include <string.h>

233
src/plugins/api.c Normal file
View File

@ -0,0 +1,233 @@
/*
* api.c
*
* Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
*
* This file is part of Profanity.
*
* Profanity 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.
*
* Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#include <stdlib.h>
#include <assert.h>
#include <glib.h>
#include "log.h"
#include "plugins/callbacks.h"
#include "plugins/autocompleters.h"
#include "profanity.h"
#include "ui/ui.h"
#include "config/theme.h"
#include "command/command.h"
#include "window_list.h"
#include "common.h"
void
api_cons_alert(void)
{
cons_alert();
}
void
api_cons_show(const char * const message)
{
if (message) {
char *parsed = str_replace(message, "\r\n", "\n");
cons_show("%s", parsed);
free(parsed);
}
}
void
api_register_command(const char *command_name, int min_args, int max_args,
const char *usage, const char *short_help, const char *long_help, void *callback,
void(*callback_func)(PluginCommand *command, gchar **args))
{
PluginCommand *command = malloc(sizeof(PluginCommand));
command->command_name = command_name;
command->min_args = min_args;
command->max_args = max_args;
command->usage = usage;
command->short_help = short_help;
command->long_help = long_help;
command->callback = callback;
command->callback_func = callback_func;
callbacks_add_command(command);
}
void
api_register_timed(void *callback, int interval_seconds,
void (*callback_func)(PluginTimedFunction *timed_function))
{
PluginTimedFunction *timed_function = malloc(sizeof(PluginTimedFunction));
timed_function->callback = callback;
timed_function->callback_func = callback_func;
timed_function->interval_seconds = interval_seconds;
timed_function->timer = g_timer_new();
callbacks_add_timed(timed_function);
}
void
api_register_ac(const char *key, char **items)
{
autocompleters_add(key, items);
}
void
api_notify(const char *message, const char *category, int timeout_ms)
{
notify(message, timeout_ms, category);
}
void
api_send_line(char *line)
{
ProfWin *current = wins_get_current();
cmd_process_input(current, line);
}
char *
api_get_current_recipient(void)
{
ProfWin *current = wins_get_current();
if (current->type == WIN_CHAT) {
ProfChatWin *chatwin = (ProfChatWin*)current;
assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK);
return chatwin->barejid;
} else {
return NULL;
}
}
char *
api_get_current_muc(void)
{
ProfWin *current = wins_get_current();
if (current->type == WIN_MUC) {
ProfMucWin *mucwin = (ProfMucWin*)current;
assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK);
return mucwin->roomjid;
} else {
return NULL;
}
}
void
api_log_debug(const char *message)
{
log_debug("%s", message);
}
void
api_log_info(const char *message)
{
log_info("%s", message);
}
void
api_log_warning(const char *message)
{
log_warning("%s", message);
}
void
api_log_error(const char *message)
{
log_error("%s", message);
}
int
api_win_exists(const char *tag)
{
return (wins_get_plugin(tag) != NULL);
}
void
api_win_create(const char *tag, void *callback,
void(*callback_func)(PluginWindowCallback *window_callback, const char *tag, const char * const line))
{
PluginWindowCallback *window = malloc(sizeof(PluginWindowCallback));
window->callback = callback;
window->callback_func = callback_func;
callbacks_add_window_handler(tag, window);
wins_new_plugin(tag);
// set status bar active
ProfPluginWin *pluginwin = wins_get_plugin(tag);
int num = wins_get_num((ProfWin*)pluginwin);
status_bar_active(num);
}
void
api_win_focus(const char *tag)
{
ProfPluginWin *pluginwin = wins_get_plugin(tag);
ui_focus_win((ProfWin*)pluginwin);
}
void
api_win_show(const char *tag, const char *line)
{
ProfPluginWin *pluginwin = wins_get_plugin(tag);
ProfWin *window = (ProfWin*)pluginwin;
win_print(window, '!', 0, NULL, 0, 0, "", line);
}
void
api_win_show_green(const char *tag, const char *line)
{
ProfPluginWin *pluginwin = wins_get_plugin(tag);
ProfWin *window = (ProfWin*)pluginwin;
win_print(window, '!', 0, NULL, 0, THEME_GREEN, "", line);
}
void
api_win_show_red(const char *tag, const char *line)
{
ProfPluginWin *pluginwin = wins_get_plugin(tag);
ProfWin *window = (ProfWin*)pluginwin;
win_print(window, '!', 0, NULL, 0, THEME_RED, "", line);
}
void
api_win_show_cyan(const char *tag, const char *line)
{
ProfPluginWin *pluginwin = wins_get_plugin(tag);
ProfWin *window = (ProfWin*)pluginwin;
win_print(window, '!', 0, NULL, 0, THEME_CYAN, "", line);
}
void
api_win_show_yellow(const char *tag, const char *line)
{
ProfPluginWin *pluginwin = wins_get_plugin(tag);
ProfWin *window = (ProfWin*)pluginwin;
win_print(window, '!', 0, NULL, 0, THEME_YELLOW, "", line);
}

69
src/plugins/api.h Normal file
View File

@ -0,0 +1,69 @@
/*
* api.h
*
* Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
*
* This file is part of Profanity.
*
* Profanity 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.
*
* Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#ifndef API_H
#define API_H
#include "plugins/callbacks.h"
void api_cons_alert(void);
void api_cons_show(const char * const message);
void api_notify(const char *message, const char *category, int timeout_ms);
void api_send_line(char *line);
char * api_get_current_recipient(void);
char * api_get_current_muc(void);
void api_register_command(const char *command_name, int min_args, int max_args,
const char *usage, const char *short_help, const char *long_help,
void *callback, void(*callback_func)(PluginCommand *command, gchar **args));
void api_register_timed(void *callback, int interval_seconds,
void (*callback_func)(PluginTimedFunction *timed_function));
void api_register_ac(const char *key, char **items);
void api_log_debug(const char *message);
void api_log_info(const char *message);
void api_log_warning(const char *message);
void api_log_error(const char *message);
int api_win_exists(const char *tag);
void api_win_create(const char *tag, void *callback,
void(*callback_func)(PluginWindowCallback *window_callback, char *tag, char *line));
void api_win_focus(const char *tag);
void api_win_show(const char *tag, const char *line);
void api_win_show_green(const char *tag, const char *line);
void api_win_show_red(const char *tag, const char *line);
void api_win_show_cyan(const char *tag, const char *line);
void api_win_show_yellow(const char *tag, const char *line);
#endif

View File

@ -0,0 +1,92 @@
/*
* autocompleters.c
*
* Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
*
* This file is part of Profanity.
*
* Profanity 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.
*
* Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#include <string.h>
#include <glib.h>
#include "tools/autocomplete.h"
static GHashTable *autocompleters;
void
autocompleters_init(void)
{
autocompleters = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)autocomplete_free);
}
void
autocompleters_add(const char *key, char **items)
{
Autocomplete new_ac = autocomplete_new();
int i = 0;
for (i = 0; i < g_strv_length(items); i++) {
autocomplete_add(new_ac, items[i]);
}
g_hash_table_insert(autocompleters, strdup(key), new_ac);
}
char *
autocompleters_complete(const char * const input)
{
char *result = NULL;
GList *keys = g_hash_table_get_keys(autocompleters);
GList *curr = keys;
while (curr) {
result = autocomplete_param_with_ac(input, curr->data, g_hash_table_lookup(autocompleters, curr->data), TRUE);
if (result) {
return result;
}
curr = g_list_next(curr);
}
return NULL;
}
void
autocompleters_reset(void)
{
GList *acs = g_hash_table_get_values(autocompleters);
GList *curr = acs;
while (curr) {
autocomplete_reset(curr->data);
curr = g_list_next(curr);
}
}
void autocompleters_destroy(void)
{
g_hash_table_destroy(autocompleters);
}

View File

@ -0,0 +1,46 @@
/*
* autocompleters.h
*
* Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
*
* This file is part of Profanity.
*
* Profanity 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.
*
* Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#ifndef AUTOCOMPLETERS_H
#define AUTOCOMPLETERS_H
#include <glib.h>
void autocompleters_init(void);
void autocompleters_add(const char *key, char **items);
char* autocompleters_complete(const char * const input);
void autocompleters_reset(void);
void autocompleters_destroy(void);
#endif

240
src/plugins/c_api.c Normal file
View File

@ -0,0 +1,240 @@
/*
* c_api.c
*
* Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
*
* This file is part of Profanity.
*
* Profanity 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.
*
* Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#include <stdlib.h>
#include <glib.h>
#include "log.h"
#include "plugins/api.h"
#include "plugins/c_api.h"
#include "plugins/callbacks.h"
#include "plugins/profapi.h"
typedef struct command_wrapper_t {
void(*func)(char **args);
} CommandWrapper;
typedef struct timed_wrapper_t {
void(*func)(void);
} TimedWrapper;
typedef struct window_wrapper_t {
void(*func)(char *tag, char *line);
} WindowWrapper;
static void
c_api_cons_alert(void)
{
api_cons_alert();
}
static void
c_api_cons_show(const char * const message)
{
if (message) {
api_cons_show(message);
}
}
static void
c_api_register_command(const char *command_name, int min_args, int max_args,
const char *usage, const char *short_help, const char *long_help, void(*callback)(char **args))
{
CommandWrapper *wrapper = malloc(sizeof(CommandWrapper));
wrapper->func = callback;
api_register_command(command_name, min_args, max_args, usage,
short_help, long_help, wrapper, c_command_callback);
}
static void
c_api_register_timed(void(*callback)(void), int interval_seconds)
{
TimedWrapper *wrapper = malloc(sizeof(TimedWrapper));
wrapper->func = callback;
api_register_timed(wrapper, interval_seconds, c_timed_callback);
}
static void
c_api_register_ac(const char *key, char **items)
{
api_register_ac(key, items);
}
static void
c_api_notify(const char *message, int timeout_ms, const char *category)
{
api_notify(message, category, timeout_ms);
}
static void
c_api_send_line(char *line)
{
api_send_line(line);
}
static char *
c_api_get_current_recipient(void)
{
return api_get_current_recipient();
}
static char *
c_api_get_current_muc(void)
{
return api_get_current_muc();
}
static void
c_api_log_debug(const char *message)
{
api_log_debug(message);
}
static void
c_api_log_info(const char *message)
{
api_log_info(message);
}
static void
c_api_log_warning(const char *message)
{
api_log_warning(message);
}
static void
c_api_log_error(const char *message)
{
api_log_error(message);
}
int
c_api_win_exists(char *tag)
{
return api_win_exists(tag);
}
void
c_api_win_create(char *tag, void(*callback)(char *tag, char *line))
{
WindowWrapper *wrapper = malloc(sizeof(WindowWrapper));
wrapper->func = callback;
api_win_create(tag, wrapper, c_window_callback);
}
void
c_api_win_focus(char *tag)
{
api_win_focus(tag);
}
void
c_api_win_show(char *tag, char *line)
{
api_win_show(tag, line);
}
void
c_api_win_show_green(char *tag, char *line)
{
api_win_show_green(tag, line);
}
void
c_api_win_show_red(char *tag, char *line)
{
api_win_show_red(tag, line);
}
void
c_api_win_show_cyan(char *tag, char *line)
{
api_win_show_cyan(tag, line);
}
void
c_api_win_show_yellow(char *tag, char *line)
{
api_win_show_yellow(tag, line);
}
void
c_command_callback(PluginCommand *command, gchar **args)
{
CommandWrapper *wrapper = command->callback;
void(*f)(gchar **args) = wrapper->func;
f(args);
}
void
c_timed_callback(PluginTimedFunction *timed_function)
{
TimedWrapper *wrapper = timed_function->callback;
void(*f)(void) = wrapper->func;
f();
}
void
c_window_callback(PluginWindowCallback *window_callback, char *tag, char *line)
{
WindowWrapper *wrapper = window_callback->callback;
void(*f)(char *tag, char *line) = wrapper->func;
f(tag, line);
}
void
c_api_init(void)
{
prof_cons_alert = c_api_cons_alert;
prof_cons_show = c_api_cons_show;
prof_register_command = c_api_register_command;
prof_register_timed = c_api_register_timed;
prof_register_ac = c_api_register_ac;
prof_notify = c_api_notify;
prof_send_line = c_api_send_line;
prof_get_current_recipient = c_api_get_current_recipient;
prof_get_current_muc = c_api_get_current_muc;
prof_log_debug = c_api_log_debug;
prof_log_info = c_api_log_info;
prof_log_warning = c_api_log_warning;
prof_log_error = c_api_log_error;
prof_win_exists = c_api_win_exists;
prof_win_create = c_api_win_create;
prof_win_focus = c_api_win_focus;
prof_win_show = c_api_win_show;
prof_win_show_green = c_api_win_show_green;
prof_win_show_red = c_api_win_show_red;
prof_win_show_cyan = c_api_win_show_cyan;
prof_win_show_yellow = c_api_win_show_yellow;
}

41
src/plugins/c_api.h Normal file
View File

@ -0,0 +1,41 @@
/*
* c_api.h
*
* Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
*
* This file is part of Profanity.
*
* Profanity 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.
*
* Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#include <glib.h>
void c_api_init(void);
void c_command_callback(PluginCommand *command, gchar **args);
void c_timed_callback(PluginTimedFunction *timed_function);
void c_window_callback(PluginWindowCallback *window_callback, char *tag, char *line);

367
src/plugins/c_plugins.c Normal file
View File

@ -0,0 +1,367 @@
/*
* c_plugins.c
*
* Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
*
* This file is part of Profanity.
*
* Profanity 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.
*
* Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#include <dlfcn.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <glib.h>
#include "config/preferences.h"
#include "log.h"
#include "plugins/api.h"
#include "plugins/callbacks.h"
#include "plugins/plugins.h"
#include "plugins/c_plugins.h"
#include "plugins/c_api.h"
#include "ui/ui.h"
void
c_env_init(void)
{
c_api_init();
}
ProfPlugin *
c_plugin_create(const char * const filename)
{
ProfPlugin *plugin;
void *handle = NULL;
gchar *plugins_dir = plugins_get_dir();
GString *path = g_string_new(plugins_dir);
g_free(plugins_dir);
g_string_append(path, "/");
g_string_append(path, filename);
handle = dlopen (path->str, RTLD_NOW | RTLD_GLOBAL);
if (!handle) {
log_warning ("dlopen failed to open `%s', %s", filename, dlerror ());
g_string_free(path, TRUE);
return NULL;
}
gchar *module_name = g_strndup(filename, strlen(filename) - 3);
plugin = malloc(sizeof(ProfPlugin));
plugin->name = strdup(module_name);
plugin->lang = LANG_C;
plugin->module = handle;
plugin->init_func = c_init_hook;
plugin->on_start_func = c_on_start_hook;
plugin->on_shutdown_func = c_on_shutdown_hook;
plugin->on_connect_func = c_on_connect_hook;
plugin->on_disconnect_func = c_on_disconnect_hook;
plugin->pre_chat_message_display = c_pre_chat_message_display_hook;
plugin->post_chat_message_display = c_post_chat_message_display_hook;
plugin->pre_chat_message_send = c_pre_chat_message_send_hook;
plugin->post_chat_message_send = c_post_chat_message_send_hook;
plugin->pre_room_message_display = c_pre_room_message_display_hook;
plugin->post_room_message_display = c_post_room_message_display_hook;
plugin->pre_room_message_send = c_pre_room_message_send_hook;
plugin->post_room_message_send = c_post_room_message_send_hook;
plugin->pre_priv_message_display = c_pre_priv_message_display_hook;
plugin->post_priv_message_display = c_post_priv_message_display_hook;
plugin->pre_priv_message_send = c_pre_priv_message_send_hook;
plugin->post_priv_message_send = c_post_priv_message_send_hook;
g_string_free(path, TRUE);
g_free(module_name);
return plugin;
}
void
c_init_hook(ProfPlugin *plugin, const char * const version, const char * const status)
{
void * f = NULL;
void (*func)(const char * const __version, const char * const __status);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_init"))) {
log_warning ("warning: %s does not have init function", plugin->name);
return ;
}
func = (void (*)(const char * const, const char * const))f;
// FIXME maybe we want to make it boolean to see if it succeeded or not?
func (version, status);
}
void
c_on_start_hook(ProfPlugin *plugin)
{
void * f = NULL;
void (*func)(void);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_on_start")))
return ;
func = (void (*)(void)) f;
func ();
}
void
c_on_shutdown_hook(ProfPlugin *plugin)
{
void * f = NULL;
void (*func)(void);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_on_shutdown")))
return ;
func = (void (*)(void)) f;
func ();
}
void
c_on_connect_hook(ProfPlugin *plugin, const char * const account_name, const char * const fulljid)
{
void * f = NULL;
void (*func)(const char * const __account_name, const char * const __fulljid);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_on_connect")))
return ;
func = (void (*)(const char * const, const char * const)) f;
func (account_name, fulljid);
}
void
c_on_disconnect_hook(ProfPlugin *plugin, const char * const account_name, const char * const fulljid)
{
void * f = NULL;
void (*func)(const char * const __account_name, const char * const __fulljid);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_on_disconnect")))
return ;
func = (void (*)(const char * const, const char * const)) f;
func (account_name, fulljid);
}
char *
c_pre_chat_message_display_hook(ProfPlugin *plugin, const char * const jid, const char *message)
{
void * f = NULL;
char* (*func)(const char * const __jid, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_pre_chat_message_display")))
return NULL;
func = (char* (*)(const char * const, const char *)) f;
return func (jid, message);
}
void
c_post_chat_message_display_hook(ProfPlugin *plugin, const char * const jid, const char *message)
{
void * f = NULL;
void (*func)(const char * const __jid, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_post_chat_message_display")))
return;
func = (void (*)(const char * const, const char *)) f;
func (jid, message);
}
char *
c_pre_chat_message_send_hook(ProfPlugin *plugin, const char * const jid, const char *message)
{
void * f = NULL;
char* (*func)(const char * const __jid, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_pre_chat_message_send")))
return NULL;
func = (char* (*)(const char * const, const char *)) f;
return func (jid, message);
}
void
c_post_chat_message_send_hook(ProfPlugin *plugin, const char * const jid, const char *message)
{
void * f = NULL;
void (*func)(const char * const __jid, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_post_chat_message_send")))
return;
func = (void (*)(const char * const, const char *)) f;
func (jid, message);
}
char *
c_pre_room_message_display_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char *message)
{
void * f = NULL;
char* (*func)(const char * const __room, const char * const __nick, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_pre_room_message_display")))
return NULL;
func = (char* (*)(const char * const, const char * const, const char *)) f;
return func (room, nick, message);
}
void
c_post_room_message_display_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char *message)
{
void * f = NULL;
void (*func)(const char * const __room, const char * const __nick, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_post_room_message_display")))
return;
func = (void (*)(const char * const, const char * const, const char *)) f;
func (room, nick, message);
}
char *
c_pre_room_message_send_hook(ProfPlugin *plugin, const char * const room, const char *message)
{
void * f = NULL;
char* (*func)(const char * const __room, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_pre_room_message_send")))
return NULL;
func = (char* (*)(const char * const, const char *)) f;
return func (room, message);
}
void
c_post_room_message_send_hook(ProfPlugin *plugin, const char * const room, const char *message)
{
void * f = NULL;
void (*func)(const char * const __room, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_post_room_message_send")))
return;
func = (void (*)(const char * const, const char *)) f;
func (room, message);
}
char *
c_pre_priv_message_display_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char *message)
{
void * f = NULL;
char* (*func)(const char * const __room, const char * const __nick, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_pre_priv_message_display")))
return NULL;
func = (char* (*)(const char * const, const char * const, const char *)) f;
return func (room, nick, message);
}
void
c_post_priv_message_display_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char *message)
{
void * f = NULL;
void (*func)(const char * const __room, const char * const __nick, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_post_priv_message_display")))
return;
func = (void (*)(const char * const, const char * const, const char *)) f;
func (room, nick, message);
}
char *
c_pre_priv_message_send_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char *message)
{
void * f = NULL;
char* (*func)(const char * const __room, const char * const __nick, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_pre_priv_message_send")))
return NULL;
func = (char* (*)(const char * const, const char * const, const char *)) f;
return func (room, nick, message);
}
void
c_post_priv_message_send_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char *message)
{
void * f = NULL;
void (*func)(const char * const __room, const char * const __nick, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_post_priv_message_send")))
return;
func = (void (*)(const char * const, const char * const, const char *)) f;
func (room, nick, message);
}
void
c_plugin_destroy(ProfPlugin *plugin)
{
assert (plugin && plugin->module);
if (dlclose (plugin->module)) {
log_warning ("dlclose failed to close `%s' with `%s'", plugin->name, dlerror ());
}
free(plugin->name);
free(plugin);
}
void
c_shutdown(void)
{
}

67
src/plugins/c_plugins.h Normal file
View File

@ -0,0 +1,67 @@
/*
* c_plugins.h
*
* Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
*
* This file is part of Profanity.
*
* Profanity 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.
*
* Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#ifndef C_PLUGINS_H
#define C_PLUGINS_H
#include "plugins/plugins.h"
void c_env_init(void);
ProfPlugin* c_plugin_create(const char * const filename);
void c_plugin_destroy(ProfPlugin * plugin);
void c_shutdown(void);
void c_init_hook(ProfPlugin *plugin, const char * const version, const char * const status);
void c_on_start_hook(ProfPlugin *plugin);
void c_on_shutdown_hook(ProfPlugin *plugin);
void c_on_connect_hook(ProfPlugin *plugin, const char * const account_name, const char * const fulljid);
void c_on_disconnect_hook(ProfPlugin *plugin, const char * const account_name, const char * const fulljid);
char* c_pre_chat_message_display_hook(ProfPlugin *plugin, const char * const jid, const char *message);
void c_post_chat_message_display_hook(ProfPlugin *plugin, const char * const jid, const char *message);
char* c_pre_chat_message_send_hook(ProfPlugin *plugin, const char * const jid, const char *message);
void c_post_chat_message_send_hook(ProfPlugin *plugin, const char * const jid, const char *message);
char* c_pre_room_message_display_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char *message);
void c_post_room_message_display_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char *message);
char* c_pre_room_message_send_hook(ProfPlugin *plugin, const char * const room, const char *message);
void c_post_room_message_send_hook(ProfPlugin *plugin, const char * const room, const char *message);
char* c_pre_priv_message_display_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char *message);
void c_post_priv_message_display_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char *message);
char* c_pre_priv_message_send_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char * const message);
void c_post_priv_message_send_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char * const message);
#endif

126
src/plugins/callbacks.c Normal file
View File

@ -0,0 +1,126 @@
/*
* callbacks.c
*
* Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
*
* This file is part of Profanity.
*
* Profanity 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.
*
* Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#include <string.h>
#include "command/command.h"
#include "plugins/callbacks.h"
#include "plugins/plugins.h"
#include "tools/autocomplete.h"
#include "tools/parser.h"
#include "ui/ui.h"
static GSList *p_commands = NULL;
static GSList *p_timed_functions = NULL;
static GHashTable *p_window_callbacks = NULL;
void
callbacks_add_command(PluginCommand *command)
{
p_commands = g_slist_append(p_commands, command);
cmd_autocomplete_add(command->command_name);
}
void
callbacks_add_timed(PluginTimedFunction *timed_function)
{
p_timed_functions = g_slist_append(p_timed_functions, timed_function);
}
void
callbacks_add_window_handler(const char *tag, PluginWindowCallback *window_callback)
{
if (p_window_callbacks == NULL) {
p_window_callbacks = g_hash_table_new(g_str_hash, g_str_equal);
}
g_hash_table_insert(p_window_callbacks, strdup(tag), window_callback);
}
void *
callbacks_get_window_handler(const char *tag)
{
if (p_window_callbacks) {
return g_hash_table_lookup(p_window_callbacks, tag);
} else {
return NULL;
}
}
gboolean
plugins_run_command(const char * const input)
{
gchar **split = g_strsplit(input, " ", -1);
GSList *p_command = p_commands;
while (p_command) {
PluginCommand *command = p_command->data;
if (g_strcmp0(split[0], command->command_name) == 0) {
gboolean result;
gchar **args = parse_args(input, command->min_args, command->max_args, &result);
if (result == FALSE) {
ui_invalid_command_usage(command->usage, NULL);
return TRUE;
} else {
command->callback_func(command, args);
g_strfreev(split);
return TRUE;
}
g_strfreev(args);
}
p_command = g_slist_next(p_command);
}
g_strfreev(split);
return FALSE;
}
void
plugins_run_timed(void)
{
GSList *p_timed_function = p_timed_functions;
while (p_timed_function) {
PluginTimedFunction *timed_function = p_timed_function->data;
gdouble elapsed = g_timer_elapsed(timed_function->timer, NULL);
if (timed_function->interval_seconds > 0 && elapsed >= timed_function->interval_seconds) {
timed_function->callback_func(timed_function);
g_timer_start(timed_function->timer);
}
p_timed_function = g_slist_next(p_timed_function);
}
return;
}

68
src/plugins/callbacks.h Normal file
View File

@ -0,0 +1,68 @@
/*
* callbacks.h
*
* Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
*
* This file is part of Profanity.
*
* Profanity 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.
*
* Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#ifndef CALLBACKS_H
#define CALLBACKS_H
#include <glib.h>
typedef struct p_command {
const char *command_name;
int min_args;
int max_args;
const char *usage;
const char *short_help;
const char *long_help;
void *callback;
void (*callback_func)(struct p_command *command, gchar **args);
} PluginCommand;
typedef struct p_timed_function {
void *callback;
void (*callback_func)(struct p_timed_function *timed_function);
int interval_seconds;
GTimer *timer;
} PluginTimedFunction;
typedef struct p_window_input_callback {
void *callback;
void (*callback_func)(struct p_window_input_callback *window_callback, const char *tag, const char * const line);
} PluginWindowCallback;
void callbacks_add_command(PluginCommand *command);
void callbacks_add_timed(PluginTimedFunction *timed_function);
void callbacks_add_window_handler(const char *tag, PluginWindowCallback *window_callback);
void * callbacks_get_window_handler(const char *tag);
#endif

497
src/plugins/plugins.c Normal file
View File

@ -0,0 +1,497 @@
/*
* plugins.c
*
* Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
*
* This file is part of Profanity.
*
* Profanity 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.
*
* Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#include <string.h>
#include <stdlib.h>
#include "common.h"
#include "config/preferences.h"
#include "log.h"
#include "plugins/callbacks.h"
#include "plugins/autocompleters.h"
#include "plugins/api.h"
#include "plugins/plugins.h"
#ifdef PROF_HAVE_PYTHON
#include "plugins/python_plugins.h"
#include "plugins/python_api.h"
#endif
#ifdef PROF_HAVE_RUBY
#include "plugins/ruby_plugins.h"
#include "plugins/ruby_api.h"
#endif
#ifdef PROF_HAVE_LUA
#include "plugins/lua_plugins.h"
#include "plugins/lua_api.h"
#endif
#ifdef PROF_HAVE_C
#include "plugins/c_plugins.h"
#include "plugins/c_api.h"
#endif
#include "ui/ui.h"
static GSList* plugins;
void
plugins_init(void)
{
plugins = NULL;
autocompleters_init();
#ifdef PROF_HAVE_PYTHON
python_env_init();
#endif
#ifdef PROF_HAVE_RUBY
ruby_env_init();
#endif
#ifdef PROF_HAVE_LUA
lua_env_init();
#endif
#ifdef PROF_HAVE_C
c_env_init();
#endif
// load plugins
gchar **plugins_load = prefs_get_plugins();
if (plugins_load) {
int i;
for (i = 0; i < g_strv_length(plugins_load); i++)
{
gboolean loaded = FALSE;
gchar *filename = plugins_load[i];
#ifdef PROF_HAVE_PYTHON
if (g_str_has_suffix(filename, ".py")) {
ProfPlugin *plugin = python_plugin_create(filename);
if (plugin) {
plugins = g_slist_append(plugins, plugin);
loaded = TRUE;
}
}
#endif
#ifdef PROF_HAVE_RUBY
if (g_str_has_suffix(filename, ".rb")) {
ProfPlugin *plugin = ruby_plugin_create(filename);
if (plugin) {
plugins = g_slist_append(plugins, plugin);
loaded = TRUE;
}
}
#endif
#ifdef PROF_HAVE_LUA
if (g_str_has_suffix(filename, ".lua")) {
ProfPlugin *plugin = lua_plugin_create(filename);
if (plugin) {
plugins = g_slist_append(plugins, plugin);
loaded = TRUE;
}
}
#endif
#ifdef PROF_HAVE_C
if (g_str_has_suffix(filename, ".so")) {
ProfPlugin *plugin = c_plugin_create(filename);
if (plugin) {
plugins = g_slist_append(plugins, plugin);
loaded = TRUE;
}
}
#endif
if (loaded == TRUE) {
log_info("Loaded plugin: %s", filename);
}
}
// initialise plugins
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
plugin->init_func(plugin, PROF_PACKAGE_VERSION, PROF_PACKAGE_STATUS);
curr = g_slist_next(curr);
}
}
return;
}
GSList *
plugins_get_list(void)
{
return plugins;
}
char *
plugins_get_lang_string(ProfPlugin *plugin)
{
switch (plugin->lang)
{
case LANG_PYTHON:
return "Python";
case LANG_RUBY:
return "Ruby";
case LANG_LUA:
return "Lua";
case LANG_C:
return "C";
default:
return "Unknown";
}
}
char *
plugins_autocomplete(const char * const input)
{
return autocompleters_complete(input);
}
void
plugins_reset_autocomplete(void)
{
autocompleters_reset();
}
void
plugins_win_process_line(char *win, const char * const line)
{
PluginWindowCallback *window = callbacks_get_window_handler(win);
window->callback_func(window, win, line);
}
void
plugins_on_start(void)
{
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
plugin->on_start_func(plugin);
curr = g_slist_next(curr);
}
}
void
plugins_on_shutdown(void)
{
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
plugin->on_shutdown_func(plugin);
curr = g_slist_next(curr);
}
}
void
plugins_on_connect(const char * const account_name, const char * const fulljid)
{
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
plugin->on_connect_func(plugin, account_name, fulljid);
curr = g_slist_next(curr);
}
}
void
plugins_on_disconnect(const char * const account_name, const char * const fulljid)
{
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
plugin->on_disconnect_func(plugin, account_name, fulljid);
curr = g_slist_next(curr);
}
}
char*
plugins_pre_chat_message_display(const char * const jid, const char *message)
{
char *new_message = NULL;
char *curr_message = strdup(message);
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
new_message = plugin->pre_chat_message_display(plugin, jid, curr_message);
if (new_message) {
free(curr_message);
curr_message = strdup(new_message);
free(new_message);
}
curr = g_slist_next(curr);
}
return curr_message;
}
void
plugins_post_chat_message_display(const char * const jid, const char *message)
{
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
plugin->post_chat_message_display(plugin, jid, message);
curr = g_slist_next(curr);
}
}
char*
plugins_pre_chat_message_send(const char * const jid, const char *message)
{
char *new_message = NULL;
char *curr_message = strdup(message);
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
new_message = plugin->pre_chat_message_send(plugin, jid, curr_message);
if (new_message) {
free(curr_message);
curr_message = strdup(new_message);
free(new_message);
}
curr = g_slist_next(curr);
}
return curr_message;
}
void
plugins_post_chat_message_send(const char * const jid, const char *message)
{
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
plugin->post_chat_message_send(plugin, jid, message);
curr = g_slist_next(curr);
}
}
char*
plugins_pre_room_message_display(const char * const room, const char * const nick, const char *message)
{
char *new_message = NULL;
char *curr_message = strdup(message);
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
new_message = plugin->pre_room_message_display(plugin, room, nick, curr_message);
if (new_message) {
free(curr_message);
curr_message = strdup(new_message);
free(new_message);
}
curr = g_slist_next(curr);
}
return curr_message;
}
void
plugins_post_room_message_display(const char * const room, const char * const nick, const char *message)
{
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
plugin->post_room_message_display(plugin, room, nick, message);
curr = g_slist_next(curr);
}
}
char*
plugins_pre_room_message_send(const char * const room, const char *message)
{
char *new_message = NULL;
char *curr_message = strdup(message);
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
new_message = plugin->pre_room_message_send(plugin, room, curr_message);
if (new_message) {
free(curr_message);
curr_message = strdup(new_message);
free(new_message);
}
curr = g_slist_next(curr);
}
return curr_message;
}
void
plugins_post_room_message_send(const char * const room, const char *message)
{
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
plugin->post_room_message_send(plugin, room, message);
curr = g_slist_next(curr);
}
}
char*
plugins_pre_priv_message_display(const char * const jid, const char *message)
{
Jid *jidp = jid_create(jid);
char *new_message = NULL;
char *curr_message = strdup(message);
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
new_message = plugin->pre_priv_message_display(plugin, jidp->barejid, jidp->resourcepart, curr_message);
if (new_message) {
free(curr_message);
curr_message = strdup(new_message);
free(new_message);
}
curr = g_slist_next(curr);
}
jid_destroy(jidp);
return curr_message;
}
void
plugins_post_priv_message_display(const char * const jid, const char *message)
{
Jid *jidp = jid_create(jid);
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
plugin->post_priv_message_display(plugin, jidp->barejid, jidp->resourcepart, message);
curr = g_slist_next(curr);
}
jid_destroy(jidp);
}
char*
plugins_pre_priv_message_send(const char * const jid, const char * const message)
{
Jid *jidp = jid_create(jid);
char *new_message = NULL;
char *curr_message = strdup(message);
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
new_message = plugin->pre_priv_message_send(plugin, jidp->barejid, jidp->resourcepart, curr_message);
if (new_message) {
free(curr_message);
curr_message = strdup(new_message);
free(new_message);
}
curr = g_slist_next(curr);
}
jid_destroy(jidp);
return curr_message;
}
void
plugins_post_priv_message_send(const char * const jid, const char * const message)
{
Jid *jidp = jid_create(jid);
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
plugin->post_priv_message_send(plugin, jidp->barejid, jidp->resourcepart, message);
curr = g_slist_next(curr);
}
jid_destroy(jidp);
}
void
plugins_shutdown(void)
{
GSList *curr = plugins;
while (curr) {
#ifdef PROF_HAVE_PYTHON
if (((ProfPlugin *)curr->data)->lang == LANG_PYTHON) {
python_plugin_destroy(curr->data);
}
#endif
#ifdef PROF_HAVE_RUBY
if (((ProfPlugin *)curr->data)->lang == LANG_RUBY) {
ruby_plugin_destroy(curr->data);
}
#endif
#ifdef PROF_HAVE_LUA
if (((ProfPlugin *)curr->data)->lang == LANG_LUA) {
lua_plugin_destroy(curr->data);
}
#endif
#ifdef PROF_HAVE_C
if (((ProfPlugin *)curr->data)->lang == LANG_C) {
c_plugin_destroy(curr->data);
}
#endif
curr = g_slist_next(curr);
}
#ifdef PROF_HAVE_PYTHON
python_shutdown();
#endif
#ifdef PROF_HAVE_RUBY
ruby_shutdown();
#endif
#ifdef PROF_HAVE_LUA
lua_shutdown();
#endif
#ifdef PROF_HAVE_C
c_shutdown();
#endif
autocompleters_destroy();
}
gchar *
plugins_get_dir(void)
{
gchar *xdg_data = xdg_get_data_home();
GString *plugins_dir = g_string_new(xdg_data);
g_string_append(plugins_dir, "/profanity/plugins");
gchar *result = strdup(plugins_dir->str);
g_free(xdg_data);
g_string_free(plugins_dir, TRUE);
return result;
}

108
src/plugins/plugins.h Normal file
View File

@ -0,0 +1,108 @@
/*
* plugins.h
*
* Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
*
* This file is part of Profanity.
*
* Profanity 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.
*
* Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#ifndef PLUGINS_H
#define PLUGINS_H
typedef enum {
LANG_PYTHON,
LANG_RUBY,
LANG_LUA,
LANG_C
} lang_t;
typedef struct prof_plugin_t {
char *name;
lang_t lang;
void *module;
void (*init_func)(struct prof_plugin_t* plugin, const char * const version,
const char * const status);
void (*on_start_func)(struct prof_plugin_t* plugin);
void (*on_shutdown_func)(struct prof_plugin_t* plugin);
void (*on_connect_func)(struct prof_plugin_t* plugin, const char * const account_name, const char * const fulljid);
void (*on_disconnect_func)(struct prof_plugin_t* plugin, const char * const account_name, const char * const fulljid);
char* (*pre_chat_message_display)(struct prof_plugin_t* plugin, const char * const jid, const char *message);
void (*post_chat_message_display)(struct prof_plugin_t* plugin, const char * const jid, const char *message);
char* (*pre_chat_message_send)(struct prof_plugin_t* plugin, const char * const jid, const char *message);
void (*post_chat_message_send)(struct prof_plugin_t* plugin, const char * const jid, const char *message);
char* (*pre_room_message_display)(struct prof_plugin_t* plugin, const char * const room, const char * const nick, const char *message);
void (*post_room_message_display)(struct prof_plugin_t* plugin, const char * const room, const char * const nick, const char *message);
char* (*pre_room_message_send)(struct prof_plugin_t* plugin, const char * const room, const char *message);
void (*post_room_message_send)(struct prof_plugin_t* plugin, const char * const room, const char *message);
char* (*pre_priv_message_display)(struct prof_plugin_t* plugin, const char * const room, const char * const nick, const char *message);
void (*post_priv_message_display)(struct prof_plugin_t* plugin, const char * const room, const char * const nick, const char *message);
char* (*pre_priv_message_send)(struct prof_plugin_t* plugin, const char * const room, const char * const nick, const char * const message);
void (*post_priv_message_send)(struct prof_plugin_t* plugin, const char * const room, const char * const nick, const char * const message);
} ProfPlugin;
void plugins_init(void);
GSList* plugins_get_list(void);
char* plugins_get_lang_string(ProfPlugin *plugin);
char* plugins_autocomplete(const char * const input);
void plugins_reset_autocomplete(void);
void plugins_shutdown(void);
void plugins_on_start(void);
void plugins_on_shutdown(void);
void plugins_on_connect(const char * const account_name, const char * const fulljid);
void plugins_on_disconnect(const char * const account_name, const char * const fulljid);
char* plugins_pre_chat_message_display(const char * const jid, const char *message);
void plugins_post_chat_message_display(const char * const jid, const char *message);
char* plugins_pre_chat_message_send(const char * const jid, const char *message);
void plugins_post_chat_message_send(const char * const jid, const char *message);
char* plugins_pre_room_message_display(const char * const room, const char * const nick, const char *message);
void plugins_post_room_message_display(const char * const room, const char * const nick, const char *message);
char* plugins_pre_room_message_send(const char * const room, const char *message);
void plugins_post_room_message_send(const char * const room, const char *message);
char* plugins_pre_priv_message_display(const char * const jid, const char *message);
void plugins_post_priv_message_display(const char * const jid, const char *message);
char* plugins_pre_priv_message_send(const char * const jid, const char * const message);
void plugins_post_priv_message_send(const char * const jid, const char * const message);
gboolean plugins_run_command(const char * const cmd);
void plugins_run_timed(void);
gchar * plugins_get_dir(void);
void plugins_win_process_line(char *win, const char * const line);
#endif

70
src/plugins/profapi.c Normal file
View File

@ -0,0 +1,70 @@
/*
* prof_api.c
*
* Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
*
* This file is part of Profanity.
*
* Profanity 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.
*
* Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#include <stdlib.h>
#include "plugins/profapi.h"
#include "plugins/callbacks.h"
void (*prof_cons_alert)(void) = NULL;
void (*prof_cons_show)(const char * const message) = NULL;
void (*prof_register_command)(const char *command_name, int min_args, int max_args,
const char *usage, const char *short_help, const char *long_help, void(*callback)(char **args)) = NULL;
void (*prof_register_timed)(void(*callback)(void), int interval_seconds) = NULL;
void (*prof_register_ac)(const char *key, char **items) = NULL;
void (*prof_notify)(const char *message, int timeout_ms, const char *category) = NULL;
void (*prof_send_line)(char *line) = NULL;
char* (*prof_get_current_recipient)(void) = NULL;
char* (*prof_get_current_muc)(void) = NULL;
void (*prof_log_debug)(const char *message) = NULL;
void (*prof_log_info)(const char *message) = NULL;
void (*prof_log_warning)(const char *message) = NULL;
void (*prof_log_error)(const char *message) = NULL;
int (*prof_win_exists)(PROF_WIN_TAG win) = NULL;
void (*prof_win_create)(PROF_WIN_TAG win, void(*input_handler)(PROF_WIN_TAG win, char *line)) = NULL;
void (*prof_win_focus)(PROF_WIN_TAG win) = NULL;
void (*prof_win_show)(PROF_WIN_TAG win, char *line) = NULL;
void (*prof_win_show_green)(PROF_WIN_TAG win, char *line) = NULL;
void (*prof_win_show_red)(PROF_WIN_TAG win, char *line) = NULL;
void (*prof_win_show_cyan)(PROF_WIN_TAG win, char *line) = NULL;
void (*prof_win_show_yellow)(PROF_WIN_TAG win, char *line) = NULL;

72
src/plugins/profapi.h Normal file
View File

@ -0,0 +1,72 @@
/*
* prof_api.h
*
* Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com>
*
* This file is part of Profanity.
*
* Profanity 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.
*
* Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#ifndef PROF_API_H
#define PROF_API_H
typedef char* PROF_WIN_TAG;
void (*prof_cons_alert)(void);
void (*prof_cons_show)(const char * const message);
void (*prof_register_command)(const char *command_name, int min_args, int max_args,
const char *usage, const char *short_help, const char *long_help, void(*callback)(char **args));
void (*prof_register_timed)(void(*callback)(void), int interval_seconds);
void (*prof_register_ac)(const char *key, char **items);
void (*prof_notify)(const char *message, int timeout_ms, const char *category);
void (*prof_send_line)(char *line);
char* (*prof_get_current_recipient)(void);
char* (*prof_get_current_muc)(void);
void (*prof_log_debug)(const char *message);
void (*prof_log_info)(const char *message);
void (*prof_log_warning)(const char *message);
void (*prof_log_error)(const char *message);
int (*prof_win_exists)(PROF_WIN_TAG win);
void (*prof_win_create)(PROF_WIN_TAG win, void(*input_handler)(PROF_WIN_TAG win, char *line));
void (*prof_win_focus)(PROF_WIN_TAG win);
void (*prof_win_show)(PROF_WIN_TAG win, char *line);
void (*prof_win_show_green)(PROF_WIN_TAG win, char *line);
void (*prof_win_show_red)(PROF_WIN_TAG win, char *line);
void (*prof_win_show_cyan)(PROF_WIN_TAG win, char *line);
void (*prof_win_show_yellow)(PROF_WIN_TAG win, char *line);
#endif

View File

@ -31,9 +31,9 @@
* source files in the program, then also delete it here.
*
*/
#include "config.h"
#include "prof_config.h"
#ifdef HAVE_GIT_VERSION
#ifdef PROF_HAVE_GIT_VERSION
#include "gitversion.h"
#endif
@ -59,10 +59,11 @@
#include "config/tlscerts.h"
#include "log.h"
#include "muc.h"
#ifdef HAVE_LIBOTR
#include "plugins/plugins.h"
#ifdef PROF_HAVE_LIBOTR
#include "otr/otr.h"
#endif
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
#include "pgp/gpg.h"
#endif
#include "resource.h"
@ -96,7 +97,9 @@ void
prof_run(char *log_level, char *account_name)
{
_init(log_level);
plugins_on_start();
_connect_default(account_name);
ui_update();
log_info("Starting main event loop");
@ -119,9 +122,10 @@ prof_run(char *log_level, char *account_name)
cont = TRUE;
}
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
otr_poll();
#endif
plugins_run_timed();
notify_remind();
jabber_process_events(10);
iq_autoping_check();
@ -318,14 +322,14 @@ _init(char *log_level)
prefs_load();
log_init(prof_log_level);
log_stderr_init(PROF_LEVEL_ERROR);
if (strcmp(PACKAGE_STATUS, "development") == 0) {
#ifdef HAVE_GIT_VERSION
log_info("Starting Profanity (%sdev.%s.%s)...", PACKAGE_VERSION, PROF_GIT_BRANCH, PROF_GIT_REVISION);
if (strcmp(PROF_PACKAGE_STATUS, "development") == 0) {
#ifdef PROF_HAVE_GIT_VERSION
log_info("Starting Profanity (%sdev.%s.%s)...", PROF_PACKAGE_VERSION, PROF_GIT_BRANCH, PROF_GIT_REVISION);
#else
log_info("Starting Profanity (%sdev)...", PACKAGE_VERSION);
log_info("Starting Profanity (%sdev)...", PROF_PACKAGE_VERSION);
#endif
} else {
log_info("Starting Profanity (%s)...", PACKAGE_VERSION);
log_info("Starting Profanity (%s)...", PROF_PACKAGE_VERSION);
}
chat_log_init();
groupchat_log_init();
@ -340,13 +344,14 @@ _init(char *log_level)
muc_init();
tlscerts_init();
scripts_init();
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
otr_init();
#endif
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
p_gpg_init();
#endif
atexit(_shutdown);
plugins_init();
inp_nonblocking(TRUE);
}
@ -367,13 +372,14 @@ _shutdown(void)
}
jabber_shutdown();
plugins_on_shutdown();
muc_close();
caps_close();
ui_close();
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
otr_shutdown();
#endif
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
p_gpg_close();
#endif
chat_log_close();
@ -383,6 +389,7 @@ _shutdown(void)
cmd_uninit();
log_stderr_close();
log_close();
plugins_shutdown();
prefs_close();
if (saved_status) {
free(saved_status);
@ -401,6 +408,8 @@ _create_directories(void)
g_string_append(chatlogs_dir, "/profanity/chatlogs");
GString *logs_dir = g_string_new(xdg_data);
g_string_append(logs_dir, "/profanity/logs");
GString *plugins_dir = g_string_new(xdg_data);
g_string_append(plugins_dir, "/profanity/plugins");
if (!mkdir_recursive(themes_dir->str)) {
log_error("Error while creating directory %s", themes_dir->str);
@ -411,10 +420,14 @@ _create_directories(void)
if (!mkdir_recursive(logs_dir->str)) {
log_error("Error while creating directory %s", logs_dir->str);
}
if (!mkdir_recursive(plugins_dir->str)) {
log_error("Error while creating directory %s", plugins_dir->str);
}
g_string_free(themes_dir, TRUE);
g_string_free(chatlogs_dir, TRUE);
g_string_free(logs_dir, TRUE);
g_string_free(plugins_dir, TRUE);
g_free(xdg_config);
g_free(xdg_data);

View File

@ -42,8 +42,7 @@ void prof_run(char *log_level, char *account_name);
void prof_handle_idle(void);
void prof_handle_activity(void);
gboolean process_input(char *inp);
gboolean prof_process_input(char *inp);
void prof_set_quit(void);

View File

@ -32,7 +32,7 @@
*
*/
#include "config.h"
#include "prof_config.h"
#include <stdlib.h>
#include <string.h>
@ -40,9 +40,9 @@
#include <stdlib.h>
#include <glib.h>
#ifdef HAVE_NCURSESW_NCURSES_H
#ifdef PROF_HAVE_NCURSESW_NCURSES_H
#include <ncursesw/ncurses.h>
#elif HAVE_NCURSES_H
#elif PROF_HAVE_NCURSES_H
#include <ncurses.h>
#endif

View File

@ -35,7 +35,7 @@
#ifndef UI_BUFFER_H
#define UI_BUFFER_H
#include "config.h"
#include "prof_config.h"
#include "config/theme.h"
#include <glib.h>

View File

@ -32,7 +32,7 @@
*
*/
#include "config.h"
#include "prof_config.h"
#include <string.h>
#include <stdlib.h>
@ -46,7 +46,8 @@
#include "ui/ui.h"
#include "ui/window.h"
#include "ui/titlebar.h"
#ifdef HAVE_LIBOTR
#include "plugins/plugins.h"
#ifdef PROF_HAVE_LIBOTR
#include "otr/otr.h"
#endif
@ -84,7 +85,7 @@ chatwin_receipt_received(ProfChatWin *chatwin, const char *const id)
win_mark_received(win, id);
}
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
void
chatwin_otr_secured(ProfChatWin *chatwin, gboolean trusted)
{
@ -234,6 +235,8 @@ chatwin_incoming_msg(ProfChatWin *chatwin, const char *const resource, const cha
{
assert(chatwin != NULL);
char *plugin_message = plugins_pre_chat_message_display(chatwin->barejid, message);
ProfWin *window = (ProfWin*)chatwin;
int num = wins_get_num(window);
@ -244,7 +247,7 @@ chatwin_incoming_msg(ProfChatWin *chatwin, const char *const resource, const cha
// currently viewing chat window with sender
if (wins_is_current(window)) {
win_print_incoming_message(window, timestamp, display_name, message, enc_mode);
win_print_incoming_message(window, timestamp, display_name, plugin_message, enc_mode);
title_bar_set_typing(FALSE);
status_bar_active(num);
@ -271,7 +274,7 @@ chatwin_incoming_msg(ProfChatWin *chatwin, const char *const resource, const cha
}
}
win_print_incoming_message(window, timestamp, display_name, message, enc_mode);
win_print_incoming_message(window, timestamp, display_name, plugin_message, enc_mode);
}
if (prefs_get_boolean(PREF_BEEP)) {
@ -279,10 +282,14 @@ chatwin_incoming_msg(ProfChatWin *chatwin, const char *const resource, const cha
}
if (notify) {
notify_message(display_name, num, message);
notify_message(display_name, num, plugin_message);
}
free(display_name);
plugins_post_chat_message_display(chatwin->barejid, plugin_message);
free(plugin_message);
}
void

View File

@ -37,9 +37,9 @@
#include <stdlib.h>
#include <assert.h>
#ifdef HAVE_NCURSESW_NCURSES_H
#ifdef PROF_HAVE_NCURSESW_NCURSES_H
#include <ncursesw/ncurses.h>
#elif HAVE_NCURSES_H
#elif PROF_HAVE_NCURSES_H
#include <ncurses.h>
#endif
@ -57,7 +57,7 @@
#include "xmpp/xmpp.h"
#include "xmpp/bookmark.h"
#ifdef HAVE_GIT_VERSION
#ifdef PROF_HAVE_GIT_VERSION
#include "gitversion.h"
#endif
@ -82,7 +82,7 @@ void
cons_debug(const char *const msg, ...)
{
ProfWin *console = wins_get_console();
if (strcmp(PACKAGE_STATUS, "development") == 0) {
if (strcmp(PROF_PACKAGE_STATUS, "development") == 0) {
va_list arg;
va_start(arg, msg);
GString *fmt_msg = g_string_new(NULL);
@ -416,18 +416,18 @@ cons_about(void)
_cons_splash_logo();
} else {
if (strcmp(PACKAGE_STATUS, "development") == 0) {
#ifdef HAVE_GIT_VERSION
win_vprint(console, '-', 0, NULL, 0, 0, "", "Welcome to Profanity, version %sdev.%s.%s", PACKAGE_VERSION, PROF_GIT_BRANCH, PROF_GIT_REVISION);
if (strcmp(PROF_PACKAGE_STATUS, "development") == 0) {
#ifdef PROF_HAVE_GIT_VERSION
win_vprint(console, '-', 0, NULL, 0, 0, "", "Welcome to Profanity, version %sdev.%s.%s", PROF_PACKAGE_VERSION, PROF_GIT_BRANCH, PROF_GIT_REVISION);
#else
win_vprint(console, '-', 0, NULL, 0, 0, "", "Welcome to Profanity, version %sdev", PACKAGE_VERSION);
win_vprint(console, '-', 0, NULL, 0, 0, "", "Welcome to Profanity, version %sdev", PROF_PACKAGE_VERSION);
#endif
} else {
win_vprint(console, '-', 0, NULL, 0, 0, "", "Welcome to Profanity, version %s", PACKAGE_VERSION);
win_vprint(console, '-', 0, NULL, 0, 0, "", "Welcome to Profanity, version %s", PROF_PACKAGE_VERSION);
}
}
win_vprint(console, '-', 0, NULL, 0, 0, "", "Copyright (C) 2012 - 2015 James Booth <%s>.", PACKAGE_BUGREPORT);
win_vprint(console, '-', 0, NULL, 0, 0, "", "Copyright (C) 2012 - 2015 James Booth <%s>.", PROF_PACKAGE_BUGREPORT);
win_println(console, 0, "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>");
win_println(console, 0, "");
win_println(console, 0, "This is free software; you are free to change and redistribute it.");
@ -2304,14 +2304,14 @@ _cons_splash_logo(void)
win_print(console, '-', 0, NULL, 0, THEME_SPLASH, "", "|_| (____/ ");
win_print(console, '-', 0, NULL, 0, THEME_SPLASH, "", "");
if (strcmp(PACKAGE_STATUS, "development") == 0) {
#ifdef HAVE_GIT_VERSION
win_vprint(console, '-', 0, NULL, 0, 0, "", "Version %sdev.%s.%s", PACKAGE_VERSION, PROF_GIT_BRANCH, PROF_GIT_REVISION);
if (strcmp(PROF_PACKAGE_STATUS, "development") == 0) {
#ifdef PROF_HAVE_GIT_VERSION
win_vprint(console, '-', 0, NULL, 0, 0, "", "Version %sdev.%s.%s", PROF_PACKAGE_VERSION, PROF_GIT_BRANCH, PROF_GIT_REVISION);
#else
win_vprint(console, '-', 0, NULL, 0, 0, "", "Version %sdev", PACKAGE_VERSION);
win_vprint(console, '-', 0, NULL, 0, 0, "", "Version %sdev", PROF_PACKAGE_VERSION);
#endif
} else {
win_vprint(console, '-', 0, NULL, 0, 0, "", "Version %s", PACKAGE_VERSION);
win_vprint(console, '-', 0, NULL, 0, 0, "", "Version %s", PROF_PACKAGE_VERSION);
}
}

View File

@ -32,9 +32,9 @@
*
*/
#include "config.h"
#include "prof_config.h"
#ifdef HAVE_GIT_VERSION
#ifdef PROF_HAVE_GIT_VERSION
#include "gitversion.h"
#endif
@ -44,13 +44,13 @@
#include <sys/ioctl.h>
#include <unistd.h>
#ifdef HAVE_LIBXSS
#ifdef PROF_HAVE_LIBXSS
#include <X11/extensions/scrnsaver.h>
#endif
#include <glib.h>
#ifdef HAVE_NCURSESW_NCURSES_H
#ifdef PROF_HAVE_NCURSESW_NCURSES_H
#include <ncursesw/ncurses.h>
#elif HAVE_NCURSES_H
#elif PROF_HAVE_NCURSES_H
#include <ncurses.h>
#endif
@ -64,7 +64,7 @@
#include "jid.h"
#include "log.h"
#include "muc.h"
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
#include "otr/otr.h"
#endif
#include "ui/ui.h"
@ -74,13 +74,14 @@
#include "ui/window.h"
#include "window_list.h"
#include "xmpp/xmpp.h"
#include "plugins/plugins.h"
static char *win_title;
static int inp_size;
static gboolean perform_resize = FALSE;
static GTimer *ui_idle_time;
#ifdef HAVE_LIBXSS
#ifdef PROF_HAVE_LIBXSS
static Display *display;
#endif
@ -104,7 +105,7 @@ ui_init(void)
wins_init();
notifier_initialise();
cons_about();
#ifdef HAVE_LIBXSS
#ifdef PROF_HAVE_LIBXSS
display = XOpenDisplay(0);
#endif
ui_idle_time = g_timer_new();
@ -149,7 +150,7 @@ unsigned long
ui_get_idle_time(void)
{
// if compiled with libxss, get the x sessions idle time
#ifdef HAVE_LIBXSS
#ifdef PROF_HAVE_LIBXSS
XScreenSaverInfo *info = XScreenSaverAllocInfo();
if (info && display) {
XScreenSaverQueryInfo(display, DefaultRootWindow(display), info);
@ -496,7 +497,7 @@ ui_close_connected_win(int index)
} else if (window->type == WIN_CHAT) {
ProfChatWin *chatwin = (ProfChatWin*) window;
assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK);
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
if (chatwin->is_otr) {
otr_end_session(chatwin->barejid);
}
@ -1325,3 +1326,21 @@ ui_show_software_version(const char *const jid, const char *const presence,
win_vprint(window, '-', 0, NULL, 0, 0, "", "OS : %s", os);
}
}
void
ui_status_bar_inactive(const int win)
{
status_bar_inactive(win);
}
void
ui_status_bar_active(const int win)
{
status_bar_active(win);
}
void
ui_status_bar_new(const int win)
{
status_bar_new(win);
}

View File

@ -33,7 +33,7 @@
*/
#define _XOPEN_SOURCE_EXTENDED
#include "config.h"
#include "prof_config.h"
#include <sys/select.h>
#include <stdlib.h>
@ -46,9 +46,9 @@
#include <readline/readline.h>
#include <readline/history.h>
#ifdef HAVE_NCURSESW_NCURSES_H
#ifdef PROF_HAVE_NCURSESW_NCURSES_H
#include <ncursesw/ncurses.h>
#elif HAVE_NCURSES_H
#elif PROF_HAVE_NCURSES_H
#include <ncurses.h>
#endif

View File

@ -31,14 +31,14 @@
* source files in the program, then also delete it here.
*
*/
#include "config.h"
#include "prof_config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <glib.h>
#ifdef HAVE_LIBNOTIFY
#ifdef PROF_HAVE_LIBNOTIFY
#include <libnotify/notify.h>
#endif
#ifdef PLATFORM_CYGWIN
@ -51,8 +51,6 @@
#include "window_list.h"
#include "config/preferences.h"
static void _notify(const char *const message, int timeout, const char *const category);
static GTimer *remind_timer;
void
@ -64,7 +62,7 @@ notifier_initialise(void)
void
notifier_uninit(void)
{
#ifdef HAVE_LIBNOTIFY
#ifdef PROF_HAVE_LIBNOTIFY
if (notify_is_initted()) {
notify_uninit();
}
@ -78,7 +76,7 @@ notify_typing(const char *const name)
char message[strlen(name) + 1 + 11];
sprintf(message, "%s: typing...", name);
_notify(message, 10000, "Incoming message");
notify(message, 10000, "Incoming message");
}
void
@ -92,7 +90,7 @@ notify_invite(const char *const from, const char *const room, const char *const
g_string_append_printf(message, "\n\"%s\"", reason);
}
_notify(message->str, 10000, "Incoming message");
notify(message->str, 10000, "Incoming message");
g_string_free(message, TRUE);
}
@ -111,8 +109,7 @@ notify_message(const char *const name, int num, const char *const text)
g_string_append_printf(message, "\n%s", text);
}
_notify(message->str, 10000, "incoming message");
notify(message->str, 10000, "incoming message");
g_string_free(message, TRUE);
}
@ -130,7 +127,7 @@ notify_room_message(const char *const nick, const char *const room, int num, con
g_string_append_printf(message, "\n%s", text);
}
_notify(message->str, 10000, "incoming message");
notify(message->str, 10000, "incoming message");
g_string_free(message, TRUE);
}
@ -140,7 +137,7 @@ notify_subscription(const char *const from)
{
GString *message = g_string_new("Subscription request: \n");
g_string_append(message, from);
_notify(message->str, 10000, "Incoming message");
notify(message->str, 10000, "Incomming message");
g_string_free(message, TRUE);
}
@ -150,14 +147,14 @@ notify_remind(void)
gdouble elapsed = g_timer_elapsed(remind_timer, NULL);
gint remind_period = prefs_get_notify_remind();
if (remind_period > 0 && elapsed >= remind_period) {
gboolean notify = wins_do_notify_remind();
gboolean donotify = wins_do_notify_remind();
gint unread = wins_get_total_unread();
gint open = muc_invites_count();
gint subs = presence_sub_request_count();
GString *text = g_string_new("");
if (notify && unread > 0) {
if (donotify && unread > 0) {
if (unread == 1) {
g_string_append(text, "1 unread message");
} else {
@ -186,8 +183,8 @@ notify_remind(void)
}
}
if ((notify && unread > 0) || (open > 0) || (subs > 0)) {
_notify(text->str, 5000, "Incoming message");
if ((donotify && unread > 0) || (open > 0) || (subs > 0)) {
notify(text->str, 5000, "Incoming message");
}
g_string_free(text, TRUE);
@ -196,10 +193,10 @@ notify_remind(void)
}
}
static void
_notify(const char *const message, int timeout, const char *const category)
void
notify(const char *const message, int timeout, const char *const category)
{
#ifdef HAVE_LIBNOTIFY
#ifdef PROF_HAVE_LIBNOTIFY
log_debug("Attempting notification: %s", message);
if (notify_is_initted()) {
log_debug("Reinitialising libnotify");
@ -251,7 +248,7 @@ _notify(const char *const message, int timeout, const char *const category)
Shell_NotifyIcon(NIM_MODIFY, &nid);
#endif
#ifdef HAVE_OSXNOTIFY
#ifdef PROF_HAVE_OSXNOTIFY
GString *notify_command = g_string_new("terminal-notifier -title \"Profanity\" -message '");
char *escaped_single = str_replace(message, "'", "'\\''");

View File

@ -32,15 +32,15 @@
*
*/
#include "config.h"
#include "prof_config.h"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#ifdef HAVE_NCURSESW_NCURSES_H
#ifdef PROF_HAVE_NCURSESW_NCURSES_H
#include <ncursesw/ncurses.h>
#elif HAVE_NCURSES_H
#elif PROF_HAVE_NCURSES_H
#include <ncurses.h>
#endif

View File

@ -36,7 +36,7 @@
#include <string.h>
#include <assert.h>
#include "config.h"
#include "prof_config.h"
#include "common.h"
#include "config/theme.h"

View File

@ -35,12 +35,12 @@
#ifndef UI_UI_H
#define UI_UI_H
#include "config.h"
#include "prof_config.h"
#include "command/commands.h"
#include "ui/win_types.h"
#include "muc.h"
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
#include "otr/otr.h"
#endif
@ -135,8 +135,7 @@ void chatwin_outgoing_carbon(ProfChatWin *chatwin, const char *const message);
void chatwin_contact_online(ProfChatWin *chatwin, Resource *resource, GDateTime *last_activity);
void chatwin_contact_offline(ProfChatWin *chatwin, char *resource, char *status);
char* chatwin_get_string(ProfChatWin *chatwin);
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
void chatwin_otr_secured(ProfChatWin *chatwin, gboolean trusted);
void chatwin_otr_unsecured(ProfChatWin *chatwin);
void chatwin_otr_trust(ProfChatWin *chatwin);
@ -343,6 +342,7 @@ ProfWin* win_create_chat(const char *const barejid);
ProfWin* win_create_muc(const char *const roomjid);
ProfWin* win_create_muc_config(const char *const title, DataForm *form);
ProfWin* win_create_private(const char *const fulljid);
ProfWin* win_create_plugin(const char *const tag);
void win_update_virtual(ProfWin *window);
void win_free(ProfWin *window);
gboolean win_notify_remind(ProfWin *window);
@ -372,6 +372,7 @@ void notify_message(const char *const name, int win, const char *const text);
void notify_room_message(const char *const nick, const char *const room, int win, const char *const text);
void notify_remind(void);
void notify_invite(const char *const from, const char *const room, const char *const reason);
void notify(const char *const message, int timeout, const char *const category);
void notify_subscription(const char *const from);
#endif

View File

@ -35,13 +35,13 @@
#ifndef UI_WIN_TYPES_H
#define UI_WIN_TYPES_H
#include "config.h"
#include "prof_config.h"
#include <wchar.h>
#include <glib.h>
#ifdef HAVE_NCURSESW_NCURSES_H
#ifdef PROF_HAVE_NCURSESW_NCURSES_H
#include <ncursesw/ncurses.h>
#elif HAVE_NCURSES_H
#elif PROF_HAVE_NCURSES_H
#include <ncurses.h>
#endif
@ -55,6 +55,7 @@
#define PROFPRIVATEWIN_MEMCHECK 77437483
#define PROFCONFWIN_MEMCHECK 64334685
#define PROFXMLWIN_MEMCHECK 87333463
#define PROFPLUGINWIN_MEMCHECK 43434777
typedef enum {
LAYOUT_SIMPLE,
@ -86,7 +87,8 @@ typedef enum {
WIN_MUC,
WIN_MUC_CONFIG,
WIN_PRIVATE,
WIN_XML
WIN_XML,
WIN_PLUGIN
} win_type_t;
typedef struct prof_win_t {
@ -143,4 +145,10 @@ typedef struct prof_xml_win_t {
unsigned long memcheck;
} ProfXMLWin;
typedef struct prof_plugin_win_t {
ProfWin super;
char *tag;
unsigned long memcheck;
} ProfPluginWin;
#endif

View File

@ -32,7 +32,7 @@
*
*/
#include "config.h"
#include "prof_config.h"
#include <stdlib.h>
#include <string.h>
@ -41,9 +41,9 @@
#include <wchar.h>
#include <glib.h>
#ifdef HAVE_NCURSESW_NCURSES_H
#ifdef PROF_HAVE_NCURSESW_NCURSES_H
#include <ncursesw/ncurses.h>
#elif HAVE_NCURSES_H
#elif PROF_HAVE_NCURSES_H
#include <ncurses.h>
#endif
@ -237,6 +237,20 @@ win_create_xmlconsole(void)
return &new_win->window;
}
ProfWin*
win_create_plugin(const char *const tag)
{
ProfPluginWin *new_win = malloc(sizeof(ProfPluginWin));
new_win->super.type = WIN_PLUGIN;
new_win->super.layout = _win_create_simple_layout();
new_win->tag = strdup(tag);
new_win->memcheck = PROFPLUGINWIN_MEMCHECK;
return &new_win->super;
}
char*
win_get_title(ProfWin *window)
{
@ -287,6 +301,11 @@ win_get_title(ProfWin *window)
if (window->type == WIN_XML) {
return strdup(XML_WIN_TITLE);
}
if (window->type == WIN_PLUGIN) {
ProfPluginWin *pluginwin = (ProfPluginWin*) window;
assert(pluginwin->memcheck == PROFPLUGINWIN_MEMCHECK);
return strdup(pluginwin->tag);
}
return NULL;
}
@ -327,6 +346,15 @@ win_get_string(ProfWin *window)
ProfXMLWin *xmlwin = (ProfXMLWin*)window;
return xmlwin_get_string(xmlwin);
}
case WIN_PLUGIN:
{
ProfPluginWin *pluginwin = (ProfPluginWin*)window;
GString *gstring = g_string_new("");
g_string_append_printf(gstring, "%s plugin", pluginwin->tag);
char *res = gstring->str;
g_string_free(gstring, FALSE);
return res;
}
default:
return NULL;
}

View File

@ -35,7 +35,7 @@
#ifndef UI_WINDOW_H
#define UI_WINDOW_H
#include "config.h"
#include "prof_config.h"
#include <wchar.h>
@ -46,9 +46,9 @@
#include "xmpp/xmpp.h"
#include "chat_state.h"
#ifdef HAVE_NCURSESW_NCURSES_H
#ifdef PROF_HAVE_NCURSESW_NCURSES_H
#include <ncursesw/ncurses.h>
#elif HAVE_NCURSES_H
#elif PROF_HAVE_NCURSES_H
#include <ncurses.h>
#endif

View File

@ -32,7 +32,7 @@
*
*/
#include "config.h"
#include "prof_config.h"
#include <string.h>
#include <assert.h>
@ -201,6 +201,27 @@ wins_get_private(const char *const fulljid)
return NULL;
}
ProfPluginWin*
wins_get_plugin(const char *const tag)
{
GList *values = g_hash_table_get_values(windows);
GList *curr = values;
while (curr) {
ProfWin *window = curr->data;
if (window->type == WIN_PLUGIN) {
ProfPluginWin *pluginwin = (ProfPluginWin*)window;
if (g_strcmp0(pluginwin->tag, tag) == 0) {
return pluginwin;
}
}
curr = g_list_next(curr);
}
g_list_free(values);
return NULL;
}
GList*
wins_get_private_chats(const char *const roomjid)
{
@ -614,6 +635,17 @@ wins_new_private(const char *const fulljid)
return newwin;
}
ProfWin *
wins_new_plugin(const char * const tag)
{
GList *keys = g_hash_table_get_keys(windows);
int result = get_next_available_win_num(keys);
ProfWin *new = win_create_plugin(tag);
g_hash_table_insert(windows, GINT_TO_POINTER(result), new);
g_list_free(keys);
return new;
}
gboolean
wins_do_notify_remind(void)
{

View File

@ -44,6 +44,7 @@ ProfWin* wins_new_chat(const char *const barejid);
ProfWin* wins_new_muc(const char *const roomjid);
ProfWin* wins_new_muc_config(const char *const roomjid, DataForm *form);
ProfWin* wins_new_private(const char *const fulljid);
ProfWin* wins_new_plugin(const char *const tag);
gboolean wins_chat_exists(const char *const barejid);
GList* wins_get_private_chats(const char *const roomjid);
@ -57,6 +58,7 @@ GList* wins_get_chat_unsubscribed(void);
ProfMucWin* wins_get_muc(const char *const roomjid);
ProfMucConfWin* wins_get_muc_conf(const char *const roomjid);
ProfPrivateWin* wins_get_private(const char *const fulljid);
ProfPluginWin* wins_get_plugin(const char *const tag);
ProfXMLWin* wins_get_xmlconsole(void);
ProfWin* wins_get_current(void);

View File

@ -32,7 +32,7 @@
*
*/
#include "config.h"
#include "prof_config.h"
#include <assert.h>
#include <stdio.h>
@ -40,10 +40,10 @@
#include <string.h>
#include <glib.h>
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
#include <mesode.h>
#endif
#ifdef HAVE_LIBSTROPHE
#ifdef PROF_HAVE_LIBSTROPHE
#include <strophe.h>
#endif

View File

@ -32,9 +32,9 @@
*
*/
#include "config.h"
#include "prof_config.h"
#ifdef HAVE_GIT_VERSION
#ifdef PROF_HAVE_GIT_VERSION
#include "gitversion.h"
#endif
@ -44,10 +44,10 @@
#include <glib.h>
#include <glib/gstdio.h>
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
#include <mesode.h>
#endif
#ifdef HAVE_LIBSTROPHE
#ifdef PROF_HAVE_LIBSTROPHE
#include <strophe.h>
#endif
@ -565,9 +565,9 @@ caps_create_query_response_stanza(xmpp_ctx_t *const ctx)
xmpp_stanza_set_attribute(identity, "type", "console");
GString *name_str = g_string_new("Profanity ");
g_string_append(name_str, PACKAGE_VERSION);
if (strcmp(PACKAGE_STATUS, "development") == 0) {
#ifdef HAVE_GIT_VERSION
g_string_append(name_str, PROF_PACKAGE_VERSION);
if (strcmp(PROF_PACKAGE_STATUS, "development") == 0) {
#ifdef PROF_HAVE_GIT_VERSION
g_string_append(name_str, "dev.");
g_string_append(name_str, PROF_GIT_BRANCH);
g_string_append(name_str, ".");

View File

@ -35,12 +35,12 @@
#ifndef XMPP_CAPABILITIES_H
#define XMPP_CAPABILITIES_H
#include "config.h"
#include "prof_config.h"
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
#include <mesode.h>
#endif
#ifdef HAVE_LIBSTROPHE
#ifdef PROF_HAVE_LIBSTROPHE
#include <strophe.h>
#endif

View File

@ -32,16 +32,16 @@
*
*/
#include "config.h"
#include "prof_config.h"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
#include <mesode.h>
#endif
#ifdef HAVE_LIBSTROPHE
#ifdef PROF_HAVE_LIBSTROPHE
#include <strophe.h>
#endif
@ -51,6 +51,7 @@
#include "jid.h"
#include "log.h"
#include "muc.h"
#include "plugins/plugins.h"
#include "profanity.h"
#include "event/server_events.h"
#include "xmpp/bookmark.h"
@ -93,12 +94,12 @@ static struct {
static GTimer *reconnect_timer;
static log_level_t _get_log_level(xmpp_log_level_t xmpp_level);
static xmpp_log_level_t _get_xmpp_log_level();
static xmpp_log_level_t _get_xmpp_log_level(void);
static void _xmpp_file_logger(void *const userdata, const xmpp_log_level_t level, const char *const area,
const char *const msg);
static xmpp_log_t* _xmpp_get_file_logger();
static xmpp_log_t* _xmpp_get_file_logger(void);
static jabber_conn_status_t _jabber_connect(const char *const fulljid, const char *const passwd,
const char *const altdomain, int port, const char *const tls_policy);
@ -235,6 +236,9 @@ jabber_disconnect(void)
{
// if connected, send end stream and wait for response
if (jabber_conn.conn_status == JABBER_CONNECTED) {
char *account_name = jabber_get_account_name();
const char *fulljid = jabber_get_fulljid();
plugins_on_disconnect(account_name, fulljid);
log_info("Closing connection");
accounts_set_last_activity(jabber_get_account_name());
jabber_conn.conn_status = JABBER_DISCONNECTING;
@ -418,7 +422,7 @@ _connection_free_session_data(void)
presence_clear_sub_requests();
}
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
static int
_connection_certfail_cb(xmpp_tlscert_t *xmpptlscert, const char *const errormsg)
{
@ -526,7 +530,7 @@ _jabber_connect(const char *const fulljid, const char *const passwd, const char
xmpp_conn_set_flags(jabber_conn.conn, XMPP_CONN_FLAG_DISABLE_TLS);
}
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
char *cert_path = prefs_get_string(PREF_TLS_CERTPATH);
if (cert_path) {
xmpp_conn_tlscert_path(jabber_conn.conn, cert_path);
@ -534,7 +538,7 @@ _jabber_connect(const char *const fulljid, const char *const passwd, const char
prefs_free_string(cert_path);
#endif
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
int connect_status = xmpp_connect_client(
jabber_conn.conn,
altdomain,
@ -580,6 +584,9 @@ _jabber_reconnect(void)
static void
_jabber_lost_connection(void)
{
char *account_name = jabber_get_account_name();
const char *fulljid = jabber_get_fulljid();
plugins_on_disconnect(account_name, fulljid);
sv_ev_lost_connection();
if (prefs_get_reconnect() != 0) {
assert(reconnect_timer == NULL);

View File

@ -35,12 +35,12 @@
#ifndef XMPP_CONNECTION_H
#define XMPP_CONNECTION_H
#include "config.h"
#include "prof_config.h"
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
#include <mesode.h>
#endif
#ifdef HAVE_LIBSTROPHE
#ifdef PROF_HAVE_LIBSTROPHE
#include <strophe.h>
#endif

View File

@ -32,15 +32,15 @@
*
*/
#include "config.h"
#include "prof_config.h"
#include <string.h>
#include <stdlib.h>
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
#include <mesode.h>
#endif
#ifdef HAVE_LIBSTROPHE
#ifdef PROF_HAVE_LIBSTROPHE
#include <strophe.h>
#endif

View File

@ -32,9 +32,9 @@
*
*/
#include "config.h"
#include "prof_config.h"
#ifdef HAVE_GIT_VERSION
#ifdef PROF_HAVE_GIT_VERSION
#include "gitversion.h"
#endif
@ -43,10 +43,10 @@
#include <stdio.h>
#include <glib.h>
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
#include <mesode.h>
#endif
#ifdef HAVE_LIBSTROPHE
#ifdef PROF_HAVE_LIBSTROPHE
#include <strophe.h>
#endif
@ -1081,9 +1081,9 @@ _version_get_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza,
xmpp_stanza_t *version = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(version, "version");
xmpp_stanza_t *version_txt = xmpp_stanza_new(ctx);
GString *version_str = g_string_new(PACKAGE_VERSION);
if (strcmp(PACKAGE_STATUS, "development") == 0) {
#ifdef HAVE_GIT_VERSION
GString *version_str = g_string_new(PROF_PACKAGE_VERSION);
if (strcmp(PROF_PACKAGE_STATUS, "development") == 0) {
#ifdef PROF_HAVE_GIT_VERSION
g_string_append(version_str, "dev.");
g_string_append(version_str, PROF_GIT_BRANCH);
g_string_append(version_str, ".");

View File

@ -32,15 +32,15 @@
*
*/
#include "config.h"
#include "prof_config.h"
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
#include <mesode.h>
#endif
#ifdef HAVE_LIBSTROPHE
#ifdef PROF_HAVE_LIBSTROPHE
#include <strophe.h>
#endif
@ -156,7 +156,7 @@ message_send_chat_pgp(const char *const barejid, const char *const msg)
char *id = create_unique_id("msg");
xmpp_stanza_t *message = NULL;
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
char *account_name = jabber_get_account_name();
ProfAccount *account = accounts_get_account(account_name);
if (account->pgp_keyid) {

View File

@ -32,7 +32,7 @@
*
*/
#include "config.h"
#include "prof_config.h"
#include <assert.h>
#include <stdlib.h>
@ -41,10 +41,10 @@
#include <glib.h>
#include <glib/gprintf.h>
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
#include <mesode.h>
#endif
#ifdef HAVE_LIBSTROPHE
#ifdef PROF_HAVE_LIBSTROPHE
#include <strophe.h>
#endif

View File

@ -32,7 +32,7 @@
*
*/
#include "config.h"
#include "prof_config.h"
#include <assert.h>
#include <stdlib.h>
@ -40,14 +40,15 @@
#include <glib.h>
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
#include <mesode.h>
#endif
#ifdef HAVE_LIBSTROPHE
#ifdef PROF_HAVE_LIBSTROPHE
#include <strophe.h>
#endif
#include "log.h"
#include "plugins/plugins.h"
#include "profanity.h"
#include "ui/ui.h"
#include "event/server_events.h"

View File

@ -32,17 +32,17 @@
*
*/
#include "config.h"
#include "prof_config.h"
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
#include <mesode.h>
#endif
#ifdef HAVE_LIBSTROPHE
#ifdef PROF_HAVE_LIBSTROPHE
#include <strophe.h>
#endif

View File

@ -35,12 +35,12 @@
#ifndef XMPP_STANZA_H
#define XMPP_STANZA_H
#include "config.h"
#include "prof_config.h"
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
#include <mesode.h>
#endif
#ifdef HAVE_LIBSTROPHE
#ifdef PROF_HAVE_LIBSTROPHE
#include <strophe.h>
#endif

View File

@ -35,12 +35,12 @@
#ifndef XMPP_XMPP_H
#define XMPP_XMPP_H
#include "config.h"
#include "prof_config.h"
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
#include <mesode.h>
#endif
#ifdef HAVE_LIBSTROPHE
#ifdef PROF_HAVE_LIBSTROPHE
#include <strophe.h>
#endif
@ -155,7 +155,7 @@ char* jabber_get_account_name(void);
GList* jabber_get_available_resources(void);
char* jabber_create_uuid(void);
void jabber_free_uuid(char *uuid);
#ifdef HAVE_LIBMESODE
#ifdef PROF_HAVE_LIBMESODE
TLSCertificate* jabber_get_tls_peer_cert(void);
#endif
gboolean jabber_conn_is_secured(void);

View File

@ -7,7 +7,7 @@
#include <cmocka.h>
#include <sys/stat.h>
#include "config.h"
#include "prof_config.h"
#include "proftest.h"
#include "test_connect.h"

View File

@ -798,7 +798,7 @@ void cmd_account_set_priority_updates_presence_when_account_connected_with_prese
will_return(jabber_get_account_name, "a_account");
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
ProfAccount *account = account_new("a_account", "a_jid", NULL, NULL, TRUE, NULL, 5222, "a_resource",
NULL, NULL, 10, 10, 10, 10, 10, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);

View File

@ -6,9 +6,9 @@
#include <string.h>
#include <glib.h>
#include "config.h"
#include "prof_config.h"
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
#include <libotr/proto.h>
#include "otr/otr.h"
#endif
@ -24,7 +24,7 @@
#define CMD_OTR "/otr"
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
void cmd_otr_shows_usage_when_no_args(void **state)
{
gchar *args[] = { NULL };

View File

@ -1,6 +1,6 @@
#include "config.h"
#include "prof_config.h"
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
void cmd_otr_shows_usage_when_no_args(void **state);
void cmd_otr_shows_usage_when_invalid_subcommand(void **state);
void cmd_otr_log_shows_usage_when_no_args(void **state);

View File

@ -6,7 +6,7 @@
#include <string.h>
#include <glib.h>
#include "config.h"
#include "prof_config.h"
#include "command/commands.h"
@ -14,7 +14,7 @@
#define CMD_PGP "/pgp"
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
void cmd_pgp_shows_usage_when_no_args(void **state)
{
gchar *args[] = { NULL };

View File

@ -1,6 +1,6 @@
#include "config.h"
#include "prof_config.h"
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
void cmd_pgp_shows_usage_when_no_args(void **state);
void cmd_pgp_start_shows_message_when_disconnected(void **state);
void cmd_pgp_start_shows_message_when_disconnecting(void **state);

View File

@ -1,4 +1,4 @@
#include "config.h"
#include "prof_config.h"
#include <glib.h>
#include <wchar.h>
@ -8,7 +8,7 @@
#include "ui/window.h"
#include "ui/ui.h"
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
#include "otr/otr.h"
#endif
@ -67,7 +67,7 @@ void ui_resize(void) {}
void ui_focus_win(ProfWin *win) {}
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
void chatwin_otr_secured(ProfChatWin *chatwin, gboolean trusted) {}
void chatwin_otr_unsecured(ProfChatWin *chatwin) {}
void chatwin_otr_trust(ProfChatWin *chatwin) {}
@ -303,8 +303,10 @@ gboolean ui_win_has_unsaved_form(int num)
return FALSE;
}
void
ui_write(char *line, int offset) {}
void ui_status_bar_inactive(const int win) {}
void ui_status_bar_active(const int win) {}
void ui_status_bar_new(const int win) {}
void ui_write(char *line, int offset) {}
// console window actions
@ -494,6 +496,10 @@ ProfWin* win_create_private(const char * const fulljid)
{
return NULL;
}
ProfWin* win_create_plugin(const char * const tag)
{
return NULL;
}
void win_update_virtual(ProfWin *window) {}
void win_free(ProfWin *window) {}
@ -540,3 +546,6 @@ void notify_remind(void) {}
void notify_invite(const char * const from, const char * const room,
const char * const reason) {}
void notify_subscription(const char * const from) {}
void notify(const char * const message, int timeout,
const char * const category) {}

View File

@ -7,9 +7,8 @@
#include <cmocka.h>
#include <sys/stat.h>
#include "config.h"
#include "prof_config.h"
#include "chat_session.h"
#include "helpers.h"
#include "test_autocomplete.h"
#include "test_chat_session.h"
@ -356,7 +355,7 @@ int main(int argc, char* argv[]) {
unit_test(cmd_account_set_eval_password_when_password_set),
unit_test(cmd_account_set_muc_sets_muc),
unit_test(cmd_account_set_nick_sets_nick),
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
unit_test(cmd_account_show_message_for_missing_otr_policy),
unit_test(cmd_account_show_message_for_invalid_otr_policy),
unit_test(cmd_account_set_otr_sets_otr),
@ -505,7 +504,7 @@ int main(int argc, char* argv[]) {
unit_test(cmd_bookmark_remove_removes_bookmark),
unit_test(cmd_bookmark_remove_shows_message_when_no_bookmark),
#ifdef HAVE_LIBOTR
#ifdef PROF_HAVE_LIBOTR
unit_test(cmd_otr_shows_usage_when_no_args),
unit_test(cmd_otr_shows_usage_when_invalid_subcommand),
unit_test(cmd_otr_log_shows_usage_when_no_args),
@ -557,7 +556,7 @@ int main(int argc, char* argv[]) {
unit_test(cmd_otr_shows_message_when_otr_unsupported),
#endif
#ifdef HAVE_LIBGPGME
#ifdef PROF_HAVE_LIBGPGME
unit_test(cmd_pgp_shows_usage_when_no_args),
unit_test(cmd_pgp_start_shows_message_when_disconnected),
unit_test(cmd_pgp_start_shows_message_when_disconnecting),