summaryrefslogtreecommitdiffstats
path: root/abs/chroot-devel/pcmanfm/vfs-file-info.c
diff options
context:
space:
mode:
Diffstat (limited to 'abs/chroot-devel/pcmanfm/vfs-file-info.c')
-rw-r--r--abs/chroot-devel/pcmanfm/vfs-file-info.c699
1 files changed, 0 insertions, 699 deletions
diff --git a/abs/chroot-devel/pcmanfm/vfs-file-info.c b/abs/chroot-devel/pcmanfm/vfs-file-info.c
deleted file mode 100644
index a397893..0000000
--- a/abs/chroot-devel/pcmanfm/vfs-file-info.c
+++ /dev/null
@@ -1,699 +0,0 @@
-/*
-* C Implementation: vfs-file-info
-*
-* Description: File information
-*
-*
-* Author: Hong Jen Yee (PCMan) <pcman.tw (AT) gmail.com>, (C) 2006
-*
-* Copyright: See COPYING file that comes with this distribution
-*
-*/
-
-#include "vfs-file-info.h"
-#include <glib.h>
-#include "glib-mem.h"
-#include <glib/gi18n.h>
-#include <grp.h> /* Query group name */
-#include <pwd.h> /* Query user name */
-#include <string.h>
-
-#include "vfs-app-desktop.h"
-#include "vfs-thumbnail-loader.h"
-#include "vfs-utils.h" /* for vfs_load_icon */
-
-static int big_thumb_size = 48, small_thumb_size = 20;
-static gboolean utf8_file_name = FALSE;
-
-void vfs_file_info_set_utf8_filename( gboolean is_utf8 )
-{
- utf8_file_name = is_utf8;
-}
-
-VFSFileInfo* vfs_file_info_new ()
-{
- VFSFileInfo * fi = g_slice_new0( VFSFileInfo );
- fi->n_ref = 1;
- return fi;
-}
-
-static void vfs_file_info_clear( VFSFileInfo* fi )
-{
- if ( fi->disp_name && fi->disp_name != fi->name )
- {
- g_free( fi->disp_name );
- fi->disp_name = NULL;
- }
- if ( fi->name )
- {
- g_free( fi->name );
- fi->name = NULL;
- }
- if ( fi->disp_size )
- {
- g_free( fi->disp_size );
- fi->disp_size = NULL;
- }
- if ( fi->disp_owner )
- {
- g_free( fi->disp_owner );
- fi->disp_owner = NULL;
- }
- if ( fi->disp_mtime )
- {
- g_free( fi->disp_mtime );
- fi->disp_mtime = NULL;
- }
- if ( fi->big_thumbnail )
- {
- gdk_pixbuf_unref( fi->big_thumbnail );
- fi->big_thumbnail = NULL;
- }
- if ( fi->small_thumbnail )
- {
- gdk_pixbuf_unref( fi->small_thumbnail );
- fi->small_thumbnail = NULL;
- }
-
- fi->disp_perm[ 0 ] = '\0';
-
- if ( fi->mime_type )
- {
- vfs_mime_type_unref( fi->mime_type );
- fi->mime_type = NULL;
- }
- fi->flags = VFS_FILE_INFO_NONE;
-}
-
-VFSFileInfo* vfs_file_info_ref( VFSFileInfo* fi )
-{
- g_atomic_int_inc( &fi->n_ref );
- return fi;
-}
-
-void vfs_file_info_unref( VFSFileInfo* fi )
-{
- if ( g_atomic_int_dec_and_test( &fi->n_ref) )
- {
- vfs_file_info_clear( fi );
- g_slice_free( VFSFileInfo, fi );
- }
-}
-
-gboolean vfs_file_info_get( VFSFileInfo* fi,
- const char* file_path,
- const char* base_name )
-{
- struct stat file_stat;
- vfs_file_info_clear( fi );
-
- if ( base_name )
- fi->name = g_strdup( base_name );
- else
- fi->name = g_path_get_basename( file_path );
-
- if ( lstat( file_path, &file_stat ) == 0 )
- {
- /* This is time-consuming but can save much memory */
- fi->mode = file_stat.st_mode;
- fi->dev = file_stat.st_dev;
- fi->uid = file_stat.st_uid;
- fi->gid = file_stat.st_gid;
- fi->size = file_stat.st_size;
- fi->mtime = file_stat.st_mtime;
- fi->atime = file_stat.st_atime;
- fi->blksize = file_stat.st_blksize;
- fi->blocks = file_stat.st_blocks;
-
- if ( G_LIKELY( utf8_file_name && g_utf8_validate ( fi->name, -1, NULL ) ) )
- {
- fi->disp_name = fi->name; /* Don't duplicate the name and save memory */
- }
- else
- {
- fi->disp_name = g_filename_display_name( fi->name );
- }
- fi->mime_type = vfs_mime_type_get_from_file( file_path,
- fi->disp_name,
- &file_stat );
- return TRUE;
- }
- else
- fi->mime_type = vfs_mime_type_get_from_type( XDG_MIME_TYPE_UNKNOWN );
- return FALSE;
-}
-
-const char* vfs_file_info_get_name( VFSFileInfo* fi )
-{
- return fi->name;
-}
-
-/* Get displayed name encoded in UTF-8 */
-const char* vfs_file_info_get_disp_name( VFSFileInfo* fi )
-{
- return fi->disp_name;
-}
-
-void vfs_file_info_set_disp_name( VFSFileInfo* fi, const char* name )
-{
- if ( fi->disp_name && fi->disp_name != fi->name )
- g_free( fi->disp_name );
- fi->disp_name = g_strdup( name );
-}
-
-void vfs_file_info_set_name( VFSFileInfo* fi, const char* name )
-{
- g_free( fi->name );
- fi->name = g_strdup( name );
-}
-
-off_t vfs_file_info_get_size( VFSFileInfo* fi )
-{
- return fi->size;
-}
-
-const char* vfs_file_info_get_disp_size( VFSFileInfo* fi )
-{
- if ( G_UNLIKELY( !fi->disp_size ) )
- {
- char buf[ 64 ];
- vfs_file_size_to_string( buf, fi->size );
- fi->disp_size = g_strdup( buf );
- }
- return fi->disp_size;
-}
-
-off_t vfs_file_info_get_blocks( VFSFileInfo* fi )
-{
- return fi->blocks;
-}
-
-VFSMimeType* vfs_file_info_get_mime_type( VFSFileInfo* fi )
-{
- vfs_mime_type_ref( fi->mime_type );
- return fi->mime_type;
-}
-
-void vfs_file_info_reload_mime_type( VFSFileInfo* fi,
- const char* full_path )
-{
- VFSMimeType * old_mime_type;
- struct stat file_stat;
-
- /* convert VFSFileInfo to struct stat */
- /* In current implementation, only st_mode is used in
- mime-type detection, so let's save some CPU cycles
- and don't copy unused fields.
- */
- file_stat.st_mode = fi->mode;
- /*
- file_stat.st_dev = fi->dev;
- file_stat.st_uid = fi->uid;
- file_stat.st_gid = fi->gid;
- file_stat.st_size = fi->size;
- file_stat.st_mtime = fi->mtime;
- file_stat.st_atime = fi->atime;
- file_stat.st_blksize = fi->blksize;
- file_stat.st_blocks = fi->blocks;
- */
- old_mime_type = fi->mime_type;
- fi->mime_type = vfs_mime_type_get_from_file( full_path,
- fi->name, &file_stat );
- vfs_file_info_load_special_info( fi, full_path );
- vfs_mime_type_unref( old_mime_type ); /* FIXME: is vfs_mime_type_unref needed ?*/
-}
-
-const char* vfs_file_info_get_mime_type_desc( VFSFileInfo* fi )
-{
- return vfs_mime_type_get_description( fi->mime_type );
-}
-
-GdkPixbuf* vfs_file_info_get_big_icon( VFSFileInfo* fi )
-{
- /* get special icons for special files, especially for
- some desktop icons */
-
- if ( G_UNLIKELY( fi->flags != VFS_FILE_INFO_NONE ) )
- {
- int w, h;
- int icon_size;
- vfs_mime_type_get_icon_size( &icon_size, NULL );
- if ( fi->big_thumbnail )
- {
- w = gdk_pixbuf_get_width( fi->big_thumbnail );
- h = gdk_pixbuf_get_height( fi->big_thumbnail );
- }
- else
- w = h = 0;
-
- if ( ABS( MAX( w, h ) - icon_size ) > 2 )
- {
- char * icon_name = NULL;
- if ( fi->big_thumbnail )
- {
- icon_name = ( char* ) g_object_steal_data(
- G_OBJECT(fi->big_thumbnail), "name" );
- gdk_pixbuf_unref( fi->big_thumbnail );
- fi->big_thumbnail = NULL;
- }
- if ( G_LIKELY( icon_name ) )
- {
- if ( G_UNLIKELY( icon_name[ 0 ] == '/' ) )
- fi->big_thumbnail = gdk_pixbuf_new_from_file( icon_name, NULL );
- else
- fi->big_thumbnail = vfs_load_icon(
- gtk_icon_theme_get_default(),
- icon_name, icon_size );
- }
- if ( fi->big_thumbnail )
- g_object_set_data_full( G_OBJECT(fi->big_thumbnail), "name", icon_name, g_free );
- else
- g_free( icon_name );
- }
- return fi->big_thumbnail ? gdk_pixbuf_ref( fi->big_thumbnail ) : NULL;
- }
- if( G_UNLIKELY(!fi->mime_type) )
- return NULL;
- return vfs_mime_type_get_icon( fi->mime_type, TRUE );
-}
-
-GdkPixbuf* vfs_file_info_get_small_icon( VFSFileInfo* fi )
-{
- return vfs_mime_type_get_icon( fi->mime_type, FALSE );
-}
-
-GdkPixbuf* vfs_file_info_get_big_thumbnail( VFSFileInfo* fi )
-{
- return fi->big_thumbnail ? gdk_pixbuf_ref( fi->big_thumbnail ) : NULL;
-}
-
-GdkPixbuf* vfs_file_info_get_small_thumbnail( VFSFileInfo* fi )
-{
- return fi->small_thumbnail ? gdk_pixbuf_ref( fi->small_thumbnail ) : NULL;
-}
-
-const char* vfs_file_info_get_disp_owner( VFSFileInfo* fi )
-{
- struct passwd * puser;
- struct group* pgroup;
- char uid_str_buf[ 32 ];
- char* user_name;
- char gid_str_buf[ 32 ];
- char* group_name;
-
- /* FIXME: user names should be cached */
- if ( ! fi->disp_owner )
- {
- puser = getpwuid( fi->uid );
- if ( puser && puser->pw_name && *puser->pw_name )
- user_name = puser->pw_name;
- else
- {
- sprintf( uid_str_buf, "%d", fi->uid );
- user_name = uid_str_buf;
- }
-
- pgroup = getgrgid( fi->gid );
- if ( pgroup && pgroup->gr_name && *pgroup->gr_name )
- group_name = pgroup->gr_name;
- else
- {
- sprintf( gid_str_buf, "%d", fi->gid );
- group_name = gid_str_buf;
- }
- fi->disp_owner = g_strdup_printf ( "%s:%s", user_name, group_name );
- }
- return fi->disp_owner;
-}
-
-const char* vfs_file_info_get_disp_mtime( VFSFileInfo* fi )
-{
- if ( ! fi->disp_mtime )
- {
- char buf[ 64 ];
- strftime( buf, sizeof( buf ),
- "%Y-%m-%d %H:%M",
- localtime( &fi->mtime ) );
- fi->disp_mtime = g_strdup( buf );
- }
- return fi->disp_mtime;
-}
-
-time_t* vfs_file_info_get_mtime( VFSFileInfo* fi )
-{
- return & fi->mtime;
-}
-
-time_t* vfs_file_info_get_atime( VFSFileInfo* fi )
-{
- return & fi->atime;
-}
-
-static void get_file_perm_string( char* perm, mode_t mode )
-{
- perm[ 0 ] = S_ISDIR( mode ) ? 'd' : ( S_ISLNK( mode ) ? 'l' : '-' );
- perm[ 1 ] = ( mode & S_IRUSR ) ? 'r' : '-';
- perm[ 2 ] = ( mode & S_IWUSR ) ? 'w' : '-';
- perm[ 3 ] = ( mode & S_IXUSR ) ? 'x' : '-';
- perm[ 4 ] = ( mode & S_IRGRP ) ? 'r' : '-';
- perm[ 5 ] = ( mode & S_IWGRP ) ? 'w' : '-';
- perm[ 6 ] = ( mode & S_IXGRP ) ? 'x' : '-';
- perm[ 7 ] = ( mode & S_IROTH ) ? 'r' : '-';
- perm[ 8 ] = ( mode & S_IWOTH ) ? 'w' : '-';
- perm[ 9 ] = ( mode & S_IXOTH ) ? 'x' : '-';
- perm[ 10 ] = '\0';
-}
-
-const char* vfs_file_info_get_disp_perm( VFSFileInfo* fi )
-{
- if ( ! fi->disp_perm[ 0 ] )
- get_file_perm_string( fi->disp_perm,
- fi->mode );
- return fi->disp_perm;
-}
-
-void vfs_file_size_to_string( char* buf, guint64 size )
-{
- char * unit;
- /* guint point; */
- gfloat val;
-
- /*
- FIXME: Is floating point calculation slower than integer division?
- Some profiling is needed here.
- */
- if ( size > ( ( guint64 ) 1 ) << 30 )
- {
- if ( size > ( ( guint64 ) 1 ) << 40 )
- {
- /*
- size /= ( ( ( guint64 ) 1 << 40 ) / 10 );
- point = ( guint ) ( size % 10 );
- size /= 10;
- */
- val = ((gfloat)size) / ( ( guint64 ) 1 << 40 );
- unit = "TB";
- }
- else
- {
- /*
- size /= ( ( 1 << 30 ) / 10 );
- point = ( guint ) ( size % 10 );
- size /= 10;
- */
- val = ((gfloat)size) / ( ( guint64 ) 1 << 30 );
- unit = "GB";
- }
- }
- else if ( size > ( 1 << 20 ) )
- {
- /*
- size /= ( ( 1 << 20 ) / 10 );
- point = ( guint ) ( size % 10 );
- size /= 10;
- */
- val = ((gfloat)size) / ( ( guint64 ) 1 << 20 );
- unit = "MB";
- }
- else if ( size > ( 1 << 10 ) )
- {
- /*
- size /= ( ( 1 << 10 ) / 10 );
- point = size % 10;
- size /= 10;
- */
- val = ((gfloat)size) / ( ( guint64 ) 1 << 10 );
- unit = "KB";
- }
- else
- {
- unit = size > 1 ? "Bytes" : "Byte";
- sprintf( buf, "%u %s", ( guint ) size, unit );
- return ;
- }
- /* sprintf( buf, "%llu.%u %s", size, point, unit ); */
- sprintf( buf, "%.1f %s", val, unit );
-}
-
-gboolean vfs_file_info_is_dir( VFSFileInfo* fi )
-{
- if ( S_ISDIR( fi->mode ) )
- return TRUE;
- if ( S_ISLNK( fi->mode ) &&
- 0 == strcmp( vfs_mime_type_get_type( fi->mime_type ), XDG_MIME_TYPE_DIRECTORY ) )
- {
- return TRUE;
- }
- return FALSE;
-}
-
-gboolean vfs_file_info_is_symlink( VFSFileInfo* fi )
-{
- return S_ISLNK( fi->mode ) ? TRUE : FALSE;
-}
-
-gboolean vfs_file_info_is_image( VFSFileInfo* fi )
-{
- /* FIXME: We had better use functions of xdg_mime to check this */
- if ( ! strncmp( "image/", vfs_mime_type_get_type( fi->mime_type ), 6 ) )
- return TRUE;
- return FALSE;
-}
-
-gboolean vfs_file_info_is_desktop_entry( VFSFileInfo* fi )
-{
- return 0 != (fi->flags & VFS_FILE_INFO_DESKTOP_ENTRY);
-}
-
-gboolean vfs_file_info_is_unknown_type( VFSFileInfo* fi )
-{
- if ( ! strcmp( XDG_MIME_TYPE_UNKNOWN,
- vfs_mime_type_get_type( fi->mime_type ) ) )
- return TRUE;
- return FALSE;
-}
-
-/* full path of the file is required by this function */
-gboolean vfs_file_info_is_executable( VFSFileInfo* fi, const char* file_path )
-{
- //return mime_type_is_executable_file( file_path, fi->mime_type->type );
- return mime_type_is_executable_file( file_path, "crfap" );
-}
-
-/* full path of the file is required by this function */
-gboolean vfs_file_info_is_text( VFSFileInfo* fi, const char* file_path )
-{
- return mime_type_is_text_file( file_path, fi->mime_type->type );
-}
-
-/*
-* Run default action of specified file.
-* Full path of the file is required by this function.
-*/
-gboolean vfs_file_info_open_file( VFSFileInfo* fi,
- const char* file_path,
- GError** err )
-{
- VFSMimeType * mime_type;
- char* app_name;
- VFSAppDesktop* app;
- GList* files = NULL;
- gboolean ret = FALSE;
- char* argv[ 2 ];
-
- if ( vfs_file_info_is_executable( fi, file_path ) )
- {
- argv[ 0 ] = (char *) file_path;
- argv[ 1 ] = '\0';
- ret = g_spawn_async( NULL, argv, NULL, G_SPAWN_STDOUT_TO_DEV_NULL|
- G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, err );
- }
- else
- {
- mime_type = vfs_file_info_get_mime_type( fi );
- app_name = vfs_mime_type_get_default_action( mime_type );
- if ( app_name )
- {
- app = vfs_app_desktop_new( app_name );
- if ( ! vfs_app_desktop_get_exec( app ) )
- app->exec = g_strdup( app_name ); /* FIXME: app->exec */
- files = g_list_prepend( files, (gpointer) file_path );
- /* FIXME: working dir is needed */
- ret = vfs_app_desktop_open_files( gdk_screen_get_default(),
- NULL, app, files, err );
- g_list_free( files );
- vfs_app_desktop_unref( app );
- g_free( app_name );
- }
- vfs_mime_type_unref( mime_type );
- }
- return ret;
-}
-
-mode_t vfs_file_info_get_mode( VFSFileInfo* fi )
-{
- return fi->mode;
-}
-
-gboolean vfs_file_info_is_thumbnail_loaded( VFSFileInfo* fi, gboolean big )
-{
- if ( big )
- return ( fi->big_thumbnail != NULL );
- return ( fi->small_thumbnail != NULL );
-}
-
-gboolean vfs_file_info_load_thumbnail( VFSFileInfo* fi,
- const char* full_path,
- gboolean big )
-{
- GdkPixbuf* thumbnail;
-
- if ( big )
- {
- if ( fi->big_thumbnail )
- return TRUE;
- }
- else
- {
- if ( fi->small_thumbnail )
- return TRUE;
- }
- thumbnail = vfs_thumbnail_load_for_file( full_path,
- big ? big_thumb_size : small_thumb_size , fi->mtime );
- if( G_LIKELY( thumbnail ) )
- {
- if ( big )
- fi->big_thumbnail = thumbnail;
- else
- fi->small_thumbnail = thumbnail;
- }
- else /* fallback to mime_type icon */
- {
- if ( big )
- fi->big_thumbnail = vfs_file_info_get_big_icon( fi );
- else
- fi->small_thumbnail = vfs_file_info_get_small_icon( fi );
- }
- return ( thumbnail != NULL );
-}
-
-void vfs_file_info_set_thumbnail_size( int big, int small )
-{
- big_thumb_size = big;
- small_thumb_size = small;
-}
-
-void vfs_file_info_load_special_info( VFSFileInfo* fi,
- const char* file_path )
-{
- /*if ( G_LIKELY(fi->type) && G_UNLIKELY(fi->type->name, "application/x-desktop") ) */
- if ( G_UNLIKELY( g_str_has_suffix( fi->name, ".desktop") ) )
- {
- VFSAppDesktop * desktop;
- const char* icon_name;
-
- fi->flags |= VFS_FILE_INFO_DESKTOP_ENTRY;
- desktop = vfs_app_desktop_new( file_path );
- if ( vfs_app_desktop_get_disp_name( desktop ) )
- {
- vfs_file_info_set_disp_name(
- fi, vfs_app_desktop_get_disp_name( desktop ) );
- }
-
- if ( (icon_name = vfs_app_desktop_get_icon_name( desktop )) )
- {
- GdkPixbuf* icon;
- int big_size, small_size;
- vfs_mime_type_get_icon_size( &big_size, &small_size );
- if( ! fi->big_thumbnail )
- {
- icon = vfs_app_desktop_get_icon( desktop, big_size, FALSE );
- if( G_LIKELY(icon) )
- fi->big_thumbnail =icon;
- }
- if( ! fi->small_thumbnail )
- {
- icon = vfs_app_desktop_get_icon( desktop, small_size, FALSE );
- if( G_LIKELY(icon) )
- fi->small_thumbnail =icon;
- }
- }
- vfs_app_desktop_unref( desktop );
- }
-}
-
-void vfs_file_info_list_free( GList* list )
-{
- g_list_foreach( list, (GFunc)vfs_file_info_unref, NULL );
- g_list_free( list );
-}
-
-
-char* vfs_file_resolve_path( const char* cwd, const char* relative_path )
-{
- GString* ret = g_string_sized_new( 4096 );
- int len;
- gboolean strip_tail;
-
- g_return_val_if_fail( G_LIKELY(relative_path), NULL );
-
- len = strlen( relative_path );
- strip_tail = (0 == len || relative_path[len-1] != '/');
-
- if( G_UNLIKELY(*relative_path != '/') ) /* relative path */
- {
- if( G_UNLIKELY(relative_path[0] == '~') ) /* home dir */
- {
- g_string_append( ret, g_get_home_dir());
- ++relative_path;
- }
- else
- {
- if( ! cwd )
- {
- char *cwd_new;
- cwd_new = g_get_current_dir();
- g_string_append( ret, cwd_new );
- g_free( cwd_new );
- }
- else
- g_string_append( ret, cwd );
- }
- }
-
- if( relative_path[0] != '/' && (0 == ret->len || ret->str[ ret->len - 1 ] != '/' ) )
- g_string_append_c( ret, '/' );
-
- while( G_LIKELY( *relative_path ) )
- {
- if( G_UNLIKELY(*relative_path == '.') )
- {
- if( relative_path[1] == '/' || relative_path[1] == '\0' ) /* current dir */
- {
- relative_path += relative_path[1] ? 2 : 1;
- continue;
- }
- if( relative_path[1] == '.' &&
- ( relative_path[2] == '/' || relative_path[2] == '\0') ) /* parent dir */
- {
- gsize len = ret->len - 2;
- while( ret->str[ len ] != '/' )
- --len;
- g_string_truncate( ret, len + 1 );
- relative_path += relative_path[2] ? 3 : 2;
- continue;
- }
- }
-
- do
- {
- g_string_append_c( ret, *relative_path );
- }while( G_LIKELY( *(relative_path++) != '/' && *relative_path ) );
- }
-
- /* if original path contains tailing '/', preserve it; otherwise, remove it. */
- if( strip_tail && G_LIKELY( ret->len > 1 ) && G_UNLIKELY( ret->str[ ret->len - 1 ] == '/' ) )
- g_string_truncate( ret, ret->len - 1 );
- return g_string_free( ret, FALSE );
-}
-