[patch] tar method won't open root directory of archive
- From: George J Karabin <gkarabin pobox com>
- To: gnome-vfs-list gnome org
- Subject: [patch] tar method won't open root directory of archive
- Date: Mon, 19 Jan 2004 13:49:04 -0800
I haven't seen any documentation in gnome-vfs to indicate how one should
encode the root directory of an archive into a URI, but empirically, it
looks like something like either "foo.tar#tar:" or "foo.tar#tar:/"
should work (gnome-vfs expands the former to the latter before giving
the uri to the module's method). The tar method doesn't handle either of
these cases. The attached patch fixes this.
Try out something like "gnomevfs-ls /path-to-file/foo.tar#:" before and
after the patch as a test case. No CVS access for me - can someone apply
it if it passes review?
The problem's filed in bugzilla as well:
http://bugzilla.gnome.org/show_bug.cgi?id=131959
- George
--- gnome-vfs-2.4.1/modules/tar-method.c.handle-root 2002-05-12 20:38:29.000000000 -0700
+++ gnome-vfs-2.4.1/modules/tar-method.c 2004-01-19 12:43:14.000000000 -0800
@@ -51,6 +51,7 @@
int current_index;
gchar *filename;
gboolean is_directory;
+ gboolean is_root;
} FileHandle;
#define TARPET_BLOCKSIZE (sizeof (union TARPET_block))
@@ -154,35 +155,42 @@
return ret;
}
-static GNode*
-tree_lookup_entry (const GNode *tree, const gchar *name)
+static gboolean
+tree_lookup_entry (const GNode *tree, const gchar *name, GNode **node)
{
- GNode *ret;
char *root = g_strdup (name);
char *txt = root;
-
- if (txt[0] == '/')
- txt++;
- ret = real_lookup_entry (tree, txt, 1);
- if (!ret && txt[strlen (txt) - 1] != '/')
+ if (txt[0] == '/')
+ {
+ if (txt[1] == '\0')
+ {
+ g_free (root);
+ return TRUE;
+ }
+ else
+ txt++;
+ }
+
+ *node = real_lookup_entry (tree, txt, 1);
+ if (!*node && txt[strlen (txt) - 1] != '/')
{
txt = g_strconcat (txt, "/", NULL);
g_free (root);
root = txt;
- ret = real_lookup_entry (tree, txt, 1);
+ *node = real_lookup_entry (tree, txt, 1);
}
g_free (root);
- if (ret && ret != tree->children)
+ if (*node && *node != tree->children)
{
- union TARPET_block *b = ret->data;
+ union TARPET_block *b = (*node)->data;
b--;
if (b->p.typeflag == TARPET_TYPE_LONGFILEN)
- ret = ret->next;
+ *node = (*node)->next;
}
- return ret;
+ return FALSE;
}
static TarFile* read_tar_file (GnomeVFSHandle *handle)
@@ -228,7 +236,7 @@
}
split_name (ret->blocks[i].p.name, &dir, &rest);
- node = tree_lookup_entry (ret->info_tree, dir);
+ tree_lookup_entry (ret->info_tree, dir, &node);
if (!node)
{
@@ -322,7 +330,7 @@
tar = ensure_tarfile (uri);
if (!tar)
return GNOME_VFS_ERROR_BAD_FILE;
- node = tree_lookup_entry (tar->info_tree, uri->text);
+ tree_lookup_entry (tar->info_tree, uri->text, &node);
if (!node)
{
tar_file_unref (tar);
@@ -468,13 +476,17 @@
union TARPET_block *start, *current;
GNode *node;
int i;
+ gboolean is_root;
if (!uri->parent)
return GNOME_VFS_ERROR_INVALID_URI;
tar = ensure_tarfile (uri);
if (uri->text)
{
- node = tree_lookup_entry (tar->info_tree, uri->text);
+ is_root = tree_lookup_entry (tar->info_tree, uri->text, &node);
+ }
+ if (!is_root)
+ {
if (!node)
{
tar_file_unref (tar);
@@ -490,8 +502,11 @@
else
current = NULL;
}
- else
+ if (is_root || !uri->text)
{
+ /* FIXME: gnome-vfs never seems to generate !uri->text
+ condition. Is it permissible by contract? */
+
node = tar->info_tree;
if (!node)
{
@@ -516,6 +531,7 @@
break;
new_handle->current_index = i;
new_handle->is_directory = TRUE;
+ new_handle->is_root = is_root;
*method_handle = (GnomeVFSMethodHandle*) new_handle;
@@ -550,7 +566,7 @@
int i;
if (uri->text)
- node = tree_lookup_entry (tar->info_tree, uri->text);
+ tree_lookup_entry (tar->info_tree, uri->text, &node);
else
node = tar->info_tree->children;
@@ -635,15 +651,16 @@
GnomeVFSURI *uri;
gchar *str;
GNode *node;
-
+ gboolean is_root;
+
if (!handle->current)
return GNOME_VFS_ERROR_EOF;
str = g_strconcat (handle->filename, "#tar:", handle->current->p.name, NULL);
uri = gnome_vfs_uri_new (str);
do_get_file_info (method, uri, file_info, 0, context);
- node = tree_lookup_entry (handle->tar->info_tree, uri->text);
- if (!node)
+ is_root = tree_lookup_entry (handle->tar->info_tree, uri->text, &node);
+ if (!node && !is_root)
{
gnome_vfs_uri_unref (uri);
return GNOME_VFS_ERROR_NOT_FOUND;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]