1.1.2
by Lionel Le Folgoc
Import upstream version 0.3.80 |
1 |
/* $Id: tvm-block-device.c 5216 2008-08-12 08:54:28Z kelnos $ */
|
1
by Yves-Alexis Perez
Import upstream version 0.1.2 |
2 |
/*-
|
1.1.2
by Lionel Le Folgoc
Import upstream version 0.3.80 |
3 |
* Copyright (c) 2007-2008 Benedikt Meurer <benny@xfce.org>.
|
1
by Yves-Alexis Perez
Import upstream version 0.1.2 |
4 |
*
|
5 |
* This program is free software; you can redistribute it and/or modify it
|
|
6 |
* under the terms of the GNU General Public License as published by the Free
|
|
7 |
* Software Foundation; either version 2 of the License, or (at your option)
|
|
8 |
* any later version.
|
|
9 |
*
|
|
10 |
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
11 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
12 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
13 |
* more details.
|
|
14 |
*
|
|
15 |
* You should have received a copy of the GNU General Public License along with
|
|
16 |
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
|
17 |
* Place, Suite 330, Boston, MA 02111-1307 USA
|
|
18 |
*/
|
|
19 |
||
20 |
#ifdef HAVE_CONFIG_H
|
|
21 |
#include <config.h> |
|
22 |
#endif
|
|
23 |
||
24 |
#ifdef HAVE_SYS_TYPES_H
|
|
25 |
#include <sys/types.h> |
|
26 |
#endif
|
|
27 |
#ifdef HAVE_SYS_STAT_H
|
|
28 |
#include <sys/stat.h> |
|
29 |
#endif
|
|
30 |
#ifdef HAVE_SYS_WAIT_H
|
|
31 |
#include <sys/wait.h> |
|
32 |
#endif
|
|
33 |
||
34 |
#ifdef HAVE_MEMORY_H
|
|
35 |
#include <memory.h> |
|
36 |
#endif
|
|
37 |
#include <stdio.h> |
|
38 |
#ifdef HAVE_STRING_H
|
|
39 |
#include <string.h> |
|
40 |
#endif
|
|
41 |
||
42 |
#include <dbus/dbus-glib-lowlevel.h> |
|
43 |
||
44 |
#include <thunar-volman/tvm-block-device.h> |
|
1.1.2
by Lionel Le Folgoc
Import upstream version 0.3.80 |
45 |
#include <thunar-volman/tvm-crypto-volume.h> |
1
by Yves-Alexis Perez
Import upstream version 0.1.2 |
46 |
#include <thunar-volman/tvm-prompt.h> |
47 |
#include <thunar-volman/tvm-run.h> |
|
48 |
||
49 |
||
50 |
||
1.1.1
by Lionel Le Folgoc
Import upstream version 0.2.0 |
51 |
static gboolean tvm_file_test (const gchar *directory, |
52 |
const gchar *filename, |
|
53 |
GFileTest test); |
|
1
by Yves-Alexis Perez
Import upstream version 0.1.2 |
54 |
static gboolean tvm_block_device_autoipod (TvmPreferences *preferences, |
55 |
LibHalContext *context, |
|
56 |
const gchar *udi, |
|
57 |
const gchar *device_file, |
|
58 |
const gchar *mount_point, |
|
59 |
GError **error); |
|
60 |
static gboolean tvm_block_device_autophoto (TvmPreferences *preferences, |
|
61 |
LibHalContext *context, |
|
62 |
const gchar *udi, |
|
63 |
const gchar *device_file, |
|
64 |
const gchar *mount_point, |
|
65 |
GError **error); |
|
66 |
static gboolean tvm_block_device_autorun (TvmPreferences *preferences, |
|
67 |
LibHalContext *context, |
|
68 |
const gchar *udi, |
|
69 |
const gchar *device_file, |
|
70 |
const gchar *mount_point, |
|
71 |
GError **error); |
|
72 |
static gboolean tvm_block_device_mount (TvmPreferences *preferences, |
|
73 |
LibHalContext *context, |
|
74 |
const gchar *udi, |
|
75 |
GError **error); |
|
76 |
static gboolean tvm_block_device_mounted (TvmPreferences *preferences, |
|
77 |
LibHalContext *context, |
|
78 |
const gchar *udi, |
|
79 |
const gchar *device_file, |
|
80 |
const gchar *mount_point, |
|
81 |
GError **error); |
|
82 |
||
83 |
||
84 |
||
85 |
static gboolean |
|
1.1.1
by Lionel Le Folgoc
Import upstream version 0.2.0 |
86 |
tvm_file_test (const gchar *directory, |
87 |
const gchar *filename, |
|
88 |
GFileTest test) |
|
89 |
{
|
|
90 |
const gchar *name; |
|
91 |
gboolean result = FALSE; |
|
92 |
gchar *path; |
|
93 |
GDir *dp; |
|
94 |
||
95 |
/* try to open the specified directory */
|
|
96 |
dp = g_dir_open (directory, 0, NULL); |
|
97 |
if (G_LIKELY (dp != NULL)) |
|
98 |
{
|
|
99 |
while (!result) |
|
100 |
{
|
|
101 |
/* read the next entry */
|
|
102 |
name = g_dir_read_name (dp); |
|
103 |
if (G_UNLIKELY (name == NULL)) |
|
104 |
break; |
|
105 |
||
106 |
/* check if we have a potential match */
|
|
107 |
if (g_ascii_strcasecmp (name, filename) == 0) |
|
108 |
{
|
|
109 |
/* check if test condition met */
|
|
110 |
path = g_build_filename (directory, name, NULL); |
|
111 |
result = g_file_test (path, test); |
|
112 |
g_free (path); |
|
113 |
}
|
|
114 |
}
|
|
115 |
||
116 |
/* cleanup */
|
|
117 |
g_dir_close (dp); |
|
118 |
}
|
|
119 |
||
120 |
return result; |
|
121 |
}
|
|
122 |
||
123 |
||
124 |
||
125 |
static gboolean |
|
1
by Yves-Alexis Perez
Import upstream version 0.1.2 |
126 |
tvm_block_device_autoipod (TvmPreferences *preferences, |
127 |
LibHalContext *context, |
|
128 |
const gchar *udi, |
|
129 |
const gchar *device_file, |
|
130 |
const gchar *mount_point, |
|
131 |
GError **error) |
|
132 |
{
|
|
133 |
gboolean result = FALSE; |
|
134 |
gboolean autoipod; |
|
1.1.2
by Lionel Le Folgoc
Import upstream version 0.3.80 |
135 |
gboolean is_audio_player = FALSE; |
1
by Yves-Alexis Perez
Import upstream version 0.1.2 |
136 |
gchar *autoipod_command; |
137 |
gchar *autophoto_command; |
|
138 |
gchar *storage_udi; |
|
139 |
gchar *path_dcim = NULL; |
|
140 |
gchar *product; |
|
1.1.2
by Lionel Le Folgoc
Import upstream version 0.3.80 |
141 |
gint response = TVM_RESPONSE_NONE; |
1
by Yves-Alexis Perez
Import upstream version 0.1.2 |
142 |
|
143 |
/* check if music players should be handled automatically */
|
|
144 |
g_object_get (G_OBJECT (preferences), "autoipod", &autoipod, "autoipod-command", &autoipod_command, NULL); |
|
145 |
if (G_LIKELY (autoipod && autoipod_command != NULL && *autoipod_command != '\0')) |
|
146 |
{
|
|
147 |
/* determine the storage device UDI */
|
|
148 |
storage_udi = libhal_device_get_property_string (context, udi, "block.storage_device", NULL); |
|
149 |
if (G_LIKELY (storage_udi != NULL)) |
|
150 |
{
|
|
151 |
/* check if we have a portable audio player here */
|
|
152 |
if (libhal_device_query_capability (context, storage_udi, "portable_audio_player", NULL)) |
|
153 |
{
|
|
1.1.2
by Lionel Le Folgoc
Import upstream version 0.3.80 |
154 |
is_audio_player = TRUE; |
1
by Yves-Alexis Perez
Import upstream version 0.1.2 |
155 |
/* check if we have an iPod here */
|
156 |
product = libhal_device_get_property_string (context, storage_udi, "info.product", NULL); |
|
157 |
if (product != NULL && strcmp (product, "iPod") != 0) |
|
158 |
{
|
|
159 |
/* an iPod may have photos */
|
|
160 |
path_dcim = g_build_filename (mount_point, "dcim", NULL); |
|
161 |
if (!g_file_test (path_dcim, G_FILE_TEST_IS_DIR)) |
|
162 |
{
|
|
163 |
/* no photos */
|
|
164 |
g_free (path_dcim); |
|
165 |
path_dcim = NULL; |
|
166 |
}
|
|
167 |
else
|
|
168 |
{
|
|
169 |
/* add the "content.photos" capability to this device */
|
|
170 |
libhal_device_add_capability (context, udi, "content.photos", NULL); |
|
171 |
}
|
|
172 |
}
|
|
173 |
libhal_free_string (product); |
|
174 |
}
|
|
175 |
||
176 |
/* check if autophoto command is specified, else we cannot handle the photos on the iPod anyway */
|
|
177 |
g_object_get (G_OBJECT (preferences), "autophoto-command", &autophoto_command, NULL); |
|
178 |
if (G_UNLIKELY (autophoto_command == NULL || *autophoto_command == '\0')) |
|
179 |
{
|
|
180 |
/* cannot handle photos */
|
|
181 |
g_free (path_dcim); |
|
182 |
path_dcim = NULL; |
|
183 |
}
|
|
184 |
||
185 |
/* iPods can carry both music and photos... */
|
|
186 |
if (G_LIKELY (path_dcim != NULL)) |
|
187 |
{
|
|
188 |
/* ...so we need to prompt what to do */
|
|
189 |
response = tvm_prompt (context, udi, "gnome-dev-ipod", _("Photos and Music"), |
|
190 |
_("Photos were found on your portable music player."), |
|
191 |
_("Would you like to import the photos or manage the music?"), |
|
192 |
_("Ig_nore"), GTK_RESPONSE_CANCEL, |
|
193 |
_("Import _Photos"), TVM_RESPONSE_PHOTOS, |
|
194 |
_("Manage _Music"), TVM_RESPONSE_MUSIC, |
|
195 |
NULL); |
|
196 |
}
|
|
197 |
else
|
|
198 |
{
|
|
199 |
/* no photos, so we can manage only music */
|
|
1.1.2
by Lionel Le Folgoc
Import upstream version 0.3.80 |
200 |
if(is_audio_player) |
201 |
response = TVM_RESPONSE_MUSIC; |
|
1
by Yves-Alexis Perez
Import upstream version 0.1.2 |
202 |
}
|
203 |
||
204 |
/* check what to do */
|
|
205 |
if (response == TVM_RESPONSE_MUSIC) |
|
206 |
{
|
|
207 |
/* run the preferred application to manage music players */
|
|
208 |
result = tvm_run_command (context, udi, autoipod_command, device_file, mount_point, error); |
|
209 |
}
|
|
210 |
else if (response == TVM_RESPONSE_PHOTOS) |
|
211 |
{
|
|
212 |
/* run the preferred application to manage photos */
|
|
213 |
result = tvm_run_command (context, udi, autophoto_command, device_file, mount_point, error); |
|
214 |
}
|
|
215 |
||
216 |
/* cleanup */
|
|
217 |
libhal_free_string (storage_udi); |
|
218 |
g_free (autophoto_command); |
|
219 |
g_free (path_dcim); |
|
220 |
}
|
|
221 |
}
|
|
222 |
||
223 |
/* cleanup */
|
|
224 |
g_free (autoipod_command); |
|
225 |
||
226 |
return result; |
|
227 |
}
|
|
228 |
||
229 |
||
230 |
||
231 |
static gboolean |
|
232 |
tvm_block_device_autophoto (TvmPreferences *preferences, |
|
233 |
LibHalContext *context, |
|
234 |
const gchar *udi, |
|
235 |
const gchar *device_file, |
|
236 |
const gchar *mount_point, |
|
237 |
GError **error) |
|
238 |
{
|
|
239 |
gboolean result = FALSE; |
|
240 |
gboolean autophoto; |
|
241 |
gchar *autophoto_command; |
|
242 |
gint response; |
|
243 |
||
244 |
/* check autophoto support is enabled */
|
|
245 |
g_object_get (G_OBJECT (preferences), "autophoto", &autophoto, "autophoto-command", &autophoto_command, NULL); |
|
246 |
if (G_LIKELY (autophoto && autophoto_command != NULL && *autophoto_command != '\0')) |
|
247 |
{
|
|
248 |
/* check if we have photos on the volume */
|
|
1.1.1
by Lionel Le Folgoc
Import upstream version 0.2.0 |
249 |
if (tvm_file_test (mount_point, "dcim", G_FILE_TEST_IS_DIR)) |
1
by Yves-Alexis Perez
Import upstream version 0.1.2 |
250 |
{
|
251 |
/* add the "content.photos" capability to this device */
|
|
252 |
libhal_device_add_capability (context, udi, "content.photos", NULL); |
|
253 |
||
254 |
/* ask the user whether to import photos */
|
|
255 |
response = tvm_prompt (context, udi, "camera-photo", _("Photo Import"), |
|
256 |
_("A photo card has been detected."), |
|
257 |
_("There are photos on the card. Would you like to add these photos to your album?"), |
|
258 |
_("Ig_nore"), GTK_RESPONSE_CANCEL, |
|
259 |
_("Import _Photos"), TVM_RESPONSE_PHOTOS, |
|
260 |
NULL); |
|
261 |
if (G_LIKELY (response == TVM_RESPONSE_PHOTOS)) |
|
262 |
{
|
|
263 |
/* run the preferred application to manage photos */
|
|
264 |
result = tvm_run_command (context, udi, autophoto_command, device_file, mount_point, error); |
|
265 |
}
|
|
266 |
else
|
|
267 |
{
|
|
268 |
/* pretend that we handled the device */
|
|
269 |
result = TRUE; |
|
270 |
}
|
|
271 |
}
|
|
272 |
}
|
|
273 |
g_free (autophoto_command); |
|
274 |
||
275 |
return result; |
|
276 |
}
|
|
277 |
||
278 |
||
279 |
||
280 |
static gboolean |
|
281 |
tvm_block_device_autorun (TvmPreferences *preferences, |
|
282 |
LibHalContext *context, |
|
283 |
const gchar *udi, |
|
284 |
const gchar *device_file, |
|
285 |
const gchar *mount_point, |
|
286 |
GError **error) |
|
287 |
{
|
|
288 |
struct stat statb_mount_point; |
|
289 |
struct stat statb_autoopen; |
|
290 |
gboolean result; |
|
291 |
gboolean autoopen; |
|
292 |
gboolean autoplay; |
|
293 |
gboolean autorun; |
|
294 |
gchar *autoplay_command; |
|
295 |
gchar *path_autoopen; |
|
296 |
gchar line[1024]; |
|
297 |
gchar *message; |
|
298 |
gchar *wine; |
|
299 |
gchar **argv; |
|
300 |
FILE *fp; |
|
301 |
gint response; |
|
302 |
gint n; |
|
303 |
||
304 |
/* check if autoplay video CDs/DVDs is enabled */
|
|
305 |
g_object_get (G_OBJECT (preferences), "autoplay-video-cd", &autoplay, "autoplay-video-cd-command", &autoplay_command, NULL); |
|
306 |
if (G_LIKELY (autoplay)) |
|
307 |
{
|
|
308 |
/* check if we have a video CD or video DVD here */
|
|
1.1.1
by Lionel Le Folgoc
Import upstream version 0.2.0 |
309 |
if (tvm_file_test (mount_point, "vcd", G_FILE_TEST_IS_DIR) || tvm_file_test (mount_point, "video_ts", G_FILE_TEST_IS_DIR)) |
1
by Yves-Alexis Perez
Import upstream version 0.1.2 |
310 |
{
|
311 |
/* try to spawn the preferred video CD/DVD-Player */
|
|
312 |
result = tvm_run_command (context, udi, autoplay_command, device_file, mount_point, error); |
|
313 |
g_free (autoplay_command); |
|
314 |
return result; |
|
315 |
}
|
|
316 |
}
|
|
317 |
g_free (autoplay_command); |
|
318 |
||
319 |
/* check if autorun support is enabled */
|
|
320 |
g_object_get (G_OBJECT (preferences), "autorun", &autorun, NULL); |
|
321 |
if (G_LIKELY (autorun)) |
|
322 |
{
|
|
323 |
/* "Autostart Files" (Desktop Application Autostart Specification) */
|
|
324 |
static const gchar *AUTORUN[] = { ".autorun", "autorun", "autorun.sh" }; |
|
325 |
for (n = 0; n < G_N_ELEMENTS (AUTORUN); ++n) |
|
326 |
{
|
|
327 |
/* check if one of the autorun files is present and executable */
|
|
1.1.1
by Lionel Le Folgoc
Import upstream version 0.2.0 |
328 |
if (tvm_file_test (mount_point, AUTORUN[n], G_FILE_TEST_IS_EXECUTABLE) |
329 |
&& tvm_file_test (mount_point, AUTORUN[n], G_FILE_TEST_IS_REGULAR)) |
|
1
by Yves-Alexis Perez
Import upstream version 0.1.2 |
330 |
{
|
331 |
/* prompt the user whether to execute this file */
|
|
332 |
message = g_strdup_printf (_("Would you like to allow \"%s\" to run?"), AUTORUN[n]); |
|
333 |
response = tvm_prompt (context, udi, "gnome-fs-executable", _("Auto-Run Confirmation"), |
|
334 |
_("Auto-Run capability detected"), message, |
|
335 |
_("Ig_nore"), GTK_RESPONSE_CANCEL, |
|
336 |
_("_Allow Auto-Run"), TVM_RESPONSE_AUTORUN, |
|
337 |
NULL); |
|
338 |
g_free (message); |
|
339 |
||
340 |
/* check if we should autorun */
|
|
341 |
if (response == TVM_RESPONSE_AUTORUN) |
|
342 |
{
|
|
343 |
/* prepare argv to launch autorun file */
|
|
344 |
argv = g_new (gchar *, 2); |
|
1.1.1
by Lionel Le Folgoc
Import upstream version 0.2.0 |
345 |
argv[0] = g_build_filename (mount_point, AUTORUN[n], NULL); |
1
by Yves-Alexis Perez
Import upstream version 0.1.2 |
346 |
argv[1] = NULL; |
347 |
||
348 |
/* try to launch the autorun file */
|
|
349 |
result = g_spawn_async (mount_point, argv, NULL, 0, NULL, NULL, NULL, error); |
|
350 |
||
351 |
/* cleanup */
|
|
352 |
g_strfreev (argv); |
|
353 |
||
354 |
/* outa here */
|
|
355 |
return result; |
|
356 |
}
|
|
357 |
}
|
|
358 |
}
|
|
359 |
||
360 |
/* check if wine is present */
|
|
361 |
wine = g_find_program_in_path ("wine"); |
|
362 |
if (G_UNLIKELY (wine != NULL)) |
|
363 |
{
|
|
364 |
/* check if we have an autorun.exe file */
|
|
1.1.1
by Lionel Le Folgoc
Import upstream version 0.2.0 |
365 |
if (tvm_file_test (mount_point, "autorun.exe", G_FILE_TEST_IS_REGULAR)) |
1
by Yves-Alexis Perez
Import upstream version 0.1.2 |
366 |
{
|
367 |
/* prompt the user whether to execute this file */
|
|
368 |
message = g_strdup_printf (_("Would you like to allow \"%s\" to run?"), "autorun.exe"); |
|
369 |
response = tvm_prompt (context, udi, "gnome-fs-executable", _("Auto-Run Confirmation"), |
|
370 |
_("Auto-Run capability detected"), message, |
|
371 |
_("Ig_nore"), GTK_RESPONSE_CANCEL, |
|
372 |
_("_Allow Auto-Run"), TVM_RESPONSE_AUTORUN, |
|
373 |
NULL); |
|
374 |
g_free (message); |
|
375 |
||
376 |
/* check if we should autorun */
|
|
377 |
if (response == TVM_RESPONSE_AUTORUN) |
|
378 |
{
|
|
379 |
/* prepare argv to launch autorun.exe file */
|
|
380 |
argv = g_new (gchar *, 3); |
|
381 |
argv[0] = wine; |
|
382 |
argv[1] = g_strdup ("autorun.exe"); |
|
383 |
argv[2] = NULL; |
|
384 |
||
385 |
/* try to launch the autorun.exe file via wine */
|
|
386 |
result = g_spawn_async (mount_point, argv, NULL, 0, NULL, NULL, NULL, error); |
|
387 |
||
388 |
/* cleanup */
|
|
389 |
g_strfreev (argv); |
|
390 |
||
391 |
/* outa here */
|
|
392 |
return result; |
|
393 |
}
|
|
394 |
}
|
|
395 |
}
|
|
396 |
g_free (wine); |
|
397 |
}
|
|
398 |
||
399 |
/* check if autoopen support is enabled */
|
|
400 |
g_object_get (G_OBJECT (preferences), "autoopen", &autoopen, NULL); |
|
401 |
if (G_LIKELY (autoopen)) |
|
402 |
{
|
|
403 |
/* "Autoopen Files" (Desktop Application Autostart Specification) */
|
|
404 |
static const gchar *AUTOOPEN[] = { ".autoopen", "autoopen" }; |
|
405 |
for (n = 0; n < G_N_ELEMENTS (AUTOOPEN); ++n) |
|
406 |
{
|
|
407 |
/* check if one of the autoopen files is present */
|
|
408 |
path_autoopen = g_build_filename (mount_point, AUTOOPEN[n], NULL); |
|
409 |
fp = fopen (path_autoopen, "r"); |
|
410 |
g_free (path_autoopen); |
|
411 |
||
412 |
/* check if the file could be opened */
|
|
413 |
if (G_UNLIKELY (fp != NULL)) |
|
414 |
{
|
|
415 |
/* read the first line of the file (MUST NOT be an absolute path) */
|
|
416 |
if (fgets (line, sizeof (line), fp) != NULL && !g_path_is_absolute (line)) |
|
417 |
{
|
|
418 |
/* determine the absolute path of the file */
|
|
419 |
path_autoopen = g_build_filename (mount_point, line, NULL); |
|
420 |
||
421 |
/* the file must exist on exactly this device */
|
|
422 |
if (stat (mount_point, &statb_mount_point) == 0 && stat (path_autoopen, &statb_autoopen) == 0 |
|
423 |
&& S_ISREG (statb_autoopen.st_mode) && (statb_autoopen.st_mode & 0111) == 0 |
|
424 |
&& (statb_mount_point.st_dev == statb_autoopen.st_dev)) |
|
425 |
{
|
|
426 |
/* prompt the user whether to autoopen this file */
|
|
427 |
message = g_strdup_printf (_("Would you like to open \"%s\"?"), AUTOOPEN[n]); |
|
428 |
response = tvm_prompt (context, udi, "gnome-fs-executable", _("Auto-Open Confirmation"), |
|
429 |
_("Auto-Open capability detected"), message, |
|
430 |
_("Ig_nore"), GTK_RESPONSE_CANCEL, |
|
431 |
_("_Open"), TVM_RESPONSE_AUTOOPEN, |
|
432 |
NULL); |
|
433 |
g_free (message); |
|
434 |
||
435 |
/* check if we should autoopen */
|
|
436 |
if (response == TVM_RESPONSE_AUTOOPEN) |
|
437 |
{
|
|
438 |
/* prepare the command to autoopen */
|
|
439 |
argv = g_new (gchar *, 3); |
|
440 |
argv[0] = g_strdup ("Thunar"); |
|
441 |
argv[1] = path_autoopen; |
|
442 |
argv[2] = NULL; |
|
443 |
||
444 |
/* let Thunar open the file */
|
|
445 |
result = g_spawn_async (mount_point, argv, NULL, 0, NULL, NULL, NULL, error); |
|
446 |
||
447 |
/* cleanup */
|
|
448 |
g_free (path_autoopen); |
|
449 |
fclose (fp); |
|
450 |
return result; |
|
451 |
}
|
|
452 |
}
|
|
453 |
||
454 |
/* cleanup */
|
|
455 |
g_free (path_autoopen); |
|
456 |
}
|
|
457 |
||
458 |
/* close the file handle */
|
|
459 |
fclose (fp); |
|
460 |
}
|
|
461 |
}
|
|
462 |
}
|
|
463 |
||
464 |
/* not handled */
|
|
465 |
return FALSE; |
|
466 |
}
|
|
467 |
||
468 |
||
469 |
||
470 |
static gboolean |
|
471 |
tvm_block_device_mount (TvmPreferences *preferences, |
|
472 |
LibHalContext *context, |
|
473 |
const gchar *udi, |
|
474 |
GError **error) |
|
475 |
{
|
|
476 |
DBusError derror; |
|
477 |
gboolean result = FALSE; |
|
478 |
GSList *mount_points; |
|
479 |
gchar *device_file; |
|
480 |
gchar *argv[4]; |
|
481 |
gint status; |
|
482 |
||
483 |
/* check if we should ignore the volume, if so, pretend that we succeed */
|
|
484 |
if (libhal_device_get_property_bool (context, udi, "volume.ignore", NULL)) |
|
485 |
return TRUE; |
|
486 |
||
487 |
/* generate the command to mount the device */
|
|
488 |
argv[0] = (gchar *) "exo-mount"; |
|
489 |
argv[1] = (gchar *) "--hal-udi"; |
|
490 |
argv[2] = (gchar *) udi; |
|
491 |
argv[3] = NULL; |
|
492 |
||
493 |
/* let exo-mount mount the device */
|
|
494 |
if (!g_spawn_sync (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, &status, error)) |
|
495 |
{
|
|
496 |
/* failed to spawn the exo-mount command */
|
|
497 |
return FALSE; |
|
498 |
}
|
|
499 |
else if (!WIFEXITED (status) || WEXITSTATUS (status) != 0) |
|
500 |
{
|
|
501 |
/* exo-mount failed, but already displayed an error */
|
|
502 |
return TRUE; |
|
503 |
}
|
|
504 |
||
505 |
/* initalize D-Bus error */
|
|
506 |
dbus_error_init (&derror); |
|
507 |
||
508 |
/* successfully mounted the device, determine the device file */
|
|
509 |
device_file = libhal_device_get_property_string (context, udi, "block.device", &derror); |
|
510 |
if (G_UNLIKELY (device_file == NULL)) |
|
511 |
{
|
|
512 |
/* propagate the error */
|
|
513 |
dbus_set_g_error (error, &derror); |
|
514 |
return FALSE; |
|
515 |
}
|
|
516 |
||
517 |
/* determine the active mount point(s) for the device from the kernel */
|
|
518 |
mount_points = exo_mount_point_list_matched (EXO_MOUNT_POINT_MATCH_ACTIVE | EXO_MOUNT_POINT_MATCH_DEVICE, device_file, NULL, NULL, error); |
|
519 |
if (G_LIKELY (mount_points != NULL)) |
|
520 |
{
|
|
521 |
/* try to handled the mounted volume */
|
|
522 |
result = tvm_block_device_mounted (preferences, context, udi, device_file, ((ExoMountPoint *) mount_points->data)->folder, error); |
|
523 |
||
524 |
/* release the mount points */
|
|
525 |
g_slist_foreach (mount_points, (GFunc) exo_mount_point_free, NULL); |
|
526 |
g_slist_free (mount_points); |
|
527 |
}
|
|
528 |
||
529 |
/* release the device file */
|
|
530 |
libhal_free_string (device_file); |
|
531 |
||
532 |
return result; |
|
533 |
}
|
|
534 |
||
535 |
||
536 |
||
537 |
||
538 |
static gboolean |
|
539 |
tvm_block_device_mounted (TvmPreferences *preferences, |
|
540 |
LibHalContext *context, |
|
541 |
const gchar *udi, |
|
542 |
const gchar *device_file, |
|
543 |
const gchar *mount_point, |
|
544 |
GError **error) |
|
545 |
{
|
|
546 |
gboolean autobrowse; |
|
547 |
gboolean result; |
|
548 |
GError *err = NULL; |
|
549 |
||
550 |
/* check if we have a portable media player here */
|
|
551 |
result = tvm_block_device_autoipod (preferences, context, udi, device_file, mount_point, &err); |
|
552 |
if (G_LIKELY (!result && err == NULL)) |
|
553 |
{
|
|
554 |
/* check if we have a digital photo camera here */
|
|
555 |
result = tvm_block_device_autophoto (preferences, context, udi, device_file, mount_point, &err); |
|
556 |
if (G_LIKELY (!result && err == NULL)) |
|
557 |
{
|
|
558 |
/* try autorun (video CD/DVD, autoopen, etc.) first */
|
|
559 |
result = tvm_block_device_autorun (preferences, context, udi, device_file, mount_point, &err); |
|
560 |
if (G_LIKELY (!result && err == NULL)) |
|
561 |
{
|
|
562 |
/* check if we should autobrowse the mount point folder */
|
|
563 |
g_object_get (G_OBJECT (preferences), "autobrowse", &autobrowse, NULL); |
|
564 |
if (G_LIKELY (autobrowse)) |
|
565 |
{
|
|
566 |
/* open the mount point folder in Thunar */
|
|
567 |
result = tvm_run_command (context, udi, "Thunar %m", device_file, mount_point, &err); |
|
568 |
}
|
|
569 |
}
|
|
570 |
}
|
|
571 |
}
|
|
572 |
||
573 |
/* check if we need to propagate an error */
|
|
574 |
if (G_UNLIKELY (err != NULL)) |
|
575 |
{
|
|
576 |
/* propagate the error */
|
|
577 |
g_propagate_error (error, err); |
|
578 |
result = FALSE; |
|
579 |
}
|
|
580 |
||
581 |
return result; |
|
582 |
}
|
|
583 |
||
584 |
||
585 |
||
586 |
/**
|
|
587 |
* tvm_block_device_added:
|
|
588 |
* @preferences : a #TvmPreferences.
|
|
589 |
* @context : a #LibHalContext.
|
|
590 |
* @udi : the HAL device UDI of the newly added block device.
|
|
591 |
* @capability : the capability, which caused this handler to be run.
|
|
592 |
* @error : return location for errors or %NULL.
|
|
593 |
*
|
|
594 |
* See #TvmDeviceCallback for further information.
|
|
595 |
*
|
|
596 |
* Return value: %TRUE if handled, %FALSE if not handled or an
|
|
597 |
* unrecoverable error occurred.
|
|
598 |
**/
|
|
599 |
gboolean
|
|
600 |
tvm_block_device_added (TvmPreferences *preferences, |
|
601 |
LibHalContext *context, |
|
602 |
const gchar *udi, |
|
603 |
const gchar *capability, |
|
604 |
GError **error) |
|
605 |
{
|
|
606 |
DBusError derror; |
|
607 |
gboolean disc_has_audio; |
|
608 |
gboolean disc_has_data; |
|
609 |
gboolean automount; |
|
610 |
gboolean autoplay; |
|
611 |
gboolean is_cdrom; |
|
1.1.1
by Lionel Le Folgoc
Import upstream version 0.2.0 |
612 |
gboolean has_filesystem; |
1.1.2
by Lionel Le Folgoc
Import upstream version 0.3.80 |
613 |
gboolean has_crypto; |
1
by Yves-Alexis Perez
Import upstream version 0.1.2 |
614 |
gchar *storage_udi; |
615 |
gchar *drive_type; |
|
1.1.1
by Lionel Le Folgoc
Import upstream version 0.2.0 |
616 |
gchar *fsusage; |
1
by Yves-Alexis Perez
Import upstream version 0.1.2 |
617 |
gint response; |
618 |
||
619 |
g_return_val_if_fail (exo_hal_udi_validate (udi, -1, NULL), FALSE); |
|
620 |
g_return_val_if_fail (TVM_IS_PREFERENCES (preferences), FALSE); |
|
621 |
g_return_val_if_fail (error == NULL || *error == NULL, FALSE); |
|
622 |
g_return_val_if_fail (capability != NULL, FALSE); |
|
623 |
g_return_val_if_fail (context != NULL, FALSE); |
|
624 |
||
625 |
/* initialize D-Bus error */
|
|
626 |
dbus_error_init (&derror); |
|
627 |
||
628 |
/* verify that we have a mountable volume here */
|
|
629 |
if (!libhal_device_get_property_bool (context, udi, "block.is_volume", &derror)) |
|
630 |
{
|
|
631 |
err0: /* check if we have an error to propagate */ |
|
632 |
if (dbus_error_is_set (&derror)) |
|
633 |
{
|
|
634 |
/* propagate the error */
|
|
635 |
dbus_set_g_error (error, &derror); |
|
636 |
dbus_error_free (&derror); |
|
637 |
}
|
|
638 |
||
639 |
return FALSE; |
|
640 |
}
|
|
641 |
||
642 |
/* determine the HAL UDI of the backing storage device */
|
|
643 |
storage_udi = libhal_device_get_property_string (context, udi, "block.storage_device", &derror); |
|
644 |
if (G_UNLIKELY (storage_udi == NULL)) |
|
645 |
goto err0; |
|
646 |
||
647 |
/* if the partition_table_changed flag is set, we don't want to mount as a partitioning tool might be modifying this device */
|
|
648 |
if (libhal_device_get_property_bool (context, storage_udi, "storage.partition_table_changed", NULL)) |
|
649 |
{
|
|
650 |
err1: libhal_free_string (storage_udi); |
|
651 |
goto err0; |
|
652 |
}
|
|
653 |
||
654 |
/* check if this device supports removable media */
|
|
655 |
if (libhal_device_get_property_bool (context, storage_udi, "storage.removable", NULL)) |
|
656 |
{
|
|
657 |
/* check if the device is locked */
|
|
658 |
if (libhal_device_get_property_bool (context, storage_udi, "info.locked", NULL)) |
|
659 |
{
|
|
660 |
/* pretend that we handled the device */
|
|
661 |
libhal_free_string (storage_udi); |
|
662 |
return TRUE; |
|
663 |
}
|
|
664 |
||
665 |
/* determine the drive type */
|
|
666 |
drive_type = libhal_device_get_property_string (context, storage_udi, "storage.drive_type", &derror); |
|
667 |
if (G_UNLIKELY (drive_type == NULL)) |
|
668 |
goto err1; |
|
669 |
||
670 |
/* check if we have a CD-ROM here */
|
|
671 |
is_cdrom = (strcmp (drive_type, "cdrom") == 0); |
|
672 |
||
673 |
/* we don't need the storage UDI any more */
|
|
674 |
libhal_free_string (storage_udi); |
|
675 |
||
676 |
/* free the drive type */
|
|
677 |
libhal_free_string (drive_type); |
|
678 |
||
679 |
/* CD-ROMs deserve special handling */
|
|
680 |
if (G_LIKELY (is_cdrom)) |
|
681 |
{
|
|
682 |
/* check for blank discs */
|
|
683 |
if (libhal_device_get_property_bool (context, udi, "volume.disc.is_blank", NULL)) |
|
684 |
{
|
|
685 |
/* run the preferred CD-Burner application */
|
|
686 |
return tvm_run_cdburner (preferences, context, udi, error); |
|
687 |
}
|
|
688 |
else
|
|
689 |
{
|
|
690 |
/* check if we have DATA/AUDIO tracks */
|
|
691 |
disc_has_audio = libhal_device_get_property_bool (context, udi, "volume.disc.has_audio", NULL); |
|
692 |
disc_has_data = libhal_device_get_property_bool (context, udi, "volume.disc.has_data", NULL); |
|
693 |
if (G_UNLIKELY (disc_has_audio && disc_has_data)) |
|
694 |
{
|
|
695 |
/* check if we need to prompt the user */
|
|
696 |
g_object_get (G_OBJECT (preferences), "automount-media", &automount, "autoplay-audio-cd", &autoplay, NULL); |
|
697 |
if (G_LIKELY (automount && autoplay)) |
|
698 |
{
|
|
699 |
/* ask what do with the mixed audio/data disc */
|
|
700 |
response = tvm_prompt (context, udi, "gnome-dev-cdrom-audio", _("Audio / Data CD"), |
|
701 |
_("The CD in the drive contains both music and files."), |
|
702 |
_("Would you like to listen to music or browse the files?"), |
|
703 |
_("Ig_nore"), GTK_RESPONSE_CANCEL, |
|
704 |
_("_Browse Files"), TVM_RESPONSE_BROWSE, |
|
705 |
_("_Play CD"), TVM_RESPONSE_PLAY, |
|
706 |
NULL); |
|
707 |
switch (response) |
|
708 |
{
|
|
709 |
case TVM_RESPONSE_PLAY: |
|
710 |
goto autoplay_disc; |
|
711 |
||
712 |
case TVM_RESPONSE_BROWSE: |
|
713 |
goto automount_disc; |
|
714 |
||
715 |
default: |
|
716 |
break; |
|
717 |
}
|
|
718 |
}
|
|
719 |
else if (automount) |
|
720 |
{
|
|
721 |
/* just automount the media */
|
|
722 |
goto automount_disc; |
|
723 |
}
|
|
724 |
else if (autoplay) |
|
725 |
{
|
|
726 |
/* just autoplay the disc */
|
|
727 |
goto autoplay_disc; |
|
728 |
}
|
|
729 |
}
|
|
730 |
else if (G_LIKELY (disc_has_audio)) |
|
731 |
{
|
|
732 |
autoplay_disc: /* run the preferred CD-Player application */ |
|
733 |
return tvm_run_cdplayer (preferences, context, udi, error); |
|
734 |
}
|
|
735 |
else if (G_LIKELY (disc_has_data)) |
|
736 |
{
|
|
737 |
automount_disc: /* check if we should automount removable media */ |
|
738 |
g_object_get (G_OBJECT (preferences), "automount-media", &automount, NULL); |
|
739 |
if (G_LIKELY (automount)) |
|
740 |
{
|
|
741 |
/* try to mount the CD-ROM in the disc */
|
|
742 |
return tvm_block_device_mount (preferences, context, udi, error); |
|
743 |
}
|
|
744 |
}
|
|
745 |
}
|
|
746 |
}
|
|
747 |
}
|
|
748 |
else
|
|
749 |
{
|
|
750 |
/* we don't need the storage UDI any more */
|
|
751 |
libhal_free_string (storage_udi); |
|
752 |
}
|
|
753 |
||
1.1.2
by Lionel Le Folgoc
Import upstream version 0.3.80 |
754 |
/* determine the file system usage of the volume */
|
1.1.1
by Lionel Le Folgoc
Import upstream version 0.2.0 |
755 |
fsusage = libhal_device_get_property_string (context, udi, "volume.fsusage", NULL); |
1.1.2
by Lionel Le Folgoc
Import upstream version 0.3.80 |
756 |
has_crypto = (G_UNLIKELY (fsusage != NULL && strcmp (fsusage, "crypto") == 0)); |
757 |
has_filesystem = (G_LIKELY (fsusage != NULL && strcmp (fsusage, "filesystem") == 0)); |
|
1.1.1
by Lionel Le Folgoc
Import upstream version 0.2.0 |
758 |
libhal_free_string (fsusage); |
1.1.2
by Lionel Le Folgoc
Import upstream version 0.3.80 |
759 |
|
760 |
/* check if we have a crypto volume to setup here */
|
|
761 |
if (G_UNLIKELY (has_crypto)) |
|
762 |
{
|
|
763 |
/* try to setup the crypto volume */
|
|
764 |
return tvm_crypto_volume_setup (preferences, context, udi, error); |
|
765 |
}
|
|
766 |
else if (G_LIKELY (has_filesystem)) |
|
767 |
{
|
|
768 |
/* check if we should automount drives, otherwise, we're done here */
|
|
769 |
g_object_get (G_OBJECT (preferences), "automount-drives", &automount, NULL); |
|
770 |
if (G_UNLIKELY (!automount)) |
|
771 |
return FALSE; |
|
772 |
||
773 |
/* try to mount the block device */
|
|
774 |
return tvm_block_device_mount (preferences, context, udi, error); |
|
775 |
}
|
|
776 |
||
777 |
return FALSE; |
|
1
by Yves-Alexis Perez
Import upstream version 0.1.2 |
778 |
}
|
779 |
||
780 |
||
781 |
||
782 |