Check current uid during startup.
[platform/upstream/ibus.git] / bus / main.c
1 /* vim:set et sts=4: */
2 /* ibus - The Input Bus
3  * Copyright (C) 2008-2009 Huang Peng <shawn.p.huang@gmail.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.     See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include <unistd.h>
22 #include <sys/types.h>
23 #include <pwd.h>
24 #include <stdlib.h>
25 #include <locale.h>
26 #include "server.h"
27 #include "ibusimpl.h"
28
29 gchar **g_argv = NULL;
30
31 static gboolean daemonize = FALSE;
32 static gboolean single = FALSE;
33 static gboolean xim = FALSE;
34 static gboolean replace = FALSE;
35 static gchar *panel = "default";
36 static gchar *config = "default";
37 static gchar *desktop = "gnome";
38 static gchar *address = "";
39 gboolean g_rescan = FALSE;
40 static gboolean verbose = FALSE;
41
42 static const GOptionEntry entries[] =
43 {
44     { "daemonize", 'd', 0, G_OPTION_ARG_NONE, &daemonize, "run ibus as background process.", NULL },
45     { "single", 's', 0, G_OPTION_ARG_NONE, &single, "do not execute panel and config module.", NULL },
46     { "xim", 'x', 0, G_OPTION_ARG_NONE, &xim, "execute ibus XIM server.", NULL },
47     { "desktop", 'n', 0, G_OPTION_ARG_STRING, &desktop, "specify the name of desktop session. [default=gnome]", "name" },
48     { "panel", 'p', 0, G_OPTION_ARG_STRING, &panel, "specify the cmdline of panel program.", "cmdline" },
49     { "config", 'c', 0, G_OPTION_ARG_STRING, &config, "specify the cmdline of config program.", "cmdline" },
50     { "address", 'a', 0, G_OPTION_ARG_STRING, &address, "specify the address of ibus daemon.", "address" },
51     { "replace", 'r', 0, G_OPTION_ARG_NONE, &replace, "if there is an old ibus-daemon is running, it will be replaced.", NULL },
52     { "re-scan", 't', 0, G_OPTION_ARG_NONE, &g_rescan, "force to re-scan components, and re-create registry cache.", NULL },
53     { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "verbose.", NULL },
54     { NULL },
55 };
56
57 static gboolean
58 execute_cmdline (const gchar *cmdline)
59 {
60     g_assert (cmdline);
61
62     gint argc;
63     gchar **argv;
64     gboolean retval;
65     GError *error;
66
67     error = NULL;
68     if (!g_shell_parse_argv (cmdline, &argc, &argv, &error)) {
69         g_warning ("Can not parse cmdline `%s` exec: %s", cmdline, error->message);
70         g_error_free (error);
71         return FALSE;
72     }
73
74     error = NULL;
75     retval = g_spawn_async (NULL, argv, NULL,
76                             G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
77                             NULL, NULL,
78                             NULL, &error);
79     g_strfreev (argv);
80
81     if (!retval) {
82         g_warning ("Can not execute cmdline `%s`: %s", cmdline, error->message);
83         g_error_free (error);
84         return FALSE;
85     }
86
87     return TRUE;
88 }
89
90 gint
91 main (gint argc, gchar **argv)
92 {
93     GOptionContext *context;
94     BusServer *server;
95     IBusBus *bus;
96
97     GError *error = NULL;
98
99     setlocale (LC_ALL, "");
100
101     context = g_option_context_new ("- ibus daemon");
102
103     g_option_context_add_main_entries (context, entries, "ibus-daemon");
104
105     g_argv = g_strdupv (argv);
106     if (!g_option_context_parse (context, &argc, &argv, &error)) {
107         g_printerr ("Option parsing failed: %s\n", error->message);
108         exit (-1);
109     }
110
111     /* check uid */
112     {
113         gchar *username = ibus_get_user_name ();
114         uid_t uid = getuid ();
115         struct passwd *pwd = getpwuid (uid);
116
117         if (pwd == NULL || strcmp (pwd->pw_name, username) != 0) {
118             g_printerr ("Please run ibus-daemon with login user! Do not run ibus-daemon with sudo or su.\n");
119             exit (-1);
120         }
121     }
122
123     /* daemonize process */
124     if (daemonize) {
125         if (daemon (1, 0) != 0) {
126             g_printerr ("Can not daemonize ibus.\n");
127             exit (-1);
128         }
129     }
130
131     /* create a new process group */
132     setpgrp ();
133
134     g_type_init ();
135
136     /* check if ibus-daemon is running in this session */
137     bus = ibus_bus_new ();
138
139     if (ibus_bus_is_connected (bus)) {
140         if (!replace) {
141             g_printerr ("current session already has an ibus-daemon.\n");
142             exit (-1);
143         }
144         ibus_bus_exit (bus, FALSE);
145         while (ibus_bus_is_connected (bus)) {
146             g_main_context_iteration (NULL, TRUE);
147         }
148     }
149     g_object_unref (bus);
150     bus = NULL;
151
152     /* create ibus server */
153     server = bus_server_get_default ();
154     bus_server_listen (server);
155
156     if (!single) {
157         /* execute config component */
158         if (g_strcmp0 (config, "default") == 0) {
159             IBusComponent *component;
160             component = bus_registry_lookup_component_by_name (BUS_DEFAULT_REGISTRY, IBUS_SERVICE_CONFIG);
161             if (component == NULL || !ibus_component_start (component)) {
162                 g_printerr ("Can not execute default config program\n");
163                 exit (-1);
164             }
165         } else if (g_strcmp0 (config, "disable") != 0 && g_strcmp0 (config, "") != 0) {
166             if (!execute_cmdline (config))
167                 exit (-1);
168         }
169
170         /* execut panel component */
171         if (g_strcmp0 (panel, "default") == 0) {
172             IBusComponent *component;
173             component = bus_registry_lookup_component_by_name (BUS_DEFAULT_REGISTRY, IBUS_SERVICE_PANEL);
174             if (component == NULL || !ibus_component_start (component)) {
175                 g_printerr ("Can not execute default panel program\n");
176                 exit (-1);
177             }
178         } else if (g_strcmp0 (panel, "disable") != 0 && g_strcmp0 (panel, "") != 0) {
179             if (!execute_cmdline (panel))
180                 exit (-1);
181         }
182     }
183
184     /* execute ibus xim server */
185     if (xim) {
186         if (!execute_cmdline (LIBEXECDIR"/ibus-x11 --kill-daemon"))
187             exit (-1);
188     }
189
190     bus_server_run (server);
191
192     return 0;
193 }