1 /***************************************************************************
4 * hal-storage-unmount.c : Unmount wrapper
6 * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 **************************************************************************/
33 #include <glib/gstdio.h>
36 #include <sys/param.h>
37 #include <sys/ucred.h>
38 #include <sys/mount.h>
43 #include <sys/mnttab.h>
44 #include <sys/vfstab.h>
48 #include <sys/types.h>
52 #include <libhal-storage.h>
54 #include <libpolkit.h>
57 #include "hal-storage-shared.h"
63 fprintf (stderr
, "This program should only be started by hald.\n");
68 invalid_unmount_option (const char *option
, const char *uid
)
70 fprintf (stderr
, "org.freedesktop.Hal.Device.Volume.InvalidUnmountOption\n");
71 fprintf (stderr
, "The option '%s' is not allowed for uid=%s\n", option
, uid
);
76 main (int argc
, char *argv
[])
82 LibHalContext
*hal_ctx
= NULL
;
83 DBusConnection
*system_bus
= NULL
;
85 LibPolKitContext
*pol_ctx
= NULL
;
88 char *invoked_by_syscon_name
;
90 char unmount_options
[1024];
96 if (!lock_hal_mtab ()) {
97 unknown_error ("Cannot obtain lock on /media/.hal-mtab");
100 device
= getenv ("HAL_PROP_BLOCK_DEVICE");
104 udi
= getenv ("HAL_PROP_INFO_UDI");
108 invoked_by_uid
= getenv ("HAL_METHOD_INVOKED_BY_UID");
110 invoked_by_syscon_name
= getenv ("HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME");
112 dbus_error_init (&error
);
113 if ((hal_ctx
= libhal_ctx_init_direct (&error
)) == NULL
) {
114 printf ("Cannot connect to hald\n");
115 LIBHAL_FREE_DBUS_ERROR (&error
);
119 dbus_error_init (&error
);
120 system_bus
= dbus_bus_get (DBUS_BUS_SYSTEM
, &error
);
121 if (system_bus
== NULL
) {
122 printf ("Cannot connect to the system bus\n");
123 LIBHAL_FREE_DBUS_ERROR (&error
);
127 pol_ctx
= libpolkit_new_context (system_bus
);
128 if (pol_ctx
== NULL
) {
129 printf ("Cannot get libpolkit context\n");
130 unknown_error ("Cannot get libpolkit context");
134 /* read from stdin */
135 if (strlen (fgets (unmount_options
, sizeof (unmount_options
), stdin
)) > 0)
136 unmount_options
[strlen (unmount_options
) - 1] = '\0';
137 /* validate that input from stdin is UTF-8 */
138 if (!g_utf8_validate (unmount_options
, -1, &end
))
139 unknown_error ("Error validating unmount_options as UTF-8");
141 printf ("unmount_options = '%s'\n", unmount_options
);
144 /* delete any trailing whitespace options from splitting the string */
145 given_options
= g_strsplit (unmount_options
, "\t", 0);
146 for (i
= g_strv_length (given_options
) - 1; i
>= 0; --i
) {
147 if (strlen (given_options
[i
]) > 0)
149 given_options
[i
] = NULL
;
155 /* check unmount options */
156 for (i
= 0; given_options
[i
] != NULL
; i
++) {
157 char *given
= given_options
[i
];
159 if (strcmp (given
, "lazy") == 0) {
161 } else if (strcmp (given
, "force") == 0) {
164 invalid_unmount_option (given
, invoked_by_uid
);
167 g_strfreev (given_options
);
170 volume
= libhal_volume_from_udi (hal_ctx
, udi
);
171 if (volume
== NULL
) {
174 drive
= libhal_drive_from_udi (hal_ctx
, udi
);
178 handle_unmount (hal_ctx
,
182 udi
, NULL
, drive
, device
, invoked_by_uid
,
183 invoked_by_syscon_name
, use_lazy
, use_force
,
188 const char *drive_udi
;
191 drive_udi
= libhal_volume_get_storage_device_udi (volume
);
193 if (drive_udi
== NULL
)
194 unknown_error ("Cannot get drive_udi from volume");
195 drive
= libhal_drive_from_udi (hal_ctx
, drive_udi
);
197 unknown_error ("Cannot get drive from hal");
199 handle_unmount (hal_ctx
,
203 udi
, volume
, drive
, device
, invoked_by_uid
,
204 invoked_by_syscon_name
, use_lazy
, use_force
,