--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modularize-extcmd.diff Sat Jul 28 19:42:13 2012 +0300
@@ -0,0 +1,386 @@
+Convert extcmd into a module
+
+diff -r 27d19b6bc194 mcabber/configure.ac
+--- a/mcabber/configure.ac Mon Apr 30 23:36:55 2012 +0300
++++ b/mcabber/configure.ac Mon Apr 30 23:37:25 2012 +0300
+@@ -283,6 +283,7 @@
+ modules/beep/Makefile
+ modules/xttitle/Makefile
+ modules/fifo/Makefile
++ modules/eventcmd/Makefile
+ modules/urlregex/Makefile
+ doc/Makefile
+ doc/guide/Makefile
+diff -r 27d19b6bc194 mcabber/mcabber/Makefile.am
+--- a/mcabber/mcabber/Makefile.am Mon Apr 30 23:36:55 2012 +0300
++++ b/mcabber/mcabber/Makefile.am Mon Apr 30 23:37:25 2012 +0300
+@@ -7,7 +7,7 @@
+ xmpp.c xmpp.h xmpp_helper.c xmpp_helper.h xmpp_defines.h \
+ xmpp_iq.c xmpp_iq.h xmpp_iqrequest.c xmpp_iqrequest.h \
+ xmpp_muc.c xmpp_muc.h xmpp_s10n.c xmpp_s10n.h \
+- caps.c caps.h help.c help.h extcmd.c extcmd.h
++ caps.c caps.h help.c help.h
+
+ if OTR
+ mcabber_SOURCES += otr.c otr.h nohtml.c nohtml.h
+@@ -55,7 +55,7 @@
+
+ mcabberincludedir = $(includedir)/mcabber
+ else
+-mcabber_SOURCES += fifo.c fifo.h
++mcabber_SOURCES += fifo.c fifo.h extcmd.c extcmd.h
+ endif
+
+ #SUBDIRS =
+diff -r 27d19b6bc194 mcabber/mcabber/hooks.c
+--- a/mcabber/mcabber/hooks.c Mon Apr 30 23:36:55 2012 +0300
++++ b/mcabber/mcabber/hooks.c Mon Apr 30 23:37:25 2012 +0300
+@@ -36,7 +36,10 @@
+ #include "utf8.h"
+ #include "commands.h"
+ #include "main.h"
+-#include "extcmd.h"
++
++#ifndef MODULES_ENABLE
++# include "extcmd.h"
++#endif
+
+ #ifdef MODULES_ENABLE
+ #include <glib.h>
+@@ -189,7 +192,9 @@
+ int is_groupchat = FALSE; // groupchat message
+ int is_room = FALSE; // window is a room window
+ int log_muc_conf = FALSE;
++#ifndef MODULES_ENABLE
+ int active_window = FALSE;
++#endif
+ int message_flags = 0;
+ guint rtype = ROSTER_TYPE_USER;
+ char *wmsg = NULL, *bmsg = NULL, *mmsg = NULL;
+@@ -397,6 +402,7 @@
+ }
+ #endif
+
++#ifndef MODULES_ENABLE
+ if (settings_opt_get_int("events_ignore_active_window") &&
+ current_buddy && scr_get_chatmode()) {
+ gpointer bud = BUDDATA(current_buddy);
+@@ -415,6 +421,7 @@
+ hk_ext_cmd(bjid, EXT_CMD_TYPE_MESSAGE,
+ is_groupchat ? EXT_CMD_INFO_GROUPCHAT : EXT_CMD_INFO_RECEIVED,
+ wmsg);
++#endif
+
+ // Beep, if enabled:
+ // - if it's a private message
+@@ -491,8 +498,10 @@
+ }
+ #endif
+
++#ifndef MODULES_ENABLE
+ // External command
+ hk_ext_cmd(bjid, EXT_CMD_TYPE_MESSAGE, EXT_CMD_INFO_SENT, NULL);
++#endif
+
+ g_free(bmsg);
+ g_free(mmsg);
+@@ -578,9 +587,11 @@
+ }
+ #endif
+
++#ifndef MODULES_ENABLE
+ // External command
+ newstatus[0] = toupper(newstatus[0]);
+ hk_ext_cmd(bjid, EXT_CMD_TYPE_STATUS, newstatus, status_msg);
++#endif
+ }
+
+ void hk_mystatuschange(time_t timestamp, enum imstatus old_status,
+@@ -704,11 +715,13 @@
+ prev_muc_unread = muc_unread;
+ prev_muc_attention = muc_attention;
+
++#ifndef MODULES_ENABLE
+ /* Call external command */
+ str_unread = g_strdup_printf("%u %u %u %u", unread_count, attention_count,
+ muc_unread, muc_attention);
+ hk_ext_cmd("", EXT_CMD_TYPE_UNREAD, str_unread, NULL);
+ g_free(str_unread);
++#endif
+ }
+
+ // hk_presence_subscription_request(jid, message)
+diff -r 27d19b6bc194 mcabber/mcabber/main.c
+--- a/mcabber/mcabber/main.c Mon Apr 30 23:36:55 2012 +0300
++++ b/mcabber/mcabber/main.c Mon Apr 30 23:37:25 2012 +0300
+@@ -44,7 +44,10 @@
+ #include "xmpp.h"
+ #include "help.h"
+ #include "events.h"
+-#include "extcmd.h"
++
++#ifndef MODULES_ENABLE
++# include "extcmd.h"
++#endif
+
+ #ifndef MODULES_ENABLE
+ # include "fifo.h"
+@@ -443,9 +446,11 @@
+ }
+ #endif
+
++#ifndef MODULES_ENABLE
+ optstring = settings_opt_get("events_command");
+ if (optstring)
+ hk_ext_cmd_init(optstring);
++#endif
+
+ optstring = settings_opt_get("roster_display_filter");
+ if (optstring)
+diff -r 27d19b6bc194 mcabber/modules/Makefile.am
+--- a/mcabber/modules/Makefile.am Mon Apr 30 23:36:55 2012 +0300
++++ b/mcabber/modules/Makefile.am Mon Apr 30 23:37:25 2012 +0300
+@@ -1,1 +1,1 @@
+-SUBDIRS = beep xttitle fifo urlregex
++SUBDIRS = beep xttitle fifo eventcmd urlregex
+diff -r 27d19b6bc194 mcabber/modules/eventcmd/Makefile.am
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ b/mcabber/modules/eventcmd/Makefile.am Mon Apr 30 23:37:25 2012 +0300
+@@ -0,0 +1,12 @@
++
++if INSTALL_HEADERS
++pkglib_LTLIBRARIES = libeventcmd.la
++libeventcmd_la_SOURCES = eventcmd.c $(top_srcdir)/mcabber/extcmd.c $(top_srcdir)/mcabber/extcmd.h
++libeventcmd_la_LDFLAGS = -module -avoid-version -shared
++
++LDADD = $(GLIB_LIBS)
++AM_CPPFLAGS = -I$(top_srcdir) $(GLIB_CFLAGS) $(LOUDMOUTH_CFLAGS) \
++ $(GPGME_CFLAGS) $(LIBOTR_CFLAGS) \
++ $(ENCHANT_CFLAGS)
++endif
++
+diff -r 27d19b6bc194 mcabber/modules/eventcmd/eventcmd.c
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ b/mcabber/modules/eventcmd/eventcmd.c Mon Apr 30 23:37:25 2012 +0300
+@@ -0,0 +1,221 @@
++
++/* Copyright 2009 Myhailo Danylenko
++ *
++ * This file is part of mcabber
++ *
++ * mcabber is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation, either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
++
++#include <glib.h>
++#include <gmodule.h>
++#include <string.h>
++#include <stdlib.h>
++#include <ctype.h> // tolower
++#include <unistd.h>
++
++#include <mcabber/settings.h>
++#include <mcabber/hooks.h>
++#include <mcabber/roster.h>
++#include <mcabber/utils.h>
++#include <mcabber/logprint.h>
++#include <mcabber/extcmd.h>
++#include <mcabber/modules.h>
++#include <mcabber/screen.h>
++#include <mcabber/config.h>
++
++static void ecm_init(void);
++static void ecm_uninit(void);
++
++module_info_t info_eventcmd = {
++ .branch = MCABBER_BRANCH,
++ .api = MCABBER_API_VERSION,
++ .version = MCABBER_VERSION,
++ .requires = NULL,
++ .init = ecm_init,
++ .uninit = ecm_uninit,
++ .description = "External command execution on events\n"
++ "Recognizes options events_command (required), events_ignore_active_window, "
++ "event_log_files, event_log_dir, eventcmd_use_nickname, eventcmd_checkstatus.",
++ .next = NULL,
++};
++
++static guint eventcmd_hpmi_hid = 0;
++static guint eventcmd_hmo_hid = 0;
++static guint eventcmd_hsc_hid = 0;
++static guint eventcmd_hulc_hid = 0;
++
++static guint eventcmd_hpmih(const gchar *name, hk_arg_t *args,
++ gpointer userdata)
++{
++ gboolean active_window = FALSE;
++ gboolean is_groupchat = FALSE;
++ gboolean timestamp = FALSE;
++ const char *bjid = NULL;
++ hk_arg_t *arg = args;
++ const char *wmsg = NULL;
++
++ while (arg->name) {
++ if (!strcmp(arg->name, "jid"))
++ bjid = arg->value;
++ else if (!strcmp(arg->name, "groupchat"))
++ is_groupchat = strcmp(arg->value, "true") ? FALSE : TRUE;
++ else if (!strcmp(arg->name, "delayed") && *(arg->value))
++ timestamp = TRUE;
++ else if (!strcmp(arg->name, "message"))
++ wmsg = arg->value;
++ arg++;
++ }
++
++ if (!bjid) {
++ scr_LogPrint(LPRINT_LOGNORM, "eventcmd: post-message-in: No jid found.");
++ return HOOK_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
++ }
++
++ if (settings_opt_get_int("events_ignore_active_window") &&
++ current_buddy && scr_get_chatmode()) {
++ gpointer bud = BUDDATA(current_buddy);
++ if (bud) {
++ const char *cjid = buddy_getjid(bud);
++ if (cjid && !strcasecmp(cjid, bjid))
++ active_window = TRUE;
++ }
++ }
++
++ if (!active_window && ((is_groupchat && !timestamp) || !is_groupchat))
++ hk_ext_cmd(bjid, EXT_CMD_TYPE_MESSAGE,
++ is_groupchat ? EXT_CMD_INFO_GROUPCHAT : EXT_CMD_INFO_RECEIVED, wmsg);
++
++ return HOOK_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
++}
++
++static guint eventcmd_hmoh(const gchar *name, hk_arg_t *args, gpointer userdata)
++{
++ const char *bjid = NULL;
++ hk_arg_t *arg = args;
++
++ while (arg->name) {
++ if (!strcmp(arg->name, "jid")) {
++ bjid = arg->value;
++ break;
++ }
++ arg++;
++ }
++
++ if (!bjid) {
++ scr_LogPrint(LPRINT_LOGNORM, "eventcmd: message-out: No jid found.");
++ return HOOK_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
++ }
++
++ hk_ext_cmd(bjid, EXT_CMD_TYPE_MESSAGE, EXT_CMD_INFO_SENT, NULL);
++
++ return HOOK_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
++}
++
++static guint eventcmd_hsch(const gchar *name, hk_arg_t *args, gpointer userdata)
++{
++ const char *bjid = NULL;
++ char status[2] = { '?', '\0' };
++ hk_arg_t *arg = args;
++ const char *message = NULL;
++
++ while (arg->name) {
++ if (!strcmp(arg->name, "jid"))
++ bjid = arg->value;
++ else if (!strcmp(arg->name, "new_status"))
++ status[0] = toupper (arg->value[0]);
++ else if (!strcmp(arg->name, "message") && arg->value && *(arg->value))
++ message = arg->value;
++ arg++;
++ }
++
++ if (!bjid) {
++ scr_LogPrint(LPRINT_LOGNORM, "eventcmd: status-change: No jid found.");
++ return HOOK_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
++ }
++
++ hk_ext_cmd(bjid, EXT_CMD_TYPE_STATUS, status, message);
++
++ return HOOK_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
++}
++
++static guint eventcmd_hulch(const gchar *name, hk_arg_t *args, gpointer userdata)
++{
++ hk_arg_t *arg = args;
++ const gchar *unread = NULL;
++ const gchar *attention = NULL;
++ const gchar *muc_unread = NULL;
++ const gchar *muc_attention = NULL;
++
++ while (arg->name) {
++ if (!strcmp(arg->name, "unread"))
++ unread = arg->value;
++ else if (!strcmp(arg->name, "attention"))
++ attention = arg->value;
++ else if (!strcmp(arg->name, "muc_unread"))
++ muc_unread = arg->value;
++ else if (!strcmp(arg->name, "muc_attention"))
++ muc_attention = arg->value;
++ arg++;
++ }
++
++ if (!unread || !attention || !muc_unread || !muc_attention) {
++ scr_LogPrint(LPRINT_LOGNORM, "eventcmd: unread-list-change: Missing parameter.");
++ return HOOK_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
++ }
++
++ {
++ gchar *str = g_strdup_printf("%s %s %s %s", unread, attention, muc_unread,
++ muc_attention);
++ hk_ext_cmd("", EXT_CMD_TYPE_UNREAD, str, NULL);
++ g_free(str);
++ }
++
++ return HOOK_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
++}
++
++const gchar *g_module_check_init(GModule *module)
++{
++ const char *command = settings_opt_get("events_command");
++ if (!command)
++ return "events_command not set";
++ hk_ext_cmd_init(command);
++ return NULL;
++}
++
++void g_module_unload(GModule *module)
++{
++ hk_ext_cmd_init(NULL);
++}
++
++static void ecm_init(void)
++{
++ eventcmd_hpmi_hid = hk_add_handler(eventcmd_hpmih, HOOK_POST_MESSAGE_IN,
++ G_PRIORITY_LOW, NULL);
++ eventcmd_hmo_hid = hk_add_handler(eventcmd_hmoh, HOOK_MESSAGE_OUT,
++ G_PRIORITY_LOW, NULL);
++ eventcmd_hsc_hid = hk_add_handler(eventcmd_hsch, HOOK_STATUS_CHANGE,
++ G_PRIORITY_LOW, NULL);
++ eventcmd_hulc_hid = hk_add_handler(eventcmd_hulch, HOOK_UNREAD_LIST_CHANGE,
++ G_PRIORITY_LOW, NULL);
++
++}
++
++static void ecm_uninit(void)
++{
++ hk_del_handler(HOOK_POST_MESSAGE_IN, eventcmd_hpmi_hid);
++ hk_del_handler(HOOK_MESSAGE_OUT, eventcmd_hmo_hid);
++ hk_del_handler(HOOK_STATUS_CHANGE, eventcmd_hsc_hid);
++ hk_del_handler(HOOK_UNREAD_LIST_CHANGE, eventcmd_hulc_hid);
++}
++
++/* vim: set expandtab cindent cinoptions=>2\:2(0 sw=2 ts=2: For Vim users... */