Initial original import from: fuse-2.4.2-2.fc4
[captive.git] / src / client / lufs / captivefs-file.c
index 611689e..216c9bb 100644 (file)
@@ -36,7 +36,7 @@
 #define CLIENT_LUFS_USE_COUNT "client-lufs-use_count"
 
 
-/* map: (const gchar *) -> (CaptiveFileObject *) */
+/* map: (const gchar *utf8) -> (CaptiveFileObject *) */
 static GHashTable *FileHandle_hash;
 G_LOCK_DEFINE_STATIC(FileHandle_hash);
 
@@ -73,14 +73,19 @@ static void FileHandle_set_use_count(CaptiveFileObject *captive_file_object,gint
 
 /* FileHandle_hash_init(); must be executed! */
 /* G_LOCK(FileHandle_hash); must be held! */
-static void FileHandle_enter(CaptiveFileObject *captive_file_object,const gchar *name_normalized)
+static void FileHandle_enter
+               (struct captivefs_vfs *captivefs_vfs,CaptiveFileObject *captive_file_object,const gchar *name_normalized)
 {
 gint use_count;
 
+       g_return_if_fail(captivefs_vfs_validate(captivefs_vfs));
        g_return_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object));
        g_return_if_fail(name_normalized);
 
        use_count=FileHandle_get_use_count(captive_file_object);
+       if (captivefs_vfs->options.debug_messages)
+               g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"FileHandle_enter: name_normalized=%s, use_count++=%d",
+                               name_normalized,(int)use_count);
        g_assert(use_count>=0);
        use_count++;
        FileHandle_set_use_count(captive_file_object,use_count);
@@ -96,17 +101,22 @@ gint use_count;
 /* FileHandle_hash_init(); must be executed! */
 /* G_LOCK(FileHandle_hash); must be held! */
 /* G_LOCK(libcaptive); must NOT be held! */
-static void FileHandle_leave_locked(CaptiveFileObject *captive_file_object,const gchar *name)
+static void FileHandle_leave_locked
+               (struct captivefs_vfs *captivefs_vfs,CaptiveFileObject *captive_file_object,const gchar *name)
 {
 gboolean errbool;
 gint use_count;
 gchar *name_normalized;
 
+       g_return_if_fail(captivefs_vfs_validate(captivefs_vfs));
        g_return_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object));
        g_return_if_fail(name);
 
        name_normalized=captive_path_normalize(name);
        use_count=FileHandle_get_use_count(captive_file_object);
+       if (captivefs_vfs->options.debug_messages)
+               g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"FileHandle_leave_locked: name_normalized=%s, use_count--=%d",
+                               name_normalized,(int)use_count);
        g_assert(use_count>=1);
        use_count--;
        FileHandle_set_use_count(captive_file_object,use_count);
@@ -127,22 +137,24 @@ gchar *name_normalized;
 /* FileHandle_hash_init(); must be executed! */
 /* G_LOCK(FileHandle_hash); must NOT be held! */
 /* G_LOCK(libcaptive); must NOT be held! */
-static void FileHandle_leave(CaptiveFileObject *captive_file_object,const gchar *name)
+static void FileHandle_leave(struct captivefs_vfs *captivefs_vfs,CaptiveFileObject *captive_file_object,const gchar *name)
 {
+       g_return_if_fail(captivefs_vfs_validate(captivefs_vfs));
        g_return_if_fail(CAPTIVE_FILE_IS_OBJECT(captive_file_object));
        g_return_if_fail(name);
 
        G_LOCK(FileHandle_hash);
-       FileHandle_leave_locked(captive_file_object,name);
+       FileHandle_leave_locked(captivefs_vfs,captive_file_object,name);
        G_UNLOCK(FileHandle_hash);
 }
 
 /* 'name' is required to exist. */
