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