예제 #1
0
파일: iq.c 프로젝트: shiplu/bitlbee
static xt_status jabber_finish_iq_auth( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
{
	struct jabber_data *jd = ic->proto_data;
	char *type;
	
	if( !( type = xt_find_attr( node, "type" ) ) )
	{
		imcb_log( ic, "Warning: Received incomplete IQ packet while authenticating" );
		imc_logout( ic, FALSE );
		return XT_HANDLED;
	}
	
	if( strcmp( type, "error" ) == 0 )
	{
		imcb_error( ic, "Authentication failure" );
		imc_logout( ic, FALSE );
		return XT_ABORT;
	}
	else if( strcmp( type, "result" ) == 0 )
	{
		/* This happens when we just successfully authenticated the
		   old (non-SASL) way. */
		jd->flags |= JFLAG_AUTHENTICATED;
		if( !jabber_get_roster( ic ) )
			return XT_ABORT;
		if( !jabber_iq_disco_server( ic ) )
			return XT_ABORT;
	}
	
	return XT_HANDLED;
}
예제 #2
0
파일: sasl.c 프로젝트: mrdon/bitlbee
xt_status sasl_pkt_result( struct xt_node *node, gpointer data )
{
	struct im_connection *ic = data;
	struct jabber_data *jd = ic->proto_data;
	char *s;
	
	s = xt_find_attr( node, "xmlns" );
	if( !s || strcmp( s, XMLNS_SASL ) != 0 )
	{
		imcb_log( ic, "Stream error while authenticating" );
		imc_logout( ic, FALSE );
		return XT_ABORT;
	}
	
	if( strcmp( node->name, "success" ) == 0 )
	{
		imcb_log( ic, "Authentication finished" );
		jd->flags |= JFLAG_AUTHENTICATED | JFLAG_STREAM_RESTART;
	}
	else if( strcmp( node->name, "failure" ) == 0 )
	{
		imcb_error( ic, "Authentication failure" );
		imc_logout( ic, FALSE );
		return XT_ABORT;
	}
	
	return XT_HANDLED;
}
예제 #3
0
파일: iq.c 프로젝트: shiplu/bitlbee
static xt_status jabber_do_iq_auth( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
{
	struct jabber_data *jd = ic->proto_data;
	struct xt_node *reply, *query;
	xt_status st;
	char *s;
	
	if( !( query = xt_find_node( node->children, "query" ) ) )
	{
		imcb_log( ic, "Warning: Received incomplete IQ packet while authenticating" );
		imc_logout( ic, FALSE );
		return XT_HANDLED;
	}
	
	/* Time to authenticate ourselves! */
	reply = xt_new_node( "query", NULL, NULL );
	xt_add_attr( reply, "xmlns", XMLNS_AUTH );
	xt_add_child( reply, xt_new_node( "username", jd->username, NULL ) );
	xt_add_child( reply, xt_new_node( "resource", set_getstr( &ic->acc->set, "resource" ), NULL ) );
	
	if( xt_find_node( query->children, "digest" ) && ( s = xt_find_attr( jd->xt->root, "id" ) ) )
	{
		/* We can do digest authentication, it seems, and of
		   course we prefer that. */
		sha1_state_t sha;
		char hash_hex[41];
		unsigned char hash[20];
		int i;
		
		sha1_init( &sha );
		sha1_append( &sha, (unsigned char*) s, strlen( s ) );
		sha1_append( &sha, (unsigned char*) ic->acc->pass, strlen( ic->acc->pass ) );
		sha1_finish( &sha, hash );
		
		for( i = 0; i < 20; i ++ )
			sprintf( hash_hex + i * 2, "%02x", hash[i] );
		
		xt_add_child( reply, xt_new_node( "digest", hash_hex, NULL ) );
	}
	else if( xt_find_node( query->children, "password" ) )
	{
		/* We'll have to stick with plaintext. Let's hope we're using SSL/TLS... */
		xt_add_child( reply, xt_new_node( "password", ic->acc->pass, NULL ) );
	}
	else
	{
		xt_free_node( reply );
		
		imcb_error( ic, "Can't find suitable authentication method" );
		imc_logout( ic, FALSE );
		return XT_ABORT;
	}
	
	reply = jabber_make_packet( "iq", "set", NULL, reply );
	jabber_cache_add( ic, reply, jabber_finish_iq_auth );
	st = jabber_write_packet( ic, reply );
	
	return st ? XT_HANDLED : XT_ABORT;
}
예제 #4
0
/**
 * Callback for getting the friends ids.
 */
static void twitter_http_get_friends_ids(struct http_request *req)
{
    struct im_connection *ic;
    struct xt_parser *parser;
    struct twitter_xml_list *txl;
    struct twitter_data *td;

    ic = req->data;

    // Check if the connection is still active.
    if (!g_slist_find(twitter_connections, ic))
        return;

    td = ic->proto_data;

    // Check if the HTTP request went well. More strict checks as this is
    // the first request we do in a session.
    if (req->status_code == 401) {
        imcb_error(ic, "Authentication failure");
        imc_logout(ic, FALSE);
        return;
    } else if (req->status_code != 200) {
        // It didn't go well, output the error and return.
        imcb_error(ic, "Could not retrieve %s: %s",
                   TWITTER_FRIENDS_IDS_URL, twitter_parse_error(req));
        imc_logout(ic, TRUE);
        return;
    } else {
        td->http_fails = 0;
    }

    /* Create the room now that we "logged in". */
    if (!td->timeline_gc && g_strcasecmp(set_getstr(&ic->acc->set, "mode"), "chat") == 0)
        twitter_groupchat_init(ic);

    txl = g_new0(struct twitter_xml_list, 1);
    txl->list = td->follow_ids;

    // Parse the data.
    parser = xt_new(NULL, txl);
    xt_feed(parser, req->reply_body, req->body_size);
    twitter_xt_get_friends_id_list(parser->root, txl);
    xt_free(parser);

    td->follow_ids = txl->list;
    if (txl->next_cursor)
        /* These were just numbers. Up to 4000 in a response AFAIK so if we get here
           we may be using a spammer account. \o/ */
        twitter_get_friends_ids(ic, txl->next_cursor);
    else
        /* Now to convert all those numbers into names.. */
        twitter_get_users_lookup(ic);

    txl->list = NULL;
    txl_free(txl);
}
예제 #5
0
파일: twitter.c 프로젝트: mrdon/bitlbee
static gboolean twitter_oauth_callback(struct oauth_info *info)
{
	struct im_connection *ic = info->data;
	struct twitter_data *td;

	if (!g_slist_find(twitter_connections, ic))
		return FALSE;

	td = ic->proto_data;
	if (info->stage == OAUTH_REQUEST_TOKEN) {
		char *name, *msg;

		if (info->request_token == NULL) {
			imcb_error(ic, "OAuth error: %s", twitter_parse_error(info->http));
			imc_logout(ic, TRUE);
			return FALSE;
		}

		name = g_strdup_printf("%s_%s", td->prefix, ic->acc->user);
		msg = g_strdup_printf("To finish OAuth authentication, please visit "
				      "%s and respond with the resulting PIN code.",
				      info->auth_url);
		imcb_buddy_msg(ic, name, msg, 0, 0);
		g_free(name);
		g_free(msg);
	} else if (info->stage == OAUTH_ACCESS_TOKEN) {
		const char *sn;
		
		if (info->token == NULL || info->token_secret == NULL) {
			imcb_error(ic, "OAuth error: %s", twitter_parse_error(info->http));
			imc_logout(ic, TRUE);
			return FALSE;
		}
		
		if ((sn = oauth_params_get(&info->params, "screen_name"))) {
			if (ic->acc->prpl->handle_cmp(sn, ic->acc->user) != 0)
				imcb_log(ic, "Warning: You logged in via OAuth as %s "
				         "instead of %s.", sn, ic->acc->user);
			g_free(td->user);
			td->user = g_strdup(sn);
		}

		/* IM mods didn't do this so far and it's ugly but I should
		   be able to get away with it... */
		g_free(ic->acc->pass);
		ic->acc->pass = oauth_to_string(info);

		twitter_login_finish(ic);
	}

	return TRUE;
}
예제 #6
0
파일: twitter.c 프로젝트: mrdon/bitlbee
static int twitter_buddy_msg(struct im_connection *ic, char *who, char *message, int away)
{
	struct twitter_data *td = ic->proto_data;
	int plen = strlen(td->prefix);

	if (g_strncasecmp(who, td->prefix, plen) == 0 && who[plen] == '_' &&
	    g_strcasecmp(who + plen + 1, ic->acc->user) == 0) {
		if (set_getbool(&ic->acc->set, "oauth") &&
		    td->oauth_info && td->oauth_info->token == NULL) {
			char pin[strlen(message) + 1], *s;

			strcpy(pin, message);
			for (s = pin + sizeof(pin) - 2; s > pin && isspace(*s); s--)
				*s = '\0';
			for (s = pin; *s && isspace(*s); s++) {
			}

			if (!oauth_access_token(s, td->oauth_info)) {
				imcb_error(ic, "OAuth error: %s",
					   "Failed to send access token request");
				imc_logout(ic, TRUE);
				return FALSE;
			}
		} else
			twitter_handle_command(ic, message);
	} else {
		twitter_direct_messages_new(ic, who, message);
	}
	return (0);
}
예제 #7
0
static int torchat_write(struct im_connection *ic, char *buf, int len)
{
	struct torchat_data *td = ic->proto_data;
	struct pollfd pfd[1];

	if (!td->ssl)
		return FALSE;

	pfd[0].fd = td->fd;
	pfd[0].events = POLLOUT;

	/* This poll is necessary or we'll get a SIGPIPE when we write() to
	 * td->fd. */
	poll(pfd, 1, 1000);

	if (pfd[0].revents & POLLHUP) {
		imc_logout(ic, TRUE);

		return FALSE;
	}

	ssl_write(td->ssl, buf, len);

	return TRUE;
}
예제 #8
0
파일: msn.c 프로젝트: GRMrGecko/bitlbee
static void msn_login( account_t *acc )
{
	struct im_connection *ic = imcb_new( acc );
	struct msn_data *md = g_new0( struct msn_data, 1 );
	
	ic->proto_data = md;
	ic->flags |= OPT_PONGS | OPT_PONGED;
	
	if( strchr( acc->user, '@' ) == NULL )
	{
		imcb_error( ic, "Invalid account name" );
		imc_logout( ic, FALSE );
		return;
	}
	
	md->ic = ic;
	md->away_state = msn_away_state_list;
	md->domaintree = g_tree_new( msn_domaintree_cmp );
	md->ns->fd = -1;
	
	msn_connections = g_slist_prepend( msn_connections, ic );
	
	imcb_log( ic, "Connecting" );
	msn_ns_connect( ic, md->ns, MSN_NS_HOST, MSN_NS_PORT );
}
예제 #9
0
파일: purple.c 프로젝트: GRMrGecko/bitlbee
static void purple_login( account_t *acc )
{
	struct im_connection *ic = imcb_new( acc );
	PurpleAccount *pa;
	
	if( ( local_bee != NULL && local_bee != acc->bee ) ||
	    ( global.conf->runmode == RUNMODE_DAEMON && !getenv( "BITLBEE_DEBUG" ) ) )
	{
		imcb_error( ic,  "Daemon mode detected. Do *not* try to use libpurple in daemon mode! "
		                 "Please use inetd or ForkDaemon mode instead." );
		imc_logout( ic, FALSE );
		return;
	}
	local_bee = acc->bee;
	
	/* For now this is needed in the _connected() handlers if using
	   GLib event handling, to make sure we're not handling events
	   on dead connections. */
	purple_connections = g_slist_prepend( purple_connections, ic );
	
	ic->proto_data = pa = purple_account_new( acc->user, (char*) acc->prpl->data );
	purple_account_set_password( pa, acc->pass );
	purple_sync_settings( acc, pa );
	
	purple_account_set_enabled( pa, "BitlBee", TRUE );
}
예제 #10
0
파일: sasl.c 프로젝트: mrdon/bitlbee
static void sasl_oauth2_got_token( gpointer data, const char *access_token, const char *refresh_token, const char *error )
{
	struct im_connection *ic = data;
	struct jabber_data *jd;
	GSList *auth = NULL;
	
	if( g_slist_find( jabber_connections, ic ) == NULL )
		return;
	
	jd = ic->proto_data;
	
	if( access_token == NULL )
	{
		imcb_error( ic, "OAuth failure (%s)", error );
		imc_logout( ic, TRUE );
		return;
	}
	
	oauth_params_parse( &auth, ic->acc->pass );
	if( refresh_token )
		oauth_params_set( &auth, "refresh_token", refresh_token );
	if( access_token )
		oauth_params_set( &auth, "access_token", access_token );
	
	g_free( ic->acc->pass );
	ic->acc->pass = oauth_params_string( auth );
	oauth_params_free( &auth );
	
	g_free( jd->oauth2_access_token );
	jd->oauth2_access_token = g_strdup( access_token );
	
	jabber_connect( ic );
}
예제 #11
0
static void purple_login(account_t *acc)
{
	struct im_connection *ic = imcb_new(acc);
	struct purple_data *pd;

	if ((local_bee != NULL && local_bee != acc->bee) ||
	    (global.conf->runmode == RUNMODE_DAEMON && !getenv("BITLBEE_DEBUG"))) {
		imcb_error(ic,  "Daemon mode detected. Do *not* try to use libpurple in daemon mode! "
		           "Please use inetd or ForkDaemon mode instead.");
		imc_logout(ic, FALSE);
		return;
	}
	local_bee = acc->bee;

	/* For now this is needed in the _connected() handlers if using
	   GLib event handling, to make sure we're not handling events
	   on dead connections. */
	purple_connections = g_slist_prepend(purple_connections, ic);

	ic->proto_data = pd = g_new0(struct purple_data, 1);
	pd->account = purple_account_new(acc->user, (char *) acc->prpl->data);
	pd->input_requests = g_hash_table_new_full(g_direct_hash, g_direct_equal,
	                                           NULL, g_free);
	pd->next_request_id = 0;
	purple_account_set_password(pd->account, acc->pass);
	purple_sync_settings(acc, pd->account);

	purple_account_set_enabled(pd->account, "BitlBee", TRUE);

	if (set_getbool(&acc->set, "mail_notifications") && set_getstr(&acc->set, "mail_notifications_handle")) {
		imcb_add_buddy(ic, set_getstr(&acc->set, "mail_notifications_handle"), NULL);
	}
}
예제 #12
0
파일: ns.c 프로젝트: GRMrGecko/bitlbee
int msn_ns_write( struct im_connection *ic, int fd, const char *fmt, ... )
{
	struct msn_data *md = ic->proto_data;
	va_list params;
	char *out;
	size_t len;
	int st;
	
	va_start( params, fmt );
	out = g_strdup_vprintf( fmt, params );
	va_end( params );
	
	if( fd < 0 )
		fd = md->ns->fd;
	
	if( getenv( "BITLBEE_DEBUG" ) )
		fprintf( stderr, "->NS%d:%s\n", fd, out );
	
	len = strlen( out );
	st = write( fd, out, len );
	g_free( out );
	if( st != len )
	{
		imcb_error( ic, "Short write() to main server" );
		imc_logout( ic, TRUE );
		return 0;
	}
	
	return 1;
}
예제 #13
0
파일: bee.c 프로젝트: GRMrGecko/bitlbee
void bee_free( bee_t *b )
{
	while( b->accounts )
	{
		if( b->accounts->ic )
			imc_logout( b->accounts->ic, FALSE );
		else if( b->accounts->reconnect )
			cancel_auto_reconnect( b->accounts );
		
		if( b->accounts->ic == NULL )
			account_del( b, b->accounts );
		else
			/* Nasty hack, but account_del() doesn't work in this
			   case and we don't want infinite loops, do we? ;-) */
			b->accounts = b->accounts->next;
	}
	
	while( b->set )
		set_del( &b->set, b->set->key );
	
	bee_group_free( b );
	
	g_free( b->user );
	g_free( b );
}
예제 #14
0
/**
 * Processes the error of a #SteamApiReq.
 *
 * @param sata   The #SteamData.
 * @param req    The #SteamApiReq.
 * @param logout TRUE to logout, otherwise FALSE.
 *
 * @return TRUE if an error exists, otherwise FALSE.
 **/
static gboolean steam_req_error(SteamData *sata, SteamApiReq *req,
                                gboolean logout)
{
    if (req->err == NULL)
        return FALSE;

    if (g_error_matches(req->err, STEAM_API_ERROR, STEAM_API_ERROR_EXPRIED)) {
        STEAM_UTIL_DEBUGLN("Relogging on due to expired session");
        steam_http_free_reqs(req->api->http);
        req = steam_api_req_new(req->api, steam_cb_relogon, sata);
        steam_api_req_logon(req);
        return TRUE;
    }

    if (g_error_matches(req->err, STEAM_HTTP_ERROR, STEAM_HTTP_ERROR_CLOSED)) {
        STEAM_UTIL_DEBUGLN("Request (%p) forcefully closed", req->req);
        /* Ignore closed HTTP connections */
        return TRUE;
    }

    STEAM_UTIL_DEBUGLN("Error: %s", req->err->message);
    imcb_error(sata->ic, "%s", req->err->message);

    if (logout) {
        STEAM_UTIL_DEBUGLN("Reconnecting due to error");
        imc_logout(sata->ic, logout);
    }

    return TRUE;
}
예제 #15
0
파일: io.c 프로젝트: jianingy/bitlbee-clone
gboolean jabber_connected_ssl( gpointer data, void *source, b_input_condition cond )
{
	struct im_connection *ic = data;
	struct jabber_data *jd;
	
	if( g_slist_find( jabber_connections, ic ) == NULL )
		return FALSE;
	
	jd = ic->proto_data;
	
	if( source == NULL )
	{
		/* The SSL connection will be cleaned up by the SSL lib
		   already, set it to NULL here to prevent a double cleanup: */
		jd->ssl = NULL;
		
		imcb_error( ic, "Could not connect to server" );
		imc_logout( ic, TRUE );
		return FALSE;
	}
	
	imcb_log( ic, "Connected to server, logging in" );
	
	return jabber_start_stream( ic );
}
예제 #16
0
파일: jabber.c 프로젝트: AlD/bitlbee
static int jabber_buddy_msg( struct im_connection *ic, char *who, char *message, int flags )
{
	struct jabber_data *jd = ic->proto_data;
	struct jabber_buddy *bud;
	struct xt_node *node;
	char *s;
	int st;
	
	if( g_strcasecmp( who, JABBER_XMLCONSOLE_HANDLE ) == 0 )
		return jabber_write( ic, message, strlen( message ) );
	
	if( g_strcasecmp( who, JABBER_OAUTH_HANDLE ) == 0 &&
	    !( jd->flags & OPT_LOGGED_IN ) && jd->fd == -1 )
	{
		if( sasl_oauth2_get_refresh_token( ic, message ) )
		{
			return 1;
		}
		else
		{
			imcb_error( ic, "OAuth failure" );
			imc_logout( ic, TRUE );
			return 0;
		}
	}
	
	if( ( s = strchr( who, '=' ) ) && jabber_chat_by_jid( ic, s + 1 ) )
		bud = jabber_buddy_by_ext_jid( ic, who, 0 );
	else
		bud = jabber_buddy_by_jid( ic, who, GET_BUDDY_BARE_OK );
	
	node = xt_new_node( "body", message, NULL );
	node = jabber_make_packet( "message", "chat", bud ? bud->full_jid : who, node );
	
	if( bud && ( jd->flags & JFLAG_WANT_TYPING ) &&
	    ( ( bud->flags & JBFLAG_DOES_XEP85 ) ||
	     !( bud->flags & JBFLAG_PROBED_XEP85 ) ) )
	{
		struct xt_node *act;
		
		/* If the user likes typing notification and if we don't know
		   (and didn't probe before) if this resource supports XEP85,
		   include a probe in this packet now. Also, if we know this
		   buddy does support XEP85, we have to send this <active/>
		   tag to tell that the user stopped typing (well, that's what
		   we guess when s/he pressed Enter...). */
		act = xt_new_node( "active", NULL, NULL );
		xt_add_attr( act, "xmlns", XMLNS_CHATSTATES );
		xt_add_child( node, act );
		
		/* Just make sure we do this only once. */
		bud->flags |= JBFLAG_PROBED_XEP85;
	}
	
	st = jabber_write_packet( ic, node );
	xt_free_node( node );
	
	return st;
}
예제 #17
0
static void prplcb_conn_disconnected(PurpleConnection *gc)
{
	struct im_connection *ic = purple_ic_by_gc(gc);

	if (ic != NULL) {
		imc_logout(ic, !gc->wants_to_die);
	}
}
예제 #18
0
void account_off(bee_t *bee, account_t *a)
{
	imc_logout(a->ic, FALSE);
	a->ic = NULL;
	if (a->reconnect) {
		/* Shouldn't happen */
		cancel_auto_reconnect(a);
	}
}
예제 #19
0
/**
 * Implemented #SteamApiFunc for #steam_api_req_auth().
 *
 * @param req  The #SteamApiReq.
 * @param data The user defined data, which is #SteamData.
 **/
static void steam_cb_auth(SteamApiReq *req, gpointer data)
{
    SteamData *sata = data;
    account_t *acc;
    gchar     *str;

    acc = sata->ic->acc;

    set_setstr(&acc->set, "cgid",   req->api->cgid);
    set_setstr(&acc->set, "esid",   req->api->esid);
    set_setstr(&acc->set, "sessid", req->api->sessid);
    set_setstr(&acc->set, "token",  req->api->token);

    if (steam_req_error(sata, req, FALSE)) {
        if (req->err->domain != STEAM_API_ERROR) {
            imc_logout(sata->ic, FALSE);
            return;
        }

        switch (req->err->code) {
        case STEAM_API_ERROR_CAPTCHA:
            str = steam_api_captcha_url(req->api->cgid);
            imcb_log(sata->ic, "View: %s", str);
            imcb_log(sata->ic, "Run: account %s set captcha <text>", acc->tag);
            g_free(str);
            break;

        case STEAM_API_ERROR_STEAMGUARD:
            imcb_log(sata->ic, "Run: account %s set authcode <code>", acc->tag);
            break;
        }

        imc_logout(sata->ic, FALSE);
        return;
    }

    steam_api_free_auth(req->api);

    imcb_log(sata->ic, "Authentication finished");
    account_off(acc->bee, acc);
    account_on(acc->bee, acc);
}
예제 #20
0
static gboolean account_on_timeout(gpointer d, gint fd, b_input_condition cond)
{
	struct im_connection *ic = d;

	if (!(ic->flags & (OPT_SLOW_LOGIN | OPT_LOGGED_IN))) {
		imcb_error(ic, "Connection timeout");
		imc_logout(ic, TRUE);
	}

	return FALSE;
}
예제 #21
0
static gboolean discord_ws_service_loop(gpointer data, gint fd,
                                        b_input_condition cond)
{
  struct im_connection *ic = data;

  discord_data *dd = ic->proto_data;

  lws_service(dd->lwsctx, 0);

  if (dd->state == WS_CLOSING) {
    imc_logout(ic, TRUE);
  }

  return TRUE;
}
예제 #22
0
파일: ns.c 프로젝트: GRMrGecko/bitlbee
static gboolean msn_ns_callback( gpointer data, gint source, b_input_condition cond )
{
	struct msn_handler_data *handler = data;
	struct im_connection *ic = handler->data;
	
	if( msn_handler( handler ) == -1 ) /* Don't do this on ret == 0, it's already done then. */
	{
		imcb_error( ic, "Error while reading from server" );
		imc_logout( ic, TRUE );
		
		return FALSE;
	}
	else
		return TRUE;
}
예제 #23
0
파일: io.c 프로젝트: jianingy/bitlbee-clone
static xt_status jabber_pkt_stream_error( struct xt_node *node, gpointer data )
{
	struct im_connection *ic = data;
	int allow_reconnect = TRUE;
	struct jabber_error *err;
	
	err = jabber_error_parse( node, XMLNS_STREAM_ERROR );
	
	/* Tssk... */
	if( err->code == NULL )
	{
		imcb_error( ic, "Unknown stream error reported by server" );
		imc_logout( ic, allow_reconnect );
		jabber_error_free( err );
		return XT_ABORT;
	}
	
	/* We know that this is a fatal error. If it's a "conflict" error, we
	   should turn off auto-reconnect to make sure we won't get some nasty
	   infinite loop! */
	if( strcmp( err->code, "conflict" ) == 0 )
	{
		imcb_error( ic, "Account and resource used from a different location" );
		allow_reconnect = FALSE;
	}
	else
	{
		imcb_error( ic, "Stream error: %s%s%s", err->code, err->text ? ": " : "",
		            err->text ? err->text : "" );
	}
	
	jabber_error_free( err );
	imc_logout( ic, allow_reconnect );
	
	return XT_ABORT;
}
예제 #24
0
파일: io.c 프로젝트: jianingy/bitlbee-clone
static gboolean jabber_write_queue( struct im_connection *ic )
{
	struct jabber_data *jd = ic->proto_data;
	int st;
	
	if( jd->ssl )
		st = ssl_write( jd->ssl, jd->txq, jd->tx_len );
	else
		st = write( jd->fd, jd->txq, jd->tx_len );
	
	if( st == jd->tx_len )
	{
		/* We wrote everything, clear the buffer. */
		g_free( jd->txq );
		jd->txq = NULL;
		jd->tx_len = 0;
		
		return TRUE;
	}
	else if( st == 0 || ( st < 0 && !ssl_sockerr_again( jd->ssl ) ) )
	{
		/* Set fd to -1 to make sure we won't write to it anymore. */
		closesocket( jd->fd );	/* Shouldn't be necessary after errors? */
		jd->fd = -1;
		
		imcb_error( ic, "Short write() to server" );
		imc_logout( ic, TRUE );
		return FALSE;
	}
	else if( st > 0 )
	{
		char *s;
		
		s = g_memdup( jd->txq + st, jd->tx_len - st );
		jd->tx_len -= st;
		g_free( jd->txq );
		jd->txq = s;
		
		return TRUE;
	}
	else
	{
		/* Just in case we had EINPROGRESS/EAGAIN: */
		
		return TRUE;
	}
}
예제 #25
0
파일: ns.c 프로젝트: GRMrGecko/bitlbee
static gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond )
{
	struct msn_handler_data *handler = data;
	struct im_connection *ic = handler->data;
	struct msn_data *md;
	
	if( !g_slist_find( msn_connections, ic ) )
		return FALSE;
	
	md = ic->proto_data;
	
	if( source == -1 )
	{
		imcb_error( ic, "Could not connect to server" );
		imc_logout( ic, TRUE );
		return FALSE;
	}
	
	g_free( handler->rxq );
	handler->rxlen = 0;
	handler->rxq = g_new0( char, 1 );
	
	if( md->uuid == NULL )
	{
		struct utsname name;
		sha1_state_t sha[1];
		
		/* UUID == SHA1("BitlBee" + my hostname + MSN username) */
		sha1_init( sha );
		sha1_append( sha, (void*) "BitlBee", 7 );
		if( uname( &name ) == 0 )
		{
			sha1_append( sha, (void*) name.nodename, strlen( name.nodename ) );
		}
		sha1_append( sha, (void*) ic->acc->user, strlen( ic->acc->user ) );
		md->uuid = sha1_random_uuid( sha );
		memcpy( md->uuid, "b171be3e", 8 ); /* :-P */
	}
	
	if( msn_ns_write( ic, source, "VER %d %s CVR0\r\n", ++md->trId, MSNP_VER ) )
	{
		handler->inpa = b_input_add( handler->fd, B_EV_IO_READ, msn_ns_callback, handler );
		imcb_log( ic, "Connected to server, waiting for reply" );
	}
	
	return FALSE;
}
예제 #26
0
/**
 * Callback for getting (twitter)friends...
 *
 * Be afraid, be very afraid! This function will potentially add hundreds of "friends". "Who has
 * hundreds of friends?" you wonder? You probably not, since you are reading the source of
 * BitlBee... Get a life and meet new people!
 */
static void twitter_http_get_users_lookup(struct http_request *req)
{
    struct im_connection *ic = req->data;
    struct twitter_data *td;
    struct xt_parser *parser;
    struct twitter_xml_list *txl;
    GSList *l = NULL;
    struct twitter_xml_user *user;

    // Check if the connection is still active.
    if (!g_slist_find(twitter_connections, ic))
        return;

    td = ic->proto_data;

    if (req->status_code != 200) {
        // It didn't go well, output the error and return.
        imcb_error(ic, "Could not retrieve %s: %s",
                   TWITTER_USERS_LOOKUP_URL, twitter_parse_error(req));
        imc_logout(ic, TRUE);
        return;
    } else {
        td->http_fails = 0;
    }

    txl = g_new0(struct twitter_xml_list, 1);
    txl->list = NULL;

    // Parse the data.
    parser = xt_new(NULL, txl);
    xt_feed(parser, req->reply_body, req->body_size);

    // Get the user list from the parsed xml feed.
    twitter_xt_get_users(parser->root, txl);
    xt_free(parser);

    // Add the users as buddies.
    for (l = txl->list; l; l = g_slist_next(l)) {
        user = l->data;
        twitter_add_buddy(ic, user->screen_name, user->name);
    }

    // Free the structure.
    txl_free(txl);

    twitter_get_users_lookup(ic);
}
예제 #27
0
파일: skype.c 프로젝트: meh/killerbee-skype
gboolean
Skype_connected (gpointer data, void* source, b_input_condition condition)
{
    im_connection* connection = data;
    SkypeData*     skype      = connection->proto_data;

    if (source == NULL) {
        skype->ssl = NULL;
        imcb_error(connection, "Could not connect to server");
        imc_logout(connection, TRUE);

        return FALSE;
    }

    imcb_log(connection, "Connected to server, logging in");

    return Skype_begin(connection);
}
예제 #28
0
파일: ns.c 프로젝트: GRMrGecko/bitlbee
gboolean msn_ns_connect( struct im_connection *ic, struct msn_handler_data *handler, const char *host, int port )
{
	if( handler->fd >= 0 )
		closesocket( handler->fd );
	
	handler->exec_command = msn_ns_command;
	handler->exec_message = msn_ns_message;
	handler->data = ic;
	handler->fd = proxy_connect( host, port, msn_ns_connected, handler );
	if( handler->fd < 0 )
	{
		imcb_error( ic, "Could not connect to server" );
		imc_logout( ic, TRUE );
		return FALSE;
	}
	
	return TRUE;
}
예제 #29
0
파일: io.c 프로젝트: jianingy/bitlbee-clone
gboolean jabber_connected_plain( gpointer data, gint source, b_input_condition cond )
{
	struct im_connection *ic = data;
	
	if( g_slist_find( jabber_connections, ic ) == NULL )
		return FALSE;
	
	if( source == -1 )
	{
		imcb_error( ic, "Could not connect to server" );
		imc_logout( ic, TRUE );
		return FALSE;
	}
	
	imcb_log( ic, "Connected to server, logging in" );
	
	return jabber_start_stream( ic );
}
예제 #30
0
파일: skype.c 프로젝트: meh/killerbee-skype
gboolean
Skype_loop (gpointer data, gint fd, b_input_condition condition)
{
    im_connection* connection = data;
    SkypeData*     skype      = connection->proto_data;
    char           buffer[IRC_LINE_SIZE];

    if (ssl_read(skype->ssl, buffer, sizeof(buffer)) <= 0 && !sockerr_again()) {
        closesocket(skype->fd);
        skype->fd = -1;

        imcb_error(connection, "Error while reading from server");
        imc_logout(connection, TRUE);

        return FALSE;
    }

    return TRUE;
}