static void sighnd_handle_signal(const gint signr) { switch (signr) { case SIGHUP: case SIGINT: case SIGQUIT: mainloop_stop(EXIT_FAILURE); break; case SIGTERM: mainloop_stop(EXIT_SUCCESS); break; default: break; } }
static gboolean server_restart_idle_cb(gpointer data) { (void)data; // QUARANTINE log_debug("@%s", __FUNCTION__); server_restart_id = 0; // terminate - we will be restarted by dbus when our interface // is used by somebody mainloop_stop(); return FALSE; }
static void sighnd_terminate(void) { static int done = 0; switch( ++done ) { case 1: mainloop_stop(); break; case 2: log_crit("Terminating NOW\n"); // fall through default: _exit(1); break; } }
static DBusHandlerResult server_filter(DBusConnection *conn, DBusMessage *msg, void *user_data) { (void)user_data; DBusHandlerResult result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; const char *interface = dbus_message_get_interface(msg); const char *member = dbus_message_get_member(msg); const char *object = dbus_message_get_path(msg); int type = dbus_message_get_type(msg); DBusMessage *rsp = 0; // QUARANTINE log_debug("@%s(%s, %s, %s)", __FUNCTION__, object, interface, member); if( !interface || !member || !object ) { goto cleanup; } if( dbus_message_is_signal(msg, DBUS_INTERFACE_LOCAL, "Disconnected") ) { /* Make a orderly shutdown if we get disconnected from * session bus, so that we do not leave behind defunct * profiledaemon process that might overwrite data saved * by another profile daemon connected to functioning * session bus. */ log_warning("disconnected from session bus - terminating\n"); mainloop_stop(); goto cleanup; } if (!strcmp(interface, "org.freedesktop.DBus.Introspectable") && !strcmp(member, "Introspect") && type == DBUS_MESSAGE_TYPE_METHOD_CALL) { result = DBUS_HANDLER_RESULT_HANDLED; log_info("introspect"); rsp = introspect(msg); if(rsp == 0) rsp = dbus_message_new_error(msg, DBUS_ERROR_FAILED, member); if(rsp != 0) dbus_connection_send(conn, rsp, 0); goto cleanup; } if( !strcmp(interface, PROFILED_INTERFACE) && !strcmp(object, PROFILED_PATH) ) { /* - - - - - - - - - - - - - - - - - - - * * as far as dbus message filtering is * considered handling of PROFILED_INTERFACE * should happen right here * - - - - - - - - - - - - - - - - - - - */ result = DBUS_HANDLER_RESULT_HANDLED; /* - - - - - - - - - - - - - - - - - - - * * handle method_call messages * - - - - - - - - - - - - - - - - - - - */ if( type == DBUS_MESSAGE_TYPE_METHOD_CALL ) { static const struct { const char *member; DBusMessage *(*func)(DBusMessage *); } lut[] = { {PROFILED_GET_PROFILES, server_get_profiles}, {PROFILED_GET_PROFILE, server_get_profile}, {PROFILED_SET_PROFILE, server_set_profile}, {PROFILED_HAS_PROFILE, server_has_profile}, {PROFILED_GET_KEYS, server_get_keys}, {PROFILED_GET_VALUES, server_get_values}, {PROFILED_GET_TYPE, server_get_type}, {PROFILED_GET_VALUE, server_get_value}, {PROFILED_SET_VALUE, server_set_value}, {PROFILED_HAS_VALUE, server_has_value}, {PROFILED_IS_WRITABLE, server_is_writable}, {0,0} }; for( int i = 0; ; ++i ) { if( lut[i].member == 0 ) { log_err("unknown method call: %s\n", member); rsp = dbus_message_new_error(msg, DBUS_ERROR_UNKNOWN_METHOD, member); break; } if( !strcmp(lut[i].member, member) ) { log_info("handling method call: %s\n", member); rsp = lut[i].func(msg); break; } } } /* - - - - - - - - - - - - - - - - - - - * * if no responce message was created * above and the peer expects reply, * create a generic error message * - - - - - - - - - - - - - - - - - - - */ if( rsp == 0 && !dbus_message_get_no_reply(msg) ) { rsp = dbus_message_new_error(msg, DBUS_ERROR_FAILED, member); } /* - - - - - - - - - - - - - - - - - - - * * send responce if we have something * to send * - - - - - - - - - - - - - - - - - - - */ if( rsp != 0 ) { dbus_connection_send(conn, rsp, 0); //dbus_connection_flush(conn); } } cleanup: if( rsp != 0 ) { dbus_message_unref(rsp); } return result; }