118c2aff7Sartem /*
218c2aff7Sartem * CDDL HEADER START
318c2aff7Sartem *
418c2aff7Sartem * The contents of this file are subject to the terms of the
518c2aff7Sartem * Common Development and Distribution License (the "License").
618c2aff7Sartem * You may not use this file except in compliance with the License.
718c2aff7Sartem *
818c2aff7Sartem * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
918c2aff7Sartem * or http://www.opensolaris.org/os/licensing.
1018c2aff7Sartem * See the License for the specific language governing permissions
1118c2aff7Sartem * and limitations under the License.
1218c2aff7Sartem *
1318c2aff7Sartem * When distributing Covered Code, include this CDDL HEADER in each
1418c2aff7Sartem * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1518c2aff7Sartem * If applicable, add the following below this CDDL HEADER, with the
1618c2aff7Sartem * fields enclosed by brackets "[]" replaced with your own identifying
1718c2aff7Sartem * information: Portions Copyright [yyyy] [name of copyright owner]
1818c2aff7Sartem *
1918c2aff7Sartem * CDDL HEADER END
2018c2aff7Sartem */
2118c2aff7Sartem /*
2297ddcdceSArtem Kachitchkine * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
2318c2aff7Sartem * Use is subject to license terms.
2418c2aff7Sartem */
2518c2aff7Sartem
2618c2aff7Sartem #include <stdio.h>
2718c2aff7Sartem #include <errno.h>
2818c2aff7Sartem #include <string.h>
2918c2aff7Sartem #include <strings.h>
3018c2aff7Sartem #include <stdarg.h>
3118c2aff7Sartem #include <fcntl.h>
3218c2aff7Sartem #include <libintl.h>
3318c2aff7Sartem #include <stdlib.h>
3418c2aff7Sartem #include <unistd.h>
3518c2aff7Sartem #include <ctype.h>
3618c2aff7Sartem #include <sys/param.h>
3718c2aff7Sartem #include <sys/types.h>
3818c2aff7Sartem #include <sys/stat.h>
3918c2aff7Sartem #include <sys/mnttab.h>
4018c2aff7Sartem
4118c2aff7Sartem #include <dbus/dbus.h>
4218c2aff7Sartem #include <dbus/dbus-glib.h>
4318c2aff7Sartem #include <dbus/dbus-glib-lowlevel.h>
4418c2aff7Sartem #include <libhal.h>
4518c2aff7Sartem #include <libhal-storage.h>
4618c2aff7Sartem
4718c2aff7Sartem #include "rmm_common.h"
4818c2aff7Sartem
490ebe3100Sartem #define RMM_PRINT_DEVICE_WIDTH 20
500ebe3100Sartem
5118c2aff7Sartem extern int rmm_debug;
5218c2aff7Sartem
5318c2aff7Sartem static const char *action_strings[] = {
5418c2aff7Sartem "eject",
5518c2aff7Sartem "mount",
5618c2aff7Sartem "remount",
5718c2aff7Sartem "unmount",
5818c2aff7Sartem "clear_mounts",
5918c2aff7Sartem "closetray"
6018c2aff7Sartem };
6118c2aff7Sartem
6218c2aff7Sartem
6318c2aff7Sartem LibHalContext *
rmm_hal_init(LibHalDeviceAdded devadd_cb,LibHalDeviceRemoved devrem_cb,LibHalDevicePropertyModified propmod_cb,LibHalDeviceCondition cond_cb,DBusError * error,rmm_error_t * rmm_error)6418c2aff7Sartem rmm_hal_init(LibHalDeviceAdded devadd_cb, LibHalDeviceRemoved devrem_cb,
6597ddcdceSArtem Kachitchkine LibHalDevicePropertyModified propmod_cb, LibHalDeviceCondition cond_cb,
6618c2aff7Sartem DBusError *error, rmm_error_t *rmm_error)
6718c2aff7Sartem {
6818c2aff7Sartem DBusConnection *dbus_conn;
6918c2aff7Sartem LibHalContext *ctx;
7018c2aff7Sartem char **devices;
7118c2aff7Sartem int nr;
7218c2aff7Sartem
7318c2aff7Sartem dbus_error_init(error);
7418c2aff7Sartem
7518c2aff7Sartem /*
7618c2aff7Sartem * setup D-Bus connection
7718c2aff7Sartem */
7818c2aff7Sartem if (!(dbus_conn = dbus_bus_get(DBUS_BUS_SYSTEM, error))) {
7918c2aff7Sartem dprintf("cannot get system bus: %s\n", rmm_strerror(error, -1));
8018c2aff7Sartem *rmm_error = RMM_EDBUS_CONNECT;
8118c2aff7Sartem return (NULL);
8218c2aff7Sartem }
8318c2aff7Sartem rmm_dbus_error_free(error);
8418c2aff7Sartem
8518c2aff7Sartem dbus_connection_setup_with_g_main(dbus_conn, NULL);
8618c2aff7Sartem dbus_connection_set_exit_on_disconnect(dbus_conn, B_TRUE);
8718c2aff7Sartem
8818c2aff7Sartem if ((ctx = libhal_ctx_new()) == NULL) {
8918c2aff7Sartem dprintf("libhal_ctx_new failed");
9018c2aff7Sartem *rmm_error = RMM_EHAL_CONNECT;
9118c2aff7Sartem return (NULL);
9218c2aff7Sartem }
9318c2aff7Sartem
9418c2aff7Sartem libhal_ctx_set_dbus_connection(ctx, dbus_conn);
9518c2aff7Sartem
9618c2aff7Sartem /*
9718c2aff7Sartem * register callbacks
9818c2aff7Sartem */
9918c2aff7Sartem if (devadd_cb != NULL) {
10018c2aff7Sartem libhal_ctx_set_device_added(ctx, devadd_cb);
10118c2aff7Sartem }
10218c2aff7Sartem if (devrem_cb != NULL) {
10318c2aff7Sartem libhal_ctx_set_device_removed(ctx, devrem_cb);
10418c2aff7Sartem }
10518c2aff7Sartem if (propmod_cb != NULL) {
10618c2aff7Sartem libhal_ctx_set_device_property_modified(ctx, propmod_cb);
10718c2aff7Sartem if (!libhal_device_property_watch_all(ctx, error)) {
10818c2aff7Sartem dprintf("property_watch_all failed %s",
10918c2aff7Sartem rmm_strerror(error, -1));
11018c2aff7Sartem libhal_ctx_free(ctx);
11118c2aff7Sartem *rmm_error = RMM_EHAL_CONNECT;
11218c2aff7Sartem return (NULL);
11318c2aff7Sartem }
11418c2aff7Sartem }
11597ddcdceSArtem Kachitchkine if (cond_cb != NULL) {
11697ddcdceSArtem Kachitchkine libhal_ctx_set_device_condition(ctx, cond_cb);
11797ddcdceSArtem Kachitchkine }
11818c2aff7Sartem
11918c2aff7Sartem if (!libhal_ctx_init(ctx, error)) {
12018c2aff7Sartem dprintf("libhal_ctx_init failed: %s", rmm_strerror(error, -1));
12118c2aff7Sartem libhal_ctx_free(ctx);
12218c2aff7Sartem *rmm_error = RMM_EHAL_CONNECT;
12318c2aff7Sartem return (NULL);
12418c2aff7Sartem }
12518c2aff7Sartem rmm_dbus_error_free(error);
12618c2aff7Sartem
12718c2aff7Sartem /*
12818c2aff7Sartem * The above functions do not guarantee that HAL is actually running.
12918c2aff7Sartem * Check by invoking a method.
13018c2aff7Sartem */
13118c2aff7Sartem if (!(devices = libhal_get_all_devices(ctx, &nr, error))) {
13218c2aff7Sartem dprintf("HAL is not running: %s", rmm_strerror(error, -1));
13318c2aff7Sartem libhal_ctx_shutdown(ctx, NULL);
13418c2aff7Sartem libhal_ctx_free(ctx);
13518c2aff7Sartem *rmm_error = RMM_EHAL_CONNECT;
13618c2aff7Sartem return (NULL);
13718c2aff7Sartem } else {
13818c2aff7Sartem rmm_dbus_error_free(error);
13918c2aff7Sartem libhal_free_string_array(devices);
14018c2aff7Sartem }
14118c2aff7Sartem
14218c2aff7Sartem return (ctx);
14318c2aff7Sartem }
14418c2aff7Sartem
14518c2aff7Sartem
14618c2aff7Sartem void
rmm_hal_fini(LibHalContext * hal_ctx)14718c2aff7Sartem rmm_hal_fini(LibHalContext *hal_ctx)
14818c2aff7Sartem {
14918c2aff7Sartem DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
15018c2aff7Sartem
151b941d3fcSartem (void) dbus_connection_unref(dbus_conn);
15218c2aff7Sartem (void) libhal_ctx_free(hal_ctx);
15318c2aff7Sartem }
15418c2aff7Sartem
15518c2aff7Sartem
15618c2aff7Sartem /*
15718c2aff7Sartem * find volume from any type of name, similar to the old media_findname()
15818c2aff7Sartem * returns the LibHalDrive object and a list of LibHalVolume objects.
15918c2aff7Sartem */
16018c2aff7Sartem LibHalDrive *
rmm_hal_volume_find(LibHalContext * hal_ctx,const char * name,DBusError * error,GSList ** volumes)16118c2aff7Sartem rmm_hal_volume_find(LibHalContext *hal_ctx, const char *name, DBusError *error,
16218c2aff7Sartem GSList **volumes)
16318c2aff7Sartem {
16418c2aff7Sartem LibHalDrive *drive;
16518c2aff7Sartem char *p;
16618c2aff7Sartem char lastc;
16718c2aff7Sartem
16818c2aff7Sartem *volumes = NULL;
16918c2aff7Sartem
17018c2aff7Sartem /* temporarily remove trailing slash */
17118c2aff7Sartem p = (char *)name + strlen(name) - 1;
17218c2aff7Sartem if (*p == '/') {
17318c2aff7Sartem lastc = *p;
17418c2aff7Sartem *p = '\0';
17518c2aff7Sartem } else {
17618c2aff7Sartem p = NULL;
17718c2aff7Sartem }
17818c2aff7Sartem
17918c2aff7Sartem if (name[0] == '/') {
18018c2aff7Sartem if (((drive = rmm_hal_volume_findby(hal_ctx,
18118c2aff7Sartem "info.udi", name, volumes)) != NULL) ||
18218c2aff7Sartem ((drive = rmm_hal_volume_findby(hal_ctx,
18318c2aff7Sartem "block.device", name, volumes)) != NULL) ||
18418c2aff7Sartem ((drive = rmm_hal_volume_findby(hal_ctx,
18518c2aff7Sartem "block.solaris.raw_device", name, volumes)) != NULL) ||
18618c2aff7Sartem ((drive = rmm_hal_volume_findby(hal_ctx,
18718c2aff7Sartem "volume.mount_point", name, volumes)) != NULL)) {
18818c2aff7Sartem goto out;
18918c2aff7Sartem } else {
19018c2aff7Sartem goto out;
19118c2aff7Sartem }
19218c2aff7Sartem }
19318c2aff7Sartem
19418c2aff7Sartem /* try volume label */
19518c2aff7Sartem if ((drive = rmm_hal_volume_findby(hal_ctx,
19618c2aff7Sartem "volume.label", name, volumes)) != NULL) {
19718c2aff7Sartem goto out;
19818c2aff7Sartem }
19918c2aff7Sartem
20018c2aff7Sartem drive = rmm_hal_volume_findby_nickname(hal_ctx, name, volumes);
20118c2aff7Sartem
20218c2aff7Sartem out:
20318c2aff7Sartem if (p != NULL) {
20418c2aff7Sartem *p = lastc;
20518c2aff7Sartem }
20618c2aff7Sartem return (drive);
20718c2aff7Sartem }
20818c2aff7Sartem
20918c2aff7Sartem /*
21018c2aff7Sartem * find default volume. Returns volume pointer and name in 'name'.
21118c2aff7Sartem */
21218c2aff7Sartem LibHalDrive *
rmm_hal_volume_find_default(LibHalContext * hal_ctx,DBusError * error,const char ** name_out,GSList ** volumes)21318c2aff7Sartem rmm_hal_volume_find_default(LibHalContext *hal_ctx, DBusError *error,
21418c2aff7Sartem const char **name_out, GSList **volumes)
21518c2aff7Sartem {
21618c2aff7Sartem LibHalDrive *drive;
21718c2aff7Sartem static const char *names[] = { "floppy", "cdrom", "rmdisk" };
21818c2aff7Sartem int i;
21918c2aff7Sartem
22018c2aff7Sartem *volumes = NULL;
22118c2aff7Sartem
22218c2aff7Sartem for (i = 0; i < NELEM(names); i++) {
22318c2aff7Sartem if ((drive = rmm_hal_volume_findby_nickname(hal_ctx,
22418c2aff7Sartem names[i], volumes)) != NULL) {
22518c2aff7Sartem /*
22618c2aff7Sartem * Skip floppy if it has no media.
22718c2aff7Sartem * XXX might want to actually check for media
22818c2aff7Sartem * every time instead of relying on volcheck.
22918c2aff7Sartem */
23018c2aff7Sartem if ((strcmp(names[i], "floppy") != 0) ||
23118c2aff7Sartem libhal_device_get_property_bool(hal_ctx,
23218c2aff7Sartem libhal_drive_get_udi(drive),
23318c2aff7Sartem "storage.removable.media_available", NULL)) {
23418c2aff7Sartem *name_out = names[i];
23518c2aff7Sartem break;
23618c2aff7Sartem }
23718c2aff7Sartem }
23818c2aff7Sartem rmm_dbus_error_free(error);
23918c2aff7Sartem }
24018c2aff7Sartem
24118c2aff7Sartem return (drive);
24218c2aff7Sartem }
24318c2aff7Sartem
24418c2aff7Sartem /*
24518c2aff7Sartem * find volume by property=value
24618c2aff7Sartem * returns the LibHalDrive object and a list of LibHalVolume objects.
24718c2aff7Sartem * XXX add support for multiple properties, reduce D-Bus traffic
24818c2aff7Sartem */
24918c2aff7Sartem LibHalDrive *
rmm_hal_volume_findby(LibHalContext * hal_ctx,const char * property,const char * value,GSList ** volumes)25018c2aff7Sartem rmm_hal_volume_findby(LibHalContext *hal_ctx, const char *property,
25118c2aff7Sartem const char *value, GSList **volumes)
25218c2aff7Sartem {
25318c2aff7Sartem DBusError error;
25418c2aff7Sartem LibHalDrive *drive = NULL;
25518c2aff7Sartem LibHalVolume *v = NULL;
25618c2aff7Sartem char **udis;
25718c2aff7Sartem int num_udis;
25818c2aff7Sartem int i;
259*68e92846Sfei feng - Sun Microsystems - Beijing China int i_drive = -1;
26018c2aff7Sartem
26118c2aff7Sartem *volumes = NULL;
26218c2aff7Sartem
26318c2aff7Sartem dbus_error_init(&error);
26418c2aff7Sartem
26518c2aff7Sartem /* get all devices with property=value */
26618c2aff7Sartem if ((udis = libhal_manager_find_device_string_match(hal_ctx, property,
26718c2aff7Sartem value, &num_udis, &error)) == NULL) {
26818c2aff7Sartem rmm_dbus_error_free(&error);
26918c2aff7Sartem return (NULL);
27018c2aff7Sartem }
27118c2aff7Sartem
272*68e92846Sfei feng - Sun Microsystems - Beijing China /* find volumes and drives among these devices */
27318c2aff7Sartem for (i = 0; i < num_udis; i++) {
27418c2aff7Sartem rmm_dbus_error_free(&error);
27518c2aff7Sartem if (libhal_device_query_capability(hal_ctx, udis[i], "volume",
27618c2aff7Sartem &error)) {
27718c2aff7Sartem v = libhal_volume_from_udi(hal_ctx, udis[i]);
27818c2aff7Sartem if (v != NULL) {
27918c2aff7Sartem *volumes = g_slist_prepend(*volumes, v);
28018c2aff7Sartem }
281*68e92846Sfei feng - Sun Microsystems - Beijing China } else if ((*volumes == NULL) &&
282*68e92846Sfei feng - Sun Microsystems - Beijing China libhal_device_query_capability(hal_ctx, udis[i], "storage",
283*68e92846Sfei feng - Sun Microsystems - Beijing China &error)) {
284*68e92846Sfei feng - Sun Microsystems - Beijing China i_drive = i;
28518c2aff7Sartem }
28618c2aff7Sartem }
28718c2aff7Sartem
28818c2aff7Sartem if (*volumes != NULL) {
289*68e92846Sfei feng - Sun Microsystems - Beijing China /* used prepend, preserve original order */
29018c2aff7Sartem *volumes = g_slist_reverse(*volumes);
29118c2aff7Sartem
29218c2aff7Sartem v = (LibHalVolume *)(*volumes)->data;
29318c2aff7Sartem drive = libhal_drive_from_udi(hal_ctx,
29418c2aff7Sartem libhal_volume_get_storage_device_udi(v));
29518c2aff7Sartem if (drive == NULL) {
29618c2aff7Sartem rmm_volumes_free (*volumes);
29718c2aff7Sartem *volumes = NULL;
29818c2aff7Sartem }
299*68e92846Sfei feng - Sun Microsystems - Beijing China } else if (i_drive >= 0) {
300*68e92846Sfei feng - Sun Microsystems - Beijing China drive = libhal_drive_from_udi(hal_ctx, udis[i_drive]);
30118c2aff7Sartem }
30218c2aff7Sartem
30318c2aff7Sartem libhal_free_string_array(udis);
30418c2aff7Sartem rmm_dbus_error_free(&error);
30518c2aff7Sartem
30618c2aff7Sartem return (drive);
30718c2aff7Sartem }
30818c2aff7Sartem
3090ebe3100Sartem static void
rmm_print_nicknames_one(LibHalDrive * d,LibHalVolume * v,const char * device,char ** drive_nicknames)3100ebe3100Sartem rmm_print_nicknames_one(LibHalDrive *d, LibHalVolume *v,
3110ebe3100Sartem const char *device, char **drive_nicknames)
31218c2aff7Sartem {
3130ebe3100Sartem const char *volume_label = NULL;
3140ebe3100Sartem const char *mount_point = NULL;
31518c2aff7Sartem boolean_t comma;
3160ebe3100Sartem int i;
31718c2aff7Sartem
3180ebe3100Sartem (void) printf("%-*s ", RMM_PRINT_DEVICE_WIDTH, device);
31918c2aff7Sartem comma = B_FALSE;
32018c2aff7Sartem
3210ebe3100Sartem if (drive_nicknames != NULL) {
3220ebe3100Sartem for (i = 0; drive_nicknames[i] != NULL; i++) {
32318c2aff7Sartem (void) printf("%s%s", comma ? "," : "",
3240ebe3100Sartem drive_nicknames[i]);
32518c2aff7Sartem comma = B_TRUE;
32618c2aff7Sartem }
32718c2aff7Sartem }
32818c2aff7Sartem
3290ebe3100Sartem if ((v != NULL) &&
3300ebe3100Sartem ((volume_label = libhal_volume_get_label(v)) != NULL) &&
33118c2aff7Sartem (strlen(volume_label) > 0)) {
33218c2aff7Sartem (void) printf("%s%s", comma ? "," : "", volume_label);
33318c2aff7Sartem comma = B_TRUE;
33418c2aff7Sartem }
33518c2aff7Sartem
3360ebe3100Sartem if ((v != NULL) &&
3370ebe3100Sartem ((mount_point = libhal_volume_get_mount_point(v)) != NULL) &&
33818c2aff7Sartem (strlen(mount_point) > 0)) {
33918c2aff7Sartem (void) printf("%s%s", comma ? "," : "", mount_point);
34018c2aff7Sartem comma = B_TRUE;
34118c2aff7Sartem }
34218c2aff7Sartem
34318c2aff7Sartem (void) printf("\n");
3440ebe3100Sartem }
3450ebe3100Sartem
3460ebe3100Sartem /*
3470ebe3100Sartem * print nicknames for each available volume
3480ebe3100Sartem *
3490ebe3100Sartem * print_mask:
3500ebe3100Sartem * RMM_PRINT_MOUNTABLE print only mountable volumes
3510ebe3100Sartem * RMM_PRINT_EJECTABLE print volume-less ejectable drives
3520ebe3100Sartem */
3530ebe3100Sartem void
rmm_print_volume_nicknames(LibHalContext * hal_ctx,DBusError * error,int print_mask)3540ebe3100Sartem rmm_print_volume_nicknames(LibHalContext *hal_ctx, DBusError *error,
3550ebe3100Sartem int print_mask)
3560ebe3100Sartem {
3570ebe3100Sartem char **udis;
3580ebe3100Sartem int num_udis;
3590ebe3100Sartem GSList *volumes = NULL;
3600ebe3100Sartem LibHalDrive *d, *d_tmp;
3610ebe3100Sartem LibHalVolume *v;
3620ebe3100Sartem const char *device;
3630ebe3100Sartem char **nicknames;
3640ebe3100Sartem int i;
3650ebe3100Sartem GSList *j;
3660ebe3100Sartem int nprinted;
3670ebe3100Sartem
3680ebe3100Sartem dbus_error_init(error);
3690ebe3100Sartem
3700ebe3100Sartem if ((udis = libhal_find_device_by_capability(hal_ctx, "storage",
3710ebe3100Sartem &num_udis, error)) == NULL) {
3720ebe3100Sartem rmm_dbus_error_free(error);
3730ebe3100Sartem return;
3740ebe3100Sartem }
3750ebe3100Sartem
3760ebe3100Sartem for (i = 0; i < num_udis; i++) {
3770ebe3100Sartem if ((d = libhal_drive_from_udi(hal_ctx, udis[i])) == NULL) {
3780ebe3100Sartem continue;
3790ebe3100Sartem }
3800ebe3100Sartem
3810ebe3100Sartem /* find volumes belonging to this drive */
3820ebe3100Sartem if ((d_tmp = rmm_hal_volume_findby(hal_ctx,
3830ebe3100Sartem "block.storage_device", udis[i], &volumes)) != NULL) {
3840ebe3100Sartem libhal_drive_free(d_tmp);
3850ebe3100Sartem }
3860ebe3100Sartem
3870ebe3100Sartem nicknames = libhal_device_get_property_strlist(hal_ctx,
3880ebe3100Sartem udis[i], "storage.solaris.nicknames", NULL);
3890ebe3100Sartem
3900ebe3100Sartem nprinted = 0;
3910ebe3100Sartem for (j = volumes; j != NULL; j = g_slist_next(j)) {
3920ebe3100Sartem v = (LibHalVolume *)(j->data);
3930ebe3100Sartem
3940ebe3100Sartem if ((device = libhal_volume_get_device_file(v)) ==
3950ebe3100Sartem NULL) {
3960ebe3100Sartem continue;
3970ebe3100Sartem }
3980ebe3100Sartem if ((print_mask & RMM_PRINT_MOUNTABLE) &&
3990ebe3100Sartem (libhal_volume_get_fsusage(v) !=
4000ebe3100Sartem LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM)) {
4010ebe3100Sartem continue;
4020ebe3100Sartem }
4030ebe3100Sartem
4040ebe3100Sartem rmm_print_nicknames_one(d, v, device, nicknames);
4050ebe3100Sartem nprinted++;
4060ebe3100Sartem }
4070ebe3100Sartem
4080ebe3100Sartem if ((nprinted == 0) &&
4090ebe3100Sartem (print_mask & RMM_PRINT_EJECTABLE) &&
4100ebe3100Sartem libhal_drive_requires_eject(d) &&
4110ebe3100Sartem ((device = libhal_drive_get_device_file(d)) != NULL)) {
4120ebe3100Sartem rmm_print_nicknames_one(d, NULL, device, nicknames);
4130ebe3100Sartem }
41418c2aff7Sartem
41518c2aff7Sartem libhal_free_string_array(nicknames);
4160ebe3100Sartem libhal_drive_free(d);
4170ebe3100Sartem rmm_volumes_free(volumes);
4180ebe3100Sartem volumes = NULL;
41918c2aff7Sartem }
42018c2aff7Sartem
4210ebe3100Sartem libhal_free_string_array(udis);
4220ebe3100Sartem }
42318c2aff7Sartem
42418c2aff7Sartem /*
42518c2aff7Sartem * find volume by nickname
42618c2aff7Sartem * returns the LibHalDrive object and a list of LibHalVolume objects.
42718c2aff7Sartem */
42818c2aff7Sartem LibHalDrive *
rmm_hal_volume_findby_nickname(LibHalContext * hal_ctx,const char * name,GSList ** volumes)42918c2aff7Sartem rmm_hal_volume_findby_nickname(LibHalContext *hal_ctx, const char *name,
43018c2aff7Sartem GSList **volumes)
43118c2aff7Sartem {
43218c2aff7Sartem DBusError error;
43318c2aff7Sartem LibHalDrive *drive = NULL;
43418c2aff7Sartem LibHalDrive *drive_tmp;
43518c2aff7Sartem char **udis;
43618c2aff7Sartem int num_udis;
43718c2aff7Sartem char **nicknames;
43818c2aff7Sartem int i, j;
43918c2aff7Sartem
44018c2aff7Sartem *volumes = NULL;
44118c2aff7Sartem
44218c2aff7Sartem dbus_error_init(&error);
44318c2aff7Sartem
44418c2aff7Sartem if ((udis = libhal_find_device_by_capability(hal_ctx, "storage",
44518c2aff7Sartem &num_udis, &error)) == NULL) {
44618c2aff7Sartem rmm_dbus_error_free(&error);
44718c2aff7Sartem return (NULL);
44818c2aff7Sartem }
44918c2aff7Sartem
45018c2aff7Sartem /* find a drive by nickname */
45118c2aff7Sartem for (i = 0; (i < num_udis) && (drive == NULL); i++) {
45218c2aff7Sartem if ((nicknames = libhal_device_get_property_strlist(hal_ctx,
45318c2aff7Sartem udis[i], "storage.solaris.nicknames", &error)) == NULL) {
45418c2aff7Sartem rmm_dbus_error_free(&error);
45518c2aff7Sartem continue;
45618c2aff7Sartem }
45718c2aff7Sartem for (j = 0; (nicknames[j] != NULL) && (drive == NULL); j++) {
45818c2aff7Sartem if (strcmp(nicknames[j], name) == 0) {
45918c2aff7Sartem drive = libhal_drive_from_udi(hal_ctx, udis[i]);
46018c2aff7Sartem }
46118c2aff7Sartem }
46218c2aff7Sartem libhal_free_string_array(nicknames);
46318c2aff7Sartem }
46418c2aff7Sartem libhal_free_string_array(udis);
46518c2aff7Sartem
46618c2aff7Sartem if (drive != NULL) {
46718c2aff7Sartem /* found the drive, now find its volumes */
46818c2aff7Sartem if ((drive_tmp = rmm_hal_volume_findby(hal_ctx,
46918c2aff7Sartem "block.storage_device", libhal_drive_get_udi(drive),
47018c2aff7Sartem volumes)) != NULL) {
47118c2aff7Sartem libhal_drive_free(drive_tmp);
47218c2aff7Sartem }
47318c2aff7Sartem }
47418c2aff7Sartem
47518c2aff7Sartem rmm_dbus_error_free(&error);
47618c2aff7Sartem
47718c2aff7Sartem return (drive);
47818c2aff7Sartem }
47918c2aff7Sartem
48018c2aff7Sartem void
rmm_volumes_free(GSList * volumes)48118c2aff7Sartem rmm_volumes_free(GSList *volumes)
48218c2aff7Sartem {
48318c2aff7Sartem GSList *i;
48418c2aff7Sartem
48518c2aff7Sartem for (i = volumes; i != NULL; i = g_slist_next(i)) {
48618c2aff7Sartem libhal_volume_free((LibHalVolume *)(i->data));
48718c2aff7Sartem }
48818c2aff7Sartem g_slist_free(volumes);
48918c2aff7Sartem }
49018c2aff7Sartem
49118c2aff7Sartem /*
49218c2aff7Sartem * Call HAL's Mount() method on the given device
49318c2aff7Sartem */
49418c2aff7Sartem boolean_t
rmm_hal_mount(LibHalContext * hal_ctx,const char * udi,char ** opts,int num_opts,char * mountpoint,DBusError * error)49518c2aff7Sartem rmm_hal_mount(LibHalContext *hal_ctx, const char *udi,
49618c2aff7Sartem char **opts, int num_opts, char *mountpoint, DBusError *error)
49718c2aff7Sartem {
49818c2aff7Sartem DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
49918c2aff7Sartem DBusMessage *dmesg, *reply;
50018c2aff7Sartem char *fstype;
50118c2aff7Sartem
50218c2aff7Sartem dprintf("mounting %s...\n", udi);
50318c2aff7Sartem
50418c2aff7Sartem if (!(dmesg = dbus_message_new_method_call("org.freedesktop.Hal", udi,
50518c2aff7Sartem "org.freedesktop.Hal.Device.Volume", "Mount"))) {
50618c2aff7Sartem dprintf(
50718c2aff7Sartem "mount failed for %s: cannot create dbus message\n", udi);
50818c2aff7Sartem return (B_FALSE);
50918c2aff7Sartem }
51018c2aff7Sartem
51118c2aff7Sartem fstype = "";
51218c2aff7Sartem if (mountpoint == NULL) {
51318c2aff7Sartem mountpoint = "";
51418c2aff7Sartem }
51518c2aff7Sartem
51618c2aff7Sartem if (!dbus_message_append_args(dmesg, DBUS_TYPE_STRING, &mountpoint,
51718c2aff7Sartem DBUS_TYPE_STRING, &fstype,
51818c2aff7Sartem DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &opts, num_opts,
51918c2aff7Sartem DBUS_TYPE_INVALID)) {
52018c2aff7Sartem dprintf("mount failed for %s: cannot append args\n", udi);
52118c2aff7Sartem dbus_message_unref(dmesg);
52218c2aff7Sartem return (B_FALSE);
52318c2aff7Sartem }
52418c2aff7Sartem
52518c2aff7Sartem dbus_error_init(error);
52618c2aff7Sartem if (!(reply = dbus_connection_send_with_reply_and_block(dbus_conn,
527b941d3fcSartem dmesg, RMM_MOUNT_TIMEOUT, error))) {
52818c2aff7Sartem dprintf("mount failed for %s: %s\n", udi, error->message);
52918c2aff7Sartem dbus_message_unref(dmesg);
53018c2aff7Sartem return (B_FALSE);
53118c2aff7Sartem }
53218c2aff7Sartem
53318c2aff7Sartem dprintf("mounted %s\n", udi);
53418c2aff7Sartem
53518c2aff7Sartem dbus_message_unref(dmesg);
53618c2aff7Sartem dbus_message_unref(reply);
53718c2aff7Sartem
53818c2aff7Sartem rmm_dbus_error_free(error);
53918c2aff7Sartem
54018c2aff7Sartem return (B_TRUE);
54118c2aff7Sartem }
54218c2aff7Sartem
54318c2aff7Sartem
54418c2aff7Sartem /*
54518c2aff7Sartem * Call HAL's Unmount() method on the given device
54618c2aff7Sartem */
54718c2aff7Sartem boolean_t
rmm_hal_unmount(LibHalContext * hal_ctx,const char * udi,DBusError * error)54818c2aff7Sartem rmm_hal_unmount(LibHalContext *hal_ctx, const char *udi, DBusError *error)
54918c2aff7Sartem {
55018c2aff7Sartem DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
55118c2aff7Sartem DBusMessage *dmesg, *reply;
55218c2aff7Sartem char **opts = NULL;
55318c2aff7Sartem
55418c2aff7Sartem dprintf("unmounting %s...\n", udi);
55518c2aff7Sartem
55618c2aff7Sartem if (!(dmesg = dbus_message_new_method_call("org.freedesktop.Hal", udi,
55718c2aff7Sartem "org.freedesktop.Hal.Device.Volume", "Unmount"))) {
55818c2aff7Sartem dprintf(
55918c2aff7Sartem "unmount failed %s: cannot create dbus message\n", udi);
56018c2aff7Sartem return (B_FALSE);
56118c2aff7Sartem }
56218c2aff7Sartem
56318c2aff7Sartem if (!dbus_message_append_args(dmesg, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
56418c2aff7Sartem &opts, 0, DBUS_TYPE_INVALID)) {
56518c2aff7Sartem dprintf("unmount failed %s: cannot append args\n", udi);
56618c2aff7Sartem dbus_message_unref(dmesg);
56718c2aff7Sartem return (B_FALSE);
56818c2aff7Sartem }
56918c2aff7Sartem
57018c2aff7Sartem dbus_error_init(error);
57118c2aff7Sartem if (!(reply = dbus_connection_send_with_reply_and_block(dbus_conn,
572b941d3fcSartem dmesg, RMM_UNMOUNT_TIMEOUT, error))) {
57318c2aff7Sartem dprintf("unmount failed for %s: %s\n", udi, error->message);
57418c2aff7Sartem dbus_message_unref(dmesg);
57518c2aff7Sartem return (B_FALSE);
57618c2aff7Sartem }
57718c2aff7Sartem
57818c2aff7Sartem dprintf("unmounted %s\n", udi);
57918c2aff7Sartem
58018c2aff7Sartem dbus_message_unref(dmesg);
58118c2aff7Sartem dbus_message_unref(reply);
58218c2aff7Sartem
58318c2aff7Sartem rmm_dbus_error_free(error);
58418c2aff7Sartem
58518c2aff7Sartem return (B_TRUE);
58618c2aff7Sartem }
58718c2aff7Sartem
58818c2aff7Sartem
58918c2aff7Sartem /*
59018c2aff7Sartem * Call HAL's Eject() method on the given device
59118c2aff7Sartem */
59218c2aff7Sartem boolean_t
rmm_hal_eject(LibHalContext * hal_ctx,const char * udi,DBusError * error)59318c2aff7Sartem rmm_hal_eject(LibHalContext *hal_ctx, const char *udi, DBusError *error)
59418c2aff7Sartem {
59518c2aff7Sartem DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
59618c2aff7Sartem DBusMessage *dmesg, *reply;
59718c2aff7Sartem char **options = NULL;
59818c2aff7Sartem uint_t num_options = 0;
59918c2aff7Sartem
60018c2aff7Sartem dprintf("ejecting %s...\n", udi);
60118c2aff7Sartem
60218c2aff7Sartem if (!(dmesg = dbus_message_new_method_call("org.freedesktop.Hal", udi,
60318c2aff7Sartem "org.freedesktop.Hal.Device.Storage", "Eject"))) {
60418c2aff7Sartem dprintf("eject %s: cannot create dbus message\n", udi);
60518c2aff7Sartem return (B_FALSE);
60618c2aff7Sartem }
60718c2aff7Sartem
60818c2aff7Sartem if (!dbus_message_append_args(dmesg,
60918c2aff7Sartem DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &options, num_options,
61018c2aff7Sartem DBUS_TYPE_INVALID)) {
61118c2aff7Sartem dprintf("eject %s: cannot append args to dbus message ", udi);
61218c2aff7Sartem dbus_message_unref(dmesg);
61318c2aff7Sartem return (B_FALSE);
61418c2aff7Sartem }
61518c2aff7Sartem
61618c2aff7Sartem dbus_error_init(error);
61718c2aff7Sartem if (!(reply = dbus_connection_send_with_reply_and_block(dbus_conn,
618b941d3fcSartem dmesg, RMM_EJECT_TIMEOUT, error))) {
61918c2aff7Sartem dprintf("eject %s: %s\n", udi, error->message);
62018c2aff7Sartem dbus_message_unref(dmesg);
62118c2aff7Sartem return (B_FALSE);
62218c2aff7Sartem }
62318c2aff7Sartem
62418c2aff7Sartem dprintf("ejected %s\n", udi);
62518c2aff7Sartem
62618c2aff7Sartem dbus_message_unref(dmesg);
62718c2aff7Sartem dbus_message_unref(reply);
62818c2aff7Sartem
62918c2aff7Sartem rmm_dbus_error_free(error);
63018c2aff7Sartem
63118c2aff7Sartem return (B_TRUE);
63218c2aff7Sartem }
63318c2aff7Sartem
63418c2aff7Sartem /*
63518c2aff7Sartem * Call HAL's CloseTray() method on the given device
63618c2aff7Sartem */
63718c2aff7Sartem boolean_t
rmm_hal_closetray(LibHalContext * hal_ctx,const char * udi,DBusError * error)63818c2aff7Sartem rmm_hal_closetray(LibHalContext *hal_ctx, const char *udi, DBusError *error)
63918c2aff7Sartem {
64018c2aff7Sartem DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
64118c2aff7Sartem DBusMessage *dmesg, *reply;
64218c2aff7Sartem char **options = NULL;
64318c2aff7Sartem uint_t num_options = 0;
64418c2aff7Sartem
64518c2aff7Sartem dprintf("closing tray %s...\n", udi);
64618c2aff7Sartem
64718c2aff7Sartem if (!(dmesg = dbus_message_new_method_call("org.freedesktop.Hal", udi,
64818c2aff7Sartem "org.freedesktop.Hal.Device.Storage", "CloseTray"))) {
64918c2aff7Sartem dprintf(
65018c2aff7Sartem "closetray failed for %s: cannot create dbus message\n",
65118c2aff7Sartem udi);
65218c2aff7Sartem return (B_FALSE);
65318c2aff7Sartem }
65418c2aff7Sartem
65518c2aff7Sartem if (!dbus_message_append_args(dmesg,
65618c2aff7Sartem DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &options, num_options,
65718c2aff7Sartem DBUS_TYPE_INVALID)) {
65818c2aff7Sartem dprintf("closetray %s: cannot append args to dbus message ",
65918c2aff7Sartem udi);
66018c2aff7Sartem dbus_message_unref(dmesg);
66118c2aff7Sartem return (B_FALSE);
66218c2aff7Sartem }
66318c2aff7Sartem
66418c2aff7Sartem dbus_error_init(error);
66518c2aff7Sartem if (!(reply = dbus_connection_send_with_reply_and_block(dbus_conn,
666b941d3fcSartem dmesg, RMM_CLOSETRAY_TIMEOUT, error))) {
66718c2aff7Sartem dprintf("closetray failed for %s: %s\n", udi, error->message);
66818c2aff7Sartem dbus_message_unref(dmesg);
66918c2aff7Sartem return (B_FALSE);
67018c2aff7Sartem }
67118c2aff7Sartem
67218c2aff7Sartem dprintf("closetray ok %s\n", udi);
67318c2aff7Sartem
67418c2aff7Sartem dbus_message_unref(dmesg);
67518c2aff7Sartem dbus_message_unref(reply);
67618c2aff7Sartem
67718c2aff7Sartem rmm_dbus_error_free(error);
67818c2aff7Sartem
67918c2aff7Sartem return (B_TRUE);
68018c2aff7Sartem }
68118c2aff7Sartem
68218c2aff7Sartem /*
68318c2aff7Sartem * Call HAL's Rescan() method on the given device
68418c2aff7Sartem */
68518c2aff7Sartem boolean_t
rmm_hal_rescan(LibHalContext * hal_ctx,const char * udi,DBusError * error)68618c2aff7Sartem rmm_hal_rescan(LibHalContext *hal_ctx, const char *udi, DBusError *error)
68718c2aff7Sartem {
68818c2aff7Sartem DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
68918c2aff7Sartem DBusMessage *dmesg, *reply;
69018c2aff7Sartem
69118c2aff7Sartem dprintf("rescanning %s...\n", udi);
69218c2aff7Sartem
69318c2aff7Sartem if (!(dmesg = dbus_message_new_method_call("org.freedesktop.Hal", udi,
69418c2aff7Sartem "org.freedesktop.Hal.Device", "Rescan"))) {
69518c2aff7Sartem dprintf("rescan failed for %s: cannot create dbus message\n",
69618c2aff7Sartem udi);
69718c2aff7Sartem return (B_FALSE);
69818c2aff7Sartem }
69918c2aff7Sartem
70018c2aff7Sartem dbus_error_init(error);
70118c2aff7Sartem if (!(reply = dbus_connection_send_with_reply_and_block(dbus_conn,
70218c2aff7Sartem dmesg, -1, error))) {
70318c2aff7Sartem dprintf("rescan failed for %s: %s\n", udi, error->message);
70418c2aff7Sartem dbus_message_unref(dmesg);
70518c2aff7Sartem return (B_FALSE);
70618c2aff7Sartem }
70718c2aff7Sartem
70818c2aff7Sartem dprintf("rescan ok %s\n", udi);
70918c2aff7Sartem
71018c2aff7Sartem dbus_message_unref(dmesg);
71118c2aff7Sartem dbus_message_unref(reply);
71218c2aff7Sartem
71318c2aff7Sartem rmm_dbus_error_free(error);
71418c2aff7Sartem
71518c2aff7Sartem return (B_TRUE);
71618c2aff7Sartem }
71718c2aff7Sartem
71818c2aff7Sartem boolean_t
rmm_hal_claim_branch(LibHalContext * hal_ctx,const char * udi)71918c2aff7Sartem rmm_hal_claim_branch(LibHalContext *hal_ctx, const char *udi)
72018c2aff7Sartem {
72118c2aff7Sartem DBusError error;
72218c2aff7Sartem DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
72318c2aff7Sartem DBusMessage *dmesg, *reply;
72418c2aff7Sartem const char *claimed_by = "rmvolmgr";
72518c2aff7Sartem
72618c2aff7Sartem dprintf("claiming branch %s...\n", udi);
72718c2aff7Sartem
72818c2aff7Sartem if (!(dmesg = dbus_message_new_method_call("org.freedesktop.Hal",
72918c2aff7Sartem "/org/freedesktop/Hal/Manager", "org.freedesktop.Hal.Manager",
73018c2aff7Sartem "ClaimBranch"))) {
73118c2aff7Sartem dprintf("cannot create dbus message\n");
73218c2aff7Sartem return (B_FALSE);
73318c2aff7Sartem }
73418c2aff7Sartem
73518c2aff7Sartem if (!dbus_message_append_args(dmesg, DBUS_TYPE_STRING, &udi,
73618c2aff7Sartem DBUS_TYPE_STRING, &claimed_by, DBUS_TYPE_INVALID)) {
73718c2aff7Sartem dprintf("cannot append args to dbus message\n");
73818c2aff7Sartem dbus_message_unref(dmesg);
73918c2aff7Sartem return (B_FALSE);
74018c2aff7Sartem }
74118c2aff7Sartem
74218c2aff7Sartem dbus_error_init(&error);
74318c2aff7Sartem if (!(reply = dbus_connection_send_with_reply_and_block(dbus_conn,
74418c2aff7Sartem dmesg, -1, &error))) {
74518c2aff7Sartem dprintf("cannot send dbus message\n");
74618c2aff7Sartem dbus_message_unref(dmesg);
74718c2aff7Sartem rmm_dbus_error_free(&error);
74818c2aff7Sartem return (B_FALSE);
74918c2aff7Sartem }
75018c2aff7Sartem
75118c2aff7Sartem dprintf("claim branch ok %s\n", udi);
75218c2aff7Sartem
75318c2aff7Sartem dbus_message_unref(dmesg);
75418c2aff7Sartem dbus_message_unref(reply);
75518c2aff7Sartem
75618c2aff7Sartem return (B_TRUE);
75718c2aff7Sartem }
75818c2aff7Sartem
75918c2aff7Sartem boolean_t
rmm_hal_unclaim_branch(LibHalContext * hal_ctx,const char * udi)76018c2aff7Sartem rmm_hal_unclaim_branch(LibHalContext *hal_ctx, const char *udi)
76118c2aff7Sartem {
76218c2aff7Sartem DBusError error;
76318c2aff7Sartem DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
76418c2aff7Sartem DBusMessage *dmesg, *reply;
76518c2aff7Sartem const char *claimed_by = "rmvolmgr";
76618c2aff7Sartem
76718c2aff7Sartem dprintf("unclaiming branch %s...\n", udi);
76818c2aff7Sartem
76918c2aff7Sartem if (!(dmesg = dbus_message_new_method_call("org.freedesktop.Hal",
77018c2aff7Sartem "/org/freedesktop/Hal/Manager", "org.freedesktop.Hal.Manager",
77118c2aff7Sartem "UnclaimBranch"))) {
77218c2aff7Sartem dprintf("cannot create dbus message\n");
77318c2aff7Sartem return (B_FALSE);
77418c2aff7Sartem }
77518c2aff7Sartem
77618c2aff7Sartem if (!dbus_message_append_args(dmesg, DBUS_TYPE_STRING, &udi,
77718c2aff7Sartem DBUS_TYPE_STRING, &claimed_by, DBUS_TYPE_INVALID)) {
77818c2aff7Sartem dprintf("cannot append args to dbus message\n");
77918c2aff7Sartem dbus_message_unref(dmesg);
78018c2aff7Sartem return (B_FALSE);
78118c2aff7Sartem }
78218c2aff7Sartem
78318c2aff7Sartem dbus_error_init(&error);
78418c2aff7Sartem if (!(reply = dbus_connection_send_with_reply_and_block(dbus_conn,
78518c2aff7Sartem dmesg, -1, &error))) {
78618c2aff7Sartem dprintf("cannot send dbus message\n");
78718c2aff7Sartem dbus_message_unref(dmesg);
78818c2aff7Sartem rmm_dbus_error_free(&error);
78918c2aff7Sartem return (B_FALSE);
79018c2aff7Sartem }
79118c2aff7Sartem
79218c2aff7Sartem dprintf("unclaim branch ok %s\n", udi);
79318c2aff7Sartem
79418c2aff7Sartem dbus_message_unref(dmesg);
79518c2aff7Sartem dbus_message_unref(reply);
79618c2aff7Sartem
79718c2aff7Sartem return (B_TRUE);
79818c2aff7Sartem }
79918c2aff7Sartem
80018c2aff7Sartem static boolean_t
rmm_action_one(LibHalContext * hal_ctx,const char * name,action_t action,const char * dev,const char * udi,LibHalVolume * v,char ** opts,int num_opts,char * mountpoint)80118c2aff7Sartem rmm_action_one(LibHalContext *hal_ctx, const char *name, action_t action,
80218c2aff7Sartem const char *dev, const char *udi, LibHalVolume *v,
80318c2aff7Sartem char **opts, int num_opts, char *mountpoint)
80418c2aff7Sartem {
80518c2aff7Sartem char dev_str[MAXPATHLEN];
80618c2aff7Sartem char *mountp;
80718c2aff7Sartem DBusError error;
80818c2aff7Sartem boolean_t ret = B_FALSE;
80918c2aff7Sartem
81018c2aff7Sartem if (strcmp(name, dev) == 0) {
81118c2aff7Sartem (void) snprintf(dev_str, sizeof (dev_str), name);
81218c2aff7Sartem } else {
81318c2aff7Sartem (void) snprintf(dev_str, sizeof (dev_str), "%s %s", name, dev);
81418c2aff7Sartem }
81518c2aff7Sartem
81618c2aff7Sartem dbus_error_init(&error);
81718c2aff7Sartem
81818c2aff7Sartem switch (action) {
81918c2aff7Sartem case EJECT:
82018c2aff7Sartem ret = rmm_hal_eject(hal_ctx, udi, &error);
82118c2aff7Sartem break;
82218c2aff7Sartem case INSERT:
82318c2aff7Sartem case REMOUNT:
82418c2aff7Sartem if (libhal_volume_is_mounted(v)) {
82518c2aff7Sartem goto done;
82618c2aff7Sartem }
82718c2aff7Sartem ret = rmm_hal_mount(hal_ctx, udi,
82818c2aff7Sartem opts, num_opts, mountpoint, &error);
82918c2aff7Sartem break;
83018c2aff7Sartem case UNMOUNT:
83118c2aff7Sartem if (!libhal_volume_is_mounted(v)) {
83218c2aff7Sartem goto done;
83318c2aff7Sartem }
83418c2aff7Sartem ret = rmm_hal_unmount(hal_ctx, udi, &error);
83518c2aff7Sartem break;
83618c2aff7Sartem case CLOSETRAY:
83718c2aff7Sartem ret = rmm_hal_closetray(hal_ctx, udi, &error);
83818c2aff7Sartem break;
83918c2aff7Sartem }
84018c2aff7Sartem
84118c2aff7Sartem if (!ret) {
84218c2aff7Sartem (void) fprintf(stderr, gettext("%s of %s failed: %s\n"),
84318c2aff7Sartem action_strings[action], dev_str, rmm_strerror(&error, -1));
84418c2aff7Sartem goto done;
84518c2aff7Sartem }
84618c2aff7Sartem
84718c2aff7Sartem switch (action) {
84818c2aff7Sartem case EJECT:
84918c2aff7Sartem (void) printf(gettext("%s ejected\n"), dev_str);
85018c2aff7Sartem break;
85118c2aff7Sartem case INSERT:
85218c2aff7Sartem case REMOUNT:
85318c2aff7Sartem mountp = rmm_get_mnttab_mount_point(dev);
85418c2aff7Sartem if (mountp != NULL) {
85518c2aff7Sartem (void) printf(gettext("%s mounted at %s\n"),
85618c2aff7Sartem dev_str, mountp);
85718c2aff7Sartem free(mountp);
85818c2aff7Sartem }
85918c2aff7Sartem break;
86018c2aff7Sartem case UNMOUNT:
86118c2aff7Sartem (void) printf(gettext("%s unmounted\n"), dev_str);
86218c2aff7Sartem break;
86318c2aff7Sartem case CLOSETRAY:
86418c2aff7Sartem (void) printf(gettext("%s tray closed\n"), dev_str);
86518c2aff7Sartem break;
86618c2aff7Sartem }
86718c2aff7Sartem
86818c2aff7Sartem done:
86918c2aff7Sartem rmm_dbus_error_free(&error);
87018c2aff7Sartem return (ret);
87118c2aff7Sartem }
87218c2aff7Sartem
87318c2aff7Sartem /*
87418c2aff7Sartem * top level action routine
87518c2aff7Sartem *
87618c2aff7Sartem * If non-null 'aa' is passed, it will be used, otherwise a local copy
87718c2aff7Sartem * will be created.
87818c2aff7Sartem */
87918c2aff7Sartem boolean_t
rmm_action(LibHalContext * hal_ctx,const char * name,action_t action,struct action_arg * aap,char ** opts,int num_opts,char * mountpoint)88018c2aff7Sartem rmm_action(LibHalContext *hal_ctx, const char *name, action_t action,
88118c2aff7Sartem struct action_arg *aap, char **opts, int num_opts, char *mountpoint)
88218c2aff7Sartem {
88318c2aff7Sartem DBusError error;
88418c2aff7Sartem GSList *volumes, *i;
88518c2aff7Sartem LibHalDrive *d;
88618c2aff7Sartem LibHalVolume *v;
88718c2aff7Sartem const char *udi, *d_udi;
88818c2aff7Sartem const char *dev, *d_dev;
88918c2aff7Sartem struct action_arg aa_local;
89018c2aff7Sartem boolean_t ret = B_FALSE;
89118c2aff7Sartem
89218c2aff7Sartem dprintf("rmm_action %s %s\n", name, action_strings[action]);
89318c2aff7Sartem
89418c2aff7Sartem if (aap == NULL) {
8957544909dSartem bzero(&aa_local, sizeof (aa_local));
89618c2aff7Sartem aap = &aa_local;
89718c2aff7Sartem }
89818c2aff7Sartem
89918c2aff7Sartem dbus_error_init(&error);
90018c2aff7Sartem
90118c2aff7Sartem /* find the drive and its volumes */
90218c2aff7Sartem d = rmm_hal_volume_find(hal_ctx, name, &error, &volumes);
90318c2aff7Sartem rmm_dbus_error_free(&error);
90418c2aff7Sartem if (d == NULL) {
90518c2aff7Sartem (void) fprintf(stderr, gettext("cannot find '%s'\n"), name);
90618c2aff7Sartem return (B_FALSE);
90718c2aff7Sartem }
90818c2aff7Sartem d_udi = libhal_drive_get_udi(d);
90918c2aff7Sartem d_dev = libhal_drive_get_device_file(d);
91018c2aff7Sartem if ((d_udi == NULL) || (d_dev == NULL)) {
91118c2aff7Sartem goto out;
91218c2aff7Sartem }
91318c2aff7Sartem
91418c2aff7Sartem /*
91518c2aff7Sartem * For those drives that do not require media eject,
91618c2aff7Sartem * EJECT turns into UNMOUNT.
91718c2aff7Sartem */
91818c2aff7Sartem if ((action == EJECT) && !libhal_drive_requires_eject(d)) {
91918c2aff7Sartem action = UNMOUNT;
92018c2aff7Sartem }
92118c2aff7Sartem
92218c2aff7Sartem /* per drive action */
92318c2aff7Sartem if ((action == EJECT) || (action == CLOSETRAY)) {
92418c2aff7Sartem ret = rmm_action_one(hal_ctx, name, action, d_dev, d_udi, NULL,
92518c2aff7Sartem opts, num_opts, NULL);
92618c2aff7Sartem
92718c2aff7Sartem if (!ret || (action == CLOSETRAY)) {
92818c2aff7Sartem goto out;
92918c2aff7Sartem }
93018c2aff7Sartem }
93118c2aff7Sartem
93218c2aff7Sartem /* per volume action */
93318c2aff7Sartem for (i = volumes; i != NULL; i = g_slist_next(i)) {
93418c2aff7Sartem v = (LibHalVolume *)i->data;
93518c2aff7Sartem udi = libhal_volume_get_udi(v);
93618c2aff7Sartem dev = libhal_volume_get_device_file(v);
93718c2aff7Sartem
93818c2aff7Sartem if ((udi == NULL) || (dev == NULL)) {
93918c2aff7Sartem continue;
94018c2aff7Sartem }
94118c2aff7Sartem if (aap == &aa_local) {
94218c2aff7Sartem if (!rmm_volume_aa_from_prop(hal_ctx, udi, v, aap)) {
94318c2aff7Sartem dprintf("rmm_volume_aa_from_prop failed %s\n",
94418c2aff7Sartem udi);
94518c2aff7Sartem continue;
94618c2aff7Sartem }
94718c2aff7Sartem }
94818c2aff7Sartem aap->aa_action = action;
94918c2aff7Sartem
95018c2aff7Sartem /* ejected above, just need postprocess */
95118c2aff7Sartem if (action != EJECT) {
95218c2aff7Sartem ret = rmm_action_one(hal_ctx, name, action, dev, udi, v,
95318c2aff7Sartem opts, num_opts, mountpoint);
95418c2aff7Sartem }
95518c2aff7Sartem if (ret) {
95618c2aff7Sartem (void) vold_postprocess(hal_ctx, udi, aap);
95718c2aff7Sartem }
95818c2aff7Sartem
95918c2aff7Sartem if (aap == &aa_local) {
96018c2aff7Sartem rmm_volume_aa_free(aap);
96118c2aff7Sartem }
96218c2aff7Sartem }
96318c2aff7Sartem
96418c2aff7Sartem out:
965*68e92846Sfei feng - Sun Microsystems - Beijing China rmm_volumes_free(volumes);
96618c2aff7Sartem libhal_drive_free(d);
96718c2aff7Sartem
96818c2aff7Sartem return (ret);
96918c2aff7Sartem }
97018c2aff7Sartem
97118c2aff7Sartem
97218c2aff7Sartem /*
97318c2aff7Sartem * rescan by name
97418c2aff7Sartem * if name is NULL, rescan all drives
97518c2aff7Sartem */
97618c2aff7Sartem boolean_t
rmm_rescan(LibHalContext * hal_ctx,const char * name,boolean_t query)97718c2aff7Sartem rmm_rescan(LibHalContext *hal_ctx, const char *name, boolean_t query)
97818c2aff7Sartem {
97918c2aff7Sartem DBusError error;
98018c2aff7Sartem GSList *volumes;
98118c2aff7Sartem LibHalDrive *drive = NULL;
98218c2aff7Sartem const char *drive_udi;
98318c2aff7Sartem char **udis;
98418c2aff7Sartem int num_udis;
98518c2aff7Sartem char *nickname;
98618c2aff7Sartem char **nicks = NULL;
98718c2aff7Sartem boolean_t do_free_udis = FALSE;
98818c2aff7Sartem int i;
9897544909dSartem boolean_t ret = B_FALSE;
99018c2aff7Sartem
99118c2aff7Sartem dprintf("rmm_rescan %s\n", name != NULL ? name : "all");
99218c2aff7Sartem
99318c2aff7Sartem dbus_error_init(&error);
99418c2aff7Sartem
99518c2aff7Sartem if (name != NULL) {
99618c2aff7Sartem if ((drive = rmm_hal_volume_find(hal_ctx, name, &error,
99718c2aff7Sartem &volumes)) == NULL) {
99818c2aff7Sartem rmm_dbus_error_free(&error);
99918c2aff7Sartem (void) fprintf(stderr,
100018c2aff7Sartem gettext("cannot find '%s'\n"), name);
100118c2aff7Sartem return (B_FALSE);
100218c2aff7Sartem }
100318c2aff7Sartem rmm_dbus_error_free(&error);
100418c2aff7Sartem g_slist_free(volumes);
100518c2aff7Sartem
100618c2aff7Sartem drive_udi = libhal_drive_get_udi(drive);
100718c2aff7Sartem udis = (char **)&drive_udi;
100818c2aff7Sartem num_udis = 1;
100918c2aff7Sartem } else {
101018c2aff7Sartem if ((udis = libhal_find_device_by_capability(hal_ctx,
101118c2aff7Sartem "storage", &num_udis, &error)) == NULL) {
101218c2aff7Sartem rmm_dbus_error_free(&error);
101318c2aff7Sartem return (B_TRUE);
101418c2aff7Sartem }
101518c2aff7Sartem rmm_dbus_error_free(&error);
101618c2aff7Sartem do_free_udis = TRUE;
101718c2aff7Sartem }
101818c2aff7Sartem
101918c2aff7Sartem for (i = 0; i < num_udis; i++) {
102018c2aff7Sartem if (name == NULL) {
102118c2aff7Sartem nicks = libhal_device_get_property_strlist(hal_ctx,
102218c2aff7Sartem udis[i], "storage.solaris.nicknames", NULL);
102318c2aff7Sartem if (nicks != NULL) {
102418c2aff7Sartem nickname = nicks[0];
102518c2aff7Sartem } else {
102618c2aff7Sartem nickname = "";
102718c2aff7Sartem }
102818c2aff7Sartem }
102918c2aff7Sartem if (!(ret = rmm_hal_rescan(hal_ctx, udis[i], &error))) {
103018c2aff7Sartem (void) fprintf(stderr,
103118c2aff7Sartem gettext("rescan of %s failed: %s\n"),
103218c2aff7Sartem name ? name : nickname,
103318c2aff7Sartem rmm_strerror(&error, -1));
103418c2aff7Sartem libhal_free_string_array(nicks);
103518c2aff7Sartem continue;
103618c2aff7Sartem }
103718c2aff7Sartem if (query) {
10387544909dSartem ret = libhal_device_get_property_bool(hal_ctx, udis[i],
10397544909dSartem "storage.removable.media_available", NULL);
10407544909dSartem if (ret) {
10417544909dSartem printf(gettext("%s is available\n"),
10427544909dSartem name ? name : nickname);
10437544909dSartem } else {
10447544909dSartem printf(gettext("%s is not available\n"),
10457544909dSartem name ? name : nickname);
10467544909dSartem }
104718c2aff7Sartem }
104818c2aff7Sartem libhal_free_string_array(nicks);
104918c2aff7Sartem }
105018c2aff7Sartem
105118c2aff7Sartem if (drive != NULL) {
105218c2aff7Sartem libhal_drive_free(drive);
105318c2aff7Sartem }
105418c2aff7Sartem if (do_free_udis) {
105518c2aff7Sartem libhal_free_string_array(udis);
105618c2aff7Sartem }
105718c2aff7Sartem
105818c2aff7Sartem return (ret);
105918c2aff7Sartem }
106018c2aff7Sartem
106118c2aff7Sartem
106218c2aff7Sartem /*
106318c2aff7Sartem * set action_arg from volume properties
106418c2aff7Sartem */
106518c2aff7Sartem boolean_t
rmm_volume_aa_from_prop(LibHalContext * hal_ctx,const char * udi_arg,LibHalVolume * volume_arg,struct action_arg * aap)106618c2aff7Sartem rmm_volume_aa_from_prop(LibHalContext *hal_ctx, const char *udi_arg,
106718c2aff7Sartem LibHalVolume *volume_arg, struct action_arg *aap)
106818c2aff7Sartem {
106918c2aff7Sartem LibHalVolume *volume = volume_arg;
107018c2aff7Sartem const char *udi = udi_arg;
107118c2aff7Sartem const char *drive_udi;
107218c2aff7Sartem char *volume_label;
107318c2aff7Sartem char *mountpoint;
107418c2aff7Sartem int len;
107518c2aff7Sartem int ret = B_FALSE;
107618c2aff7Sartem
107718c2aff7Sartem /* at least udi or volume must be supplied */
107818c2aff7Sartem if ((udi == NULL) && (volume == NULL)) {
107918c2aff7Sartem return (B_FALSE);
108018c2aff7Sartem }
108118c2aff7Sartem if (volume == NULL) {
108218c2aff7Sartem if ((volume = libhal_volume_from_udi(hal_ctx, udi)) == NULL) {
108318c2aff7Sartem dprintf("cannot get volume %s\n", udi);
108418c2aff7Sartem goto out;
108518c2aff7Sartem }
108618c2aff7Sartem }
108718c2aff7Sartem if (udi == NULL) {
108818c2aff7Sartem if ((udi = libhal_volume_get_udi(volume)) == NULL) {
108918c2aff7Sartem dprintf("cannot get udi\n");
109018c2aff7Sartem goto out;
109118c2aff7Sartem }
109218c2aff7Sartem }
109318c2aff7Sartem drive_udi = libhal_volume_get_storage_device_udi(volume);
109418c2aff7Sartem
109518c2aff7Sartem if (!(aap->aa_symdev = libhal_device_get_property_string(hal_ctx,
109618c2aff7Sartem drive_udi, "storage.solaris.legacy.symdev", NULL))) {
109718c2aff7Sartem dprintf("property %s not found %s\n",
109818c2aff7Sartem "storage.solaris.legacy.symdev", drive_udi);
109918c2aff7Sartem goto out;
110018c2aff7Sartem }
110118c2aff7Sartem if (!(aap->aa_media = libhal_device_get_property_string(hal_ctx,
110218c2aff7Sartem drive_udi, "storage.solaris.legacy.media_type", NULL))) {
110318c2aff7Sartem dprintf("property %s not found %s\n",
110418c2aff7Sartem "storage.solaris.legacy.media_type", drive_udi);
110518c2aff7Sartem goto out;
110618c2aff7Sartem }
110718c2aff7Sartem
110818c2aff7Sartem /* name is derived from volume label */
110918c2aff7Sartem aap->aa_name = NULL;
111018c2aff7Sartem if ((volume_label = (char *)libhal_device_get_property_string(hal_ctx,
111118c2aff7Sartem udi, "volume.label", NULL)) != NULL) {
111218c2aff7Sartem if ((len = strlen(volume_label)) > 0) {
111318c2aff7Sartem aap->aa_name = rmm_vold_convert_volume_label(
111418c2aff7Sartem volume_label, len);
111518c2aff7Sartem if (strlen(aap->aa_name) == 0) {
111618c2aff7Sartem free(aap->aa_name);
111718c2aff7Sartem aap->aa_name = NULL;
111818c2aff7Sartem }
111918c2aff7Sartem }
112018c2aff7Sartem libhal_free_string(volume_label);
112118c2aff7Sartem }
112218c2aff7Sartem /* if no label, then unnamed_<mediatype> */
112318c2aff7Sartem if (aap->aa_name == NULL) {
112418c2aff7Sartem aap->aa_name = (char *)calloc(1, sizeof ("unnamed_floppyNNNN"));
112518c2aff7Sartem if (aap->aa_name == NULL) {
112618c2aff7Sartem goto out;
112718c2aff7Sartem }
112818c2aff7Sartem (void) snprintf(aap->aa_name, sizeof ("unnamed_floppyNNNN"),
112918c2aff7Sartem "unnamed_%s", aap->aa_media);
113018c2aff7Sartem }
113118c2aff7Sartem
113218c2aff7Sartem if (!(aap->aa_path = libhal_device_get_property_string(hal_ctx, udi,
113318c2aff7Sartem "block.device", NULL))) {
113418c2aff7Sartem dprintf("property %s not found %s\n", "block.device", udi);
113518c2aff7Sartem goto out;
113618c2aff7Sartem }
113718c2aff7Sartem if (!(aap->aa_rawpath = libhal_device_get_property_string(hal_ctx, udi,
113818c2aff7Sartem "block.solaris.raw_device", NULL))) {
113918c2aff7Sartem dprintf("property %s not found %s\n",
114018c2aff7Sartem "block.solaris.raw_device", udi);
114118c2aff7Sartem goto out;
114218c2aff7Sartem }
114318c2aff7Sartem if (!(aap->aa_type = libhal_device_get_property_string(hal_ctx, udi,
114418c2aff7Sartem "volume.fstype", NULL))) {
114518c2aff7Sartem dprintf("property %s not found %s\n", "volume.fstype", udi);
114618c2aff7Sartem goto out;
114718c2aff7Sartem }
114818c2aff7Sartem if (!libhal_device_get_property_bool(hal_ctx, udi,
114918c2aff7Sartem "volume.is_partition", NULL)) {
115018c2aff7Sartem aap->aa_partname = NULL;
115118c2aff7Sartem } else if (!(aap->aa_partname = libhal_device_get_property_string(
115218c2aff7Sartem hal_ctx, udi, "block.solaris.slice", NULL))) {
115318c2aff7Sartem dprintf("property %s not found %s\n",
115418c2aff7Sartem "block.solaris.slice", udi);
115518c2aff7Sartem goto out;
115618c2aff7Sartem }
115718c2aff7Sartem if (!(mountpoint = libhal_device_get_property_string(hal_ctx, udi,
115818c2aff7Sartem "volume.mount_point", NULL))) {
115918c2aff7Sartem dprintf("property %s not found %s\n",
116018c2aff7Sartem "volume.mount_point", udi);
116118c2aff7Sartem goto out;
116218c2aff7Sartem }
116318c2aff7Sartem /*
116418c2aff7Sartem * aa_mountpoint can be reallocated in rmm_volume_aa_update_mountpoint()
116518c2aff7Sartem * won't have to choose between free() or libhal_free_string() later on
116618c2aff7Sartem */
116718c2aff7Sartem aap->aa_mountpoint = strdup(mountpoint);
116818c2aff7Sartem libhal_free_string(mountpoint);
116918c2aff7Sartem if (aap->aa_mountpoint == NULL) {
117018c2aff7Sartem dprintf("mountpoint is NULL %s\n", udi);
117118c2aff7Sartem goto out;
117218c2aff7Sartem }
117318c2aff7Sartem
117418c2aff7Sartem ret = B_TRUE;
117518c2aff7Sartem
117618c2aff7Sartem out:
117718c2aff7Sartem if ((volume != NULL) && (volume != volume_arg)) {
117818c2aff7Sartem libhal_volume_free(volume);
117918c2aff7Sartem }
118018c2aff7Sartem if (!ret) {
118118c2aff7Sartem rmm_volume_aa_free(aap);
118218c2aff7Sartem }
118318c2aff7Sartem return (ret);
118418c2aff7Sartem }
118518c2aff7Sartem
118618c2aff7Sartem /* ARGSUSED */
118718c2aff7Sartem void
rmm_volume_aa_update_mountpoint(LibHalContext * hal_ctx,const char * udi,struct action_arg * aap)118818c2aff7Sartem rmm_volume_aa_update_mountpoint(LibHalContext *hal_ctx, const char *udi,
118918c2aff7Sartem struct action_arg *aap)
119018c2aff7Sartem {
119118c2aff7Sartem if (aap->aa_mountpoint != NULL) {
119218c2aff7Sartem free(aap->aa_mountpoint);
119318c2aff7Sartem }
119418c2aff7Sartem aap->aa_mountpoint = rmm_get_mnttab_mount_point(aap->aa_path);
119518c2aff7Sartem }
119618c2aff7Sartem
119718c2aff7Sartem void
rmm_volume_aa_free(struct action_arg * aap)119818c2aff7Sartem rmm_volume_aa_free(struct action_arg *aap)
119918c2aff7Sartem {
120018c2aff7Sartem if (aap->aa_symdev != NULL) {
120118c2aff7Sartem libhal_free_string(aap->aa_symdev);
120218c2aff7Sartem aap->aa_symdev = NULL;
120318c2aff7Sartem }
120418c2aff7Sartem if (aap->aa_name != NULL) {
120518c2aff7Sartem free(aap->aa_name);
120618c2aff7Sartem aap->aa_name = NULL;
120718c2aff7Sartem }
120818c2aff7Sartem if (aap->aa_path != NULL) {
120918c2aff7Sartem libhal_free_string(aap->aa_path);
121018c2aff7Sartem aap->aa_path = NULL;
121118c2aff7Sartem }
121218c2aff7Sartem if (aap->aa_rawpath != NULL) {
121318c2aff7Sartem libhal_free_string(aap->aa_rawpath);
121418c2aff7Sartem aap->aa_rawpath = NULL;
121518c2aff7Sartem }
121618c2aff7Sartem if (aap->aa_type != NULL) {
121718c2aff7Sartem libhal_free_string(aap->aa_type);
121818c2aff7Sartem aap->aa_type = NULL;
121918c2aff7Sartem }
122018c2aff7Sartem if (aap->aa_media != NULL) {
122118c2aff7Sartem libhal_free_string(aap->aa_media);
122218c2aff7Sartem aap->aa_media = NULL;
122318c2aff7Sartem }
122418c2aff7Sartem if (aap->aa_partname != NULL) {
122518c2aff7Sartem libhal_free_string(aap->aa_partname);
122618c2aff7Sartem aap->aa_partname = NULL;
122718c2aff7Sartem }
122818c2aff7Sartem if (aap->aa_mountpoint != NULL) {
122918c2aff7Sartem free(aap->aa_mountpoint);
123018c2aff7Sartem aap->aa_mountpoint = NULL;
123118c2aff7Sartem }
123218c2aff7Sartem }
123318c2aff7Sartem
123418c2aff7Sartem /*
123518c2aff7Sartem * get device's mount point from mnttab
123618c2aff7Sartem */
123718c2aff7Sartem char *
rmm_get_mnttab_mount_point(const char * special)123818c2aff7Sartem rmm_get_mnttab_mount_point(const char *special)
123918c2aff7Sartem {
124018c2aff7Sartem char *mount_point = NULL;
124118c2aff7Sartem FILE *f;
124218c2aff7Sartem struct mnttab mnt;
124318c2aff7Sartem struct mnttab mpref = { NULL, NULL, NULL, NULL, NULL };
124418c2aff7Sartem
124518c2aff7Sartem if ((f = fopen(MNTTAB, "r")) != NULL) {
124618c2aff7Sartem mpref.mnt_special = (char *)special;
124718c2aff7Sartem if (getmntany(f, &mnt, &mpref) == 0) {
124818c2aff7Sartem mount_point = strdup(mnt.mnt_mountp);
124918c2aff7Sartem }
125018c2aff7Sartem fclose(f);
125118c2aff7Sartem }
125218c2aff7Sartem
125318c2aff7Sartem return (mount_point);
125418c2aff7Sartem }
125518c2aff7Sartem
125618c2aff7Sartem
125718c2aff7Sartem /*
125818c2aff7Sartem * get human readable string from error values
125918c2aff7Sartem */
126018c2aff7Sartem const char *
rmm_strerror(DBusError * dbus_error,int rmm_error)126118c2aff7Sartem rmm_strerror(DBusError *dbus_error, int rmm_error)
126218c2aff7Sartem {
126318c2aff7Sartem const char *str;
126418c2aff7Sartem
126518c2aff7Sartem if ((dbus_error != NULL) && dbus_error_is_set(dbus_error)) {
126618c2aff7Sartem str = dbus_error->message;
126718c2aff7Sartem } else {
126818c2aff7Sartem switch (rmm_error) {
126918c2aff7Sartem case RMM_EOK:
127018c2aff7Sartem str = gettext("success");
127118c2aff7Sartem break;
127218c2aff7Sartem case RMM_EDBUS_CONNECT:
127318c2aff7Sartem str = gettext("cannot connect to D-Bus");
127418c2aff7Sartem break;
127518c2aff7Sartem case RMM_EHAL_CONNECT:
127618c2aff7Sartem str = gettext("cannot connect to HAL");
127718c2aff7Sartem break;
127818c2aff7Sartem default:
127918c2aff7Sartem str = gettext("undefined error");
128018c2aff7Sartem break;
128118c2aff7Sartem }
128218c2aff7Sartem }
128318c2aff7Sartem
128418c2aff7Sartem return (str);
128518c2aff7Sartem }
128618c2aff7Sartem
128718c2aff7Sartem void
rmm_dbus_error_free(DBusError * error)128818c2aff7Sartem rmm_dbus_error_free(DBusError *error)
128918c2aff7Sartem {
129018c2aff7Sartem if (error != NULL && dbus_error_is_set(error)) {
129118c2aff7Sartem dbus_error_free(error);
129218c2aff7Sartem }
129318c2aff7Sartem }
129418c2aff7Sartem
129518c2aff7Sartem static int
rmm_vold_isbadchar(int c)129618c2aff7Sartem rmm_vold_isbadchar(int c)
129718c2aff7Sartem {
129818c2aff7Sartem int ret_val = 0;
129918c2aff7Sartem
130018c2aff7Sartem
130118c2aff7Sartem switch (c) {
130218c2aff7Sartem case '/':
130318c2aff7Sartem case ';':
130418c2aff7Sartem case '|':
130518c2aff7Sartem ret_val = 1;
130618c2aff7Sartem break;
130718c2aff7Sartem default:
130818c2aff7Sartem if (iscntrl(c) || isspace(c)) {
130918c2aff7Sartem ret_val = 1;
131018c2aff7Sartem }
131118c2aff7Sartem }
131218c2aff7Sartem
131318c2aff7Sartem return (ret_val);
131418c2aff7Sartem }
131518c2aff7Sartem
131618c2aff7Sartem char *
rmm_vold_convert_volume_label(const char * name,size_t len)131718c2aff7Sartem rmm_vold_convert_volume_label(const char *name, size_t len)
131818c2aff7Sartem {
131918c2aff7Sartem char buf[MAXNAMELEN+1];
132018c2aff7Sartem char *s = buf;
132118c2aff7Sartem int i;
132218c2aff7Sartem
132318c2aff7Sartem if (len > MAXNAMELEN) {
132418c2aff7Sartem len = MAXNAMELEN;
132518c2aff7Sartem }
132618c2aff7Sartem
132718c2aff7Sartem for (i = 0; i < len; i++) {
132818c2aff7Sartem if (name[i] == '\0') {
132918c2aff7Sartem break;
133018c2aff7Sartem }
133118c2aff7Sartem if (isgraph((int)name[i])) {
133218c2aff7Sartem if (isupper((int)name[i])) {
133318c2aff7Sartem *s++ = tolower((int)name[i]);
133418c2aff7Sartem } else if (rmm_vold_isbadchar((int)name[i])) {
133518c2aff7Sartem *s++ = '_';
133618c2aff7Sartem } else {
133718c2aff7Sartem *s++ = name[i];
133818c2aff7Sartem }
133918c2aff7Sartem }
134018c2aff7Sartem }
134118c2aff7Sartem *s = '\0';
134218c2aff7Sartem s = strdup(buf);
134318c2aff7Sartem
134418c2aff7Sartem return (s);
134518c2aff7Sartem }
134618c2aff7Sartem
134718c2aff7Sartem /*
134818c2aff7Sartem * swiped from mkdir.c
134918c2aff7Sartem */
135018c2aff7Sartem int
makepath(char * dir,mode_t mode)135118c2aff7Sartem makepath(char *dir, mode_t mode)
135218c2aff7Sartem {
135318c2aff7Sartem int err;
135418c2aff7Sartem char *slash;
135518c2aff7Sartem
135618c2aff7Sartem
135718c2aff7Sartem if ((mkdir(dir, mode) == 0) || (errno == EEXIST)) {
135818c2aff7Sartem return (0);
135918c2aff7Sartem }
136018c2aff7Sartem if (errno != ENOENT) {
136118c2aff7Sartem return (-1);
136218c2aff7Sartem }
136318c2aff7Sartem if ((slash = strrchr(dir, '/')) == NULL) {
136418c2aff7Sartem return (-1);
136518c2aff7Sartem }
136618c2aff7Sartem *slash = '\0';
136718c2aff7Sartem err = makepath(dir, mode);
136818c2aff7Sartem *slash++ = '/';
136918c2aff7Sartem
137018c2aff7Sartem if (err || (*slash == '\0')) {
137118c2aff7Sartem return (err);
137218c2aff7Sartem }
137318c2aff7Sartem
137418c2aff7Sartem return (mkdir(dir, mode));
137518c2aff7Sartem }
137618c2aff7Sartem
137718c2aff7Sartem
137818c2aff7Sartem void
dprintf(const char * fmt,...)137918c2aff7Sartem dprintf(const char *fmt, ...)
138018c2aff7Sartem {
138118c2aff7Sartem
138218c2aff7Sartem va_list ap;
138318c2aff7Sartem const char *p;
138418c2aff7Sartem char msg[BUFSIZ];
138518c2aff7Sartem char *errmsg = strerror(errno);
138618c2aff7Sartem char *s;
138718c2aff7Sartem
138818c2aff7Sartem if (rmm_debug == 0) {
138918c2aff7Sartem return;
139018c2aff7Sartem }
139118c2aff7Sartem
139218c2aff7Sartem (void) memset(msg, 0, BUFSIZ);
139318c2aff7Sartem
139418c2aff7Sartem /* scan for %m and replace with errno msg */
139518c2aff7Sartem s = &msg[strlen(msg)];
139618c2aff7Sartem p = fmt;
139718c2aff7Sartem
139818c2aff7Sartem while (*p != '\0') {
139918c2aff7Sartem if ((*p == '%') && (*(p+1) == 'm')) {
140018c2aff7Sartem (void) strcat(s, errmsg);
140118c2aff7Sartem p += 2;
140218c2aff7Sartem s += strlen(errmsg);
140318c2aff7Sartem continue;
140418c2aff7Sartem }
140518c2aff7Sartem *s++ = *p++;
140618c2aff7Sartem }
140718c2aff7Sartem *s = '\0'; /* don't forget the null byte */
140818c2aff7Sartem
140918c2aff7Sartem va_start(ap, fmt);
141018c2aff7Sartem (void) vfprintf(stderr, msg, ap);
141118c2aff7Sartem va_end(ap);
141218c2aff7Sartem }
1413