00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <glib.h>
00035 #include <hal/libhal.h>
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <unistd.h>
00039 #include <string.h>
00040 #include <errno.h>
00041 #include <sys/statvfs.h>
00042
00043
00044 #include <liberipc/eripc.h>
00045
00046
00047 #include "log.h"
00048 #include "conf.h"
00049 #include "devicelist.h"
00050 #include "hal.h"
00051 #include "ipc.h"
00052 #include "system.h"
00053
00054 #define UNUSED(x) (void)(x)
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 static const gchar *UDI_MMC_HOST = "/org/freedesktop/Hal/devices/platform_mxcmci_0_mmc_host";
00067 static const gint SD_FREE_MB_ERROR_LEVEL = 1;
00068
00069
00070
00071
00072
00073
00074 static LibHalContext *halContext = NULL;
00075 static gboolean g_unmount_all_volumes = FALSE;
00076 static gpointer g_unmount_callback_data = NULL;
00077 static void (*g_unmount_callback_func)(gpointer user_data);
00078
00079 static gboolean g_remount_all_volumes = FALSE;
00080 static gpointer g_remount_callback_data = NULL;
00081 static void (*g_remount_callback_func)(gpointer user_data);
00082
00083
00084
00085
00086
00087
00088 static void hal_device_added (LibHalContext *ctx, const char *udi);
00089 static void hal_device_removed (LibHalContext *ctx, const char *udi);
00090 static void hal_device_property_modified(LibHalContext *ctx, const char *udi,
00091 const char *key,
00092 dbus_bool_t is_removed,
00093 dbus_bool_t is_added);
00094 static int hal_property_matches_udi (const char *property, const char *value,
00095 const char *udi);
00096 static char **hal_get_property_value (LibHalPropertyType type,
00097 const char *property, const char *udi,
00098 DBusError *dbus_error_pointer);
00099 static char **hal_udi_property_value (const char *property, const char *udi);
00100
00101
00102 static void volume_is_mounted (LibHalContext *ctx, const char *udi);
00103 static void remount_next_volume (void);
00104
00105 static void unmount_volumes (void);
00106 static void unmount_volume (hal_device *device);
00107 static void unmount_volume_finished (void);
00108 static gboolean device_is_internal_mmc_host(hal_device *device);
00109 static gboolean udi_is_internal_mmc_host(const char *udi);
00110 static void udi_mount_volume (const char *udi);
00111
00112
00113
00114
00115
00116
00117 gboolean hal_set_services()
00118 {
00119 gboolean retval = FALSE;
00120 DBusConnection *dbus_connection;
00121 DBusError error;
00122
00123 LOGPRINTF("entry");
00124
00125 dbus_error_init (&error);
00126
00127 halContext = libhal_ctx_new();
00128 if (halContext == NULL)
00129 {
00130 ERRORPRINTF("Failed to create HAL context");
00131 return FALSE;
00132 }
00133
00134 dbus_connection = eripc_get_system_connection(eripcClient->context);
00135
00136 retval = libhal_ctx_set_dbus_connection(halContext, dbus_connection);
00137 if (!retval)
00138 {
00139 ERRORPRINTF("Failed to setup dbus connection");
00140 return FALSE;
00141 }
00142
00143 retval = libhal_ctx_set_device_added(halContext, hal_device_added);
00144 if (!retval)
00145 {
00146 ERRORPRINTF("Failed to set callback");
00147 return FALSE;
00148 }
00149
00150 libhal_ctx_set_device_removed(halContext, hal_device_removed);
00151 libhal_ctx_set_device_property_modified(halContext, hal_device_property_modified);
00152
00153 if (!libhal_ctx_init(halContext, NULL))
00154 {
00155 ERRORPRINTF("Failed to initialize HAL connection to daemon");
00156 libhal_ctx_free(halContext);
00157 halContext = NULL;
00158 return FALSE;
00159 }
00160
00161 libhal_device_property_watch_all(halContext, &error);
00162 if (dbus_error_is_set (&error))
00163 {
00164 WARNPRINTF("Failed to watch all HAL properties: %s", error.message);
00165 dbus_error_free (&error);
00166 return FALSE;
00167 }
00168
00169 return TRUE;
00170 }
00171
00172
00173 void hal_check_dbus_error(DBusError *error)
00174 {
00175 if (dbus_error_is_set(error))
00176 {
00177 ERRORPRINTF("DBus Error! %s: %s", error->name, error->message);
00178 dbus_error_free(error);
00179 }
00180 }
00181
00182
00183 void hal_device_print(const char *udi)
00184 {
00185 g_return_if_fail(halContext != NULL);
00186
00187 libhal_device_print(halContext, udi, NULL);
00188 }
00189
00190
00191 void hal_add_devices()
00192 {
00193 LOGPRINTF("entry");
00194
00195 g_return_if_fail(halContext != NULL);
00196
00197 DBusError error;
00198 char **all_udi = NULL;
00199 char **current_udi = NULL;
00200 int num_device = 0;
00201 hal_device *device = NULL;
00202
00203 dbus_error_init(&error);
00204 all_udi = libhal_get_all_devices(halContext, &num_device, &error);
00205 hal_check_dbus_error(&error);
00206
00207 if (all_udi == NULL)
00208 {
00209 LOGPRINTF("No HAL devices. Out of memory or an error occured in HAL");
00210 return;
00211 }
00212
00213 current_udi = all_udi;
00214
00215 while ((*current_udi) != NULL)
00216 {
00217
00218
00219 char *storage_device = libhal_device_get_property_string(halContext, *current_udi, "block.storage_device", NULL);
00220 if (
00221 libhal_device_property_exists(halContext, *current_udi, "block.device", NULL)
00222 &&
00223 hal_property_matches_udi("block.is_volume", "true", *current_udi)
00224 &&
00225 hal_property_matches_udi("volume.is_mounted", "false", *current_udi)
00226 )
00227 {
00228 udi_mount_volume(*current_udi);
00229 }
00230 else if (
00231 libhal_device_property_exists(halContext, *current_udi, "block.device", NULL)
00232 &&
00233 hal_property_matches_udi("block.is_volume", "true", *current_udi)
00234 &&
00235 hal_property_matches_udi("volume.is_mounted", "true", *current_udi)
00236 )
00237 {
00238
00239
00240 volume_is_mounted(halContext, *current_udi);
00241 }
00242
00243 device = hal_device_list_add_device(halContext, *current_udi);
00244 if (storage_device) libhal_free_string(storage_device);
00245 current_udi++;
00246 }
00247 }
00248
00249
00250 char **hal_get_iterator_value(const LibHalPropertyType type, LibHalPropertySetIterator *iter)
00251 {
00252 char **value = NULL;
00253 char tmp[256];
00254
00255 if (type == LIBHAL_PROPERTY_TYPE_STRLIST)
00256 {
00257 return libhal_psi_get_strlist(iter);
00258 }
00259
00260 value = g_try_malloc0(2*sizeof(char *));
00261 if (value == NULL)
00262 {
00263 return NULL;
00264 }
00265 value[1] = NULL;
00266
00267 if (type == DBUS_TYPE_STRING)
00268 {
00269 char *hal_value = libhal_psi_get_string(iter);
00270 if (hal_value != NULL)
00271 {
00272 value[0] = g_strdup(hal_value);
00273 }
00274 }
00275 else if (type == DBUS_TYPE_BOOLEAN)
00276 {
00277 dbus_bool_t value_b = libhal_psi_get_bool(iter);
00278 if (value_b == TRUE)
00279 {
00280 value[0] = g_strdup("true");
00281 }
00282 else
00283 {
00284 value[0] = g_strdup("false");
00285 }
00286 }
00287 else if (type == DBUS_TYPE_INT32)
00288 {
00289 dbus_int32_t int_value = libhal_psi_get_int(iter);
00290 snprintf(tmp, 255, "%d", int_value);
00291 tmp[255] = '\0';
00292 value[0] = g_strdup(tmp);
00293 }
00294 else if (type == DBUS_TYPE_UINT64)
00295 {
00296 dbus_uint64_t uint_value = libhal_psi_get_uint64(iter);
00297 snprintf(tmp, 255, "%llu", uint_value);
00298 tmp[255] = '\0';
00299 value[0] = g_strdup(tmp);
00300 }
00301 else if (type == DBUS_TYPE_DOUBLE)
00302 {
00303 double dble_value = libhal_psi_get_double(iter);
00304 snprintf(tmp, 255, "%g", dble_value);
00305 tmp[255] = '\0';
00306 value[0] = g_strdup(tmp);
00307 }
00308 else
00309 {
00310 LOGPRINTF("Unhandled HAL iterator type: %d", type);
00311 }
00312 return value;
00313 }
00314
00315
00316 char **hal_property_value(const char *key, const char *udi, const hal_device* device)
00317 {
00318 char **values;
00319
00320 if ((udi == NULL) || (key == NULL))
00321 {
00322 LOGPRINTF("Warning: hal_property_value was called with a NULL value");
00323 return NULL;
00324 }
00325 if (!strcmp(key,"udi"))
00326 {
00327 char *new_udi = g_strdup(udi);
00328 if (new_udi == NULL)
00329 {
00330 return NULL;
00331 }
00332 values = g_try_malloc0(2*sizeof(char*));
00333 if (values == NULL)
00334 {
00335 g_free(new_udi);
00336 return NULL;
00337 }
00338 values[0] = new_udi;
00339 values[1] = NULL;
00340 return values;
00341 }
00342
00343 if (device != NULL)
00344 {
00345 hal_device_property *property = hal_device_list_get_property(key, device);
00346 return property->values;
00347 }
00348 return hal_udi_property_value(key, udi);
00349 }
00350
00351
00352 void hal_remount_all_volumes(gpointer callback_function, gpointer user_data)
00353 {
00354 LOGPRINTF("entry");
00355
00356 if (g_remount_callback_func != NULL)
00357 {
00358 WARNPRINTF("sorry, remounting already in progress");
00359 }
00360 else
00361 {
00362
00363 g_remount_all_volumes = TRUE;
00364 g_remount_callback_func = callback_function;
00365 g_remount_callback_data = user_data;
00366
00367
00368 remount_next_volume();
00369 }
00370 }
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404 void hal_unmount_all_volumes(gpointer callback_function, gpointer user_data)
00405 {
00406 LOGPRINTF("entry");
00407
00408 if (g_unmount_callback_func != NULL)
00409 {
00410 WARNPRINTF("sorry, unmounting already in progress");
00411 }
00412 else
00413 {
00414
00415 g_unmount_all_volumes = TRUE;
00416 g_unmount_callback_func = callback_function;
00417 g_unmount_callback_data = user_data;
00418
00419
00420 sync();
00421
00422
00423 unmount_volumes();
00424 }
00425 }
00426
00427
00428 gchar *hal_get_mountpoint_device()
00429 {
00430 LOGPRINTF("entry");
00431
00432 gchar *dev_name = NULL;
00433 hal_device *device = hal_device_list_get_root();
00434 hal_device_property *property;
00435
00436 while (device != NULL)
00437 {
00438 property = hal_device_list_get_property("volume.mount_point", device);
00439 if ((property != NULL) && (*property->values != NULL) && ((*property->values)[0] != '\0'))
00440 {
00441 if ((*property->values !=NULL) && (strcmp(*property->values, MOUNTPOINT_CARD) == 0))
00442 {
00443 property = hal_device_list_get_property("block.device", device);
00444 if ((property != NULL) && (*property->values != NULL) && ((*property->values)[0] != '\0'))
00445 {
00446 dev_name = *property->values;
00447 break;
00448 }
00449 }
00450 }
00451 device = device->next;
00452 }
00453 return dev_name;
00454 }
00455
00456
00457
00458
00459
00460
00461 static void hal_device_added(LibHalContext *ctx, const char *udi)
00462 {
00463 LOGPRINTF("entry: udi %s", udi);
00464
00465 char *storage_device = libhal_device_get_property_string(ctx, udi, "block.storage_device", NULL);
00466
00467
00468
00469
00470 if ( libhal_device_property_exists(ctx, udi, "block.device", NULL)
00471 &&
00472 hal_property_matches_udi("block.is_volume", "true", udi) )
00473 {
00474 udi_mount_volume(udi);
00475 }
00476
00477
00478 hal_device_list_add_device(ctx, udi);
00479
00480 if (storage_device) libhal_free_string(storage_device);
00481 }
00482
00483
00484 static void hal_device_removed(LibHalContext *ctx, const char *udi)
00485 {
00486 UNUSED(ctx);
00487 LOGPRINTF("entry: udi %s", udi);
00488
00489
00490
00491 hal_device *removed_device = NULL;
00492 removed_device = hal_device_list_find_device(udi);
00493 if (removed_device != NULL)
00494 {
00495
00496
00497
00498
00499 enum state_card state = sys_get_card();
00500 if (state != STATE_CARD_EJECTED)
00501 {
00502 if (device_is_internal_mmc_host(removed_device))
00503 {
00504 if (state == STATE_CARD_MOUNTED)
00505 {
00506 WARNPRINTF("card ejected before unmount, force unmount now");
00507
00508
00509 sys_spawn_async("umount -lf " MOUNTPOINT_CARD);
00510
00511
00512 ipc_send_volume_unmounted(MOUNTPOINT_CARD);
00513
00514 sys_set_card(STATE_CARD_UNMOUNTED);
00515 }
00516 else
00517 {
00518 sys_set_card(STATE_CARD_EJECTED);
00519 }
00520 }
00521 }
00522
00523
00524 hal_device_list_remove_device(udi);
00525 }
00526 else
00527 {
00528 WARNPRINTF("Cannot find device %s in hal list", udi);
00529
00530
00531
00532 }
00533 }
00534
00535
00536 static gboolean udi_is_internal_mmc_host(const char *udi)
00537 {
00538 char *ip = NULL;
00539 ip = libhal_device_get_property_string(halContext, udi, "info.parent", NULL);
00540 if (ip)
00541 {
00542
00543
00544 if (hal_property_matches_udi("info.parent", UDI_MMC_HOST, ip))
00545 {
00546 libhal_free_string(ip);
00547 return TRUE;
00548 }
00549 else
00550 {
00551 char *ipp = NULL;
00552 ipp = libhal_device_get_property_string(halContext, ip, "info.parent", NULL);
00553 libhal_free_string(ip);
00554 if (ipp)
00555 {
00556
00557 if (hal_property_matches_udi("info.parent", UDI_MMC_HOST, ipp))
00558 {
00559 libhal_free_string(ipp);
00560 return TRUE;
00561 }
00562 }
00563 }
00564 }
00565 return FALSE;
00566 }
00567
00568
00569 static void udi_mount_volume(const char *udi)
00570 {
00571 LOGPRINTF("entry udi [%s]", udi);
00572
00573 char *command = NULL;
00574
00575 if (udi_is_internal_mmc_host(udi))
00576 {
00577
00578 gint retval = rmdir(MOUNTPOINT_CARD);
00579 if ((retval == 0) || (errno == ENOENT))
00580 {
00581
00582 char *dev_name = g_path_get_basename(MOUNTPOINT_CARD);
00583 command = g_strdup_printf("halevt-mount -u %s -p %s -m 002 -o %s", udi, dev_name, MOUNT_OPTIONS);
00584 g_free(dev_name);
00585 }
00586 else
00587 {
00588 ERRORPRINTF("mounting failed, %s is already occupied (%d, %s)", MOUNTPOINT_CARD, errno, strerror(errno));
00589 }
00590 }
00591 else
00592 {
00593
00594 command = g_strdup_printf("halevt-mount -u %s -m 002 -o %s", udi, MOUNT_OPTIONS);
00595 }
00596
00597 if (command)
00598 {
00599 sys_reset_idle_time();
00600 sys_spawn_async(command);
00601 g_free(command);
00602 }
00603 }
00604
00605
00606 static gboolean device_is_internal_mmc_host(hal_device *device)
00607 {
00608 LOGPRINTF("entry");
00609 hal_device_property *property = NULL;
00610
00611 property = hal_device_list_get_property("info.parent", device);
00612 if (property && (*property->values != NULL))
00613 {
00614
00615
00616 property = hal_device_list_get_property("info.parent", hal_device_list_find_device(*property->values));
00617 if (property && (*property->values != NULL) && (strcmp(*property->values, UDI_MMC_HOST) == 0))
00618 {
00619 return TRUE;
00620 }
00621 else
00622 {
00623
00624 property = hal_device_list_get_property("info.parent", hal_device_list_find_device(*property->values));
00625 if (property && (*property->values != NULL) && (strcmp(*property->values, UDI_MMC_HOST) == 0))
00626 {
00627 return TRUE;
00628 }
00629 }
00630 }
00631 return FALSE;
00632 }
00633
00634
00635 static void hal_device_property_modified(LibHalContext *ctx, const char *udi,
00636 const char *key, dbus_bool_t is_removed, dbus_bool_t is_added)
00637 {
00638 UNUSED(is_added);
00639 LOGPRINTF("entry: udi %s, key %s, added:%d, removed:%d", udi, key, is_added, is_removed);
00640
00641 g_return_if_fail(key!=NULL);
00642
00643 if (strcmp(key,"volume.mount_point") == 0)
00644 {
00645 char *mount_point = libhal_device_get_property_string(ctx, udi, "volume.mount_point", NULL);
00646
00647 LOGPRINTF("volume.mount_point = %s", mount_point);
00648
00649 if ((mount_point != NULL) && (mount_point[0] != '\0'))
00650 {
00651 LOGPRINTF("Filled volume.mount_point, wait for is_mounted callback");
00652
00653 }
00654 else
00655 {
00656 LOGPRINTF("Cleared volume.mount_point, find in device list");
00657
00658
00659
00660
00661 hal_device *removed_device = NULL;
00662 hal_device_property *property = NULL;
00663
00664 removed_device = hal_device_list_find_device(udi);
00665
00666 if (removed_device != NULL)
00667 {
00668 property = hal_device_list_get_property("volume.mount_point", removed_device);
00669 if ((property != NULL) && (*property->values != NULL) && ((*property->values)[0] != '\0'))
00670 {
00671 LOGPRINTF("Mountpoint removed [%s]", *property->values);
00672
00673 sys_reset_idle_time();
00674
00675
00676 sys_spawn_async("halevt-mount -s");
00677
00678
00679 ipc_send_volume_unmounted(*property->values);
00680
00681 if (strcmp(*property->values, MOUNTPOINT_CARD) == 0)
00682 {
00683 sys_set_card(STATE_CARD_UNMOUNTED);
00684 }
00685
00686
00687 hal_device_list_remove_property(udi, key);
00688 }
00689 }
00690 else
00691 {
00692 WARNPRINTF("mount point for %s not found", key);
00693 }
00694 }
00695 if (mount_point) libhal_free_string(mount_point);
00696 }
00697 else if (strcmp(key,"volume.is_mounted") == 0)
00698 {
00699
00700
00701 LOGPRINTF("volume.is_mounted");
00702
00703
00704
00705
00706
00707
00708
00709 if ( libhal_device_property_exists(ctx, udi, "block.device", NULL)
00710 &&
00711 libhal_device_get_property_bool(ctx, udi, "block.is_volume", NULL) )
00712 {
00713
00714 sys_spawn_async("halevt-mount -s");
00715
00716 if (libhal_device_get_property_bool(ctx, udi, "volume.is_mounted", NULL))
00717 {
00718
00719 hal_device_list_set_property(udi, key);
00720
00721 volume_is_mounted(ctx, udi);
00722 }
00723 else
00724 {
00725
00726 }
00727 }
00728 }
00729 else if (strcmp(key,"irex.battery") == 0)
00730 {
00731 LOGPRINTF("irex.battery");
00732
00733 char *battery = libhal_device_get_property_string(ctx, udi, "irex.battery", NULL);
00734 if (battery)
00735 {
00736 sys_update_battery(battery);
00737 libhal_free_string(battery);
00738 }
00739 }
00740 else if (strcmp(key,"irex.hardware_state") == 0)
00741 {
00742 LOGPRINTF("irex.hardware_state");
00743
00744 char *hw_sate = libhal_device_get_property_string(ctx, udi, "irex.hardware_state", NULL);
00745 if (hw_sate)
00746 {
00747 sys_update_hardware(hw_sate);
00748 libhal_free_string(hw_sate);
00749 }
00750 }
00751
00752
00753 if (is_removed)
00754 {
00755 hal_device_list_remove_property(udi, key);
00756 }
00757 else
00758 {
00759 hal_device_list_set_property(udi, key);
00760 }
00761 }
00762
00763
00764 static char **hal_get_property_value(LibHalPropertyType type, const char *property, const char *udi,
00765 DBusError *dbus_error_pointer)
00766 {
00767 char **value = NULL;
00768 char tmp[256];
00769
00770 if (type == LIBHAL_PROPERTY_TYPE_STRLIST)
00771 {
00772 return libhal_device_get_property_strlist(halContext, udi, property, dbus_error_pointer);;
00773 }
00774
00775 value = g_try_malloc0(2*sizeof(char *));
00776 if (value == NULL)
00777 {
00778 return NULL;
00779 }
00780 value[1] = NULL;
00781
00782 if (type == DBUS_TYPE_STRING)
00783 {
00784 char *hal_value = libhal_device_get_property_string(halContext, udi, property, dbus_error_pointer);
00785 if (hal_value != NULL)
00786 {
00787 value[0] = g_strdup(hal_value);
00788 libhal_free_string(hal_value);
00789 }
00790 }
00791 else if (type == DBUS_TYPE_BOOLEAN)
00792 {
00793 dbus_bool_t value_b = libhal_device_get_property_bool(halContext, udi, property, dbus_error_pointer);
00794 if (value_b == TRUE)
00795 {
00796 value[0] = g_strdup("true");
00797 }
00798 else
00799 {
00800 value[0] = g_strdup("false");
00801 }
00802 }
00803 else if (type == DBUS_TYPE_INT32)
00804 {
00805 dbus_int32_t int_value = libhal_device_get_property_int(halContext, udi, property, dbus_error_pointer);
00806 snprintf(tmp, 255, "%d", int_value);
00807 tmp[255] = '\0';
00808 value[0] = g_strdup(tmp);
00809 }
00810 else if (type == DBUS_TYPE_UINT64)
00811 {
00812 dbus_uint64_t uint_value = libhal_device_get_property_uint64(halContext, udi, property, dbus_error_pointer);
00813 snprintf(tmp, 255, "%llu", uint_value);
00814 tmp[255] = '\0';
00815 value[0] = g_strdup(tmp);
00816 }
00817 else if (type == DBUS_TYPE_DOUBLE)
00818 {
00819 double dble_value = libhal_device_get_property_double(halContext, udi, property, dbus_error_pointer);
00820 snprintf(tmp, 255, "%g", dble_value);
00821 tmp[255] = '\0';
00822 value[0] = g_strdup(tmp);
00823 }
00824 else
00825 {
00826 LOGPRINTF("Unhandled HAL type for property %s, device %s: %d", property, udi, type);
00827 }
00828 return value;
00829 }
00830
00831
00832 static int hal_property_matches_udi(const char *property, const char *value, const char *udi)
00833 {
00834 DBusError dbus_error;
00835 int result = 0;
00836
00837 if ((udi == NULL) || (property == NULL) || (value == NULL))
00838 {
00839 LOGPRINTF("Warning: hal_property_matches called with a NULL value");
00840 return 0;
00841 }
00842
00843 dbus_error_init(&dbus_error);
00844
00845
00846
00847 if (libhal_device_property_exists(halContext, udi, property, &dbus_error))
00848 {
00849 LibHalPropertyType type;
00850
00851
00852
00853 hal_check_dbus_error(&dbus_error);
00854
00855 if (value == NULL)
00856 {
00857 return 1;
00858 }
00859
00860 type = libhal_device_get_property_type(halContext, udi, property, &dbus_error);
00861 hal_check_dbus_error(&dbus_error);
00862
00863
00864
00865 if (type == DBUS_TYPE_BOOLEAN)
00866 {
00867 dbus_bool_t val_bool = FALSE;
00868 if (!strcmp(value, "true"))
00869 {
00870 val_bool = TRUE;
00871 }
00872 result = (libhal_device_get_property_bool(halContext, udi, property, &dbus_error) == val_bool);
00873 }
00874 else if (type == DBUS_TYPE_STRING)
00875 {
00876 char *str_val = libhal_device_get_property_string(halContext, udi, property, &dbus_error);
00877 if (str_val != NULL)
00878 {
00879 result = (!strcmp(value, str_val));
00880 libhal_free_string(str_val);
00881 }
00882 }
00883 else if (type == DBUS_TYPE_INT32)
00884 {
00885 result = (libhal_device_get_property_int(halContext, udi, property, &dbus_error) == atoi(value));
00886 }
00887 else if (type == LIBHAL_PROPERTY_TYPE_STRING)
00888 {
00889 char **cur_str;
00890 char **str_list = libhal_device_get_property_strlist(halContext, udi, property, &dbus_error);
00891 if (str_list != NULL)
00892 {
00893 cur_str = str_list;
00894 while ((*cur_str) != NULL)
00895 {
00896 if (!strcmp((*cur_str), value))
00897 {
00898 result = 1;
00899 break;
00900 }
00901 cur_str++;
00902 }
00903 libhal_free_string_array(str_list);
00904 }
00905 }
00906 else if (type == DBUS_TYPE_UINT64)
00907 {
00908 result = ( (guint64) libhal_device_get_property_int(halContext, udi, property, &dbus_error) ==
00909 strtoull(value, NULL, 10) );
00910 }
00911 else if (type == DBUS_TYPE_DOUBLE)
00912 {
00913 result = (libhal_device_get_property_double(halContext, udi, property, &dbus_error) ==
00914 strtod(value, NULL));
00915 }
00916 else
00917 {
00918 LOGPRINTF("HAL type not handled in match (%s,%s,%s): %d", property, value, udi, type);
00919 return 0;
00920 }
00921 }
00922
00923 hal_check_dbus_error(&dbus_error);
00924
00925 return result;
00926 }
00927
00928
00929 static char **hal_udi_property_value(const char *property, const char *udi)
00930 {
00931 char **values = NULL;
00932 DBusError dbus_error;
00933
00934 if ((udi == NULL) || (property == NULL))
00935 {
00936 WARNPRINTF("hal_udi_property_value was called with a NULL value");
00937 return NULL;
00938 }
00939
00940 dbus_error_init(&dbus_error);
00941
00942 if (libhal_device_property_exists(halContext, udi, property, &dbus_error))
00943 {
00944 LibHalPropertyType type;
00945
00946 hal_check_dbus_error(&dbus_error);
00947
00948 type = libhal_device_get_property_type(halContext, udi, property, &dbus_error);
00949 hal_check_dbus_error(&dbus_error);
00950
00951 values = hal_get_property_value(type, property, udi, &dbus_error);
00952 }
00953 hal_check_dbus_error(&dbus_error);
00954
00955 return values;
00956 }
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008 static void volume_is_mounted(LibHalContext *ctx, const char *udi)
01009 {
01010
01011 char *mount_point = libhal_device_get_property_string(ctx, udi, "volume.mount_point", NULL);
01012
01013 LOGPRINTF("entry udi [%s] mount_point [%s]", udi, mount_point);
01014
01015 if (mount_point)
01016 {
01017 sys_reset_idle_time();
01018
01019
01020 gint64 mbfree = -1;
01021 gboolean readonly = FALSE;
01022 gboolean sdfull = FALSE;
01023
01024 struct statvfs s;
01025 if (statvfs(mount_point, &s) == 0)
01026 {
01027 mbfree = s.f_frsize * s.f_bavail >> 20;
01028 if (s.f_flag & ST_RDONLY)
01029 {
01030 readonly = TRUE;
01031 }
01032 }
01033
01034 LOGPRINTF("mbfree [%lld] readonly [%d]", mbfree, readonly);
01035
01036 if (mbfree == -1)
01037 {
01038 ERRORPRINTF("failed to get free space from mount point [%s]", mount_point);
01039 }
01040 else if (readonly)
01041 {
01042 ipc_show_splash("sdreadonly");
01043 }
01044 else if (mbfree <= SD_FREE_MB_ERROR_LEVEL)
01045 {
01046 ipc_show_splash("sdfull");
01047 sdfull = TRUE;
01048 }
01049
01050 if (!readonly)
01051 {
01052
01053
01054 if (sys_is_emulator())
01055 {
01056 LOGPRINTF("EMULATOR Emulate mount at [%s]", MOUNTPOINT_CARD);
01057 sys_set_card(STATE_CARD_INDEXING);
01058 }
01059 else
01060 {
01061 if (strcmp(mount_point, MOUNTPOINT_CARD) == 0)
01062 {
01063 LOGPRINTF("Internal card found at [%s]", MOUNTPOINT_CARD);
01064 if (sdfull)
01065 {
01066
01067 sys_set_card(STATE_CARD_MOUNTED);
01068 }
01069 else
01070 {
01071 sys_set_card(STATE_CARD_INDEXING);
01072 }
01073 }
01074 else
01075 {
01076 LOGPRINTF("Volume found at [%s]", mount_point);
01077 ipc_send_volume_mounted(mount_point);
01078 }
01079 }
01080 }
01081 else
01082 {
01083 if (strcmp(mount_point, MOUNTPOINT_CARD) == 0)
01084 {
01085 sys_set_card(STATE_CARD_INACCESSIBLE);
01086 }
01087
01088
01089
01090 hal_device *device = hal_device_list_find_device(udi);
01091 unmount_volume(device);
01092 }
01093
01094 libhal_free_string(mount_point);
01095 }
01096
01097 if (g_remount_all_volumes)
01098 {
01099
01100 remount_next_volume();
01101 }
01102 }
01103
01104
01105 static void unmount_volumes()
01106 {
01107 LOGPRINTF("entry");
01108
01109 hal_device *device = hal_device_list_get_root();
01110 if (device != NULL)
01111 {
01112 unmount_volume(device);
01113 }
01114 else
01115 {
01116 LOGPRINTF("no volumes to unmount");
01117 unmount_volume_finished();
01118 }
01119 }
01120
01121
01122 static void on_volume_unmounted(GPid pid, gint status, gpointer data)
01123 {
01124 UNUSED(pid);
01125 UNUSED(status);
01126 LOGPRINTF("entry");
01127
01128 hal_device *device = (hal_device *) data;
01129 if (device->next && g_unmount_all_volumes)
01130 {
01131
01132 unmount_volume(device->next);
01133 }
01134 else
01135 {
01136 LOGPRINTF("no more volumes to unmount");
01137 unmount_volume_finished();
01138 }
01139 }
01140
01141
01142 static void unmount_volume_finished(void)
01143 {
01144 LOGPRINTF("entry");
01145
01146
01147 if (g_unmount_callback_func)
01148 {
01149 LOGPRINTF("call callback handler");
01150
01151 (*g_unmount_callback_func)(g_unmount_callback_data);
01152
01153
01154 g_unmount_callback_func = NULL;
01155 g_unmount_callback_data = NULL;
01156 }
01157 else
01158 {
01159 LOGPRINTF("no callback handler");
01160 }
01161 }
01162
01163
01164 static void unmount_volume(hal_device *device)
01165 {
01166 LOGPRINTF("entry");
01167
01168 while (device != NULL)
01169 {
01170 hal_device_property *property = NULL;
01171 property = hal_device_list_get_property("volume.is_mounted", device);
01172 if ((property != NULL) && (*property->values != NULL) && ((*property->values)[0] != '\0'))
01173 {
01174 LOGPRINTF("udi %s, volume.is_mounted = %s", device->udi, *property->values);
01175 if (strcmp(*property->values, "true") == 0)
01176 {
01177 property = hal_device_list_get_property("volume.mount_point", device);
01178 if ((property != NULL) && (*property->values != NULL) && ((*property->values)[0] != '\0'))
01179 {
01180 gchar *command = NULL;
01181 command = g_strconcat("unmount.sh ", *property->values, NULL);
01182 LOGPRINTF("%s", command);
01183
01184 sys_spawn_async_with_callback(command, on_volume_unmounted, device);
01185 g_free(command);
01186 return;
01187 }
01188 }
01189 }
01190 device = device->next;
01191 }
01192
01193 LOGPRINTF("no more volumes to unmount");
01194 unmount_volume_finished();
01195 }
01196
01197
01198 static void remount_next_volume()
01199 {
01200 LOGPRINTF("entry");
01201
01202 hal_device *device = hal_device_list_get_root();
01203 hal_device_property *property = NULL;
01204
01205 while (device != NULL)
01206 {
01207 property = hal_device_list_get_property("volume.is_mounted", device);
01208 if ((property != NULL) && (*property->values != NULL) && ((*property->values)[0] != '\0'))
01209 {
01210 LOGPRINTF("udi %s, volume.is_mounted = %s", device->udi, *property->values);
01211 if (strcmp(*property->values, "false") == 0)
01212 {
01213 udi_mount_volume(device->udi);
01214 return;
01215 }
01216 }
01217 device = device->next;
01218 }
01219
01220
01221 LOGPRINTF("no more volume to remmount");
01222 g_remount_all_volumes = FALSE;
01223
01224
01225 if (g_remount_callback_func)
01226 {
01227 LOGPRINTF("call callback handler");
01228
01229 (*g_remount_callback_func)(g_remount_callback_data);
01230
01231
01232 g_remount_callback_func = NULL;
01233 g_remount_callback_data = NULL;
01234 }
01235 else
01236 {
01237 LOGPRINTF("no callback handler");
01238 }
01239 }