Print this page
4833 Remove volrmmount
4845 rm(u)mount don't always print mount/unmount errors
4846 HAL partition names don't match real parition names
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/rmvolmgr/rmm_common.c
+++ new/usr/src/cmd/rmvolmgr/rmm_common.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 - */
21 -/*
20 + *
21 + *
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 + *
25 + * Copyright 2014 Andrew Stormont.
24 26 */
25 27
26 28 #include <stdio.h>
27 29 #include <errno.h>
28 30 #include <string.h>
29 31 #include <strings.h>
30 32 #include <stdarg.h>
31 33 #include <fcntl.h>
32 34 #include <libintl.h>
33 35 #include <stdlib.h>
34 36 #include <unistd.h>
35 37 #include <ctype.h>
36 38 #include <sys/param.h>
37 39 #include <sys/types.h>
38 40 #include <sys/stat.h>
39 41 #include <sys/mnttab.h>
40 42
41 43 #include <dbus/dbus.h>
42 44 #include <dbus/dbus-glib.h>
43 45 #include <dbus/dbus-glib-lowlevel.h>
44 46 #include <libhal.h>
45 47 #include <libhal-storage.h>
46 48
47 49 #include "rmm_common.h"
48 50
49 51 #define RMM_PRINT_DEVICE_WIDTH 20
50 52
51 53 extern int rmm_debug;
52 54
53 55 static const char *action_strings[] = {
54 56 "eject",
55 57 "mount",
56 58 "remount",
57 59 "unmount",
58 60 "clear_mounts",
59 61 "closetray"
60 62 };
61 63
62 64
63 65 LibHalContext *
64 66 rmm_hal_init(LibHalDeviceAdded devadd_cb, LibHalDeviceRemoved devrem_cb,
65 67 LibHalDevicePropertyModified propmod_cb, LibHalDeviceCondition cond_cb,
66 68 DBusError *error, rmm_error_t *rmm_error)
67 69 {
68 70 DBusConnection *dbus_conn;
69 71 LibHalContext *ctx;
70 72 char **devices;
71 73 int nr;
72 74
73 75 dbus_error_init(error);
74 76
75 77 /*
76 78 * setup D-Bus connection
77 79 */
78 80 if (!(dbus_conn = dbus_bus_get(DBUS_BUS_SYSTEM, error))) {
79 81 dprintf("cannot get system bus: %s\n", rmm_strerror(error, -1));
80 82 *rmm_error = RMM_EDBUS_CONNECT;
81 83 return (NULL);
82 84 }
83 85 rmm_dbus_error_free(error);
84 86
85 87 dbus_connection_setup_with_g_main(dbus_conn, NULL);
86 88 dbus_connection_set_exit_on_disconnect(dbus_conn, B_TRUE);
87 89
88 90 if ((ctx = libhal_ctx_new()) == NULL) {
89 91 dprintf("libhal_ctx_new failed");
90 92 *rmm_error = RMM_EHAL_CONNECT;
91 93 return (NULL);
92 94 }
93 95
94 96 libhal_ctx_set_dbus_connection(ctx, dbus_conn);
95 97
96 98 /*
97 99 * register callbacks
98 100 */
99 101 if (devadd_cb != NULL) {
100 102 libhal_ctx_set_device_added(ctx, devadd_cb);
101 103 }
102 104 if (devrem_cb != NULL) {
103 105 libhal_ctx_set_device_removed(ctx, devrem_cb);
104 106 }
105 107 if (propmod_cb != NULL) {
106 108 libhal_ctx_set_device_property_modified(ctx, propmod_cb);
107 109 if (!libhal_device_property_watch_all(ctx, error)) {
108 110 dprintf("property_watch_all failed %s",
109 111 rmm_strerror(error, -1));
110 112 libhal_ctx_free(ctx);
111 113 *rmm_error = RMM_EHAL_CONNECT;
112 114 return (NULL);
113 115 }
114 116 }
115 117 if (cond_cb != NULL) {
116 118 libhal_ctx_set_device_condition(ctx, cond_cb);
117 119 }
118 120
119 121 if (!libhal_ctx_init(ctx, error)) {
120 122 dprintf("libhal_ctx_init failed: %s", rmm_strerror(error, -1));
121 123 libhal_ctx_free(ctx);
122 124 *rmm_error = RMM_EHAL_CONNECT;
123 125 return (NULL);
124 126 }
125 127 rmm_dbus_error_free(error);
126 128
127 129 /*
128 130 * The above functions do not guarantee that HAL is actually running.
129 131 * Check by invoking a method.
130 132 */
131 133 if (!(devices = libhal_get_all_devices(ctx, &nr, error))) {
132 134 dprintf("HAL is not running: %s", rmm_strerror(error, -1));
133 135 libhal_ctx_shutdown(ctx, NULL);
134 136 libhal_ctx_free(ctx);
135 137 *rmm_error = RMM_EHAL_CONNECT;
136 138 return (NULL);
137 139 } else {
138 140 rmm_dbus_error_free(error);
139 141 libhal_free_string_array(devices);
140 142 }
141 143
142 144 return (ctx);
143 145 }
144 146
145 147
146 148 void
147 149 rmm_hal_fini(LibHalContext *hal_ctx)
148 150 {
149 151 DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
150 152
151 153 (void) dbus_connection_unref(dbus_conn);
152 154 (void) libhal_ctx_free(hal_ctx);
153 155 }
154 156
155 157
156 158 /*
157 159 * find volume from any type of name, similar to the old media_findname()
158 160 * returns the LibHalDrive object and a list of LibHalVolume objects.
159 161 */
160 162 LibHalDrive *
161 163 rmm_hal_volume_find(LibHalContext *hal_ctx, const char *name, DBusError *error,
162 164 GSList **volumes)
163 165 {
164 166 LibHalDrive *drive;
165 167 char *p;
166 168 char lastc;
167 169
168 170 *volumes = NULL;
169 171
170 172 /* temporarily remove trailing slash */
171 173 p = (char *)name + strlen(name) - 1;
172 174 if (*p == '/') {
173 175 lastc = *p;
174 176 *p = '\0';
175 177 } else {
176 178 p = NULL;
177 179 }
178 180
179 181 if (name[0] == '/') {
180 182 if (((drive = rmm_hal_volume_findby(hal_ctx,
181 183 "info.udi", name, volumes)) != NULL) ||
182 184 ((drive = rmm_hal_volume_findby(hal_ctx,
183 185 "block.device", name, volumes)) != NULL) ||
184 186 ((drive = rmm_hal_volume_findby(hal_ctx,
185 187 "block.solaris.raw_device", name, volumes)) != NULL) ||
186 188 ((drive = rmm_hal_volume_findby(hal_ctx,
187 189 "volume.mount_point", name, volumes)) != NULL)) {
188 190 goto out;
189 191 } else {
190 192 goto out;
191 193 }
192 194 }
193 195
194 196 /* try volume label */
195 197 if ((drive = rmm_hal_volume_findby(hal_ctx,
196 198 "volume.label", name, volumes)) != NULL) {
197 199 goto out;
198 200 }
199 201
200 202 drive = rmm_hal_volume_findby_nickname(hal_ctx, name, volumes);
201 203
202 204 out:
203 205 if (p != NULL) {
204 206 *p = lastc;
205 207 }
206 208 return (drive);
207 209 }
208 210
209 211 /*
210 212 * find default volume. Returns volume pointer and name in 'name'.
211 213 */
212 214 LibHalDrive *
213 215 rmm_hal_volume_find_default(LibHalContext *hal_ctx, DBusError *error,
214 216 const char **name_out, GSList **volumes)
215 217 {
216 218 LibHalDrive *drive;
217 219 static const char *names[] = { "floppy", "cdrom", "rmdisk" };
218 220 int i;
219 221
220 222 *volumes = NULL;
221 223
222 224 for (i = 0; i < NELEM(names); i++) {
223 225 if ((drive = rmm_hal_volume_findby_nickname(hal_ctx,
224 226 names[i], volumes)) != NULL) {
225 227 /*
226 228 * Skip floppy if it has no media.
227 229 * XXX might want to actually check for media
228 230 * every time instead of relying on volcheck.
229 231 */
230 232 if ((strcmp(names[i], "floppy") != 0) ||
231 233 libhal_device_get_property_bool(hal_ctx,
232 234 libhal_drive_get_udi(drive),
233 235 "storage.removable.media_available", NULL)) {
234 236 *name_out = names[i];
235 237 break;
236 238 }
237 239 }
238 240 rmm_dbus_error_free(error);
239 241 }
240 242
241 243 return (drive);
242 244 }
243 245
244 246 /*
245 247 * find volume by property=value
246 248 * returns the LibHalDrive object and a list of LibHalVolume objects.
247 249 * XXX add support for multiple properties, reduce D-Bus traffic
248 250 */
249 251 LibHalDrive *
250 252 rmm_hal_volume_findby(LibHalContext *hal_ctx, const char *property,
251 253 const char *value, GSList **volumes)
252 254 {
253 255 DBusError error;
254 256 LibHalDrive *drive = NULL;
255 257 LibHalVolume *v = NULL;
256 258 char **udis;
257 259 int num_udis;
258 260 int i;
259 261 int i_drive = -1;
260 262
261 263 *volumes = NULL;
262 264
263 265 dbus_error_init(&error);
264 266
265 267 /* get all devices with property=value */
266 268 if ((udis = libhal_manager_find_device_string_match(hal_ctx, property,
267 269 value, &num_udis, &error)) == NULL) {
268 270 rmm_dbus_error_free(&error);
269 271 return (NULL);
270 272 }
271 273
272 274 /* find volumes and drives among these devices */
273 275 for (i = 0; i < num_udis; i++) {
274 276 rmm_dbus_error_free(&error);
275 277 if (libhal_device_query_capability(hal_ctx, udis[i], "volume",
276 278 &error)) {
277 279 v = libhal_volume_from_udi(hal_ctx, udis[i]);
278 280 if (v != NULL) {
279 281 *volumes = g_slist_prepend(*volumes, v);
280 282 }
281 283 } else if ((*volumes == NULL) &&
282 284 libhal_device_query_capability(hal_ctx, udis[i], "storage",
283 285 &error)) {
284 286 i_drive = i;
285 287 }
286 288 }
287 289
288 290 if (*volumes != NULL) {
289 291 /* used prepend, preserve original order */
290 292 *volumes = g_slist_reverse(*volumes);
291 293
292 294 v = (LibHalVolume *)(*volumes)->data;
293 295 drive = libhal_drive_from_udi(hal_ctx,
294 296 libhal_volume_get_storage_device_udi(v));
295 297 if (drive == NULL) {
296 298 rmm_volumes_free (*volumes);
297 299 *volumes = NULL;
298 300 }
299 301 } else if (i_drive >= 0) {
300 302 drive = libhal_drive_from_udi(hal_ctx, udis[i_drive]);
301 303 }
302 304
303 305 libhal_free_string_array(udis);
304 306 rmm_dbus_error_free(&error);
305 307
306 308 return (drive);
307 309 }
308 310
309 311 static void
310 312 rmm_print_nicknames_one(LibHalDrive *d, LibHalVolume *v,
311 313 const char *device, char **drive_nicknames)
312 314 {
313 315 const char *volume_label = NULL;
314 316 const char *mount_point = NULL;
315 317 boolean_t comma;
316 318 int i;
317 319
318 320 (void) printf("%-*s ", RMM_PRINT_DEVICE_WIDTH, device);
319 321 comma = B_FALSE;
320 322
321 323 if (drive_nicknames != NULL) {
322 324 for (i = 0; drive_nicknames[i] != NULL; i++) {
323 325 (void) printf("%s%s", comma ? "," : "",
324 326 drive_nicknames[i]);
325 327 comma = B_TRUE;
326 328 }
327 329 }
328 330
329 331 if ((v != NULL) &&
330 332 ((volume_label = libhal_volume_get_label(v)) != NULL) &&
331 333 (strlen(volume_label) > 0)) {
332 334 (void) printf("%s%s", comma ? "," : "", volume_label);
333 335 comma = B_TRUE;
334 336 }
335 337
336 338 if ((v != NULL) &&
337 339 ((mount_point = libhal_volume_get_mount_point(v)) != NULL) &&
338 340 (strlen(mount_point) > 0)) {
339 341 (void) printf("%s%s", comma ? "," : "", mount_point);
340 342 comma = B_TRUE;
341 343 }
342 344
343 345 (void) printf("\n");
344 346 }
345 347
346 348 /*
347 349 * print nicknames for each available volume
348 350 *
349 351 * print_mask:
350 352 * RMM_PRINT_MOUNTABLE print only mountable volumes
351 353 * RMM_PRINT_EJECTABLE print volume-less ejectable drives
352 354 */
353 355 void
354 356 rmm_print_volume_nicknames(LibHalContext *hal_ctx, DBusError *error,
355 357 int print_mask)
356 358 {
357 359 char **udis;
358 360 int num_udis;
359 361 GSList *volumes = NULL;
360 362 LibHalDrive *d, *d_tmp;
361 363 LibHalVolume *v;
362 364 const char *device;
363 365 char **nicknames;
364 366 int i;
365 367 GSList *j;
366 368 int nprinted;
367 369
368 370 dbus_error_init(error);
369 371
370 372 if ((udis = libhal_find_device_by_capability(hal_ctx, "storage",
371 373 &num_udis, error)) == NULL) {
372 374 rmm_dbus_error_free(error);
373 375 return;
374 376 }
375 377
376 378 for (i = 0; i < num_udis; i++) {
377 379 if ((d = libhal_drive_from_udi(hal_ctx, udis[i])) == NULL) {
378 380 continue;
379 381 }
380 382
381 383 /* find volumes belonging to this drive */
382 384 if ((d_tmp = rmm_hal_volume_findby(hal_ctx,
383 385 "block.storage_device", udis[i], &volumes)) != NULL) {
384 386 libhal_drive_free(d_tmp);
385 387 }
386 388
387 389 nicknames = libhal_device_get_property_strlist(hal_ctx,
388 390 udis[i], "storage.solaris.nicknames", NULL);
389 391
390 392 nprinted = 0;
391 393 for (j = volumes; j != NULL; j = g_slist_next(j)) {
392 394 v = (LibHalVolume *)(j->data);
393 395
394 396 if ((device = libhal_volume_get_device_file(v)) ==
395 397 NULL) {
396 398 continue;
397 399 }
398 400 if ((print_mask & RMM_PRINT_MOUNTABLE) &&
399 401 (libhal_volume_get_fsusage(v) !=
400 402 LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM)) {
401 403 continue;
402 404 }
403 405
404 406 rmm_print_nicknames_one(d, v, device, nicknames);
405 407 nprinted++;
406 408 }
407 409
408 410 if ((nprinted == 0) &&
409 411 (print_mask & RMM_PRINT_EJECTABLE) &&
410 412 libhal_drive_requires_eject(d) &&
411 413 ((device = libhal_drive_get_device_file(d)) != NULL)) {
412 414 rmm_print_nicknames_one(d, NULL, device, nicknames);
413 415 }
414 416
415 417 libhal_free_string_array(nicknames);
416 418 libhal_drive_free(d);
417 419 rmm_volumes_free(volumes);
418 420 volumes = NULL;
419 421 }
420 422
421 423 libhal_free_string_array(udis);
422 424 }
423 425
424 426 /*
425 427 * find volume by nickname
426 428 * returns the LibHalDrive object and a list of LibHalVolume objects.
427 429 */
428 430 LibHalDrive *
429 431 rmm_hal_volume_findby_nickname(LibHalContext *hal_ctx, const char *name,
430 432 GSList **volumes)
431 433 {
432 434 DBusError error;
433 435 LibHalDrive *drive = NULL;
434 436 LibHalDrive *drive_tmp;
435 437 char **udis;
436 438 int num_udis;
437 439 char **nicknames;
438 440 int i, j;
439 441
440 442 *volumes = NULL;
441 443
442 444 dbus_error_init(&error);
443 445
444 446 if ((udis = libhal_find_device_by_capability(hal_ctx, "storage",
445 447 &num_udis, &error)) == NULL) {
446 448 rmm_dbus_error_free(&error);
447 449 return (NULL);
448 450 }
449 451
450 452 /* find a drive by nickname */
451 453 for (i = 0; (i < num_udis) && (drive == NULL); i++) {
452 454 if ((nicknames = libhal_device_get_property_strlist(hal_ctx,
453 455 udis[i], "storage.solaris.nicknames", &error)) == NULL) {
454 456 rmm_dbus_error_free(&error);
455 457 continue;
456 458 }
457 459 for (j = 0; (nicknames[j] != NULL) && (drive == NULL); j++) {
458 460 if (strcmp(nicknames[j], name) == 0) {
459 461 drive = libhal_drive_from_udi(hal_ctx, udis[i]);
460 462 }
461 463 }
462 464 libhal_free_string_array(nicknames);
463 465 }
464 466 libhal_free_string_array(udis);
465 467
466 468 if (drive != NULL) {
467 469 /* found the drive, now find its volumes */
468 470 if ((drive_tmp = rmm_hal_volume_findby(hal_ctx,
469 471 "block.storage_device", libhal_drive_get_udi(drive),
470 472 volumes)) != NULL) {
471 473 libhal_drive_free(drive_tmp);
472 474 }
473 475 }
474 476
475 477 rmm_dbus_error_free(&error);
476 478
477 479 return (drive);
478 480 }
479 481
480 482 void
481 483 rmm_volumes_free(GSList *volumes)
482 484 {
483 485 GSList *i;
484 486
485 487 for (i = volumes; i != NULL; i = g_slist_next(i)) {
486 488 libhal_volume_free((LibHalVolume *)(i->data));
487 489 }
488 490 g_slist_free(volumes);
489 491 }
490 492
491 493 /*
492 494 * Call HAL's Mount() method on the given device
493 495 */
494 496 boolean_t
495 497 rmm_hal_mount(LibHalContext *hal_ctx, const char *udi,
496 498 char **opts, int num_opts, char *mountpoint, DBusError *error)
497 499 {
498 500 DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
499 501 DBusMessage *dmesg, *reply;
500 502 char *fstype;
501 503
502 504 dprintf("mounting %s...\n", udi);
503 505
504 506 if (!(dmesg = dbus_message_new_method_call("org.freedesktop.Hal", udi,
505 507 "org.freedesktop.Hal.Device.Volume", "Mount"))) {
506 508 dprintf(
507 509 "mount failed for %s: cannot create dbus message\n", udi);
508 510 return (B_FALSE);
509 511 }
510 512
511 513 fstype = "";
512 514 if (mountpoint == NULL) {
513 515 mountpoint = "";
514 516 }
515 517
516 518 if (!dbus_message_append_args(dmesg, DBUS_TYPE_STRING, &mountpoint,
517 519 DBUS_TYPE_STRING, &fstype,
518 520 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &opts, num_opts,
519 521 DBUS_TYPE_INVALID)) {
520 522 dprintf("mount failed for %s: cannot append args\n", udi);
521 523 dbus_message_unref(dmesg);
522 524 return (B_FALSE);
523 525 }
524 526
525 527 dbus_error_init(error);
526 528 if (!(reply = dbus_connection_send_with_reply_and_block(dbus_conn,
527 529 dmesg, RMM_MOUNT_TIMEOUT, error))) {
528 530 dprintf("mount failed for %s: %s\n", udi, error->message);
529 531 dbus_message_unref(dmesg);
530 532 return (B_FALSE);
531 533 }
532 534
533 535 dprintf("mounted %s\n", udi);
534 536
535 537 dbus_message_unref(dmesg);
536 538 dbus_message_unref(reply);
537 539
538 540 rmm_dbus_error_free(error);
539 541
540 542 return (B_TRUE);
541 543 }
542 544
543 545
544 546 /*
545 547 * Call HAL's Unmount() method on the given device
546 548 */
547 549 boolean_t
548 550 rmm_hal_unmount(LibHalContext *hal_ctx, const char *udi, DBusError *error)
549 551 {
550 552 DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
551 553 DBusMessage *dmesg, *reply;
552 554 char **opts = NULL;
553 555
554 556 dprintf("unmounting %s...\n", udi);
555 557
556 558 if (!(dmesg = dbus_message_new_method_call("org.freedesktop.Hal", udi,
557 559 "org.freedesktop.Hal.Device.Volume", "Unmount"))) {
558 560 dprintf(
559 561 "unmount failed %s: cannot create dbus message\n", udi);
560 562 return (B_FALSE);
561 563 }
562 564
563 565 if (!dbus_message_append_args(dmesg, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
564 566 &opts, 0, DBUS_TYPE_INVALID)) {
565 567 dprintf("unmount failed %s: cannot append args\n", udi);
566 568 dbus_message_unref(dmesg);
567 569 return (B_FALSE);
568 570 }
569 571
570 572 dbus_error_init(error);
571 573 if (!(reply = dbus_connection_send_with_reply_and_block(dbus_conn,
572 574 dmesg, RMM_UNMOUNT_TIMEOUT, error))) {
573 575 dprintf("unmount failed for %s: %s\n", udi, error->message);
574 576 dbus_message_unref(dmesg);
575 577 return (B_FALSE);
576 578 }
577 579
578 580 dprintf("unmounted %s\n", udi);
579 581
580 582 dbus_message_unref(dmesg);
581 583 dbus_message_unref(reply);
582 584
583 585 rmm_dbus_error_free(error);
584 586
585 587 return (B_TRUE);
586 588 }
587 589
588 590
589 591 /*
590 592 * Call HAL's Eject() method on the given device
591 593 */
592 594 boolean_t
593 595 rmm_hal_eject(LibHalContext *hal_ctx, const char *udi, DBusError *error)
594 596 {
595 597 DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
596 598 DBusMessage *dmesg, *reply;
597 599 char **options = NULL;
598 600 uint_t num_options = 0;
599 601
600 602 dprintf("ejecting %s...\n", udi);
601 603
602 604 if (!(dmesg = dbus_message_new_method_call("org.freedesktop.Hal", udi,
603 605 "org.freedesktop.Hal.Device.Storage", "Eject"))) {
604 606 dprintf("eject %s: cannot create dbus message\n", udi);
605 607 return (B_FALSE);
606 608 }
607 609
608 610 if (!dbus_message_append_args(dmesg,
609 611 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &options, num_options,
610 612 DBUS_TYPE_INVALID)) {
611 613 dprintf("eject %s: cannot append args to dbus message ", udi);
612 614 dbus_message_unref(dmesg);
613 615 return (B_FALSE);
614 616 }
615 617
616 618 dbus_error_init(error);
617 619 if (!(reply = dbus_connection_send_with_reply_and_block(dbus_conn,
618 620 dmesg, RMM_EJECT_TIMEOUT, error))) {
619 621 dprintf("eject %s: %s\n", udi, error->message);
620 622 dbus_message_unref(dmesg);
621 623 return (B_FALSE);
622 624 }
623 625
624 626 dprintf("ejected %s\n", udi);
625 627
626 628 dbus_message_unref(dmesg);
627 629 dbus_message_unref(reply);
628 630
629 631 rmm_dbus_error_free(error);
630 632
631 633 return (B_TRUE);
632 634 }
633 635
634 636 /*
635 637 * Call HAL's CloseTray() method on the given device
636 638 */
637 639 boolean_t
638 640 rmm_hal_closetray(LibHalContext *hal_ctx, const char *udi, DBusError *error)
639 641 {
640 642 DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
641 643 DBusMessage *dmesg, *reply;
642 644 char **options = NULL;
643 645 uint_t num_options = 0;
644 646
645 647 dprintf("closing tray %s...\n", udi);
646 648
647 649 if (!(dmesg = dbus_message_new_method_call("org.freedesktop.Hal", udi,
648 650 "org.freedesktop.Hal.Device.Storage", "CloseTray"))) {
649 651 dprintf(
650 652 "closetray failed for %s: cannot create dbus message\n",
651 653 udi);
652 654 return (B_FALSE);
653 655 }
654 656
655 657 if (!dbus_message_append_args(dmesg,
656 658 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &options, num_options,
657 659 DBUS_TYPE_INVALID)) {
658 660 dprintf("closetray %s: cannot append args to dbus message ",
659 661 udi);
660 662 dbus_message_unref(dmesg);
661 663 return (B_FALSE);
662 664 }
663 665
664 666 dbus_error_init(error);
665 667 if (!(reply = dbus_connection_send_with_reply_and_block(dbus_conn,
666 668 dmesg, RMM_CLOSETRAY_TIMEOUT, error))) {
667 669 dprintf("closetray failed for %s: %s\n", udi, error->message);
668 670 dbus_message_unref(dmesg);
669 671 return (B_FALSE);
670 672 }
671 673
672 674 dprintf("closetray ok %s\n", udi);
673 675
674 676 dbus_message_unref(dmesg);
675 677 dbus_message_unref(reply);
676 678
677 679 rmm_dbus_error_free(error);
678 680
679 681 return (B_TRUE);
680 682 }
681 683
682 684 /*
683 685 * Call HAL's Rescan() method on the given device
684 686 */
685 687 boolean_t
686 688 rmm_hal_rescan(LibHalContext *hal_ctx, const char *udi, DBusError *error)
687 689 {
688 690 DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
689 691 DBusMessage *dmesg, *reply;
690 692
691 693 dprintf("rescanning %s...\n", udi);
692 694
693 695 if (!(dmesg = dbus_message_new_method_call("org.freedesktop.Hal", udi,
694 696 "org.freedesktop.Hal.Device", "Rescan"))) {
695 697 dprintf("rescan failed for %s: cannot create dbus message\n",
696 698 udi);
697 699 return (B_FALSE);
698 700 }
699 701
700 702 dbus_error_init(error);
701 703 if (!(reply = dbus_connection_send_with_reply_and_block(dbus_conn,
702 704 dmesg, -1, error))) {
703 705 dprintf("rescan failed for %s: %s\n", udi, error->message);
704 706 dbus_message_unref(dmesg);
705 707 return (B_FALSE);
706 708 }
707 709
708 710 dprintf("rescan ok %s\n", udi);
709 711
710 712 dbus_message_unref(dmesg);
711 713 dbus_message_unref(reply);
712 714
713 715 rmm_dbus_error_free(error);
714 716
715 717 return (B_TRUE);
716 718 }
717 719
718 720 boolean_t
719 721 rmm_hal_claim_branch(LibHalContext *hal_ctx, const char *udi)
720 722 {
721 723 DBusError error;
722 724 DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
723 725 DBusMessage *dmesg, *reply;
724 726 const char *claimed_by = "rmvolmgr";
725 727
726 728 dprintf("claiming branch %s...\n", udi);
727 729
728 730 if (!(dmesg = dbus_message_new_method_call("org.freedesktop.Hal",
729 731 "/org/freedesktop/Hal/Manager", "org.freedesktop.Hal.Manager",
730 732 "ClaimBranch"))) {
731 733 dprintf("cannot create dbus message\n");
732 734 return (B_FALSE);
733 735 }
734 736
735 737 if (!dbus_message_append_args(dmesg, DBUS_TYPE_STRING, &udi,
736 738 DBUS_TYPE_STRING, &claimed_by, DBUS_TYPE_INVALID)) {
737 739 dprintf("cannot append args to dbus message\n");
738 740 dbus_message_unref(dmesg);
739 741 return (B_FALSE);
740 742 }
741 743
742 744 dbus_error_init(&error);
743 745 if (!(reply = dbus_connection_send_with_reply_and_block(dbus_conn,
744 746 dmesg, -1, &error))) {
745 747 dprintf("cannot send dbus message\n");
746 748 dbus_message_unref(dmesg);
747 749 rmm_dbus_error_free(&error);
748 750 return (B_FALSE);
749 751 }
750 752
751 753 dprintf("claim branch ok %s\n", udi);
752 754
753 755 dbus_message_unref(dmesg);
754 756 dbus_message_unref(reply);
755 757
756 758 return (B_TRUE);
757 759 }
758 760
759 761 boolean_t
760 762 rmm_hal_unclaim_branch(LibHalContext *hal_ctx, const char *udi)
761 763 {
762 764 DBusError error;
763 765 DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
764 766 DBusMessage *dmesg, *reply;
765 767 const char *claimed_by = "rmvolmgr";
766 768
767 769 dprintf("unclaiming branch %s...\n", udi);
768 770
769 771 if (!(dmesg = dbus_message_new_method_call("org.freedesktop.Hal",
770 772 "/org/freedesktop/Hal/Manager", "org.freedesktop.Hal.Manager",
771 773 "UnclaimBranch"))) {
772 774 dprintf("cannot create dbus message\n");
773 775 return (B_FALSE);
774 776 }
775 777
776 778 if (!dbus_message_append_args(dmesg, DBUS_TYPE_STRING, &udi,
777 779 DBUS_TYPE_STRING, &claimed_by, DBUS_TYPE_INVALID)) {
778 780 dprintf("cannot append args to dbus message\n");
779 781 dbus_message_unref(dmesg);
780 782 return (B_FALSE);
781 783 }
782 784
783 785 dbus_error_init(&error);
784 786 if (!(reply = dbus_connection_send_with_reply_and_block(dbus_conn,
785 787 dmesg, -1, &error))) {
786 788 dprintf("cannot send dbus message\n");
787 789 dbus_message_unref(dmesg);
788 790 rmm_dbus_error_free(&error);
789 791 return (B_FALSE);
790 792 }
791 793
792 794 dprintf("unclaim branch ok %s\n", udi);
793 795
794 796 dbus_message_unref(dmesg);
795 797 dbus_message_unref(reply);
796 798
797 799 return (B_TRUE);
798 800 }
799 801
↓ open down ↓ |
766 lines elided |
↑ open up ↑ |
800 802 static boolean_t
801 803 rmm_action_one(LibHalContext *hal_ctx, const char *name, action_t action,
802 804 const char *dev, const char *udi, LibHalVolume *v,
803 805 char **opts, int num_opts, char *mountpoint)
804 806 {
805 807 char dev_str[MAXPATHLEN];
806 808 char *mountp;
807 809 DBusError error;
808 810 boolean_t ret = B_FALSE;
809 811
812 + dprintf("rmm_action_one %s %s\n", name, action_strings[action]);
813 +
810 814 if (strcmp(name, dev) == 0) {
811 815 (void) snprintf(dev_str, sizeof (dev_str), name);
812 816 } else {
813 817 (void) snprintf(dev_str, sizeof (dev_str), "%s %s", name, dev);
814 818 }
815 819
816 820 dbus_error_init(&error);
817 821
818 822 switch (action) {
819 823 case EJECT:
820 824 ret = rmm_hal_eject(hal_ctx, udi, &error);
821 825 break;
822 826 case INSERT:
823 827 case REMOUNT:
824 - if (libhal_volume_is_mounted(v)) {
825 - goto done;
826 - }
827 828 ret = rmm_hal_mount(hal_ctx, udi,
828 829 opts, num_opts, mountpoint, &error);
829 830 break;
830 831 case UNMOUNT:
831 - if (!libhal_volume_is_mounted(v)) {
832 - goto done;
833 - }
834 832 ret = rmm_hal_unmount(hal_ctx, udi, &error);
835 833 break;
836 834 case CLOSETRAY:
837 835 ret = rmm_hal_closetray(hal_ctx, udi, &error);
838 836 break;
839 837 }
840 838
841 839 if (!ret) {
842 840 (void) fprintf(stderr, gettext("%s of %s failed: %s\n"),
843 841 action_strings[action], dev_str, rmm_strerror(&error, -1));
844 842 goto done;
845 843 }
846 844
847 845 switch (action) {
848 846 case EJECT:
849 847 (void) printf(gettext("%s ejected\n"), dev_str);
850 848 break;
851 849 case INSERT:
852 850 case REMOUNT:
853 851 mountp = rmm_get_mnttab_mount_point(dev);
854 852 if (mountp != NULL) {
855 853 (void) printf(gettext("%s mounted at %s\n"),
856 854 dev_str, mountp);
857 855 free(mountp);
858 856 }
859 857 break;
860 858 case UNMOUNT:
861 859 (void) printf(gettext("%s unmounted\n"), dev_str);
862 860 break;
863 861 case CLOSETRAY:
864 862 (void) printf(gettext("%s tray closed\n"), dev_str);
865 863 break;
866 864 }
867 865
868 866 done:
869 867 rmm_dbus_error_free(&error);
870 868 return (ret);
871 869 }
872 870
873 871 /*
874 872 * top level action routine
875 873 *
876 874 * If non-null 'aa' is passed, it will be used, otherwise a local copy
877 875 * will be created.
878 876 */
879 877 boolean_t
880 878 rmm_action(LibHalContext *hal_ctx, const char *name, action_t action,
881 879 struct action_arg *aap, char **opts, int num_opts, char *mountpoint)
882 880 {
883 881 DBusError error;
884 882 GSList *volumes, *i;
885 883 LibHalDrive *d;
886 884 LibHalVolume *v;
887 885 const char *udi, *d_udi;
888 886 const char *dev, *d_dev;
889 887 struct action_arg aa_local;
890 888 boolean_t ret = B_FALSE;
891 889
892 890 dprintf("rmm_action %s %s\n", name, action_strings[action]);
893 891
894 892 if (aap == NULL) {
895 893 bzero(&aa_local, sizeof (aa_local));
896 894 aap = &aa_local;
897 895 }
898 896
899 897 dbus_error_init(&error);
900 898
901 899 /* find the drive and its volumes */
902 900 d = rmm_hal_volume_find(hal_ctx, name, &error, &volumes);
903 901 rmm_dbus_error_free(&error);
904 902 if (d == NULL) {
905 903 (void) fprintf(stderr, gettext("cannot find '%s'\n"), name);
906 904 return (B_FALSE);
907 905 }
908 906 d_udi = libhal_drive_get_udi(d);
909 907 d_dev = libhal_drive_get_device_file(d);
910 908 if ((d_udi == NULL) || (d_dev == NULL)) {
911 909 goto out;
↓ open down ↓ |
68 lines elided |
↑ open up ↑ |
912 910 }
913 911
914 912 /*
915 913 * For those drives that do not require media eject,
916 914 * EJECT turns into UNMOUNT.
917 915 */
918 916 if ((action == EJECT) && !libhal_drive_requires_eject(d)) {
919 917 action = UNMOUNT;
920 918 }
921 919
920 + /*
921 + * We can't mount or unmount a drive that has no volumes.
922 + * Either the media isn't inserted or it's not formatted
923 + */
924 + if (volumes == NULL && (action != EJECT && action != CLOSETRAY)) {
925 + (void) fprintf(stderr, libhal_drive_requires_eject(d) ?
926 + gettext("no volumes in '%s' to %s\n") :
927 + gettext("no volumes on '%s' to %s\n"),
928 + name, action_strings[action]);
929 + goto out;
930 + }
931 +
922 932 /* per drive action */
923 933 if ((action == EJECT) || (action == CLOSETRAY)) {
924 934 ret = rmm_action_one(hal_ctx, name, action, d_dev, d_udi, NULL,
925 935 opts, num_opts, NULL);
926 936
927 937 if (!ret || (action == CLOSETRAY)) {
928 938 goto out;
929 939 }
930 940 }
931 941
932 942 /* per volume action */
933 943 for (i = volumes; i != NULL; i = g_slist_next(i)) {
934 944 v = (LibHalVolume *)i->data;
935 945 udi = libhal_volume_get_udi(v);
936 946 dev = libhal_volume_get_device_file(v);
937 947
938 948 if ((udi == NULL) || (dev == NULL)) {
939 949 continue;
940 950 }
941 951 if (aap == &aa_local) {
942 952 if (!rmm_volume_aa_from_prop(hal_ctx, udi, v, aap)) {
943 953 dprintf("rmm_volume_aa_from_prop failed %s\n",
944 954 udi);
945 955 continue;
946 956 }
947 957 }
948 958 aap->aa_action = action;
949 959
950 960 /* ejected above, just need postprocess */
951 961 if (action != EJECT) {
952 962 ret = rmm_action_one(hal_ctx, name, action, dev, udi, v,
953 963 opts, num_opts, mountpoint);
954 964 }
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
955 965 if (ret) {
956 966 (void) vold_postprocess(hal_ctx, udi, aap);
957 967 }
958 968
959 969 if (aap == &aa_local) {
960 970 rmm_volume_aa_free(aap);
961 971 }
962 972 }
963 973
964 974 out:
965 - rmm_volumes_free(volumes);
966 - libhal_drive_free(d);
975 + if (volumes != NULL)
976 + rmm_volumes_free(volumes);
977 + if (d != NULL)
978 + libhal_drive_free(d);
967 979
968 980 return (ret);
969 981 }
970 982
971 983
972 984 /*
973 985 * rescan by name
974 986 * if name is NULL, rescan all drives
975 987 */
976 988 boolean_t
977 989 rmm_rescan(LibHalContext *hal_ctx, const char *name, boolean_t query)
978 990 {
979 991 DBusError error;
980 992 GSList *volumes;
981 993 LibHalDrive *drive = NULL;
982 994 const char *drive_udi;
983 995 char **udis;
984 996 int num_udis;
985 997 char *nickname;
986 998 char **nicks = NULL;
987 999 boolean_t do_free_udis = FALSE;
988 1000 int i;
989 1001 boolean_t ret = B_FALSE;
990 1002
991 1003 dprintf("rmm_rescan %s\n", name != NULL ? name : "all");
992 1004
993 1005 dbus_error_init(&error);
994 1006
995 1007 if (name != NULL) {
996 1008 if ((drive = rmm_hal_volume_find(hal_ctx, name, &error,
997 1009 &volumes)) == NULL) {
998 1010 rmm_dbus_error_free(&error);
999 1011 (void) fprintf(stderr,
1000 1012 gettext("cannot find '%s'\n"), name);
1001 1013 return (B_FALSE);
1002 1014 }
1003 1015 rmm_dbus_error_free(&error);
1004 1016 g_slist_free(volumes);
1005 1017
1006 1018 drive_udi = libhal_drive_get_udi(drive);
1007 1019 udis = (char **)&drive_udi;
1008 1020 num_udis = 1;
1009 1021 } else {
1010 1022 if ((udis = libhal_find_device_by_capability(hal_ctx,
1011 1023 "storage", &num_udis, &error)) == NULL) {
1012 1024 rmm_dbus_error_free(&error);
1013 1025 return (B_TRUE);
1014 1026 }
1015 1027 rmm_dbus_error_free(&error);
1016 1028 do_free_udis = TRUE;
1017 1029 }
1018 1030
1019 1031 for (i = 0; i < num_udis; i++) {
1020 1032 if (name == NULL) {
1021 1033 nicks = libhal_device_get_property_strlist(hal_ctx,
1022 1034 udis[i], "storage.solaris.nicknames", NULL);
1023 1035 if (nicks != NULL) {
1024 1036 nickname = nicks[0];
1025 1037 } else {
1026 1038 nickname = "";
1027 1039 }
1028 1040 }
1029 1041 if (!(ret = rmm_hal_rescan(hal_ctx, udis[i], &error))) {
1030 1042 (void) fprintf(stderr,
1031 1043 gettext("rescan of %s failed: %s\n"),
1032 1044 name ? name : nickname,
1033 1045 rmm_strerror(&error, -1));
1034 1046 libhal_free_string_array(nicks);
1035 1047 continue;
1036 1048 }
1037 1049 if (query) {
1038 1050 ret = libhal_device_get_property_bool(hal_ctx, udis[i],
1039 1051 "storage.removable.media_available", NULL);
1040 1052 if (ret) {
1041 1053 printf(gettext("%s is available\n"),
1042 1054 name ? name : nickname);
1043 1055 } else {
1044 1056 printf(gettext("%s is not available\n"),
1045 1057 name ? name : nickname);
1046 1058 }
1047 1059 }
1048 1060 libhal_free_string_array(nicks);
1049 1061 }
1050 1062
1051 1063 if (drive != NULL) {
1052 1064 libhal_drive_free(drive);
1053 1065 }
1054 1066 if (do_free_udis) {
1055 1067 libhal_free_string_array(udis);
1056 1068 }
1057 1069
1058 1070 return (ret);
1059 1071 }
1060 1072
1061 1073
1062 1074 /*
1063 1075 * set action_arg from volume properties
1064 1076 */
1065 1077 boolean_t
1066 1078 rmm_volume_aa_from_prop(LibHalContext *hal_ctx, const char *udi_arg,
1067 1079 LibHalVolume *volume_arg, struct action_arg *aap)
1068 1080 {
1069 1081 LibHalVolume *volume = volume_arg;
1070 1082 const char *udi = udi_arg;
1071 1083 const char *drive_udi;
1072 1084 char *volume_label;
1073 1085 char *mountpoint;
1074 1086 int len;
1075 1087 int ret = B_FALSE;
1076 1088
1077 1089 /* at least udi or volume must be supplied */
1078 1090 if ((udi == NULL) && (volume == NULL)) {
1079 1091 return (B_FALSE);
1080 1092 }
1081 1093 if (volume == NULL) {
1082 1094 if ((volume = libhal_volume_from_udi(hal_ctx, udi)) == NULL) {
1083 1095 dprintf("cannot get volume %s\n", udi);
1084 1096 goto out;
1085 1097 }
1086 1098 }
1087 1099 if (udi == NULL) {
1088 1100 if ((udi = libhal_volume_get_udi(volume)) == NULL) {
1089 1101 dprintf("cannot get udi\n");
1090 1102 goto out;
1091 1103 }
1092 1104 }
1093 1105 drive_udi = libhal_volume_get_storage_device_udi(volume);
1094 1106
1095 1107 if (!(aap->aa_symdev = libhal_device_get_property_string(hal_ctx,
1096 1108 drive_udi, "storage.solaris.legacy.symdev", NULL))) {
1097 1109 dprintf("property %s not found %s\n",
1098 1110 "storage.solaris.legacy.symdev", drive_udi);
1099 1111 goto out;
1100 1112 }
1101 1113 if (!(aap->aa_media = libhal_device_get_property_string(hal_ctx,
1102 1114 drive_udi, "storage.solaris.legacy.media_type", NULL))) {
1103 1115 dprintf("property %s not found %s\n",
1104 1116 "storage.solaris.legacy.media_type", drive_udi);
1105 1117 goto out;
1106 1118 }
1107 1119
1108 1120 /* name is derived from volume label */
1109 1121 aap->aa_name = NULL;
1110 1122 if ((volume_label = (char *)libhal_device_get_property_string(hal_ctx,
1111 1123 udi, "volume.label", NULL)) != NULL) {
1112 1124 if ((len = strlen(volume_label)) > 0) {
1113 1125 aap->aa_name = rmm_vold_convert_volume_label(
1114 1126 volume_label, len);
1115 1127 if (strlen(aap->aa_name) == 0) {
1116 1128 free(aap->aa_name);
1117 1129 aap->aa_name = NULL;
1118 1130 }
1119 1131 }
1120 1132 libhal_free_string(volume_label);
1121 1133 }
1122 1134 /* if no label, then unnamed_<mediatype> */
1123 1135 if (aap->aa_name == NULL) {
1124 1136 aap->aa_name = (char *)calloc(1, sizeof ("unnamed_floppyNNNN"));
1125 1137 if (aap->aa_name == NULL) {
1126 1138 goto out;
1127 1139 }
1128 1140 (void) snprintf(aap->aa_name, sizeof ("unnamed_floppyNNNN"),
1129 1141 "unnamed_%s", aap->aa_media);
1130 1142 }
1131 1143
1132 1144 if (!(aap->aa_path = libhal_device_get_property_string(hal_ctx, udi,
1133 1145 "block.device", NULL))) {
1134 1146 dprintf("property %s not found %s\n", "block.device", udi);
1135 1147 goto out;
1136 1148 }
1137 1149 if (!(aap->aa_rawpath = libhal_device_get_property_string(hal_ctx, udi,
1138 1150 "block.solaris.raw_device", NULL))) {
1139 1151 dprintf("property %s not found %s\n",
1140 1152 "block.solaris.raw_device", udi);
1141 1153 goto out;
1142 1154 }
1143 1155 if (!(aap->aa_type = libhal_device_get_property_string(hal_ctx, udi,
1144 1156 "volume.fstype", NULL))) {
1145 1157 dprintf("property %s not found %s\n", "volume.fstype", udi);
1146 1158 goto out;
1147 1159 }
1148 1160 if (!libhal_device_get_property_bool(hal_ctx, udi,
1149 1161 "volume.is_partition", NULL)) {
1150 1162 aap->aa_partname = NULL;
1151 1163 } else if (!(aap->aa_partname = libhal_device_get_property_string(
1152 1164 hal_ctx, udi, "block.solaris.slice", NULL))) {
1153 1165 dprintf("property %s not found %s\n",
1154 1166 "block.solaris.slice", udi);
1155 1167 goto out;
1156 1168 }
1157 1169 if (!(mountpoint = libhal_device_get_property_string(hal_ctx, udi,
1158 1170 "volume.mount_point", NULL))) {
1159 1171 dprintf("property %s not found %s\n",
1160 1172 "volume.mount_point", udi);
1161 1173 goto out;
1162 1174 }
1163 1175 /*
1164 1176 * aa_mountpoint can be reallocated in rmm_volume_aa_update_mountpoint()
1165 1177 * won't have to choose between free() or libhal_free_string() later on
1166 1178 */
1167 1179 aap->aa_mountpoint = strdup(mountpoint);
1168 1180 libhal_free_string(mountpoint);
1169 1181 if (aap->aa_mountpoint == NULL) {
1170 1182 dprintf("mountpoint is NULL %s\n", udi);
1171 1183 goto out;
1172 1184 }
1173 1185
1174 1186 ret = B_TRUE;
1175 1187
1176 1188 out:
1177 1189 if ((volume != NULL) && (volume != volume_arg)) {
1178 1190 libhal_volume_free(volume);
1179 1191 }
1180 1192 if (!ret) {
1181 1193 rmm_volume_aa_free(aap);
1182 1194 }
1183 1195 return (ret);
1184 1196 }
1185 1197
1186 1198 /* ARGSUSED */
1187 1199 void
1188 1200 rmm_volume_aa_update_mountpoint(LibHalContext *hal_ctx, const char *udi,
1189 1201 struct action_arg *aap)
1190 1202 {
1191 1203 if (aap->aa_mountpoint != NULL) {
1192 1204 free(aap->aa_mountpoint);
1193 1205 }
1194 1206 aap->aa_mountpoint = rmm_get_mnttab_mount_point(aap->aa_path);
1195 1207 }
1196 1208
1197 1209 void
1198 1210 rmm_volume_aa_free(struct action_arg *aap)
1199 1211 {
1200 1212 if (aap->aa_symdev != NULL) {
1201 1213 libhal_free_string(aap->aa_symdev);
1202 1214 aap->aa_symdev = NULL;
1203 1215 }
1204 1216 if (aap->aa_name != NULL) {
1205 1217 free(aap->aa_name);
1206 1218 aap->aa_name = NULL;
1207 1219 }
1208 1220 if (aap->aa_path != NULL) {
1209 1221 libhal_free_string(aap->aa_path);
1210 1222 aap->aa_path = NULL;
1211 1223 }
1212 1224 if (aap->aa_rawpath != NULL) {
1213 1225 libhal_free_string(aap->aa_rawpath);
1214 1226 aap->aa_rawpath = NULL;
1215 1227 }
1216 1228 if (aap->aa_type != NULL) {
1217 1229 libhal_free_string(aap->aa_type);
1218 1230 aap->aa_type = NULL;
1219 1231 }
1220 1232 if (aap->aa_media != NULL) {
1221 1233 libhal_free_string(aap->aa_media);
1222 1234 aap->aa_media = NULL;
1223 1235 }
1224 1236 if (aap->aa_partname != NULL) {
1225 1237 libhal_free_string(aap->aa_partname);
1226 1238 aap->aa_partname = NULL;
1227 1239 }
1228 1240 if (aap->aa_mountpoint != NULL) {
1229 1241 free(aap->aa_mountpoint);
1230 1242 aap->aa_mountpoint = NULL;
1231 1243 }
1232 1244 }
1233 1245
1234 1246 /*
1235 1247 * get device's mount point from mnttab
1236 1248 */
1237 1249 char *
1238 1250 rmm_get_mnttab_mount_point(const char *special)
1239 1251 {
1240 1252 char *mount_point = NULL;
1241 1253 FILE *f;
1242 1254 struct mnttab mnt;
1243 1255 struct mnttab mpref = { NULL, NULL, NULL, NULL, NULL };
1244 1256
1245 1257 if ((f = fopen(MNTTAB, "r")) != NULL) {
1246 1258 mpref.mnt_special = (char *)special;
1247 1259 if (getmntany(f, &mnt, &mpref) == 0) {
1248 1260 mount_point = strdup(mnt.mnt_mountp);
1249 1261 }
1250 1262 fclose(f);
1251 1263 }
1252 1264
1253 1265 return (mount_point);
1254 1266 }
1255 1267
1256 1268
1257 1269 /*
1258 1270 * get human readable string from error values
1259 1271 */
1260 1272 const char *
1261 1273 rmm_strerror(DBusError *dbus_error, int rmm_error)
1262 1274 {
1263 1275 const char *str;
1264 1276
1265 1277 if ((dbus_error != NULL) && dbus_error_is_set(dbus_error)) {
1266 1278 str = dbus_error->message;
1267 1279 } else {
1268 1280 switch (rmm_error) {
1269 1281 case RMM_EOK:
1270 1282 str = gettext("success");
1271 1283 break;
1272 1284 case RMM_EDBUS_CONNECT:
1273 1285 str = gettext("cannot connect to D-Bus");
1274 1286 break;
1275 1287 case RMM_EHAL_CONNECT:
1276 1288 str = gettext("cannot connect to HAL");
1277 1289 break;
1278 1290 default:
1279 1291 str = gettext("undefined error");
1280 1292 break;
1281 1293 }
1282 1294 }
1283 1295
1284 1296 return (str);
1285 1297 }
1286 1298
1287 1299 void
1288 1300 rmm_dbus_error_free(DBusError *error)
1289 1301 {
1290 1302 if (error != NULL && dbus_error_is_set(error)) {
1291 1303 dbus_error_free(error);
1292 1304 }
1293 1305 }
1294 1306
1295 1307 static int
1296 1308 rmm_vold_isbadchar(int c)
1297 1309 {
1298 1310 int ret_val = 0;
1299 1311
1300 1312
1301 1313 switch (c) {
1302 1314 case '/':
1303 1315 case ';':
1304 1316 case '|':
1305 1317 ret_val = 1;
1306 1318 break;
1307 1319 default:
1308 1320 if (iscntrl(c) || isspace(c)) {
1309 1321 ret_val = 1;
1310 1322 }
1311 1323 }
1312 1324
1313 1325 return (ret_val);
1314 1326 }
1315 1327
1316 1328 char *
1317 1329 rmm_vold_convert_volume_label(const char *name, size_t len)
1318 1330 {
1319 1331 char buf[MAXNAMELEN+1];
1320 1332 char *s = buf;
1321 1333 int i;
1322 1334
1323 1335 if (len > MAXNAMELEN) {
1324 1336 len = MAXNAMELEN;
1325 1337 }
1326 1338
1327 1339 for (i = 0; i < len; i++) {
1328 1340 if (name[i] == '\0') {
1329 1341 break;
1330 1342 }
1331 1343 if (isgraph((int)name[i])) {
1332 1344 if (isupper((int)name[i])) {
1333 1345 *s++ = tolower((int)name[i]);
1334 1346 } else if (rmm_vold_isbadchar((int)name[i])) {
1335 1347 *s++ = '_';
1336 1348 } else {
1337 1349 *s++ = name[i];
1338 1350 }
1339 1351 }
1340 1352 }
1341 1353 *s = '\0';
1342 1354 s = strdup(buf);
1343 1355
1344 1356 return (s);
1345 1357 }
1346 1358
1347 1359 /*
1348 1360 * swiped from mkdir.c
1349 1361 */
1350 1362 int
1351 1363 makepath(char *dir, mode_t mode)
1352 1364 {
1353 1365 int err;
1354 1366 char *slash;
1355 1367
1356 1368
1357 1369 if ((mkdir(dir, mode) == 0) || (errno == EEXIST)) {
1358 1370 return (0);
1359 1371 }
1360 1372 if (errno != ENOENT) {
1361 1373 return (-1);
1362 1374 }
1363 1375 if ((slash = strrchr(dir, '/')) == NULL) {
1364 1376 return (-1);
1365 1377 }
1366 1378 *slash = '\0';
1367 1379 err = makepath(dir, mode);
1368 1380 *slash++ = '/';
1369 1381
1370 1382 if (err || (*slash == '\0')) {
1371 1383 return (err);
1372 1384 }
1373 1385
1374 1386 return (mkdir(dir, mode));
1375 1387 }
1376 1388
1377 1389
1378 1390 void
1379 1391 dprintf(const char *fmt, ...)
1380 1392 {
1381 1393
1382 1394 va_list ap;
1383 1395 const char *p;
1384 1396 char msg[BUFSIZ];
1385 1397 char *errmsg = strerror(errno);
1386 1398 char *s;
1387 1399
1388 1400 if (rmm_debug == 0) {
1389 1401 return;
1390 1402 }
1391 1403
1392 1404 (void) memset(msg, 0, BUFSIZ);
1393 1405
1394 1406 /* scan for %m and replace with errno msg */
1395 1407 s = &msg[strlen(msg)];
1396 1408 p = fmt;
1397 1409
1398 1410 while (*p != '\0') {
1399 1411 if ((*p == '%') && (*(p+1) == 'm')) {
1400 1412 (void) strcat(s, errmsg);
1401 1413 p += 2;
1402 1414 s += strlen(errmsg);
1403 1415 continue;
1404 1416 }
1405 1417 *s++ = *p++;
1406 1418 }
1407 1419 *s = '\0'; /* don't forget the null byte */
1408 1420
1409 1421 va_start(ap, fmt);
1410 1422 (void) vfprintf(stderr, msg, ap);
1411 1423 va_end(ap);
1412 1424 }
↓ open down ↓ |
436 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX