const gchar * ibus_get_address (void) { static gchar *address = NULL; pid_t pid = -1; static gchar buffer[1024]; FILE *pf; /* free address */ if (address != NULL) { g_free (address); address = NULL; } /* get address from env variable */ address = g_strdup (g_getenv ("IBUS_ADDRESS")); if (address) { return address; } /* read address from ~/.config/ibus/bus/soketfile */ pf = fopen (ibus_get_socket_path (), "r"); if (pf == NULL) { return NULL; } while (!feof (pf)) { gchar *p = buffer; if (fgets (buffer, sizeof (buffer), pf) == NULL) break; /* skip comment line */ if (p[0] == '#') continue; /* parse IBUS_ADDRESS */ if (strncmp (p, "IBUS_ADDRESS=", sizeof ("IBUS_ADDRESS=") - 1) == 0) { address = p + sizeof ("IBUS_ADDRESS=") - 1; for (p = (gchar *)address; *p != '\n' && *p != '\0'; p++); if (*p == '\n') *p = '\0'; address = g_strdup (address); continue; } /* parse IBUS_DAEMON_PID */ if (strncmp (p, "IBUS_DAEMON_PID=", sizeof ("IBUS_DAEMON_PID=") - 1) == 0) { pid = atoi(p + sizeof ("IBUS_DAEMON_PID=") - 1); continue; } } fclose (pf); if (pid == -1 || kill (pid, 0) != 0) { return NULL; } return address; }
static void ibus_bus_init (IBusBus *bus) { struct stat buf; gchar *path; GFile *file; IBusBusPrivate *priv; priv = IBUS_BUS_GET_PRIVATE (bus); priv->config = NULL; priv->connection = NULL; priv->watch_dbus_signal = FALSE; path = g_path_get_dirname (ibus_get_socket_path ()); if (stat (path, &buf) == 0) { if (buf.st_uid != ibus_get_daemon_uid ()) { g_warning ("The owner of %s is not %s!", path, ibus_get_user_name ()); return; } } #if 0 else { if (getuid () == ibus_get_daemon_uid ()) { mkdir (path, 0700); chmod (path, 0700); } } #endif ibus_bus_connect (bus); file = g_file_new_for_path (ibus_get_socket_path ()); priv->monitor = g_file_monitor_file (file, 0, NULL, NULL); g_signal_connect (priv->monitor, "changed", (GCallback) _changed_cb, bus); g_object_unref (file); g_free (path); }
const gchar * ibus_get_address (void) { static gchar *address = NULL; if (address == NULL) { address = g_strdup_printf ( "unix:path=%s", ibus_get_socket_path ()); } return address; }
void ibus_write_address (const gchar *address) { FILE *pf; gchar *path; g_return_if_fail (address != NULL); path = g_path_get_dirname (ibus_get_socket_path ()); g_mkdir_with_parents (path, 0700); g_free (path); g_unlink (ibus_get_socket_path ()); pf = fopen (ibus_get_socket_path (), "w"); g_return_if_fail (pf != NULL); fprintf (pf, "# This file is created by ibus-daemon, please do not modify it\n" "IBUS_ADDRESS=%s\n" "IBUS_DAEMON_PID=%ld\n", address, (glong) getpid ()); fclose (pf); }
gboolean bus_server_listen (BusServer *server) { g_assert (BUS_IS_SERVER (server)); const gchar *mechanisms[] = { "EXTERNAL", NULL }; const gchar *address = "unix:tmpdir=/tmp/"; gboolean retval; #if 0 path = ibus_get_socket_folder (); mkdir (path, 0700); chmod (path, 0700); address = ibus_get_address (); #endif retval = ibus_server_listen (IBUS_SERVER (server), address); #if 0 chmod (ibus_get_socket_path (), 0600); #endif ibus_server_set_auth_mechanisms ((IBusServer *)server, mechanisms); if (!retval) { #if 0 g_printerr ("Can not listen on %s! Please try remove directory %s and run again.", address, path); #else g_printerr ("Can not listen on %s!", address); #endif exit (-1); } ibus_write_address (ibus_server_get_address (IBUS_SERVER (server))); return retval; }
static void ibus_bus_connect (IBusBus *bus) { IBusBusPrivate *priv; priv = IBUS_BUS_GET_PRIVATE (bus); #if 0 socket_path = ibus_get_socket_path (); if (stat (socket_path, &buf) != 0) { g_warning ("Can not get stat from %s!", socket_path); return; } if (buf.st_uid != ibus_get_daemon_uid ()) { g_warning ("The owner of %s is not %s!", socket_path, ibus_get_user_name ()); return; } if (priv->connection != NULL) { ibus_object_destroy ((IBusObject *) priv->connection); } #endif if (ibus_get_address () != NULL) { priv->connection = ibus_connection_open (ibus_get_address ()); } if (priv->connection) { ibus_bus_hello (bus); g_signal_connect (priv->connection, "destroy", (GCallback) _connection_destroy_cb, bus); g_signal_emit (bus, bus_signals[CONNECTED], 0); if (priv->watch_dbus_signal) { ibus_bus_watch_dbus_signal (bus); } } }