dbus_service.c

来自「非常好的dns解析软件」· C语言 代码 · 共 1,156 行 · 第 1/2 页

C
1,156
字号
/*  dbus_service.c * *  D-BUS Service Utilities *   *  Provides MINIMAL utilities for construction of D-BUS "Services". *   *  Copyright(C) Jason Vas Dias, Red Hat Inc., 2005 * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation at  *           http://www.fsf.org/licensing/licenses/gpl.txt *  and included in this software distribution as the "LICENSE" file. * *  This program 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 General Public License for more details. * */#include <sys/types.h>#include <unistd.h>#include <linux/limits.h>#include <sys/time.h>#include <sys/socket.h>#include <sys/select.h>#include <sys/wait.h>#include <sys/ioctl.h>#include <time.h>#include <signal.h>#include <syslog.h>#include <fcntl.h>#include <string.h>extern size_t strnlen(const char *s, size_t maxlen);#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <ifaddrs.h>#include <search.h>#include <getopt.h>typedef void (*__free_fn_t) (void *__nodep);extern void tdestroy (void *__root, __free_fn_t __freefct);#include <stdint.h>#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <errno.h>#define  DBUS_API_SUBJECT_TO_CHANGE  "Very Annoying and Silly!"#include <dbus/dbus.h>#include <named/dbus_service.h>typedef struct dbcs_s{    DBusConnection *connection;    DBusDispatchStatus dispatchStatus;    uint32_t        status;    dbus_svc_WatchHandler wh;    void *          wh_arg;    const char    * unique_name;    dbus_svc_MessageHandler mh;    void          * def_mh_obj;    dbus_svc_MessageHandler mf;    void          * def_mf_obj;    dbus_svc_ShutdownHandler sh;    void          * sh_obj;      dbus_svc_ErrorHandler eh;    dbus_svc_ErrorHandler dh;    /*{ glibc b-trees: */    void *          roots;    void *          timeouts;      void *          watches;    void *          filters;    /*}*/    int             n;     fd_set          r_fds;    fd_set          s_r_fds;    fd_set          w_fds;    fd_set          s_w_fds;    fd_set          e_fds;      fd_set          s_e_fds;    DBusMessage     *currentMessage;    int             rejectMessage;} DBusConnectionState;typedef struct root_s{    char *path;        char *if_prefix;    DBUS_SVC cs;    dbus_svc_MessageHandler mh;            void *object;    void *tree;} Root;typedef struct mhn_s{    char *path;        dbus_svc_MessageHandler mh;        void *object;} MessageHandlerNode;typedef struct mfn_s{    DBusConnectionState *cs;    dbus_svc_MessageHandler mf;    void *obj;    int n_matches;    char **matches;} MessageFilterNode;typedef struct dbto_s{    DBusTimeout   *to;    DBusConnectionState *cs;    struct timeval tv;} DBusConnectionTimeout;static void no_free( void *p){ p=0; }static int ptr_key_comparator( const void *p1, const void *p2 ){    return	(  (p1 == p2) 	   ? 0	   :( (p1 > p2)	      ? 1	      : -1	    )	);}static DBusHandlerResultdefault_message_filter (   DBusConnection     *connection,    DBusMessage        *message,    void               *p){    DBusConnectionState *cs = p;    uint32_t type  =dbus_message_get_type( message ),	   serial  =dbus_message_get_serial( message );    uint8_t  reply =dbus_message_get_no_reply( message )==0;    const char 	*path =    dbus_message_get_path( message ),	*dest =    dbus_message_get_destination( message ),	*member =  dbus_message_get_member( message ),	*interface=dbus_message_get_interface( message ),	*sender   =dbus_message_get_sender( message ),	*signature=dbus_message_get_signature( message );    connection = connection;    if(cs->mf)	return	(*(cs->mf))( cs, type, reply, serial, dest, path, member, interface, 0L,		    sender, signature, message, 0L, 0L, 0L, cs->def_mf_obj	          ) ;    return HANDLED;}uint8_tdbus_svc_add_filter(  DBusConnectionState *cs, dbus_svc_MessageHandler mh, void *obj, int n_matches, ... ){    DBusError error;    va_list va;    char *m;    va_start(va, n_matches );        cs->mf = mh;    cs->def_mf_obj = obj;    if ( ! dbus_connection_add_filter (cs->connection, default_message_filter, cs, NULL))    {	if( cs->eh != 0L ) (*(cs->eh))("dbus_svc_add_filter: dbus_connection_add_filter failed");	va_end(va);	return( 0 );    }    if( n_matches )    {	memset(&error,'\0',sizeof(DBusError));	dbus_error_init(&error);	while( n_matches-- )	{	    m = va_arg(va, char* ) ;	    dbus_bus_add_match(cs->connection, m, &error);	    if( dbus_error_is_set(&error))	    {		if( cs->eh != 0L ) (*(cs->eh))("dbus_svc_add_filter: dbus_bus_add_match failed for %s: %s %s",					       m, error.name, error.message		                              );		va_end(va);		return(0);	    }	}    }    return( 1 );}uint8_tdbus_svc_get_args_va(DBusConnectionState *cs, DBusMessage* msg, dbus_svc_DataType firstType, va_list va){    DBusError error;    memset(&error,'\0',sizeof(DBusError));    dbus_error_init(&error);    if( (!dbus_message_get_args_valist(msg, &error, firstType, va)) || dbus_error_is_set(&error) )    {	if(  dbus_error_is_set(&error) )	{	    if( cs->eh != 0L ) (*(cs->eh))("dbus_svc_get_args failed: %s %s",error.name, error.message);	    dbus_error_free(&error);	}else	    if( cs->eh != 0L ) (*(cs->eh))("dbus_svc_get_args failed: dbus_message_get_args_valist failed");	return( 0 );    }    return( 1 );}uint8_tdbus_svc_get_args(DBusConnectionState *cs, DBusMessage* msg, dbus_svc_DataType firstType, ...){    va_list va;    uint8_t r;    va_start(va, firstType);    r = dbus_svc_get_args_va( cs, msg, firstType, va);    va_end(va);    return r;}uint8_t dbus_svc_send_va(  DBusConnectionState *cs,   dbus_svc_MessageType type,      int32_t reply_serial,   uint32_t *new_serial,   const char *destination,   const char *path,   const char *interface,   const char *member,   dbus_svc_DataType firstType,   va_list va){    DBusMessageIter iter;    char *e;    DBusMessage *msg = 	dbus_svc_new_message	(   cs,	    type,	    reply_serial,	    destination,	    path,	    interface,	    member	);    if(msg == 0L)    {	if( cs->eh != 0L ) (*(cs->eh))("dbus_svc_send: dbus_svc_new_message failed");	return 0;    }    if( type != DBUS_MESSAGE_TYPE_ERROR )    {	if( !dbus_message_append_args_valist( msg, firstType, va ) )	{	    if( cs->eh != 0L ) (*(cs->eh))("dbus_svc_send: dbus_message_append_args_valist failed");	    return 0;	}    }else    {	if( firstType == DBUS_TYPE_STRING )	{	    e = 0L;	    e = va_arg( va, char* );	    	    if( (e == 0L) ||  !dbus_message_set_error_name( msg, e ) )	    {		if( cs->eh != 0L ) (*(cs->eh))("dbus_svc_send: dbus_message_set_error_name failed");		return 0;	    }	    firstType = va_arg(va, int);	    if( firstType == DBUS_TYPE_STRING )	    {		e = 0L;		e =  va_arg( va, char* );		if( e == 0L )		{		    if( cs->eh != 0L ) (*(cs->eh))("dbus_svc_send: NULL error message");		    return 0;		    		    		}		dbus_message_iter_init_append (msg, &iter);				if( !dbus_message_iter_append_basic 		    (&iter, DBUS_TYPE_STRING, &e)		  )		{		    if( cs->eh != 0L ) (*(cs->eh))("dbus_svc_send: dbus_message_iter_append_basic failed");		    return 0;		    		    		}	    }	}else	{	    if( cs->eh != 0L ) (*(cs->eh))("dbus_svc_send: unhandled type for error name: %c", firstType);	    return 0;	    	}    }    if( !dbus_connection_send(cs->connection, msg, new_serial) )    {	if( cs->eh != 0L ) (*(cs->eh))("dbus_svc_send: dbus_message_send failed");	return 0;    }    if( cs->dh != 0L ) (*(cs->dh))("Sending message");    dbus_connection_flush(cs->connection);    return 1;}uint8_t dbus_svc_send(  DBusConnectionState *cs,   dbus_svc_MessageType type,   int32_t reply_serial,   uint32_t *new_serial,   const char *destination,   const char *path,   const char *interface,   const char *member,   dbus_svc_DataType firstType,   ...){    uint8_t r;    va_list va;    va_start(va, firstType);    r = dbus_svc_send_va(cs, type, reply_serial, new_serial, destination, path,interface,member,firstType,va);    va_end(va);    return ( r ) ;}dbus_svc_MessageHandledbus_svc_new_message( DBusConnectionState* cs,  dbus_svc_MessageType type,  int32_t reply_serial,  const char *destination,  const char *path,  const char *interface,  const char *member){    DBusMessage *msg = dbus_message_new(type);        if( msg == 0L)    {	if( cs->eh != 0L ) (*(cs->eh))("dbus_svc_new_message: dbus_message_set_reply_serial failed");	return 0;    }    if( reply_serial != -1 )    {	if( !dbus_message_set_reply_serial(msg,reply_serial) )	{	    if( cs->eh != 0L ) (*(cs->eh))("dbus_svc_new_message: dbus_message_set_reply_serial failed");	    return 0;	}        }	        if( (destination !=0L) && !dbus_message_set_destination(msg, destination) )    {	if( cs->eh != 0L ) (*(cs->eh))("dbus_svc_new_message: dbus_message_set_destination failed");	return 0;    }    if( !dbus_message_set_path(msg, path) )    {	if( cs->eh != 0L ) (*(cs->eh))("dbus_svc_new_message: dbus_message_set_path failed");	return 0;    }    if( ! dbus_message_set_interface(msg,interface) )    {	if( cs->eh != 0L ) (*(cs->eh))("dbus_svc_new_message: dbus_message_set_interface failed - %s", interface);	return 0;    }    if( !dbus_message_set_member(msg,member) )    {	if( cs->eh != 0L ) (*(cs->eh))("dbus_svc_new_message: dbus_message_set_member failed");	return 0;    }    return msg;    }extern uint8_tdbus_svc_send_message(    DBusConnectionState *cs,     dbus_svc_MessageHandle msg,     uint32_t *new_serial ){    if( !dbus_connection_send(cs->connection, msg, new_serial) )    {	if( cs->eh != 0L ) (*(cs->eh))("dbus_svc_send: dbus_message_send failed");	return 0;    }    if( cs->dh != 0L ) (*(cs->dh))("Sending message");    dbus_connection_flush(cs->connection);       return 1;}uint8_tdbus_svc_message_append_args(DBusConnectionState *cs, dbus_svc_MessageHandle msg, dbus_svc_DataType firstType, ...){    va_list va;    va_start(va, firstType);    if( !dbus_message_append_args_valist( msg, firstType, va ) )    {	if( cs->eh != 0L ) (*(cs->eh))("dbus_svc_send: dbus_message_append_args failed");	return 0;	    }    va_end(va);    return ( 1 ) ;}dbus_svc_MessageHandle dbus_svc_call( DBusConnectionState *cs,  const char *destination,  const char *path,  const char *member,  const char *interface,  dbus_svc_DataType firstType,  ... ){    DBusMessage *message=0L, *reply=0L;    va_list va;    DBusError error;    int reply_timeout=20000;    va_start(va, firstType);    memset(&error,'\0',sizeof(DBusError));    dbus_error_init(&error);    if(( message = 	 dbus_message_new_method_call 	 (  destination,	    path,	    interface,	    member	 )       ) == 0L      )    {	if( cs->eh != 0L ) (*(cs->eh))("dbus_svc_call: dbus_message_new_method_call failed");	va_end(va);	return(0L);    };    if( !dbus_message_append_args_valist( message, firstType, va ) )    {	if( cs->eh != 0L ) (*(cs->eh))("dbus_svc_call: dbus_message_append_args_valist failed");	va_end(va);	return(0L);    }    if((reply = 	dbus_connection_send_with_reply_and_block 	(cs->connection,	 message, reply_timeout,	 &error	)       ) == 0L          )    {	if( cs->eh != 0L ) (*(cs->eh))("dbus_svc_call: dbus_message_send_with_reply_and_block failed: %s %s",		    error.name, error.message	           );	va_end(va);	return(0L);    }    return reply;}dbus_svc_MessageIteratordbus_svc_message_iterator_new( DBusConnectionState *cs, DBusMessage *msg){    DBusMessageIter *iter = malloc( sizeof(DBusMessageIter) );    void *p =cs;    p++;    if( iter != 0L )    {	if( !dbus_message_iter_init( msg, iter ))	{	    free( iter ) ;	    iter = 0L;	}    }    return iter;}uint32_tdbus_svc_message_next_arg_type( DBusConnectionState *cs, dbus_svc_MessageIterator iter ){    void *p =cs;    p++;    return dbus_message_iter_get_arg_type( iter );}voiddbus_svc_message_next_arg( DBusConnectionState *cs, dbus_svc_MessageIterator iter, void *value ){    void *p =cs;    p++;    dbus_message_iter_get_basic( iter, value );    dbus_message_iter_next( iter );}uint32_tdbus_svc_message_element_type(DBusConnectionState *cs , dbus_svc_MessageIterator  iter){    void *p =cs;    p++;    return dbus_message_iter_get_element_type(iter);}voiddbus_svc_message_get_elements( DBusConnectionState *cs , dbus_svc_MessageIterator  iter, uint32_t *n, void *array ){    void *p =cs;    p++;    dbus_message_iter_get_fixed_array( iter, n, array);}void dbus_svc_message_iterator_free(  DBusConnectionState *cs, dbus_svc_MessageIterator iter ){    void *p =cs;    p++;    free( iter );}uint8_t dbus_svc_message_type(  DBusMessage *msg ){    return dbus_message_get_type( msg );}static DBusConnectionState *dbcs_new( DBusConnection *connection ){    DBusConnectionState *dbcs = (DBusConnectionState *) malloc( sizeof(DBusConnectionState) );    if ( dbcs )    {	memset( dbcs, '\0', sizeof( DBusConnectionState ));	dbcs->connection = connection;    }    return(dbcs);}static DBusConnectionTimeout *timeout_new( DBusTimeout *timeout ){    DBusConnectionTimeout *to = (DBusConnectionTimeout *) malloc ( sizeof(DBusConnectionTimeout) );    if( to != 0L )    {	to->to = timeout;	dbus_timeout_set_data(timeout, to, 0L);	if( dbus_timeout_get_enabled(timeout) )	    gettimeofday(&(to->tv),0L);	else	{	    to->tv.tv_sec = 0 ;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?