コード例 #1
0
ファイル: steam.c プロジェクト: bitlbee/bitlbee-steam
static void
steam_cb_user_search(SteamApiReq *req, gpointer data)
{
    const gchar *tag;
    gchar sid[STEAM_ID_STRMAX];
    GList *l;
    guint i;
    SteamData *sata = data;
    SteamUserInfo *info;

    if (steam_req_error(sata, req, TRUE)) {
        return;
    }

    for (l = req->infs->head, i = 0; (l != NULL) && (i < 2); l = l->next, i++);

    switch (i) {
    case 0:
        imcb_error(sata->ic, "Failed to find any friend(s)");
        return;

    case 1:
        info = req->infs->head->data;
        req = steam_api_req_new(req->api, steam_cb_user_action, sata);
        steam_api_req_user_add(req, info->id);
        return;
    }

    imcb_log(sata->ic, "Select from one of the following Steam Friends:");
    tag = sata->ic->acc->tag;

    for (l = req->infs->head, i = 1; l != NULL; l = l->next, i++) {
        info = l->data;
        STEAM_ID_STR(info->id, sid);

        imcb_log(sata->ic, "%u. `%s' %s", i, info->nick, info->profile);
        imcb_log(sata->ic, "-- add %s steamid:%s", tag, sid);
    }
}
コード例 #2
0
ファイル: steam.c プロジェクト: roughnecks/bitlbee-steam
/**
 * Implemented #SteamApiFunc for #steam_api_req_logon().
 *
 * @param req  The #SteamApiReq.
 * @param data The user defined data, which is #SteamData.
 **/
