const gchar * ibus_get_local_machine_id (void) { static gchar *machine_id = NULL; if (machine_id == NULL) { gchar *id = dbus_get_local_machine_id (); machine_id = g_strdup (id); dbus_free (id); } return machine_id; }
/* Read the machine uuid from file if needed. Returns TRUE if machine_uuid is * set after this function */ static int read_machine_uuid_if_needed (void) { if (machine_uuid != NULL) return TRUE; machine_uuid = dbus_get_local_machine_id (); if (machine_uuid == NULL) return FALSE; verbose ("UID: %s\n", machine_uuid); return TRUE; }
char* _fcitx_get_socket_path() { char* addressFile = NULL; char* machineId = dbus_get_local_machine_id(); asprintf(&addressFile, "%s-%d", machineId, fcitx_utils_get_display_number()); dbus_free(machineId); char* file = NULL; FcitxXDGGetFileUserWithPrefix("dbus", addressFile, NULL, &file); return file; }
/** * Process a message from D-Bus. */ static void cdbus_process(session_t *ps, DBusMessage *msg) { bool success = false; #define cdbus_m_ismethod(method) \ dbus_message_is_method_call(msg, CDBUS_INTERFACE_NAME, method) if (cdbus_m_ismethod("reset")) { ps->reset = true; if (!dbus_message_get_no_reply(msg)) cdbus_reply_bool(ps, msg, true); success = true; } else if (cdbus_m_ismethod("repaint")) { force_repaint(ps); if (!dbus_message_get_no_reply(msg)) cdbus_reply_bool(ps, msg, true); success = true; } else if (cdbus_m_ismethod("list_win")) { success = cdbus_process_list_win(ps, msg); } else if (cdbus_m_ismethod("win_get")) { success = cdbus_process_win_get(ps, msg); } else if (cdbus_m_ismethod("win_set")) { success = cdbus_process_win_set(ps, msg); } else if (cdbus_m_ismethod("find_win")) { success = cdbus_process_find_win(ps, msg); } else if (cdbus_m_ismethod("opts_get")) { success = cdbus_process_opts_get(ps, msg); } else if (cdbus_m_ismethod("opts_set")) { success = cdbus_process_opts_set(ps, msg); } #undef cdbus_m_ismethod else if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Introspectable", "Introspect")) { success = cdbus_process_introspect(ps, msg); } else if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Peer", "Ping")) { cdbus_reply(ps, msg, NULL, NULL); success = true; } else if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Peer", "GetMachineId")) { char *uuid = dbus_get_local_machine_id(); if (uuid) { cdbus_reply_string(ps, msg, uuid); dbus_free(uuid); success = true; } } else if (dbus_message_is_signal(msg, "org.freedesktop.DBus", "NameAcquired") || dbus_message_is_signal(msg, "org.freedesktop.DBus", "NameLost")) { success = true; } else { if (DBUS_MESSAGE_TYPE_ERROR == dbus_message_get_type(msg)) { printf_errf("(): Error message of path \"%s\" " "interface \"%s\", member \"%s\", error \"%s\"", dbus_message_get_path(msg), dbus_message_get_interface(msg), dbus_message_get_member(msg), dbus_message_get_error_name(msg)); } else { printf_errf("(): Illegal message of type \"%s\", path \"%s\" " "interface \"%s\", member \"%s\"", cdbus_repr_msgtype(msg), dbus_message_get_path(msg), dbus_message_get_interface(msg), dbus_message_get_member(msg)); } if (DBUS_MESSAGE_TYPE_METHOD_CALL == dbus_message_get_type(msg) && !dbus_message_get_no_reply(msg)) cdbus_reply_err(ps, msg, CDBUS_ERROR_BADMSG, CDBUS_ERROR_BADMSG_S); success = true; } // If the message could not be processed, and an reply is expected, return // an empty reply. if (!success && DBUS_MESSAGE_TYPE_METHOD_CALL == dbus_message_get_type(msg) && !dbus_message_get_no_reply(msg)) cdbus_reply_err(ps, msg, CDBUS_ERROR_UNKNOWN, CDBUS_ERROR_UNKNOWN_S); // Free the message dbus_message_unref(msg); }
void* DBusCreate(FcitxInstance* instance) { FcitxDBus *dbusmodule = (FcitxDBus*) fcitx_utils_malloc0(sizeof(FcitxDBus)); FcitxAddon* dbusaddon = FcitxAddonsGetAddonByName(FcitxInstanceGetAddons(instance), FCITX_DBUS_NAME); dbusmodule->owner = instance; DBusError err; if (FcitxInstanceIsTryReplace(instance)) { fcitx_utils_launch_tool("fcitx-remote", "-e"); sleep(1); } dbus_threads_init_default(); // first init dbus dbus_error_init(&err); int retry = 0; DBusConnection* conn = NULL; char* servicename = NULL; asprintf(&servicename, "%s-%d", FCITX_DBUS_SERVICE, fcitx_utils_get_display_number()); /* do session dbus initialize */ do { if (!getenv("DISPLAY") && !getenv("DBUS_SESSION_BUS_ADDRESS")) { FcitxLog(WARNING, "Without DISPLAY or DBUS_SESSION_BUS_ADDRESS session bus will not work"); break; } /* try to get session dbus */ while (1) { conn = dbus_bus_get(DBUS_BUS_SESSION, &err); if (dbus_error_is_set(&err)) { FcitxLog(WARNING, "Connection Error (%s)", err.message); dbus_error_free(&err); dbus_error_init(&err); } if (NULL == conn && retry < MAX_RETRY_TIMES) { retry ++; sleep(RETRY_INTERVAL * retry); } else { break; } } if (NULL == conn) { break; } if (!dbus_connection_add_filter(conn, DBusModuleFilter, dbusmodule, NULL)) break; if (!dbus_connection_set_watch_functions(conn, DBusAddWatch, DBusRemoveWatch, NULL, &dbusmodule->watches, NULL)) { FcitxLog(WARNING, "Add Watch Function Error"); dbus_error_free(&err); dbus_error_init(&err); dbus_connection_unref(conn); conn = NULL; break; } /* from here we know dbus connection is successful, now we need to register the service */ dbus_connection_set_exit_on_disconnect(conn, FALSE); dbusmodule->conn = conn; boolean request_retry = false; int replaceCountdown = FcitxInstanceIsTryReplace(instance) ? 3 : 0; FcitxInstanceResetTryReplace(instance); do { request_retry = false; // request a name on the bus int ret = dbus_bus_request_name(conn, servicename, DBUS_NAME_FLAG_DO_NOT_QUEUE, &err); if (dbus_error_is_set(&err)) { FcitxLog(WARNING, "Name Error (%s)", err.message); goto dbus_init_failed; } if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { FcitxLog(WARNING, "DBus Service Already Exists"); if (replaceCountdown > 0) { replaceCountdown --; fcitx_utils_launch_tool("fcitx-remote", "-e"); /* sleep for a while and retry */ sleep(1); request_retry = true; continue; } /* if we know fcitx exists, we should exit. */ dbus_error_free(&err); free(servicename); free(dbusmodule); FcitxInstanceEnd(instance); return NULL; } } while (request_retry); dbus_connection_flush(dbusmodule->conn); } while(0); DBusConnection* privconn = NULL; do { int noPrivateDBus = fcitx_utils_get_boolean_env("FCITX_NO_PRIVATE_DBUS", false); if (noPrivateDBus) break; char* file; FILE* dbusfp = FcitxXDGGetFileWithPrefix("dbus", "daemon.conf", "r", &file); if (dbusfp) { fclose(dbusfp); } else { free(file); file = NULL; } dbusmodule->daemon = DBusLaunch(file); fcitx_utils_free(file); if (dbusmodule->daemon.pid == 0) break; privconn = dbus_connection_open(dbusmodule->daemon.address, &err); if (dbus_error_is_set(&err)) { FcitxLog(ERROR, "Private dbus daemon connection error (%s)", err.message); break; } dbus_bus_register(privconn, &err); if (dbus_error_is_set(&err)) { FcitxLog(ERROR, "Private dbus bus register error (%s)", err.message); break; } int ret = dbus_bus_request_name(privconn, servicename, DBUS_NAME_FLAG_DO_NOT_QUEUE, &err); if (dbus_error_is_set(&err)) { FcitxLog(WARNING, "Private Name Error (%s)", err.message); break; } if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { FcitxLog(ERROR, "Private DBus Service Already Exists, fcitx being hacked?"); break; } if (!dbus_connection_add_filter(privconn, DBusModuleFilter, dbusmodule, NULL)) break; if (!dbus_connection_set_watch_functions(privconn, DBusAddWatch, DBusRemoveWatch, NULL, &dbusmodule->watches, NULL)) { FcitxLog(WARNING, "Add Watch Function Error"); break; } char* addressFile = NULL; char* localMachineId = dbus_get_local_machine_id(); asprintf(&addressFile, "%s-%d", localMachineId, fcitx_utils_get_display_number()); dbus_free(localMachineId); FILE* fp = FcitxXDGGetFileUserWithPrefix("dbus", addressFile, "w", NULL); free(addressFile); if (!fp) break; fprintf(fp, "%s", dbusmodule->daemon.address); fwrite("\0", sizeof(char), 1, fp); pid_t curPid = getpid(); fwrite(&dbusmodule->daemon.pid, sizeof(pid_t), 1, fp); fwrite(&curPid, sizeof(pid_t), 1, fp); fclose(fp); dbusmodule->privconn = privconn; char* command = fcitx_utils_get_fcitx_path_with_filename("bindir", "/fcitx-dbus-watcher"); char* pidstring = NULL; asprintf(&pidstring, "%d", dbusmodule->daemon.pid); char* args[] = { command, dbusmodule->daemon.address, pidstring, NULL }; fcitx_utils_start_process(args); free(command); free(pidstring); } while(0); if (!dbusmodule->privconn) { if (privconn) { dbus_connection_unref(privconn); DBusKill(&dbusmodule->daemon); } } FcitxModuleAddFunction(dbusaddon, DBusGetConnection); FcitxModuleAddFunction(dbusaddon, DBusGetPrivateConnection); dbus_error_free(&err); dbusmodule->serviceName = servicename; return dbusmodule; dbus_init_failed: dbus_error_free(&err); fcitx_utils_free(servicename); if (conn) dbus_connection_unref(conn); DBusKill(&dbusmodule->daemon); fcitx_utils_free(dbusmodule); return NULL; }