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 + -
显示快捷键?