-static CaptiveFileObject *FileHandle_lookup_enter(const char *name)
+static CaptiveFileObject *FileHandle_lookup_enter(struct captivefs_vfs *captivefs_vfs,const char *name)
 {
 CaptiveFileObject *captive_file_object;
 gchar *name_normalized;
 
+       g_return_val_if_fail(captivefs_vfs_validate(captivefs_vfs),NULL);
        g_return_val_if_fail(name!=NULL,NULL);
 
        name_normalized=captive_path_normalize(name);
@@ -156,7 +168,7 @@ gchar *name_normalized;
                return NULL;
                }
        g_assert(CAPTIVE_FILE_IS_OBJECT(captive_file_object));
-       FileHandle_enter(captive_file_object,name_normalized);
+       FileHandle_enter(captivefs_vfs,captive_file_object,name_normalized);
        G_UNLOCK(FileHandle_hash);
        g_free(name_normalized);
 
@@ -170,6 +182,7 @@ CaptiveFileObject *captive_file_object;
 GnomeVFSResult errvfsresult;
 gchar *name_normalized;
 
+       g_return_val_if_fail(captivefs_vfs_validate(captivefs_vfs),NULL);
        g_return_val_if_fail(name!=NULL,NULL);
 
        name_normalized=captive_path_normalize(name);
@@ -178,14 +191,14 @@ gchar *name_normalized;
        captive_file_object=g_hash_table_lookup(FileHandle_hash,name_normalized);
        if (!create && captive_file_object) {
                g_assert(CAPTIVE_FILE_IS_OBJECT(captive_file_object));
-               FileHandle_enter(captive_file_object,name_normalized);
+               FileHandle_enter(captivefs_vfs,captive_file_object,name_normalized);
                G_UNLOCK(FileHandle_hash);
                g_free(name_normalized);
                return captive_file_object;
                }
        if ( create && captive_file_object) {
                g_assert(CAPTIVE_FILE_IS_OBJECT(captive_file_object));
-               FileHandle_enter(captive_file_object,name_normalized);
+               FileHandle_enter(captivefs_vfs,captive_file_object,name_normalized);
                G_UNLOCK(FileHandle_hash);
                g_free(name_normalized);
                return NULL;
@@ -201,6 +214,15 @@ gchar *name_normalized;
                errvfsresult=captive_file_new_open(&captive_file_object,captivefs_vfs->captive_vfs_object,name_normalized,
                                GNOME_VFS_OPEN_READ|GNOME_VFS_OPEN_WRITE|GNOME_VFS_OPEN_RANDOM);
                G_UNLOCK(libcaptive);
+               /* HIDDEN SYSTEM files (FIXME: or just HIDDEN or just SYSTEM?)
+                * refuse to be GNOME_VFS_OPEN_WRITE-opened.
+                */
+               if (errvfsresult==GNOME_VFS_ERROR_ACCESS_DENIED) {
+                       G_LOCK(libcaptive);
+                       errvfsresult=captive_file_new_open(&captive_file_object,captivefs_vfs->captive_vfs_object,name_normalized,
+                                       GNOME_VFS_OPEN_READ|GNOME_VFS_OPEN_RANDOM);
+                       G_UNLOCK(libcaptive);
+                       }
                }
        else {
                G_LOCK(libcaptive);
@@ -215,7 +237,7 @@ gchar *name_normalized;
                g_free(name_normalized);
                return NULL;
                }
-       FileHandle_enter(captive_file_object,name_normalized);
+       FileHandle_enter(captivefs_vfs,captive_file_object,name_normalized);
        G_UNLOCK(FileHandle_hash);
        g_object_unref(captive_file_object);    /* for captive_file_new_open() / captive_file_new_create() */
        g_free(name_normalized);
@@ -252,6 +274,8 @@ GnomeVFSFileInfo file_info;
        if (captivefs_vfs->options.debug_messages)
                g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_stat: name=%s",name);
 
+       name=CAPTIVEFS_FILENAME_TO_UTF8_ALLOCA(name);
+
        captive_file_object=FileHandle_lookup_open_enter(captivefs_vfs,name,FALSE);
        if (!captive_file_object)
                return -1;
@@ -260,7 +284,7 @@ GnomeVFSFileInfo file_info;
        errvfsresult=captive_file_file_info_get(captive_file_object,&file_info);
        G_UNLOCK(libcaptive);
 
