xref: /aosp_15_r20/external/selinux/restorecond/user.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker /*
2*2d543d20SAndroid Build Coastguard Worker  * restorecond
3*2d543d20SAndroid Build Coastguard Worker  *
4*2d543d20SAndroid Build Coastguard Worker  * Copyright (C) 2006-2009 Red Hat
5*2d543d20SAndroid Build Coastguard Worker  * Copyright (C) 2020 Nicolas Iooss
6*2d543d20SAndroid Build Coastguard Worker  * see file 'COPYING' for use and warranty information
7*2d543d20SAndroid Build Coastguard Worker  *
8*2d543d20SAndroid Build Coastguard Worker  * This program is free software; you can redistribute it and/or
9*2d543d20SAndroid Build Coastguard Worker  * modify it under the terms of the GNU General Public License as
10*2d543d20SAndroid Build Coastguard Worker  * published by the Free Software Foundation; either version 2 of
11*2d543d20SAndroid Build Coastguard Worker  * the License, or (at your option) any later version.
12*2d543d20SAndroid Build Coastguard Worker  *
13*2d543d20SAndroid Build Coastguard Worker  * This program is distributed in the hope that it will be useful,
14*2d543d20SAndroid Build Coastguard Worker  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15*2d543d20SAndroid Build Coastguard Worker  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*2d543d20SAndroid Build Coastguard Worker  * GNU General Public License for more details.
17*2d543d20SAndroid Build Coastguard Worker .*
18*2d543d20SAndroid Build Coastguard Worker  * You should have received a copy of the GNU General Public License
19*2d543d20SAndroid Build Coastguard Worker  * along with this program; if not, write to the Free Software
20*2d543d20SAndroid Build Coastguard Worker  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21*2d543d20SAndroid Build Coastguard Worker  * 02111-1307  USA
22*2d543d20SAndroid Build Coastguard Worker  *
23*2d543d20SAndroid Build Coastguard Worker  * Authors:
24*2d543d20SAndroid Build Coastguard Worker  *   Dan Walsh <[email protected]>
25*2d543d20SAndroid Build Coastguard Worker  *   Nicolas Iooss <[email protected]>
26*2d543d20SAndroid Build Coastguard Worker */
27*2d543d20SAndroid Build Coastguard Worker 
28*2d543d20SAndroid Build Coastguard Worker #define _GNU_SOURCE
29*2d543d20SAndroid Build Coastguard Worker #include <sys/inotify.h>
30*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
31*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
32*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
33*2d543d20SAndroid Build Coastguard Worker #include <signal.h>
34*2d543d20SAndroid Build Coastguard Worker #include <string.h>
35*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
36*2d543d20SAndroid Build Coastguard Worker #include <ctype.h>
37*2d543d20SAndroid Build Coastguard Worker #include <sys/file.h>
38*2d543d20SAndroid Build Coastguard Worker #include <sys/types.h>
39*2d543d20SAndroid Build Coastguard Worker #include <sys/stat.h>
40*2d543d20SAndroid Build Coastguard Worker #include <syslog.h>
41*2d543d20SAndroid Build Coastguard Worker #include <limits.h>
42*2d543d20SAndroid Build Coastguard Worker #include <fcntl.h>
43*2d543d20SAndroid Build Coastguard Worker 
44*2d543d20SAndroid Build Coastguard Worker #include <selinux/selinux.h>
45*2d543d20SAndroid Build Coastguard Worker 
46*2d543d20SAndroid Build Coastguard Worker #include "restorecond.h"
47*2d543d20SAndroid Build Coastguard Worker #include "stringslist.h"
48*2d543d20SAndroid Build Coastguard Worker #include <glib.h>
49*2d543d20SAndroid Build Coastguard Worker #include <glib-unix.h>
50*2d543d20SAndroid Build Coastguard Worker 
51*2d543d20SAndroid Build Coastguard Worker static int local_lock_fd = -1;
52*2d543d20SAndroid Build Coastguard Worker 
53*2d543d20SAndroid Build Coastguard Worker #ifdef HAVE_DBUS
54*2d543d20SAndroid Build Coastguard Worker #include <gio/gio.h>
55*2d543d20SAndroid Build Coastguard Worker 
56*2d543d20SAndroid Build Coastguard Worker static const char *DBUS_NAME = "org.selinux.Restorecond";
57*2d543d20SAndroid Build Coastguard Worker 
on_name_acquired(GDBusConnection * connection G_GNUC_UNUSED,const gchar * name,gpointer user_data G_GNUC_UNUSED)58*2d543d20SAndroid Build Coastguard Worker static void on_name_acquired(GDBusConnection *connection G_GNUC_UNUSED,
59*2d543d20SAndroid Build Coastguard Worker 			     const gchar *name,
60*2d543d20SAndroid Build Coastguard Worker 			     gpointer user_data G_GNUC_UNUSED)
61*2d543d20SAndroid Build Coastguard Worker {
62*2d543d20SAndroid Build Coastguard Worker 	if (debug_mode)
63*2d543d20SAndroid Build Coastguard Worker 		g_print("D-Bus name acquired: %s\n", name);
64*2d543d20SAndroid Build Coastguard Worker }
65*2d543d20SAndroid Build Coastguard Worker 
on_name_lost(GDBusConnection * connection G_GNUC_UNUSED,const gchar * name,gpointer user_data)66*2d543d20SAndroid Build Coastguard Worker static void on_name_lost(GDBusConnection *connection G_GNUC_UNUSED,
67*2d543d20SAndroid Build Coastguard Worker 			 const gchar *name,
68*2d543d20SAndroid Build Coastguard Worker 			 gpointer user_data)
69*2d543d20SAndroid Build Coastguard Worker {
70*2d543d20SAndroid Build Coastguard Worker 	/* Exit when the D-Bus connection closes */
71*2d543d20SAndroid Build Coastguard Worker 	GMainLoop *loop = user_data;
72*2d543d20SAndroid Build Coastguard Worker 
73*2d543d20SAndroid Build Coastguard Worker 	if (debug_mode)
74*2d543d20SAndroid Build Coastguard Worker 		g_print("D-Bus name lost (%s), exiting\n", name);
75*2d543d20SAndroid Build Coastguard Worker 	g_main_loop_quit(loop);
76*2d543d20SAndroid Build Coastguard Worker }
77*2d543d20SAndroid Build Coastguard Worker 
78*2d543d20SAndroid Build Coastguard Worker /**
79*2d543d20SAndroid Build Coastguard Worker  * Try starting a D-Bus server on the session bus.
80*2d543d20SAndroid Build Coastguard Worker  * Returns -1 if the connection failed, so that a local server can be launched
81*2d543d20SAndroid Build Coastguard Worker  */
dbus_server(GMainLoop * loop)82*2d543d20SAndroid Build Coastguard Worker static int dbus_server(GMainLoop *loop)
83*2d543d20SAndroid Build Coastguard Worker {
84*2d543d20SAndroid Build Coastguard Worker 	GDBusConnection *bus;
85*2d543d20SAndroid Build Coastguard Worker 	guint client_id;
86*2d543d20SAndroid Build Coastguard Worker 
87*2d543d20SAndroid Build Coastguard Worker 	bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
88*2d543d20SAndroid Build Coastguard Worker 	if (!bus)
89*2d543d20SAndroid Build Coastguard Worker 		return -1;
90*2d543d20SAndroid Build Coastguard Worker 
91*2d543d20SAndroid Build Coastguard Worker 	client_id = g_bus_own_name_on_connection(
92*2d543d20SAndroid Build Coastguard Worker 		bus,
93*2d543d20SAndroid Build Coastguard Worker 		DBUS_NAME,
94*2d543d20SAndroid Build Coastguard Worker 		G_BUS_NAME_OWNER_FLAGS_NONE,
95*2d543d20SAndroid Build Coastguard Worker 		on_name_acquired,
96*2d543d20SAndroid Build Coastguard Worker 		on_name_lost,
97*2d543d20SAndroid Build Coastguard Worker 		loop,
98*2d543d20SAndroid Build Coastguard Worker 		NULL);
99*2d543d20SAndroid Build Coastguard Worker 	g_object_unref(bus);
100*2d543d20SAndroid Build Coastguard Worker 	if (client_id == 0)
101*2d543d20SAndroid Build Coastguard Worker 		return -1;
102*2d543d20SAndroid Build Coastguard Worker 
103*2d543d20SAndroid Build Coastguard Worker 	return 0;
104*2d543d20SAndroid Build Coastguard Worker }
105*2d543d20SAndroid Build Coastguard Worker 
106*2d543d20SAndroid Build Coastguard Worker #endif
107*2d543d20SAndroid Build Coastguard Worker 
108*2d543d20SAndroid Build Coastguard Worker /* size of the event structure, not counting name */
109*2d543d20SAndroid Build Coastguard Worker #define EVENT_SIZE  (sizeof (struct inotify_event))
110*2d543d20SAndroid Build Coastguard Worker /* reasonable guess as to size of 1024 events */
111*2d543d20SAndroid Build Coastguard Worker #define BUF_LEN        (1024 * (EVENT_SIZE + 16))
112*2d543d20SAndroid Build Coastguard Worker 
113*2d543d20SAndroid Build Coastguard Worker static gboolean
io_channel_callback(GIOChannel * source,GIOCondition condition,gpointer data)114*2d543d20SAndroid Build Coastguard Worker io_channel_callback
115*2d543d20SAndroid Build Coastguard Worker  (GIOChannel *source,
116*2d543d20SAndroid Build Coastguard Worker   GIOCondition condition,
117*2d543d20SAndroid Build Coastguard Worker   gpointer data __attribute__((__unused__)))
118*2d543d20SAndroid Build Coastguard Worker {
119*2d543d20SAndroid Build Coastguard Worker 
120*2d543d20SAndroid Build Coastguard Worker   char buffer[BUF_LEN+1];
121*2d543d20SAndroid Build Coastguard Worker   gsize bytes_read;
122*2d543d20SAndroid Build Coastguard Worker   unsigned int i = 0;
123*2d543d20SAndroid Build Coastguard Worker 
124*2d543d20SAndroid Build Coastguard Worker   if (condition & G_IO_IN) {
125*2d543d20SAndroid Build Coastguard Worker     /* Data is available. */
126*2d543d20SAndroid Build Coastguard Worker     g_io_channel_read_chars
127*2d543d20SAndroid Build Coastguard Worker       (source, buffer,
128*2d543d20SAndroid Build Coastguard Worker        sizeof (buffer),
129*2d543d20SAndroid Build Coastguard Worker        &bytes_read, NULL);
130*2d543d20SAndroid Build Coastguard Worker 
131*2d543d20SAndroid Build Coastguard Worker     if (! bytes_read) {
132*2d543d20SAndroid Build Coastguard Worker 	    /* Session/Terminal Ended */
133*2d543d20SAndroid Build Coastguard Worker 	    exit(0);
134*2d543d20SAndroid Build Coastguard Worker     }
135*2d543d20SAndroid Build Coastguard Worker 
136*2d543d20SAndroid Build Coastguard Worker     while (i < bytes_read) {
137*2d543d20SAndroid Build Coastguard Worker 	    struct inotify_event *event;
138*2d543d20SAndroid Build Coastguard Worker 	    event = (struct inotify_event *)&buffer[i];
139*2d543d20SAndroid Build Coastguard Worker 	    if (debug_mode)
140*2d543d20SAndroid Build Coastguard Worker 		    printf("wd=%d mask=%u cookie=%u len=%u\n",
141*2d543d20SAndroid Build Coastguard Worker 			   event->wd, event->mask,
142*2d543d20SAndroid Build Coastguard Worker 			   event->cookie, event->len);
143*2d543d20SAndroid Build Coastguard Worker 	    if (event->len)
144*2d543d20SAndroid Build Coastguard Worker 		    watch_list_find(event->wd, event->name);
145*2d543d20SAndroid Build Coastguard Worker 
146*2d543d20SAndroid Build Coastguard Worker 	    i += EVENT_SIZE + event->len;
147*2d543d20SAndroid Build Coastguard Worker     }
148*2d543d20SAndroid Build Coastguard Worker   }
149*2d543d20SAndroid Build Coastguard Worker 
150*2d543d20SAndroid Build Coastguard Worker   /* An error happened while reading
151*2d543d20SAndroid Build Coastguard Worker      the file. */
152*2d543d20SAndroid Build Coastguard Worker 
153*2d543d20SAndroid Build Coastguard Worker   if (condition & G_IO_NVAL)
154*2d543d20SAndroid Build Coastguard Worker     return FALSE;
155*2d543d20SAndroid Build Coastguard Worker 
156*2d543d20SAndroid Build Coastguard Worker   /* We have reached the end of the
157*2d543d20SAndroid Build Coastguard Worker      file. */
158*2d543d20SAndroid Build Coastguard Worker 
159*2d543d20SAndroid Build Coastguard Worker   if (condition & G_IO_HUP) {
160*2d543d20SAndroid Build Coastguard Worker     g_io_channel_shutdown (source, 0, NULL);
161*2d543d20SAndroid Build Coastguard Worker     exit(0);
162*2d543d20SAndroid Build Coastguard Worker     return FALSE;
163*2d543d20SAndroid Build Coastguard Worker   }
164*2d543d20SAndroid Build Coastguard Worker 
165*2d543d20SAndroid Build Coastguard Worker   /* Returning TRUE will make sure
166*2d543d20SAndroid Build Coastguard Worker      the callback remains associated
167*2d543d20SAndroid Build Coastguard Worker      to the channel. */
168*2d543d20SAndroid Build Coastguard Worker 
169*2d543d20SAndroid Build Coastguard Worker   return TRUE;
170*2d543d20SAndroid Build Coastguard Worker }
171*2d543d20SAndroid Build Coastguard Worker 
start(void)172*2d543d20SAndroid Build Coastguard Worker int start(void) {
173*2d543d20SAndroid Build Coastguard Worker #ifdef HAVE_DBUS
174*2d543d20SAndroid Build Coastguard Worker 	GDBusConnection *bus;
175*2d543d20SAndroid Build Coastguard Worker 	GError *err = NULL;
176*2d543d20SAndroid Build Coastguard Worker 	GVariant *result;
177*2d543d20SAndroid Build Coastguard Worker 
178*2d543d20SAndroid Build Coastguard Worker 	/* Get a connection to the session bus */
179*2d543d20SAndroid Build Coastguard Worker 	bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &err);
180*2d543d20SAndroid Build Coastguard Worker 	if (!bus) {
181*2d543d20SAndroid Build Coastguard Worker 		if (debug_mode)
182*2d543d20SAndroid Build Coastguard Worker 			g_warning("Failed to connect to the D-BUS daemon: %s", err->message);
183*2d543d20SAndroid Build Coastguard Worker 		g_error_free(err);
184*2d543d20SAndroid Build Coastguard Worker 		return 1;
185*2d543d20SAndroid Build Coastguard Worker 	}
186*2d543d20SAndroid Build Coastguard Worker 
187*2d543d20SAndroid Build Coastguard Worker 	/* Start restorecond D-Bus service by pinging its bus name
188*2d543d20SAndroid Build Coastguard Worker 	 *
189*2d543d20SAndroid Build Coastguard Worker 	 * https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-peer
190*2d543d20SAndroid Build Coastguard Worker 	 */
191*2d543d20SAndroid Build Coastguard Worker 	result = g_dbus_connection_call_sync(bus,
192*2d543d20SAndroid Build Coastguard Worker 					     DBUS_NAME, /* bus name */
193*2d543d20SAndroid Build Coastguard Worker 					     "/", /* object path */
194*2d543d20SAndroid Build Coastguard Worker 					     "org.freedesktop.DBus.Peer", /* interface */
195*2d543d20SAndroid Build Coastguard Worker 					     "Ping", /* method */
196*2d543d20SAndroid Build Coastguard Worker 					     NULL, /* parameters */
197*2d543d20SAndroid Build Coastguard Worker 					     NULL, /* reply_type */
198*2d543d20SAndroid Build Coastguard Worker 					     G_DBUS_CALL_FLAGS_NONE,
199*2d543d20SAndroid Build Coastguard Worker 					     -1, /* timeout_msec */
200*2d543d20SAndroid Build Coastguard Worker 					     NULL,
201*2d543d20SAndroid Build Coastguard Worker 					     &err);
202*2d543d20SAndroid Build Coastguard Worker 	if (!result) {
203*2d543d20SAndroid Build Coastguard Worker 		g_object_unref(bus);
204*2d543d20SAndroid Build Coastguard Worker 		if (debug_mode)
205*2d543d20SAndroid Build Coastguard Worker 			g_warning("Failed to start %s: %s", DBUS_NAME, err->message);
206*2d543d20SAndroid Build Coastguard Worker 		g_error_free(err);
207*2d543d20SAndroid Build Coastguard Worker 		return 1;
208*2d543d20SAndroid Build Coastguard Worker 	}
209*2d543d20SAndroid Build Coastguard Worker 	g_object_unref(bus);
210*2d543d20SAndroid Build Coastguard Worker #endif /* HAVE_DBUS */
211*2d543d20SAndroid Build Coastguard Worker 	return 0;
212*2d543d20SAndroid Build Coastguard Worker }
213*2d543d20SAndroid Build Coastguard Worker 
local_server(void)214*2d543d20SAndroid Build Coastguard Worker static int local_server(void) {
215*2d543d20SAndroid Build Coastguard Worker 	// ! dbus, run as local service
216*2d543d20SAndroid Build Coastguard Worker 	char *ptr=NULL;
217*2d543d20SAndroid Build Coastguard Worker 	if (asprintf(&ptr, "%s/.restorecond", homedir) < 0) {
218*2d543d20SAndroid Build Coastguard Worker 		if (debug_mode)
219*2d543d20SAndroid Build Coastguard Worker 			perror("asprintf");
220*2d543d20SAndroid Build Coastguard Worker 		return -1;
221*2d543d20SAndroid Build Coastguard Worker 	}
222*2d543d20SAndroid Build Coastguard Worker 	local_lock_fd = open(ptr, O_CREAT | O_WRONLY | O_NOFOLLOW | O_CLOEXEC, S_IRUSR | S_IWUSR);
223*2d543d20SAndroid Build Coastguard Worker 	if (debug_mode)
224*2d543d20SAndroid Build Coastguard Worker 		g_warning ("Lock file: %s", ptr);
225*2d543d20SAndroid Build Coastguard Worker 
226*2d543d20SAndroid Build Coastguard Worker 	free(ptr);
227*2d543d20SAndroid Build Coastguard Worker 	if (local_lock_fd < 0) {
228*2d543d20SAndroid Build Coastguard Worker 		if (debug_mode)
229*2d543d20SAndroid Build Coastguard Worker 			perror("open");
230*2d543d20SAndroid Build Coastguard Worker 		return -1;
231*2d543d20SAndroid Build Coastguard Worker 	}
232*2d543d20SAndroid Build Coastguard Worker 	if (flock(local_lock_fd, LOCK_EX | LOCK_NB) < 0) {
233*2d543d20SAndroid Build Coastguard Worker 		if (debug_mode)
234*2d543d20SAndroid Build Coastguard Worker 			perror("flock");
235*2d543d20SAndroid Build Coastguard Worker 		close(local_lock_fd);
236*2d543d20SAndroid Build Coastguard Worker 		local_lock_fd = -1;
237*2d543d20SAndroid Build Coastguard Worker 		return -1;
238*2d543d20SAndroid Build Coastguard Worker 	}
239*2d543d20SAndroid Build Coastguard Worker 	/* watch for stdin/terminal going away */
240*2d543d20SAndroid Build Coastguard Worker 	GIOChannel *in = g_io_channel_unix_new(0);
241*2d543d20SAndroid Build Coastguard Worker 	g_io_add_watch_full( in,
242*2d543d20SAndroid Build Coastguard Worker 			     G_PRIORITY_HIGH,
243*2d543d20SAndroid Build Coastguard Worker 			     G_IO_IN|G_IO_ERR|G_IO_HUP,
244*2d543d20SAndroid Build Coastguard Worker 			     io_channel_callback, NULL, NULL);
245*2d543d20SAndroid Build Coastguard Worker 
246*2d543d20SAndroid Build Coastguard Worker 	return 0;
247*2d543d20SAndroid Build Coastguard Worker }
248*2d543d20SAndroid Build Coastguard Worker 
end_local_server(void)249*2d543d20SAndroid Build Coastguard Worker static void end_local_server(void) {
250*2d543d20SAndroid Build Coastguard Worker 	if (local_lock_fd >= 0)
251*2d543d20SAndroid Build Coastguard Worker 		close(local_lock_fd);
252*2d543d20SAndroid Build Coastguard Worker 	local_lock_fd = -1;
253*2d543d20SAndroid Build Coastguard Worker }
254*2d543d20SAndroid Build Coastguard Worker 
sigterm_handler(gpointer user_data)255*2d543d20SAndroid Build Coastguard Worker static int sigterm_handler(gpointer user_data)
256*2d543d20SAndroid Build Coastguard Worker {
257*2d543d20SAndroid Build Coastguard Worker 	GMainLoop *loop = user_data;
258*2d543d20SAndroid Build Coastguard Worker 
259*2d543d20SAndroid Build Coastguard Worker 	if (debug_mode)
260*2d543d20SAndroid Build Coastguard Worker 		g_print("Received SIGTERM, exiting\n");
261*2d543d20SAndroid Build Coastguard Worker 	g_main_loop_quit(loop);
262*2d543d20SAndroid Build Coastguard Worker 	return FALSE;
263*2d543d20SAndroid Build Coastguard Worker }
264*2d543d20SAndroid Build Coastguard Worker 
265*2d543d20SAndroid Build Coastguard Worker 
server(int master_fd,const char * watch_file)266*2d543d20SAndroid Build Coastguard Worker int server(int master_fd, const char *watch_file) {
267*2d543d20SAndroid Build Coastguard Worker 	GMainLoop *loop;
268*2d543d20SAndroid Build Coastguard Worker 
269*2d543d20SAndroid Build Coastguard Worker 	loop = g_main_loop_new (NULL, FALSE);
270*2d543d20SAndroid Build Coastguard Worker 
271*2d543d20SAndroid Build Coastguard Worker #ifdef HAVE_DBUS
272*2d543d20SAndroid Build Coastguard Worker 	if (dbus_server(loop) != 0)
273*2d543d20SAndroid Build Coastguard Worker #endif /* HAVE_DBUS */
274*2d543d20SAndroid Build Coastguard Worker 		if (local_server())
275*2d543d20SAndroid Build Coastguard Worker 			goto end;
276*2d543d20SAndroid Build Coastguard Worker 
277*2d543d20SAndroid Build Coastguard Worker 	read_config(master_fd, watch_file);
278*2d543d20SAndroid Build Coastguard Worker 
279*2d543d20SAndroid Build Coastguard Worker 	if (watch_list_isempty())
280*2d543d20SAndroid Build Coastguard Worker 		goto end;
281*2d543d20SAndroid Build Coastguard Worker 
282*2d543d20SAndroid Build Coastguard Worker 	set_matchpathcon_flags(MATCHPATHCON_NOTRANS);
283*2d543d20SAndroid Build Coastguard Worker 
284*2d543d20SAndroid Build Coastguard Worker 	GIOChannel *c = g_io_channel_unix_new(master_fd);
285*2d543d20SAndroid Build Coastguard Worker 
286*2d543d20SAndroid Build Coastguard Worker 	g_io_add_watch_full(c,
287*2d543d20SAndroid Build Coastguard Worker 			    G_PRIORITY_HIGH,
288*2d543d20SAndroid Build Coastguard Worker 			    G_IO_IN|G_IO_ERR|G_IO_HUP,
289*2d543d20SAndroid Build Coastguard Worker 			    io_channel_callback, NULL, NULL);
290*2d543d20SAndroid Build Coastguard Worker 
291*2d543d20SAndroid Build Coastguard Worker 	/* Handle SIGTERM */
292*2d543d20SAndroid Build Coastguard Worker 	g_unix_signal_add_full(G_PRIORITY_DEFAULT,
293*2d543d20SAndroid Build Coastguard Worker 			       SIGTERM,
294*2d543d20SAndroid Build Coastguard Worker 			       sigterm_handler,
295*2d543d20SAndroid Build Coastguard Worker 			       loop,
296*2d543d20SAndroid Build Coastguard Worker 			       NULL);
297*2d543d20SAndroid Build Coastguard Worker 
298*2d543d20SAndroid Build Coastguard Worker 	g_main_loop_run (loop);
299*2d543d20SAndroid Build Coastguard Worker 
300*2d543d20SAndroid Build Coastguard Worker end:
301*2d543d20SAndroid Build Coastguard Worker 	end_local_server();
302*2d543d20SAndroid Build Coastguard Worker 	g_main_loop_unref (loop);
303*2d543d20SAndroid Build Coastguard Worker 	return 0;
304*2d543d20SAndroid Build Coastguard Worker }
305*2d543d20SAndroid Build Coastguard Worker 
306