static void steam_cb_logon(SteamApiReq *req, gpointer data)
{
    SteamData *sata = data;

    if (steam_req_error(sata, req, TRUE))
        return;

    set_setstr(&sata->ic->acc->set, "umqid", req->api->umqid);
    imcb_log(sata->ic, "Requesting friends list");

    req = steam_api_req_new(req->api, steam_cb_friends, sata);
    steam_api_req_friends(req);
}
コード例 #3
0
ファイル: purple.c プロジェクト: GRMrGecko/bitlbee
static void *prplcb_notify_userinfo( PurpleConnection *gc, const char *who, PurpleNotifyUserInfo *user_info )
{
	struct im_connection *ic = purple_ic_by_gc( gc );
	GString *info = g_string_new( "" );
	GList *l = purple_notify_user_info_get_entries( user_info );
	char *key;
	const char *value;
	int n;
	
	while( l )
	{
		PurpleNotifyUserInfoEntry *e = l->data;
		
		switch( purple_notify_user_info_entry_get_type( e ) )
		{
		case PURPLE_NOTIFY_USER_INFO_ENTRY_PAIR:
		case PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER:
			key = g_strdup( purple_notify_user_info_entry_get_label( e ) );
			value = purple_notify_user_info_entry_get_value( e );
			
			if( key )
			{
				strip_html( key );
				g_string_append_printf( info, "%s: ", key );
				
				if( value )
				{
					n = strlen( value ) - 1;
					while( isspace( value[n] ) )
						n --;
					g_string_append_len( info, value, n + 1 );
				}
				g_string_append_c( info, '\n' );
				g_free( key );
			}
			
			break;
		case PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK:
			g_string_append( info, "------------------------\n" );
			break;
		}
		
		l = l->next;
	}
	
	imcb_log( ic, "User %s info:\n%s", who, info->str );
	g_string_free( info, TRUE );
	
	return NULL;
}
コード例 #4
0
ファイル: twitter.c プロジェクト: mrdon/bitlbee
void twitter_login_finish(struct im_connection *ic)
{
	struct twitter_data *td = ic->proto_data;

	td->flags &= ~TWITTER_DOING_TIMELINE;

	if (set_getbool(&ic->acc->set, "oauth") && !td->oauth_info)
		twitter_oauth_start(ic);
	else if (!(td->flags & TWITTER_MODE_ONE) &&
	         !(td->flags & TWITTER_HAVE_FRIENDS)) {
		imcb_log(ic, "Getting contact list");
		twitter_get_friends_ids(ic, -1);
	} else
		twitter_main_loop_start(ic);
}
コード例 #5
0
ファイル: iq.c プロジェクト: shiplu/bitlbee
int jabber_get_roster( struct im_connection *ic )
{
	struct xt_node *node;
	int st;
	
	imcb_log( ic, "Authenticated, requesting buddy list" );
	
	node = xt_new_node( "query", NULL, NULL );
	xt_add_attr( node, "xmlns", XMLNS_ROSTER );
	node = jabber_make_packet( "iq", "get", NULL, node );
	
	jabber_cache_add( ic, node, jabber_parse_roster );
	st = jabber_write_packet( ic, node );
	
	return st;
}
コード例 #6
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;
}
コード例 #7
0
ファイル: bee_user.c プロジェクト: Songzhongrang/reposity
/* IM->UI callbacks */
void imcb_buddy_status(struct im_connection *ic, const char *handle, int flags, const char *state, const char *message)
{
	bee_t *bee = ic->bee;
	bee_user_t *bu, *old;

	if (!(bu = bee_user_by_handle(bee, ic, handle))) {
		if (g_strcasecmp(set_getstr(&ic->bee->set, "handle_unknown"), "add") == 0) {
			bu = bee_user_new(bee, ic, handle, BEE_USER_LOCAL);
		} else {
			if (g_strcasecmp(set_getstr(&ic->bee->set, "handle_unknown"), "ignore") != 0) {
				imcb_log(ic, "imcb_buddy_status() for unknown handle %s:\n"
				         "flags = %d, state = %s, message = %s", handle, flags,
				         state ? state : "NULL", message ? message : "NULL");
			}

			return;
		}
	}

	/* May be nice to give the UI something to compare against. */
	old = g_memdup(bu, sizeof(bee_user_t));

	/* TODO(wilmer): OPT_AWAY, or just state == NULL ? */
	bu->flags = flags;
	bu->status_msg = g_strdup(message);
	if (state && *state) {
		bu->status = g_strdup(state);
	} else if (flags & OPT_AWAY) {
		bu->status = g_strdup("Away");
	} else {
		bu->status = NULL;
	}

	if (bu->status == NULL && (flags & OPT_MOBILE) &&
	    set_getbool(&bee->set, "mobile_is_away")) {
		bu->flags |= BEE_USER_AWAY;
		bu->status = g_strdup("Mobile");
	}

	if (bee->ui->user_status) {
		bee->ui->user_status(bee, bu, old);
	}

	g_free(old->status_msg);
	g_free(old->status);
	g_free(old);
}
コード例 #8
0
ファイル: msn.c プロジェクト: GRMrGecko/bitlbee
static char *set_eval_display_name( set_t *set, char *value )
{
	account_t *acc = set->data;
	struct im_connection *ic = acc->ic;
	struct msn_data *md = ic->proto_data;
	
	if( md->flags & MSN_EMAIL_UNVERIFIED )
		imcb_log( ic, "Warning: Your e-mail address is unverified. MSN doesn't allow "
		              "changing your display name until your e-mail address is verified." );
	
	if( md->flags & MSN_GOT_PROFILE_DN )
		msn_soap_profile_set_dn( ic, value );
	else
		msn_soap_addressbook_set_display_name( ic, value );
	
	return msn_ns_set_display_name( ic, value ) ? value : NULL;
}
コード例 #9
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);
}
コード例 #10
0
ファイル: sasl.c プロジェクト: mrdon/bitlbee
void sasl_oauth2_init( struct im_connection *ic )
{
	struct jabber_data *jd = ic->proto_data;
	char *msg, *url;
	
	imcb_log( ic, "Starting OAuth authentication" );
	
	/* Temporary contact, just used to receive the OAuth response. */
	imcb_add_buddy( ic, JABBER_OAUTH_HANDLE, NULL );
	url = oauth2_url( jd->oauth2_service );
	msg = g_strdup_printf( "Open this URL in your browser to authenticate: %s", url );
	imcb_buddy_msg( ic, JABBER_OAUTH_HANDLE, msg, 0, 0 );
	imcb_buddy_msg( ic, JABBER_OAUTH_HANDLE, "Respond to this message with the returned "
	                                         "authorization token.", 0, 0 );
	
	g_free( msg );
	g_free( url );
}
コード例 #11
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 );
}
コード例 #12
0
ファイル: iq.c プロジェクト: shiplu/bitlbee
static xt_status jabber_parse_roster( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
{
	struct xt_node *query, *c;
	int initial = ( orig != NULL );
	
	if( !( query = xt_find_node( node->children, "query" ) ) )
	{
		imcb_log( ic, "Warning: Received NULL roster packet" );
		return XT_HANDLED;
	}
	
	c = query->children;
	while( ( c = xt_find_node( c, "item" ) ) )
	{
		struct xt_node *group = xt_find_node( c->children, "group" );
		char *jid = xt_find_attr( c, "jid" );
		char *name = xt_find_attr( c, "name" );
		char *sub = xt_find_attr( c, "subscription" );
		
		if( jid && sub )
		{
			if( ( strcmp( sub, "both" ) == 0 || strcmp( sub, "to" ) == 0 ) )
			{
				imcb_add_buddy( ic, jid, ( group && group->text_len ) ?
				                           group->text : NULL );
				
				if( name )
					imcb_rename_buddy( ic, jid, name );
			}
			else if( strcmp( sub, "remove" ) == 0 )
			{
				jabber_buddy_remove_bare( ic, jid );
				imcb_remove_buddy( ic, jid, NULL );
			}
		}
		
		c = c->next;
	}
	
	if( initial )
		imcb_connected( ic );
	
	return XT_HANDLED;
}
コード例 #13
0
ファイル: iq.c プロジェクト: shiplu/bitlbee
xt_status jabber_iq_query_server( struct im_connection *ic, char *jid, char *xmlns )
{
	struct xt_node *node, *query;
	struct jabber_data *jd = ic->proto_data;
	
	node = xt_new_node( "query", NULL, NULL );
	xt_add_attr( node, "xmlns", xmlns );
	
	if( !( query = jabber_make_packet( "iq", "get", jid, node ) ) )
	{
		imcb_log( ic, "WARNING: Couldn't generate server query" );
		xt_free_node( node );
	}

	jd->have_streamhosts--;
	jabber_cache_add( ic, query, jabber_iq_parse_server_features );

	return jabber_write_packet( ic, query ) ? XT_HANDLED : XT_ABORT;
}
コード例 #14
0
ファイル: steam.c プロジェクト: dequis/bitlbee-steam
/**
 * Implemented #SteamApiFunc for #steam_api_req_key().
 *
 * @param req  The #SteamApiReq.
 * @param data The user defined data, which is #SteamData.
 **/
static void steam_cb_key(SteamApiReq *req, gpointer data)
{
    SteamData *sata = data;
    account_t *acc;
    gchar     *ac;
    gchar     *cc;

    if (steam_req_error(sata, req, TRUE))
        return;

    acc = sata->ic->acc;
    ac  = set_getstr(&acc->set, "authcode");
    cc  = set_getstr(&acc->set, "captcha");

    imcb_log(sata->ic, "Requesting authentication token");

    req = steam_api_req_new(req->api, steam_cb_auth, sata);
    steam_api_req_auth(req, acc->user, acc->pass, ac, cc);
}
コード例 #15
0
ファイル: sasl.c プロジェクト: mrdon/bitlbee
int sasl_oauth2_get_refresh_token( struct im_connection *ic, const char *msg )
{
	struct jabber_data *jd = ic->proto_data;
	char *code;
	int ret;
	
	imcb_log( ic, "Requesting OAuth access token" );
	
	/* Don't do it here because the caller may get confused if the contact
	   we're currently sending a message to is deleted. */
	b_timeout_add( 1, sasl_oauth2_remove_contact, ic );
	
	code = g_strdup( msg );
	g_strstrip( code );
	ret = oauth2_access_token( jd->oauth2_service, OAUTH2_AUTH_CODE,
	                           code, sasl_oauth2_got_token, ic );
	
	g_free( code );
	return ret;
}
コード例 #16
0
ファイル: si.c プロジェクト: AaronVanGeffen/bitlbee
/* file_transfer canceled() callback */
void jabber_si_canceled(file_transfer_t *ft, char *reason)
{
	struct jabber_transfer *tf = ft->data;
	struct xt_node *reply, *iqnode;

	if (tf->accepted) {
		return;
	}

	iqnode = jabber_make_packet("iq", "error", tf->ini_jid, NULL);
	xt_add_attr(iqnode, "id", tf->iq_id);
	reply = jabber_make_error_packet(iqnode, "forbidden", "cancel", "403");
	xt_free_node(iqnode);

	if (!jabber_write_packet(tf->ic, reply)) {
		imcb_log(tf->ic, "WARNING: Error generating reply to file transfer request");
	}
	xt_free_node(reply);

}
コード例 #17
0
ファイル: iq.c プロジェクト: shiplu/bitlbee
static xt_status jabber_add_to_roster_callback( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
{
	char *s, *jid = NULL;
	struct xt_node *c;
	
	if( ( c = xt_find_node( orig->children, "query" ) ) &&
	    ( c = xt_find_node( c->children, "item" ) ) &&
	    ( jid = xt_find_attr( c, "jid" ) ) &&
	    ( s = xt_find_attr( node, "type" ) ) &&
	    strcmp( s, "result" ) == 0 )
	{
		if( bee_user_by_handle( ic->bee, ic, jid ) == NULL )
			imcb_add_buddy( ic, jid, NULL );
	}
	else
	{
		imcb_log( ic, "Error while adding `%s' to your contact list.",
		          jid ? jid : "(unknown handle)" );
	}
	
	return XT_HANDLED;
}
コード例 #18
0
ファイル: msn_util.c プロジェクト: chpatrick/BitlSteam
void msn_msgq_purge( struct im_connection *ic, GSList **list )
{
	struct msn_message *m;
	GString *ret;
	GSList *l;
	int n = 0;
	
	l = *list;
	if( l == NULL )
		return;
	
	m = l->data;
	ret = g_string_sized_new( 1024 );
	g_string_printf( ret, "Warning: Cleaning up MSN (switchboard) connection with unsent "
	                      "messages to %s:", m->who ? m->who : "unknown recipient" );
	
	while( l )
	{
		m = l->data;
		
		if( strncmp( m->text, "\r\r\r", 3 ) != 0 )
		{
			g_string_append_printf( ret, "\n%s", m->text );
			n ++;
		}
		
		g_free( m->who );
		g_free( m->text );
		g_free( m );
		
		l = l->next;
	}
	g_slist_free( *list );
	*list = NULL;
	
	if( n > 0 )
		imcb_log( ic, "%s", ret->str );
	g_string_free( ret, TRUE );
}
コード例 #19
0
ファイル: bee_user.c プロジェクト: Songzhongrang/reposity
void imcb_buddy_msg(struct im_connection *ic, const char *handle, const char *msg, uint32_t flags, time_t sent_at)
{
	bee_t *bee = ic->bee;
	bee_user_t *bu;

	bu = bee_user_by_handle(bee, ic, handle);

	if (!bu && !(ic->flags & OPT_LOGGING_OUT)) {
		char *h = set_getstr(&bee->set, "handle_unknown");

		if (g_strcasecmp(h, "ignore") == 0) {
			return;
		} else if (g_strncasecmp(h, "add", 3) == 0) {
			bu = bee_user_new(bee, ic, handle, BEE_USER_LOCAL);
		}
	}

	if (bee->ui->user_msg && bu) {
		bee->ui->user_msg(bee, bu, msg, sent_at);
	} else {
		imcb_log(ic, "Message from unknown handle %s:\n%s", handle, msg);
	}
}
コード例 #20
0
ファイル: sasl.c プロジェクト: mrdon/bitlbee
xt_status sasl_pkt_mechanisms( struct xt_node *node, gpointer data )
{
	struct im_connection *ic = data;
	struct jabber_data *jd = ic->proto_data;
	struct xt_node *c, *reply;
	char *s;
	int sup_plain = 0, sup_digest = 0, sup_gtalk = 0, sup_fb = 0;
	int want_oauth = FALSE;
	GString *mechs;
	
	if( !sasl_supported( ic ) )
	{
		/* Should abort this now, since we should already be doing
		   IQ authentication. Strange things happen when you try
		   to do both... */
		imcb_log( ic, "XMPP 1.0 non-compliant server seems to support SASL, please report this as a BitlBee bug!" );
		return XT_HANDLED;
	}
	
	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;
	}
	
	want_oauth = set_getbool( &ic->acc->set, "oauth" );
	
	mechs = g_string_new( "" );
	c = node->children;
	while( ( c = xt_find_node( c, "mechanism" ) ) )
	{
		if( c->text && g_strcasecmp( c->text, "PLAIN" ) == 0 )
			sup_plain = 1;
		else if( c->text && g_strcasecmp( c->text, "DIGEST-MD5" ) == 0 )
			sup_digest = 1;
		else if( c->text && g_strcasecmp( c->text, "X-OAUTH2" ) == 0 )
			sup_gtalk = 1;
		else if( c->text && g_strcasecmp( c->text, "X-FACEBOOK-PLATFORM" ) == 0 )
			sup_fb = 1;
		
		if( c->text )
			g_string_append_printf( mechs, " %s", c->text );
		
		c = c->next;
	}
	
	if( !want_oauth && !sup_plain && !sup_digest )
	{
		if( !sup_gtalk && !sup_fb )
			imcb_error( ic, "This server requires OAuth "
			                "(supported schemes:%s)", mechs->str );
		else
			imcb_error( ic, "BitlBee does not support any of the offered SASL "
			                "authentication schemes:%s", mechs->str );
		imc_logout( ic, FALSE );
		g_string_free( mechs, TRUE );
		return XT_ABORT;
	}
	g_string_free( mechs, TRUE );
	
	reply = xt_new_node( "auth", NULL, NULL );
	xt_add_attr( reply, "xmlns", XMLNS_SASL );
	
	if( sup_gtalk && want_oauth )
	{
		int len;
		
		/* X-OAUTH2 is, not *the* standard OAuth2 SASL/XMPP implementation.
		   It's currently used by GTalk and vaguely documented on
		   http://code.google.com/apis/cloudprint/docs/rawxmpp.html . */
		xt_add_attr( reply, "mechanism", "X-OAUTH2" );
		
		len = strlen( jd->username ) + strlen( jd->oauth2_access_token ) + 2;
		s = g_malloc( len + 1 );
		s[0] = 0;
		strcpy( s + 1, jd->username );
		strcpy( s + 2 + strlen( jd->username ), jd->oauth2_access_token );
		reply->text = base64_encode( (unsigned char *)s, len );
		reply->text_len = strlen( reply->text );
		g_free( s );
	}
	else if( sup_fb && want_oauth )
	{
		xt_add_attr( reply, "mechanism", "X-FACEBOOK-PLATFORM" );
		jd->flags |= JFLAG_SASL_FB;
	}
	else if( want_oauth )
	{
		imcb_error( ic, "OAuth requested, but not supported by server" );
		imc_logout( ic, FALSE );
		xt_free_node( reply );
		return XT_ABORT;
	}
	else if( sup_digest )
	{
		xt_add_attr( reply, "mechanism", "DIGEST-MD5" );
		
		/* The rest will be done later, when we receive a <challenge/>. */
	}
	else if( sup_plain )
	{
		int len;
		
		xt_add_attr( reply, "mechanism", "PLAIN" );
		
		/* With SASL PLAIN in XMPP, the text should be b64(\0user\0pass) */
		len = strlen( jd->username ) + strlen( ic->acc->pass ) + 2;
		s = g_malloc( len + 1 );
		s[0] = 0;
		strcpy( s + 1, jd->username );
		strcpy( s + 2 + strlen( jd->username ), ic->acc->pass );
		reply->text = base64_encode( (unsigned char *)s, len );
		reply->text_len = strlen( reply->text );
		g_free( s );
	}
	
	if( reply && !jabber_write_packet( ic, reply ) )
	{
		xt_free_node( reply );
		return XT_ABORT;
	}
	xt_free_node( reply );
	
	/* To prevent classic authentication from happening. */
	jd->flags |= JFLAG_STREAM_STARTED;
	
	return XT_HANDLED;
}
コード例 #21
0
ファイル: si.c プロジェクト: AaronVanGeffen/bitlbee
/*
 * First function that gets called when a file transfer request comes in.
 * A lot to parse.
 *
 * We choose a stream type from the options given by the initiator.
 * Then we wait for imcb to call the accept or cancel callbacks.
 */
int jabber_si_handle_request(struct im_connection *ic, struct xt_node *node, struct xt_node *sinode)
{
	struct xt_node *c, *d, *reply;
	char *sid, *ini_jid, *tgt_jid, *iq_id, *s, *ext_jid, *size_s;
	struct jabber_buddy *bud;
	int requestok = FALSE;
	char *name, *cmp;
	size_t size;
	struct jabber_transfer *tf;
	struct jabber_data *jd = ic->proto_data;
	file_transfer_t *ft;

	/* All this means we expect something like this: ( I think )
	 * <iq from=... to=... id=...>
	 *      <si id=id xmlns=si profile=ft>
	 *              <file xmlns=ft/>
	 *              <feature xmlns=feature>
	 *                      <x xmlns=xdata type=submit>
	 *                              <field var=stream-method>
	 *
	 */
	if (!(ini_jid          = xt_find_attr(node, "from")) ||
	    !(tgt_jid          = xt_find_attr(node, "to")) ||
	    !(iq_id            = xt_find_attr(node, "id")) ||
	    !(sid              = xt_find_attr(sinode, "id")) ||
	    !(cmp              = xt_find_attr(sinode, "profile")) ||
	    !(0               == strcmp(cmp, XMLNS_FILETRANSFER)) ||
	    !(d                = xt_find_node(sinode->children, "file")) ||
	    !(cmp = xt_find_attr(d, "xmlns")) ||
	    !(0               == strcmp(cmp, XMLNS_FILETRANSFER)) ||
	    !(name             = xt_find_attr(d, "name")) ||
	    !(size_s           = xt_find_attr(d, "size")) ||
	    !(1               == sscanf(size_s, "%zd", &size)) ||
	    !(d                = xt_find_node(sinode->children, "feature")) ||
	    !(cmp              = xt_find_attr(d, "xmlns")) ||
	    !(0               == strcmp(cmp, XMLNS_FEATURE)) ||
	    !(d                = xt_find_node(d->children, "x")) ||
	    !(cmp              = xt_find_attr(d, "xmlns")) ||
	    !(0               == strcmp(cmp, XMLNS_XDATA)) ||
	    !(cmp              = xt_find_attr(d, "type")) ||
	    !(0               == strcmp(cmp, "form")) ||
	    !(d                = xt_find_node(d->children, "field")) ||
	    !(cmp              = xt_find_attr(d, "var")) ||
	    !(0               == strcmp(cmp, "stream-method"))) {
		imcb_log(ic, "WARNING: Received incomplete Stream Initiation request");
	} else {
		/* Check if we support one of the options */

		c = d->children;
		while ((c = xt_find_node(c, "option"))) {
			if ((d = xt_find_node(c->children, "value")) &&
			    (d->text != NULL) &&
			    (strcmp(d->text, XMLNS_BYTESTREAMS) == 0)) {
				requestok = TRUE;
				break;
			} else {
				c = c->next;
			}
		}

		if (!requestok) {
			imcb_log(ic, "WARNING: Unsupported file transfer request from %s", ini_jid);
		}
	}

	if (requestok) {
		/* Figure out who the transfer should come from... */

		ext_jid = ini_jid;
		if ((s = strchr(ini_jid, '/'))) {
			if ((bud = jabber_buddy_by_jid(ic, ini_jid, GET_BUDDY_EXACT))) {
				bud->last_msg = time(NULL);
				ext_jid = bud->ext_jid ? : bud->bare_jid;
			} else {
				*s = 0; /* We need to generate a bare JID now. */
			}
		}
コード例 #22
0
ファイル: jabber.c プロジェクト: AlD/bitlbee
/* Separate this from jabber_login() so we can do OAuth first if necessary.
   Putting this in io.c would probably be more correct. */
void jabber_connect( struct im_connection *ic )
{
	account_t *acc = ic->acc;
	struct jabber_data *jd = ic->proto_data;
	int i;
	char *connect_to;
	struct ns_srv_reply **srvl = NULL, *srv = NULL;
	
	/* Figure out the hostname to connect to. */
	if( acc->server && *acc->server )
		connect_to = acc->server;
	else if( ( srvl = srv_lookup( "xmpp-client", "tcp", jd->server ) ) ||
	         ( srvl = srv_lookup( "jabber-client", "tcp", jd->server ) ) )
	{
		/* Find the lowest-priority one. These usually come
		   back in random/shuffled order. Not looking at
		   weights etc for now. */
		srv = *srvl;
		for( i = 1; srvl[i]; i ++ )
			if( srvl[i]->prio < srv->prio )
				srv = srvl[i];
		
		connect_to = srv->name;
	}
	else
		connect_to = jd->server;
	
	imcb_log( ic, "Connecting" );
	
	for( i = 0; jabber_port_list[i] > 0; i ++ )
		if( set_getint( &acc->set, "port" ) == jabber_port_list[i] )
			break;

	if( jabber_port_list[i] == 0 )
	{
		imcb_log( ic, "Illegal port number" );
		imc_logout( ic, FALSE );
		return;
	}
	
	/* For non-SSL connections we can try to use the port # from the SRV
	   reply, but let's not do that when using SSL, SSL usually runs on
	   non-standard ports... */
	if( set_getbool( &acc->set, "ssl" ) )
	{
		jd->ssl = ssl_connect( connect_to, set_getint( &acc->set, "port" ), FALSE, jabber_connected_ssl, ic );
		jd->fd = jd->ssl ? ssl_getfd( jd->ssl ) : -1;
	}
	else
	{
		jd->fd = proxy_connect( connect_to, srv ? srv->port : set_getint( &acc->set, "port" ), jabber_connected_plain, ic );
	}
	srv_free( srvl );
	
	if( jd->fd == -1 )
	{
		imcb_error( ic, "Could not connect to server" );
		imc_logout( ic, TRUE );
		
		return;
	}
	
	if( set_getbool( &acc->set, "xmlconsole" ) )
	{
		jd->flags |= JFLAG_XMLCONSOLE;
		/* Shouldn't really do this at this stage already, maybe. But
		   I think this shouldn't break anything. */
		imcb_add_buddy( ic, JABBER_XMLCONSOLE_HANDLE, NULL );
	}
	
	jabber_generate_id_hash( jd );
}
コード例 #23
0
ファイル: skype.c プロジェクト: GRMrGecko/bitlbee
static void skype_parse_user(struct im_connection *ic, char *line)
{
	int flags = 0;
	char *ptr;
	struct skype_data *sd = ic->proto_data;
	char *user = strchr(line, ' ');
	char *status = strrchr(line, ' ');

	status++;
	ptr = strchr(++user, ' ');
	if (!ptr)
		return;
	*ptr = '\0';
	ptr++;
	if (!strncmp(ptr, "ONLINESTATUS ", 13)) {
		if (!strlen(user) || !strcmp(user, sd->username))
			return;
		if (!set_getbool(&ic->acc->set, "test_join")
				&& !strcmp(user, "echo123"))
			return;
		ptr = g_strdup_printf("*****@*****.**", user);
		imcb_add_buddy(ic, ptr, skype_group_by_username(ic, user));
		if (strcmp(status, "OFFLINE") && (strcmp(status, "SKYPEOUT") ||
			!set_getbool(&ic->acc->set, "skypeout_offline")))
			flags |= OPT_LOGGED_IN;
		if (strcmp(status, "ONLINE") && strcmp(status, "SKYPEME"))
			flags |= OPT_AWAY;
		imcb_buddy_status(ic, ptr, flags, NULL, NULL);
		g_free(ptr);
	} else if (!strncmp(ptr, "RECEIVEDAUTHREQUEST ", 20)) {
		char *message = ptr + 20;
		if (strlen(message))
			skype_buddy_ask(ic, user, message);
	} else if (!strncmp(ptr, "BUDDYSTATUS ", 12)) {
		char *st = ptr + 12;
		if (!strcmp(st, "3")) {
			char *buf = g_strdup_printf("*****@*****.**", user);
			imcb_add_buddy(ic, buf, skype_group_by_username(ic, user));
			g_free(buf);
		}
	} else if (!strncmp(ptr, "MOOD_TEXT ", 10)) {
		char *buf = g_strdup_printf("*****@*****.**", user);
		bee_user_t *bu = bee_user_by_handle(ic->bee, ic, buf);
		g_free(buf);
		buf = ptr + 10;
		if (bu)
			imcb_buddy_status(ic, bu->handle, bu->flags, NULL,
					*buf ? buf : NULL);
		if (set_getbool(&ic->acc->set, "show_moods"))
			imcb_log(ic, "User `%s' changed mood text to `%s'", user, buf);
	} else if (!strncmp(ptr, "FULLNAME ", 9)) {
		char *name = ptr + 9;
		if (sd->is_info) {
			sd->is_info = FALSE;
			sd->info_fullname = g_strdup(name);
		} else {
			char *buf = g_strdup_printf("*****@*****.**", user);
			imcb_rename_buddy(ic, buf, name);
			g_free(buf);
		}
	} else if (!strncmp(ptr, "PHONE_HOME ", 11))
		sd->info_phonehome = g_strdup(ptr + 11);
	else if (!strncmp(ptr, "PHONE_OFFICE ", 13))
		sd->info_phoneoffice = g_strdup(ptr + 13);
	else if (!strncmp(ptr, "PHONE_MOBILE ", 13))
		sd->info_phonemobile = g_strdup(ptr + 13);
	else if (!strncmp(ptr, "NROF_AUTHED_BUDDIES ", 20))
		sd->info_nrbuddies = g_strdup(ptr + 20);
	else if (!strncmp(ptr, "TIMEZONE ", 9))
		sd->info_tz = g_strdup(ptr + 9);
	else if (!strncmp(ptr, "LASTONLINETIMESTAMP ", 20))
		sd->info_seen = g_strdup(ptr + 20);
	else if (!strncmp(ptr, "SEX ", 4))
		sd->info_sex = g_strdup(ptr + 4);
	else if (!strncmp(ptr, "LANGUAGE ", 9))
		sd->info_language = g_strdup(ptr + 9);
	else if (!strncmp(ptr, "COUNTRY ", 8))
		sd->info_country = g_strdup(ptr + 8);
	else if (!strncmp(ptr, "PROVINCE ", 9))
		sd->info_province = g_strdup(ptr + 9);
	else if (!strncmp(ptr, "CITY ", 5))
		sd->info_city = g_strdup(ptr + 5);
	else if (!strncmp(ptr, "HOMEPAGE ", 9))
		sd->info_homepage = g_strdup(ptr + 9);
	else if (!strncmp(ptr, "ABOUT ", 6)) {
		/* Support multiple about lines. */
		if (!sd->info_about)
			sd->info_about = g_strdup(ptr + 6);
		else {
			GString *st = g_string_new(sd->info_about);
			g_string_append_printf(st, "\n%s", ptr + 6);
			g_free(sd->info_about);
			sd->info_about = g_strdup(st->str);
			g_string_free(st, TRUE);
		}
	} else if (!strncmp(ptr, "BIRTHDAY ", 9)) {
		sd->info_birthday = g_strdup(ptr + 9);

		GString *st = g_string_new("Contact Information\n");
		g_string_append_printf(st, "Skype Name: %s\n", user);
		if (sd->info_fullname) {
			if (strlen(sd->info_fullname))
				g_string_append_printf(st, "Full Name: %s\n",
					sd->info_fullname);
			g_free(sd->info_fullname);
			sd->info_fullname = NULL;
		}
		if (sd->info_phonehome) {
			if (strlen(sd->info_phonehome))
				g_string_append_printf(st, "Home Phone: %s\n",
					sd->info_phonehome);
			g_free(sd->info_phonehome);
			sd->info_phonehome = NULL;
		}
		if (sd->info_phoneoffice) {
			if (strlen(sd->info_phoneoffice))
				g_string_append_printf(st, "Office Phone: %s\n",
					sd->info_phoneoffice);
			g_free(sd->info_phoneoffice);
			sd->info_phoneoffice = NULL;
		}
		if (sd->info_phonemobile) {
			if (strlen(sd->info_phonemobile))
				g_string_append_printf(st, "Mobile Phone: %s\n",
					sd->info_phonemobile);
			g_free(sd->info_phonemobile);
			sd->info_phonemobile = NULL;
		}
		g_string_append_printf(st, "Personal Information\n");
		if (sd->info_nrbuddies) {
			if (strlen(sd->info_nrbuddies))
				g_string_append_printf(st,
					"Contacts: %s\n", sd->info_nrbuddies);
			g_free(sd->info_nrbuddies);
			sd->info_nrbuddies = NULL;
		}
		if (sd->info_tz) {
			if (strlen(sd->info_tz)) {
				char ib[256];
				time_t t = time(NULL);
				t += atoi(sd->info_tz)-(60*60*24);
				struct tm *gt = gmtime(&t);
				strftime(ib, 256, "%H:%M:%S", gt);
				g_string_append_printf(st,
					"Local Time: %s\n", ib);
			}
			g_free(sd->info_tz);
			sd->info_tz = NULL;
		}
		if (sd->info_seen) {
			if (strlen(sd->info_seen)) {
				char ib[256];
				time_t it = atoi(sd->info_seen);
				struct tm *tm = localtime(&it);
				strftime(ib, 256, ("%Y. %m. %d. %H:%M"), tm);
				g_string_append_printf(st,
					"Last Seen: %s\n", ib);
			}
			g_free(sd->info_seen);
			sd->info_seen = NULL;
		}
		if (sd->info_birthday) {
			if (strlen(sd->info_birthday) &&
				strcmp(sd->info_birthday, "0")) {
				char ib[256];
				struct tm tm;
				strptime(sd->info_birthday, "%Y%m%d", &tm);
				strftime(ib, 256, "%B %d, %Y", &tm);
				g_string_append_printf(st,
					"Birthday: %s\n", ib);

				strftime(ib, 256, "%Y", &tm);
				int year = atoi(ib);
				time_t t = time(NULL);
				struct tm *lt = localtime(&t);
				g_string_append_printf(st,
					"Age: %d\n", lt->tm_year+1900-year);
			}
			g_free(sd->info_birthday);
			sd->info_birthday = NULL;
		}
		if (sd->info_sex) {
			if (strlen(sd->info_sex)) {
				char *iptr = sd->info_sex;
				while (*iptr++)
					*iptr = tolower(*iptr);
				g_string_append_printf(st,
					"Gender: %s\n", sd->info_sex);
			}
			g_free(sd->info_sex);
			sd->info_sex = NULL;
		}
		if (sd->info_language) {
			if (strlen(sd->info_language)) {
				char *iptr = strchr(sd->info_language, ' ');
				if (iptr)
					iptr++;
				else
					iptr = sd->info_language;
				g_string_append_printf(st,
					"Language: %s\n", iptr);
			}
			g_free(sd->info_language);
			sd->info_language = NULL;
		}
		if (sd->info_country) {
			if (strlen(sd->info_country)) {
				char *iptr = strchr(sd->info_country, ' ');
				if (iptr)
					iptr++;
				else
					iptr = sd->info_country;
				g_string_append_printf(st,
					"Country: %s\n", iptr);
			}
			g_free(sd->info_country);
			sd->info_country = NULL;
		}
		if (sd->info_province) {
			if (strlen(sd->info_province))
				g_string_append_printf(st,
					"Region: %s\n", sd->info_province);
			g_free(sd->info_province);
			sd->info_province = NULL;
		}
		if (sd->info_city) {
			if (strlen(sd->info_city))
				g_string_append_printf(st,
					"City: %s\n", sd->info_city);
			g_free(sd->info_city);
			sd->info_city = NULL;
		}
		if (sd->info_homepage) {
			if (strlen(sd->info_homepage))
				g_string_append_printf(st,
					"Homepage: %s\n", sd->info_homepage);
			g_free(sd->info_homepage);
			sd->info_homepage = NULL;
		}
		if (sd->info_about) {
			if (strlen(sd->info_about))
				g_string_append_printf(st, "%s\n",
					sd->info_about);
			g_free(sd->info_about);
			sd->info_about = NULL;
		}
		imcb_log(ic, "%s", st->str);
		g_string_free(st, TRUE);
	}
}
コード例 #24
0
ファイル: iq.c プロジェクト: shiplu/bitlbee
/*
 * Query the server for "items", query each "item" for identities, query each "item" that's a proxy for it's bytestream info
 */
xt_status jabber_iq_parse_server_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
{
	struct xt_node *c;
	struct jabber_data *jd = ic->proto_data;
	char *xmlns, *from;

	if( !( c = xt_find_node( node->children, "query" ) ) ||
	    !( from = xt_find_attr( node, "from" ) ) ||
	    !( xmlns = xt_find_attr( c, "xmlns" ) ) )
	{
		imcb_log( ic, "WARNING: Received incomplete IQ-result packet for discover" );
		return XT_HANDLED;
	}

	jd->have_streamhosts++;

	if( strcmp( xmlns, XMLNS_DISCO_ITEMS ) == 0 )
	{
		char *itemjid;

		/* answer from server */
	
		c = c->children;
		while( ( c = xt_find_node( c, "item" ) ) )
		{
			itemjid = xt_find_attr( c, "jid" );
			
			if( itemjid )
				jabber_iq_query_server( ic, itemjid, XMLNS_DISCO_INFO );

			c = c->next;
		}
	}
	else if( strcmp( xmlns, XMLNS_DISCO_INFO ) == 0 )
	{
		char *category, *type;

		/* answer from potential proxy */

		c = c->children;
		while( ( c = xt_find_node( c, "identity" ) ) )
		{
			category = xt_find_attr( c, "category" );
			type = xt_find_attr( c, "type" );

			if( type && ( strcmp( type, "bytestreams" ) == 0 ) &&
			    category && ( strcmp( category, "proxy" ) == 0 ) )
				jabber_iq_query_server( ic, from, XMLNS_BYTESTREAMS );

			c = c->next;
		}
	}
	else if( strcmp( xmlns, XMLNS_BYTESTREAMS ) == 0 )
	{
		char *host, *jid, *port_s;
		int port;

		/* answer from proxy */

		if( ( c = xt_find_node( c->children, "streamhost" ) ) &&
		    ( host = xt_find_attr( c, "host" ) ) &&
		    ( port_s = xt_find_attr( c, "port" ) ) &&
		    ( sscanf( port_s, "%d", &port ) == 1 ) &&
		    ( jid = xt_find_attr( c, "jid" ) ) )
		{
			jabber_streamhost_t *sh = g_new0( jabber_streamhost_t, 1 );
			
			sh->jid = g_strdup( jid );
			sh->host = g_strdup( host );
			g_snprintf( sh->port, sizeof( sh->port ), "%u", port );

			imcb_log( ic, "Proxy found: jid %s host %s port %u", jid, host, port );
			jd->streamhosts = g_slist_append( jd->streamhosts, sh );
		}
	}

	if( jd->have_streamhosts == 0 )
		jd->have_streamhosts++;

	return XT_HANDLED;
}
コード例 #25
0
ファイル: iq.c プロジェクト: shiplu/bitlbee
static xt_status jabber_iq_display_vcard( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
{
	struct xt_node *vc, *c, *sc; /* subchild, ic is already in use ;-) */
	GString *reply;
	char *s;
	
	if( ( s = xt_find_attr( node, "type" ) ) == NULL ||
	    strcmp( s, "result" ) != 0 ||
	    ( vc = xt_find_node( node->children, "vCard" ) ) == NULL )
	{
		s = xt_find_attr( orig, "to" ); /* If this returns NULL something's wrong.. */
		imcb_log( ic, "Could not retrieve vCard of %s", s ? s : "(NULL)" );
		return XT_HANDLED;
	}
	
	s = xt_find_attr( orig, "to" );
	reply = g_string_new( "vCard information for " );
	reply = g_string_append( reply, s ? s : "(NULL)" );
	reply = g_string_append( reply, ":\n" );
	
	/* I hate this format, I really do... */
	
	if( ( c = xt_find_node( vc->children, "FN" ) ) && c->text_len )
		g_string_append_printf( reply, "Name: %s\n", c->text );
	
	if( ( c = xt_find_node( vc->children, "N" ) ) && c->children )
	{
		reply = g_string_append( reply, "Full name:" );
		
		if( ( sc = xt_find_node( c->children, "PREFIX" ) ) && sc->text_len )
			g_string_append_printf( reply, " %s", sc->text );
		if( ( sc = xt_find_node( c->children, "GIVEN" ) ) && sc->text_len )
			g_string_append_printf( reply, " %s", sc->text );
		if( ( sc = xt_find_node( c->children, "MIDDLE" ) ) && sc->text_len )
			g_string_append_printf( reply, " %s", sc->text );
		if( ( sc = xt_find_node( c->children, "FAMILY" ) ) && sc->text_len )
			g_string_append_printf( reply, " %s", sc->text );
		if( ( sc = xt_find_node( c->children, "SUFFIX" ) ) && sc->text_len )
			g_string_append_printf( reply, " %s", sc->text );
		
		reply = g_string_append_c( reply, '\n' );
	}
	
	if( ( c = xt_find_node( vc->children, "NICKNAME" ) ) && c->text_len )
		g_string_append_printf( reply, "Nickname: %s\n", c->text );
	
	if( ( c = xt_find_node( vc->children, "BDAY" ) ) && c->text_len )
		g_string_append_printf( reply, "Date of birth: %s\n", c->text );
	
	/* Slightly alternative use of for... ;-) */
	for( c = vc->children; ( c = xt_find_node( c, "EMAIL" ) ); c = c->next )
	{
		if( ( sc = xt_find_node( c->children, "USERID" ) ) == NULL || sc->text_len == 0 )
			continue;
		
		if( xt_find_node( c->children, "HOME" ) )
			s = "Home";
		else if( xt_find_node( c->children, "WORK" ) )
			s = "Work";
		else
			s = "Misc.";
		
		g_string_append_printf( reply, "%s e-mail address: %s\n", s, sc->text );
	}
	
	if( ( c = xt_find_node( vc->children, "URL" ) ) && c->text_len )
		g_string_append_printf( reply, "Homepage: %s\n", c->text );
	
	/* Slightly alternative use of for... ;-) */
	for( c = vc->children; ( c = xt_find_node( c, "ADR" ) ); c = c->next )
	{
		if( xt_find_node( c->children, "HOME" ) )
			s = "Home";
		else if( xt_find_node( c->children, "WORK" ) )
			s = "Work";
		else
			s = "Misc.";
		
		g_string_append_printf( reply, "%s address: ", s );
		
		if( ( sc = xt_find_node( c->children, "STREET" ) ) && sc->text_len )
			g_string_append_printf( reply, "%s ", sc->text );
		if( ( sc = xt_find_node( c->children, "EXTADR" ) ) && sc->text_len )
			g_string_append_printf( reply, "%s, ", sc->text );
		if( ( sc = xt_find_node( c->children, "PCODE" ) ) && sc->text_len )
			g_string_append_printf( reply, "%s, ", sc->text );
		if( ( sc = xt_find_node( c->children, "LOCALITY" ) ) && sc->text_len )
			g_string_append_printf( reply, "%s, ", sc->text );
		if( ( sc = xt_find_node( c->children, "REGION" ) ) && sc->text_len )
			g_string_append_printf( reply, "%s, ", sc->text );
		if( ( sc = xt_find_node( c->children, "CTRY" ) ) && sc->text_len )
			g_string_append_printf( reply, "%s", sc->text );
		
		if( reply->str[reply->len-2] == ',' )
			reply = g_string_truncate( reply, reply->len-2 );
		
		reply = g_string_append_c( reply, '\n' );
	}
	
	for( c = vc->children; ( c = xt_find_node( c, "TEL" ) ); c = c->next )
	{
		if( ( sc = xt_find_node( c->children, "NUMBER" ) ) == NULL || sc->text_len == 0 )
			continue;
		
		if( xt_find_node( c->children, "HOME" ) )
			s = "Home";
		else if( xt_find_node( c->children, "WORK" ) )
			s = "Work";
		else
			s = "Misc.";
		
		g_string_append_printf( reply, "%s phone number: %s\n", s, sc->text );
	}
	
	if( ( c = xt_find_node( vc->children, "DESC" ) ) && c->text_len )
		g_string_append_printf( reply, "Other information:\n%s", c->text );
	
	/* *sigh* */
	
	imcb_log( ic, "%s", reply->str );
	g_string_free( reply, TRUE );
	
	return XT_HANDLED;
}
コード例 #26
0
ファイル: skype.c プロジェクト: GRMrGecko/bitlbee
static void skype_parse_call(struct im_connection *ic, char *line)
{
	struct skype_data *sd = ic->proto_data;
	char *id = strchr(line, ' ');
	char buf[IRC_LINE_SIZE];

	if (!++id)
		return;
	char *info = strchr(id, ' ');

	if (!info)
		return;
	*info = '\0';
	info++;
	if (!strncmp(info, "FAILUREREASON ", 14))
		sd->failurereason = atoi(strchr(info, ' '));
	else if (!strcmp(info, "STATUS RINGING")) {
		if (sd->call_id)
			g_free(sd->call_id);
		sd->call_id = g_strdup(id);
		skype_printf(ic, "GET CALL %s PARTNER_HANDLE\n", id);
		sd->call_status = SKYPE_CALL_RINGING;
	} else if (!strcmp(info, "STATUS MISSED")) {
		skype_printf(ic, "GET CALL %s PARTNER_HANDLE\n", id);
		sd->call_status = SKYPE_CALL_MISSED;
	} else if (!strcmp(info, "STATUS CANCELLED")) {
		skype_printf(ic, "GET CALL %s PARTNER_HANDLE\n", id);
		sd->call_status = SKYPE_CALL_CANCELLED;
	} else if (!strcmp(info, "STATUS FINISHED")) {
		skype_printf(ic, "GET CALL %s PARTNER_HANDLE\n", id);
		sd->call_status = SKYPE_CALL_FINISHED;
	} else if (!strcmp(info, "STATUS REFUSED")) {
		skype_printf(ic, "GET CALL %s PARTNER_HANDLE\n", id);
		sd->call_status = SKYPE_CALL_REFUSED;
	} else if (!strcmp(info, "STATUS UNPLACED")) {
		if (sd->call_id)
			g_free(sd->call_id);
		/* Save the ID for later usage (Cancel/Finish). */
		sd->call_id = g_strdup(id);
		sd->call_out = TRUE;
	} else if (!strcmp(info, "STATUS FAILED")) {
		imcb_error(ic, "Call failed: %s",
			skype_call_strerror(sd->failurereason));
		sd->call_id = NULL;
	} else if (!strncmp(info, "DURATION ", 9)) {
		if (sd->call_duration)
			g_free(sd->call_duration);
		sd->call_duration = g_strdup(info+9);
	} else if (!strncmp(info, "PARTNER_HANDLE ", 15)) {
		info += 15;
		if (!sd->call_status)
			return;
		switch (sd->call_status) {
		case SKYPE_CALL_RINGING:
			if (sd->call_out)
				imcb_log(ic, "You are currently ringing the user %s.", info);
			else {
				g_snprintf(buf, IRC_LINE_SIZE,
					"The user %s is currently ringing you.",
					info);
				skype_call_ask(ic, sd->call_id, buf);
			}
			break;
		case SKYPE_CALL_MISSED:
			imcb_log(ic, "You have missed a call from user %s.",
				info);
			break;
		case SKYPE_CALL_CANCELLED:
			imcb_log(ic, "You cancelled the call to the user %s.",
				info);
			sd->call_status = 0;
			sd->call_out = FALSE;
			break;
		case SKYPE_CALL_REFUSED:
			if (sd->call_out)
				imcb_log(ic, "The user %s refused the call.",
					info);
			else
				imcb_log(ic,
					"You refused the call from user %s.",
					info);
			sd->call_out = FALSE;
			break;
		case SKYPE_CALL_FINISHED:
			if (sd->call_duration)
				imcb_log(ic,
					"You finished the call to the user %s "
					"(duration: %s seconds).",
					info, sd->call_duration);
			else
				imcb_log(ic,
					"You finished the call to the user %s.",
					info);
			sd->call_out = FALSE;
			break;
		default:
			/* Don't be noisy, ignore other statuses for now. */
			break;
		}
		sd->call_status = 0;
	}
}
コード例 #27
0
ファイル: iq.c プロジェクト: shiplu/bitlbee
xt_status jabber_pkt_bind_sess( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
{
	struct jabber_data *jd = ic->proto_data;
	struct xt_node *c, *reply = NULL;
	char *s;
	
	if( node && ( c = xt_find_node( node->children, "bind" ) ) )
	{
		c = xt_find_node( c->children, "jid" );
		if( !c || !c->text )
		{
			/* Server is crap, but this is no disaster. */
		}
		else if( strncmp( jd->me, c->text, strlen( jd->me ) ) != 0 )
		{
			s = strchr( c->text, '/' );
			if( s )
				*s = '\0';
			jabber_set_me( ic, c->text );
			imcb_log( ic, "Server claims your JID is `%s' instead of `%s'. "
			          "This mismatch may cause problems with groupchats "
			          "and possibly other things.",
			          c->text, ic->acc->user );
			if( s )
				*s = '/';
		}
		else if( c && c->text_len && ( s = strchr( c->text, '/' ) ) &&
		         strcmp( s + 1, set_getstr( &ic->acc->set, "resource" ) ) != 0 )
			imcb_log( ic, "Server changed session resource string to `%s'", s + 1 );
	}
	
	if( jd->flags & JFLAG_WANT_BIND )
	{
		reply = xt_new_node( "bind", NULL, xt_new_node( "resource", set_getstr( &ic->acc->set, "resource" ), NULL ) );
		xt_add_attr( reply, "xmlns", XMLNS_BIND );
		jd->flags &= ~JFLAG_WANT_BIND;
	}
	else if( jd->flags & JFLAG_WANT_SESSION )
	{
		reply = xt_new_node( "session", NULL, NULL );
		xt_add_attr( reply, "xmlns", XMLNS_SESSION );
		jd->flags &= ~JFLAG_WANT_SESSION;
	}
	
	if( reply != NULL )
	{
		reply = jabber_make_packet( "iq", "set", NULL, reply );
		jabber_cache_add( ic, reply, jabber_pkt_bind_sess );
		
		if( !jabber_write_packet( ic, reply ) )
			return XT_ABORT;
	}
	else if( ( jd->flags & ( JFLAG_WANT_BIND | JFLAG_WANT_SESSION ) ) == 0 )
	{
		if( !jabber_get_roster( ic ) )
			return XT_ABORT;
		if( !jabber_iq_disco_server( ic ) )
			return XT_ABORT;
	}
	
	return XT_HANDLED;
}
コード例 #28
0
ファイル: iq.c プロジェクト: shiplu/bitlbee
xt_status jabber_pkt_iq( struct xt_node *node, gpointer data )
{
	struct im_connection *ic = data;
	struct jabber_data *jd = ic->proto_data;
	struct xt_node *c, *reply = NULL;
	char *type, *s;
	int st, pack = 1;
	
	type = xt_find_attr( node, "type" );
	
	if( !type )
	{
		imcb_error( ic, "Received IQ packet without type." );
		imc_logout( ic, TRUE );
		return XT_ABORT;
	}
	
	if( strcmp( type, "result" ) == 0 || strcmp( type, "error" ) == 0 )
	{
		return jabber_cache_handle_packet( ic, node );
	}
	else if( strcmp( type, "get" ) == 0 )
	{
		if( !( ( c = xt_find_node( node->children, "query" ) ) ||
		       ( c = xt_find_node( node->children, "ping" ) ) ||
		       ( c = xt_find_node( node->children, "time" ) ) ) ||
		    !( s = xt_find_attr( c, "xmlns" ) ) )
		{
			/* Sigh. Who decided to suddenly invent new elements
			   instead of just sticking with <query/>? */
			return XT_HANDLED;
		}
		
		reply = xt_new_node( "query", NULL, NULL );
		xt_add_attr( reply, "xmlns", s );
		
		/* Of course this is a very essential query to support. ;-) */
		if( strcmp( s, XMLNS_VERSION ) == 0 )
		{
			xt_add_child( reply, xt_new_node( "name", set_getstr( &ic->acc->set, "user_agent" ), NULL ) );
			xt_add_child( reply, xt_new_node( "version", BITLBEE_VERSION, NULL ) );
			xt_add_child( reply, xt_new_node( "os", ARCH, NULL ) );
		}
		else if( strcmp( s, XMLNS_TIME_OLD ) == 0 )
		{
			time_t time_ep;
			char buf[1024];
			
			buf[sizeof(buf)-1] = 0;
			time_ep = time( NULL );
			
			strftime( buf, sizeof( buf ) - 1, "%Y%m%dT%H:%M:%S", gmtime( &time_ep ) );
			xt_add_child( reply, xt_new_node( "utc", buf, NULL ) );
			
			strftime( buf, sizeof( buf ) - 1, "%Z", localtime( &time_ep ) );
			xt_add_child( reply, xt_new_node( "tz", buf, NULL ) );
		}
		else if( strcmp( s, XMLNS_TIME ) == 0 )
		{
			time_t time_ep;
			char buf[1024];
			
			buf[sizeof(buf)-1] = 0;
			time_ep = time( NULL );
			
			xt_free_node( reply );
			reply = xt_new_node( "time", NULL, NULL );
			xt_add_attr( reply, "xmlns", XMLNS_TIME );
			
			strftime( buf, sizeof( buf ) - 1, "%Y%m%dT%H:%M:%SZ", gmtime( &time_ep ) );
			xt_add_child( reply, xt_new_node( "utc", buf, NULL ) );
			
			strftime( buf, sizeof( buf ) - 1, "%z", localtime( &time_ep ) );
			if( strlen( buf ) >= 5 )
			{
				buf[6] = '\0';
				buf[5] = buf[4];
				buf[4] = buf[3];
				buf[3] = ':';
			}
			xt_add_child( reply, xt_new_node( "tzo", buf, NULL ) );
		}
		else if( strcmp( s, XMLNS_PING ) == 0 )
		{
			xt_free_node( reply );
			reply = jabber_make_packet( "iq", "result", xt_find_attr( node, "from" ), NULL );
			if( ( s = xt_find_attr( node, "id" ) ) )
				xt_add_attr( reply, "id", s );
			pack = 0;
		}
		else if( strcmp( s, XMLNS_DISCO_INFO ) == 0 )
		{
			const char *features[] = { XMLNS_DISCO_INFO,
			                           XMLNS_VERSION,
			                           XMLNS_TIME_OLD,
			                           XMLNS_TIME,
			                           XMLNS_CHATSTATES,
			                           XMLNS_MUC,
			                           XMLNS_PING,
			                           XMLNS_SI,
			                           XMLNS_BYTESTREAMS,
			                           XMLNS_FILETRANSFER,
			                           NULL };
			const char **f;
			
			c = xt_new_node( "identity", NULL, NULL );
			xt_add_attr( c, "category", "client" );
			xt_add_attr( c, "type", "pc" );
			xt_add_attr( c, "name", set_getstr( &ic->acc->set, "user_agent" ) );
			xt_add_child( reply, c );
			
			for( f = features; *f; f ++ )
			{
				c = xt_new_node( "feature", NULL, NULL );
				xt_add_attr( c, "var", *f );
				xt_add_child( reply, c );
			}
		}
		else
		{
			xt_free_node( reply );
			reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel", NULL );
			pack = 0;
		}
	}
	else if( strcmp( type, "set" ) == 0 )
	{
		if( ( c = xt_find_node( node->children, "si" ) ) &&
		    ( s = xt_find_attr( c, "xmlns" ) ) &&
		    ( strcmp( s, XMLNS_SI ) == 0 ) )
		{
			return jabber_si_handle_request( ic, node, c );
		}
		else if( !( c = xt_find_node( node->children, "query" ) ) ||
		         !( s = xt_find_attr( c, "xmlns" ) ) )
		{
			return XT_HANDLED;
		}
		else if( strcmp( s, XMLNS_ROSTER ) == 0 )
		{
		/* This is a roster push. XMPP servers send this when someone
		   was added to (or removed from) the buddy list. AFAIK they're
		   sent even if we added this buddy in our own session. */
			int bare_len = strlen( jd->me );
			
			if( ( s = xt_find_attr( node, "from" ) ) == NULL ||
			    ( strncmp( s, jd->me, bare_len ) == 0 &&
			      ( s[bare_len] == 0 || s[bare_len] == '/' ) ) )
			{
				jabber_parse_roster( ic, node, NULL );
				
				/* Should we generate a reply here? Don't think it's
				   very important... */
			}
			else
			{
				imcb_log( ic, "Warning: %s tried to fake a roster push!", s ? s : "(unknown)" );
				
				xt_free_node( reply );
				reply = jabber_make_error_packet( node, "not-allowed", "cancel", NULL );
				pack = 0;
			}
		}
		else if( strcmp( s, XMLNS_BYTESTREAMS ) == 0 )
		{
			/* Bytestream Request (stage 2 of file transfer) */
			return jabber_bs_recv_request( ic, node, c );
		}
		else
		{
			xt_free_node( reply );
			reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel", NULL );
			pack = 0;
		}
	}
	
	/* If we recognized the xmlns and managed to generate a reply,
	   finish and send it. */
	if( reply )
	{
		/* Normally we still have to pack it into an iq-result
		   packet, but for errors, for example, we don't. */
		if( pack )
		{
			reply = jabber_make_packet( "iq", "result", xt_find_attr( node, "from" ), reply );
			if( ( s = xt_find_attr( node, "id" ) ) )
				xt_add_attr( reply, "id", s );
		}
		
		st = jabber_write_packet( ic, reply );
		xt_free_node( reply );
		if( !st )
			return XT_ABORT;
	}
	
	return XT_HANDLED;
}
コード例 #29
0
ファイル: purple.c プロジェクト: GRMrGecko/bitlbee
static void prplcb_conn_progress( PurpleConnection *gc, const char *text, size_t step, size_t step_count )
{
	struct im_connection *ic = purple_ic_by_gc( gc );
	
	imcb_log( ic, "%s", text );
}
コード例 #30
0
ファイル: steam.c プロジェクト: bitlbee/bitlbee-steam
static void
steam_cb_user_info_nicks(SteamApiReq *req, gpointer data)
{
    const gchar *ctr;
    gchar *str;
    GSList *l;
    guint i;
    SteamData *sata = data;
    SteamUserInfo *info = req->infs->head->data;

    if (steam_req_error(sata, req, TRUE)) {
        return;
    }

    if (info->fullname != NULL) {
        imcb_log(sata->ic, "Name: %s (%s)", info->nick, info->fullname);
    } else {
        imcb_log(sata->ic, "Name: %s", info->nick);
    }

    if (info->game != NULL) {
        if (info->server != NULL) {
            imcb_log(sata->ic, "Playing: %s - steam://connect/%s",
                     info->game, info->server);
        } else {
            imcb_log(sata->ic, "Playing: %s", info->game);
        }
    }

    ctr = steam_user_state_str(info->state);

    if (info->state == STEAM_USER_STATE_OFFLINE) {
        str = steam_util_time_since_utc(info->ltime);
    } else {
        str = steam_user_flags_str(info->flags);
    }

    if (str != NULL) {
        imcb_log(sata->ic, "Status: %s (%s)", ctr, str);
        g_free(str);
    } else {
        imcb_log(sata->ic, "Status: %s", ctr);
    }

    imcb_log(sata->ic, "Steam ID: %" STEAM_ID_FORMAT " (%" G_GINT32_FORMAT ")",
             info->id, STEAM_ID_ACCID(info->id));

    if (info->profile != NULL) {
        imcb_log(sata->ic, "Profile: %s", info->profile);
    }

    if (info->nicks != NULL) {
        imcb_log(sata->ic, "Nicknames:");

        for (l = info->nicks, i = 1; l != NULL; l = l->next, i++) {
            imcb_log(sata->ic, "%u. `%s'", i, (gchar *) l->data);
        }
    }

    steam_user_status(sata, info, NULL);
}