X-Git-Url: http://git.jankratochvil.net/?a=blobdiff_plain;f=src%2Flibcaptive%2Fclient%2Ffile-parent.c;h=8fdf41e78fc04703b168de677b34cb95f6b20c53;hb=21dea5024c2fba9bcbe080dbd917dd27562c1190;hp=e0348ffdd84d495335a9a668f89b6b9bdf73c0bd;hpb=ecce6d1e3521682c5b5fff2320b352747e7d3910;p=captive.git diff --git a/src/libcaptive/client/file-parent.c b/src/libcaptive/client/file-parent.c index e0348ff..8fdf41e 100644 --- a/src/libcaptive/client/file-parent.c +++ b/src/libcaptive/client/file-parent.c @@ -25,6 +25,8 @@ #include "vfs-parent.h" #include "reactos/ntos/types.h" /* for ULONG */ #include "parent-connector.h" +#include "captive/client.h" /* for captive_path_normalize() */ +#include static gpointer captive_file_parent_object_parent_class=NULL; @@ -40,9 +42,9 @@ static GnomeVFSResult captive_file_parent_seek static GnomeVFSResult captive_file_parent_tell(CaptiveFileObject *captive_file_object,GnomeVFSFileOffset *offset_return); static GnomeVFSResult captive_file_parent_remove(CaptiveFileObject *captive_file_object); static GnomeVFSResult captive_file_parent_file_info_get - (CaptiveFileObject *captive_file_object,GnomeVFSFileInfo *file_info); + (CaptiveFileObject *captive_file_object,CaptiveFileInfoObject **captive_file_info_object_return); static GnomeVFSResult captive_file_parent_file_info_set - (CaptiveFileObject *captive_file_object,const GnomeVFSFileInfo *info,GnomeVFSSetFileInfoMask mask); + (CaptiveFileObject *captive_file_object,CaptiveFileInfoObject *captive_file_info_object,GnomeVFSSetFileInfoMask mask); static GnomeVFSResult captive_file_parent_truncate(CaptiveFileObject *captive_file_object,GnomeVFSFileSize file_size); static GnomeVFSResult captive_file_parent_move (CaptiveFileObject *captive_file_object_old,const gchar *pathname_new,gboolean force_replace); @@ -180,6 +182,8 @@ GnomeVFSResult captive_file_parent_new_open(CaptiveFileObject **captive_file_obj { CaptiveFileParentObject *captive_file_parent_object; GnomeVFSResult r; +gint retried=0; +gint retried_commit=0; g_return_val_if_fail(captive_file_object_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS); @@ -193,18 +197,30 @@ GnomeVFSResult r; captive_file_parent_init(captive_file_parent_object,captive_vfs_object); - if (GNOME_VFS_OK!=(r=captive_parent_connector_connect(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object)))) - return r; - - if (GNOME_VFS_OK!=(r=captive_sandbox_parent_file_new_open(captive_file_parent_object))) { - g_object_unref(captive_file_parent_object); - *captive_file_object_return=NULL; - return r; - } - - *captive_file_object_return=CAPTIVE_FILE_OBJECT(captive_file_parent_object); - return (*captive_file_parent_object_captive_parent_connector_open_orig) - (CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object)); + do { + if (GNOME_VFS_OK!=(r=captive_parent_connector_connect(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object)))) + return r; + if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE + !=(r=captive_sandbox_parent_file_new_open(captive_file_parent_object))) { + if (GNOME_VFS_ERROR_SERVICE_OBSOLETE==r) { + if (!retried_commit++) { + if (GNOME_VFS_OK!=(r=captive_vfs_commit(captive_vfs_object))) + return r; + retried=0; + continue; + } + } + if (GNOME_VFS_OK!=r) { + g_object_unref(captive_file_parent_object); + *captive_file_object_return=NULL; + return r; + } + *captive_file_object_return=CAPTIVE_FILE_OBJECT(captive_file_parent_object); + return (*captive_file_parent_object_captive_parent_connector_open_orig) + (CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object)); + } + } while (!retried++); + return r; } @@ -213,6 +229,8 @@ GnomeVFSResult captive_file_parent_new_create(CaptiveFileObject **captive_file_o { CaptiveFileParentObject *captive_file_parent_object; GnomeVFSResult r; +gint retried=0; +gint retried_commit=0; g_return_val_if_fail(captive_file_object_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(CAPTIVE_VFS_PARENT_IS_OBJECT(captive_vfs_object),GNOME_VFS_ERROR_BAD_PARAMETERS); @@ -229,16 +247,31 @@ GnomeVFSResult r; if (GNOME_VFS_OK!=(r=captive_parent_connector_connect(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object)))) return r; - if (GNOME_VFS_OK!=(r=captive_sandbox_parent_file_new_create(captive_file_parent_object,exclusive,perm))) { - g_object_unref(captive_file_parent_object); - *captive_file_object_return=NULL; - return r; - } - captive_parent_connector_set_dirty(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object)); - - *captive_file_object_return=CAPTIVE_FILE_OBJECT(captive_file_parent_object); - return (*captive_file_parent_object_captive_parent_connector_open_orig) - (CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object)); + do { + if (GNOME_VFS_OK!=(r=captive_parent_connector_connect(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object)))) + return r; + if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE + !=(r=captive_sandbox_parent_file_new_create(captive_file_parent_object,exclusive,perm))) { + if (GNOME_VFS_ERROR_SERVICE_OBSOLETE==r) { + if (!retried_commit++) { + if (GNOME_VFS_OK!=(r=captive_vfs_commit(captive_vfs_object))) + return r; + retried=0; + continue; + } + } + if (GNOME_VFS_OK!=r) { + g_object_unref(captive_file_parent_object); + *captive_file_object_return=NULL; + return r; + } + captive_parent_connector_set_dirty(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object)); + *captive_file_object_return=CAPTIVE_FILE_OBJECT(captive_file_parent_object); + return (*captive_file_parent_object_captive_parent_connector_open_orig) + (CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object)); + } + } while (!retried++); + return r; } @@ -315,6 +348,7 @@ static GnomeVFSResult captive_file_parent_read(CaptiveFileObject *captive_file_o CaptiveFileParentObject *captive_file_parent_object; GnomeVFSResult r; gint retried=0; +gint retried_commit=0; g_return_val_if_fail(CAPTIVE_FILE_PARENT_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(buffer!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); @@ -327,8 +361,17 @@ gint retried=0; if (GNOME_VFS_OK!=(r=captive_parent_connector_open(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object)))) return r; if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE - !=(r=captive_sandbox_parent_file_read(captive_file_parent_object,buffer,num_bytes,bytes_read_return))) + !=(r=captive_sandbox_parent_file_read(captive_file_parent_object,buffer,num_bytes,bytes_read_return))) { + if (GNOME_VFS_ERROR_SERVICE_OBSOLETE==r) { + if (!retried_commit++) { + if (GNOME_VFS_OK!=(r=captive_vfs_commit(captive_file_object->vfs))) + return r; + retried=0; + continue; + } + } return r; + } } while (!retried++); return r; } @@ -442,14 +485,14 @@ gint retried=0; static GnomeVFSResult captive_file_parent_file_info_get - (CaptiveFileObject *captive_file_object,GnomeVFSFileInfo *file_info) + (CaptiveFileObject *captive_file_object,CaptiveFileInfoObject **captive_file_info_object_return) { CaptiveFileParentObject *captive_file_parent_object; GnomeVFSResult r; gint retried=0; g_return_val_if_fail(CAPTIVE_FILE_PARENT_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS); - g_return_val_if_fail(file_info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(captive_file_info_object_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); captive_file_parent_object=CAPTIVE_FILE_PARENT_OBJECT(captive_file_object); @@ -457,7 +500,7 @@ gint retried=0; if (GNOME_VFS_OK!=(r=captive_parent_connector_open(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object)))) return r; if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE - !=(r=captive_sandbox_parent_file_file_info_get(captive_file_parent_object,file_info))) + !=(r=captive_sandbox_parent_file_file_info_get(captive_file_parent_object,captive_file_info_object_return))) return r; } while (!retried++); return r; @@ -465,14 +508,14 @@ gint retried=0; static GnomeVFSResult captive_file_parent_file_info_set - (CaptiveFileObject *captive_file_object,const GnomeVFSFileInfo *info,GnomeVFSSetFileInfoMask mask) + (CaptiveFileObject *captive_file_object,CaptiveFileInfoObject *captive_file_info_object,GnomeVFSSetFileInfoMask mask) { CaptiveFileParentObject *captive_file_parent_object; GnomeVFSResult r; gint retried=0; g_return_val_if_fail(CAPTIVE_FILE_PARENT_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS); - g_return_val_if_fail(info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(CAPTIVE_FILE_INFO_IS_OBJECT(captive_file_info_object),GNOME_VFS_ERROR_BAD_PARAMETERS); captive_file_parent_object=CAPTIVE_FILE_PARENT_OBJECT(captive_file_object); @@ -480,7 +523,7 @@ gint retried=0; if (GNOME_VFS_OK!=(r=captive_parent_connector_open(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object)))) return r; if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE - !=(r=captive_sandbox_parent_file_file_info_set(captive_file_parent_object,info,mask))) { + !=(r=captive_sandbox_parent_file_file_info_set(captive_file_parent_object,captive_file_info_object,mask))) { if (GNOME_VFS_OK==r) captive_parent_connector_set_dirty(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object)); return r; @@ -520,19 +563,48 @@ static GnomeVFSResult captive_file_parent_move CaptiveFileParentObject *captive_file_parent_object_old; GnomeVFSResult r; gint retried=0; +gchar *chksub_pathname_old_cased,*chksub_pathname_new_cased; /* case-sensitive version */ +gchar *chksub_pathname_old,*chksub_pathname_new,*chksub_s_old,*chksub_s_new; g_return_val_if_fail(CAPTIVE_FILE_PARENT_IS_OBJECT(captive_file_object_old),GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(pathname_new!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); captive_file_parent_object_old=CAPTIVE_FILE_PARENT_OBJECT(captive_file_object_old); + /* Prevent "mv dir dir/subdir" as it is not catched by ntfs.sys of NT-5.1sp1. */ + /* FIXME: Move to 'CaptiveFileSlaveObject' but it has no '->pathname' stored now! */ + /* FIXME: UTF8 may not be compared correctly - we should use g_utf8_collate() */ + chksub_pathname_old_cased=captive_path_normalize(captive_file_parent_object_old->pathname); + chksub_pathname_new_cased=captive_path_normalize(pathname_new); + chksub_pathname_old=g_utf8_casefold(chksub_pathname_old_cased, + -1); /* len; '\0'-terminated */ + chksub_pathname_new=g_utf8_casefold(chksub_pathname_new_cased, + -1); /* len; '\0'-terminated */ + g_free(chksub_pathname_old_cased); + g_free(chksub_pathname_new_cased); + for ( + chksub_s_old=chksub_pathname_old,chksub_s_new=chksub_pathname_new; + *chksub_s_old && *chksub_s_new && tolower(*chksub_s_old)==tolower(*chksub_s_new); + chksub_s_old++,chksub_s_new++); + g_assert(chksub_s_old>chksub_pathname_old); + g_assert(chksub_s_new>chksub_pathname_new); + if (!*chksub_s_old && (!*chksub_s_new || *chksub_s_new=='/')) + return GNOME_VFS_ERROR_DIRECTORY_BUSY; + if (!*chksub_s_new && (!*chksub_s_old || *chksub_s_old=='/')) + return GNOME_VFS_ERROR_DIRECTORY_BUSY; + g_free(chksub_pathname_old); + g_free(chksub_pathname_new); + do { if (GNOME_VFS_OK!=(r=captive_parent_connector_open(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object_old)))) return r; if (GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE !=(r=captive_sandbox_parent_file_move(captive_file_parent_object_old,pathname_new,force_replace))) { - if (GNOME_VFS_OK==r) + if (GNOME_VFS_OK==r) { + g_free(captive_file_parent_object_old->pathname); + captive_file_parent_object_old->pathname=g_strdup(pathname_new); captive_parent_connector_set_dirty(CAPTIVE_PARENT_CONNECTOR(captive_file_parent_object_old)); + } return r; } } while (!retried++);