Print this page
4845 rm(u)mount don't always print mount/unmount errors
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 + * Assume anything other than EJECT and CLOSETRAY is a
922 + * variant of mount or unmount and requires the device
923 + * to have at least one volume.
924 + */
925 + if (volumes == NULL && (action != EJECT && action != CLOSETRAY)) {
926 + (void) fprintf(stderr,
927 + gettext("cannot %s device '%s' with no volumes\n"),
928 + action_strings[action], name);
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);
975 + if (volumes != NULL)
976 + rmm_volumes_free(volumes);
966 977 libhal_drive_free(d);
967 978
968 979 return (ret);
969 980 }
970 981
971 982
972 983 /*
973 984 * rescan by name
974 985 * if name is NULL, rescan all drives
975 986 */
976 987 boolean_t
977 988 rmm_rescan(LibHalContext *hal_ctx, const char *name, boolean_t query)
978 989 {
979 990 DBusError error;
980 991 GSList *volumes;
981 992 LibHalDrive *drive = NULL;
982 993 const char *drive_udi;
983 994 char **udis;
984 995 int num_udis;
985 996 char *nickname;
986 997 char **nicks = NULL;
987 998 boolean_t do_free_udis = FALSE;
988 999 int i;
989 1000 boolean_t ret = B_FALSE;
990 1001
991 1002 dprintf("rmm_rescan %s\n", name != NULL ? name : "all");
992 1003
993 1004 dbus_error_init(&error);
994 1005
995 1006 if (name != NULL) {
996 1007 if ((drive = rmm_hal_volume_find(hal_ctx, name, &error,
997 1008 &volumes)) == NULL) {
998 1009 rmm_dbus_error_free(&error);
999 1010 (void) fprintf(stderr,
1000 1011 gettext("cannot find '%s'\n"), name);
1001 1012 return (B_FALSE);
1002 1013 }
1003 1014 rmm_dbus_error_free(&error);
1004 1015 g_slist_free(volumes);
1005 1016
1006 1017 drive_udi = libhal_drive_get_udi(drive);
1007 1018 udis = (char **)&drive_udi;
1008 1019 num_udis = 1;
1009 1020 } else {
1010 1021 if ((udis = libhal_find_device_by_capability(hal_ctx,
1011 1022 "storage", &num_udis, &error)) == NULL) {
1012 1023 rmm_dbus_error_free(&error);
1013 1024 return (B_TRUE);
1014 1025 }
1015 1026 rmm_dbus_error_free(&error);
1016 1027 do_free_udis = TRUE;
1017 1028 }
1018 1029
1019 1030 for (i = 0; i < num_udis; i++) {
1020 1031 if (name == NULL) {
1021 1032 nicks = libhal_device_get_property_strlist(hal_ctx,
1022 1033 udis[i], "storage.solaris.nicknames", NULL);
1023 1034 if (nicks != NULL) {
1024 1035 nickname = nicks[0];
1025 1036 } else {
1026 1037 nickname = "";
1027 1038 }
1028 1039 }
1029 1040 if (!(ret = rmm_hal_rescan(hal_ctx, udis[i], &error))) {
1030 1041 (void) fprintf(stderr,
1031 1042 gettext("rescan of %s failed: %s\n"),
1032 1043 name ? name : nickname,
1033 1044 rmm_strerror(&error, -1));
1034 1045 libhal_free_string_array(nicks);
1035 1046 continue;
1036 1047 }
1037 1048 if (query) {
1038 1049 ret = libhal_device_get_property_bool(hal_ctx, udis[i],
1039 1050 "storage.removable.media_available", NULL);
1040 1051 if (ret) {
1041 1052 printf(gettext("%s is available\n"),
1042 1053 name ? name : nickname);
1043 1054 } else {
1044 1055 printf(gettext("%s is not available\n"),
1045 1056 name ? name : nickname);
1046 1057 }
1047 1058 }
1048 1059 libhal_free_string_array(nicks);
1049 1060 }
1050 1061
1051 1062 if (drive != NULL) {
1052 1063 libhal_drive_free(drive);
1053 1064 }
1054 1065 if (do_free_udis) {
1055 1066 libhal_free_string_array(udis);
1056 1067 }
1057 1068
1058 1069 return (ret);
1059 1070 }
1060 1071
1061 1072
1062 1073 /*
1063 1074 * set action_arg from volume properties
1064 1075 */
1065 1076 boolean_t
1066 1077 rmm_volume_aa_from_prop(LibHalContext *hal_ctx, const char *udi_arg,
1067 1078 LibHalVolume *volume_arg, struct action_arg *aap)
1068 1079 {
1069 1080 LibHalVolume *volume = volume_arg;
1070 1081 const char *udi = udi_arg;
1071 1082 const char *drive_udi;
1072 1083 char *volume_label;
1073 1084 char *mountpoint;
1074 1085 int len;
1075 1086 int ret = B_FALSE;
1076 1087
1077 1088 /* at least udi or volume must be supplied */
1078 1089 if ((udi == NULL) && (volume == NULL)) {
1079 1090 return (B_FALSE);
1080 1091 }
1081 1092 if (volume == NULL) {
1082 1093 if ((volume = libhal_volume_from_udi(hal_ctx, udi)) == NULL) {
1083 1094 dprintf("cannot get volume %s\n", udi);
1084 1095 goto out;
1085 1096 }
1086 1097 }
1087 1098 if (udi == NULL) {
1088 1099 if ((udi = libhal_volume_get_udi(volume)) == NULL) {
1089 1100 dprintf("cannot get udi\n");
1090 1101 goto out;
1091 1102 }
1092 1103 }
1093 1104 drive_udi = libhal_volume_get_storage_device_udi(volume);
1094 1105
1095 1106 if (!(aap->aa_symdev = libhal_device_get_property_string(hal_ctx,
1096 1107 drive_udi, "storage.solaris.legacy.symdev", NULL))) {
1097 1108 dprintf("property %s not found %s\n",
1098 1109 "storage.solaris.legacy.symdev", drive_udi);
1099 1110 goto out;
1100 1111 }
1101 1112 if (!(aap->aa_media = libhal_device_get_property_string(hal_ctx,
1102 1113 drive_udi, "storage.solaris.legacy.media_type", NULL))) {
1103 1114 dprintf("property %s not found %s\n",
1104 1115 "storage.solaris.legacy.media_type", drive_udi);
1105 1116 goto out;
1106 1117 }
1107 1118
1108 1119 /* name is derived from volume label */
1109 1120 aap->aa_name = NULL;
1110 1121 if ((volume_label = (char *)libhal_device_get_property_string(hal_ctx,
1111 1122 udi, "volume.label", NULL)) != NULL) {
1112 1123 if ((len = strlen(volume_label)) > 0) {
1113 1124 aap->aa_name = rmm_vold_convert_volume_label(
1114 1125 volume_label, len);
1115 1126 if (strlen(aap->aa_name) == 0) {
1116 1127 free(aap->aa_name);
1117 1128 aap->aa_name = NULL;
1118 1129 }
1119 1130 }
1120 1131 libhal_free_string(volume_label);
1121 1132 }
1122 1133 /* if no label, then unnamed_<mediatype> */
1123 1134 if (aap->aa_name == NULL) {
1124 1135 aap->aa_name = (char *)calloc(1, sizeof ("unnamed_floppyNNNN"));
1125 1136 if (aap->aa_name == NULL) {
1126 1137 goto out;
1127 1138 }
1128 1139 (void) snprintf(aap->aa_name, sizeof ("unnamed_floppyNNNN"),
1129 1140 "unnamed_%s", aap->aa_media);
1130 1141 }
1131 1142
1132 1143 if (!(aap->aa_path = libhal_device_get_property_string(hal_ctx, udi,
1133 1144 "block.device", NULL))) {
1134 1145 dprintf("property %s not found %s\n", "block.device", udi);
1135 1146 goto out;
1136 1147 }
1137 1148 if (!(aap->aa_rawpath = libhal_device_get_property_string(hal_ctx, udi,
1138 1149 "block.solaris.raw_device", NULL))) {
1139 1150 dprintf("property %s not found %s\n",
1140 1151 "block.solaris.raw_device", udi);
1141 1152 goto out;
1142 1153 }
1143 1154 if (!(aap->aa_type = libhal_device_get_property_string(hal_ctx, udi,
1144 1155 "volume.fstype", NULL))) {
1145 1156 dprintf("property %s not found %s\n", "volume.fstype", udi);
1146 1157 goto out;
1147 1158 }
1148 1159 if (!libhal_device_get_property_bool(hal_ctx, udi,
1149 1160 "volume.is_partition", NULL)) {
1150 1161 aap->aa_partname = NULL;
1151 1162 } else if (!(aap->aa_partname = libhal_device_get_property_string(
1152 1163 hal_ctx, udi, "block.solaris.slice", NULL))) {
1153 1164 dprintf("property %s not found %s\n",
1154 1165 "block.solaris.slice", udi);
1155 1166 goto out;
1156 1167 }
1157 1168 if (!(mountpoint = libhal_device_get_property_string(hal_ctx, udi,
1158 1169 "volume.mount_point", NULL))) {
1159 1170 dprintf("property %s not found %s\n",
1160 1171 "volume.mount_point", udi);
1161 1172 goto out;
1162 1173 }
1163 1174 /*
1164 1175 * aa_mountpoint can be reallocated in rmm_volume_aa_update_mountpoint()
1165 1176 * won't have to choose between free() or libhal_free_string() later on
1166 1177 */
1167 1178 aap->aa_mountpoint = strdup(mountpoint);
1168 1179 libhal_free_string(mountpoint);
1169 1180 if (aap->aa_mountpoint == NULL) {
1170 1181 dprintf("mountpoint is NULL %s\n", udi);
1171 1182 goto out;
1172 1183 }
1173 1184
1174 1185 ret = B_TRUE;
1175 1186
1176 1187 out:
1177 1188 if ((volume != NULL) && (volume != volume_arg)) {
1178 1189 libhal_volume_free(volume);
1179 1190 }
1180 1191 if (!ret) {
1181 1192 rmm_volume_aa_free(aap);
1182 1193 }
1183 1194 return (ret);
1184 1195 }
1185 1196
1186 1197 /* ARGSUSED */
1187 1198 void
1188 1199 rmm_volume_aa_update_mountpoint(LibHalContext *hal_ctx, const char *udi,
1189 1200 struct action_arg *aap)
1190 1201 {
1191 1202 if (aap->aa_mountpoint != NULL) {
1192 1203 free(aap->aa_mountpoint);
1193 1204 }
1194 1205 aap->aa_mountpoint = rmm_get_mnttab_mount_point(aap->aa_path);
1195 1206 }
1196 1207
1197 1208 void
1198 1209 rmm_volume_aa_free(struct action_arg *aap)
1199 1210 {
1200 1211 if (aap->aa_symdev != NULL) {
1201 1212 libhal_free_string(aap->aa_symdev);
1202 1213 aap->aa_symdev = NULL;
1203 1214 }
1204 1215 if (aap->aa_name != NULL) {
1205 1216 free(aap->aa_name);
1206 1217 aap->aa_name = NULL;
1207 1218 }
1208 1219 if (aap->aa_path != NULL) {
1209 1220 libhal_free_string(aap->aa_path);
1210 1221 aap->aa_path = NULL;
1211 1222 }
1212 1223 if (aap->aa_rawpath != NULL) {
1213 1224 libhal_free_string(aap->aa_rawpath);
1214 1225 aap->aa_rawpath = NULL;
1215 1226 }
1216 1227 if (aap->aa_type != NULL) {
1217 1228 libhal_free_string(aap->aa_type);
1218 1229 aap->aa_type = NULL;
1219 1230 }
1220 1231 if (aap->aa_media != NULL) {
1221 1232 libhal_free_string(aap->aa_media);
1222 1233 aap->aa_media = NULL;
1223 1234 }
1224 1235 if (aap->aa_partname != NULL) {
1225 1236 libhal_free_string(aap->aa_partname);
1226 1237 aap->aa_partname = NULL;
1227 1238 }
1228 1239 if (aap->aa_mountpoint != NULL) {
1229 1240 free(aap->aa_mountpoint);
1230 1241 aap->aa_mountpoint = NULL;
1231 1242 }
1232 1243 }
1233 1244
1234 1245 /*
1235 1246 * get device's mount point from mnttab
1236 1247 */
1237 1248 char *
1238 1249 rmm_get_mnttab_mount_point(const char *special)
1239 1250 {
1240 1251 char *mount_point = NULL;
1241 1252 FILE *f;
1242 1253 struct mnttab mnt;
1243 1254 struct mnttab mpref = { NULL, NULL, NULL, NULL, NULL };
1244 1255
1245 1256 if ((f = fopen(MNTTAB, "r")) != NULL) {
1246 1257 mpref.mnt_special = (char *)special;
1247 1258 if (getmntany(f, &mnt, &mpref) == 0) {
1248 1259 mount_point = strdup(mnt.mnt_mountp);
1249 1260 }
1250 1261 fclose(f);
1251 1262 }
1252 1263
1253 1264 return (mount_point);
1254 1265 }
1255 1266
1256 1267
1257 1268 /*
1258 1269 * get human readable string from error values
1259 1270 */
1260 1271 const char *
1261 1272 rmm_strerror(DBusError *dbus_error, int rmm_error)
1262 1273 {
1263 1274 const char *str;
1264 1275
1265 1276 if ((dbus_error != NULL) && dbus_error_is_set(dbus_error)) {
1266 1277 str = dbus_error->message;
1267 1278 } else {
1268 1279 switch (rmm_error) {
1269 1280 case RMM_EOK:
1270 1281 str = gettext("success");
1271 1282 break;
1272 1283 case RMM_EDBUS_CONNECT:
1273 1284 str = gettext("cannot connect to D-Bus");
1274 1285 break;
1275 1286 case RMM_EHAL_CONNECT:
1276 1287 str = gettext("cannot connect to HAL");
1277 1288 break;
1278 1289 default:
1279 1290 str = gettext("undefined error");
1280 1291 break;
1281 1292 }
1282 1293 }
1283 1294
1284 1295 return (str);
1285 1296 }
1286 1297
1287 1298 void
1288 1299 rmm_dbus_error_free(DBusError *error)
1289 1300 {
1290 1301 if (error != NULL && dbus_error_is_set(error)) {
1291 1302 dbus_error_free(error);
1292 1303 }
1293 1304 }
1294 1305
1295 1306 static int
1296 1307 rmm_vold_isbadchar(int c)
1297 1308 {
1298 1309 int ret_val = 0;
1299 1310
1300 1311
1301 1312 switch (c) {
1302 1313 case '/':
1303 1314 case ';':
1304 1315 case '|':
1305 1316 ret_val = 1;
1306 1317 break;
1307 1318 default:
1308 1319 if (iscntrl(c) || isspace(c)) {
1309 1320 ret_val = 1;
1310 1321 }
1311 1322 }
1312 1323
1313 1324 return (ret_val);
1314 1325 }
1315 1326
1316 1327 char *
1317 1328 rmm_vold_convert_volume_label(const char *name, size_t len)
1318 1329 {
1319 1330 char buf[MAXNAMELEN+1];
1320 1331 char *s = buf;
1321 1332 int i;
1322 1333
1323 1334 if (len > MAXNAMELEN) {
1324 1335 len = MAXNAMELEN;
1325 1336 }
1326 1337
1327 1338 for (i = 0; i < len; i++) {
1328 1339 if (name[i] == '\0') {
1329 1340 break;
1330 1341 }
1331 1342 if (isgraph((int)name[i])) {
1332 1343 if (isupper((int)name[i])) {
1333 1344 *s++ = tolower((int)name[i]);
1334 1345 } else if (rmm_vold_isbadchar((int)name[i])) {
1335 1346 *s++ = '_';
1336 1347 } else {
1337 1348 *s++ = name[i];
1338 1349 }
1339 1350 }
1340 1351 }
1341 1352 *s = '\0';
1342 1353 s = strdup(buf);
1343 1354
1344 1355 return (s);
1345 1356 }
1346 1357
1347 1358 /*
1348 1359 * swiped from mkdir.c
1349 1360 */
1350 1361 int
1351 1362 makepath(char *dir, mode_t mode)
1352 1363 {
1353 1364 int err;
1354 1365 char *slash;
1355 1366
1356 1367
1357 1368 if ((mkdir(dir, mode) == 0) || (errno == EEXIST)) {
1358 1369 return (0);
1359 1370 }
1360 1371 if (errno != ENOENT) {
1361 1372 return (-1);
1362 1373 }
1363 1374 if ((slash = strrchr(dir, '/')) == NULL) {
1364 1375 return (-1);
1365 1376 }
1366 1377 *slash = '\0';
1367 1378 err = makepath(dir, mode);
1368 1379 *slash++ = '/';
1369 1380
1370 1381 if (err || (*slash == '\0')) {
1371 1382 return (err);
1372 1383 }
1373 1384
1374 1385 return (mkdir(dir, mode));
1375 1386 }
1376 1387
1377 1388
1378 1389 void
1379 1390 dprintf(const char *fmt, ...)
1380 1391 {
1381 1392
1382 1393 va_list ap;
1383 1394 const char *p;
1384 1395 char msg[BUFSIZ];
1385 1396 char *errmsg = strerror(errno);
1386 1397 char *s;
1387 1398
1388 1399 if (rmm_debug == 0) {
1389 1400 return;
1390 1401 }
1391 1402
1392 1403 (void) memset(msg, 0, BUFSIZ);
1393 1404
1394 1405 /* scan for %m and replace with errno msg */
1395 1406 s = &msg[strlen(msg)];
1396 1407 p = fmt;
1397 1408
1398 1409 while (*p != '\0') {
1399 1410 if ((*p == '%') && (*(p+1) == 'm')) {
1400 1411 (void) strcat(s, errmsg);
1401 1412 p += 2;
1402 1413 s += strlen(errmsg);
1403 1414 continue;
1404 1415 }
1405 1416 *s++ = *p++;
1406 1417 }
1407 1418 *s = '\0'; /* don't forget the null byte */
1408 1419
1409 1420 va_start(ap, fmt);
1410 1421 (void) vfprintf(stderr, msg, ap);
1411 1422 va_end(ap);
1412 1423 }
↓ open down ↓ |
437 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX