static void bonjour_bytestreams_connect(PurpleXfer *xfer) { PurpleBuddy *pb; PurpleAccount *account = NULL; XepXfer *xf; char dstaddr[41]; const gchar *name = NULL; unsigned char hashval[20]; char *p; int i; if(xfer == NULL) return; purple_debug_info("bonjour", "bonjour-bytestreams-connect.\n"); xf = (XepXfer*)xfer->data; if(!xf) return; pb = xf->pb; name = purple_buddy_get_name(pb); account = purple_buddy_get_account(pb); p = g_strdup_printf("%s%s%s", xf->sid, name, bonjour_get_jid(account)); purple_cipher_digest_region("sha1", (guchar *)p, strlen(p), sizeof(hashval), hashval, NULL); g_free(p); memset(dstaddr, 0, 41); p = dstaddr; for(i = 0; i < 20; i++, p += 2) snprintf(p, 3, "%02x", hashval[i]); xf->proxy_info = purple_proxy_info_new(); purple_proxy_info_set_type(xf->proxy_info, PURPLE_PROXY_SOCKS5); purple_proxy_info_set_host(xf->proxy_info, xf->proxy_host); purple_proxy_info_set_port(xf->proxy_info, xf->proxy_port); xf->proxy_connection = purple_proxy_connect_socks5_account( purple_account_get_connection(account), account, xf->proxy_info, dstaddr, 0, bonjour_bytestreams_connect_cb, xfer); if(xf->proxy_connection == NULL) { xep_ft_si_reject(xf->data, xf->iq_id, xfer->who, "404", "cancel"); /* Cancel the connection */ purple_xfer_cancel_local(xfer); } }
void purple_initmodule() { struct prpl funcs; GList *prots; GString *help; char *dir; if( B_EV_IO_READ != PURPLE_INPUT_READ || B_EV_IO_WRITE != PURPLE_INPUT_WRITE ) { /* FIXME FIXME FIXME FIXME FIXME :-) */ exit( 1 ); } dir = g_strdup_printf( "%s/purple", global.conf->configdir ); purple_util_set_user_dir( dir ); g_free( dir ); purple_debug_set_enabled( FALSE ); purple_core_set_ui_ops( &bee_core_uiops ); purple_eventloop_set_ui_ops( &glib_eventloops ); if( !purple_core_init( "BitlBee") ) { /* Initializing the core failed. Terminate. */ fprintf( stderr, "libpurple initialization failed.\n" ); abort(); } if( proxytype != PROXY_NONE ) { PurpleProxyInfo *pi = purple_global_proxy_get_info(); switch( proxytype ) { case PROXY_SOCKS4: purple_proxy_info_set_type( pi, PURPLE_PROXY_SOCKS4 ); break; case PROXY_SOCKS5: purple_proxy_info_set_type( pi, PURPLE_PROXY_SOCKS5 ); break; case PROXY_HTTP: purple_proxy_info_set_type( pi, PURPLE_PROXY_HTTP ); break; } purple_proxy_info_set_host( pi, proxyhost ); purple_proxy_info_set_port( pi, proxyport ); purple_proxy_info_set_username( pi, proxyuser ); purple_proxy_info_set_password( pi, proxypass ); } purple_set_blist( purple_blist_new() ); /* No, really. So far there were ui_ops for everything, but now suddenly one needs to use signals for typing notification stuff. :-( */ purple_signal_connect( purple_conversations_get_handle(), "buddy-typing", &funcs, PURPLE_CALLBACK(prplcb_buddy_typing), NULL ); purple_signal_connect( purple_conversations_get_handle(), "buddy-typed", &funcs, PURPLE_CALLBACK(prplcb_buddy_typing), NULL ); purple_signal_connect( purple_conversations_get_handle(), "buddy-typing-stopped", &funcs, PURPLE_CALLBACK(prplcb_buddy_typing), NULL ); memset( &funcs, 0, sizeof( funcs ) ); funcs.login = purple_login; funcs.init = purple_init; funcs.logout = purple_logout; funcs.buddy_msg = purple_buddy_msg; funcs.away_states = purple_away_states; funcs.set_away = purple_set_away; funcs.add_buddy = purple_add_buddy; funcs.remove_buddy = purple_remove_buddy; funcs.add_permit = purple_add_permit; funcs.add_deny = purple_add_deny; funcs.rem_permit = purple_rem_permit; funcs.rem_deny = purple_rem_deny; funcs.get_info = purple_get_info; funcs.keepalive = purple_keepalive; funcs.send_typing = purple_send_typing; funcs.handle_cmp = g_strcasecmp; /* TODO(wilmer): Set these only for protocols that support them? */ funcs.chat_msg = purple_chat_msg; funcs.chat_with = purple_chat_with; funcs.chat_invite = purple_chat_invite; funcs.chat_leave = purple_chat_leave; funcs.chat_join = purple_chat_join; funcs.transfer_request = purple_transfer_request; help = g_string_new( "BitlBee libpurple module supports the following IM protocols:\n" ); /* Add a protocol entry to BitlBee's structures for every protocol supported by this libpurple instance. */ for( prots = purple_plugins_get_protocols(); prots; prots = prots->next ) { PurplePlugin *prot = prots->data; struct prpl *ret; /* If we already have this one (as a native module), don't add a libpurple duplicate. */ if( find_protocol( prot->info->id ) ) continue; ret = g_memdup( &funcs, sizeof( funcs ) ); ret->name = ret->data = prot->info->id; if( strncmp( ret->name, "prpl-", 5 ) == 0 ) ret->name += 5; register_protocol( ret ); g_string_append_printf( help, "\n* %s (%s)", ret->name, prot->info->name ); /* libpurple doesn't define a protocol called OSCAR, but we need it to be compatible with normal BitlBee. */ if( g_strcasecmp( prot->info->id, "prpl-aim" ) == 0 ) { ret = g_memdup( &funcs, sizeof( funcs ) ); ret->name = "oscar"; ret->data = prot->info->id; register_protocol( ret ); } } g_string_append( help, "\n\nFor used protocols, more information about available " "settings can be found using \x02help purple <protocol name>\x02 " "(create an account using that protocol first!)" ); /* Add a simple dynamically-generated help item listing all the supported protocols. */ help_add_mem( &global.help, "purple", help->str ); g_string_free( help, TRUE ); }