/********************************************************************\ * BitlBee -- An IRC to other IM-networks gateway * * * * Copyright 2002-2006 Wilmer van der Gaast and others * \********************************************************************/ /* * nogaim * * Gaim without gaim - for BitlBee * * This file contains functions called by the Gaim IM-modules. It's written * from scratch for BitlBee and doesn't contain any code from Gaim anymore * (except for the function names). */ /* This program 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 with the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define BITLBEE_CORE #include "nogaim.h" #include static int remove_chat_buddy_silent( struct groupchat *b, const char *handle ); GSList *connections; #ifdef WITH_PLUGINS gboolean load_plugin(char *path) { void (*init_function) (void); GModule *mod = g_module_open(path, G_MODULE_BIND_LAZY); if(!mod) { log_message(LOGLVL_ERROR, "Can't find `%s', not loading (%s)\n", path, g_module_error()); return FALSE; } if(!g_module_symbol(mod,"init_plugin",(gpointer *) &init_function)) { log_message(LOGLVL_WARNING, "Can't find function `init_plugin' in `%s'\n", path); return FALSE; } init_function(); return TRUE; } void load_plugins(void) { GDir *dir; GError *error = NULL; dir = g_dir_open(global.conf->plugindir, 0, &error); if (dir) { const gchar *entry; char *path; while ((entry = g_dir_read_name(dir))) { path = g_build_filename(global.conf->plugindir, entry, NULL); if(!path) { log_message(LOGLVL_WARNING, "Can't build path for %s\n", entry); continue; } load_plugin(path); g_free(path); } g_dir_close(dir); } } #endif /* nogaim.c */ GList *protocols = NULL; void register_protocol (struct prpl *p) { protocols = g_list_append(protocols, p); } struct prpl *find_protocol(const char *name) { GList *gl; for (gl = protocols; gl; gl = gl->next) { struct prpl *proto = gl->data; if(!g_strcasecmp(proto->name, name)) return proto; } return NULL; } /* nogaim.c */ void nogaim_init() { extern void msn_initmodule(); extern void oscar_initmodule(); extern void byahoo_initmodule(); extern void jabber_initmodule(); #ifdef WITH_MSN msn_initmodule(); #endif #ifdef WITH_OSCAR oscar_initmodule(); #endif #ifdef WITH_YAHOO byahoo_initmodule(); #endif #ifdef WITH_JABBER jabber_initmodule(); #endif #ifdef WITH_PLUGINS load_plugins(); #endif } GSList *get_connections() { return connections; } /* multi.c */ struct im_connection *imcb_new( account_t *acc ) { struct im_connection *ic; ic = g_new0( struct im_connection, 1 ); ic->irc = acc->irc; ic->acc = acc; acc->ic = ic; connections = g_slist_append( connections, ic ); return( ic ); } void imc_free( struct im_connection *ic ) { account_t *a; /* Destroy the pointer to this connection from the account list */ for( a = ic->irc->accounts; a; a = a->next ) if( a->ic == ic ) { a->ic = NULL; break; } connections = g_slist_remove( connections, ic ); g_free( ic ); } static void serv_got_crap( struct im_connection *ic, char *format, ... ) { va_list params; char *text; account_t *a; va_start( params, format ); text = g_strdup_vprintf( format, params ); va_end( params ); if( ( g_strcasecmp( set_getstr( &ic->irc->set, "strip_html" ), "always" ) == 0 ) || ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) ) strip_html( text ); /* Try to find a different connection on the same protocol. */ for( a = ic->irc->accounts; a; a = a->next ) if( a->prpl == ic->acc->prpl && a->ic != ic ) break; /* If we found one, include the screenname in the message. */ if( a ) irc_usermsg( ic->irc, "%s(%s) - %s", ic->acc->prpl->name, ic->acc->user, text ); else irc_usermsg( ic->irc, "%s - %s", ic->acc->prpl->name, text ); g_free( text ); } void imcb_log( struct im_connection *ic, char *format, ... ) { va_list params; char *text; va_start( params, format ); text = g_strdup_vprintf( format, params ); va_end( params ); if( ic->flags & OPT_LOGGED_IN ) serv_got_crap( ic, "%s", text ); else serv_got_crap( ic, "Logging in: %s", text ); g_free( text ); } void imcb_error( struct im_connection *ic, char *format, ... ) { va_list params; char *text; va_start( params, format ); text = g_strdup_vprintf( format, params ); va_end( params ); if( ic->flags & OPT_LOGGED_IN ) serv_got_crap( ic, "Error: %s", text ); else serv_got_crap( ic, "Couldn't log in: %s", text ); g_free( text ); } static gboolean send_keepalive( gpointer d, gint fd, b_input_condition cond ) { struct im_connection *ic = d; if( ic->acc->prpl->keepalive ) ic->acc->prpl->keepalive( ic ); return TRUE; } void imcb_connected( struct im_connection *ic ) { user_t *u; /* MSN servers sometimes redirect you to a different server and do the whole login sequence again, so these "late" calls to this function should be handled correctly. (IOW, ignored) */ if( ic->flags & OPT_LOGGED_IN ) return; u = user_find( ic->irc, ic->irc->nick ); imcb_log( ic, "Logged in" ); ic->keepalive = b_timeout_add( 60000, send_keepalive, ic ); ic->flags |= OPT_LOGGED_IN; /* Also necessary when we're not away, at least for some of the protocols. */ imc_set_away( ic, u->away ); } gboolean auto_reconnect( gpointer data, gint fd, b_input_condition cond ) { account_t *a = data; a->reconnect = 0; account_on( a->irc, a ); return( FALSE ); /* Only have to run the timeout once */ } void cancel_auto_reconnect( account_t *a ) { b_event_remove( a->reconnect ); a->reconnect = 0; } void imc_logout( struct im_connection *ic, int allow_reconnect ) { irc_t *irc = ic->irc; user_t *t, *u; account_t *a; /* Nested calls might happen sometimes, this is probably the best place to catch them. */ if( ic->flags & OPT_LOGGING_OUT ) return; else ic->flags |= OPT_LOGGING_OUT; imcb_log( ic, "Signing off.." ); b_event_remove( ic->keepalive ); ic->keepalive = 0; ic->acc->prpl->logout( ic ); b_event_remove( ic->inpa ); u = irc->users; while( u ) { if( u->ic == ic ) { t = u->next; u
#include <stdlib.h>
#include <glib.h>
#include <gmodule.h>
#include <check.h>
#include <string.h>
#include <stdio.h>
#include "jabber/jabber.h"

static struct im_connection *ic;

static void check_buddy_add(int l)
{
	struct jabber_buddy *budw1, *budw2, *budw3, *budn, *bud;
	
	budw1 = jabber_buddy_add( ic, "wilmer@gaast.net/BitlBee" );
	budw1->last_msg = time( NULL ) - 100;
	budw2 = jabber_buddy_add( ic, "WILMER@gaast.net/Telepathy" );
	budw2->priority = 2;
	budw2->last_msg = time( NULL );
	budw3 = jabber_buddy_add( ic, "wilmer@GAAST.NET/bitlbee" );
	budw3->last_msg = time( NULL ) - 200;
	budw3->priority = 4;
	/* TODO(wilmer): Shouldn't this just return budw3? */
	fail_if( jabber_buddy_add( ic, "wilmer@gaast.net/Telepathy" ) != NULL );
	
	budn = jabber_buddy_add( ic, "nekkid@lamejab.net" );
	/* Shouldn't be allowed if there's already a bare JID. */
	fail_if( jabber_buddy_add( ic, "nekkid@lamejab.net/Illegal" ) );
	
	/* Case sensitivity: Case only matters after the / */
	fail_if( jabber_buddy_by_jid( ic, "wilmer@gaast.net/BitlBee", 0 ) ==
	         jabber_buddy_by_jid( ic, "wilmer@gaast.net/bitlbee", 0 ) );
	fail_if( jabber_buddy_by_jid( ic, "wilmer@gaast.net/telepathy", 0 ) );
	
	fail_unless( jabber_buddy_by_jid( ic, "wilmer@gaast.net/BitlBee", 0 ) == budw1 );
	fail_unless( jabber_buddy_by_jid( ic, "WILMER@GAAST.NET/BitlBee", GET_BUDDY_EXACT ) == budw1 );
	fail_unless( jabber_buddy_by_jid( ic, "wilmer@GAAST.NET/BitlBee", GET_BUDDY_CREAT ) == budw1 );

	fail_if( jabber_buddy_by_jid( ic, "wilmer@gaast.net", GET_BUDDY_EXACT ) );
	fail_unless( jabber_buddy_by_jid( ic, "WILMER@gaast.net", 0 ) == budw3 );

	/* Check O_FIRST and see if it's indeed the first item from the list. */
	fail_unless( ( bud = jabber_buddy_by_jid( ic, "wilmer@gaast.net", GET_BUDDY_FIRST ) ) == budw1 );
	fail_unless( bud->next == budw2 && bud->next->next == budw3 && bud->next->next->next == NULL );
	
	/* Change the resource_select setting, now we should get a different resource. */
	set_setstr( &ic->acc->set, "resource_select", "activity" );
	fail_unless( jabber_buddy_by_jid( ic, "wilmer@GAAST.NET", 0 ) == budw2 );
	
	/* Some testing of bare JID handling (which is horrible). */
	fail_if( jabber_buddy_by_jid( ic, "nekkid@lamejab.net/Illegal", 0 ) );
	fail_if( jabber_buddy_by_jid( <