Otr v4 support, build fix
authorMyhailo Danylenko <isbear@ukrpost.net>
Sun, 13 Jan 2013 06:42:35 +0200
changeset 61 9b4f7e14c19c
parent 60 7b9a9bbdb40b
child 62 f5249c9544e5
Otr v4 support, build fix * added use-otr-v4.diff * added automake-fix-deprecated-macro.diff * updated add-cmake.diff for otr v4
add-cmake.diff
automake-fix-deprecated-macro.diff
series
use-otr-v4.diff
--- a/add-cmake.diff	Fri Nov 30 21:11:10 2012 +0200
+++ b/add-cmake.diff	Sun Jan 13 06:42:35 2013 +0200
@@ -1,20 +1,20 @@
 # HG changeset patch
-# Parent 9dbc874e6cf72a133e8568ae28fd254c6028d60a
+# Parent 19a36ac5d0b55244c4b3bdef8cb6f98874a9d961
 [work-in-progress] Add possibility to build with CMake
 
-diff -r 9dbc874e6cf7 .hgignore
---- a/.hgignore	Fri Jul 20 17:29:26 2012 +0300
-+++ b/.hgignore	Fri Jul 20 17:29:52 2012 +0300
+diff -r 19a36ac5d0b5 .hgignore
+--- a/.hgignore	Sun Jan 13 06:17:13 2013 +0200
++++ b/.hgignore	Sun Jan 13 06:40:40 2013 +0200
 @@ -34,3 +34,5 @@
  tags
  mcabber/ptodo
  mcabber/ppatches
 +
 +mcabber/build
-diff -r 9dbc874e6cf7 mcabber/CMakeLists.txt
+diff -r 19a36ac5d0b5 mcabber/CMakeLists.txt
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/mcabber/CMakeLists.txt	Fri Jul 20 17:29:52 2012 +0300
-@@ -0,0 +1,296 @@
++++ b/mcabber/CMakeLists.txt	Sun Jan 13 06:40:40 2013 +0200
+@@ -0,0 +1,303 @@
 +## Copyright 2010-2012 Myhailo Danylenko
 +# This file is part of mcabber.
 +#
@@ -127,9 +127,16 @@
 +
 +# Libotr
 +if ( WANT_OTR )
-+	pkg_check_modules ( LIBOTR libotr )
++	pkg_check_modules ( LIBOTR libotr>=4.0.0 )
 +	if ( LIBOTR_FOUND )
 +		set ( HAVE_LIBOTR TRUE )
++	else()
++		# libotr started shipping .pc starting from 3.2.0...
++		pkg_check_modules ( LIBOTR libotr>=3.1.0 )
++		if ( LIBOTR_FOUND )
++			set ( HAVE_LIBOTR TRUE )
++			set ( HAVE_LIBOTR3 TRUE )
++		endif()
 +	endif ()
 +endif ()
 +
@@ -311,10 +318,10 @@
 +endif ()
 +
 +## The End ## vim: se ts=4 sw=4: ##
-diff -r 9dbc874e6cf7 mcabber/config.h.in
+diff -r 19a36ac5d0b5 mcabber/config.h.in
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/mcabber/config.h.in	Fri Jul 20 17:29:52 2012 +0300
-@@ -0,0 +1,49 @@
++++ b/mcabber/config.h.in	Sun Jan 13 06:40:40 2013 +0200
+@@ -0,0 +1,51 @@
 +/* help @help.c */
 +#define DATA_DIR                      "@DATA_DIR@"
 +/* conditional @main.c */ /* does it have any effect really? */
@@ -333,6 +340,8 @@
 +#cmakedefine HAVE_LIBIDN              @HAVE_LIBIDN@
 +/* alot */
 +#cmakedefine HAVE_LIBOTR              @HAVE_LIBOTR@
++/* otr.[ch] */
++#cmakedefine HAVE_LIBOTR3             @HAVE_LIBOTR3@
 +/* @screen.c */
 +#cmakedefine HAVE_LOCALCHARSET_H      @HAVE_LOCALCHARSET_H@
 +#cmakedefine HAVE_NCURSESW_NCURSES_H  @HAVE_NCURSESW_NCURSES_H@
