コード例 #1
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);

}
コード例 #2
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;
}