-       FileHandle_leave(captive_file_object,name);
+       FileHandle_leave(captivefs_vfs,captive_file_object,name);
 
        if (errvfsresult!=GNOME_VFS_OK)
                return -1;
@@ -284,11 +308,13 @@ CaptiveFileObject *captive_file_object;
        if (captivefs_vfs->options.debug_messages)
                g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_create: file=%s,mode=0x%X",file,mode);
 
+       file=CAPTIVEFS_FILENAME_TO_UTF8_ALLOCA(file);
+
        captive_file_object=FileHandle_lookup_open_enter(captivefs_vfs,file,TRUE);
        if (!captive_file_object)
                return -1;
 
-       FileHandle_leave(captive_file_object,file);
+       FileHandle_leave(captivefs_vfs,captive_file_object,file);
 
        return 0;
 }
@@ -307,6 +333,8 @@ CaptiveFileObject *captive_file_object;
        if (captivefs_vfs->options.debug_messages)
                g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_unlink: file=%s",file);
 
+       file=CAPTIVEFS_FILENAME_TO_UTF8_ALLOCA(file);
+
        captive_file_object=FileHandle_lookup_open_enter(captivefs_vfs,file,FALSE);
        if (!captive_file_object)
                return -1;
@@ -315,7 +343,7 @@ CaptiveFileObject *captive_file_object;
        errvfsresult=captive_file_remove(captive_file_object);
        G_UNLOCK(libcaptive);
 
-       FileHandle_leave(captive_file_object,file);
+       FileHandle_leave(captivefs_vfs,captive_file_object,file);
 
        if (errvfsresult!=GNOME_VFS_OK)
                return -1;
@@ -339,6 +367,9 @@ gint use_count;
        if (captivefs_vfs->options.debug_messages)
                g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_rename: old_name=%s,new_name=%s",old_name,new_name);
 
+       old_name=CAPTIVEFS_FILENAME_TO_UTF8_ALLOCA(old_name);
+       new_name=CAPTIVEFS_FILENAME_TO_UTF8_ALLOCA(new_name);
+
        captive_file_object=FileHandle_lookup_open_enter(captivefs_vfs,old_name,FALSE);
        if (!captive_file_object)
                return -1;
@@ -351,7 +382,7 @@ gint use_count;
                        g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_rename: old_name=%s,new_name=%s: BUSY use_count=%d",
                                        old_name,new_name,(int)use_count);
                G_UNLOCK(FileHandle_hash);
-               FileHandle_leave(captive_file_object,old_name);
+               FileHandle_leave(captivefs_vfs,captive_file_object,old_name);
                return -1;
                }
 
@@ -360,7 +391,7 @@ gint use_count;
                        FALSE); /* force_replace */
        G_UNLOCK(libcaptive);
 
-       FileHandle_leave_locked(captive_file_object,old_name);
+       FileHandle_leave_locked(captivefs_vfs,captive_file_object,old_name);
        G_UNLOCK(FileHandle_hash);
 
        if (errvfsresult!=GNOME_VFS_OK)
@@ -394,6 +425,8 @@ GnomeVFSOpenMode gnome_vfs_open_mode;
        if (captivefs_vfs->options.debug_messages)
                g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_open: file=%s,mode=0x%X",file,mode);
 
+       file=CAPTIVEFS_FILENAME_TO_UTF8_ALLOCA(file);
+
        if (!captivefs_vfs_validate(captivefs_vfs))
                return -1;
 
@@ -429,11 +462,13 @@ CaptiveFileObject *captive_file_object;
        if (captivefs_vfs->options.debug_messages)
                g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_release: file=%s",file);
 
-       if (!(captive_file_object=FileHandle_lookup_enter(file)))
+       file=CAPTIVEFS_FILENAME_TO_UTF8_ALLOCA(file);
+
+       if (!(captive_file_object=FileHandle_lookup_enter(captivefs_vfs,file)))
                return -1;
 
-       FileHandle_leave(captive_file_object,file);     /* for FileHandle_lookup_enter() */
-       FileHandle_leave(captive_file_object,file);
+       FileHandle_leave(captivefs_vfs,captive_file_object,file);       /* for FileHandle_lookup_enter() */
+       FileHandle_leave(captivefs_vfs,captive_file_object,file);
 
        return 0;
 }
