aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2010-09-01 23:09:27 +0100
committerWilmer van der Gaast <wilmer@gaast.net>2010-09-01 23:09:27 +0100
commit934db064a58ebec2edea83df4fa07e2c83220344 (patch)
treeb7a4aac7deff47cc743102dcb2bd8ded426c8bcd
parent0c85c08d210e16bb10dc283b4a1478ce53c0c1b1 (diff)
Do encryption and decryption. Somehow SMP and other things aren't working
so well yet, at least when testing with Pidgin on the other side. Not sure where the bug is.
-rw-r--r--irc.h8
-rw-r--r--irc_im.c86
-rw-r--r--otr.c41
-rw-r--r--otr.h26
-rw-r--r--protocols/bee_user.c4
5 files changed, 102 insertions, 63 deletions
diff --git a/irc.h b/irc.h
index 516cc959..0c8d2981 100644
--- a/irc.h
+++ b/irc.h
@@ -229,12 +229,16 @@ typedef struct irc_plugin
/* At the end of irc_free(). */
void (*irc_free)( irc_t *irc );
+ /* Problem with the following two functions is ordering if multiple
+ plugins are handling them. Let's keep fixing that problem for
+ whenever it becomes important. */
+
/* Called by bee_irc_user_privmsg_cb(). Return NULL if you want to
abort sending the msg. */
- char* (*filter_msg_out)( irc_user_t *iu, const char *msg, int flags );
+ char* (*filter_msg_out)( irc_user_t *iu, char *msg, int flags );
/* Called by bee_irc_user_msg(). Return NULL if you swallowed the
message and don't want anything to go to the user. */
- char* (*filter_msg_in)( irc_user_t *iu, const char *msg, int flags );
+ char* (*filter_msg_in)( irc_user_t *iu, char *msg, int flags );
} irc_plugin_t;
extern GSList *irc_plugins; /* struct irc_plugin */
diff --git a/irc_im.c b/irc_im.c
index 662a5bf2..f2262100 100644
--- a/irc_im.c
+++ b/irc_im.c
@@ -191,13 +191,15 @@ void bee_irc_channel_update( irc_t *irc, irc_channel_t *ic, irc_user_t *iu )
}
}
-static gboolean bee_irc_user_msg( bee_t *bee, bee_user_t *bu, const char *msg, time_t sent_at )
+static gboolean bee_irc_user_msg( bee_t *bee, bee_user_t *bu, const char *msg_, time_t sent_at )
{
irc_t *irc = bee->ui_data;
irc_user_t *iu = (irc_user_t *) bu->ui_data;
char *dst, *prefix = NULL;
char *wrapped, *ts = NULL;
irc_channel_t *ic = NULL;
+ char *msg = g_strdup( msg_ );
+ GSList *l;
if( sent_at > 0 && set_getbool( &irc->b->set, "display_timestamps" ) )
ts = irc_format_timestamp( irc, sent_at );
@@ -223,11 +225,41 @@ static gboolean bee_irc_user_msg( bee_t *bee, bee_user_t *bu, const char *msg, t
ts = NULL;
}
+ for( l = irc_plugins; l; l = l->next )
+ {
+ irc_plugin_t *p = l->data;
+ if( p->filter_msg_in )
+ {
+ char *s = p->filter_msg_in( iu, msg, 0 );
+ if( s )
+ {
+ if( s != msg )
+ g_free( msg );
+ msg = s;
+ }
+ else
+ {
+ /* Modules can swallow messages. */
+ return TRUE;
+ }
+ }
+ }
+
+ if( ( g_strcasecmp( set_getstr( &bee->set, "strip_html" ), "always" ) == 0 ) ||
+ ( ( bu->ic->flags & OPT_DOES_HTML ) && set_getbool( &bee->set, "strip_html" ) ) )
+ {
+ char *s = g_strdup( msg );
+ strip_html( s );
+ g_free( msg );
+ msg = s;
+ }
+
wrapped = word_wrap( msg, 425 );
irc_send_msg( iu, "PRIVMSG", dst, wrapped, prefix );
g_free( wrapped );
g_free( prefix );
+ g_free( msg );
g_free( ts );
return TRUE;
@@ -348,18 +380,18 @@ static gboolean bee_irc_user_privmsg( irc_user_t *iu, const char *msg )
set_getint( &iu->irc->b->set, "away_reply_timeout" );
}
+ if( iu->pastebuf == NULL )
+ iu->pastebuf = g_string_new( msg );
+ else
+ {
+ b_event_remove( iu->pastebuf_timer );
+ g_string_append_printf( iu->pastebuf, "\n%s", msg );
+ }
+
if( set_getbool( &iu->irc->b->set, "paste_buffer" ) )
{
int delay;
- if( iu->pastebuf == NULL )
- iu->pastebuf = g_string_new( msg );
- else
- {
- b_event_remove( iu->pastebuf_timer );
- g_string_append_printf( iu->pastebuf, "\n%s", msg );
- }
-
if( ( delay = set_getint( &iu->irc->b->set, "paste_buffer_delay" ) ) <= 5 )
delay *= 1000;
@@ -368,17 +400,45 @@ static gboolean bee_irc_user_privmsg( irc_user_t *iu, const char *msg )
return TRUE;
}
else
- return bee_user_msg( iu->irc->b, iu->bu, msg, 0 );
+ {
+ bee_irc_user_privmsg_cb( iu, 0, 0 );
+
+ return TRUE;
+ }
}
static gboolean bee_irc_user_privmsg_cb( gpointer data, gint fd, b_input_condition cond )
{
irc_user_t *iu = data;
+ char *msg = g_string_free( iu->pastebuf, FALSE );
+ GSList *l;
+
+ for( l = irc_plugins; l; l = l->next )
+ {
+ irc_plugin_t *p = l->data;
+ if( p->filter_msg_out )
+ {
+ char *s = p->filter_msg_out( iu, msg, 0 );
+ if( s )
+ {
+ if( s != msg )
+ g_free( msg );
+ msg = s;
+ }
+ else
+ {
+ /* Modules can swallow messages. */
+ iu->pastebuf = NULL;
+ g_free( msg );
+ return FALSE;
+ }
+ }
+ }
- bee_user_msg( iu->irc->b, iu->bu, iu->pastebuf->str, 0 );
+ bee_user_msg( iu->irc->b, iu->bu, msg, 0 );
- g_string_free( iu->pastebuf, TRUE );
- iu->pastebuf = 0;
+ g_free( msg );
+ iu->pastebuf = NULL;
iu->pastebuf_timer = 0;
return FALSE;
diff --git a/otr.c b/otr.c
index 1395f49a..11abab63 100644
--- a/otr.c
+++ b/otr.c
@@ -343,24 +343,25 @@ int otr_check_for_key(account_t *a)
}
}
-char *otr_handle_message(struct im_connection *ic, const char *handle, const char *msg)
+char *otr_filter_msg_in(irc_user_t *iu, char *msg, int flags)
{
int ignore_msg;
char *newmsg = NULL;
OtrlTLV *tlvs = NULL;
char *colormsg;
- irc_t *irc = ic->bee->ui_data;
+ irc_t *irc = iu->irc;
+ struct im_connection *ic = iu->bu->ic;
/* don't do OTR on certain (not classic IM) protocols, e.g. twitter */
if(ic->acc->prpl->options & OPT_NOOTR) {
- return (g_strdup(msg));
+ return msg;
}
ignore_msg = otrl_message_receiving(irc->otr->us, &otr_ops, ic,
- ic->acc->user, ic->acc->prpl->name, handle, msg, &newmsg,
+ ic->acc->user, ic->acc->prpl->name, iu->bu->handle, msg, &newmsg,
&tlvs, NULL, NULL);
- otr_handle_smp(ic, handle, tlvs);
+ otr_handle_smp(ic, iu->bu->handle, tlvs);
if(ignore_msg) {
/* this was an internal OTR protocol message */
@@ -370,10 +371,10 @@ char *otr_handle_message(struct im_connection *ic, const char *handle, const cha
return g_strdup(msg);
} else {
/* OTR has processed this message */
- ConnContext *context = otrl_context_find(irc->otr->us, handle,
+ ConnContext *context = otrl_context_find(irc->otr->us, iu->bu->handle,
ic->acc->user, ic->acc->prpl->name, 0, NULL, NULL, NULL);
if(context && context->msgstate == OTRL_MSGSTATE_ENCRYPTED &&
- set_getbool(&ic->bee->set, "color_encrypted")) {
+ set_getbool(&ic->bee->set, "otr_color_encrypted")) {
/* color according to f'print trust */
int color;
const char *trust = context->active_fingerprint->trust;
@@ -397,34 +398,34 @@ char *otr_handle_message(struct im_connection *ic, const char *handle, const cha
}
}
-int otr_send_message(struct im_connection *ic, const char *handle, const char *msg, int flags)
+char *otr_filter_msg_out(irc_user_t *iu, char *msg, int flags)
{
int st;
char *otrmsg = NULL;
ConnContext *ctx = NULL;
- irc_t *irc = ic->bee->ui_data;
+ irc_t *irc = iu->irc;
+ struct im_connection *ic = iu->bu->ic;
/* don't do OTR on certain (not classic IM) protocols, e.g. twitter */
if(ic->acc->prpl->options & OPT_NOOTR) {
- /* TODO(wilmer): const */
- return (ic->acc->prpl->buddy_msg(ic, (char*) handle, (char*) msg, flags));
+ return msg;
}
st = otrl_message_sending(irc->otr->us, &otr_ops, ic,
- ic->acc->user, ic->acc->prpl->name, handle,
+ ic->acc->user, ic->acc->prpl->name, iu->bu->handle,
msg, NULL, &otrmsg, NULL, NULL);
if(st) {
- return st;
+ return NULL;
}
ctx = otrl_context_find(irc->otr->us,
- handle, ic->acc->user, ic->acc->prpl->name,
+ iu->bu->handle, ic->acc->user, ic->acc->prpl->name,
1, NULL, NULL, NULL);
if(otrmsg) {
if(!ctx) {
otrl_message_free(otrmsg);
- return 1;
+ return NULL;
}
st = otrl_message_fragment_and_send(&otr_ops, ic, ctx,
otrmsg, OTRL_FRAGMENT_SEND_ALL, NULL);
@@ -432,16 +433,20 @@ int otr_send_message(struct im_connection *ic, const char *handle, const char *m
} else {
/* note: otrl_message_sending handles policy, so that if REQUIRE_ENCRYPTION is set,
this case does not occur */
- st = ic->acc->prpl->buddy_msg( ic, (char *)handle, (char *)msg, flags );
+ return msg;
}
- return st;
+ /* TODO: Error reporting should be done here now (if st!=0), probably. */
+
+ return NULL;
}
static const struct irc_plugin otr_plugin =
{
otr_irc_new,
otr_irc_free,
+ otr_filter_msg_out,
+ otr_filter_msg_in,
};
static void cmd_otr(irc_t *irc, char **args)
@@ -715,7 +720,7 @@ void cmd_otr_connect(irc_t *irc, char **args)
return;
}
- /* TODO(wilmer): imc_buddy_msg(u->bu->ic, u->bu->handle, "?OTR?", 0); */
+ bee_user_msg(irc->b, u->bu, "?OTR?", 0);
}
void cmd_otr_smp(irc_t *irc, char **args)
diff --git a/otr.h b/otr.h
index c18d12af..41f54585 100644
--- a/otr.h
+++ b/otr.h
@@ -40,7 +40,6 @@ struct im_connection;
struct account;
-#ifdef WITH_OTR
#include <libotr/proto.h>
#include <libotr/message.h>
#include <libotr/privkey.h>
@@ -80,29 +79,4 @@ void otr_rename(const char *onick, const char *nnick);
/* called from account_add() */
int otr_check_for_key(struct account *a);
-/* called from imcb_buddy_msg() */
-char *otr_handle_message(struct im_connection *ic, const char *handle,
- const char *msg);
-
-/* called from imc_buddy_msg() */
-int otr_send_message(struct im_connection *ic, const char *handle, const char *msg,
- int flags);
-
-#else
-
-typedef void otr_t;
-typedef void *OtrlMessageAppOps;
-
-#define otr_free(otr) {}
-#define otr_load(irc) {}
-#define otr_save(irc) {}
-#define otr_remove(nick) {}
-#define otr_rename(onick,nnick) {}
-#define otr_check_for_key(acc) (0)
-#define otr_handle_message(ic,handle,msg) (g_strdup(msg))
-#define otr_send_message(ic,h,m,f) (ic->acc->prpl->buddy_msg(ic,h,m,f))
-
-void cmd_otr_nosupport(void *, char **);
-
-#endif
#endif
diff --git a/protocols/bee_user.c b/protocols/bee_user.c
index 04253c47..33853a1e 100644
--- a/protocols/bee_user.c
+++ b/protocols/bee_user.c
@@ -237,10 +237,6 @@ void imcb_buddy_msg( struct im_connection *ic, const char *handle, char *msg, ui
}
}
- if( ( g_strcasecmp( set_getstr( &ic->bee->set, "strip_html" ), "always" ) == 0 ) ||
- ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->bee->set, "strip_html" ) ) )
- strip_html( msg );
-
if( bee->ui->user_msg && bu )
bee->ui->user_msg( bee, bu, msg, sent_at );
else