# HG changeset patch
# Parent  d4d77c56d8da7c9771579efe469440eb25947271
Convert extcmd into a module

diff -r d4d77c56d8da mcabber/configure.ac
--- a/mcabber/configure.ac	Sat Nov 07 17:28:17 2015 +0200
+++ b/mcabber/configure.ac	Sat Nov 07 17:38:46 2015 +0200
@@ -295,6 +295,7 @@
                  modules/beep/Makefile
                  modules/xttitle/Makefile
                  modules/fifo/Makefile
+                 modules/eventcmd/Makefile
                  modules/urlregex/Makefile
                  doc/Makefile
                  doc/guide/Makefile
diff -r d4d77c56d8da mcabber/mcabber/Makefile.am
--- a/mcabber/mcabber/Makefile.am	Sat Nov 07 17:28:17 2015 +0200
+++ b/mcabber/mcabber/Makefile.am	Sat Nov 07 17:38:46 2015 +0200
@@ -7,8 +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 carbons.c carbons.h \
-		  extcmd.c extcmd.h
+		  caps.c caps.h help.c help.h carbons.c carbons.h
 
 if OTR
 mcabber_SOURCES += otr.c otr.h nohtml.c nohtml.h
@@ -57,7 +56,7 @@
 
 mcabberincludedir = $(includedir)/mcabber
 else
-mcabber_SOURCES += fifo_internal.c fifo.h
+mcabber_SOURCES += fifo_internal.c fifo.h extcmd.c extcmd.h
 endif
 
 #SUBDIRS =
diff -r d4d77c56d8da mcabber/mcabber/hooks.c
--- a/mcabber/mcabber/hooks.c	Sat Nov 07 17:28:17 2015 +0200
+++ b/mcabber/mcabber/hooks.c	Sat Nov 07 17:38:46 2015 +0200
@@ -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;
@@ -402,6 +407,7 @@
   }
 #endif
 
+#ifndef MODULES_ENABLE
   if (settings_opt_get_int("events_ignore_active_window") &&
       current_buddy && scr_get_chatmode()) {
     gpointer bud = BUDDATA(current_buddy);
@@ -420,6 +426,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
@@ -500,8 +507,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);
@@ -587,9 +596,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,
@@ -711,11 +722,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 d4d77c56d8da mcabber/mcabber/main.c
--- a/mcabber/mcabber/main.c	Sat Nov 07 17:28:17 2015 +0200
+++ b/mcabber/mcabber/main.c	Sat Nov 07 17:38:46 2015 +0200
@@ -50,9 +50,9 @@
 #include "help.h"
 #include "events.h"
 #include "compl.h"
-#include "extcmd.h"
 
 #ifndef MODULES_ENABLE
+# include "extcmd.h"
 # include "fifo.h"
 #endif
 
@@ -509,9 +509,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 d4d77c56d8da mcabber/modules/Makefile.am
--- a/mcabber/modules/Makefile.am	Sat Nov 07 17:28:17 2015 +0200
+++ b/mcabber/modules/Makefile.am	Sat Nov 07 17:38:46 2015 +0200
@@ -1,1 +1,1 @@
-SUBDIRS = beep xttitle fifo urlregex
+SUBDIRS = beep xttitle fifo eventcmd urlregex
diff -r d4d77c56d8da mcabber/modules/eventcmd/Makefile.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/modules/eventcmd/Makefile.am	Sat Nov 07 17:38:46 2015 +0200
@@ -0,0 +1,13 @@
+
+if INSTALL_HEADERS
+pkglib_LTLIBRARIES = libeventcmd.la
+libeventcmd_la_SOURCES = eventcmd.c ../mcabber/extcmd.c ../mcabber/extcmd.h
+libeventcmd_la_LDFLAGS = -module -avoid-version -shared
+
+LDADD = $(GLIB_LIBS)
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir) \
+				$(GLIB_CFLAGS) $(LOUDMOUTH_CFLAGS) \
+				$(GPGME_CFLAGS) $(LIBOTR_CFLAGS) \
+				$(ENCHANT_CFLAGS)
+endif
+
diff -r d4d77c56d8da mcabber/modules/eventcmd/eventcmd.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/modules/eventcmd/eventcmd.c	Sat Nov 07 17:38:46 2015 +0200
@@ -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... */