@@ -456,7 +491,9 @@ GnomeVFSResult errvfsresult;
                g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_read: file=%s,offset=%" G_GINT64_FORMAT ",count=0x%lX",
                                file,(gint64)offset,count);
 
-       if (!(captive_file_object=FileHandle_lookup_enter(file)))
+       file=CAPTIVEFS_FILENAME_TO_UTF8_ALLOCA(file);
+
+       if (!(captive_file_object=FileHandle_lookup_enter(captivefs_vfs,file)))
                return -1;
 
        /* Do not unlock 'libcaptive' between seek() and read()! */
@@ -464,13 +501,13 @@ GnomeVFSResult errvfsresult;
        errvfsresult=captive_file_seek(captive_file_object,GNOME_VFS_SEEK_START,offset);
        if (errvfsresult!=GNOME_VFS_OK) {
                G_UNLOCK(libcaptive);
-               FileHandle_leave(captive_file_object,file);
+               FileHandle_leave(captivefs_vfs,captive_file_object,file);
                return -1;
                }
 
        errvfsresult=captive_file_read(captive_file_object,buf,count,&bytes_read);
        G_UNLOCK(libcaptive);
-       FileHandle_leave(captive_file_object,file);
+       FileHandle_leave(captivefs_vfs,captive_file_object,file);
        if (errvfsresult!=GNOME_VFS_OK)
                return -1;
 
@@ -500,7 +537,9 @@ GnomeVFSResult errvfsresult;
                g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_write: file=%s,offset=%" G_GINT64_FORMAT ",count=0x%lX",
                                file,(gint64)offset,count);
 
-       if (!(captive_file_object=FileHandle_lookup_enter(file)))
+       file=CAPTIVEFS_FILENAME_TO_UTF8_ALLOCA(file);
+
+       if (!(captive_file_object=FileHandle_lookup_enter(captivefs_vfs,file)))
                return -1;
 
        /* Do not unlock 'libcaptive' between seek() and write()! */
@@ -508,13 +547,13 @@ GnomeVFSResult errvfsresult;
        errvfsresult=captive_file_seek(captive_file_object,GNOME_VFS_SEEK_START,offset);
        if (errvfsresult!=GNOME_VFS_OK) {
                G_UNLOCK(libcaptive);
-               FileHandle_leave(captive_file_object,file);
+               FileHandle_leave(captivefs_vfs,captive_file_object,file);
                return -1;
                }
 
        errvfsresult=captive_file_write(captive_file_object,buf,count,&bytes_written);
        G_UNLOCK(libcaptive);
-       FileHandle_leave(captive_file_object,file);
+       FileHandle_leave(captivefs_vfs,captive_file_object,file);
        if (errvfsresult!=GNOME_VFS_OK)
                return -1;
 
@@ -543,6 +582,8 @@ CaptiveFileObject *captive_file_object;
        if (captivefs_vfs->options.debug_messages)
                g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"captivefs_setattr: file=%s",file);
 
+       file=CAPTIVEFS_FILENAME_TO_UTF8_ALLOCA(file);
+
        if (!captivefs_lufs_fattr_to_GnomeVFSFileInfo(&file_info,fattr))
                return -1;
 
@@ -562,7 +603,11 @@ CaptiveFileObject *captive_file_object;
                                                                        | GNOME_VFS_FILE_INFO_FIELDS_CTIME))
                                                        ? 0 : GNOME_VFS_SET_FILE_INFO_TIME));
        G_UNLOCK(libcaptive);
-       FileHandle_leave(captive_file_object,file);
+       G_LOCK(libcaptive);
+       if (errvfsresult==GNOME_VFS_OK)
+       errvfsresult=captive_file_truncate(captive_file_object,fattr->f_size);
+       G_UNLOCK(libcaptive);
+       FileHandle_leave(captivefs_vfs,captive_file_object,file);
        if (errvfsresult!=GNOME_VFS_OK)
                return -1;