1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 *
3 * Copyright (C) 2007-2010 David Zeuthen <zeuthen@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program 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
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 */
20
21 #include "config.h"
22 #include <glib/gi18n.h>
23
24 #include <gio/gio.h>
25 #include <glib-unix.h>
26
27 #include <blockdev/blockdev.h>
28
29 #include "udiskslogging.h"
30 #include "udisksdaemontypes.h"
31 #include "udisksdaemon.h"
32
33 /* ---------------------------------------------------------------------------------------------------- */
34
35 static GMainLoop *loop = NULL;
36 static gboolean enable_tcrypt = FALSE;
37 static gboolean opt_replace = FALSE;
38 static gboolean opt_no_debug = FALSE;
39 static gboolean opt_debug = FALSE;
40 static gboolean opt_no_sigint = FALSE;
41 static gboolean opt_disable_modules = FALSE;
42 static gboolean opt_force_load_modules = FALSE;
43 static gboolean opt_uninstalled = FALSE;
44 static GOptionEntry opt_entries[] =
45 {
46 {"replace", 'r', 0, G_OPTION_ARG_NONE, &opt_replace, "Replace existing daemon", NULL},
47 {"no-debug", 'n', 0, G_OPTION_ARG_NONE, &opt_no_debug, "Don't print debug information on stdout/stderr (IGNORED, see '--debug')", NULL},
48 {"debug", 'd', 0, G_OPTION_ARG_NONE, &opt_debug, "Print debug information on stdout/stderr", NULL},
49 {"no-sigint", 's', 0, G_OPTION_ARG_NONE, &opt_no_sigint, "Do not handle SIGINT for controlled shutdown", NULL},
50 {"disable-modules", 0, 0, G_OPTION_ARG_NONE, &opt_disable_modules, "Do not load modules even when asked for it", NULL},
51 {"force-load-modules", 0, 0, G_OPTION_ARG_NONE, &opt_force_load_modules, "Activate modules on startup", NULL},
52 {"uninstalled", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_uninstalled, "Load modules from build directory", NULL},
53 {NULL }
54 };
55
56 static UDisksDaemon *the_daemon = NULL;
57
58 static void
on_bus_acquired(GDBusConnection * connection,const gchar * name,gpointer user_data)59 on_bus_acquired (GDBusConnection *connection,
60 const gchar *name,
61 gpointer user_data)
62 {
63 the_daemon = udisks_daemon_new (connection,
64 opt_disable_modules,
65 opt_force_load_modules,
66 opt_uninstalled,
67 enable_tcrypt);
68 udisks_debug ("Connected to the system bus");
69 }
70
71 static void
on_name_lost(GDBusConnection * connection,const gchar * name,gpointer user_data)72 on_name_lost (GDBusConnection *connection,
73 const gchar *name,
74 gpointer user_data)
75 {
76 if (the_daemon == NULL)
77 {
78 udisks_critical ("Failed to connect to the system message bus");
79 }
80 else
81 {
82 udisks_info ("Lost (or failed to acquire) the name %s on the system message bus", name);
83 }
84 g_main_loop_quit (loop);
85 }
86
87 static void
on_name_acquired(GDBusConnection * connection,const gchar * name,gpointer user_data)88 on_name_acquired (GDBusConnection *connection,
89 const gchar *name,
90 gpointer user_data)
91 {
92 udisks_notice ("Acquired the name %s on the system message bus", name);
93 }
94
95 static gboolean
on_sigint(gpointer user_data)96 on_sigint (gpointer user_data)
97 {
98 udisks_info ("Caught SIGINT. Initiating shutdown");
99 g_main_loop_quit (loop);
100 return G_SOURCE_CONTINUE; /* We will manually remove the source using g_source_remove */
101 }
102
103 int
main(int argc,char ** argv)104 main (int argc,
105 char **argv)
106 {
107 GError *error;
108 GOptionContext *opt_context;
109 gint ret;
110 guint name_owner_id;
111 guint sigint_id;
112
113 ret = 1;
114 loop = NULL;
115 opt_context = NULL;
116 name_owner_id = 0;
117 sigint_id = 0;
118
119 /* avoid gvfs (http://bugzilla.gnome.org/show_bug.cgi?id=526454) */
120 if (!g_setenv ("GIO_USE_VFS", "local", TRUE))
121 {
122 g_printerr ("Error setting GIO_USE_GVFS\n");
123 goto out;
124 }
125
126 opt_context = g_option_context_new ("udisks storage daemon");
127 g_option_context_add_main_entries (opt_context, opt_entries, NULL);
128 error = NULL;
129 if (!g_option_context_parse (opt_context, &argc, &argv, &error))
130 {
131 g_printerr ("Error parsing options: %s\n", error->message);
132 g_clear_error (&error);
133 goto out;
134 }
135
136 if (opt_no_debug)
137 {
138 udisks_warning ("The --no-debug option is deprecated and ignored. See '--help'.");
139 }
140 if (opt_debug)
141 {
142 /* tell GLib logging to not throw away DEBUG and INFO messages (for our
143 "udisks" domain) unless already specified somehow by the user */
144 g_setenv("G_MESSAGES_DEBUG", "udisks", FALSE);
145 }
146
147 if (g_getenv ("PATH") == NULL)
148 g_setenv ("PATH", "/usr/bin:/bin:/usr/sbin:/sbin", TRUE);
149
150 udisks_notice ("udisks daemon version %s starting", PACKAGE_VERSION);
151
152 if (! bd_utils_get_linux_version (&error))
153 {
154 udisks_warning ("Failed to retrieve kernel version: %s", error->message);
155 g_clear_error (&error);
156 }
157
158 loop = g_main_loop_new (NULL, FALSE);
159
160 if (!opt_no_sigint)
161 {
162 sigint_id = g_unix_signal_add_full (G_PRIORITY_DEFAULT,
163 SIGINT,
164 on_sigint,
165 NULL, /* user_data */
166 NULL); /* GDestroyNotify */
167 }
168
169 enable_tcrypt = g_file_test ("/etc/udisks2/tcrypt.conf", G_FILE_TEST_IS_REGULAR);
170
171 name_owner_id = g_bus_own_name (G_BUS_TYPE_SYSTEM,
172 "org.freedesktop.UDisks2",
173 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
174 (opt_replace ? G_BUS_NAME_OWNER_FLAGS_REPLACE : 0),
175 on_bus_acquired,
176 on_name_acquired,
177 on_name_lost,
178 NULL,
179 NULL);
180
181
182 udisks_debug ("Entering main event loop");
183
184 g_main_loop_run (loop);
185
186 ret = 0;
187
188 out:
189 if (sigint_id > 0)
190 g_source_remove (sigint_id);
191 if (the_daemon != NULL)
192 g_object_unref (the_daemon);
193 if (name_owner_id != 0)
194 g_bus_unown_name (name_owner_id);
195 if (loop != NULL)
196 g_main_loop_unref (loop);
197 if (opt_context != NULL)
198 g_option_context_free (opt_context);
199
200 udisks_notice ("udisks daemon version %s exiting", PACKAGE_VERSION);
201
202 return ret;
203 }
204