/* $Id$ * gnome-vfs init/shutdown implementation of interface to libcaptive * Copyright (C) 2002-2003 Jan Kratochvil * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; exactly version 2 of June 1991 is required * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "gnome-vfs-method.h" /* self */ #include "giognomevfs.h" #include #include #include "captive/macros.h" #include "gnome-vfs-module.h" #include "captive/client-directory.h" #include "captive/client-file.h" #include "captive/client-vfs.h" #include static GnomeVFSMethod GnomeVFSMethod_static; G_LOCK_DEFINE_STATIC(GnomeVFSMethod_static); /* map: (gchar *)method_name -> (struct method_name_info *) */ static GHashTable *method_name_hash; G_LOCK_DEFINE_STATIC(method_name_hash); struct method_name_info { gchar *captive_args; struct captive_options captive_options; }; static void method_name_hash_key_destroy_func(gchar *key) { g_return_if_fail(key!=NULL); g_free(key); } static void method_name_hash_value_destroy_func(struct method_name_info *value) { g_return_if_fail(value!=NULL); g_free(value->captive_args); captive_options_free(&value->captive_options); g_free(value); } static void method_name_hash_init(void) { G_LOCK(method_name_hash); if (!method_name_hash) { method_name_hash=g_hash_table_new_full( g_str_hash, /* hash_func */ g_str_equal, /* key_equal_func */ (GDestroyNotify)method_name_hash_key_destroy_func, /* key_destroy_func */ (GDestroyNotify)method_name_hash_value_destroy_func); /* value_destroy_func */ } G_UNLOCK(method_name_hash); } /* map: (gchar *)uri_parent_string "method_name:uri_parent" -> (CaptiveVfsObject *)captive_vfs_object */ static GHashTable *uri_parent_string_hash; G_LOCK_DEFINE_STATIC(uri_parent_string_hash); static void uri_parent_string_hash_key_destroy_func(gchar *key) { g_return_if_fail(key!=NULL); g_free(key); } static void uri_parent_string_hash_value_destroy_func(CaptiveVfsObject *value) { g_return_if_fail(value!=NULL); g_object_unref(value); } static void uri_parent_string_hash_init(void) { G_LOCK(uri_parent_string_hash); if (!uri_parent_string_hash) { uri_parent_string_hash=g_hash_table_new_full( g_str_hash, /* hash_func */ g_str_equal, /* key_equal_func */ (GDestroyNotify)uri_parent_string_hash_key_destroy_func, /* key_destroy_func */ (GDestroyNotify)uri_parent_string_hash_value_destroy_func); /* value_destroy_func */ } G_UNLOCK(uri_parent_string_hash); } static GnomeVFSResult captive_gnomevfs_uri_parent_init(CaptiveVfsObject **captive_vfs_object_return,GnomeVFSURI *uri) { const gchar *uri_parent_string; gchar *uri_parent_string_parent; GnomeVFSResult errvfsresult; CaptiveVfsObject *captive_vfs_object; g_return_val_if_fail(uri!=NULL,GNOME_VFS_ERROR_INVALID_URI); g_return_val_if_fail(captive_vfs_object_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); uri_parent_string_hash_init(); if (!uri->parent) return GNOME_VFS_ERROR_INVALID_URI; if (!uri->text) /* not needed here but we don't permit non-specific fs-image reference */ return GNOME_VFS_ERROR_INVALID_URI; uri_parent_string_parent=gnome_vfs_uri_to_string(uri->parent,GNOME_VFS_URI_HIDE_NONE); g_assert(uri_parent_string_parent!=NULL); uri_parent_string=captive_printf_alloca("%s:%s",uri->method_string,uri_parent_string_parent); g_assert(uri_parent_string!=NULL); G_LOCK(uri_parent_string_hash); captive_vfs_object=g_hash_table_lookup(uri_parent_string_hash,uri_parent_string); G_UNLOCK(uri_parent_string_hash); if (!captive_vfs_object) { struct method_name_info *method_name_info; struct captive_options options_captive; G_LOCK(method_name_hash); method_name_info=g_hash_table_lookup(method_name_hash,uri->method_string); G_UNLOCK(method_name_hash); if (!method_name_info) g_return_val_if_reached(GNOME_VFS_ERROR_INVALID_URI); /* should not happend */ captive_options_copy(&options_captive,&method_name_info->captive_options); g_assert(options_captive.image_iochannel==NULL); errvfsresult=captive_gnomevfs_giognomevfs_new( (struct captive_gnomevfs_giognomevfs **)&options_captive.image_iochannel, /* giognomevfsp */ uri->parent, /* uri */ options_captive.rwmode); /* rwmode */ if (errvfsresult!=GNOME_VFS_OK) { captive_options_free(&options_captive); g_assert_not_reached(); return errvfsresult; } errvfsresult=captive_vfs_new(&captive_vfs_object,&options_captive); if (errvfsresult!=GNOME_VFS_OK) { captive_options_free(&options_captive); g_assert_not_reached(); return errvfsresult; } captive_options_free(&options_captive); G_LOCK(uri_parent_string_hash); g_hash_table_insert(uri_parent_string_hash,g_strdup(uri_parent_string),captive_vfs_object); G_UNLOCK(uri_parent_string_hash); } *captive_vfs_object_return=captive_vfs_object; return GNOME_VFS_OK; } static GnomeVFSResult captive_gnomevfs_open_directory(GnomeVFSMethod *method, GnomeVFSMethodHandle **method_handle,GnomeVFSURI *uri,GnomeVFSFileInfoOptions options,GnomeVFSContext *context) { GnomeVFSResult errvfsresult; CaptiveVfsObject *captive_vfs_object; CaptiveDirectoryObject *captive_directory_object; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(method_handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); errvfsresult=captive_gnomevfs_uri_parent_init(&captive_vfs_object,uri); g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); G_LOCK(libcaptive); errvfsresult=captive_directory_new_open( &captive_directory_object, /* captive_directory_object_return */ captive_vfs_object, /* captive_vfs_object */ uri->text); /* pathname */ G_UNLOCK(libcaptive); *method_handle=(GnomeVFSMethodHandle *)captive_directory_object; return errvfsresult; } static GnomeVFSResult captive_gnomevfs_close_directory(GnomeVFSMethod *method, GnomeVFSMethodHandle *method_handle,GnomeVFSContext *context) { CaptiveDirectoryObject *captive_directory_object; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); captive_directory_object=(CaptiveDirectoryObject *)method_handle; g_return_val_if_fail(CAPTIVE_DIRECTORY_IS_OBJECT(captive_directory_object),GNOME_VFS_ERROR_BAD_PARAMETERS); G_LOCK(libcaptive); g_object_unref(captive_directory_object); G_UNLOCK(libcaptive); return GNOME_VFS_OK; } static GnomeVFSResult captive_gnomevfs_read_directory(GnomeVFSMethod *method, GnomeVFSMethodHandle *method_handle,GnomeVFSFileInfo *file_info,GnomeVFSContext *context) { GnomeVFSResult errvfsresult; CaptiveDirectoryObject *captive_directory_object; CaptiveFileInfoObject *captive_file_info_object; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); captive_directory_object=(CaptiveDirectoryObject *)method_handle; g_return_val_if_fail(CAPTIVE_DIRECTORY_IS_OBJECT(captive_directory_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(file_info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); G_LOCK(libcaptive); errvfsresult=captive_directory_read(captive_directory_object,&captive_file_info_object); G_UNLOCK(libcaptive); if (GNOME_VFS_OK!=errvfsresult) return errvfsresult; gnome_vfs_file_info_copy(file_info,&captive_file_info_object->p); G_LOCK(libcaptive); g_object_unref(captive_file_info_object); G_UNLOCK(libcaptive); return GNOME_VFS_OK; } static GnomeVFSResult captive_gnomevfs_make_directory(GnomeVFSMethod *method, GnomeVFSURI *uri,guint perm,GnomeVFSContext *context) { GnomeVFSResult errvfsresult; CaptiveVfsObject *captive_vfs_object; CaptiveDirectoryObject *captive_directory_object; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); errvfsresult=captive_gnomevfs_uri_parent_init(&captive_vfs_object,uri); g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); G_LOCK(libcaptive); errvfsresult=captive_directory_new_make( &captive_directory_object, /* captive_directory_object_return */ captive_vfs_object, /* captive_vfs_object */ uri->text, /* pathname */ perm); /* perm */ G_UNLOCK(libcaptive); if (errvfsresult!=GNOME_VFS_OK) return errvfsresult; G_LOCK(libcaptive); g_object_unref(captive_directory_object); G_UNLOCK(libcaptive); return GNOME_VFS_OK; } static GnomeVFSResult captive_gnomevfs_remove_directory(GnomeVFSMethod *method, GnomeVFSURI *uri,GnomeVFSContext *context) { GnomeVFSResult errvfsresult; CaptiveVfsObject *captive_vfs_object; CaptiveDirectoryObject *captive_directory_object; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); errvfsresult=captive_gnomevfs_uri_parent_init(&captive_vfs_object,uri); g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); G_LOCK(libcaptive); errvfsresult=captive_directory_new_open( &captive_directory_object, /* captive_directory_object_return */ captive_vfs_object, /* captive_vfs_object */ uri->text); /* pathname */ G_UNLOCK(libcaptive); if (errvfsresult!=GNOME_VFS_OK) return errvfsresult; G_LOCK(libcaptive); errvfsresult=captive_directory_remove(captive_directory_object); G_UNLOCK(libcaptive); G_LOCK(libcaptive); g_object_unref(captive_directory_object); G_UNLOCK(libcaptive); return errvfsresult; } static GnomeVFSResult captive_gnomevfs_open(GnomeVFSMethod *method, GnomeVFSMethodHandle **method_handle_return,GnomeVFSURI *uri,GnomeVFSOpenMode mode,GnomeVFSContext *context) { GnomeVFSResult errvfsresult; CaptiveVfsObject *captive_vfs_object; CaptiveFileObject *captive_file_object; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(method_handle_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); errvfsresult=captive_gnomevfs_uri_parent_init(&captive_vfs_object,uri); g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); G_LOCK(libcaptive); errvfsresult=captive_file_new_open( &captive_file_object, /* captive_file_object_return */ captive_vfs_object, /* captive_vfs_object */ uri->text, /* pathname */ mode); /* mode */ G_UNLOCK(libcaptive); *method_handle_return=(GnomeVFSMethodHandle *)captive_file_object; return errvfsresult; } static GnomeVFSResult captive_gnomevfs_create(GnomeVFSMethod *method, GnomeVFSMethodHandle **method_handle_return,GnomeVFSURI *uri,GnomeVFSOpenMode mode,gboolean exclusive,guint perm, GnomeVFSContext *context) { GnomeVFSResult errvfsresult; CaptiveVfsObject *captive_vfs_object; CaptiveFileObject *captive_file_object; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(method_handle_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); errvfsresult=captive_gnomevfs_uri_parent_init(&captive_vfs_object,uri); g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); G_LOCK(libcaptive); errvfsresult=captive_file_new_create( &captive_file_object, /* captive_file_object_return */ captive_vfs_object, /* captive_vfs_object */ uri->text, /* pathname */ mode, /* mode */ exclusive, /* exclusive */ perm); /* perm */ G_UNLOCK(libcaptive); *method_handle_return=(GnomeVFSMethodHandle *)captive_file_object; return errvfsresult; } GnomeVFSResult captive_gnomevfs_unlink(GnomeVFSMethod *method, GnomeVFSURI *uri,GnomeVFSContext *context) { GnomeVFSResult errvfsresult; CaptiveVfsObject *captive_vfs_object; CaptiveFileObject *captive_file_object; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); errvfsresult=captive_gnomevfs_uri_parent_init(&captive_vfs_object,uri); g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); G_LOCK(libcaptive); errvfsresult=captive_file_new_open( &captive_file_object, /* captive_file_object_return */ captive_vfs_object, /* captive_vfs_object */ uri->text, /* pathname */ (GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_WRITE | GNOME_VFS_OPEN_RANDOM)); /* mode; is it OK? */ G_UNLOCK(libcaptive); if (errvfsresult!=GNOME_VFS_OK) return errvfsresult; G_LOCK(libcaptive); errvfsresult=captive_file_remove(captive_file_object); G_UNLOCK(libcaptive); G_LOCK(libcaptive); g_object_unref(captive_file_object); G_UNLOCK(libcaptive); return errvfsresult; } static GnomeVFSResult captive_gnomevfs_close(GnomeVFSMethod *method, GnomeVFSMethodHandle *method_handle,GnomeVFSContext *context) { CaptiveFileObject *captive_file_object; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); captive_file_object=(CaptiveFileObject *)method_handle; g_return_val_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS); G_LOCK(libcaptive); g_object_unref(captive_file_object); G_UNLOCK(libcaptive); return GNOME_VFS_OK; } static GnomeVFSResult captive_gnomevfs_read(GnomeVFSMethod *method,GnomeVFSMethodHandle *method_handle, gpointer buffer,GnomeVFSFileSize num_bytes,GnomeVFSFileSize *bytes_read_return,GnomeVFSContext *context) { GnomeVFSResult errvfsresult; CaptiveFileObject *captive_file_object; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); captive_file_object=(CaptiveFileObject *)method_handle; g_return_val_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(buffer!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(bytes_read_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); G_LOCK(libcaptive); errvfsresult=captive_file_read(captive_file_object,buffer,num_bytes,bytes_read_return); G_UNLOCK(libcaptive); return errvfsresult; } static GnomeVFSResult captive_gnomevfs_write(GnomeVFSMethod *method,GnomeVFSMethodHandle *method_handle, gconstpointer buffer,GnomeVFSFileSize num_bytes,GnomeVFSFileSize *bytes_written_return,GnomeVFSContext *context) { GnomeVFSResult errvfsresult; CaptiveFileObject *captive_file_object; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); captive_file_object=(CaptiveFileObject *)method_handle; g_return_val_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(buffer!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(bytes_written_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); G_LOCK(libcaptive); errvfsresult=captive_file_write(captive_file_object,buffer,num_bytes,bytes_written_return); G_UNLOCK(libcaptive); return errvfsresult; } static GnomeVFSResult captive_gnomevfs_seek(GnomeVFSMethod *method, GnomeVFSMethodHandle *method_handle,GnomeVFSSeekPosition whence,GnomeVFSFileOffset offset,GnomeVFSContext *context) { GnomeVFSResult errvfsresult; CaptiveFileObject *captive_file_object; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); captive_file_object=(CaptiveFileObject *)method_handle; g_return_val_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS); G_LOCK(libcaptive); errvfsresult=captive_file_seek(captive_file_object,whence,offset); G_UNLOCK(libcaptive); return errvfsresult; } static GnomeVFSResult captive_gnomevfs_tell(GnomeVFSMethod *method, GnomeVFSMethodHandle *method_handle,GnomeVFSFileOffset *offset_return) { GnomeVFSResult errvfsresult; CaptiveFileObject *captive_file_object; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); captive_file_object=(CaptiveFileObject *)method_handle; g_return_val_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(offset_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); G_LOCK(libcaptive); errvfsresult=captive_file_tell(captive_file_object,offset_return); G_UNLOCK(libcaptive); return errvfsresult; } static gboolean captive_gnomevfs_is_local(GnomeVFSMethod *method,const GnomeVFSURI *uri) { g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(uri!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); return gnome_vfs_uri_is_local(uri->parent); } static GnomeVFSResult captive_gnomevfs_get_file_info(GnomeVFSMethod *method, GnomeVFSURI *uri,GnomeVFSFileInfo *file_info,GnomeVFSFileInfoOptions options,GnomeVFSContext *context) { GnomeVFSResult errvfsresult; CaptiveVfsObject *captive_vfs_object; CaptiveFileObject *captive_file_object; CaptiveFileInfoObject *captive_file_info_object; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(file_info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); /* handle 'options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE'? */ errvfsresult=captive_gnomevfs_uri_parent_init(&captive_vfs_object,uri); g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); G_LOCK(libcaptive); errvfsresult=captive_file_new_open( &captive_file_object, /* captive_file_object_return */ captive_vfs_object, /* captive_vfs_object */ uri->text, /* pathname */ 0); /* mode; 0 means FILE_READ_ATTRIBUTES */ G_UNLOCK(libcaptive); if (errvfsresult!=GNOME_VFS_OK) return errvfsresult; G_LOCK(libcaptive); errvfsresult=captive_file_file_info_get(captive_file_object,&captive_file_info_object); G_UNLOCK(libcaptive); if (GNOME_VFS_OK!=errvfsresult) goto fail_g_object_unref_captive_file_object; gnome_vfs_file_info_copy(file_info,&captive_file_info_object->p); G_LOCK(libcaptive); g_object_unref(captive_file_info_object); G_UNLOCK(libcaptive); fail_g_object_unref_captive_file_object: G_LOCK(libcaptive); g_object_unref(captive_file_object); G_UNLOCK(libcaptive); return errvfsresult; } GnomeVFSResult captive_gnomevfs_get_file_info_from_handle(GnomeVFSMethod *method, GnomeVFSMethodHandle *method_handle,GnomeVFSFileInfo *file_info,GnomeVFSFileInfoOptions options,GnomeVFSContext *context) { GnomeVFSResult errvfsresult; CaptiveFileObject *captive_file_object; CaptiveFileInfoObject *captive_file_info_object; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); captive_file_object=(CaptiveFileObject *)method_handle; g_return_val_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(file_info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); /* handle 'options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE'? */ G_LOCK(libcaptive); errvfsresult=captive_file_file_info_get(captive_file_object,&captive_file_info_object); G_UNLOCK(libcaptive); if (GNOME_VFS_OK!=errvfsresult) return errvfsresult; gnome_vfs_file_info_copy(file_info,&captive_file_info_object->p); G_LOCK(libcaptive); g_object_unref(captive_file_info_object); G_UNLOCK(libcaptive); return GNOME_VFS_OK; } GnomeVFSResult captive_gnomevfs_truncate_handle(GnomeVFSMethod *method, GnomeVFSMethodHandle *handle,GnomeVFSFileSize length,GnomeVFSContext *context) { GnomeVFSResult errvfsresult; CaptiveFileObject *captive_file_object; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); captive_file_object=(CaptiveFileObject *)handle; g_return_val_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS); G_LOCK(libcaptive); errvfsresult=captive_file_truncate(captive_file_object,length); G_UNLOCK(libcaptive); return errvfsresult; } GnomeVFSResult captive_gnomevfs_truncate(GnomeVFSMethod *method, GnomeVFSURI *uri,GnomeVFSFileSize length,GnomeVFSContext *context) { GnomeVFSResult errvfsresult; CaptiveVfsObject *captive_vfs_object; CaptiveFileObject *captive_file_object; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); errvfsresult=captive_gnomevfs_uri_parent_init(&captive_vfs_object,uri); g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); G_LOCK(libcaptive); errvfsresult=captive_file_new_open( &captive_file_object, /* captive_file_object_return */ captive_vfs_object, /* captive_vfs_object */ uri->text, /* pathname */ (GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_WRITE | GNOME_VFS_OPEN_RANDOM)); /* mode; is it OK? */ G_UNLOCK(libcaptive); if (errvfsresult!=GNOME_VFS_OK) return errvfsresult; G_LOCK(libcaptive); errvfsresult=captive_file_truncate(captive_file_object,length); G_UNLOCK(libcaptive); G_LOCK(libcaptive); g_object_unref(captive_file_object); G_UNLOCK(libcaptive); return errvfsresult; } GnomeVFSResult captive_gnomevfs_move(GnomeVFSMethod *method, GnomeVFSURI *old_uri,GnomeVFSURI *new_uri,gboolean force_replace,GnomeVFSContext *context) { GnomeVFSResult errvfsresult; CaptiveVfsObject *captive_old_vfs_object; CaptiveVfsObject *captive_new_vfs_object; CaptiveFileObject *captive_old_file_object; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); errvfsresult=captive_gnomevfs_uri_parent_init(&captive_old_vfs_object,old_uri); g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); errvfsresult=captive_gnomevfs_uri_parent_init(&captive_new_vfs_object,new_uri); g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); if (captive_old_vfs_object!=captive_new_vfs_object) return GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM; G_LOCK(libcaptive); errvfsresult=captive_file_new_open( &captive_old_file_object, /* captive_file_object_return */ captive_old_vfs_object, /* captive_vfs_object; ==captive_new_vfs_object */ old_uri->text, /* pathname */ (GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_WRITE)); /* mode; is it OK? */ G_UNLOCK(libcaptive); if (errvfsresult!=GNOME_VFS_OK) return errvfsresult; G_LOCK(libcaptive); errvfsresult=captive_file_move(captive_old_file_object,new_uri->text,force_replace); G_UNLOCK(libcaptive); G_LOCK(libcaptive); g_object_unref(captive_old_file_object); G_UNLOCK(libcaptive); return errvfsresult; } GnomeVFSResult captive_gnomevfs_check_same_fs(GnomeVFSMethod *method, GnomeVFSURI *a,GnomeVFSURI *b,gboolean *same_fs_return,GnomeVFSContext *context) { CaptiveVfsObject *captive_vfs_object_a; CaptiveVfsObject *captive_vfs_object_b; GnomeVFSResult errvfsresult; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(same_fs_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); errvfsresult=captive_gnomevfs_uri_parent_init(&captive_vfs_object_a,a); g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); errvfsresult=captive_gnomevfs_uri_parent_init(&captive_vfs_object_b,b); g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); *same_fs_return=(captive_vfs_object_a==captive_vfs_object_b); return GNOME_VFS_OK; } GnomeVFSResult captive_gnomevfs_set_file_info(GnomeVFSMethod *method, GnomeVFSURI *a,const GnomeVFSFileInfo *info,GnomeVFSSetFileInfoMask mask,GnomeVFSContext *context) { GnomeVFSResult errvfsresult; CaptiveVfsObject *captive_vfs_object; CaptiveFileObject *captive_file_object; CaptiveFileInfoObject *captive_file_info_object; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); errvfsresult=captive_gnomevfs_uri_parent_init(&captive_vfs_object,a); g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); G_LOCK(libcaptive); errvfsresult=captive_file_new_open( &captive_file_object, /* captive_file_object_return */ captive_vfs_object, /* captive_vfs_object */ a->text, /* pathname */ (GNOME_VFS_OPEN_WRITE | GNOME_VFS_OPEN_RANDOM)); /* mode; is it OK? */ G_UNLOCK(libcaptive); if (errvfsresult!=GNOME_VFS_OK) return errvfsresult; G_LOCK(libcaptive); errvfsresult=captive_file_info_object_new(&captive_file_info_object); G_UNLOCK(libcaptive); if (errvfsresult!=GNOME_VFS_OK) goto fail_g_object_unref_captive_file_object; captive_file_info_object->p=*info; /* Unsupported by GnomeVFS, see: http://bugzilla.gnome.org/show_bug.cgi?id=325427 */ captive_file_info_object->atime_nsec=0; captive_file_info_object->mtime_nsec=0; captive_file_info_object->ctime_nsec=0; G_LOCK(libcaptive); errvfsresult=captive_file_file_info_set(captive_file_object,captive_file_info_object,mask); G_UNLOCK(libcaptive); G_LOCK(libcaptive); g_object_unref(captive_file_info_object); G_UNLOCK(libcaptive); fail_g_object_unref_captive_file_object: G_LOCK(libcaptive); g_object_unref(captive_file_object); G_UNLOCK(libcaptive); return errvfsresult; } /** * captive_gnomevfs_init: * * Returns: Initialized structure of #GnomeVFSMethod with static methods of libcaptive-gnomevfs. */ GnomeVFSMethod *captive_gnomevfs_method_init(const gchar *method_name,const gchar *captive_args) { struct method_name_info *method_name_info; g_return_val_if_fail(method_name!=NULL,NULL); g_return_val_if_fail(captive_args!=NULL,NULL); method_name_hash_init(); G_LOCK(method_name_hash); method_name_info=g_hash_table_lookup(method_name_hash,method_name); if (method_name_info && strcmp(method_name_info->captive_args,captive_args)) method_name_info=NULL; G_UNLOCK(method_name_hash); if (!method_name_info) { captive_new(method_name_info); method_name_info->captive_args=g_strdup(captive_args); captive_options_init(&method_name_info->captive_options); if (!captive_options_parse(&method_name_info->captive_options,captive_args)) { g_assert_not_reached(); g_free(method_name_info->captive_args); g_free(method_name_info); return NULL; } G_LOCK(method_name_hash); g_hash_table_replace(method_name_hash,g_strdup(method_name),method_name_info); G_UNLOCK(method_name_hash); } G_LOCK(GnomeVFSMethod_static); CAPTIVE_MEMZERO(&GnomeVFSMethod_static); GnomeVFSMethod_static.method_table_size=sizeof(GnomeVFSMethod_static); GnomeVFSMethod_static.open =captive_gnomevfs_open; /* mandatory */ GnomeVFSMethod_static.create =captive_gnomevfs_create; /* mandatory */ GnomeVFSMethod_static.close =captive_gnomevfs_close; GnomeVFSMethod_static.read =captive_gnomevfs_read; GnomeVFSMethod_static.write =captive_gnomevfs_write; GnomeVFSMethod_static.seek =captive_gnomevfs_seek; GnomeVFSMethod_static.tell =captive_gnomevfs_tell; GnomeVFSMethod_static.truncate_handle =captive_gnomevfs_truncate_handle; GnomeVFSMethod_static.open_directory =captive_gnomevfs_open_directory; GnomeVFSMethod_static.close_directory =captive_gnomevfs_close_directory; GnomeVFSMethod_static.read_directory =captive_gnomevfs_read_directory; GnomeVFSMethod_static.get_file_info =captive_gnomevfs_get_file_info; /* mandatory */ GnomeVFSMethod_static.get_file_info_from_handle=captive_gnomevfs_get_file_info_from_handle; GnomeVFSMethod_static.is_local =captive_gnomevfs_is_local; /* mandatory */ GnomeVFSMethod_static.make_directory =captive_gnomevfs_make_directory; GnomeVFSMethod_static.remove_directory =captive_gnomevfs_remove_directory; GnomeVFSMethod_static.move =captive_gnomevfs_move; GnomeVFSMethod_static.unlink =captive_gnomevfs_unlink; GnomeVFSMethod_static.check_same_fs =captive_gnomevfs_check_same_fs; GnomeVFSMethod_static.set_file_info =captive_gnomevfs_set_file_info; GnomeVFSMethod_static.truncate =captive_gnomevfs_truncate; /* TODO: GnomeVFSMethodFindDirectoryFunc find_directory; */ /* TODO: GnomeVFSMethodCreateSymbolicLinkFunc create_symbolic_link; */ /* TODO: GnomeVFSMethodMonitorAddFunc monitor_add; */ /* TODO: GnomeVFSMethodMonitorCancelFunc monitor_cancel; */ /* TODO: GnomeVFSMethodFileControlFunc file_control; */ G_UNLOCK(GnomeVFSMethod_static); return &GnomeVFSMethod_static; } /** * captive_gnomevfs_method_shutdown: * * Shutdowns libcaptive-gnomevfs successfuly flushing all caches. * * This operation may not completely clean up the process space * if libcaptive #sandbox is not in use. * * Sad note about gnome-vfs-2.1.5 is that it never calls this function. :-) */ void captive_gnomevfs_method_shutdown(void) { uri_parent_string_hash_init(); G_LOCK(uri_parent_string_hash); g_hash_table_destroy(uri_parent_string_hash); uri_parent_string_hash=NULL; G_UNLOCK(uri_parent_string_hash); method_name_hash_init(); G_LOCK(method_name_hash); g_hash_table_destroy(method_name_hash); method_name_hash=NULL; G_UNLOCK(method_name_hash); }