clean spec file
[platform/upstream/ibus.git] / src / ibusshare.c
1 /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
2 /* vim:set et sts=4: */
3 /* ibus - The Input Bus
4  * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
5  * Copyright (C) 2008-2010 Red Hat, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
20  * USA
21  */
22
23 #include "ibusshare.h"
24 #include <glib.h>
25 #include <glib/gstdio.h>
26 #include <glib-object.h>
27 #include <sys/time.h>
28 #include <sys/types.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <ibus.h>
34
35 static gchar *_display = NULL;
36
37 const gchar *
38 ibus_get_local_machine_id (void)
39 {
40     static gchar *machine_id = NULL;
41
42     if (machine_id == NULL) {
43         GError *error = NULL;
44         if (!g_file_get_contents ("/var/lib/dbus/machine-id",
45                                   &machine_id,
46                                   NULL,
47                                   &error) &&
48             !g_file_get_contents ("/etc/machine-id",
49                                   &machine_id,
50                                   NULL,
51                                   NULL)) {
52             g_warning ("Unable to load /var/lib/dbus/machine-id: %s", error->message);
53             g_error_free (error);
54             machine_id = "machine-id";
55         }
56         else {
57             g_strstrip (machine_id);
58         }
59     }
60
61     return machine_id;
62 }
63
64 void
65 ibus_set_display (const gchar *display)
66 {
67     if (_display != NULL)
68         g_free (_display);
69     _display = g_strdup (display);
70 }
71
72 const gchar *
73 ibus_get_user_name (void)
74 {
75     return g_get_user_name ();
76 }
77
78 glong
79 ibus_get_daemon_uid (void)
80 {
81     return getuid ();
82 }
83
84 const gchar *
85 ibus_get_session_id (void)
86 {
87     return g_getenv("IBUS_SESSION_ID");
88 }
89
90 const gchar *
91 ibus_get_socket_path (void)
92 {
93     static gchar *path = NULL;
94
95     if (path == NULL) {
96         gchar *hostname = "unix";
97         gchar *display;
98         gchar *displaynumber = "0";
99         /* gchar *screennumber = "0"; */
100         gchar *p;
101
102         path = g_strdup (g_getenv ("IBUS_ADDRESS_FILE"));
103         if (path != NULL) {
104             return path;
105         }
106
107         if (_display == NULL) {
108             display = g_strdup (g_getenv ("DISPLAY"));
109         }
110         else {
111             display = g_strdup (_display);
112         }
113
114         if (display != NULL) {
115             p = display;
116             hostname = display;
117             for (; *p != ':' && *p != '\0'; p++);
118
119             if (*p == ':') {
120                 *p = '\0';
121                 p++;
122                 displaynumber = p;
123             }
124
125             for (; *p != '.' && *p != '\0'; p++);
126
127             if (*p == '.') {
128                 *p = '\0';
129                 p++;
130                 /* Do not use screennumber
131                  screennumber = p; */
132             }
133         }
134
135         if (hostname[0] == '\0')
136             hostname = "unix";
137
138         p = g_strdup_printf ("%s-%s-%s",
139                              ibus_get_local_machine_id (),
140                              hostname,
141                              displaynumber);
142         path = g_build_filename (g_get_user_config_dir (),
143                                  "ibus",
144                                  "bus",
145                                  p,
146                                  NULL);
147         g_free (p);
148         g_free (display);
149     }
150     return path;
151 }
152
153 gint
154 ibus_get_timeout (void)
155 {
156     /* 6000 ms is the default timeout on the ibus-daemon side (5 sec) plus 1. */
157     static const gint default_timeout = 6000;
158
159     static gint64 timeout = -2;
160     if (timeout == -2) {
161         const gchar *timeout_str = g_getenv ("IBUS_TIMEOUT");
162         if (timeout_str == NULL) {
163             timeout = default_timeout;
164         } else {
165             timeout = g_ascii_strtoll(timeout_str, NULL, 10);
166             if (timeout < -1 || timeout == 0 || timeout > G_MAXINT) {
167                 timeout = default_timeout;
168             }
169         }
170     }
171     return timeout;
172 }
173
174 const gchar *
175 ibus_get_address (void)
176 {
177     static gchar *address = NULL;
178     pid_t pid = -1;
179     static gchar buffer[1024];
180     FILE *pf;
181
182     /* free address */
183     if (address != NULL) {
184         g_free (address);
185         address = NULL;
186     }
187
188     /* get address from env variable */
189     address = g_strdup (g_getenv ("IBUS_ADDRESS"));
190     if (address) {
191         return address;
192     }
193
194     /* read address from ~/.config/ibus/bus/soketfile */
195     pf = fopen (ibus_get_socket_path (), "r");
196     if (pf == NULL) {
197         return NULL;
198     }
199
200     while (!feof (pf)) {
201         gchar *p = buffer;
202         if (fgets (buffer, sizeof (buffer), pf) == NULL)
203             break;
204
205         /* skip comment line */
206         if (p[0] == '#')
207             continue;
208         /* parse IBUS_ADDRESS */
209         if (strncmp (p, "IBUS_ADDRESS=", sizeof ("IBUS_ADDRESS=") - 1) == 0) {
210             address = p + sizeof ("IBUS_ADDRESS=") - 1;
211             for (p = (gchar *)address; *p != '\n' && *p != '\0'; p++);
212             if (*p == '\n')
213                 *p = '\0';
214             address = g_strdup (address);
215             continue;
216         }
217
218         /* parse IBUS_DAEMON_PID */
219         if (strncmp (p, "IBUS_DAEMON_PID=", sizeof ("IBUS_DAEMON_PID=") - 1) == 0) {
220             pid = atoi(p + sizeof ("IBUS_DAEMON_PID=") - 1);
221             continue;
222         }
223
224     }
225     fclose (pf);
226
227     if (pid == -1 || kill (pid, 0) != 0) {
228         return NULL;
229     }
230
231     return address;
232 }
233
234 void
235 ibus_write_address (const gchar *address)
236 {
237     FILE *pf;
238     gchar *path;
239     g_return_if_fail (address != NULL);
240
241     path = g_path_get_dirname (ibus_get_socket_path ());
242     g_mkdir_with_parents (path, 0700);
243     g_free (path);
244
245     g_unlink (ibus_get_socket_path ());
246     pf = fopen (ibus_get_socket_path (), "w");
247     g_return_if_fail (pf != NULL);
248
249     fprintf (pf,
250         "# This file is created by ibus-daemon, please do not modify it\n"
251         "IBUS_ADDRESS=%s\n"
252         "IBUS_DAEMON_PID=%ld\n",
253         address, (glong) getpid ());
254     fclose (pf);
255 }
256
257 void
258 ibus_free_strv (gchar **strv)
259 {
260     gchar **p;
261
262     if (strv == NULL)
263         return;
264
265     for (p = strv; *p != NULL; p++) {
266         g_free (*p);
267     }
268
269     g_free (strv);
270 }
271
272 void
273 ibus_init (void)
274 {
275 #if !GLIB_CHECK_VERSION(2,35,0)
276     g_type_init ();
277 #endif
278     IBUS_ERROR;
279     IBUS_TYPE_TEXT;
280     IBUS_TYPE_ATTRIBUTE;
281     IBUS_TYPE_ATTR_LIST;
282     IBUS_TYPE_LOOKUP_TABLE;
283     IBUS_TYPE_COMPONENT;
284     IBUS_TYPE_ENGINE_DESC;
285     IBUS_TYPE_OBSERVED_PATH;
286     IBUS_TYPE_REGISTRY;
287 }
288
289 static GMainLoop *main_loop = NULL;
290
291 void
292 ibus_main (void)
293 {
294     main_loop = g_main_loop_new (NULL, FALSE);
295
296     g_main_loop_run (main_loop);
297
298     g_main_loop_unref (main_loop);
299     main_loop = NULL;
300 }
301
302 void
303 ibus_quit (void)
304 {
305     if (main_loop) {
306         g_main_loop_quit (main_loop);
307     }
308 }
309
310 static gboolean ibus_log_handler_is_verbose = FALSE;
311 static guint ibus_log_handler_id = 0;
312
313 static void
314 ibus_log_handler (const gchar    *log_domain,
315                   GLogLevelFlags  log_level,
316                   const gchar    *message,
317                   gpointer        user_data)
318 {
319     // In the quiet mode (i.e. not verbose), we'll ignore DEBUG and
320     // WARNING messages.
321     if (!ibus_log_handler_is_verbose &&
322         ((log_level & G_LOG_LEVEL_DEBUG) ||
323          (log_level & G_LOG_LEVEL_WARNING))) {
324         return;
325     }
326     // Add timing info like "17:34:57.680038" (hour, min, sec, microsecond).
327     struct timeval time_val;
328     gettimeofday (&time_val, NULL);
329     struct tm local_time;
330     localtime_r (&time_val.tv_sec, &local_time);
331     char* new_message =
332         g_strdup_printf ("%02d:%02d:%02d.%6d: %s",
333                          local_time.tm_hour,
334                          local_time.tm_min,
335                          local_time.tm_sec,
336                          (int)time_val.tv_usec,
337                          message);
338     g_log_default_handler (log_domain, log_level, new_message, user_data);
339     g_free (new_message);
340 }
341
342 void
343 ibus_set_log_handler (gboolean verbose)
344 {
345     if (ibus_log_handler_id != 0) {
346         g_log_remove_handler (G_LOG_DOMAIN, ibus_log_handler_id);
347     }
348
349     ibus_log_handler_is_verbose = verbose;
350     ibus_log_handler_id = g_log_set_handler (G_LOG_DOMAIN,
351                                              G_LOG_LEVEL_MASK,
352                                              ibus_log_handler,
353                                              NULL);
354 }
355
356 void
357 ibus_unset_log_handler (void)
358 {
359     if (ibus_log_handler_id != 0) {
360         g_log_remove_handler (G_LOG_DOMAIN, ibus_log_handler_id);
361         ibus_log_handler_id = 0;
362     }
363 }