@@ -364,10 +373,10 @@
 +/* option, also XEP0085? */
 +#cmakedefine XEP0022                  @XEP0022@
 +/* end */
-diff -r 9dbc874e6cf7 mcabber/configure.ac
---- a/mcabber/configure.ac	Fri Jul 20 17:29:26 2012 +0300
-+++ b/mcabber/configure.ac	Fri Jul 20 17:29:52 2012 +0300
-@@ -36,9 +36,8 @@
+diff -r 19a36ac5d0b5 mcabber/configure.ac
+--- a/mcabber/configure.ac	Sun Jan 13 06:17:13 2013 +0200
++++ b/mcabber/configure.ac	Sun Jan 13 06:40:40 2013 +0200
+@@ -35,9 +35,8 @@
  
  # Checks for header files.
  AC_HEADER_STDC
@@ -379,7 +388,7 @@
  AC_CHECK_HEADERS([unistd.h], , AC_MSG_ERROR([Missing header file]))
  AC_VAR_TIMEZONE_EXTERNALS
  
-@@ -59,10 +58,8 @@
+@@ -58,10 +57,8 @@
  AC_TYPE_SIGNAL
  AC_FUNC_STRFTIME
  AC_FUNC_VPRINTF
@@ -392,22 +401,22 @@
  
  
  AC_CHECK_DECLS([strptime],,,
-diff -r 9dbc874e6cf7 mcabber/hgcset.h.in
+diff -r 19a36ac5d0b5 mcabber/hgcset.h.in
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/mcabber/hgcset.h.in	Fri Jul 20 17:29:52 2012 +0300
++++ b/mcabber/hgcset.h.in	Sun Jan 13 06:40:40 2013 +0200
 @@ -0,0 +1,3 @@
 +/* this can go to config.h */
 +#define HGCSET "@HGCSET@"
 +/* end */
-diff -r 9dbc874e6cf7 mcabber/mcabber.menu.in
+diff -r 19a36ac5d0b5 mcabber/mcabber.menu.in
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/mcabber/mcabber.menu.in	Fri Jul 20 17:29:52 2012 +0300
++++ b/mcabber/mcabber.menu.in	Sun Jan 13 06:40:40 2013 +0200
 @@ -0,0 +1,2 @@
 +?package(mcabber):needs="text" section="Applications/Network/Communication"\
 +  title="mcabber" command="@CMAKE_INSTALL_PREFIX@/bin/mcabber"
-diff -r 9dbc874e6cf7 mcabber/mcabber.pc.in.in
+diff -r 19a36ac5d0b5 mcabber/mcabber.pc.in.in
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/mcabber/mcabber.pc.in.in	Fri Jul 20 17:29:52 2012 +0300
++++ b/mcabber/mcabber.pc.in.in	Sun Jan 13 06:40:40 2013 +0200
 @@ -0,0 +1,14 @@
 +prefix=${CMAKE_INSTALL_PREFIX}
 +exec_prefix=$${EMPTY}{prefix}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/automake-fix-deprecated-macro.diff	Sun Jan 13 06:42:35 2013 +0200
@@ -0,0 +1,17 @@
+# HG changeset patch
+# Parent 163fb7b56e26b914c31f34059011dbde78666536
+Fix deprecated AM_CONFIG_HEADER
+
+diff -r 163fb7b56e26 -r 651a27690961 mcabber/configure.ac
+--- a/mcabber/configure.ac	Sun Jan 06 09:48:27 2013 +0530
++++ b/mcabber/configure.ac	Sat Jan 12 18:00:08 2013 +0200
+@@ -5,8 +5,7 @@
+ AC_INIT([mcabber],[0.10.3-dev],[mcabber@lilotux.net])
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_SRCDIR([mcabber])
+-AM_CONFIG_HEADER(mcabber/config.h)
+-AC_CONFIG_HEADER(include/config.h)
++AC_CONFIG_HEADERS([mcabber/config.h include/config.h])
+ 
+ AC_PROG_LIBTOOL
+ AC_PROG_RANLIB
--- a/series	Fri Nov 30 21:11:10 2012 +0200
+++ b/series	Sun Jan 13 06:42:35 2013 +0200
@@ -1,3 +1,5 @@
+automake-fix-deprecated-macro.diff
+use-otr-v4.diff
 fix-date-fill.diff
 switch-to-experimental.diff
 separate-extcmd.diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/use-otr-v4.diff	Sun Jan 13 06:42:35 2013 +0200
@@ -0,0 +1,595 @@
+# HG changeset patch
+# Parent 1b31bdb72d83850b146a0e1e135eba35bad73d29
+Switch to libotr v4 API
+
+diff -r 1b31bdb72d83 mcabber/configure.ac
+--- a/mcabber/configure.ac	Sun Jan 13 04:35:32 2013 +0200
++++ b/mcabber/configure.ac	Sun Jan 13 06:15:55 2013 +0200
+@@ -183,16 +183,26 @@
+ 
+ # Check for otr
+ AC_ARG_ENABLE(otr,
+-              AC_HELP_STRING([--enable-otr],
+-                             [enable OTR (Off-the-Record) messaging support]),
+-              enable_otr=$enableval, otr="")
++    AC_HELP_STRING([--enable-otr],
++                   [enable OTR (Off-the-Record) messaging support]),
++    enable_otr=$enableval,
++    otr="")
+ if test "x$enable_otr" = "xyes"; then
+-  # Look for libgcrypt and libotr
+-  AM_PATH_LIBGCRYPT(1.2.2, [
+-          AM_PATH_LIBOTR(3.1.0, ,
+-                         AC_MSG_ERROR(libotr 3.1.0 or newer is required.))
+-      ], AC_MSG_ERROR(libgcrypt 1.2.2 or newer is required.)
+-  )
++    # Look for libgcrypt and libotr
++    AM_PATH_LIBGCRYPT(1.2.2, [
++        AM_PATH_LIBOTR(4.0.0, [
++            AC_DEFINE([HAVE_LIBOTR], 1, [Define if you use libotr])
++        ], [
++            AM_PATH_LIBOTR(3.1.0, [
++                AC_DEFINE([HAVE_LIBOTR], 1, [Define if you use libotr])
++                AC_DEFINE([HAVE_LIBOTR3], 1, [Define if you use libotr v3])
++            ], [
++                AC_MSG_ERROR(libotr 3.1.0 or newer is required.)
++            ])
++        ])
++    ], [
++        AC_MSG_ERROR(libgcrypt 1.2.2 or newer is required.)
++    ])
+ fi
+ 
+ # Check for Enchant stuff
+@@ -289,3 +299,4 @@
+                  mcabber.pc
+                  Makefile])
+ AC_OUTPUT
++dnl vim: set expandtab cindent cinoptions=>2\:2(0 sw=2 ts=2:  For Vim users...
+diff -r 1b31bdb72d83 mcabber/mcabber/otr.c
+--- a/mcabber/mcabber/otr.c	Sun Jan 13 04:35:32 2013 +0200
++++ b/mcabber/mcabber/otr.c	Sun Jan 13 06:15:55 2013 +0200
+@@ -56,6 +56,20 @@
+                                          const char *protocol,
+                                          const char *recipient,
+                                          const char *message);
++static void       cb_update_context_list(void *opdata);
++static void       cb_new_fingerprint    (void *opdata, OtrlUserState us,
++                                         const char *accountname,
++                                         const char *protocol,
++                                         const char *username,
++                                         unsigned char fingerprint[20]);
++static void       cb_write_fingerprints (void *opdata);
++static void       cb_gone_secure        (void *opdata, ConnContext *context);
++static void       cb_gone_insecure      (void *opdata, ConnContext *context);
++static void       cb_still_secure       (void *opdata, ConnContext *context,
++                                         int is_reply);
++static int        cb_max_message_size   (void *opdata, ConnContext *context);
++
++#ifdef HAVE_LIBOTR3
+ static void       cb_notify             (void *opdata,
+                                          OtrlNotifyLevel level,
+                                          const char *accountname,
+@@ -69,22 +83,26 @@
+                                          const char *protocol,
+                                          const char *username,
+                                          const char *msg);
+-static void       cb_update_context_list(void *opdata);
+ static const char *cb_protocol_name     (void *opdata, const char *protocol);
+ static void       cb_protocol_name_free (void *opdata,
+                                          const char *protocol_name);
+-static void       cb_new_fingerprint    (void *opdata, OtrlUserState us,
+-                                         const char *accountname,
+-                                         const char *protocol,
+-                                         const char *username,
+-                                         unsigned char fingerprint[20]);
+-static void       cb_write_fingerprints (void *opdata);
+-static void       cb_gone_secure        (void *opdata, ConnContext *context);
+-static void       cb_gone_insecure      (void *opdata, ConnContext *context);
+-static void       cb_still_secure       (void *opdata, ConnContext *context,
+-                                         int is_reply);
+ static void       cb_log_message        (void *opdata, const char *message);
+-static int        cb_max_message_size   (void *opdata, ConnContext *context);
++
++static void       otr_handle_smp_tlvs   (OtrlTLV *tlvs, ConnContext *ctx);
++#else /* HAVE_LIBOTR3 */
++static char *tagfile = NULL;
++static guint otr_timer_source = 0;
++
++static void       cb_handle_smp_event   (void *opdata, OtrlSMPEvent event,
++                                         ConnContext *context, unsigned short percent,
++                                         char *question);
++static void       cb_handle_msg_event   (void *opdata, OtrlMessageEvent event,
++                                         ConnContext *context, const char *message,
++                                         gcry_error_t err);
++static void       cb_create_instag      (void *opdata, const char *accountname,
++                                         const char *protocol);
++static void       cb_timer_control      (void *opdata, unsigned int interval);
++#endif /* HAVE_LIBOTR3 */
+ 
+ static OtrlMessageAppOps ops =
+ {
+@@ -92,26 +110,44 @@
+   cb_create_privkey,
+   cb_is_logged_in,
+   cb_inject_message,
++#ifdef HAVE_LIBOTR3
+   cb_notify,
+   cb_display_otr_message,
++#endif
+   cb_update_context_list,
++#ifdef HAVE_LIBOTR3
+   cb_protocol_name,
+   cb_protocol_name_free,
++#endif
+   cb_new_fingerprint,
+   cb_write_fingerprints,
+   cb_gone_secure,
+   cb_gone_insecure,
+   cb_still_secure,
++#ifdef HAVE_LIBOTR3
+   cb_log_message,
++#endif
+   cb_max_message_size,
+-  NULL, /*account_name*/
+-  NULL  /*account_name_free*/
++  NULL, /* account_name */
++  NULL, /* account_name_free */
++#ifndef HAVE_LIBOTR3
++  NULL, /* received_symkey */
++  NULL, /* otr_error_message */
++  NULL, /* otr_error_message_free */
++  NULL, /* resent_msg_prefix */
++  NULL, /* resent_msg_prefix_free */
++  cb_handle_smp_event,
++  cb_handle_msg_event,
++  cb_create_instag,
++  NULL, /* convert_msg */
++  NULL, /* convert_free */
++  cb_timer_control,
++#endif
+ };
+ 
+ static void otr_message_disconnect(ConnContext *ctx);
+ static ConnContext *otr_get_context(const char *buddy);
+ static void otr_startstop(const char *buddy, int start);
+-static void otr_handle_smp_tlvs(OtrlTLV *tlvs, ConnContext *ctx);
+ 
+ static char *otr_get_dir(void);
+ 
+@@ -145,6 +181,13 @@
+     scr_LogPrint(LPRINT_LOGNORM, "Could not read OTR fingerprints from %s",
+                  fprfile);
+   }
++#ifndef HAVE_LIBOTR3
++  tagfile = g_strdup_printf("%s%s.tag", root, account);
++  if (otrl_instag_read(userstate, tagfile)) {
++    scr_LogPrint(LPRINT_LOGNORM, "Could not read OTR instance tag from %s", tagfile);
++    cb_create_instag(NULL, account, OTR_PROTOCOL_NAME);
++  }
++#endif
+ }
+ 
+ void otr_terminate(void)
+@@ -154,6 +197,13 @@
+   if (!otr_is_enabled)
+     return;
+ 
++#ifndef HAVE_LIBOTR3
++  if (otr_timer_source > 0) {
++    g_source_remove (otr_timer_source);
++    otr_timer_source = 0;
++  }
++#endif
++
+   for (ctx = userstate->context_root; ctx; ctx = ctx->next)
+     if (ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED)
+       otr_message_disconnect(ctx);
+@@ -175,6 +225,12 @@
+   userstate = NULL;
+   g_free(keyfile);
+   keyfile = NULL;
++  g_free(fprfile);
++  fprfile = NULL;
++#ifndef HAVE_LIBOTR3
++  g_free(tagfile);
++  tagfile = NULL;
++#endif
+ }
+ 
+ static char *otr_get_dir(void)
+@@ -206,7 +262,12 @@
+ 
+   mc_strtolower(lowcasebuddy);
+   ctx = otrl_context_find(userstate, lowcasebuddy, account, OTR_PROTOCOL_NAME,
++#ifdef HAVE_LIBOTR3
+                           1, &null, NULL, NULL);
++#else
++                          // INSTAG XXX
++                          OTRL_INSTAG_BEST, 1, &null, NULL, NULL);
++#endif
+   g_free(lowcasebuddy);
+   return ctx;
+ }
+@@ -216,7 +277,12 @@
+   if (ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED)
+     cb_gone_insecure(NULL, ctx);
+   otrl_message_disconnect(userstate, &ops, NULL, ctx->accountname,
++#ifdef HAVE_LIBOTR3
+                           ctx->protocol, ctx->username);
++#else
++                          // INSTAG XXX
++                          ctx->protocol, ctx->username, OTRL_INSTAG_BEST);
++#endif
+ }
+ 
+ static void otr_startstop(const char *buddy, int start)
+@@ -283,6 +349,8 @@
+   cb_write_fingerprints(NULL);
+ }
+ 
++#ifdef HAVE_LIBOTR3
++
+ static void otr_handle_smp_tlvs(OtrlTLV *tlvs, ConnContext *ctx)
+ {
+   OtrlTLV *tlv = NULL;
+@@ -354,6 +422,130 @@
+   }
+ }
+ 
++#else /* HAVE_LIBOTR3 */
++
++static void cb_handle_smp_event(void *opdata, OtrlSMPEvent event,
++                                ConnContext *context, unsigned short percent,
++                                char *question)
++{
++  const char *msg = NULL;
++  char *freeme = NULL;
++  switch (event) {
++    case OTRL_SMPEVENT_ASK_FOR_SECRET:
++      msg = freeme = g_strdup_printf("OTR: Socialist Millionaires' Protocol: "
++                                     "Received SMP Initiation.\n"
++                                     "Answer with /otr smpr %s $secret",
++                                     context->username);
++      break;
++    case OTRL_SMPEVENT_ASK_FOR_ANSWER:
++      msg = freeme = g_strdup_printf("OTR: Socialist Millionaires' Protocol: "
++                                     "Received SMP Initiation.\n"
++                                     "Answer with /otr smpr %s $secret\n"
++                                     "Question: %s", context->username,
++                                     question);
++      break;
++    case OTRL_SMPEVENT_CHEATED:
++      msg = "OTR: Socialist Millionaires' Protocol: Correspondent cancelled negotiation!";
++      otrl_message_abort_smp(userstate, &ops, opdata, context);
++      break;
++    case OTRL_SMPEVENT_IN_PROGRESS:
++      scr_log_print(LPRINT_DEBUG, "OTR: Socialist Millionaires' Protocol: "
++                                  "Negotiation is in pogress...");
++      break;
++    case OTRL_SMPEVENT_SUCCESS:
++      msg = "OTR: Socialist Millionaires' Protocol: Success!";
++      break;
++    case OTRL_SMPEVENT_FAILURE:
++      msg = "OTR: Socialist Millionaires' Protocol: Failure.";
++      break;
++    case OTRL_SMPEVENT_ABORT:
++      msg = "OTR: Socialist Millionaires' Protocol: Aborted.";
++      break;
++    case OTRL_SMPEVENT_ERROR:
++      msg = "OTR: Socialist Millionaires' Protocol: Error occured, aborting negotiations!";
++      otrl_message_abort_smp(userstate, &ops, opdata, context);
++      break;
++    default:
++      break;
++  }
++
++  if (msg) {
++    scr_WriteIncomingMessage(context->username, msg, 0, HBB_PREFIX_INFO, 0);
++    g_free(freeme);
++  }
++}
++
++static void cb_handle_msg_event(void *opdata, OtrlMessageEvent event,
++                                ConnContext *context, const char *message,
++                                gcry_error_t err)
++{
++  const char *msg = NULL;
++  char *freeme = NULL;
++  switch (event) {
++    case OTRL_MSGEVENT_ENCRYPTION_REQUIRED:
++      msg = "OTR: Policy requires encryption on message!";
++      break;
++    case OTRL_MSGEVENT_ENCRYPTION_ERROR:
++      msg = "OTR: Encryption error! Message not sent.";
++      break;
++    case OTRL_MSGEVENT_CONNECTION_ENDED:
++      msg = "OTR: Connection closed by remote end, message lost. "
++            "Close or refresh connection.";
++      break;
++    case OTRL_MSGEVENT_SETUP_ERROR:
++      // FIXME
++      msg = freeme = g_strdup_printf("OTR: Error setting up private conversation: %u",
++                                     err);
++      break;
++    case OTRL_MSGEVENT_MSG_REFLECTED:
++      msg = "OTR: Received own OTR message!";
++      break;
++    case OTRL_MSGEVENT_MSG_RESENT:
++      msg = "OTR: Previous message was resent.";
++      break;
++    case OTRL_MSGEVENT_RCVDMSG_NOT_IN_PRIVATE:
++      msg = "OTR: Received encrypted message, but connection is not established " \
++            "yet! Message lost.";
++      break;
++    case OTRL_MSGEVENT_RCVDMSG_UNREADABLE:
++      msg = "OTR: Unable to read incoming message!";
++      break;
++    case OTRL_MSGEVENT_RCVDMSG_MALFORMED:
++      msg = "OTR: Malformed incoming message!";
++      break;
++    case OTRL_MSGEVENT_LOG_HEARTBEAT_RCVD:
++      scr_log_print(LPRINT_DEBUG, "OTR: Received heartbeat.");
++      break;
++    case OTRL_MSGEVENT_LOG_HEARTBEAT_SENT:
++      scr_log_print(LPRINT_DEBUG, "OTR: Sent heartbeat.");
++      break;
++    case OTRL_MSGEVENT_RCVDMSG_GENERAL_ERR:
++      msg = freeme = g_strdup_printf("OTR: Received general otr error: %s",
++                                     message);
++      break;
++    case OTRL_MSGEVENT_RCVDMSG_UNENCRYPTED:
++      msg = freeme = g_strdup_printf("OTR: Received unencrypted message: %s",
++                                     message);
++      break;
++    case OTRL_MSGEVENT_RCVDMSG_UNRECOGNIZED:
++      msg = "OTR: Unable to determine type of received OTR message!";
++      break;
++    case OTRL_MSGEVENT_RCVDMSG_FOR_OTHER_INSTANCE:
++      // XXX
++      scr_log_print(LPRINT_DEBUG, "OTR: Received message for other instance.");
++      break;
++    default:
++      break;
++  }
++
++  if (msg) {
++    scr_WriteIncomingMessage(context->username, msg, 0, HBB_PREFIX_INFO, 0);
++    g_free(freeme);
++  }
++}
++
++#endif /* HAVE_LIBOTR3 */
++
+ /*
+  * returns whether a otr_message was received
+  * sets *otr_data to NULL, when it was an internal otr message
+@@ -362,8 +554,10 @@
+ {
+   int ignore_message;
+   char *newmessage = NULL;
++#ifdef HAVE_LIBOTR3
+   OtrlTLV *tlvs = NULL;
+   OtrlTLV *tlv = NULL;
++#endif
+   ConnContext *ctx;
+ 
+   ctx = otr_get_context(buddy);
+@@ -371,8 +565,8 @@
+   ignore_message = otrl_message_receiving(userstate, &ops, NULL,
+                                           ctx->accountname, ctx->protocol,
+                                           ctx->username, *otr_data,
+-                                          &newmessage, &tlvs,NULL, NULL);
+-
++#ifdef HAVE_LIBOTR3
++                                          &newmessage, &tlvs, NULL, NULL);
+ 
+   tlv = otrl_tlv_find(tlvs, OTRL_TLV_DISCONNECTED);
+   if (tlv) {
+@@ -387,6 +581,9 @@
+ 
+   if (tlvs != NULL)
+     otrl_tlv_free(tlvs);
++#else
++                                          &newmessage, NULL, NULL, NULL, NULL);
++#endif
+ 
+   if (ignore_message)
+     *otr_data = NULL;
+@@ -410,13 +607,27 @@
+ 
+   if (ctx->msgstate == OTRL_MSGSTATE_PLAINTEXT)
+     err = otrl_message_sending(userstate, &ops, NULL, ctx->accountname,
++#ifdef HAVE_LIBOTR3
+                                ctx->protocol, ctx->username, *msg, NULL,
+                                &newmessage, NULL, NULL);
++#else
++                               // INSTAG XXX
++                               ctx->protocol, ctx->username, OTRL_INSTAG_BEST,
++                               *msg, NULL, &newmessage, OTRL_FRAGMENT_SEND_SKIP,
++                               NULL, NULL, NULL);
++#endif
+   else {
+     htmlmsg = html_escape(*msg);
+     err = otrl_message_sending(userstate, &ops, NULL, ctx->accountname,
++#ifdef HAVE_LIBOTR3
+                                ctx->protocol, ctx->username, htmlmsg, NULL,
+                                &newmessage, NULL, NULL);
++#else
++                               // INSTAG XXX
++                               ctx->protocol, ctx->username, OTRL_INSTAG_BEST,
++                               htmlmsg, NULL, &newmessage, OTRL_FRAGMENT_SEND_SKIP,
++                               NULL, NULL, NULL);
++#endif
+     g_free(htmlmsg);
+   }
+ 
+@@ -648,42 +859,6 @@
+                   LM_MESSAGE_SUB_TYPE_NOT_SET, NULL);
+ }
+ 
+-/* Display a notification message for a particular
+- * accountname / protocol / username conversation. */
+-static void cb_notify(void *opdata, OtrlNotifyLevel level,
+-                      const char *accountname, const char *protocol,
+-                      const char *username, const char *title,
+-                      const char *primary, const char *secondary)
+-{
+-  char *type;
+-  char *sbuf = NULL;
+-  switch (level) {
+-    case OTRL_NOTIFY_ERROR:   type = "error";   break;
+-    case OTRL_NOTIFY_WARNING: type = "warning"; break;
+-    case OTRL_NOTIFY_INFO:    type = "info";    break;
+-    default:                  type = "unknown";
+-  }
+-  sbuf = g_strdup_printf("OTR %s:%s\n%s\n%s",type,title, primary, secondary);
+-  scr_WriteIncomingMessage(username, sbuf, 0, HBB_PREFIX_INFO, 0);
+-  g_free(sbuf);
+-}
+-
+-/* Display an OTR control message for a particular
+- * accountname / protocol / username conversation.  Return 0 if you are able
+- * to successfully display it.  If you return non-0 (or if this
+- * function is NULL), the control message will be displayed inline,
+- * as a received message, or else by using the above notify()
+- * callback. */
+-static int cb_display_otr_message(void *opdata, const char *accountname,
+-                                  const char *protocol, const char *username,
+-                                  const char *msg)
+-{
+-  char *strippedmsg = html_strip(msg);
+-  scr_WriteIncomingMessage(username, strippedmsg, 0, HBB_PREFIX_INFO, 0);
+-  g_free(strippedmsg);
+-  return 0;
+-}
+-
+ /* When the list of ConnContexts changes (including a change in
+  * state), this is called so the UI can be updated. */
+ static void cb_update_context_list(void *opdata)
+@@ -692,19 +867,6 @@
+    * then use this function (?!)*/
+ }
+ 
+-/* Return a newly allocated string containing a human-friendly name
+- * for the given protocol id */
+-static const char *cb_protocol_name(void *opdata, const char *protocol)
+-{
+-  return protocol;
+-}
+-
+-/* Deallocate a string allocated by protocol_name */
+-static void cb_protocol_name_free (void *opdata, const char *protocol_name)
+-{
+-  /* We didn't allocated memory, so we don't have to free anything :p */
+-}
+-
+ /* A new fingerprint for the given user has been received. */
+ static void cb_new_fingerprint(void *opdata, OtrlUserState us,
+                                const char *accountname, const char *protocol,
+@@ -748,12 +910,92 @@
+                            HBB_PREFIX_INFO, 0);
+ }
+ 
++#ifdef HAVE_LIBOTR3
++
++/* Display a notification message for a particular
++ * accountname / protocol / username conversation. */
++static void cb_notify(void *opdata, OtrlNotifyLevel level,
++                      const char *accountname, const char *protocol,
++                      const char *username, const char *title,
++                      const char *primary, const char *secondary)
++{
++  char *type;
++  char *sbuf = NULL;
++  switch (level) {
++    case OTRL_NOTIFY_ERROR:   type = "error";   break;
++    case OTRL_NOTIFY_WARNING: type = "warning"; break;
++    case OTRL_NOTIFY_INFO:    type = "info";    break;
++    default:                  type = "unknown";
++  }
++  sbuf = g_strdup_printf("OTR %s:%s\n%s\n%s",type,title, primary, secondary);
++  scr_WriteIncomingMessage(username, sbuf, 0, HBB_PREFIX_INFO, 0);
++  g_free(sbuf);
++}
++
++/* Display an OTR control message for a particular
++ * accountname / protocol / username conversation.  Return 0 if you are able
++ * to successfully display it.  If you return non-0 (or if this
++ * function is NULL), the control message will be displayed inline,
++ * as a received message, or else by using the above notify()
++ * callback. */
++static int cb_display_otr_message(void *opdata, const char *accountname,
++                                  const char *protocol, const char *username,
++                                  const char *msg)
++{
++  char *strippedmsg = html_strip(msg);
++  scr_WriteIncomingMessage(username, strippedmsg, 0, HBB_PREFIX_INFO, 0);
++  g_free(strippedmsg);
++  return 0;
++}
++
++/* Return a newly allocated string containing a human-friendly name
++ * for the given protocol id */
++static const char *cb_protocol_name(void *opdata, const char *protocol)
++{
++  return protocol;
++}
++
++/* Deallocate a string allocated by protocol_name */
++static void cb_protocol_name_free (void *opdata, const char *protocol_name)
++{
++  /* We didn't allocated memory, so we don't have to free anything :p */
++}
++
+ /* Log a message.  The passed message will end in "\n". */
+ static void cb_log_message(void *opdata, const char *message)
+ {
+   scr_LogPrint(LPRINT_DEBUG, "OTR: %s", message);
+ }
+ 
++#else /* HAVE_LIBOTR3 */
++
++/* Generate unique instance tag for account. */
++static void cb_create_instag(void *opdata, const char *accountname,
++                             const char *protocol)
++{
++  if (otrl_instag_generate(userstate, tagfile, accountname, protocol)) {
++    scr_LogPrint(LPRINT_LOGNORM, "OTR instance tag generation failed!");
++  }
++}
++
++static gboolean otr_timer_cb(gpointer userdata)
++{
++  otrl_message_poll(userstate, &ops, userdata);
++  return TRUE;
++}
++
++static void cb_timer_control(void *opdata, unsigned int interval)
++{
++  if (otr_timer_source > 0) {
++    g_source_remove(otr_timer_source);
++    otr_timer_source = 0;
++  }
++  if (interval > 0)
++    otr_timer_source = g_timeout_add_seconds(interval, otr_timer_cb, opdata);
++}
++
++#endif /* HAVE_LIBOTR3 */
++
+ /* Find the maximum message size supported by this protocol. */
+ static int cb_max_message_size(void *opdata, ConnContext *context)
+ {
+diff -r 1b31bdb72d83 mcabber/mcabber/otr.h
+--- a/mcabber/mcabber/otr.h	Sun Jan 13 04:35:32 2013 +0200
++++ b/mcabber/mcabber/otr.h	Sun Jan 13 06:15:55 2013 +0200
+@@ -5,6 +5,9 @@
+ 
+ #ifdef HAVE_LIBOTR
+ 
++#ifndef HAVE_LIBOTR3
++# include <libotr/instag.h>
++#endif
+ #include <libotr/proto.h>
+ #include <libotr/message.h>
+ #include <libotr/privkey.h>