⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vfs-volume.c

📁 台湾人开发的Linux下的文件管理器
💻 C
📖 第 1 页 / 共 2 页
字号:
/**  C Implementation: vfs-volume** Description: *** Author: Hong Jen Yee (PCMan) <pcman.tw (AT) gmail.com>, (C) 2006** Copyright: See COPYING file that comes with this distribution**/#ifdef HAVE_CONFIG_H#include <config.h>#endif#include "vfs-volume.h"#include "glib-mem.h"#include <glib/gi18n.h>#ifdef HAVE_HAL#include <dbus/dbus.h>#include <dbus/dbus-glib.h>#include <dbus/dbus-glib-lowlevel.h>#include <libhal.h> /* #include <libhal-storage.h> */struct _VFSVolume{    char* udi;    char* storage_udi;    char* disp_name;    char* icon;    char* mount_point;    gboolean is_mounted;    gboolean is_hotpluggable;    gboolean is_removable;    gboolean requires_eject;};typedef struct _VFSVolumeCallbackData{    VFSVolumeCallback cb;    gpointer user_data;}VFSVolumeCallbackData;static LibHalContext* hal_context = NULL;static DBusConnection * dbus_connection = NULL;/* FIXME: Will it be better if we use GSList? */static GArray* volumes = NULL;static GArray* callbacks = NULL;static call_callbacks( VFSVolume* vol, VFSVolumeState state ){    int i;    VFSVolumeCallbackData* e;    if ( !callbacks )        return ;    e = ( VFSVolumeCallbackData* ) callbacks->data;    for ( i = 0; i < callbacks->len; ++i )    {        ( *e[ i ].cb ) ( vol, state, e[ i ].user_data );    }}static void vfs_volume_set_from_udi( VFSVolume* volume, const char* udi ){    g_free( volume->udi );    volume->udi = g_strdup( udi );    g_free( volume->mount_point );    volume->mount_point = libhal_device_get_property_string ( hal_context,                                                              udi,                                                              "volume.mount_point",                                                              NULL );    if ( volume->mount_point && !*volume->mount_point )    {        libhal_free_string( volume->mount_point );        volume->mount_point = NULL;    }    g_free( volume->storage_udi );    volume->storage_udi = libhal_device_get_property_string ( hal_context,                                                              udi,                                                              "block.storage_device",                                                              NULL );    if ( G_UNLIKELY( ! volume->mount_point ) )        volume->is_mounted = FALSE;    else        volume->is_mounted = libhal_device_get_property_bool ( hal_context,                                                               udi,                                                               "volume.is_mounted",                                                               NULL );    volume->is_hotpluggable = libhal_device_get_property_bool ( hal_context,                                                                volume->storage_udi,                                                                "storage.hotpluggable",                                                                NULL );    volume->requires_eject = libhal_device_get_property_bool ( hal_context,                                                               volume->storage_udi,                                                               "storage.requires_eject",                                                               NULL );    volume->is_removable = libhal_device_get_property_bool ( hal_context,                                                             volume->storage_udi,                                                             "storage.removable",                                                             NULL );}static VFSVolume* vfs_volume_new( const char* udi ){    VFSVolume * volume;    const char* storage_udi;    volume = g_slice_new0( VFSVolume );    vfs_volume_set_from_udi( volume, udi );    return volume;}void vfs_volume_free( VFSVolume* volume ){    g_free( volume->udi );    if ( volume->mount_point )        libhal_free_string( volume->mount_point );    if ( volume->storage_udi )        libhal_free_string( volume->storage_udi );    g_free( volume->disp_name );    g_slice_free( VFSVolume, volume );}static void vfs_volume_update_disp_name( VFSVolume* vol ){    char * disp_name = NULL;    char* label;    g_free( vol->disp_name );    if( G_UNLIKELY(vol->mount_point &&         0 == strcmp("/", vol->mount_point)) )    {        vol->disp_name = g_strdup(_("File System"));        return;    }    label = libhal_device_get_property_string ( hal_context, vol->udi, "volume.label", NULL );    if ( G_LIKELY( label ) )    {        if ( *label )            disp_name = g_strdup( label );        libhal_free_string( label );    }    /* FIXME: Display better names for cdroms and other removable media */    if ( ! disp_name )    {        char * device;        device = libhal_device_get_property_string ( hal_context, vol->udi, "block.device", NULL );        if ( G_LIKELY( device ) )        {            if ( *device )                disp_name = g_path_get_basename( device );            libhal_free_string( device );        }    }    vol->disp_name = disp_name;}static void on_hal_device_added( LibHalContext *ctx, const char *udi ){    VFSVolume * volume;    char* fs;    if ( libhal_device_get_property_bool ( ctx, udi, "volume.ignore", NULL ) )        return ;    if ( ! libhal_device_property_exists ( ctx, udi, "volume.fsusage", NULL ) )        return ;    /* g_debug("device added: %s", udi); */    fs = libhal_device_get_property_string ( ctx, udi, "volume.fsusage", NULL );    if ( !fs || ( ( strcmp ( fs, "filesystem" ) != 0 ) && ( strcmp ( fs, "crypto" ) != 0 ) ) )    {        libhal_free_string ( fs );        return ;    }g_debug("device added: %s", udi);    volume = vfs_volume_new( udi );    /* FIXME: sort items */    volumes = g_array_append_val( volumes, volume );    call_callbacks( volume, VFS_VOLUME_ADDED );}static void on_hal_device_removed( LibHalContext *ctx, const char *udi ){    int i;    VFSVolume **v, *volume;    if ( !volumes )        return ;    /* g_debug("device removed: %s", udi); */    v = ( VFSVolume** ) volumes->data;    for ( i = 0; i < volumes->len; ++i )    {        if ( 0 == strcmp( v[ i ] ->udi, udi ) )        {            volume = v[ i ];            volumes = g_array_remove_index( volumes, i );            call_callbacks( volume, VFS_VOLUME_REMOVED );            vfs_volume_free( volume );            break;        }    }}static void on_hal_property_modified( LibHalContext *ctx,                                      const char *udi,                                      const char *key,                                      dbus_bool_t is_removed,                                      dbus_bool_t is_added ){    /* FIXME: on_hal_property_modified: this func is not efficient, nor correct */    int i;    VFSVolume** v;    if ( !volumes )        return ;    v = ( VFSVolume** ) volumes->data;    for ( i = 0; i < volumes->len; ++i )    {        if ( 0 == strcmp( v[ i ] ->udi , udi ) )        {            vfs_volume_set_from_udi( v[ i ], udi );            vfs_volume_update_disp_name( v[ i ] );            call_callbacks( v[ i ], VFS_VOLUME_CHANGED );            break;        }    }}static void on_hal_condition ( LibHalContext *ctx,                               const char *udi,                               const char *condition_name,                               const char *condition_detail ){    /* FIXME: on_hal_condition: this func is not efficient, nor correct */    /* g_debug( "condition changed: %s, %s, %s\n", condition_name, condition_detail, udi ); */    int i;    VFSVolume** v;    if ( !volumes )        return ;    v = ( VFSVolume** ) volumes->data;    for ( i = 0; i < volumes->len; ++i )    {        if ( 0 == strcmp( v[ i ] ->udi , udi ) )        {            vfs_volume_set_from_udi( v[ i ], udi );            call_callbacks( v[ i ], VFS_VOLUME_CHANGED );            break;        }    }}/* This function is taken from gnome volumen manager */static dbus_bool_thal_mainloop_integration ( LibHalContext *ctx, DBusError *error ){    dbus_connection = dbus_bus_get ( DBUS_BUS_SYSTEM, error );    if ( dbus_error_is_set ( error ) )        return FALSE;    dbus_connection_setup_with_g_main ( dbus_connection, NULL );    libhal_ctx_set_dbus_connection ( ctx, dbus_connection );    return TRUE;}gboolean vfs_volume_init(){    DBusError error;    char** devices;    char** device;    int n;    if ( hal_context )        return TRUE;    hal_context = libhal_ctx_new ();    if ( hal_context )    {        dbus_error_init ( &error );        if ( hal_mainloop_integration ( hal_context, &error ) )        {            libhal_ctx_set_device_added ( hal_context, on_hal_device_added );            libhal_ctx_set_device_removed ( hal_context, on_hal_device_removed );            libhal_ctx_set_device_property_modified ( hal_context, on_hal_property_modified );            /*                libhal_ctx_set_device_new_capability (ctx, on_hal_device_new_capability);                libhal_ctx_set_device_lost_capability (ctx, on_hal_device_lost_capability);            */            libhal_ctx_set_device_condition( hal_context, on_hal_condition );            if ( libhal_ctx_init ( hal_context, &error ) )            {                devices = libhal_find_device_by_capability ( hal_context, "volume", &n, &error );                if ( devices )                {                    volumes = g_array_sized_new( FALSE, FALSE, sizeof( VFSVolume* ), n + 4 );                    for ( device = devices; *device; ++device )                    {                        on_hal_device_added( hal_context, *device );                    }                    libhal_free_string_array ( devices );                }                else                    volumes = g_array_sized_new( FALSE, FALSE, sizeof( VFSVolume* ), 4 );                if ( libhal_device_property_watch_all ( hal_context, &error ) )                {                    dbus_error_free ( &error );                    return TRUE;                }                else                {                    g_warning ( "%s\n", error.message );                }            }            else            {                g_warning ( "%s\n", error.message );            }        }        libhal_ctx_free ( hal_context );        hal_context = NULL;        dbus_error_free ( &error );    }    else    {        g_warning ( "%s\n", error.message );    }    return FALSE;}gboolean vfs_volume_clean(){    int i;    VFSVolume** vols;    if ( callbacks )        g_array_free( callbacks, TRUE );    if ( volumes )    {        vols = ( VFSVolume** ) volumes->data;        for ( i = 0; i < volumes->len; ++i )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -