2013-03-31 18:16:37 +04:00
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd .
Copyright 2013 Lennart Poettering
systemd is free software ; you can redistribute it and / or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation ; either version 2.1 of the License , or
( at your option ) any later version .
systemd 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
Lesser General Public License for more details .
You should have received a copy of the GNU Lesser General Public License
along with systemd ; If not , see < http : //www.gnu.org/licenses/>.
* * */
# include <assert.h>
# include "log.h"
# include "util.h"
# include "macro.h"
# include "bus-match.h"
# include "bus-message.h"
2013-10-16 08:10:04 +04:00
# include "bus-util.h"
2014-05-15 03:15:30 +04:00
# include "bus-slot.h"
2013-03-31 18:16:37 +04:00
static bool mask [ 32 ] ;
2013-11-21 22:34:37 +04:00
static int filter ( sd_bus * b , sd_bus_message * m , void * userdata , sd_bus_error * ret_error ) {
2013-03-31 18:16:37 +04:00
log_info ( " Ran %i " , PTR_TO_INT ( userdata ) ) ;
mask [ PTR_TO_INT ( userdata ) ] = true ;
return 0 ;
}
static bool mask_contains ( unsigned a [ ] , unsigned n ) {
unsigned i , j ;
for ( i = 0 ; i < ELEMENTSOF ( mask ) ; i + + ) {
bool found = false ;
for ( j = 0 ; j < n ; j + + )
if ( a [ j ] = = i ) {
found = true ;
break ;
}
if ( found ! = mask [ i ] )
return false ;
}
return true ;
}
2014-05-15 03:15:30 +04:00
static int match_add ( sd_bus_slot * slots , struct bus_match_node * root , const char * match , int value ) {
2013-05-19 20:39:08 +04:00
struct bus_match_component * components = NULL ;
unsigned n_components = 0 ;
2014-05-15 03:15:30 +04:00
sd_bus_slot * s ;
2013-05-19 20:39:08 +04:00
int r ;
2014-05-15 03:15:30 +04:00
s = slots + value ;
zero ( * s ) ;
2013-05-19 20:39:08 +04:00
r = bus_match_parse ( match , & components , & n_components ) ;
if ( r < 0 )
return r ;
2014-05-15 03:15:30 +04:00
s - > userdata = INT_TO_PTR ( value ) ;
s - > match_callback . callback = filter ;
r = bus_match_add ( root , components , n_components , & s - > match_callback ) ;
2013-05-19 20:39:08 +04:00
bus_match_parse_free ( components , n_components ) ;
return r ;
}
2013-03-31 18:16:37 +04:00
int main ( int argc , char * argv [ ] ) {
2014-06-06 20:30:01 +04:00
struct bus_match_node root = {
. type = BUS_MATCH_ROOT ,
} ;
2013-03-31 18:16:37 +04:00
_cleanup_bus_message_unref_ sd_bus_message * m = NULL ;
2014-06-06 20:30:01 +04:00
_cleanup_bus_unref_ sd_bus * bus = NULL ;
2013-03-31 18:16:37 +04:00
enum bus_match_node_type i ;
2014-05-15 03:15:30 +04:00
sd_bus_slot slots [ 15 ] ;
2014-06-06 20:30:01 +04:00
int r ;
2013-03-31 18:16:37 +04:00
2014-06-06 20:30:01 +04:00
r = sd_bus_open_system ( & bus ) ;
if ( r < 0 )
return EXIT_TEST_SKIP ;
2013-03-31 18:16:37 +04:00
2014-05-15 03:15:30 +04:00
assert_se ( match_add ( slots , & root , " arg2='wal \\ 'do',sender='foo',type='signal',interface='bar.x', " , 1 ) > = 0 ) ;
assert_se ( match_add ( slots , & root , " arg2='wal \\ 'do2',sender='foo',type='signal',interface='bar.x', " , 2 ) > = 0 ) ;
assert_se ( match_add ( slots , & root , " arg3='test',sender='foo',type='signal',interface='bar.x', " , 3 ) > = 0 ) ;
assert_se ( match_add ( slots , & root , " arg3='test',sender='foo',type='method_call',interface='bar.x', " , 4 ) > = 0 ) ;
assert_se ( match_add ( slots , & root , " " , 5 ) > = 0 ) ;
assert_se ( match_add ( slots , & root , " interface='quux.x' " , 6 ) > = 0 ) ;
assert_se ( match_add ( slots , & root , " interface='bar.x' " , 7 ) > = 0 ) ;
assert_se ( match_add ( slots , & root , " member='waldo',path='/foo/bar' " , 8 ) > = 0 ) ;
assert_se ( match_add ( slots , & root , " path='/foo/bar' " , 9 ) > = 0 ) ;
assert_se ( match_add ( slots , & root , " path_namespace='/foo' " , 10 ) > = 0 ) ;
assert_se ( match_add ( slots , & root , " path_namespace='/foo/quux' " , 11 ) > = 0 ) ;
assert_se ( match_add ( slots , & root , " arg1='two' " , 12 ) > = 0 ) ;
assert_se ( match_add ( slots , & root , " member='waldo',arg2path='/prefix/' " , 13 ) > = 0 ) ;
assert_se ( match_add ( slots , & root , " member=waldo,path='/foo/bar',arg3namespace='prefix' " , 14 ) > = 0 ) ;
2013-03-31 18:16:37 +04:00
bus_match_dump ( & root , 0 ) ;
2014-06-06 20:30:01 +04:00
assert_se ( sd_bus_message_new_signal ( bus , & m , " /foo/bar " , " bar.x " , " waldo " ) > = 0 ) ;
2013-03-31 18:16:37 +04:00
assert_se ( sd_bus_message_append ( m , " ssss " , " one " , " two " , " /prefix/three " , " prefix.four " ) > = 0 ) ;
2013-12-12 23:00:19 +04:00
assert_se ( bus_message_seal ( m , 1 , 0 ) > = 0 ) ;
2013-03-31 18:16:37 +04:00
zero ( mask ) ;
2013-05-16 23:14:56 +04:00
assert_se ( bus_match_run ( NULL , & root , m ) = = 0 ) ;
2013-03-31 18:16:37 +04:00
assert_se ( mask_contains ( ( unsigned [ ] ) { 9 , 8 , 7 , 5 , 10 , 12 , 13 , 14 } , 8 ) ) ;
2014-05-15 03:15:30 +04:00
assert_se ( bus_match_remove ( & root , & slots [ 8 ] . match_callback ) > = 0 ) ;
assert_se ( bus_match_remove ( & root , & slots [ 13 ] . match_callback ) > = 0 ) ;
2013-03-31 18:16:37 +04:00
bus_match_dump ( & root , 0 ) ;
zero ( mask ) ;
2013-05-16 23:14:56 +04:00
assert_se ( bus_match_run ( NULL , & root , m ) = = 0 ) ;
2013-03-31 18:16:37 +04:00
assert_se ( mask_contains ( ( unsigned [ ] ) { 9 , 5 , 10 , 12 , 14 , 7 } , 6 ) ) ;
for ( i = 0 ; i < _BUS_MATCH_NODE_TYPE_MAX ; i + + ) {
char buf [ 32 ] ;
const char * x ;
assert_se ( x = bus_match_node_type_to_string ( i , buf , sizeof ( buf ) ) ) ;
if ( i > = BUS_MATCH_MESSAGE_TYPE )
assert_se ( bus_match_node_type_from_string ( x , strlen ( x ) ) = = i ) ;
}
bus_match_free ( & root ) ;
return 0 ;
}