예제 #1
0
파일: vfs-dir.c 프로젝트: alfbar0/spacefm
void vfs_dir_class_init( VFSDirClass* klass )
{
    GObjectClass * object_class;

    object_class = ( GObjectClass * ) klass;
    parent_class = g_type_class_peek_parent ( klass );

    object_class->set_property = vfs_dir_set_property;
    object_class->get_property = vfs_dir_get_property;
    object_class->finalize = vfs_dir_finalize;

    /* signals */
//    klass->file_created = on_vfs_dir_file_created;
//    klass->file_deleted = on_vfs_dir_file_deleted;
//    klass->file_changed = on_vfs_dir_file_changed;

    /*
    * file-created is emitted when there is a new file created in the dir.
    * The param is VFSFileInfo of the newly created file.
    */
    signals[ FILE_CREATED_SIGNAL ] =
        g_signal_new ( "file-created",
                       G_TYPE_FROM_CLASS ( klass ),
                       G_SIGNAL_RUN_FIRST,
                       G_STRUCT_OFFSET ( VFSDirClass, file_created ),
                       NULL, NULL,
                       g_cclosure_marshal_VOID__POINTER,
                       G_TYPE_NONE, 1, G_TYPE_POINTER );

    /*
    * file-deleted is emitted when there is a file deleted in the dir.
    * The param is VFSFileInfo of the newly created file.
    */
    signals[ FILE_DELETED_SIGNAL ] =
        g_signal_new ( "file-deleted",
                       G_TYPE_FROM_CLASS ( klass ),
                       G_SIGNAL_RUN_FIRST,
                       G_STRUCT_OFFSET ( VFSDirClass, file_deleted ),
                       NULL, NULL,
                       g_cclosure_marshal_VOID__POINTER,
                       G_TYPE_NONE, 1, G_TYPE_POINTER );

    /*
    * file-changed is emitted when there is a file changed in the dir.
    * The param is VFSFileInfo of the newly created file.
    */
    signals[ FILE_CHANGED_SIGNAL ] =
        g_signal_new ( "file-changed",
                       G_TYPE_FROM_CLASS ( klass ),
                       G_SIGNAL_RUN_FIRST,
                       G_STRUCT_OFFSET ( VFSDirClass, file_changed ),
                       NULL, NULL,
                       g_cclosure_marshal_VOID__POINTER,
                       G_TYPE_NONE, 1, G_TYPE_POINTER );

    signals[ THUMBNAIL_LOADED_SIGNAL ] =
        g_signal_new ( "thumbnail-loaded",
                       G_TYPE_FROM_CLASS ( klass ),
                       G_SIGNAL_RUN_FIRST,
                       G_STRUCT_OFFSET ( VFSDirClass, thumbnail_loaded ),
                       NULL, NULL,
                       g_cclosure_marshal_VOID__POINTER,
                       G_TYPE_NONE, 1, G_TYPE_POINTER );

    signals[ FILE_LISTED_SIGNAL ] =
        g_signal_new ( "file-listed",
                       G_TYPE_FROM_CLASS ( klass ),
                       G_SIGNAL_RUN_FIRST,
                       G_STRUCT_OFFSET ( VFSDirClass, file_listed ),
                       NULL, NULL,
                       g_cclosure_marshal_VOID__BOOLEAN,
                       G_TYPE_NONE, 1, G_TYPE_BOOLEAN );

    /* FIXME: Is there better way to do this? */
    if( G_UNLIKELY( ! is_desktop_set ) )
        vfs_get_desktop_dir();

    if( ! home_trash_dir )
        vfs_get_trash_dir();
}
예제 #2
0
파일: vfs-file-task.c 프로젝트: ib/pcmanfm
static gpointer vfs_file_task_thread ( VFSFileTask* task )
{
    GList * l;
    struct stat file_stat;
    dev_t dest_dev = 0;
    GFunc funcs[] = {( GFunc ) vfs_file_task_move,
                     ( GFunc ) vfs_file_task_copy,
                     ( GFunc ) vfs_file_task_move,  /* trash */
                     ( GFunc ) vfs_file_task_delete,
                     ( GFunc ) vfs_file_task_link,
                     ( GFunc ) vfs_file_task_chown_chmod};

    if ( task->type < VFS_FILE_TASK_MOVE
            || task->type >= VFS_FILE_TASK_LAST )
        goto _exit_thread;

    task->state = VFS_FILE_TASK_RUNNING;
    task->current_file = ( char* ) task->src_paths->data;
    task->total_size = 0;

    if( task->type == VFS_FILE_TASK_TRASH )
    {
        task->dest_dir = g_build_filename( vfs_get_trash_dir(), "files", NULL );
        /* Create the trash dir if it doesn't exist */
        if( ! g_file_test( task->dest_dir, G_FILE_TEST_EXISTS ) )
            g_mkdir_with_parents( task->dest_dir, 0700 );
    }

    call_progress_callback( task );

    /* Calculate total size of all files */
    if ( task->recursive )
    {
        for ( l = task->src_paths; l; l = l->next )
        {
            if( task->dest_dir && g_str_has_prefix( task->dest_dir, (char*)l->data ) )
            {
                /* FIXME: This has serious problems */
                /* Check if source file is contained in destination dir */
                /* The src file is already in dest dir */
                if( lstat( (char*)l->data, &file_stat ) == 0
                    && S_ISDIR(file_stat.st_mode) )
                {
                    /* It's a dir */
                    if ( task->state_cb )
                    {
                        char* err;
                        char* disp_src;
                        char* disp_dest;
                        disp_src = g_filename_display_name( (char*)l->data );
                        disp_dest = g_filename_display_name( task->dest_dir );
                        err = g_strdup_printf( _("Destination directory \"%1$s\" is contained in source \"%2$s\""), disp_dest, disp_src );
                        if ( task->state_cb( task, VFS_FILE_TASK_ERROR,
                             err, task->state_cb_data ) )
                            task->state = VFS_FILE_TASK_RUNNING;
                        else
                            task->state = VFS_FILE_TASK_ABORTED;
                        g_free( disp_src );
                        g_free( disp_dest );
                        g_free( err );
                    }
                    else
                        task->state = VFS_FILE_TASK_ABORTED;
                    if ( should_abort( task ) )
                        goto _exit_thread;
                }
            }
            get_total_size_of_dir( task, ( char* ) l->data, &task->total_size );
        }
    }
    else
    {
        if ( task->type != VFS_FILE_TASK_CHMOD_CHOWN )
        {
            if ( task->dest_dir &&
                    lstat( task->dest_dir, &file_stat ) < 0 )
            {
                task->error = errno;
                call_state_callback( task, VFS_FILE_TASK_ERROR );
                if ( should_abort( task ) )
                    goto _exit_thread;
            }
            dest_dev = file_stat.st_dev;
        }

        for ( l = task->src_paths; l; l = l->next )
        {
            if ( lstat( ( char* ) l->data, &file_stat ) == -1 )
            {
                task->error = errno;
                call_state_callback( task, VFS_FILE_TASK_ERROR );
                if ( should_abort( task ) )
                    goto _exit_thread;
            }
            if ( S_ISLNK( file_stat.st_mode ) )      /* Don't do deep copy for symlinks */
                task->recursive = FALSE;
            else if ( task->type == VFS_FILE_TASK_MOVE || task->type == VFS_FILE_TASK_TRASH )
                task->recursive = ( file_stat.st_dev != dest_dev );

            if ( task->recursive )
            {
                get_total_size_of_dir( task, ( char* ) l->data,
                                       &task->total_size );
            }
            else
            {
                task->total_size += file_stat.st_size;
            }
        }
    }

    g_list_foreach( task->src_paths,
                    funcs[ task->type ],
                    task );

_exit_thread:
    if ( task->state_cb )
        call_state_callback( task, VFS_FILE_TASK_FINISH );
    else
    {
        /* FIXME: Will this cause any problem? */
        task->thread = NULL;
        vfs_file_task_free( task );
    }
    return NULL;
}