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

📄 xdgmime.c

📁 台湾人开发的Linux下的文件管理器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- mode: C; c-file-style: "gnu" -*- *//* xdgmime.c: XDG Mime Spec mime resolver.  Based on version 0.11 of the spec. * * More info can be found at http://www.freedesktop.org/standards/ * * Copyright (C) 2003,2004  Red Hat, Inc. * Copyright (C) 2003,2004  Jonathan Blandford <jrb@alum.mit.edu> * Copyright (C) 2006       Hong Jen Yee <pcman.tw@gmail.com> * * Licensed under the Academic Free License version 2.0 * Or under the following terms: * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//* * xdgmime is originally provided by freedesktop.org * This copy has been "heavily modified" by Hong Jen Yee to * be used in PCMan File Manager. */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include "xdgmime.h"#include "xdgmimeint.h"#include "xdgmimeglob.h"#include "xdgmimemagic.h"#include "xdgmimealias.h"#include "xdgmimeparent.h"#include "xdgmimecache.h"#include <stdio.h>#include <string.h>#include <sys/stat.h>#include <sys/types.h>#include <fcntl.h>#include <sys/time.h>#include <unistd.h>#include <assert.h>#include <glib.h>#include "vfs-file-monitor.h"/* typedef struct XdgDirTimeList XdgDirTimeList; */typedef struct XdgCallbackList XdgCallbackList;static time_t last_stat_time = 0;static XdgGlobHash *global_hash = NULL;static XdgMimeMagic *global_magic = NULL;static XdgAliasList *alias_list = NULL;static XdgParentList *parent_list = NULL;/* static XdgDirTimeList *dir_time_list = NULL; */static XdgCallbackList *callback_list = NULL;XdgMimeCache **_caches = NULL;static int n_caches = 0;const char xdg_mime_type_unknown[] = "application/octet-stream";/* 2006.01.16 added by Hong Jen Yee (PCMan) */const char xdg_mime_type_directory[] = "inode/directory";const char xdg_mime_type_executable[] = "application/x-executable";const char xdg_mime_type_plain_text[] = "text/plain";/* VFSFileMonotors used to monitor the change of mime data files */static GSList* monitor_list = NULL;static guint update_timout = 0;enum{    XDG_CHECKED_UNCHECKED,    XDG_CHECKED_VALID,    XDG_CHECKED_INVALID};struct XdgCallbackList{    XdgCallbackList *next;    XdgCallbackList *prev;    int callback_id;    XdgMimeCallback callback;    void *data;    XdgMimeDestroy destroy;};/* Function called by xdg_run_command_on_dirs.  If it returns TRUE, further * directories aren't looked at */typedef int ( *XdgDirectoryFunc ) ( const char *directory,                                    void *user_data );static gboolean xdg_mime_reload_cache( gpointer user_data );static void xdg_mime_file_changed ( VFSFileMonitor* fm,                                    VFSFileMonitorEvent event,                                    const char* file_name,                                    gpointer user_data ){    if ( 0 == update_timout )   /* Update cache */        update_timout = g_timeout_add( 1000, ( GSourceFunc ) xdg_mime_reload_cache, NULL );}static intxdg_mime_init_from_directory ( const char *directory ){    char * file_name;    struct stat st;    assert ( directory != NULL );    file_name = malloc ( strlen ( directory ) + strlen ( "/mime/mime.cache" ) + 1 );    strcpy ( file_name, directory );    strcat ( file_name, "/mime/mime.cache" );    XdgMimeCache * cache = _xdg_mime_cache_new_from_file ( file_name );    /* If non-existant files are monitored, the callback functions       will be called when the file is created. */    VFSFileMonitor* monitor = vfs_file_monitor_add( file_name,                                                    xdg_mime_file_changed, NULL );    monitor_list = g_slist_prepend( monitor_list, monitor );    if ( stat ( file_name, &st ) == 0 )    {        if ( cache != NULL )        {            _caches = realloc ( _caches, sizeof ( XdgMimeCache * ) * ( n_caches + 2 ) );            _caches[ n_caches ] = cache;            _caches[ n_caches + 1 ] = NULL;            n_caches++;            return FALSE;        }    }    free ( file_name );    file_name = malloc ( strlen ( directory ) + strlen ( "/mime/globs" ) + 1 );    strcpy ( file_name, directory );    strcat ( file_name, "/mime/globs" );    if ( stat ( file_name, &st ) == 0 )    {        _xdg_mime_glob_read_from_file ( global_hash, file_name );    }    free ( file_name );    file_name = malloc ( strlen ( directory ) + strlen ( "/mime/magic" ) + 1 );    strcpy ( file_name, directory );    strcat ( file_name, "/mime/magic" );    if ( stat ( file_name, &st ) == 0 )    {        _xdg_mime_magic_read_from_file ( global_magic, file_name );    }    free ( file_name );    file_name = malloc ( strlen ( directory ) + strlen ( "/mime/aliases" ) + 1 );    strcpy ( file_name, directory );    strcat ( file_name, "/mime/aliases" );    _xdg_mime_alias_read_from_file ( alias_list, file_name );    free ( file_name );    file_name = malloc ( strlen ( directory ) + strlen ( "/mime/subclasses" ) + 1 );    strcpy ( file_name, directory );    strcat ( file_name, "/mime/subclasses" );    _xdg_mime_parent_read_from_file ( parent_list, file_name );    free ( file_name );    return FALSE; /* Keep processing */}/* Runs a command on all the directories in the search path */void xdg_run_command_on_dirs ( XdgDirectoryFunc func,                               void *user_data ){    const char * xdg_data_home;    const char *xdg_data_dirs;    const char *ptr;    xdg_data_home = getenv ( "XDG_DATA_HOME" );    if ( xdg_data_home )    {        if ( ( func ) ( xdg_data_home, user_data ) )            return ;    }    else    {        const char *home;        home = getenv ( "HOME" );        if ( home != NULL )        {            char * guessed_xdg_home;            int stop_processing;            guessed_xdg_home = malloc ( strlen ( home ) + strlen ( "/.local/share" ) + 1 );            strcpy ( guessed_xdg_home, home );            strcat ( guessed_xdg_home, "/.local/share" );            stop_processing = ( func ) ( guessed_xdg_home, user_data );            free ( guessed_xdg_home );            if ( stop_processing )                return ;        }    }    xdg_data_dirs = getenv ( "XDG_DATA_DIRS" );    if ( xdg_data_dirs == NULL )        xdg_data_dirs = "/usr/local/share:/usr/share";    ptr = xdg_data_dirs;    while ( *ptr != '\000' )    {        const char * end_ptr;        char *dir;        int len;        int stop_processing;        end_ptr = ptr;        while ( *end_ptr != ':' && *end_ptr != '\000' )            end_ptr ++;        if ( end_ptr == ptr )        {            ptr++;            continue;        }        if ( *end_ptr == ':' )            len = end_ptr - ptr;        else            len = end_ptr - ptr + 1;        dir = malloc ( len + 1 );        strncpy ( dir, ptr, len );        dir[ len ] = '\0';        stop_processing = ( func ) ( dir, user_data );        free ( dir );        if ( stop_processing )            return ;        ptr = end_ptr;    }}void xdg_mime_init ( void ){    global_hash = _xdg_glob_hash_new ();    global_magic = _xdg_mime_magic_new ();    alias_list = _xdg_mime_alias_list_new ();    parent_list = _xdg_mime_parent_list_new ();    xdg_run_command_on_dirs ( ( XdgDirectoryFunc ) xdg_mime_init_from_directory,                              NULL );}gboolean xdg_mime_reload_cache( gpointer user_data ){    XdgCallbackList * list;    xdg_mime_shutdown();    xdg_mime_init();    update_timout = 0;    for ( list = callback_list; list; list = list->next )        ( list->callback ) ( list->data );    return FALSE;}const char *xdg_mime_get_mime_type_for_data ( const void *data,                                  size_t len ){    const char * mime_type;    if ( _caches )        return _xdg_mime_cache_get_mime_type_for_data ( data, len );    mime_type = _xdg_mime_magic_lookup_data ( global_magic, data, len, NULL, 0 );    if ( mime_type )        return mime_type;    return XDG_MIME_TYPE_UNKNOWN;}/* 2006.02.26 added by Hong Jen Yee */int xdg_mime_is_text_file( const char *file_path, const char* mime_type ){    int file;    unsigned char data[ 256 ];    int rlen;    int i;    int ret = 0;    if ( mime_type            && xdg_mime_mime_type_subclass( mime_type, XDG_MIME_TYPE_PLAIN_TEXT ) )    {        return 1;    }    if ( !file_path )    {        return 0;    }    file = open ( file_path, O_RDONLY );    if ( file != -1 )    {        rlen = read ( file, data, sizeof( data ) );        if ( rlen != -1 )        {            for ( i = 0; i < rlen; ++i )            {                if ( data[ i ] == '\0' )                {                    break;                }            }            if ( i >= rlen )            {                ret = 1;            }        }        close ( file );    }    return ret;}/* 2006.02.26 added by Hong Jen Yee */int xdg_mime_is_executable_file( const char *file_path, const char* mime_type ){    int file;    int i;    int ret = 0;    if ( !mime_type )    {        mime_type = xdg_mime_get_mime_type_for_file( file_path, NULL, NULL );    }    /*    * Only executable types can be executale.    * Since some common types, such as application/x-shellscript,    * are not in mime database, we have to add them ourselves.    */    if ( xdg_mime_mime_type_subclass( mime_type, XDG_MIME_TYPE_EXECUTABLE ) ||            xdg_mime_mime_type_subclass( mime_type, "application/x-shellscript" ) )    {        if ( file_path )        {            if ( ! g_file_test( file_path, G_FILE_TEST_IS_EXECUTABLE ) )                return 0;        }        return 1;    }    return 0;}

⌨️ 快捷键说明

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