summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@users.sourceforge.net>2009-11-28 13:11:51 +0100
committerTomas Bzatek <tbzatek@users.sourceforge.net>2009-11-28 13:11:51 +0100
commit9382f127ccebdd59917c97c61d008ed0e127cd75 (patch)
tree0a48c8296199b343c76ef532eef014f908bc2e4d
parent70eeaa4ec712895539ca6ecd60a42b93ec9b0904 (diff)
downloadtuxcmd-modules-9382f127ccebdd59917c97c61d008ed0e127cd75.tar.xz
Engine and VFS API cleanupv0.6.72
Also enable symlink resolving by default.
-rw-r--r--common/filelist-vfs-intf.c263
-rw-r--r--common/filelist-vfs-intf.h68
-rw-r--r--common/filelist.c382
-rw-r--r--common/filelist.h99
-rw-r--r--common/strutils.c157
-rw-r--r--common/strutils.h36
-rw-r--r--common/treepath_vfs.c231
-rw-r--r--common/treepath_vfs.h61
-rw-r--r--common/treepathutils.c386
-rw-r--r--common/treepathutils.h58
-rw-r--r--common/tuxcmd-vfs.h (renamed from common/vfs_types.h)130
-rw-r--r--common/vfsutils.c80
-rw-r--r--common/vfsutils.h24
-rw-r--r--gvfs/Makefile20
-rw-r--r--gvfs/gvfs.c327
l---------gvfs/tuxcmd-vfs.h1
l---------gvfs/vfs_types.h1
-rw-r--r--libarchive/Makefile34
l---------libarchive/filelist-vfs-intf.c1
l---------libarchive/filelist-vfs-intf.h1
l---------libarchive/filelist.c1
l---------libarchive/filelist.h1
-rw-r--r--libarchive/libarchive.c688
l---------libarchive/treepath_vfs.c1
l---------libarchive/treepath_vfs.h1
l---------libarchive/treepathutils.c1
l---------libarchive/treepathutils.h1
l---------libarchive/tuxcmd-vfs.h1
l---------libarchive/vfs_types.h1
-rw-r--r--unrar/Makefile30
l---------unrar/filelist-vfs-intf.c1
l---------unrar/filelist-vfs-intf.h1
l---------unrar/filelist.c1
l---------unrar/filelist.h1
l---------unrar/treepath_vfs.c1
l---------unrar/treepath_vfs.h1
l---------unrar/treepathutils.c1
l---------unrar/treepathutils.h1
l---------unrar/tuxcmd-vfs.h1
-rw-r--r--unrar/unrar.c794
l---------unrar/vfs_types.h1
-rw-r--r--zip/Makefile28
l---------zip/filelist-vfs-intf.c1
l---------zip/filelist-vfs-intf.h1
l---------zip/filelist.c1
l---------zip/filelist.h1
l---------zip/treepath_vfs.c1
l---------zip/treepath_vfs.h1
l---------zip/treepathutils.c1
l---------zip/treepathutils.h1
l---------zip/tuxcmd-vfs.h1
l---------zip/vfs_types.h1
-rw-r--r--zip/zip.cpp819
53 files changed, 2506 insertions, 2241 deletions
diff --git a/common/filelist-vfs-intf.c b/common/filelist-vfs-intf.c
new file mode 100644
index 0000000..e806334
--- /dev/null
+++ b/common/filelist-vfs-intf.c
@@ -0,0 +1,263 @@
+/* Tux Commander VFS: convenient interface for VFS modules to a filelist tree
+ * Copyright (C) 2007-2009 Tomas Bzatek <tbzatek@users.sourceforge.net>
+ * Check for updates on tuxcmd.sourceforge.net
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <stdio.h>
+#include <string.h>
+#include <glib.h>
+
+#include "tuxcmd-vfs.h"
+#include "strutils.h"
+#include "vfsutils.h"
+#include "filelist.h"
+#include "filelist-vfs-intf.h"
+
+
+
+
+
+
+struct VfsFilelistData *
+vfs_filelist_new (struct PathTree *files)
+{
+ struct VfsFilelistData * data;
+
+ data = g_malloc0 (sizeof (struct VfsFilelistData));
+
+ log ("vfs_filelist_new()\n");
+ data->files = files;
+
+ return data;
+}
+
+void
+vfs_filelist_free (struct VfsFilelistData *data)
+{
+ if (! data) {
+ fprintf (stderr, "vfs_filelist_free: data == NULL !\n");
+ return;
+ }
+ g_free (data->list_dir_path);
+ g_free (data);
+}
+
+
+/* -------------------------------------------------------------------------------------- */
+
+guint64
+internal_get_dir_size (struct VfsFilelistData *data, struct PathTree *tree)
+{
+ guint64 Size;
+ struct PathTree *n;
+ unsigned long idx;
+
+ Size = 0;
+ if (! data->break_get_dir_size && tree) {
+ n = NULL;
+ idx = 0;
+ while ((n = filelist_tree_get_item_by_index (tree, idx))) {
+ if (data->break_get_dir_size)
+ break;
+ if (n->data) {
+ log ("internal_get_dir_size: found item '%s', size = %zd \n", n->node, n->data->iSize);
+ Size += (n->data->ItemType == vDirectory) ? internal_get_dir_size (data, n) : n->data->iSize;
+ }
+ idx++;
+ }
+ }
+ return Size;
+}
+
+guint64
+vfs_filelist_get_dir_size (struct VfsFilelistData *data, const char *APath)
+{
+ struct PathTree *node;
+
+ if (! data)
+ return 0;
+ data->break_get_dir_size = FALSE;
+
+ node = filelist_tree_find_node_by_path (data->files, APath);
+ if (node) {
+ return internal_get_dir_size (data, node);
+ } else {
+ printf ("(EE) VFSGetDirSize: path '%s' not found\n", APath);
+ return 0;
+ }
+}
+
+void
+vfs_filelist_get_dir_size_break (struct VfsFilelistData *data)
+{
+ if (data)
+ data->break_get_dir_size = TRUE;
+}
+
+
+/* -------------------------------------------------------------------------------------- */
+
+static void
+assign_file_info (struct PathTree* node, struct TVFSItem *Item, const char *reference_full_path, gboolean follow_symlinks, gboolean add_full_path)
+{
+ copy_vfs_item (node->data, Item);
+ if (add_full_path && reference_full_path) {
+ g_free (Item->FName);
+ g_free (Item->FDisplayName);
+ Item->FName = g_strdup (reference_full_path);
+ Item->FDisplayName = g_filename_display_name (reference_full_path);
+ }
+ if (follow_symlinks && node->symlink_target_data) {
+ Item->iSize = node->symlink_target_data->iSize;
+ Item->iPackedSize = node->symlink_target_data->iPackedSize;
+ Item->ItemType = node->symlink_target_data->ItemType;
+ }
+}
+
+TVFSResult
+vfs_filelist_file_info (struct VfsFilelistData *data, const char *AFileName, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath)
+{
+ struct PathTree *node;
+
+ if (data && data->files) {
+ node = filelist_tree_find_node_by_path (data->files, AFileName);
+ if (node) {
+ if (node->data) {
+ assign_file_info (node, Item, AFileName, FollowSymlinks, AddFullPath);
+ printf ("(II) VFSFileInfo: found file: '%s'\n", Item->FName);
+ return cVFS_OK;
+ } else {
+ printf ("(EE) VFSFileInfo: node->data == NULL! \n");
+ return cVFS_Failed;
+ }
+ } else {
+ printf ("(EE) VFSFileInfo: file specified not found\n");
+ return cVFS_No_More_Files;
+ }
+ } else {
+ printf ("(EE) VFSFileInfo: Invalid pointers to data objects.\n");
+ return cVFS_Failed;
+ }
+}
+
+TVFSResult
+vfs_filelist_list_first (struct VfsFilelistData *data, const char *sDir, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath)
+{
+ struct PathTree *node;
+ char *full_path;
+
+ data->list_dir_index = -1;
+ data->list_dir_node = NULL;
+
+ if (sDir == NULL) {
+ printf ("(EE) VFSListFirst: sDir is NULL!\n");
+ return cVFS_Failed;
+ }
+
+ data->list_dir_index = 0;
+ data->list_dir_node = filelist_tree_find_node_by_path (data->files, sDir);
+ data->follow_symlinks = FollowSymlinks;
+ data->add_full_path = AddFullPath;
+ data->list_dir_path = include_trailing_path_sep (sDir);
+
+ /* Find the directory in the filelist */
+ if (data->list_dir_node) {
+ node = filelist_tree_get_item_by_index (data->list_dir_node, data->list_dir_index);
+ if (node) {
+ full_path = NULL;
+ if (AddFullPath)
+ full_path = g_build_filename (sDir, node->data->FName, NULL);
+ assign_file_info (node, Item, full_path, FollowSymlinks, AddFullPath);
+ g_free (full_path);
+ printf ("(II) VFSListFirst: found file: %s\n", Item->FName);
+ return cVFS_OK;
+ } else {
+ printf ("(II) VFSListFirst: no more files\n");
+ return cVFS_No_More_Files;
+ }
+ } else {
+ printf ("(EE) VFSListFirst: Directory '%s' not found.\n", sDir);
+ return cVFS_Failed;
+ }
+}
+
+TVFSResult
+vfs_filelist_list_next (struct VfsFilelistData *data, struct TVFSItem *Item)
+{
+ struct PathTree *node;
+ char *full_path;
+
+ full_path = NULL;
+ if (! data->list_dir_node) {
+ printf ("(EE) VFSListNext: data->list_dir_node is NULL!\n");
+ return cVFS_Failed;
+ }
+ data->list_dir_index++;
+
+ node = filelist_tree_get_item_by_index (data->list_dir_node, data->list_dir_index);
+ if (node) {
+ if (data->add_full_path)
+ full_path = g_build_filename (data->list_dir_path, node->data->FName, NULL);
+ assign_file_info (node, Item, full_path, data->follow_symlinks, data->add_full_path);
+ g_free (full_path);
+ printf ("(II) VFSListNext: found file: %s\n", Item->FName);
+ return cVFS_OK;
+ } else {
+ printf ("(II) VFSListNext: no more files\n");
+ return cVFS_No_More_Files;
+ }
+}
+
+TVFSResult
+vfs_filelist_list_close (struct VfsFilelistData *data)
+{
+ data->list_dir_index = -1;
+ data->list_dir_node = NULL;
+ g_free (data->list_dir_path);
+ data->list_dir_path = NULL;
+ return cVFS_OK;
+}
+
+
+/* -------------------------------------------------------------------------------------- */
+
+char *
+vfs_filelist_change_dir (struct VfsFilelistData *data, const char *NewPath)
+{
+ char *ANewPath;
+
+ if (NewPath == NULL) {
+ printf("(EE) VFSChangeDir: NewPath is NULL!\n");
+ return NULL;
+ }
+
+ /* make up the target path */
+ printf ("(--) VFSChangeDir: Going to change dir from '%s'\n", NewPath);
+ ANewPath = exclude_trailing_path_sep (NewPath);
+ if (! ANewPath || strlen (ANewPath) <= 0)
+ ANewPath = g_strdup ("/");
+ printf ("(--) VFSChangeDir: Going to change dir to '%s'\n", ANewPath);
+
+ /* find the directory in the filelist */
+ if (filelist_tree_find_node_by_path (data->files, ANewPath)) {
+ return ANewPath;
+ } else {
+ printf ("(EE) VFSChangeDir: Directory '%s' not found.\n", ANewPath);
+ g_free (ANewPath);
+ return NULL;
+ }
+}
diff --git a/common/filelist-vfs-intf.h b/common/filelist-vfs-intf.h
new file mode 100644
index 0000000..ce93e1e
--- /dev/null
+++ b/common/filelist-vfs-intf.h
@@ -0,0 +1,68 @@
+/* Tux Commander VFS: convenient interface for VFS modules to a filelist tree
+ * Copyright (C) 2007-2009 Tomas Bzatek <tbzatek@users.sourceforge.net>
+ * Check for updates on tuxcmd.sourceforge.net
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+#ifndef __TREEPATH_VFS_H__
+#define __TREEPATH_VFS_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+#include <glib.h>
+
+#include "tuxcmd-vfs.h"
+#include "filelist.h"
+
+
+struct VfsFilelistData {
+ struct PathTree *files;
+
+ unsigned int list_dir_index;
+ struct PathTree *list_dir_node;
+ char * list_dir_path;
+
+ gboolean follow_symlinks;
+ gboolean add_full_path;
+
+ gboolean break_get_dir_size;
+};
+
+
+struct VfsFilelistData * vfs_filelist_new (struct PathTree *files);
+void vfs_filelist_free (struct VfsFilelistData *data);
+
+guint64 vfs_filelist_get_dir_size (struct VfsFilelistData *data, const char *APath);
+void vfs_filelist_get_dir_size_break (struct VfsFilelistData *data);
+
+gboolean vfs_filelist_file_exists (struct VfsFilelistData *data, const char *FileName, const long Use_lstat);
+TVFSResult vfs_filelist_file_info (struct VfsFilelistData *data, const char *AFileName, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath);
+
+TVFSResult vfs_filelist_list_first (struct VfsFilelistData *data, const char *sDir, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath);
+TVFSResult vfs_filelist_list_next (struct VfsFilelistData *data, struct TVFSItem *Item);
+TVFSResult vfs_filelist_list_close (struct VfsFilelistData *data);
+
+char * vfs_filelist_change_dir (struct VfsFilelistData *data, const char *NewPath);
+
+
+
+#ifdef __cplusplus
+ }
+#endif
+#endif /* __TREEPATH_VFS_H__ */
diff --git a/common/filelist.c b/common/filelist.c
new file mode 100644
index 0000000..cae250e
--- /dev/null
+++ b/common/filelist.c
@@ -0,0 +1,382 @@
+/* Tux Commander VFS: Filelist tree storage
+ * Copyright (C) 2007-2009 Tomas Bzatek <tbzatek@users.sourceforge.net>
+ * Check for updates on tuxcmd.sourceforge.net
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <stdio.h>
+#include <string.h>
+#include <glib.h>
+
+#include "filelist.h"
+#include "strutils.h"
+#include "vfsutils.h"
+
+
+
+struct PathTree *
+filelist_tree_new ()
+{
+ struct PathTree *tree;
+
+ tree = g_malloc0 (sizeof (struct PathTree));
+ log ("filelist_tree_new()\n");
+ tree->items = g_ptr_array_new ();
+ tree->data = NULL;
+ tree->original_index = 0;
+ tree->node = g_strdup ("/");
+ tree->original_pathstr = NULL;
+
+ /* create placeholder data */
+ tree->data = create_placeholder_item (tree->node, vDirectory);
+
+ return tree;
+}
+
+void
+filelist_tree_free (struct PathTree *tree)
+{
+ int i;
+
+ if (! tree) {
+ fprintf (stderr, "filelist_tree_free: tree == NULL !\n");
+ return;
+ }
+
+ if (tree->items && tree->items->len > 0) {
+ for (i = 0; i < tree->items->len; i++)
+ filelist_tree_free (g_ptr_array_index (tree->items, i));
+ }
+ if (tree->items)
+ g_ptr_array_free (tree->items, TRUE);
+ free_vfs_item (tree->data);
+ g_free (tree->node);
+ g_free (tree->original_pathstr);
+ g_free (tree);
+}
+
+
+/* -------------------------------------------------------------------------------------- */
+
+static void
+filelist_tree_print_recurr (struct PathTree *tree, int level)
+{
+ char *fill;
+ int i;
+ struct PathTree* t;
+
+ if (tree) {
+ fill = g_strnfill (level * 2, 32);
+ g_print (" %s#%lu. \"%s\"\n", fill, tree->original_index, tree->node);
+
+ if (tree->items && tree->items->len > 0)
+ for (i = 0; i < tree->items->len; i++) {
+ t = g_ptr_array_index (tree->items, i);
+ filelist_tree_print_recurr (t, level + 1);
+ }
+ g_free (fill);
+ }
+}
+
+void
+filelist_tree_print (struct PathTree *tree)
+{
+ filelist_tree_print_recurr (tree, 0);
+}
+
+
+/* -------------------------------------------------------------------------------------- */
+
+struct PathTree *
+filelist_tree_find_node_by_path (struct PathTree *tree, const char *path)
+{
+ char *p;
+ char *first_part;
+ char *last_part;
+ struct PathTree *node;
+ struct PathTree *t;
+ unsigned int i;
+
+ /* remove leading './' */
+ if (strstr (path, "./") == path)
+ path += 2;
+ /* remove leading and trailing '/' if present */
+ p = exclude_trailing_path_sep (path + G_IS_DIR_SEPARATOR (*path));
+ log (" filelist_tree_find_node_by_path: path = '%s', p = '%s'\n", path, p);
+
+ node = NULL;
+ if (tree && tree->node && g_strcmp0 (tree->node, "/") == 0 && g_strcmp0 (path, "/") == 0) {
+ log (" filelist_tree_find_node_by_path: matched root '/' element, returning.\n");
+ node = tree;
+ } else
+ if (tree && tree->items && tree->items->len > 0) {
+ split_path (p, &first_part, &last_part);
+ log (" filelist_tree_find_node_by_path: pos = '%s'\n", pos);
+ log (" filelist_tree_find_node_by_path: first_part = '%s'\n", first_part);
+ log (" filelist_tree_find_node_by_path: last_part = '%s'\n", last_part);
+
+ /* find existing node */
+ for (i = 0; i < tree->items->len; i++) {
+ t = g_ptr_array_index (tree->items, i);
+ if (g_strcmp0 (t->node, first_part) == 0) {
+ /* this is the final station */
+ if (! last_part) {
+ node = t;
+ log (" filelist_tree_find_node_by_path: found final node '%s', returning.\n", t->node);
+ } else
+
+ /* recurse to child items */
+ if (t->items && last_part) {
+ log (" filelist_tree_find_node_by_path: found node '%s', recursing in deep.\n", t->node);
+ node = filelist_tree_find_node_by_path (t, last_part);
+ } else {
+ /* item found but no subitems */
+ log (" filelist_tree_find_node_by_path: found node '%s', but no subitems found.\n", t->node);
+ }
+
+ break;
+ }
+ }
+ g_free (first_part);
+ g_free (last_part);
+ }
+ g_free (p);
+ return node;
+}
+
+unsigned long int
+filelist_find_original_index_by_path (struct PathTree *tree, const char *path)
+{
+ struct PathTree *node;
+
+ node = filelist_tree_find_node_by_path (tree, path);
+ return node ? node->original_index : 0;
+}
+
+
+/* -------------------------------------------------------------------------------------- */
+
+static void
+filelist_tree_add_item_recurr (struct PathTree *tree, const char *path, struct TVFSItem *item, const char *original_pathstr, unsigned long int original_index)
+{
+ char *first_part;
+ char *last_part;
+ struct PathTree *t;
+ struct PathTree *node;
+ unsigned int i;
+
+ split_path (path, &first_part, &last_part);
+ log (" filelist_tree_add_item_recur: pos = '%s'\n", pos);
+ log (" filelist_tree_add_item_recur: first_part = '%s'\n", first_part);
+ log (" filelist_tree_add_item_recur: last_part = '%s'\n", last_part);
+
+ if (last_part == NULL) {
+ /* final destination, create new item here */
+ log (" filelist_tree_add_item_recur: creating new item here.\n");
+ t = g_malloc0 (sizeof (struct PathTree));
+ t->items = NULL;
+ t->data = item;
+ t->node = g_strdup (first_part);
+ t->original_index = original_index;
+ t->original_pathstr = g_strdup (original_pathstr);
+ if (t->data) {
+ g_free (t->data->FName);
+ g_free (t->data->FDisplayName);
+ t->data->FName = g_strdup (path);
+ t->data->FDisplayName = g_filename_display_name (path);
+ }
+ /* create new list of subitems and add new item */
+ if (! tree->items)
+ tree->items = g_ptr_array_new ();
+ g_ptr_array_add (tree->items, t);
+ } else {
+ /* not a final place, find parent node or create new one if doesn't exist */
+ log (" filelist_tree_add_item_recur: node '%s', path '%s'\n", tree->node, path);
+ if (! tree->items)
+ tree->items = g_ptr_array_new ();
+
+ node = NULL;
+ if (tree->items->len > 0)
+ for (i = 0; i < tree->items->len; i++) {
+ t = g_ptr_array_index (tree->items, i);
+ if (g_strcmp0 (t->node, first_part) == 0) {
+ log (" filelist_tree_add_item_recur: found node '%s'\n", t->node);
+ node = t;
+ break;
+ }
+ }
+
+ if (node == NULL) {
+ /* create new path holder node */
+ log (" filelist_tree_add_item_recur: parent node not found, creating new path holder\n");
+ node = g_malloc0 (sizeof (struct PathTree));
+ node->items = g_ptr_array_new ();
+ node->node = g_strdup (first_part);
+ node->original_index = 0;
+ node->original_pathstr = NULL;
+
+ /* create placeholder data */
+ node->data = create_placeholder_item (node->node, vDirectory);
+ g_ptr_array_add (tree->items, node);
+ }
+
+ /* and recurse one level deeper */
+ filelist_tree_add_item_recurr (node, last_part, item, original_pathstr, original_index);
+ }
+ g_free (first_part);
+ g_free (last_part);
+}
+
+
+gboolean
+filelist_tree_add_item (struct PathTree *tree, const char *path, struct TVFSItem *item, const char *original_pathstr, unsigned long int original_index)
+{
+ char *p;
+ char *pp;
+ struct PathTree *found;
+
+ if (! tree) {
+ fprintf (stderr, "filelist_tree_add_item: tree == NULL !\n");
+ return FALSE;
+ }
+ if (! path) {
+ fprintf (stderr, "filelist_tree_add_item: path == NULL !\n");
+ return FALSE;
+ }
+
+ if (g_strcmp0 (path, "/") == 0 || g_strcmp0 (path, ".") == 0 || g_strcmp0 (path, "..") == 0 || g_strcmp0 (path, "./") == 0) {
+ fprintf (stderr, "filelist_tree_add_item: path '%s' is not a valid path\n", path);
+ return FALSE;
+ }
+
+ /* remove leading './' */
+ if (g_strstr_len (path, -1, "./") == path)
+ path += 2;
+
+ /* remove leading and trailing '/' if present */
+ p = exclude_trailing_path_sep (path + G_IS_DIR_SEPARATOR (*path));
+ log (" filelist_tree_add_item: p = '%s'\n", p);
+
+ pp = canonicalize_filename (p);
+ if (! pp)
+ pp = g_strdup (p);
+
+ found = filelist_tree_find_node_by_path (tree, pp);
+ if (found) {
+ /* replace old data with current ones (record might have been created automatically during path building) */
+ log (" filelist_tree_add_item: found old item, replacing data\n");
+ found->original_index = original_index;
+ /* free old data */
+ free_vfs_item (found->data);
+ found->data = item;
+ if (found->data) {
+ g_free (found->data->FName);
+ g_free (found->data->FDisplayName);
+ found->data->FName = g_strdup (found->node);
+ found->data->FDisplayName = g_filename_display_name (found->node);
+ }
+ } else {
+ /* create new item recursively */
+ filelist_tree_add_item_recurr (tree, pp, item, original_pathstr, original_index);
+ }
+
+ g_free (p);
+ g_free (pp);
+ return TRUE;
+}
+
+
+/* -------------------------------------------------------------------------------------- */
+
+struct PathTree *
+filelist_tree_get_item_by_index (struct PathTree *tree, unsigned long int index)
+{
+ struct PathTree *t = NULL;
+
+ if (tree && tree->items && tree->items->len > index)
+ t = g_ptr_array_index (tree->items, index);
+ return t;
+}
+
+
+/* -------------------------------------------------------------------------------------- */
+
+static void
+resolve_symlink_recurr (struct PathTree *node, struct PathTree *root_tree, const char *path, const char *link_dest, int level)
+{
+ char *rel;
+ char *new_path;
+ struct PathTree *link_t;
+
+ rel = resolve_relative (path, link_dest);
+ g_print (" resolve_symlink_recurr: relative = '%s'\n", rel);
+ if (rel) {
+ link_t = filelist_tree_find_node_by_path (root_tree, rel);
+ if (link_t && link_t->data) {
+ if (link_t->data->IsLink) {
+ /* another symlink, recurse into deep */
+ new_path = g_path_get_dirname (rel);
+ if (level > FILELIST_MAX_SYMLINK_DEPTH || ! new_path) {
+ node->symlink_target_data = link_t->data;
+ g_print (" resolve_symlink_recurr: max depth reached, link is broken. new_path = '%s'\n", new_path);
+ } else {
+ g_print (" resolve_symlink_recurr: going deep, rel = '%s', new_path = '%s'\n", rel, new_path);
+ resolve_symlink_recurr (node, root_tree, new_path, link_t->data->sLinkTo, level + 1);
+ }
+ g_free (new_path);
+ } else {
+ /* final destination */
+ node->symlink_target_data = link_t->data;
+ g_print (" resolve_symlink_recurr: reached target '%s'\n", rel);
+ }
+ } else {
+ /* target not found, link is broken */
+ node->symlink_target_data = NULL;
+ g_print (" resolve_symlink_recurr: target '%s' not found, link is broken\n", rel);
+ }
+ }
+ g_free (rel);
+}
+
+static void
+filelist_tree_resolve_symlinks_recurr (struct PathTree *tree, struct PathTree *root_tree, const char *path)
+{
+ struct PathTree *t;
+ char *new_path;
+ unsigned int i;
+
+ if (tree && tree->items && tree->items->len > 0) {
+ for (i = 0; i < tree->items->len; i++) {
+ t = g_ptr_array_index (tree->items, i);
+
+ if (t && t->data && t->data->IsLink && t->data->sLinkTo) {
+ g_print ("filelist_tree_resolve_symlinks: found '%s/%s' --> '%s', resolving...\n", path, t->node, t->data->sLinkTo);
+ resolve_symlink_recurr (t, root_tree, path, t->data->sLinkTo, 1);
+ }
+ new_path = g_build_filename (path, t->node, NULL);
+ filelist_tree_resolve_symlinks_recurr (t, root_tree, new_path);
+ g_free (new_path);
+ }
+ }
+}
+
+void
+filelist_tree_resolve_symlinks (struct PathTree *tree)
+{
+ log ("filelist_tree_resolve_symlinks: begin\n");
+ filelist_tree_resolve_symlinks_recurr (tree, tree, "/");
+ log ("filelist_tree_resolve_symlinks: end\n");
+}
diff --git a/common/filelist.h b/common/filelist.h
new file mode 100644
index 0000000..e28699e
--- /dev/null
+++ b/common/filelist.h
@@ -0,0 +1,99 @@
+/* Tux Commander VFS: Filelist tree storage
+ * Copyright (C) 2007-2009 Tomas Bzatek <tbzatek@users.sourceforge.net>
+ * Check for updates on tuxcmd.sourceforge.net
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+#ifndef __TREEPATHUTILS_H__
+#define __TREEPATHUTILS_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+#include <glib.h>
+#include "tuxcmd-vfs.h"
+
+
+/****
+ * USAGE / RULES:
+ *
+ * 1. create new tree, add items one by one with filelist_tree_add_item(), found during first archive listing
+ * 2. optionally call filelist_tree_resolve_symlinks()
+ * 3. when mapping a file back, use filelist_find_original_index_by_path() or filelist_tree_find_node_by_path()
+ * and take the particular attribute (original_XXX) as a reference to match the archive records against.
+ *
+ *
+ * - don't set the FName and FDisplayName values, filelist functions set these dynamically
+ * when traversing tree during adding.
+ *
+ * - due to the previous fact, the FDisplayName string is taken from original path, making
+ * sure it's valid UTF-8. No way to have different display name than the file name.
+ *
+ * - it's important to set either 'original_index' or 'original_pathstr' value, to match
+ * exact file back in the archive during VFSCopyToLocal operation. These attributes are
+ * left untouched by filelist functions.
+ *
+ * - all returned values are constants, do not modify anything (except of the item data itself).
+ *
+ * - the 'symlink_target_data' member is just a pointer to an existing data, don't free it.
+ *
+ * - the single 'node' and 'tree' objects are virtually equal, linked together. It may lead
+ * to a slight confusion.
+ *
+ */
+
+
+#define FILELIST_MAX_SYMLINK_DEPTH 20 /* do not go deeper than 20 levels */
+
+
+struct PathTree {
+ GPtrArray * items;
+ struct TVFSItem * data;
+ struct TVFSItem * symlink_target_data;
+ unsigned long int original_index; /* original index as stored in the archive, for matching back */
+ char * node;
+ char * original_pathstr; /* original path as stored in the archive, for matching back */
+};
+
+
+struct PathTree * filelist_tree_new ();
+void filelist_tree_free (struct PathTree *tree);
+
+/* Convenient function to print whole tree, for debugging purposes. */
+void filelist_tree_print (struct PathTree *tree);
+
+/* Add item into the particular structure under the 'path' node. This function tries to find the right node
+ * and creates placeholder nodes in between, when a part of the directory structure is missing.
+ */
+gboolean filelist_tree_add_item (struct PathTree *tree, const char *path, struct TVFSItem *item, const char *original_pathstr, unsigned long int original_index);
+
+struct PathTree * filelist_tree_find_node_by_path (struct PathTree *tree, const char *path);
+unsigned long int filelist_find_original_index_by_path (struct PathTree *tree, const char *path);
+
+void filelist_tree_resolve_symlinks (struct PathTree *tree);
+
+/* Find the n-th item inside one node, the 'index' argument is absolute position in the list.
+ * Don't confuse with 'original_index' member. Used in vfs_filelist_list_next().
+ */
+struct PathTree * filelist_tree_get_item_by_index (struct PathTree *tree, unsigned long int index);
+
+
+#ifdef __cplusplus
+ }
+#endif
+#endif /* __TREEPATHUTILS_H__ */
diff --git a/common/strutils.c b/common/strutils.c
index 5383b8a..3b0a1db 100644
--- a/common/strutils.c
+++ b/common/strutils.c
@@ -1,4 +1,4 @@
-/* Tux Commandern VFS: String utilities
+/* Tux Commander VFS: String utilities
* Copyright (C) 2007 Tomas Bzatek <tbzatek@users.sourceforge.net>
* Check for updates on tuxcmd.sourceforge.net
*
@@ -17,89 +17,102 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <stdio.h>
#include <string.h>
#include <glib.h>
+
#include "strutils.h"
-char* include_trailing_path_sep(const char *APath)
+
+char *
+include_trailing_path_sep (const char *APath)
{
- if (APath == NULL) return NULL;
- char *ANewPath;
-// log("xxx = %s\n", (APath + strlen(APath) - 1));
- if (strcmp(APath + strlen(APath) - 1, "/") != 0) {
- ANewPath = (char*)malloc(strlen(APath) + 2);
- snprintf(ANewPath, strlen(APath) + 2, "%s/", APath);
- } else ANewPath = strdup(APath);
- return ANewPath;
+ if (APath == NULL)
+ return NULL;
+ if (g_strcmp0 (APath + strlen (APath) - 1, "/") != 0)
+ return g_strdup_printf ("%s/", APath);
+ else
+ return g_strdup (APath);
}
-char* exclude_trailing_path_sep(const char *APath)
+char *
+exclude_trailing_path_sep (const char *APath)
{
- if (APath == NULL) return NULL;
- char *ANewPath;
-// log("orig = %s, len = %d, xxx = %s\n", APath, (int)strlen(APath), (APath + strlen(APath) - 1));
- if ((strcmp(APath + strlen(APath) - 1, "/") == 0) && (strlen(APath) > 1)) {
- ANewPath = (char*)malloc(strlen(APath));
- snprintf(ANewPath, strlen(APath), "%s", APath); // The number of bytes copied includes the trailing \0
- } else ANewPath = strdup(APath);
- return ANewPath;
+ if (APath == NULL)
+ return NULL;
+ if (strlen (APath) > 1 && g_strcmp0 (APath + strlen (APath) - 1, "/") == 0)
+ return g_strndup (APath, strlen (APath) - 1);
+ else
+ return g_strdup(APath);
}
-char* include_leading_path_sep(const char *APath)
+char *
+include_leading_path_sep (const char *APath)
{
- if (APath == NULL) return NULL;
- char *ANewPath;
-// log("xxx = %s, %lu, strlen(APath) = %d, index() = %ld\n", APath, (unsigned long int)APath, (int)strlen(APath), (unsigned long int)index(APath, 0x2f));
- if (index(APath, 0x2f) != APath) {
- ANewPath = (char*)malloc(strlen(APath) + 2);
- snprintf(ANewPath, strlen(APath) + 2, "/%s", APath); // The number of bytes copied includes the trailing \0
- } else ANewPath = strdup(APath);
- return ANewPath;
+ if (APath == NULL)
+ return NULL;
+ if (! g_path_is_absolute (APath))
+ return g_strdup_printf ("/%s", APath);
+ else
+ return g_strdup (APath);
}
-char* exclude_leading_path_sep(const char* APath)
+char *
+exclude_leading_path_sep (const char *APath)
{
- if (APath == NULL) return NULL;
- char *s = strdup(APath);
- char *ss;
- if (IS_DIR_SEP(*s)) ss = strdup(s + 1); else ss = strdup(s);
- free(s);
- return ss;
+ if (APath == NULL)
+ return NULL;
+ if (g_path_is_absolute (APath))
+ return g_strdup (APath + 1);
+ else
+ return g_strdup (APath);
}
-char* extract_file_name(const char *APath)
+/* -------------------------------------------------------------------------------------- */
+
+char *
+resolve_relative (const char *source, const char *point_to)
{
- if (APath == NULL) return NULL;
-// log("xxx = %s\n", (APath + strlen(APath) - 1));
- const char *file_part = rindex(APath, 0x2f); // returns NULL if not found or if the file is in the root ( / )
- if (file_part == NULL) return NULL;
- return strdup(file_part + 1);
+ char *rel;
+ char *canon;
+
+ if (source == NULL)
+ return NULL;
+ if (point_to == NULL)
+ return g_strdup (source);
+ if (g_path_is_absolute (point_to))
+ return g_strdup (point_to);
+
+ rel = g_build_filename (source, point_to, NULL);
+ log ("resolve_relative: rel = '%s'\n", rel);
+ canon = canonicalize_filename (rel);
+ log ("resolve_relative: canon = '%s'\n", canon);
+ g_free (rel);
+
+ return canon;
}
-// Extracts file path starting with "/" and ending with "/"
-char* extract_file_path(const char *APath)
+void
+split_path (const char *path, char **first_part, char **last_part)
{
- if (APath == NULL) return NULL;
-// log("xxx = %s\n", (APath + strlen(APath) - 1));
- const char *file_part = rindex(APath, 0x2f); // returns NULL if not found or if the file is in the root ( / )
- if (file_part == NULL) return NULL;
- char *ANewPath = (char*)malloc(file_part - APath + 2);
- snprintf(ANewPath, file_part - APath + 2, "%s", APath);
- return ANewPath;
+ const char *pos;
+
+ pos = strstr (path, "/");
+ if (pos) {
+ *first_part = g_strndup (path, pos - path);
+ *last_part = g_strdup (pos + 1);
+ } else {
+ *first_part = g_strdup (path);
+ *last_part = NULL;
+ }
}
+/* -------------------------------------------------------------------------------------- */
-
-
-
-
-
-// canonicalize_filename() is stolen from glib-2.16
-// Copyright (C) 2006-2007 Alexander Larsson <alexl@redhat.com>
+/* canonicalize_filename() has been stolen from glib-2.16 */
+/* Copyright (C) 2006-2007 Alexander Larsson <alexl@redhat.com> */
char *
canonicalize_filename (const char *filename)
{
@@ -179,34 +192,18 @@ canonicalize_filename (const char *filename)
}
-char* resolve_relative(const char *source, const char *point_to)
-{
- if (source == NULL) return NULL;
- if (point_to == NULL) return strdup(source);
- if (g_path_is_absolute(point_to)) return strdup(point_to);
-
- char *rel = g_build_filename(source, point_to, NULL);
- log("resolve_relative: rel = '%s'\n", rel);
- char *canon = canonicalize_filename(rel);
- log("resolve_relative: canon = '%s'\n", canon);
- free(rel);
-
- return canon;
-}
-
-
+/* -------------------------------------------------------------------------------------- */
-// Originally stolen from wine-0.9.19, utf8.c
-// Copyright 2000 Alexandre Julliard
-char*
+/* stolen from wine-0.9.19, utf8.c */
+/* Copyright 2000 Alexandre Julliard */
+char *
wide_to_utf8 (const wchar_t *src)
{
#define CONV_BUFF_MAX 32768
int len;
char *buf, *dst, *ret;
- buf = (char *) malloc (CONV_BUFF_MAX);
- memset (&buf[0], 0, CONV_BUFF_MAX);
+ buf = (char *) g_malloc0 (CONV_BUFF_MAX);
dst = buf;
if (src)
@@ -251,6 +248,6 @@ wide_to_utf8 (const wchar_t *src)
}
ret = g_strdup (buf);
- free (buf);
+ g_free (buf);
return ret;
}
diff --git a/common/strutils.h b/common/strutils.h
index 84f6013..7fed4c5 100644
--- a/common/strutils.h
+++ b/common/strutils.h
@@ -20,32 +20,36 @@
#ifndef __STRUTILS_H__
#define __STRUTILS_H__
-
-
-#include <string.h>
-#include <stdlib.h>
+#ifdef __cplusplus
+ extern "C" {
+#endif
#ifdef __VERBOSE_DEBUG
- #define log(msg...) printf(msg)
+ #define log(msg...) g_print(msg)
#else
#define log(msg...) { }
#endif
-#define IS_DIR_SEP(ch) ((ch) == '/')
+/* path manipulating functions, all return newly allocated string */
+char * include_trailing_path_sep (const char *APath);
+char * exclude_trailing_path_sep (const char *APath);
+char * include_leading_path_sep (const char *APath);
+char * exclude_leading_path_sep (const char *APath);
+
+char * resolve_relative (const char *source, const char *point_to);
-// path manipulating functions, all return newly allocated string, you can then free them as you want
-char* include_trailing_path_sep(const char *APath);
-char* exclude_trailing_path_sep(const char *APath);
-char* include_leading_path_sep(const char *APath);
-char* exclude_leading_path_sep(const char *APath);
-char* extract_file_name(const char *APath);
-char* extract_file_path(const char *APath);
-char* resolve_relative(const char *source, const char *point_to);
-char* canonicalize_filename(const char *filename);
+/* split the first path element (single level) and copy the rest (multiple levels) */
+void split_path (const char *path, char **first_part, char **last_part);
-char* wide_to_utf8(const wchar_t *src);
+char * canonicalize_filename (const char *filename);
+char * wide_to_utf8 (const wchar_t *src);
+
+
+#ifdef __cplusplus
+ }
+#endif
#endif /* __STRUTILS_H__ */
diff --git a/common/treepath_vfs.c b/common/treepath_vfs.c
deleted file mode 100644
index 34a779a..0000000
--- a/common/treepath_vfs.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/* Tux Commander VFS: basic tree_path routines
- * Copyright (C) 2007 Tomas Bzatek <tbzatek@users.sourceforge.net>
- * Check for updates on tuxcmd.sourceforge.net
- *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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 <stdio.h>
-#include <string.h>
-#include <glib.h>
-
-#include "vfs_types.h"
-#include "strutils.h"
-#include "vfsutils.h"
-#include "treepathutils.h"
-#include "treepath_vfs.h"
-
-
-
-
-
-
-struct VfsFilelistData* vfs_filelist_new(struct PathTree *files)
-{
- struct VfsFilelistData *data= (struct VfsFilelistData*)malloc(sizeof(struct VfsFilelistData));
- memset(data, 0, sizeof(struct VfsFilelistData));
-
- log("vfs_filelist_new()\n");
- data->files = files;
-
- return data;
-}
-
-
-void vfs_filelist_free(struct VfsFilelistData *data)
-{
- if (! data) {
- fprintf(stderr, "vfs_filelist_free: data == NULL !\n");
- return;
- }
- if (data)
- {
- free(data);
- }
-}
-
-void vfs_filelist_set_files(struct VfsFilelistData *data, struct PathTree *files)
-{
- if (data) data->files = files;
-}
-
-
-
-
-
-u_int64_t internal_get_dir_size(struct VfsFilelistData *data, struct PathTree *tree)
-{
- if (data->break_get_dir_size) return 0;
- u_int64_t Size = 0;
- if (tree) {
- struct PathTree *n = NULL;
- unsigned long idx = 0;
- while ((n = filelist_tree_get_item_by_index(tree, idx))) {
- if (data->break_get_dir_size) break;
- if (n->data) {
- log("internal_get_dir_size: found item '%s', size = %zd \n", n->node, n->data->iSize);
- Size += (n->data->ItemType == vDirectory) ? internal_get_dir_size(data, n) : n->data->iSize;
- }
- idx++;
- }
- }
- return Size;
-}
-
-u_int64_t vfs_filelist_get_dir_size(struct VfsFilelistData *data, char *APath)
-{
- if (! data) return 0;
- data->break_get_dir_size = FALSE;
-
- struct PathTree* node = filelist_tree_find_node_by_path(data->files, APath);
- if (node) {
- return internal_get_dir_size(data, node);
- } else {
- printf("(EE) VFSGetDirSize: path '%s' not found\n", APath);
- return 0;
- }
-}
-
-void vfs_filelist_get_dir_size_break(struct VfsFilelistData *data)
-{
- if (data) data->break_get_dir_size = TRUE;
-}
-
-
-
-
-
-
-long vfs_filelist_file_exists(struct VfsFilelistData *data, const char *FileName, const long Use_lstat)
-{
- if ((data) && (data->files)) {
- struct PathTree* node = filelist_tree_find_node_by_path(data->files, FileName);
- return node != NULL;
- } else {
- printf ("(EE) VFSFileExists: Invalid pointers to data objects.\n");
- return FALSE;
- }
-}
-
-
-TVFSResult vfs_filelist_file_info(struct VfsFilelistData *data, char *AFileName, struct TVFSItem *Item)
-{
- if ((data) && (data->files)) {
- struct PathTree* node = filelist_tree_find_node_by_path(data->files, AFileName);
- if (node) {
- if (node->data) {
- copy_vfs_item(node->data, Item);
- Item->FName = strdup(AFileName);
- Item->FDisplayName = strdup(AFileName);
- printf("(II) VFSFileInfo: found file: '%s'\n", Item->FName);
- return cVFS_OK;
- } else {
- printf("(EE) VFSFileInfo: node->data == NULL! \n");
- return cVFS_Failed;
- }
- } else {
- printf("(EE) VFSFileInfo: file specified not found\n");
- return cVFS_No_More_Files;
- }
- } else {
- printf ("(EE) VFSFileInfo: Invalid pointers to data objects.\n");
- return cVFS_Failed;
- }
-}
-
-
-
-
-
-
-TVFSResult vfs_filelist_list_first(struct VfsFilelistData *data, char *sDir, struct TVFSItem *Item)
-{
- data->list_dir_index = -1;
- data->list_dir_node = NULL;
-
- if (sDir == NULL) {
- printf("(EE) VFSListFirst: sDir is NULL!\n");
- return cVFS_Failed;
- }
-
- data->list_dir_index = 0;
- data->list_dir_node = filelist_tree_find_node_by_path(data->files, sDir);
-
- // Find the directory in the filelist
- if (data->list_dir_node) {
- struct PathTree* node = filelist_tree_get_item_by_index(data->list_dir_node, data->list_dir_index);
- if (node) {
- copy_vfs_item(node->data, Item);
- printf("(II) VFSListFirst: found file: %s\n", Item->FName);
- return cVFS_OK;
- } else {
- printf("(II) VFSListFirst: no more files\n");
- return cVFS_No_More_Files;
- }
- } else {
- printf ("(EE) VFSListFirst: Directory '%s' not found.\n", sDir);
- return cVFS_Failed;
- }
-}
-
-TVFSResult vfs_filelist_list_next(struct VfsFilelistData *data, char *sDir, struct TVFSItem *Item)
-{
- if (! data->list_dir_node) {
- printf("(EE) VFSListNext: data->list_dir_node is NULL!\n");
- return cVFS_Failed;
- }
- data->list_dir_index++;
-
- struct PathTree* node = filelist_tree_get_item_by_index(data->list_dir_node, data->list_dir_index);
- if (node) {
- copy_vfs_item(node->data, Item);
- printf("(II) VFSListNext: found file: %s\n", Item->FName);
- return cVFS_OK;
- } else {
- printf("(II) VFSListNext: no more files\n");
- return cVFS_No_More_Files;
- }
-}
-
-TVFSResult vfs_filelist_list_close(struct VfsFilelistData *data)
-{
- data->list_dir_index = -1;
- data->list_dir_node = NULL;
- return cVFS_OK;
-}
-
-
-char* vfs_filelist_change_dir(struct VfsFilelistData *data, char *NewPath)
-{
- if (NewPath == NULL) {
- printf("(EE) VFSChangeDir: NewPath is NULL!\n");
- return NULL;
- }
-
- // Make up the target path
- printf ("(--) VFSChangeDir: Going to change dir from '%s'\n", NewPath);
- char *ANewPath = exclude_trailing_path_sep(NewPath);
- if (strlen(ANewPath) <= 0) ANewPath = strdup("/");
- printf ("(--) VFSChangeDir: Going to change dir to '%s'\n", ANewPath);
-
- // Find the directory in the filelist
- if (filelist_tree_find_node_by_path(data->files, ANewPath)) {
- return ANewPath;
- } else {
- printf ("(EE) VFSChangeDir: Directory '%s' not found.\n", ANewPath);
- free(ANewPath);
- return NULL;
- }
-}
diff --git a/common/treepath_vfs.h b/common/treepath_vfs.h
deleted file mode 100644
index 2f78414..0000000
--- a/common/treepath_vfs.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Tux Commander VFS: basic tree_path routines
- * Copyright (C) 2007 Tomas Bzatek <tbzatek@users.sourceforge.net>
- * Check for updates on tuxcmd.sourceforge.net
- *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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
- */
-
-#ifndef __TREEPATH_VFS_H__
-#define __TREEPATH_VFS_H__
-
-
-#include <stdio.h>
-#include <string.h>
-#include <glib.h>
-
-#include "vfs_types.h"
-#include "treepathutils.h"
-
-
-struct VfsFilelistData {
- struct PathTree *files;
-
- unsigned int list_dir_index;
- struct PathTree *list_dir_node;
-
- gboolean break_get_dir_size;
-};
-
-
-struct VfsFilelistData* vfs_filelist_new(struct PathTree *files);
-void vfs_filelist_free(struct VfsFilelistData *data);
-void vfs_filelist_set_files(struct VfsFilelistData *data, struct PathTree *files);
-
-u_int64_t vfs_filelist_get_dir_size(struct VfsFilelistData *data, char *APath);
-void vfs_filelist_get_dir_size_break(struct VfsFilelistData *data);
-
-long vfs_filelist_file_exists(struct VfsFilelistData *data, const char *FileName, const long Use_lstat);
-TVFSResult vfs_filelist_file_info(struct VfsFilelistData *data, char *AFileName, struct TVFSItem *Item);
-
-TVFSResult vfs_filelist_list_first(struct VfsFilelistData *data, char *sDir, struct TVFSItem *Item);
-TVFSResult vfs_filelist_list_next(struct VfsFilelistData *data, char *sDir, struct TVFSItem *Item);
-TVFSResult vfs_filelist_list_close(struct VfsFilelistData *data);
-
-char* vfs_filelist_change_dir(struct VfsFilelistData *data, char *NewPath);
-
-
-
-
-#endif /* __TREEPATH_VFS_H__ */
diff --git a/common/treepathutils.c b/common/treepathutils.c
deleted file mode 100644
index c8f2b18..0000000
--- a/common/treepathutils.c
+++ /dev/null
@@ -1,386 +0,0 @@
-/* Tux Commander VFS: String utilities
- * Copyright (C) 2007-2008 Tomas Bzatek <tbzatek@users.sourceforge.net>
- * Check for updates on tuxcmd.sourceforge.net
- *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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 <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <glib.h>
-
-#include "treepathutils.h"
-#include "strutils.h"
-#include "vfsutils.h"
-
-
-
-
-
-
-struct PathTree* filelist_tree_new()
-{
- struct PathTree *tree = (struct PathTree*)malloc(sizeof(struct PathTree));
- memset(tree, 0, sizeof(struct PathTree));
- log("filelist_tree_new()\n");
- tree->items = g_ptr_array_new();
- tree->data = NULL;
- tree->index = 0;
- tree->node = strdup("/");
- tree->original_pathstr = NULL;
-
- // create placeholder data
- tree->data = (struct TVFSItem*)malloc(sizeof(struct TVFSItem));
- memset(tree->data, 0, sizeof(struct TVFSItem));
- tree->data->FName = strdup(tree->node);
- tree->data->FDisplayName = strdup(tree->node);
- tree->data->ItemType = vDirectory;
- tree->data->iMode = S_IRWXO + S_IRWXG + S_IRWXU;
- tree->data->iUID = geteuid();
- tree->data->iGID = getegid();
- tree->data->m_time = time(NULL);
- tree->data->c_time = tree->data->m_time;
- tree->data->a_time = tree->data->m_time;
-
- return tree;
-}
-
-
-void filelist_tree_free(struct PathTree *tree)
-{
- if (! tree) {
- fprintf(stderr, "filelist_tree_free: tree == NULL !\n");
- return;
- }
- if (tree)
- {
- if ((tree->items) && (tree->items->len > 0)) {
- unsigned int i;
- for (i = 0; i < tree->items->len; i++)
- filelist_tree_free((struct PathTree*)g_ptr_array_index(tree->items, i));
- }
- if (tree->items)
- g_ptr_array_free(tree->items, TRUE);
- if (tree->data) {
- if (tree->data->FName) free(tree->data->FName);
- if (tree->data->FDisplayName) free(tree->data->FDisplayName);
- if (tree->data->sLinkTo) free(tree->data->sLinkTo);
- free(tree->data);
- }
- if (tree->node)
- free(tree->node);
- if (tree->original_pathstr)
- free(tree->original_pathstr);
- free(tree);
- }
-}
-
-
-void filelist_tree_print_recurr(struct PathTree *tree, int level)
-{
- if (tree) {
- char *fill = g_strnfill(level * 2, 32);
- printf(" %s#%lu. \"%s\"\n", fill, tree->index, tree->node);
-
- if ((tree->items) && (tree->items->len > 0)) {
- unsigned int i;
- for (i = 0; i < tree->items->len; i++)
- {
- struct PathTree* t = (struct PathTree*)g_ptr_array_index(tree->items, i);
- filelist_tree_print_recurr(t, level + 1);
- }
- }
-
- g_free(fill);
- }
-}
-
-
-void filelist_tree_print(struct PathTree *tree)
-{
- filelist_tree_print_recurr(tree, 0);
-}
-
-
-struct PathTree* filelist_tree_find_node_by_path(struct PathTree *tree, const char *path)
-{
- // remove leading './'
- if (strstr(path, "./") == path) path += 2;
-
- // remove leading and trailing '/' if present
- char *p;
- if (IS_DIR_SEP(*path)) p = exclude_trailing_path_sep(path + 1);
- else p = exclude_trailing_path_sep(path);
-
- log(" filelist_tree_find_node_by_path: path = '%s', p = '%s'\n", path, p);
-// log("xx: '%s', '%s'\n", tree->node, path);
-
- struct PathTree* node = NULL;
- if ((tree) && (tree->node) && (strcmp(tree->node, "/") == 0) && (strcmp(path, "/") == 0)) {
- log(" filelist_tree_find_node_by_path: matched root '/' element, returning.\n");
- node = tree;
- } else
- if ((tree) && (tree->items) && (tree->items->len > 0)) {
- // split path
- char *pos = strstr(p, "/");
- char *first_part;
- char *last_part;
- if (pos) {
- first_part = strndup(p, pos - p);
- if (strlen(pos + 1) > 0) last_part = strdup(pos + 1);
- else last_part = NULL;
- } else {
- first_part = strdup(p);
- last_part = NULL;
- }
- log(" filelist_tree_find_node_by_path: pos = '%s'\n", pos);
- log(" filelist_tree_find_node_by_path: first_part = '%s'\n", first_part);
- log(" filelist_tree_find_node_by_path: last_part = '%s'\n", last_part);
-
- // find existing node
- unsigned int i;
- for (i = 0; i < tree->items->len; i++)
- {
- struct PathTree* t = (struct PathTree*)g_ptr_array_index(tree->items, i);
- if (strcmp(t->node, first_part) == 0) {
- // this is the final station
- if (! last_part) {
- node = t;
- log(" filelist_tree_find_node_by_path: found final node '%s', returning.\n", t->node);
- } else
- // recurse to child items
- if ((t->items) && (last_part)) {
- log(" filelist_tree_find_node_by_path: found node '%s', recursing in deep.\n", t->node);
- node = filelist_tree_find_node_by_path(t, last_part);
- } else {
- // item found but no subitems
- log(" filelist_tree_find_node_by_path: found node '%s', but no subitems found.\n", t->node);
- }
-
- break;
- }
- }
- free(first_part);
- free(last_part);
- }
- free(p);
- return node;
-}
-
-unsigned long int filelist_find_index_by_path(struct PathTree *tree, const char *path)
-{
- struct PathTree* node = filelist_tree_find_node_by_path(tree, path);
- if (node) return node->index;
- else return 0;
-}
-
-void filelist_tree_add_item_recurr(struct PathTree *tree, const char *path, const char *original_pathstr, struct TVFSItem *item, unsigned long index)
-{
- const char *pos = strstr(path, "/");
- char *first_part;
- char *last_part;
- if (pos) {
- first_part = strndup(path, pos - path);
- if (strlen(pos + 1) > 0) last_part = strdup(pos + 1);
- else last_part = NULL;
- } else {
- first_part = strdup(path);
- last_part = NULL;
- }
- log(" filelist_tree_add_item_recur: pos = '%s'\n", pos);
- log(" filelist_tree_add_item_recur: first_part = '%s'\n", first_part);
- log(" filelist_tree_add_item_recur: last_part = '%s'\n", last_part);
-
- if (! last_part)
- { // final destination, create new item here
- log(" filelist_tree_add_item_recur: creating new item here.\n");
- struct PathTree *t = (struct PathTree*)malloc(sizeof(struct PathTree));
- memset(t, 0, sizeof(struct PathTree));
- t->items = NULL;
- t->data = item;
- t->index = index;
- t->node = strdup(path);
- if (original_pathstr) t->original_pathstr = strdup(original_pathstr);
- if (t->data) t->data->FName = strdup(path);
- if (t->data) t->data->FDisplayName = strdup(path);
- // create new list of subitems and add new item
- if (! tree->items) tree->items = g_ptr_array_new();
- g_ptr_array_add(tree->items, t);
- } else
- { // find parent node or create new one if doesn't exist
- log(" filelist_tree_add_item_recur: node '%s', path '%s'\n", tree->node, path);
- if (! tree->items) tree->items = g_ptr_array_new();
-
- struct PathTree *node = NULL;
- if (tree->items->len > 0) {
- unsigned int i;
- for (i = 0; i < tree->items->len; i++)
- {
- struct PathTree* t = (struct PathTree*)g_ptr_array_index(tree->items, i);
- if (strcmp(t->node, first_part) == 0) {
- log(" filelist_tree_add_item_recur: found node '%s'\n", t->node);
- node = t;
- break;
- }
- }
- }
-
- // create new path holder node
- if (! node) {
- log(" filelist_tree_add_item_recur: parent node not found, creating new path holder\n");
- node = (struct PathTree*)malloc(sizeof(struct PathTree));
- memset(node, 0, sizeof(struct PathTree));
- node->items = g_ptr_array_new();
- node->index = 0;
- node->node = strdup(first_part);
- node->original_pathstr = NULL;
-
- // create placeholder data
- node->data = (struct TVFSItem*)malloc(sizeof(struct TVFSItem));
- memset(node->data, 0, sizeof(struct TVFSItem));
- node->data->FName = strdup(node->node);
- node->data->FDisplayName = strdup(node->node);
- node->data->ItemType = vDirectory;
- node->data->iMode = S_IRWXO + S_IRWXG + S_IRWXU;
- node->data->iUID = geteuid();
- node->data->iGID = getegid();
- node->data->m_time = time(NULL);
- node->data->c_time = node->data->m_time;
- node->data->a_time = node->data->m_time;
-
- g_ptr_array_add(tree->items, node);
- }
-
- // and recurse one level deeper
- filelist_tree_add_item_recurr(node, last_part, original_pathstr, item, index);
- }
-
- free(first_part);
- free(last_part);
-}
-
-
-gboolean filelist_tree_add_item(struct PathTree *tree, const char *path, const char *original_pathstr, struct TVFSItem *item, unsigned long index)
-{
- if (! tree) {
- fprintf(stderr, "filelist_tree_add_item: tree == NULL !\n");
- return FALSE;
- }
- if (! path) {
- fprintf(stderr, "filelist_tree_add_item: path == NULL !\n");
- return FALSE;
- }
-
- if ((strcmp(path, "/") == 0) || (strcmp(path, ".") == 0) || (strcmp(path, "..") == 0) || (strcmp(path, "./") == 0)) {
- fprintf(stderr, "filelist_tree_add_item: path '%s' is not a valid path\n", path);
- return FALSE;
- }
-
- // remove leading './'
- if (strstr(path, "./") == path) path += 2;
-
- // remove leading and trailing '/' if present
- char *p;
- if (IS_DIR_SEP(*path)) p = exclude_trailing_path_sep(path + 1);
- else p = exclude_trailing_path_sep(path);
- log(" filelist_tree_add_item: p = '%s'\n", p);
-
- char *pp;
- pp = canonicalize_filename (p);
- if (! pp)
- pp = strdup (p);
-
- struct PathTree* found = filelist_tree_find_node_by_path(tree, pp);
-
- if (found)
- { // replace old data with current ones (record might have been created automatically during path building)
- log(" filelist_tree_add_item: found old item, replacing data\n");
- found->index = index;
- // free old data
- if (found->data) free_vfs_item(found->data);
- found->data = item;
- if (found->data) found->data->FName = strdup(found->node);
- if (found->data) found->data->FDisplayName = strdup(found->node);
- } else
- // create new item recursively
- filelist_tree_add_item_recurr(tree, pp, original_pathstr, item, index);
-
- free(p);
- free(pp);
- return TRUE;
-}
-
-struct PathTree* filelist_tree_get_item_by_index(struct PathTree *tree, unsigned long index)
-{
- struct PathTree* t = NULL;
- if ((tree) && (tree->items) && (tree->items->len > index)) {
- t = (struct PathTree*)g_ptr_array_index(tree->items, index);
- }
- return t;
-}
-
-
-void filelist_tree_resolve_symlinks_recurr(struct PathTree *tree, struct PathTree *root_tree, const char *path)
-{
- if (tree) {
- if ((tree->items) && (tree->items->len > 0)) {
- unsigned int i;
- for (i = 0; i < tree->items->len; i++)
- {
- struct PathTree* t = (struct PathTree*)g_ptr_array_index(tree->items, i);
- gchar *new_path;
-
- if ((t) && (t->data) && (t->data->ItemType == vSymlink) && (t->data->sLinkTo)) {
- log("filelist_tree_resolve_symlinks: found '%s/%s' --> '%s'\n", path, t->node, t->data->sLinkTo);
- gchar *rel = resolve_relative(path, t->data->sLinkTo);
- log(" filelist_tree_resolve_symlinks: relative = '%s'\n", rel);
- if (rel) {
- struct PathTree* link_t = filelist_tree_find_node_by_path(root_tree, rel);
- if ((link_t) && (link_t->data)) {
- /* WARNING: this is dangerous since we're destroying the symlink type */
- // t->data->ItemType = link_t->data->ItemType;
- t->data->a_time = link_t->data->a_time;
- t->data->c_time = link_t->data->c_time;
- t->data->m_time = link_t->data->m_time;
- t->data->iGID = link_t->data->iGID;
- t->data->iUID = link_t->data->iUID;
- t->data->iMode = link_t->data->iMode;
- t->data->iSize = link_t->data->iSize;
- }
- g_free(rel);
- }
- }
- if ((strlen(path) == 1) && (IS_DIR_SEP(*path)))
- new_path = g_strconcat("/", t->node, NULL);
- else
- new_path = g_strconcat(path, "/", t->node, NULL);
-
- filelist_tree_resolve_symlinks_recurr(t, root_tree, new_path);
- g_free(new_path);
- }
- }
- }
-}
-
-void filelist_tree_resolve_symlinks(struct PathTree *tree)
-{
- log("filelist_tree_resolve_symlinks: begin\n");
- filelist_tree_resolve_symlinks_recurr(tree, tree, "/");
- log("filelist_tree_resolve_symlinks: end\n");
-}
-
diff --git a/common/treepathutils.h b/common/treepathutils.h
deleted file mode 100644
index a902a33..0000000
--- a/common/treepathutils.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Tux Commander VFS: String utilities
- * Copyright (C) 2007-2008 Tomas Bzatek <tbzatek@users.sourceforge.net>
- * Check for updates on tuxcmd.sourceforge.net
- *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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
- */
-
-#ifndef __TREEPATHUTILS_H__
-#define __TREEPATHUTILS_H__
-
-
-#include <stdio.h>
-#include <string.h>
-#include <glib.h>
-
-#include "vfs_types.h"
-
-
-struct PathTree {
- GPtrArray* items;
- struct TVFSItem *data;
- unsigned long index;
- char *node;
- char *original_pathstr;
-};
-
-
-struct PathTree* filelist_tree_new();
-void filelist_tree_free(struct PathTree *tree);
-void filelist_tree_print(struct PathTree *tree);
-
-/* Symlink resolving: strongly discouraged to use at the present state of art.
- * We would have to implement full symlink system, do loop checking etc. */
-void filelist_tree_resolve_symlinks(struct PathTree *tree);
-
-gboolean filelist_tree_add_item(struct PathTree *tree, const char *path, const char *original_pathstr, struct TVFSItem *item, unsigned long index);
-struct PathTree* filelist_tree_find_node_by_path(struct PathTree *tree, const char *path);
-unsigned long int filelist_find_index_by_path(struct PathTree *tree, const char *path);
-struct PathTree* filelist_tree_get_item_by_index(struct PathTree *tree, unsigned long index);
-
-
-
-
-
-
-#endif /* __TREEPATHUTILS_H__ */
diff --git a/common/vfs_types.h b/common/tuxcmd-vfs.h
index 49c62e9..2ebed6d 100644
--- a/common/vfs_types.h
+++ b/common/tuxcmd-vfs.h
@@ -1,9 +1,9 @@
/* Tux Commander VFS: Virtual File System types and definitions
* - prototypes functions and types
- * draft version 3
+ * draft version 5
*
* Copyright (C) 2003 Radek Cervinka <radek.cervinka@centrum.cz>
- * Copyright (C) 2008 Tomas Bzatek <tbzatek@users.sourceforge.net>
+ * Copyright (C) 2008-2009 Tomas Bzatek <tbzatek@users.sourceforge.net>
*
* 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
@@ -23,10 +23,12 @@
#ifndef __VFS_TYPES_H__
#define __VFS_TYPES_H__
+#ifdef __cplusplus
+ extern "C" {
+#endif
-#include <stdio.h>
-#include <stdint.h>
-#include <sys/types.h>
+
+#include <glib.h>
typedef int TVFSResult;
@@ -49,62 +51,50 @@ typedef enum {
} TVFSPasswordSave;
-typedef void (* TVFSLogFunc)(const char *s);
-typedef void *TVFSFileDes;
+typedef void (* TVFSLogFunc) (const char *s);
+typedef void * TVFSFileDes;
/* Return FALSE to break the operation */
typedef int (* TVFSProgressCallback)
- (u_int64_t position,
- u_int64_t max,
- void *user_data);
+ (guint64 position,
+ guint64 max,
+ void *user_data);
/* Return index of the choice selected or negative number when dialog has been cancelled */
typedef void (* TVFSAskQuestionCallback)
- (const char *message,
+ (const char *message,
const char **choices,
- int *choice,
- int cancel_choice,
- void *user_data);
+ int *choice,
+ int cancel_choice,
+ void *user_data);
typedef int (* TVFSAskPasswordCallback)
- (const char *message,
- const char *default_user,
- const char *default_domain,
- const char *default_password,
- TVFSAskPasswordFlags flags,
- char **username,
- char **password,
- int *anonymous,
- char **domain,
- TVFSPasswordSave *password_save,
- void *user_data);
-
-
-static const int cVFSVersion = 5; // current version of the VFS API
-
-// Capabilities
-static const int capVFS_nil = 0;
-static const int capVFS_List = 1 << 0;
-static const int capVFS_CopyOut = 1 << 1;
-static const int capVFS_CopyIn = 1 << 2;
-static const int capVFS_MkDir = 1 << 3;
-static const int capVFS_RmDir = 1 << 4;
-static const int capVFS_Multiple = 1 << 5; // support multiple files = background copy & thread safe
-static const int capVFS_Delete = 1 << 6;
-static const int capVFS_Rename = 1 << 7;
-static const int capVFS_Execute = 1 << 8;
-static const int capVFS_Append = 1 << 9;
-
-// Error codes (TVFSResult)
+ (const char *message,
+ const char *default_user,
+ const char *default_domain,
+ const char *default_password,
+ TVFSAskPasswordFlags flags,
+ char **username,
+ char **password,
+ int *anonymous,
+ char **domain,
+ TVFSPasswordSave *password_save,
+ void *user_data);
+
+
+/* current version of the VFS API */
+static const int cVFSVersion = 5;
+
+/* error codes (TVFSResult) */
enum {
cVFS_OK = 0,
- cVFS_Failed = 1, // also No such file
+ cVFS_Failed = 1, /* also No such file */
cVFS_Cancelled = 2,
cVFS_Not_Supported = 3,
cVFS_No_More_Files = 4,
cVFS_ReadErr = 5,
- cVFS_WriteErr = 6, // also Readonly FileSystem
+ cVFS_WriteErr = 6, /* also Readonly FileSystem */
cVFS_LoginFailed = 7,
cVFS_PermissionDenied = 8,
cVFS_NoSpaceLeft = 9,
@@ -115,7 +105,7 @@ enum {
};
-// Open modes
+/* open modes */
enum {
cVFS_OpenRead,
cVFS_OpenWrite,
@@ -123,40 +113,42 @@ enum {
};
-// Item Type enum
enum TVFSItemType {
vRegular = 0,
- vSymlink = 1,
- vChardev = 2,
- vBlockdev = 3,
- vDirectory = 4,
- vFifo = 5,
- vSock = 6,
- vOther = 7
+ vChardev = 1,
+ vBlockdev = 2,
+ vDirectory = 3,
+ vFifo = 4,
+ vSock = 5,
+ vOther = 6
};
struct TVFSItem {
- char *FName;
- char *FDisplayName; // valid UTF-8 string
- int64_t iSize;
- int64_t iPackedSize; // set to -1 if plugin doesn't support this feature
- __time_t m_time; // numbers should be located before the other variables (bug?)
- __time_t a_time;
- __time_t c_time;
- __mode_t iMode;
- char *sLinkTo;
- __uid_t iUID;
- __gid_t iGID;
+ char *FName;
+ char *FDisplayName; /* valid UTF-8 string */
+ guint64 iSize;
+ gint64 iPackedSize; /* set to -1 if plugin doesn't support this feature */
+ guint32 m_time;
+ guint32 a_time;
+ guint32 c_time;
+ guint32 iMode;
+ gboolean IsLink;
+ char *sLinkTo;
+ guint32 iUID;
+ guint32 iGID;
enum TVFSItemType ItemType;
};
struct TVFSInfo {
- char *ID; // unique identifier, not shown in GUI
- char *Name; // plugin name, GUI string (UTF-8)
- char *About; // GUI string (UTF-8)
- char *Copyright; // GUI string (UTF-8)
+ char *ID; /* unique identifier, not shown in GUI */
+ char *Name; /* plugin name, GUI string (UTF-8) */
+ char *About; /* GUI string (UTF-8) */
+ char *Copyright; /* GUI string (UTF-8) */
};
+#ifdef __cplusplus
+ }
+#endif
#endif /* __VFS_TYPES_H__ */
diff --git a/common/vfsutils.c b/common/vfsutils.c
index 173c0df..856d9f9 100644
--- a/common/vfsutils.c
+++ b/common/vfsutils.c
@@ -1,5 +1,5 @@
-/* Tux Commander VFS: String utilities
- * Copyright (C) 2007 Tomas Bzatek <tbzatek@users.sourceforge.net>
+/* Tux Commander VFS: VFS utilities
+ * Copyright (C) 2007-2009 Tomas Bzatek <tbzatek@users.sourceforge.net>
* Check for updates on tuxcmd.sourceforge.net
*
* This program is free software; you can redistribute it and/or modify
@@ -17,52 +17,76 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <stdio.h>
+#include <unistd.h>
#include <string.h>
+#include <sys/stat.h>
#include <glib.h>
#include "strutils.h"
-#include "vfs_types.h"
+#include "tuxcmd-vfs.h"
-void copy_vfs_item(struct TVFSItem *src, struct TVFSItem *dst)
+void
+copy_vfs_item (struct TVFSItem *src, struct TVFSItem *dst)
{
+ memcpy (dst, src, sizeof (struct TVFSItem));
dst->FName = g_strdup (src->FName);
dst->FDisplayName = g_strdup (src->FDisplayName);
- dst->iSize = src->iSize;
- dst->iPackedSize = src->iPackedSize;
- dst->m_time = src->m_time;
- dst->a_time = src->a_time;
- dst->c_time = src->c_time;
- dst->iMode = src->iMode;
dst->sLinkTo = g_strdup (src->sLinkTo);
- dst->iUID = src->iUID;
- dst->iGID = src->iGID;
- dst->ItemType = src->ItemType;
}
-void free_vfs_item(struct TVFSItem *item)
+void
+free_vfs_item (struct TVFSItem *item)
{
if (item) {
- if (item->FName)
- free(item->FName);
- if (item->FDisplayName)
- free(item->FDisplayName);
- if (item->sLinkTo)
- free(item->sLinkTo);
- free(item);
+ g_free (item->FName);
+ g_free (item->FDisplayName);
+ g_free (item->sLinkTo);
+ g_free (item);
}
}
-int compare_two_same_files(const char *Path1, const char *Path2)
+/* -------------------------------------------------------------------------------------- */
+
+struct TVFSItem *
+create_placeholder_item (const char *name, enum TVFSItemType item_type)
+{
+ struct TVFSItem *data;
+
+ data = g_malloc0 (sizeof (struct TVFSItem));
+ data->FName = g_strdup (name);
+ data->FDisplayName = g_strdup (name);
+ data->ItemType = item_type;
+ data->iMode = S_IRWXO + S_IRWXG + S_IRWXU;
+ data->IsLink = FALSE;
+ data->iUID = geteuid ();
+ data->iGID = getegid ();
+ data->m_time = time (NULL);
+ data->c_time = data->m_time;
+ data->a_time = data->m_time;
+ data->iSize = 0;
+ data->iPackedSize = -1;
+
+ return data;
+}
+
+
+/* -------------------------------------------------------------------------------------- */
+
+gboolean
+compare_two_same_files (const char *path1, const char *path2)
{
- char *f1 = exclude_trailing_path_sep(Path1);
- char *f2 = exclude_trailing_path_sep(Path2);
- gboolean b = strcmp(f1, f2) == 0;
- free(f1);
- free(f2);
+ char *f1, *f2;
+ gboolean b;
+
+ f1 = exclude_trailing_path_sep (path1);
+ f2 = exclude_trailing_path_sep (path2);
+ b = (g_strcmp0 (f1, f2) == 0);
+ g_free (f1);
+ g_free (f2);
+
return b;
}
diff --git a/common/vfsutils.h b/common/vfsutils.h
index 5dd61f2..404b313 100644
--- a/common/vfsutils.h
+++ b/common/vfsutils.h
@@ -1,5 +1,5 @@
-/* Tux Commander VFS: String utilities
- * Copyright (C) 2007 Tomas Bzatek <tbzatek@users.sourceforge.net>
+/* Tux Commander VFS: VFS utilities
+ * Copyright (C) 2007-2009 Tomas Bzatek <tbzatek@users.sourceforge.net>
* Check for updates on tuxcmd.sourceforge.net
*
* This program is free software; you can redistribute it and/or modify
@@ -20,20 +20,28 @@
#ifndef __VFSUTILS_H__
#define __VFSUTILS_H__
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
-#include <stdio.h>
-#include <string.h>
#include <glib.h>
-#include "vfs_types.h"
+#include "tuxcmd-vfs.h"
+
+void copy_vfs_item (struct TVFSItem *src, struct TVFSItem *dst);
+void free_vfs_item (struct TVFSItem *item);
-void copy_vfs_item(struct TVFSItem *src, struct TVFSItem *dst);
-void free_vfs_item(struct TVFSItem *item);
+/* creates a placeholder item */
+struct TVFSItem * create_placeholder_item (const char *name, enum TVFSItemType item_type);
-int compare_two_same_files(const char *Path1, const char *Path2);
+gboolean compare_two_same_files (const char *path1, const char *path2);
+#ifdef __cplusplus
+ }
+#endif
#endif /* __VFSUTILS_H__ */
diff --git a/gvfs/Makefile b/gvfs/Makefile
index 0e1985c..5e7f996 100644
--- a/gvfs/Makefile
+++ b/gvfs/Makefile
@@ -1,21 +1,20 @@
# path definitions
DESTDIR = /usr
-INSTALL=install -c
+INSTALL = install -c
INSTALL_DATA = ${INSTALL} -m 644
# compiler options
CC = gcc
-CFLAGS =-I. -I/usr/include \
- -Wall -fPIC -O2 -g \
- -DG_DISABLE_DEPRECATED -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE
+CFLAGS = -I. -I/usr/include \
+ -Wall -fPIC -O2 -g \
+ -DG_DISABLE_DEPRECATED -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE
-LIB_SUFFIX=`if test \`uname -m\` = x86_64 -o \`uname -m\` = ppc64; then echo 64; fi`
+LIB_SUFFIX = `if test \`uname -m\` = x86_64 -o \`uname -m\` = ppc64; then echo 64; fi`
-# VFS_COMMON_OBJECTS=strutils.o treepathutils.o treepath_vfs.o vfsutils.o
-VFS_COMMON_OBJECTS=
+VFS_COMMON_OBJECTS =
-VFS_OBJECTS=gvfs.o
+VFS_OBJECTS = gvfs.o
.SUFFIXES: .c
@@ -28,11 +27,6 @@ all shared static: libgvfs_plugin.so
libgvfs_plugin.so: $(VFS_COMMON_OBJECTS) $(VFS_OBJECTS)
$(CC) -shared -o libgvfs_plugin.so $(VFS_COMMON_OBJECTS) $(VFS_OBJECTS) $(CFLAGS) `pkg-config glib-2.0 gio-2.0 --libs`
-strutils.o: strutils.c strutils.h
-treepathutils.o: treepathutils.c treepathutils.h
-vfsutils.o: vfsutils.c vfsutils.h
-treepath_vfs.o: treepath_vfs.c treepath_vfs.h
-
install::
$(INSTALL) ./libgvfs_plugin.so $(DESTDIR)/lib$(LIB_SUFFIX)/tuxcmd/
diff --git a/gvfs/gvfs.c b/gvfs/gvfs.c
index 7b15b5e..d72b417 100644
--- a/gvfs/gvfs.c
+++ b/gvfs/gvfs.c
@@ -1,5 +1,5 @@
/* GVFS plugin for Tux Commander
- * Copyright (C) 2008 Tomas Bzatek <tbzatek@users.sourceforge.net>
+ * Copyright (C) 2008-2009 Tomas Bzatek <tbzatek@users.sourceforge.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -19,35 +19,36 @@
#include <stdio.h>
#include <string.h>
-#include <stdlib.h>
-#include <stdint.h>
#include <sys/stat.h>
-#include <errno.h>
+#include <glib.h>
#include <gio/gio.h>
-#include <glib/gtypes.h>
-#include "vfs_types.h"
+#include "tuxcmd-vfs.h"
-#define VERSION "0.1.10"
-#define BUILD_DATE "2009-10-25"
+#define VERSION "0.2.0"
+#define BUILD_DATE "2009-11-21"
#define DEFAULT_BLOCK_SIZE 0x10000 /* 64kB */
-#define CONST_DEFAULT_QUERY_INFO_ATTRIBUTES G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_NAME "," \
- G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME "," G_FILE_ATTRIBUTE_STANDARD_SIZE "," \
- G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET "," G_FILE_ATTRIBUTE_TIME_MODIFIED "," \
- G_FILE_ATTRIBUTE_TIME_ACCESS "," G_FILE_ATTRIBUTE_TIME_CHANGED "," \
+#define CONST_DEFAULT_QUERY_INFO_ATTRIBUTES G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK "," \
+ G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME "," \
+ G_FILE_ATTRIBUTE_STANDARD_SIZE "," G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET "," \
+ G_FILE_ATTRIBUTE_TIME_MODIFIED "," G_FILE_ATTRIBUTE_TIME_ACCESS "," G_FILE_ATTRIBUTE_TIME_CHANGED "," \
G_FILE_ATTRIBUTE_UNIX_MODE "," G_FILE_ATTRIBUTE_UNIX_UID "," \
G_FILE_ATTRIBUTE_UNIX_GID
struct TVFSGlobs {
TVFSLogFunc log_func;
GFile *file;
- GFileEnumerator *enumerator;
GCancellable *cancellable;
+ GFileEnumerator *enumerator;
+ GFile *enumerated_file;
+ gboolean enum_follow_symlinks;
+ gboolean enum_add_full_path;
+
GMainLoop *mount_main_loop;
TVFSResult mount_result;
int mount_try;
@@ -120,10 +121,10 @@ g_error_to_TVFSResult (GError *error)
}
static void
-ask_password_cb (GMountOperation *op,
- const char *message,
- const char *default_user,
- const char *default_domain,
+ask_password_cb (GMountOperation *op,
+ const char *message,
+ const char *default_user,
+ const char *default_domain,
GAskPasswordFlags flags,
gpointer user_data)
{
@@ -236,9 +237,9 @@ ask_question_cb (GMountOperation *op,
}
static void
-mount_done_cb (GObject *object,
+mount_done_cb (GObject *object,
GAsyncResult *res,
- gpointer user_data)
+ gpointer user_data)
{
struct TVFSGlobs *globs;
gboolean succeeded;
@@ -300,6 +301,7 @@ VFSNew (TVFSLogFunc log_func)
globs->file = NULL;
globs->enumerator = NULL;
+ globs->enumerated_file = NULL;
globs->cancellable = NULL;
globs->break_get_dir_size = FALSE;
@@ -314,11 +316,11 @@ VFSNew (TVFSLogFunc log_func)
}
void
-VFSSetCallbacks (struct TVFSGlobs *globs,
- TVFSAskQuestionCallback ask_question_callback,
- TVFSAskPasswordCallback ask_password_callback,
- TVFSProgressCallback progress_func,
- void *data)
+VFSSetCallbacks (struct TVFSGlobs *globs,
+ TVFSAskQuestionCallback ask_question_callback,
+ TVFSAskPasswordCallback ask_password_callback,
+ TVFSProgressCallback progress_func,
+ void *data)
{
globs->callback_ask_question = ask_question_callback;
globs->callback_ask_password = ask_password_callback;
@@ -330,7 +332,7 @@ void
VFSFree (struct TVFSGlobs *globs)
{
globs->log_func ("GVFS plugin: VFSDestroy");
- free (globs);
+ g_free (globs);
}
int
@@ -387,7 +389,7 @@ VFSGetNetworkServices ()
}
TVFSResult
-VFSOpenURI (struct TVFSGlobs *globs, char *sURI)
+VFSOpenURI (struct TVFSGlobs *globs, const char *sURI)
{
GFile *f, *f2;
GFileInfo *info;
@@ -458,17 +460,17 @@ VFSClose (struct TVFSGlobs *globs)
return cVFS_OK;
}
-char *
-VFSGetPath (struct TVFSGlobs *globs)
+static char *
+get_absolute_path (GFile *file)
{
GFile *root;
char *path, *s;
- if (globs->file) {
- root = g_file_resolve_relative_path (globs->file, "/");
+ if (file) {
+ root = g_file_resolve_relative_path (file, "/");
if (root == NULL)
return NULL;
- path = g_file_get_relative_path (root, globs->file);
+ path = g_file_get_relative_path (root, file);
if (path == NULL) {
g_object_unref (root);
return NULL;
@@ -477,7 +479,6 @@ VFSGetPath (struct TVFSGlobs *globs)
s = g_strdup_printf ("/%s", path);
else
s = g_strdup (path);
- g_print ("(II) VFSGetPath: '%s'\n", s);
g_free (path);
g_object_unref (root);
return s;
@@ -487,6 +488,17 @@ VFSGetPath (struct TVFSGlobs *globs)
}
char *
+VFSGetPath (struct TVFSGlobs *globs)
+{
+ char *s;
+
+ s = get_absolute_path (globs->file);
+ g_print ("(II) VFSGetPath: '%s'\n", s);
+
+ return s;
+}
+
+char *
VFSGetPathURI (struct TVFSGlobs *globs)
{
if (globs->file)
@@ -495,56 +507,47 @@ VFSGetPathURI (struct TVFSGlobs *globs)
return NULL;
}
-guint64
-VFSGetFileSystemFree (struct TVFSGlobs *globs, char *APath)
+TVFSResult
+VFSGetFileSystemInfo (struct TVFSGlobs *globs, const char *APath, gint64 *FSSize, gint64 *FSFree, char **FSLabel)
{
GFileInfo *info;
GError *error;
- guint64 res;
-
- if (globs->file == NULL)
- return 0;
+ TVFSResult res;
- error = NULL;
- info = g_file_query_filesystem_info (globs->file, G_FILE_ATTRIBUTE_FILESYSTEM_FREE, NULL, &error);
- if (error) {
- g_print ("(EE) VFSGetFileSystemFree: %s\n", error->message);
- g_error_free (error);
- return 0;
- }
- res = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE);
- g_object_unref (info);
- return res;
-}
-
-guint64
-VFSGetFileSystemSize (struct TVFSGlobs *globs, char *APath)
-{
- GFileInfo *info;
- GError *error;
- guint64 res;
+ if (FSSize)
+ *FSSize = -1;
+ if (FSFree)
+ *FSFree = -1;
+ if (FSLabel)
+ *FSLabel = NULL;
if (globs->file == NULL)
- return 0;
+ return cVFS_Failed;
error = NULL;
- info = g_file_query_filesystem_info (globs->file, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE, NULL, &error);
+ info = g_file_query_filesystem_info (globs->file, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE "," G_FILE_ATTRIBUTE_FILESYSTEM_FREE, NULL, &error);
if (error) {
- g_print ("(EE) VFSGetFileSystemSize: %s\n", error->message);
+ g_print ("(EE) VFSGetFileSystemInfo: %s\n", error->message);
g_error_free (error);
- return 0;
+ res = cVFS_Failed;
}
- res = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE);
- g_object_unref (info);
+ else {
+ if (FSSize)
+ *FSSize = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE);
+ if (FSFree)
+ *FSFree = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE);
+ res = cVFS_OK;
+ }
+ if (info)
+ g_object_unref (info);
return res;
}
-
/**************************************************************************************************************************************/
/**************************************************************************************************************************************/
TVFSResult
-VFSChangeDir (struct TVFSGlobs *globs, char *NewPath)
+VFSChangeDir (struct TVFSGlobs *globs, const char *NewPath)
{
GFile *f;
GFileEnumerator *en;
@@ -616,6 +619,7 @@ VFSChangeDir (struct TVFSGlobs *globs, char *NewPath)
}
globs->enumerator = en;
+ globs->enumerated_file = g_file_dup (f);
g_object_unref (globs->file);
globs->file = f;
@@ -627,17 +631,24 @@ VFSChangeDir (struct TVFSGlobs *globs, char *NewPath)
/**************************************************************************************************************************************/
static void
-g_file_info_to_TVFSItem (GFileInfo *info, struct TVFSItem *Item)
+g_file_info_to_TVFSItem (GFileInfo *info, struct TVFSItem *Item, GFile *reference_file, gboolean follow_symlinks, gboolean add_full_path)
{
+ GFileInfo *symlink_info = NULL;
+ GError *error;
+
g_assert (info != NULL);
g_assert (Item != NULL);
- Item->FName = g_strdup (g_file_info_get_name (info));
- Item->FDisplayName = g_strdup (g_file_info_get_display_name (info));
- Item->sLinkTo = g_file_info_get_symlink_target (info) == NULL ? NULL : g_strdup (g_file_info_get_symlink_target (info));
- Item->iSize = g_file_info_get_size (info);
- Item->iPackedSize = -1;
- Item->iMode = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE);
+ if (add_full_path) {
+ Item->FName = get_absolute_path (reference_file);
+ if (Item->FName == NULL)
+ Item->FName = g_strdup (g_file_info_get_name (info));
+ Item->FDisplayName = g_filename_display_name (Item->FName);
+ } else {
+ Item->FName = g_strdup (g_file_info_get_name (info));
+ Item->FDisplayName = g_strdup (g_file_info_get_display_name (info));
+ }
+ Item->sLinkTo = g_strdup (g_file_info_get_symlink_target (info));
Item->m_time = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
Item->a_time = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_ACCESS);
@@ -648,31 +659,38 @@ g_file_info_to_TVFSItem (GFileInfo *info, struct TVFSItem *Item)
// g_print ("(II) g_file_info_to_TVFSItem: type = %d\n", g_file_info_get_file_type (info));
// g_print ("(II) g_file_info_to_TVFSItem: UNIX_MODE = %d\n", Item->iMode);
- if (g_file_info_get_is_symlink (info)) {
- Item->ItemType = vSymlink;
- }
- else
- {
- switch (g_file_info_get_file_type (info)) {
- case G_FILE_TYPE_REGULAR:
- Item->ItemType = vRegular;
- break;
- case G_FILE_TYPE_DIRECTORY:
- case G_FILE_TYPE_SHORTCUT: /* Used in network:/// */
- case G_FILE_TYPE_MOUNTABLE:
- Item->ItemType = vDirectory;
- break;
- case G_FILE_TYPE_SYMBOLIC_LINK:
- Item->ItemType = vSymlink;
- break;
- case G_FILE_TYPE_SPECIAL: /* socket, fifo, blockdev, chardev */
- Item->ItemType = vBlockdev;
- break;
- case G_FILE_TYPE_UNKNOWN:
- default: Item->ItemType = vRegular;
+ Item->IsLink = g_file_info_get_is_symlink (info);
+ if (Item->IsLink && follow_symlinks) {
+ error = NULL;
+ symlink_info = g_file_query_info (reference_file, CONST_DEFAULT_QUERY_INFO_ATTRIBUTES,
+ G_FILE_QUERY_INFO_NONE, NULL, &error);
+
+ if (error) {
+ g_print ("(EE) g_file_info_to_TVFSItem: g_file_query_info() error: %s\n", error->message);
+ g_error_free (error);
}
}
+ Item->iSize = g_file_info_get_size (symlink_info ? symlink_info : info);
+ Item->iPackedSize = -1;
+ Item->iMode = g_file_info_get_attribute_uint32 (symlink_info ? symlink_info : info, G_FILE_ATTRIBUTE_UNIX_MODE);
+
+ switch (g_file_info_get_file_type (symlink_info ? symlink_info : info)) {
+ case G_FILE_TYPE_REGULAR:
+ Item->ItemType = vRegular;
+ break;
+ case G_FILE_TYPE_DIRECTORY:
+ case G_FILE_TYPE_SHORTCUT: /* Used in network:/// */
+ case G_FILE_TYPE_MOUNTABLE:
+ Item->ItemType = vDirectory;
+ break;
+ case G_FILE_TYPE_SPECIAL: /* socket, fifo, blockdev, chardev */
+ Item->ItemType = vBlockdev;
+ break;
+ case G_FILE_TYPE_UNKNOWN:
+ default: Item->ItemType = vRegular;
+ }
+
/* fallback to default file mode if read fails */
if (Item->iMode == 0) {
if (Item->ItemType == vDirectory)
@@ -680,14 +698,18 @@ g_file_info_to_TVFSItem (GFileInfo *info, struct TVFSItem *Item)
else
Item->iMode = S_IRUSR + S_IWUSR + S_IRGRP + S_IROTH;
}
+
+ if (symlink_info)
+ g_object_unref (symlink_info);
}
TVFSResult
-VFSListNext (struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item)
+VFSListNext (struct TVFSGlobs *globs, struct TVFSItem *Item)
{
GError *error;
GFileInfo *info;
TVFSResult res;
+ GFile *f;
if (globs->file == NULL) {
g_print ("(EE) VFSListNext: globs->file == NULL !\n");
@@ -708,15 +730,54 @@ VFSListNext (struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item)
}
if (! error && ! info)
return cVFS_No_More_Files;
- g_file_info_to_TVFSItem (info, Item);
+
+ f = g_file_get_child (globs->enumerated_file, g_file_info_get_name (info));
+ g_file_info_to_TVFSItem (info, Item, f, globs->enum_follow_symlinks, globs->enum_add_full_path);
+ g_object_unref (f);
+
g_object_unref (info);
return cVFS_OK;
}
TVFSResult
-VFSListFirst (struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item)
+VFSListFirst (struct TVFSGlobs *globs, const char *sDir, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath)
{
- return VFSListNext (globs, sDir, Item);
+ GFile *list_file;
+ GError *error;
+ TVFSResult res;
+
+ list_file = g_file_resolve_relative_path (globs->file, sDir);
+ if (! list_file) {
+ g_print ("(EE) VFSListFirst: list_file == NULL !\n");
+ return cVFS_Failed;
+ }
+
+ if (globs->enumerator == NULL || ! g_file_equal (globs->file, list_file)) {
+ g_print ("(WW) VFSListFirst: resetting enumerator\n");
+ if (globs->enumerator) {
+ g_file_enumerator_close (globs->enumerator, NULL, NULL);
+ g_object_unref (globs->enumerator);
+ }
+ if (globs->enumerated_file)
+ g_object_unref (globs->enumerated_file);
+ globs->enumerated_file = NULL;
+ error = NULL;
+ globs->enumerator = g_file_enumerate_children (list_file, CONST_DEFAULT_QUERY_INFO_ATTRIBUTES,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error);
+ if (error) {
+ g_print ("(EE) VFSListFirst: g_file_enumerate_children() error: %s\n", error->message);
+ res = g_error_to_TVFSResult (error);
+ g_error_free (error);
+ g_object_unref (list_file);
+ return res;
+ }
+ globs->enumerated_file = g_object_ref (list_file);
+ }
+ globs->enum_follow_symlinks = FollowSymlinks;
+ globs->enum_add_full_path = AddFullPath;
+
+ g_object_unref (list_file);
+ return VFSListNext (globs, Item);
}
TVFSResult
@@ -725,10 +786,6 @@ VFSListClose (struct TVFSGlobs *globs)
GError *error;
TVFSResult res;
- if (globs->file == NULL) {
- g_print ("(EE) VFSListClose: globs->file == NULL !\n");
- return cVFS_Failed;
- }
if (globs->enumerator == NULL) {
g_print ("(EE) VFSListClose: globs->enumerator == NULL !\n");
return cVFS_Failed;
@@ -739,6 +796,8 @@ VFSListClose (struct TVFSGlobs *globs)
g_file_enumerator_close (globs->enumerator, NULL, &error);
g_object_unref (globs->enumerator);
globs->enumerator = NULL;
+ g_object_unref (globs->enumerated_file);
+ globs->enumerated_file = NULL;
if (error) {
g_print ("(EE) VFSListClose: g_file_enumerator_close() error: %s\n", error->message);
res = g_error_to_TVFSResult (error);
@@ -751,39 +810,8 @@ VFSListClose (struct TVFSGlobs *globs)
/**************************************************************************************************************************************/
/**************************************************************************************************************************************/
-long
-VFSFileExists (struct TVFSGlobs *globs, const char *FileName, const long Use_lstat)
-{
- GFile *f;
- GError *error;
- GFileInfo *info;
-
- if (globs->file == NULL) {
- g_print ("(EE) VFSFileExists: globs->file == NULL !\n");
- return cVFS_Failed;
- }
-
- f = g_file_resolve_relative_path (globs->file, FileName);
- if (f == NULL) {
- g_print ("(EE) VFSMkDir: g_file_resolve_relative_path() failed.\n");
- return cVFS_Failed;
- }
-
- error = NULL;
- info = g_file_query_info (f, G_FILE_ATTRIBUTE_STANDARD_NAME,
- Use_lstat ? G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS : G_FILE_QUERY_INFO_NONE, NULL, &error);
- g_object_unref (f);
- if (error) {
-// g_print ("(EE) VFSFileExists: g_file_query_info() error: %s\n", error->message);
- g_error_free (error);
- return FALSE;
- }
- g_object_unref (info);
- return TRUE;
-}
-
TVFSResult
-VFSFileInfo (struct TVFSGlobs *globs, char *AFileName, struct TVFSItem *Item)
+VFSFileInfo (struct TVFSGlobs *globs, const char *AFileName, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath)
{
GFile *f;
GError *error;
@@ -804,15 +832,16 @@ VFSFileInfo (struct TVFSGlobs *globs, char *AFileName, struct TVFSItem *Item)
error = NULL;
info = g_file_query_info (f, CONST_DEFAULT_QUERY_INFO_ATTRIBUTES,
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error);
- g_object_unref (f);
if (error) {
g_print ("(EE) VFSFileInfo: g_file_query_info() error: %s\n", error->message);
res = g_error_to_TVFSResult (error);
g_error_free (error);
+ g_object_unref (f);
return res;
}
- g_file_info_to_TVFSItem (info, Item);
+ g_file_info_to_TVFSItem (info, Item, f, FollowSymlinks, AddFullPath);
g_object_unref (info);
+ g_object_unref (f);
return cVFS_OK;
}
@@ -956,7 +985,7 @@ VFSMakeSymLink (struct TVFSGlobs *globs, const char *NewFileName, const char *Po
}
TVFSResult
-VFSChmod (struct TVFSGlobs *globs, const char *FileName, const uint Mode)
+VFSChmod (struct TVFSGlobs *globs, const char *FileName, guint32 Mode)
{
GFile *f;
GError *error;
@@ -987,7 +1016,7 @@ VFSChmod (struct TVFSGlobs *globs, const char *FileName, const uint Mode)
}
TVFSResult
-VFSChown (struct TVFSGlobs *globs, const char *FileName, const uint UID, const uint GID)
+VFSChown (struct TVFSGlobs *globs, const char *FileName, guint32 UID, guint32 GID)
{
GFile *f;
GError *error;
@@ -1027,7 +1056,7 @@ VFSChown (struct TVFSGlobs *globs, const char *FileName, const uint UID, const u
}
TVFSResult
-VFSChangeTimes (struct TVFSGlobs *globs, char *APath, long mtime, long atime)
+VFSChangeTimes (struct TVFSGlobs *globs, const char *APath, guint32 mtime, guint32 atime)
{
GFile *f;
GError *error;
@@ -1119,12 +1148,13 @@ VFSGetDirSize_recurse (struct TVFSGlobs *globs, GFile *file, guint64 *size)
}
guint64
-VFSGetDirSize (struct TVFSGlobs *globs, char *APath)
+VFSGetDirSize (struct TVFSGlobs *globs, const char *APath)
{
GFile *f;
guint64 size;
- if (globs == NULL) return 0;
+ if (globs == NULL)
+ return 0;
if (globs->file == NULL) {
g_print ("(EE) VFSGetDirSize: globs->file == NULL !\n");
return 0;
@@ -1192,14 +1222,14 @@ VFSWriteFile (struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, gpointer Buff
}
void
-VFSSetBlockSize (struct TVFSGlobs *globs, int Value)
+VFSSetBlockSize (struct TVFSGlobs *globs, guint32 Value)
{
if (globs)
globs->block_size = Value;
}
gboolean
-VFSIsOnSameFS (struct TVFSGlobs *globs, const char *Path1, const char *Path2)
+VFSIsOnSameFS (struct TVFSGlobs *globs, const char *Path1, const char *Path2, gboolean FollowSymlinks)
{
GFile *file1, *file2;
GFileInfo *info1, *info2;
@@ -1224,7 +1254,8 @@ VFSIsOnSameFS (struct TVFSGlobs *globs, const char *Path1, const char *Path2)
error = NULL;
info1 = g_file_query_info (file1, G_FILE_ATTRIBUTE_ID_FILESYSTEM,
- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error);
+ FollowSymlinks ? G_FILE_QUERY_INFO_NONE : G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ NULL, &error);
if (error) {
g_print ("(EE) VFSIsOnSameFS: g_file_query_info() error: %s\n", error->message);
g_error_free (error);
@@ -1233,7 +1264,8 @@ VFSIsOnSameFS (struct TVFSGlobs *globs, const char *Path1, const char *Path2)
return FALSE;
}
info2 = g_file_query_info (file2, G_FILE_ATTRIBUTE_ID_FILESYSTEM,
- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error);
+ FollowSymlinks ? G_FILE_QUERY_INFO_NONE : G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ NULL, &error);
if (error) {
g_print ("(EE) VFSIsOnSameFS: g_file_query_info() error: %s\n", error->message);
g_error_free (error);
@@ -1256,7 +1288,7 @@ VFSIsOnSameFS (struct TVFSGlobs *globs, const char *Path1, const char *Path2)
}
gboolean
-VFSTwoSameFiles (struct TVFSGlobs *globs, const char *Path1, const char *Path2)
+VFSTwoSameFiles (struct TVFSGlobs *globs, const char *Path1, const char *Path2, gboolean FollowSymlinks)
{
GFile *file1, *file2;
gboolean res;
@@ -1274,10 +1306,11 @@ VFSTwoSameFiles (struct TVFSGlobs *globs, const char *Path1, const char *Path2)
}
if (file2 == NULL) {
g_print ("(EE) VFSTwoSameFiles: g_file_resolve_relative_path() failed.\n");
+ g_object_unref (file1);
return FALSE;
}
- /* FIXME: we should do some I/O test, we're esentially comparing strings at the moment */
+ /* FIXME: we should do some I/O test here, we're esentially comparing strings at the moment */
res = g_file_equal (file1, file2);
g_object_unref (file1);
g_object_unref (file2);
@@ -1307,7 +1340,7 @@ vfs_copy_progress_callback (goffset current_num_bytes,
}
}
-#define TUXCMD_DEFAULT_COPY_FLAGS G_FILE_COPY_OVERWRITE | G_FILE_COPY_NOFOLLOW_SYMLINKS | G_FILE_COPY_ALL_METADATA
+#define TUXCMD_DEFAULT_COPY_FLAGS G_FILE_COPY_OVERWRITE | G_FILE_COPY_NOFOLLOW_SYMLINKS | G_FILE_COPY_ALL_METADATA
TVFSResult
VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append)
diff --git a/gvfs/tuxcmd-vfs.h b/gvfs/tuxcmd-vfs.h
new file mode 120000
index 0000000..b7f193e
--- /dev/null
+++ b/gvfs/tuxcmd-vfs.h
@@ -0,0 +1 @@
+../common/tuxcmd-vfs.h \ No newline at end of file
diff --git a/gvfs/vfs_types.h b/gvfs/vfs_types.h
deleted file mode 120000
index c2235a2..0000000
--- a/gvfs/vfs_types.h
+++ /dev/null
@@ -1 +0,0 @@
-../common/vfs_types.h \ No newline at end of file
diff --git a/libarchive/Makefile b/libarchive/Makefile
index 595cd5f..26b4502 100644
--- a/libarchive/Makefile
+++ b/libarchive/Makefile
@@ -1,30 +1,26 @@
# path definitions
DESTDIR = /usr
-INSTALL=install -c
+INSTALL = install -c
INSTALL_DATA = ${INSTALL} -m 644
-DIR_COMMON=../common/
-DIR_LIBARCHIVE=./libarchive-2.7.1
+DIR_LIBARCHIVE = ./libarchive-2.7.1
# compiler options
CC = gcc
-CPP = g++
-CFLAGS =-I. -I/usr/include -I$(DIR_COMMON) \
- -Wall -fPIC -O2 -g \
- -DG_DISABLE_DEPRECATED -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE \
- -D__VERBOSE_DEBUGx
+CFLAGS = -I. -I/usr/include \
+ -Wall -fPIC -O2 -g \
+ -DG_DISABLE_DEPRECATED -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE \
+ -D__VERBOSE_DEBUGx
-LIB_SUFFIX=`if test \`uname -m\` = x86_64 -o \`uname -m\` = ppc64; then echo 64; fi`
+LIB_SUFFIX = `if test \`uname -m\` = x86_64 -o \`uname -m\` = ppc64; then echo 64; fi`
-VFS_COMMON_OBJECTS=strutils.o treepathutils.o treepath_vfs.o vfsutils.o
+VFS_COMMON_OBJECTS = filelist.o filelist-vfs-intf.o strutils.o vfsutils.o
+
+VFS_OBJECTS = libarchive.o
-VFS_OBJECTS=libarchive.o
-
-.SUFFIXES: .c .cpp
+.SUFFIXES: .c
.c.o:
$(CC) $(CFLAGS) `pkg-config glib-2.0 --cflags` -c $<
-.cpp.o:
- $(CPP) $(CFLAGS) `pkg-config glib-2.0 --cflags` -c $<
all: static
@@ -48,10 +44,10 @@ lib_libarchive_compile:
fi;
-strutils.o: strutils.c strutils.h
-treepathutils.o: treepathutils.c treepathutils.h
-vfsutils.o: vfsutils.c vfsutils.h
-treepath_vfs.o: treepath_vfs.c treepath_vfs.h
+filelist.o: filelist.h filelist.c
+filelist-vfs-intf.o: filelist-vfs-intf.h filelist-vfs-intf.c
+strutils.o: strutils.h strutils.c
+vfsutils.o: vfsutils.h vfsutils.c
install::
$(INSTALL) ./libarchive_plugin.so $(DESTDIR)/lib$(LIB_SUFFIX)/tuxcmd/
diff --git a/libarchive/filelist-vfs-intf.c b/libarchive/filelist-vfs-intf.c
new file mode 120000
index 0000000..68d7a7c
--- /dev/null
+++ b/libarchive/filelist-vfs-intf.c
@@ -0,0 +1 @@
+../common/filelist-vfs-intf.c \ No newline at end of file
diff --git a/libarchive/filelist-vfs-intf.h b/libarchive/filelist-vfs-intf.h
new file mode 120000
index 0000000..f7afe49
--- /dev/null
+++ b/libarchive/filelist-vfs-intf.h
@@ -0,0 +1 @@
+../common/filelist-vfs-intf.h \ No newline at end of file
diff --git a/libarchive/filelist.c b/libarchive/filelist.c
new file mode 120000
index 0000000..9504563
--- /dev/null
+++ b/libarchive/filelist.c
@@ -0,0 +1 @@
+../common/filelist.c \ No newline at end of file
diff --git a/libarchive/filelist.h b/libarchive/filelist.h
new file mode 120000
index 0000000..90a52e1
--- /dev/null
+++ b/libarchive/filelist.h
@@ -0,0 +1 @@
+../common/filelist.h \ No newline at end of file
diff --git a/libarchive/libarchive.c b/libarchive/libarchive.c
index e9ecfc0..13039f2 100644
--- a/libarchive/libarchive.c
+++ b/libarchive/libarchive.c
@@ -1,5 +1,5 @@
/* libarchive plugin for Tux Commander
- * version 0.1.7, designed for libarchive v2.5.5 - v2.7.1 (recommended)
+ * version 0.2.0, designed for libarchive v2.5.5 - v2.7.1 (recommended)
* Copyright (C) 2008-2009 Tomas Bzatek <tbzatek@users.sourceforge.net>
* Check for updates on tuxcmd.sourceforge.net
*
@@ -27,21 +27,15 @@
#include <string.h>
#include <stdlib.h>
-#include <stdint.h>
-#include <sys/stat.h>
-#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
-#include <dirent.h>
-#include <fnmatch.h>
-#include <unistd.h>
#include <glib.h>
-#include "vfs_types.h"
+#include "tuxcmd-vfs.h"
#include "vfsutils.h"
#include "strutils.h"
-#include "treepathutils.h"
-#include "treepath_vfs.h"
+#include "filelist.h"
+#include "filelist-vfs-intf.h"
#include <archive.h>
#include <archive_entry.h>
@@ -58,8 +52,8 @@
#endif
-#define MODULE_VERSION "0.1.7"
-#define MODULE_BUILD_DATE "2009-11-17"
+#define MODULE_VERSION "0.2.0"
+#define MODULE_BUILD_DATE "2009-11-26"
#define DEFAULT_BLOCK_SIZE 65536
@@ -70,20 +64,18 @@
/** Auxiliary classes */
/************** ****************/
-
-
-// Declaration of the global plugin object
+/* declaration of the global plugin object */
struct TVFSGlobs {
TVFSLogFunc log_func;
char *curr_dir;
char *archive_path;
- unsigned long block_size;
+ guint32 block_size;
struct PathTree *files;
struct VfsFilelistData *vfs_filelist;
- u_int64_t total_size;
+ guint64 total_size;
TVFSAskQuestionCallback callback_ask_question;
TVFSAskPasswordCallback callback_ask_password;
@@ -94,18 +86,16 @@ struct TVFSGlobs {
+/******************************************************************************************************/
+/** Basic initialization functions */
+/************** ****************/
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-////////////////////////
-// Basic initialization functions
struct TVFSGlobs *
VFSNew (TVFSLogFunc log_func)
{
struct TVFSGlobs * globs;
- globs = (struct TVFSGlobs *) malloc (sizeof (struct TVFSGlobs));
- memset (globs, 0, sizeof (struct TVFSGlobs));
+ globs = g_malloc0 (sizeof (struct TVFSGlobs));
globs->block_size = DEFAULT_BLOCK_SIZE;
@@ -115,17 +105,28 @@ VFSNew (TVFSLogFunc log_func)
globs->callback_progress = NULL;
globs->log_func = log_func;
- if (globs->log_func != NULL) globs->log_func("libarchive plugin: VFSInit");
+ if (globs->log_func != NULL)
+ globs->log_func ("libarchive plugin: VFSInit");
return globs;
}
+
void
-VFSSetCallbacks (struct TVFSGlobs *globs,
- TVFSAskQuestionCallback ask_question_callback,
- TVFSAskPasswordCallback ask_password_callback,
- TVFSProgressCallback progress_func,
- void *data)
+VFSFree (struct TVFSGlobs *globs)
+{
+ if (globs->log_func != NULL)
+ globs->log_func ("libarchive plugin: VFSDestroy");
+ g_free (globs);
+}
+
+
+void
+VFSSetCallbacks (struct TVFSGlobs *globs,
+ TVFSAskQuestionCallback ask_question_callback,
+ TVFSAskPasswordCallback ask_password_callback,
+ TVFSProgressCallback progress_func,
+ void *data)
{
globs->callback_ask_question = ask_question_callback;
globs->callback_ask_password = ask_password_callback;
@@ -133,18 +134,13 @@ VFSSetCallbacks (struct TVFSGlobs *globs,
globs->callback_data = data;
}
-void
-VFSFree (struct TVFSGlobs *globs)
-{
- if (globs->log_func != NULL) globs->log_func("libarchive plugin: VFSDestroy");
- free (globs);
-}
int VFSVersion()
{
return cVFSVersion;
}
+
struct TVFSInfo *
VFSGetInfo()
{
@@ -164,15 +160,16 @@ VFSGetInfo()
return module_info;
}
+
char *
VFSGetArchiveExts ()
{
/* Make sure these end with a semicolon */
-#define BASIC_FORMATS "tar;cpio;iso;a;shar;"
-#define BZIP_FORMATS "tar.bz2;tbz2;"
-#define ZLIB_FORMATS "tar.gz;tgz;tar.z;deb;"
-#define XZ_FORMATS "tar.lzma;tar.xz;"
-#define LZMA_FORMATS "tar.lzma;"
+#define BASIC_FORMATS "tar;cpio;iso;a;shar;"
+#define BZIP_FORMATS "tar.bz2;tbz2;"
+#define ZLIB_FORMATS "tar.gz;tgz;tar.z;deb;"
+#define XZ_FORMATS "tar.lzma;tar.xz;"
+#define LZMA_FORMATS "tar.lzma;"
char *formats;
@@ -248,172 +245,207 @@ char *formats;
/**************************************************************************************************************************************/
/**************************************************************************************************************************************/
-static TVFSResult libarchive_open(struct archive **a, const char *filename, size_t block_size)
+static TVFSResult
+libarchive_open (struct archive **a, const char *filename, guint32 block_size)
{
int r;
- *a = archive_read_new();
+ *a = archive_read_new ();
- // Register supported formats
+ /* Register supported formats */
+ archive_read_support_compression_all (*a);
+ archive_read_support_format_all (*a);
- archive_read_support_compression_all(*a);
- archive_read_support_format_all(*a);
-
- r = archive_read_open_file(*a, filename, block_size);
+ r = archive_read_open_file (*a, filename, block_size);
if (r) {
- fprintf(stderr, "(EE) libarchive_open: error occured when opening archive: %s\n", archive_error_string(*a));
+ fprintf (stderr, "(EE) libarchive_open: error occured when opening archive: %s\n", archive_error_string (*a));
return cVFS_Failed;
}
return cVFS_OK;
}
-
-
-TVFSResult VFSOpenArchive(struct TVFSGlobs *globs, char *sName)
+TVFSResult
+VFSOpenArchive (struct TVFSGlobs *globs, const char *sName)
{
- globs->files = filelist_tree_new();
- globs->vfs_filelist = vfs_filelist_new(globs->files);
- globs->curr_dir = NULL;
- globs->archive_path = strdup(sName);
- globs->total_size = 0;
- fprintf(stderr, "(--) VFSOpenArchive: trying to open archive '%s'...\n", globs->archive_path);
-
TVFSResult Result;
struct archive *a;
struct archive_entry *entry;
+ struct TVFSItem *item;
int r;
+ char *s;
- Result = libarchive_open(&a, globs->archive_path, globs->block_size);
- if (Result == cVFS_OK)
- {
- for (;;) {
- entry = NULL;
- r = archive_read_next_header(a, &entry);
- if (r == ARCHIVE_EOF) {
- break;
- } else
- if (r == ARCHIVE_WARN) {
- log("(WW) VFSOpenArchive: file '%s' - libarchive warning: '%s'\n", archive_entry_pathname(entry), archive_error_string(a));
- } else
- if (r != ARCHIVE_OK) {
- fprintf(stderr, "(EE) VFSOpenArchive: error occured while reading archive: '%s'\n", archive_error_string(a));
- Result = cVFS_Failed;
- break;
- }
-
- log("found file: %s, mode = %x\n", archive_entry_pathname(entry), archive_entry_mode(entry));
-
- // Create a TVFSItem entry and fill all info
- struct TVFSItem *item = (struct TVFSItem*)malloc(sizeof(struct TVFSItem));
- memset(item, 0, sizeof(struct TVFSItem));
-
- item->iSize = (int64_t)archive_entry_size(entry);
- item->iPackedSize = -1; /* no support */
- globs->total_size += item->iSize;
-
- mode_t mode = archive_entry_mode(entry);
- item->iMode = archive_entry_mode(entry);
- if (S_ISREG(mode)) item->ItemType = vRegular;
- else if (S_ISDIR(mode)) item->ItemType = vDirectory;
- else if (S_ISCHR(mode)) item->ItemType = vChardev;
- else if (S_ISBLK(mode)) item->ItemType = vBlockdev;
- else if (S_ISFIFO(mode)) item->ItemType = vFifo;
- else if (S_ISLNK(mode)) item->ItemType = vSymlink;
- else if (S_ISSOCK(mode)) item->ItemType = vSock;
-
- if (item->ItemType == vSymlink)
- item->sLinkTo = strdup(archive_entry_symlink(entry));
-
- item->iUID = geteuid();
- item->iGID = getegid();
- item->m_time = archive_entry_mtime(entry);
- item->c_time = archive_entry_ctime(entry);
- item->a_time = archive_entry_atime(entry);
-
- char *s;
- if (g_utf8_validate (archive_entry_pathname(entry), -1, NULL))
- s = g_strdup (archive_entry_pathname(entry));
- else {
- if (archive_entry_pathname_w(entry))
- s = wide_to_utf8 (archive_entry_pathname_w(entry));
- else
- s = g_filename_display_name (archive_entry_pathname(entry));
- }
-// g_print("file = '%s', wide = '%ls'\n", archive_entry_pathname(entry), archive_entry_pathname_w(entry));
-
- // Add item to the global list and continue with next file
- filelist_tree_add_item(globs->files, s, archive_entry_pathname(entry), item, 0);
- g_free (s);
- }
- archive_read_close(a);
+ globs->files = filelist_tree_new ();
+ globs->vfs_filelist = vfs_filelist_new (globs->files);
+ globs->curr_dir = NULL;
+ globs->archive_path = g_strdup (sName);
+ globs->total_size = 0;
+ fprintf (stderr, "(--) VFSOpenArchive: trying to open archive '%s'...\n", globs->archive_path);
+
+ Result = libarchive_open (&a, globs->archive_path, globs->block_size);
+ if (Result == cVFS_OK) {
+ for (;;) {
+ entry = NULL;
+ r = archive_read_next_header (a, &entry);
+ if (r == ARCHIVE_EOF) {
+ break;
+ } else
+ if (r == ARCHIVE_WARN) {
+ log ("(WW) VFSOpenArchive: file '%s' - libarchive warning: '%s'\n", archive_entry_pathname (entry), archive_error_string (a));
+ } else
+ if (r != ARCHIVE_OK) {
+ fprintf (stderr, "(EE) VFSOpenArchive: error occured while reading archive: '%s'\n", archive_error_string (a));
+ Result = cVFS_Failed;
+ break;
+ }
+
+ log ("found file: %s, mode = %x\n", archive_entry_pathname (entry), archive_entry_mode (entry));
+
+ /* Create a TVFSItem entry and fill all info */
+ item = g_malloc0 (sizeof (struct TVFSItem));
+
+ item->iSize = (guint64) archive_entry_size (entry);
+ item->iPackedSize = -1; /* no support */
+ globs->total_size += item->iSize;
+
+ item->iMode = archive_entry_mode (entry);
+ item->ItemType = vRegular; /* fallback */
+ item->IsLink = FALSE;
+ switch (archive_entry_filetype (entry)) {
+ case AE_IFDIR:
+ item->ItemType = vDirectory;
+ break;
+ case AE_IFIFO:
+ item->ItemType = vFifo;
+ break;
+ case AE_IFCHR:
+ item->ItemType = vChardev;
+ break;
+ case AE_IFBLK:
+ item->ItemType = vBlockdev;
+ break;
+ case AE_IFSOCK:
+ item->ItemType = vSock;
+ break;
+ case AE_IFLNK:
+ item->IsLink = TRUE;
+ break;
+ case AE_IFMT:
+ item->ItemType = vOther;
+ break;
+ case AE_IFREG:
+ default:
+ item->ItemType = vRegular;
+ break;
+ }
+
+ if (item->IsLink)
+ item->sLinkTo = g_strdup (archive_entry_symlink (entry));
+
+/* item->iUID = geteuid();
+ item->iGID = getegid(); */
+ item->iUID = archive_entry_uid (entry);
+ item->iGID = archive_entry_gid (entry);
+ item->m_time = archive_entry_mtime (entry);
+ item->c_time = archive_entry_ctime (entry);
+ item->a_time = archive_entry_atime (entry);
+
+ /* Create valid UTF-8 filename */
+ if (g_utf8_validate (archive_entry_pathname (entry), -1, NULL))
+ s = g_strdup (archive_entry_pathname (entry));
+ else {
+ if (archive_entry_pathname_w (entry))
+ s = wide_to_utf8 (archive_entry_pathname_w (entry));
+ else
+ s = g_filename_display_name (archive_entry_pathname (entry));
+ }
+
+ /* Add item to the global tree and continue with next file */
+ filelist_tree_add_item (globs->files, s, item, archive_entry_pathname (entry), 0);
+ g_free (s);
+ }
+ archive_read_close (a);
}
- archive_read_finish(a);
- fprintf(stderr, "(II) VFSOpenArchive: done. \n");
+ archive_read_finish (a);
+ fprintf (stderr, "(II) VFSOpenArchive: done. \n");
- /* FIXME: temporarily disabled */
-// filelist_tree_resolve_symlinks(globs->files);
+ /* Resolve symlinks */
+ GTimer *timer = g_timer_new ();
+ filelist_tree_resolve_symlinks (globs->files);
+ g_print (" filelist_tree_resolve_symlinks: elapsed %d ms\n", (int) (g_timer_elapsed (timer, NULL) * 1000));
+ g_timer_destroy (timer);
- printf("\n\nList of items:\n");
- filelist_tree_print(globs->files);
+ printf ("\n\nList of items:\n");
+ filelist_tree_print (globs->files);
return Result;
}
-TVFSResult VFSClose(struct TVFSGlobs *globs)
+TVFSResult
+VFSClose (struct TVFSGlobs *globs)
{
if (globs) {
- fprintf(stderr, "(II) VFSClose: Freeing objects...\n");
- if (globs->vfs_filelist) vfs_filelist_free(globs->vfs_filelist);
- if (globs->files) filelist_tree_free(globs->files);
- if (globs->archive_path) free(globs->archive_path);
- if (globs->curr_dir) free(globs->curr_dir);
+ fprintf (stderr, "(II) VFSClose: Freeing objects...\n");
+ if (globs->vfs_filelist)
+ vfs_filelist_free (globs->vfs_filelist);
+ if (globs->files)
+ filelist_tree_free (globs->files);
+ g_free (globs->archive_path);
+ g_free (globs->curr_dir);
}
return cVFS_OK;
}
+
char *
VFSGetPath (struct TVFSGlobs *globs)
{
return include_trailing_path_sep (globs->curr_dir);
}
-u_int64_t VFSGetFileSystemFree(struct TVFSGlobs *globs, char *APath)
-{
- return 0;
-}
-u_int64_t VFSGetFileSystemSize(struct TVFSGlobs *globs, char *APath)
+TVFSResult
+VFSGetFileSystemInfo (struct TVFSGlobs *globs, const char *APath, gint64 *FSSize, gint64 *FSFree, char **FSLabel)
{
- return globs->total_size;
+ if (FSSize)
+ *FSSize = globs->total_size;
+ if (FSFree)
+ *FSFree = 0;
+ if (FSLabel)
+ *FSLabel = NULL;
+ return cVFS_OK;
}
-
-
-
/******************************************************************************************************/
-TVFSResult VFSChangeDir(struct TVFSGlobs *globs, char *NewPath)
+TVFSResult
+VFSChangeDir (struct TVFSGlobs *globs, const char *NewPath)
{
if (NewPath == NULL) {
printf("(EE) VFSChangeDir: NewPath is NULL!\n");
return cVFS_Failed;
}
- globs->curr_dir = vfs_filelist_change_dir(globs->vfs_filelist, NewPath);
- if (globs->curr_dir) return cVFS_OK;
- else return cVFS_Failed;
+ globs->curr_dir = vfs_filelist_change_dir (globs->vfs_filelist, NewPath);
+ if (globs->curr_dir)
+ return cVFS_OK;
+ else
+ return cVFS_Failed;
}
-int VFSGetPasswordRequired(struct TVFSGlobs *globs)
+
+gboolean
+VFSGetPasswordRequired (struct TVFSGlobs *globs)
{
+ /* no support for encrypted archives in libarchive */
return FALSE;
}
/******************************************************************************************************/
-TVFSResult VFSListFirst(struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item)
+TVFSResult
+VFSListFirst (struct TVFSGlobs *globs, const char *sDir, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath)
{
if (sDir == NULL) {
printf("(EE) VFSListFirst: sDir is NULL!\n");
@@ -421,32 +453,32 @@ TVFSResult VFSListFirst(struct TVFSGlobs *globs, char *sDir, struct TVFSItem *It
}
printf ("(--) VFSListFirst: Going to list all items in '%s'\n", sDir);
- return vfs_filelist_list_first(globs->vfs_filelist, sDir, Item);
+ return vfs_filelist_list_first (globs->vfs_filelist, sDir, Item, FollowSymlinks, AddFullPath);
}
-TVFSResult VFSListNext(struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item)
+TVFSResult
+VFSListNext (struct TVFSGlobs *globs, struct TVFSItem *Item)
{
- return vfs_filelist_list_next(globs->vfs_filelist, sDir, Item);
+ return vfs_filelist_list_next (globs->vfs_filelist, Item);
}
-TVFSResult VFSListClose(struct TVFSGlobs *globs)
+TVFSResult
+VFSListClose (struct TVFSGlobs *globs)
{
- return vfs_filelist_list_close(globs->vfs_filelist);
+ return vfs_filelist_list_close (globs->vfs_filelist);
}
/******************************************************************************************************/
-long VFSFileExists(struct TVFSGlobs *globs, const char *FileName, const long Use_lstat)
-{
- if (! globs) return FALSE;
- return vfs_filelist_file_exists(globs->vfs_filelist, FileName, Use_lstat);
-}
-TVFSResult VFSFileInfo(struct TVFSGlobs *globs, char *AFileName, struct TVFSItem *Item)
+TVFSResult
+VFSFileInfo (struct TVFSGlobs *globs, const char *AFileName, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath)
{
- printf("(--) VFSFileInfo: requested info for object '%s'\n", AFileName);
- if (!globs) return cVFS_Failed;
- return vfs_filelist_file_info(globs->vfs_filelist, AFileName, Item);
+ printf ("(--) VFSFileInfo: requested info for object '%s'\n", AFileName);
+ if (! globs)
+ return cVFS_Failed;
+
+ return vfs_filelist_file_info (globs->vfs_filelist, AFileName, Item, FollowSymlinks, AddFullPath);
}
@@ -454,16 +486,22 @@ TVFSResult VFSFileInfo(struct TVFSGlobs *globs, char *AFileName, struct TVFSItem
/** Recursive tree size counting */
/************** ****************/
-u_int64_t VFSGetDirSize(struct TVFSGlobs *globs, char *APath)
+guint64
+VFSGetDirSize (struct TVFSGlobs *globs, const char *APath)
{
- if (! globs) return 0;
- return vfs_filelist_get_dir_size(globs->vfs_filelist, APath);
+ if (! globs)
+ return 0;
+
+ return vfs_filelist_get_dir_size (globs->vfs_filelist, APath);
}
-void VFSBreakGetDirSize(struct TVFSGlobs *globs)
+void
+VFSBreakGetDirSize (struct TVFSGlobs *globs)
{
- printf("(WW) VFSBreakGetDirSize: calling break\n");
- if (globs) vfs_filelist_get_dir_size_break(globs->vfs_filelist);
+ printf ("(WW) VFSBreakGetDirSize: calling break\n");
+
+ if (globs)
+ vfs_filelist_get_dir_size_break (globs->vfs_filelist);
}
@@ -471,52 +509,52 @@ void VFSBreakGetDirSize(struct TVFSGlobs *globs)
/** Methods modifying the archive */
/************** ****************/
-TVFSResult VFSMkDir(struct TVFSGlobs *globs, const char *sDirName)
+TVFSResult VFSMkDir (struct TVFSGlobs *globs, const char *sDirName)
{
- printf("(WW) VFSMkDir: Not supported in libarchive plugin.\n");
+ printf ("(WW) VFSMkDir: Not supported in libarchive plugin.\n");
return cVFS_Not_Supported;
}
-TVFSResult VFSRemove(struct TVFSGlobs *globs, const char *APath)
+TVFSResult VFSRemove (struct TVFSGlobs *globs, const char *APath)
{
- printf("(WW) VFSRemove: Not supported in libarchive plugin.\n");
+ printf ("(WW) VFSRemove: Not supported in libarchive plugin.\n");
return cVFS_Not_Supported;
}
-TVFSResult VFSRename(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName)
+TVFSResult VFSRename (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName)
{
- printf("(WW) VFSRename: Not supported in libarchive plugin.\n");
+ printf ("(WW) VFSRename: Not supported in libarchive plugin.\n");
return cVFS_Not_Supported;
}
-TVFSResult VFSMakeSymLink(struct TVFSGlobs *globs, const char *NewFileName, const char *PointTo)
+TVFSResult VFSMakeSymLink (struct TVFSGlobs *globs, const char *NewFileName, const char *PointTo)
{
- printf("(WW) VFSMakeSymLink: Not supported in libarchive plugin.\n");
+ printf ("(WW) VFSMakeSymLink: Not supported in libarchive plugin.\n");
return cVFS_Not_Supported;
}
-TVFSResult VFSChmod(struct TVFSGlobs *globs, const char *FileName, const uint Mode)
+TVFSResult VFSChmod (struct TVFSGlobs *globs, const char *FileName, guint32 Mode)
{
- printf("(WW) VFSChmod: Not supported in libarchive plugin.\n");
+ printf ("(WW) VFSChmod: Not supported in libarchive plugin.\n");
return cVFS_Not_Supported;
}
-TVFSResult VFSChown(struct TVFSGlobs *globs, const char *FileName, const uint UID, const uint GID)
+TVFSResult VFSChown (struct TVFSGlobs *globs, const char *FileName, guint32 UID, guint32 GID)
{
- printf("(WW) VFSChown: Not supported in libarchive plugin.\n");
+ printf ("(WW) VFSChown: Not supported in libarchive plugin.\n");
return cVFS_Not_Supported;
}
-TVFSResult VFSChangeTimes(struct TVFSGlobs *globs, char *APath, long mtime, long atime)
+TVFSResult VFSChangeTimes (struct TVFSGlobs *globs, char *APath, guint32 mtime, guint32 atime)
{
- printf("(WW) VFSChangeTimes: Not supported in libarchive plugin.\n");
+ printf ("(WW) VFSChangeTimes: Not supported in libarchive plugin.\n");
return cVFS_Not_Supported;
}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-////////////////////////
+/******************************************************************************************************/
+/************** **/
TVFSFileDes VFSOpenFile(struct TVFSGlobs *globs, const char *APath, int Mode, int *Error)
{
@@ -547,27 +585,30 @@ int VFSWriteFile(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, void *Buff
return 0;
}
-void VFSSetBlockSize(struct TVFSGlobs *globs, int Value)
+void
+VFSSetBlockSize (struct TVFSGlobs *globs, guint32 Value)
{
- globs->block_size = Value;
+ if (globs)
+ globs->block_size = Value;
}
-int VFSIsOnSameFS(struct TVFSGlobs *globs, const char *Path1, const char *Path2)
+gboolean
+VFSIsOnSameFS (struct TVFSGlobs *globs, const char *Path1, const char *Path2, gboolean FollowSymlinks)
{
- printf("(WW) VFSIsOnSameFS: Not supported in libarchive plugin.\n");
+ printf ("(WW) VFSIsOnSameFS: Not supported in libarchive plugin.\n");
return TRUE;
}
-int VFSTwoSameFiles(struct TVFSGlobs *globs, const char *Path1, const char *Path2)
+gboolean
+VFSTwoSameFiles (struct TVFSGlobs *globs, const char *Path1, const char *Path2, gboolean FollowSymlinks)
{
- printf("(WW) VFSTwoSameFiles: Not supported in libarchive, comparing by paths.\n");
- return compare_two_same_files(Path1, Path2);
+ printf ("(WW) VFSTwoSameFiles: Not supported in libarchive, comparing by paths.\n");
+ return compare_two_same_files (Path1, Path2);
}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-////////////////////////
-
+/******************************************************************************************************/
+/************** **/
@@ -576,158 +617,154 @@ int VFSTwoSameFiles(struct TVFSGlobs *globs, const char *Path1, const char *Path
* Quote: "This implementation minimizes copying of data and is sparse-file aware."
**/
static TVFSResult
-my_archive_read_data_into_fd(struct TVFSGlobs *globs, struct archive *a, struct archive_entry *entry, const char *sDstName, size_t max_block, int Append)
-{
- int r;
- int fd;
- const void *buff;
- size_t size, bytes_to_write;
- ssize_t bytes_written, total_written;
- off_t offset;
- off_t output_offset;
- u_int64_t file_size;
- gboolean cancel = FALSE;
-
-
- printf("(II) my_archive_read_data_into_fd: extracting to '%s', Append = %d\n", sDstName, Append);
-
- if (Append) fd = open(sDstName, O_APPEND | O_WRONLY);
- else fd = open(sDstName, O_CREAT | O_WRONLY | O_TRUNC,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
- if (fd < 0) {
- fprintf(stderr, "(EE) my_archive_read_data_into_fd: error occured while extracting data: %s\n", strerror(errno));
- return cVFS_Failed;
- }
-
- total_written = 0;
- output_offset = 0;
- file_size = (u_int64_t)archive_entry_size(entry);
-
- while ((r = archive_read_data_block(a, &buff, &size, &offset)) == ARCHIVE_OK) {
- const char *p = buff;
- if (offset > output_offset) {
- lseek(fd, offset - output_offset, SEEK_CUR);
- output_offset = offset;
- }
- while (size > 0) {
- if (cancel) break;
- bytes_to_write = size;
- if (bytes_to_write > max_block)
- bytes_to_write = max_block;
- bytes_written = write(fd, p, bytes_to_write);
- if (bytes_written < 0) {
- fprintf(stderr, "(EE) my_archive_read_data_into_fd: error occured while extracting data: %s\n", strerror(errno));
- return cVFS_Failed;
- }
- output_offset += bytes_written;
- total_written += bytes_written;
- p += bytes_written;
- size -= bytes_written;
-
- log(" (II) my_archive_read_data_into_fd: bytes_written = %zd, total_written = %zd\n", bytes_written, total_written);
- if (globs->callback_progress) {
- if (! globs->callback_progress(total_written, file_size, globs->callback_data)) {
- cancel = TRUE;
- break;
- }
-// usleep(100000);
- }
- }
- }
-
- if ((close(fd)) || ((r != ARCHIVE_OK) && (r != ARCHIVE_EOF))) {
- fprintf(stderr, "(EE) my_archive_read_data_into_fd: error closing extracted file: %s\n", strerror(errno));
- return cVFS_WriteErr;
- }
- if (cancel) {
- if (unlink(sDstName))
- fprintf(stderr, "(EE) my_archive_read_data_into_fd: error unlinking cancelled extraction: %s\n", strerror(errno));
- return cVFS_Cancelled;
- }
- printf("(II) my_archive_read_data_into_fd: done.\n");
- return cVFS_OK;
-}
-
-
-TVFSResult VFSCopyToLocal(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, int Append)
-{
- if ((sSrcName == NULL) || (sDstName == NULL) || (strlen(sSrcName) < 1) || (strlen(sDstName) < 1)) {
- printf("(EE) VFSCopyToLocal: The value of 'sSrcName' or 'sDstName' is NULL or empty\n");
+my_archive_read_data_into_fd (struct TVFSGlobs *globs, struct archive *a, struct archive_entry *entry, const char *sDstName, size_t max_block, gboolean Append)
+{
+ int r;
+ int fd;
+ const void *buff;
+ size_t size, bytes_to_write;
+ ssize_t bytes_written, total_written;
+ off_t offset;
+ off_t output_offset;
+ guint64 file_size;
+ gboolean cancel = FALSE;
+
+
+ printf ("(II) my_archive_read_data_into_fd: extracting to '%s', Append = %d\n", sDstName, Append);
+
+ if (Append)
+ fd = open (sDstName, O_APPEND | O_WRONLY);
+ else
+ fd = open(sDstName, O_CREAT | O_WRONLY | O_TRUNC,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ if (fd < 0) {
+ fprintf (stderr, "(EE) my_archive_read_data_into_fd: error occured while extracting data: %s\n", strerror (errno));
return cVFS_Failed;
}
- printf("(II) VFSCopyToLocal: copying file '%s' out to '%s'\n", sSrcName, sDstName);
-
- struct PathTree *node = filelist_tree_find_node_by_path(globs->files, sSrcName);
- if (! node) {
- fprintf(stderr, "(EE) VFSCopyToLocal: cannot find file '%s'\n", sSrcName);
- return cVFS_ReadErr;
+ total_written = 0;
+ output_offset = 0;
+ file_size = (guint64) archive_entry_size (entry);
+
+ while ((r = archive_read_data_block (a, &buff, &size, &offset)) == ARCHIVE_OK) {
+ const char *p = buff;
+ if (offset > output_offset) {
+ lseek (fd, offset - output_offset, SEEK_CUR);
+ output_offset = offset;
+ }
+ while (size > 0) {
+ if (cancel)
+ break;
+ bytes_to_write = size;
+ if (bytes_to_write > max_block)
+ bytes_to_write = max_block;
+ bytes_written = write (fd, p, bytes_to_write);
+ if (bytes_written < 0) {
+ fprintf (stderr, "(EE) my_archive_read_data_into_fd: error occured while extracting data: %s\n", strerror (errno));
+ return cVFS_Failed;
+ }
+ output_offset += bytes_written;
+ total_written += bytes_written;
+ p += bytes_written;
+ size -= bytes_written;
+
+ log (" (II) my_archive_read_data_into_fd: bytes_written = %zd, total_written = %zd\n", bytes_written, total_written);
+ if (globs->callback_progress)
+ if (! globs->callback_progress (total_written, file_size, globs->callback_data)) {
+ cancel = TRUE;
+ break;
+ }
+ }
}
- const char *src = node->original_pathstr;
- if (! src) {
- fprintf(stderr, "(WW) VFSCopyToLocal: cannot determine original filename\n");
- src = sSrcName;
+ if (close (fd) || (r != ARCHIVE_OK && r != ARCHIVE_EOF)) {
+ fprintf (stderr, "(EE) my_archive_read_data_into_fd: error closing extracted file: %s\n", strerror (errno));
+ return cVFS_WriteErr;
+ }
+ if (cancel) {
+ if (unlink (sDstName))
+ fprintf (stderr, "(EE) my_archive_read_data_into_fd: error unlinking cancelled extraction: %s\n", strerror (errno));
+ return cVFS_Cancelled;
}
- printf("(II) VFSCopyToLocal: new src path: '%s'\n", src);
+ printf ("(II) my_archive_read_data_into_fd: done.\n");
+ return cVFS_OK;
+}
+TVFSResult
+VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append)
+{
+ struct PathTree *node;
+ const char *src;
TVFSResult Result;
struct archive *a;
struct archive_entry *entry;
int r;
- gboolean found = FALSE;
-
- Result = libarchive_open(&a, globs->archive_path, globs->block_size);
- if (Result == cVFS_OK)
- {
- for (;;) {
- entry = NULL;
- r = archive_read_next_header(a, &entry);
- if (r == ARCHIVE_EOF) {
- break;
- } else
- if (r == ARCHIVE_WARN) {
- log("(WW) VFSOpen: file '%s' - libarchive warning: '%s'\n", archive_entry_pathname(entry), archive_error_string(a));
- } else
- if (r != ARCHIVE_OK) {
- fprintf(stderr, "(EE) VFSCopyToLocal: error occured while reading archive: '%s'\n", archive_error_string(a));
- Result = cVFS_Failed;
- break;
- }
-
-// printf ("found file: %s, mode = %x\n", archive_entry_pathname(entry), archive_entry_mode(entry));
- const char *ssrc = src;
- const char *asrc = archive_entry_pathname(entry);
- if (IS_DIR_SEP(*ssrc)) ssrc++;
- if (IS_DIR_SEP(*asrc)) asrc++;
-
-// printf ("strcmp: '%s' vs. '%s'\n", ssrc, asrc);
- if (strcmp(ssrc, asrc) == 0) {
-// printf("--> found file, extracting\n");
- fprintf(stderr, "(II) VFSCopyToLocal: extract_file_path(sDstName) = '%s', extract_file_name(sDstName) = '%s' \n", extract_file_path(sDstName), extract_file_name(sDstName));
- found = TRUE;
-
- Result = my_archive_read_data_into_fd(globs, a, entry, sDstName, globs->block_size, Append);
- break;
- }
- }
- archive_read_close(a);
+ gboolean found;
+
+ if (sSrcName == NULL || sDstName == NULL || strlen (sSrcName) < 1 || strlen (sDstName) < 1) {
+ printf ("(EE) VFSCopyToLocal: The value of 'sSrcName' or 'sDstName' is NULL or empty\n");
+ return cVFS_Failed;
+ }
+
+ printf ("(II) VFSCopyToLocal: copying file '%s' out to '%s'\n", sSrcName, sDstName);
+
+ node = filelist_tree_find_node_by_path (globs->files, sSrcName);
+ if (! node) {
+ fprintf (stderr, "(EE) VFSCopyToLocal: cannot find file '%s'\n", sSrcName);
+ return cVFS_ReadErr;
}
- archive_read_finish(a);
- if ((! found) && Result == cVFS_OK) {
- fprintf(stderr, "(EE) VFSCopyToLocal: file not found in archive.\n");
+ src = node->original_pathstr;
+ if (! src) {
+ fprintf (stderr, "(WW) VFSCopyToLocal: cannot determine original filename\n");
+ src = sSrcName;
+ }
+ printf ("(II) VFSCopyToLocal: new src path: '%s'\n", src);
+
+
+ found = FALSE;
+ Result = libarchive_open (&a, globs->archive_path, globs->block_size);
+ if (Result == cVFS_OK) {
+ for (;;) {
+ entry = NULL;
+ r = archive_read_next_header (a, &entry);
+ if (r == ARCHIVE_EOF) {
+ break;
+ } else
+ if (r == ARCHIVE_WARN) {
+ log("(WW) VFSOpen: file '%s' - libarchive warning: '%s'\n", archive_entry_pathname (entry), archive_error_string (a));
+ } else
+ if (r != ARCHIVE_OK) {
+ fprintf (stderr, "(EE) VFSCopyToLocal: error occured while reading archive: '%s'\n", archive_error_string (a));
+ Result = cVFS_Failed;
+ break;
+ }
+
+ if (g_strcmp0 (src, archive_entry_pathname (entry)) == 0) {
+ found = TRUE;
+ Result = my_archive_read_data_into_fd (globs, a, entry, sDstName, globs->block_size, Append);
+ break;
+ }
+ }
+ archive_read_close (a);
+ }
+ archive_read_finish (a);
+
+ if (! found && Result == cVFS_OK) {
+ fprintf (stderr, "(EE) VFSCopyToLocal: file not found in archive.\n");
Result = cVFS_ReadErr;
}
- fprintf(stderr, "(II) VFSCopyToLocal: finished. \n");
+ fprintf (stderr, "(II) VFSCopyToLocal: finished. \n");
return Result;
}
-TVFSResult VFSCopyFromLocal(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, int Append)
+
+TVFSResult
+VFSCopyFromLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append)
{
- printf("(WW) VFSCopyFromLocal: Not supported in libarchive plugin.\n");
+ printf ("(WW) VFSCopyFromLocal: Not supported in libarchive plugin.\n");
return cVFS_Not_Supported;
}
@@ -737,7 +774,6 @@ TVFSResult VFSCopyFromLocal(struct TVFSGlobs *globs, const char *sSrcName, const
/**********
* TODO:
*
- * - UTF-8, FName/FDisplayName and absolute/relative paths revision needed!
* - archive testing (needs new VFS API)
* - write support
* - support creating new archives (needs new VFS API)
diff --git a/libarchive/treepath_vfs.c b/libarchive/treepath_vfs.c
deleted file mode 120000
index f4b41b3..0000000
--- a/libarchive/treepath_vfs.c
+++ /dev/null
@@ -1 +0,0 @@
-../common/treepath_vfs.c \ No newline at end of file
diff --git a/libarchive/treepath_vfs.h b/libarchive/treepath_vfs.h
deleted file mode 120000
index a1e19e7..0000000
--- a/libarchive/treepath_vfs.h
+++ /dev/null
@@ -1 +0,0 @@
-../common/treepath_vfs.h \ No newline at end of file
diff --git a/libarchive/treepathutils.c b/libarchive/treepathutils.c
deleted file mode 120000
index ae760bc..0000000
--- a/libarchive/treepathutils.c
+++ /dev/null
@@ -1 +0,0 @@
-../common/treepathutils.c \ No newline at end of file
diff --git a/libarchive/treepathutils.h b/libarchive/treepathutils.h
deleted file mode 120000
index 4e3c904..0000000
--- a/libarchive/treepathutils.h
+++ /dev/null
@@ -1 +0,0 @@
-../common/treepathutils.h \ No newline at end of file
diff --git a/libarchive/tuxcmd-vfs.h b/libarchive/tuxcmd-vfs.h
new file mode 120000
index 0000000..b7f193e
--- /dev/null
+++ b/libarchive/tuxcmd-vfs.h
@@ -0,0 +1 @@
+../common/tuxcmd-vfs.h \ No newline at end of file
diff --git a/libarchive/vfs_types.h b/libarchive/vfs_types.h
deleted file mode 120000
index c2235a2..0000000
--- a/libarchive/vfs_types.h
+++ /dev/null
@@ -1 +0,0 @@
-../common/vfs_types.h \ No newline at end of file
diff --git a/unrar/Makefile b/unrar/Makefile
index 7407cbe..14aa5fc 100644
--- a/unrar/Makefile
+++ b/unrar/Makefile
@@ -1,23 +1,23 @@
# path definitions
DESTDIR = /usr
-INSTALL=install -c
+INSTALL = install -c
INSTALL_DATA = ${INSTALL} -m 644
DIR_UNRAR = unrar
# compiler options
CC = gcc
CPP = g++
-CFLAGS =-I. -I/usr/include -I$(DIR_UNRAR) \
- -Wall -fPIC -O2 -g \
- -DG_DISABLE_DEPRECATED -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE \
- -D__VERBOSE_DEBUGx
+CFLAGS = -I. -I/usr/include -I$(DIR_UNRAR) \
+ -Wall -fPIC -O2 -g \
+ -DG_DISABLE_DEPRECATED -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE \
+ -D__VERBOSE_DEBUGx
-LIB_SUFFIX=`if test \`uname -m\` = x86_64 -o \`uname -m\` = ppc64; then echo 64; fi`
+LIB_SUFFIX = `if test \`uname -m\` = x86_64 -o \`uname -m\` = ppc64; then echo 64; fi`
-UNRAR_LIB_OBJ=$(DIR_UNRAR)/filestr.o $(DIR_UNRAR)/scantree.o $(DIR_UNRAR)/dll.o
+UNRAR_LIB_OBJ = $(DIR_UNRAR)/filestr.o $(DIR_UNRAR)/scantree.o $(DIR_UNRAR)/dll.o
-UNRAR_OBJECTS=$(DIR_UNRAR)/rar.o $(DIR_UNRAR)/strlist.o $(DIR_UNRAR)/strfn.o \
+UNRAR_OBJECTS = $(DIR_UNRAR)/rar.o $(DIR_UNRAR)/strlist.o $(DIR_UNRAR)/strfn.o \
$(DIR_UNRAR)/pathfn.o $(DIR_UNRAR)/int64.o $(DIR_UNRAR)/savepos.o \
$(DIR_UNRAR)/global.o $(DIR_UNRAR)/file.o $(DIR_UNRAR)/filefn.o \
$(DIR_UNRAR)/filcreat.o $(DIR_UNRAR)/archive.o $(DIR_UNRAR)/arcread.o \
@@ -32,9 +32,9 @@ UNRAR_OBJECTS=$(DIR_UNRAR)/rar.o $(DIR_UNRAR)/strlist.o $(DIR_UNRAR)/strfn.o \
$(DIR_UNRAR)/unpack.o $(DIR_UNRAR)/cmddata.o
-VFS_COMMON_OBJECTS=strutils.o treepathutils.o treepath_vfs.o vfsutils.o
+VFS_COMMON_OBJECTS = filelist.o filelist-vfs-intf.o strutils.o vfsutils.o
-VFS_OBJECTS=unrar.o rarlog.o
+VFS_OBJECTS = unrar.o rarlog.o
.SUFFIXES: .c .cpp
@@ -52,11 +52,11 @@ libunrar_plugin.so: libunrar $(VFS_COMMON_OBJECTS) $(VFS_OBJECTS)
libunrar:
( cd $(DIR_UNRAR) && make -f ../Makefile.unrar ) || exit 1
-strutils.o: strutils.c strutils.h
-treepathutils.o: treepathutils.c treepathutils.h
-vfsutils.o: vfsutils.c vfsutils.h
-treepath_vfs.o: treepath_vfs.c treepath_vfs.h
-rarlog.o: rarlog.cpp rarlog.hpp
+filelist.o: filelist.h filelist.c
+filelist-vfs-intf.o: filelist-vfs-intf.h filelist-vfs-intf.c
+strutils.o: strutils.h strutils.c
+vfsutils.o: vfsutils.h vfsutils.c
+rarlog.o: rarlog.hpp rarlog.cpp
install::
$(INSTALL) ./libunrar_plugin.so $(DESTDIR)/lib$(LIB_SUFFIX)/tuxcmd/
diff --git a/unrar/filelist-vfs-intf.c b/unrar/filelist-vfs-intf.c
new file mode 120000
index 0000000..68d7a7c
--- /dev/null
+++ b/unrar/filelist-vfs-intf.c
@@ -0,0 +1 @@
+../common/filelist-vfs-intf.c \ No newline at end of file
diff --git a/unrar/filelist-vfs-intf.h b/unrar/filelist-vfs-intf.h
new file mode 120000
index 0000000..f7afe49
--- /dev/null
+++ b/unrar/filelist-vfs-intf.h
@@ -0,0 +1 @@
+../common/filelist-vfs-intf.h \ No newline at end of file
diff --git a/unrar/filelist.c b/unrar/filelist.c
new file mode 120000
index 0000000..9504563
--- /dev/null
+++ b/unrar/filelist.c
@@ -0,0 +1 @@
+../common/filelist.c \ No newline at end of file
diff --git a/unrar/filelist.h b/unrar/filelist.h
new file mode 120000
index 0000000..90a52e1
--- /dev/null
+++ b/unrar/filelist.h
@@ -0,0 +1 @@
+../common/filelist.h \ No newline at end of file
diff --git a/unrar/treepath_vfs.c b/unrar/treepath_vfs.c
deleted file mode 120000
index f4b41b3..0000000
--- a/unrar/treepath_vfs.c
+++ /dev/null
@@ -1 +0,0 @@
-../common/treepath_vfs.c \ No newline at end of file
diff --git a/unrar/treepath_vfs.h b/unrar/treepath_vfs.h
deleted file mode 120000
index a1e19e7..0000000
--- a/unrar/treepath_vfs.h
+++ /dev/null
@@ -1 +0,0 @@
-../common/treepath_vfs.h \ No newline at end of file
diff --git a/unrar/treepathutils.c b/unrar/treepathutils.c
deleted file mode 120000
index ae760bc..0000000
--- a/unrar/treepathutils.c
+++ /dev/null
@@ -1 +0,0 @@
-../common/treepathutils.c \ No newline at end of file
diff --git a/unrar/treepathutils.h b/unrar/treepathutils.h
deleted file mode 120000
index 4e3c904..0000000
--- a/unrar/treepathutils.h
+++ /dev/null
@@ -1 +0,0 @@
-../common/treepathutils.h \ No newline at end of file
diff --git a/unrar/tuxcmd-vfs.h b/unrar/tuxcmd-vfs.h
new file mode 120000
index 0000000..b7f193e
--- /dev/null
+++ b/unrar/tuxcmd-vfs.h
@@ -0,0 +1 @@
+../common/tuxcmd-vfs.h \ No newline at end of file
diff --git a/unrar/unrar.c b/unrar/unrar.c
index 0db1493..61ce4c4 100644
--- a/unrar/unrar.c
+++ b/unrar/unrar.c
@@ -1,6 +1,6 @@
/* UNRAR plugin for Tux Commander
- * version 0.3.7, designed for unrar v3.8.2
- * Copyright (C) 2008 Tomas Bzatek <tbzatek@users.sourceforge.net>
+ * version 0.4.0, designed for unrar v3.8.2
+ * Copyright (C) 2007-2009 Tomas Bzatek <tbzatek@users.sourceforge.net>
* Check for updates on tuxcmd.sourceforge.net
*
* Uses UNRAR sources
@@ -26,21 +26,17 @@
*/
#include <string.h>
+#include <stdio.h>
#include <stdlib.h>
-#include <stdint.h>
-#include <sys/stat.h>
-#include <sys/types.h>
#include <errno.h>
-#include <dirent.h>
-#include <fnmatch.h>
#include <unistd.h>
#include <glib.h>
-#include "vfs_types.h"
+#include "tuxcmd-vfs.h"
#include "vfsutils.h"
#include "strutils.h"
-#include "treepathutils.h"
-#include "treepath_vfs.h"
+#include "filelist.h"
+#include "filelist-vfs-intf.h"
#define _UNIX
@@ -48,15 +44,20 @@
#include "unrar/dll.hpp"
-// Compatibility types from headers.hpp
+/* Compatibility types from headers.hpp */
enum HOST_SYSTEM {
- HOST_MSDOS=0,HOST_OS2=1,HOST_WIN32=2,HOST_UNIX=3,HOST_MACOS=4,
- HOST_BEOS=5,HOST_MAX
+ HOST_MSDOS = 0,
+ HOST_OS2 = 1,
+ HOST_WIN32 = 2,
+ HOST_UNIX = 3,
+ HOST_MACOS = 4,
+ HOST_BEOS = 5,
+ HOST_MAX
};
-#define VERSION "0.3.7"
-#define BUILD_DATE "2009-10-25"
+#define VERSION "0.4.0"
+#define BUILD_DATE "2009-11-26"
#define DEFAULT_BLOCK_SIZE 65536
@@ -64,7 +65,7 @@ enum HOST_SYSTEM {
-// Declaration of the global plugin object
+/* Declaration of the global plugin object */
struct TVFSGlobs {
TVFSLogFunc log_func;
char *curr_dir;
@@ -75,15 +76,15 @@ struct TVFSGlobs {
gboolean volume_missing_abort;
char *password;
- unsigned long block_size;
+ guint32 block_size;
struct PathTree *files;
struct VfsFilelistData *vfs_filelist;
- int64_t total_size;
+ guint64 total_size;
- int64_t extract_file_size;
- int64_t extract_done;
+ guint64 extract_file_size;
+ guint64 extract_done;
gboolean extract_cancelled;
TVFSAskQuestionCallback callback_ask_question;
@@ -100,13 +101,13 @@ struct TVFSGlobs {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////
// Basic initialization functions
+
struct TVFSGlobs *
VFSNew (TVFSLogFunc log_func)
{
struct TVFSGlobs * globs;
- globs = (struct TVFSGlobs *) malloc (sizeof (struct TVFSGlobs));
- memset (globs, 0, sizeof (struct TVFSGlobs));
+ globs = g_malloc0 (sizeof (struct TVFSGlobs));
globs->block_size = DEFAULT_BLOCK_SIZE;
globs->need_password = FALSE;
@@ -120,7 +121,8 @@ VFSNew (TVFSLogFunc log_func)
globs->callback_progress = NULL;
globs->log_func = log_func;
- if (globs->log_func != NULL) globs->log_func("unrar plugin: VFSInit");
+ if (globs->log_func)
+ globs->log_func("unrar plugin: VFSInit");
return globs;
}
@@ -141,19 +143,23 @@ VFSSetCallbacks (struct TVFSGlobs *globs,
void
VFSFree (struct TVFSGlobs *globs)
{
- if (globs->log_func != NULL) globs->log_func("unrar plugin: VFSDestroy");
- free (globs);
+ if (globs->log_func)
+ globs->log_func("unrar plugin: VFSDestroy");
+ g_free (globs);
}
-int VFSVersion()
+int
+VFSVersion ()
{
return cVFSVersion;
}
struct TVFSInfo *
-VFSGetInfo()
+VFSGetInfo ()
{
- struct TVFSInfo *module_info = g_malloc0 (sizeof (struct TVFSInfo));
+ struct TVFSInfo *module_info;
+
+ module_info = g_malloc0 (sizeof (struct TVFSInfo));
module_info->ID = g_strdup ("unrar_plugin");
module_info->Name = g_strdup ("UNRAR plugin");
@@ -174,77 +180,79 @@ VFSGetArchiveExts ()
/**************************************************************************************************************************************/
/**************************************************************************************************************************************/
-int unrar_callback(UINT msg, LONG UserData, LONG P1, LONG P2)
+static int
+unrar_callback (UINT msg, LONG UserData, LONG P1, LONG P2)
{
+ struct TVFSGlobs *globs;
+
// fprintf(stderr, "(II) unrar_callback called: msg = %d, UserData = %lx, sizeof(UserData) = %ld, P1 = %ld, P2 = %ld\n", msg, UserData, sizeof(UserData), P1, P2);
if (! UserData) {
- fprintf(stderr, "(WW) unrar_callback: UserData == NULL, exiting!\n");
+ fprintf (stderr, "(WW) unrar_callback: UserData == NULL, exiting!\n");
return 0;
}
- struct TVFSGlobs *globs = (struct TVFSGlobs *)UserData;
+ globs = (struct TVFSGlobs *) UserData;
// >= 0 => Weiter, -1 => Stop
- switch(msg)
- {
+ switch (msg) {
case UCM_CHANGEVOLUME: {
if (P2 == RAR_VOL_ASK) {
- fprintf(stderr, " (II) unrar_callback: UCM_CHANGEVOLUME message, RAR_VOL_ASK, P1 = %ld, (char*)P1 = '%s' \n", P1, (char*)P1);
- if (P1) {
- if (globs->callback_ask_question) {
- static const char *choices[] = {
- "Abort", /* response = 0 */
- "Ignore", /* response = 1 */
- NULL
- };
- char *message, *s;
- int choice = -1;
-
- s = g_filename_to_utf8 ((char *)P1, -1, NULL, NULL, NULL);
- message = g_strdup_printf ("Archive is incomplete, volume missing: \n\n%s", s ? s : (char *)P1);
- globs->callback_ask_question (message, &choices[0], &choice, 0,
- globs->callback_data);
- g_free (message);
- if (s) g_free (s);
-
- if (choice != 1)
- globs->volume_missing_abort = TRUE;
- return -1;
- } else {
- if (access((char*)P1, R_OK) != 0) {
- fprintf(stderr, "(EE) unrar_callback: UCM_CHANGEVOLUME message, RAR_VOL_ASK: access test failed - missing part? Error = %s \n", strerror(errno));
- return -1;
- }
- }
- }
+ fprintf (stderr, " (II) unrar_callback: UCM_CHANGEVOLUME message, RAR_VOL_ASK, P1 = %ld, (char*)P1 = '%s' \n", P1, (char*)P1);
+ if (P1) {
+ if (globs->callback_ask_question) {
+ static const char *choices[] = {
+ "Abort", /* response = 0 */
+ "Ignore", /* response = 1 */
+ NULL
+ };
+ char *message, *s;
+ int choice = -1;
+
+ s = g_filename_display_name((char *)P1);
+ message = g_strdup_printf ("Archive is incomplete, volume missing: \n\n%s", s ? s : (char *)P1);
+ globs->callback_ask_question (message, &choices[0], &choice, 0,
+ globs->callback_data);
+ g_free (message);
+ g_free (s);
+
+ if (choice != 1)
+ globs->volume_missing_abort = TRUE;
+ return -1;
+ } else {
+ if (access((char*)P1, R_OK) != 0) {
+ fprintf (stderr, "(EE) unrar_callback: UCM_CHANGEVOLUME message, RAR_VOL_ASK: access test failed - missing part? Error = %s \n", strerror (errno));
+ return -1;
+ }
+ }
+ }
} else
if (P2 == RAR_VOL_NOTIFY) {
- fprintf(stderr, " (II) unrar_callback: UCM_CHANGEVOLUME message, RAR_VOL_NOTIFY, P1 = %ld, (char*)P1 = '%s' \n", P1, (char*)P1);
+ fprintf (stderr, " (II) unrar_callback: UCM_CHANGEVOLUME message, RAR_VOL_NOTIFY, P1 = %ld, (char*)P1 = '%s' \n", P1, (char*)P1);
}
break;
}
case UCM_PROCESSDATA: {
- fprintf(stderr, " (II) unrar_callback: UCM_PROCESSDATA message, P1 = %ld, P2 = %ld \n", P1, P2);
+ fprintf (stderr, " (II) unrar_callback: UCM_PROCESSDATA message, P1 = %ld, P2 = %ld \n", P1, P2);
// printf(" (II) unrar_callback: globs = 0x%lX, UserData = 0x%lX \n", (unsigned long int)globs, UserData);
- if ((globs) && (globs->callback_progress)) {
-// printf(" (II) unrar_callback: globs->extract_callback_func = 0x%lX, globs->extract_callback_data = 0x%lX \n", (unsigned long int)globs->extract_callback_func, (unsigned long int)globs->extract_callback_data);
-// long int res = globs->extract_callback_func((u_int64_t)P1, (u_int64_t)((u_int64_t)P1 + (u_int64_t)P2), globs->extract_callback_data);
-
- globs->extract_done += P2;
- int res = globs->callback_progress(globs->extract_done, globs->extract_file_size, globs->callback_data);
-
-// fprintf(stderr, " (II) unrar_callback: res = %d \n", res);
- if (! res ) {
- globs->extract_cancelled = TRUE;
- fprintf(stderr, "(WW) unrar_callback: received cancellation result\n");
- return -1; // Cancel operation
- }
+ if (globs && globs->callback_progress) {
+// printf(" (II) unrar_callback: globs->extract_callback_func = 0x%lX, globs->extract_callback_data = 0x%lX \n", (unsigned long int)globs->extract_callback_func, (unsigned long int)globs->extract_callback_data);
+// long int res = globs->extract_callback_func((u_int64_t)P1, (u_int64_t)((u_int64_t)P1 + (u_int64_t)P2), globs->extract_callback_data);
+
+ globs->extract_done += P2;
+ int res = globs->callback_progress(globs->extract_done, globs->extract_file_size, globs->callback_data);
+
+// fprintf(stderr, " (II) unrar_callback: res = %d \n", res);
+ if (! res ) {
+ globs->extract_cancelled = TRUE;
+ fprintf (stderr, "(WW) unrar_callback: received cancellation result\n");
+ return -1; // Cancel operation
+ }
}
break;
}
case UCM_NEEDPASSWORD: {
- fprintf(stderr, " (II) unrar_callback: UCM_NEEDPASSWORD message, P1 = %ld, P2 = %ld, (char*)P1 = '%s', maxlen = %ld \n", P1, P2, (char*)P1, P2);
+ fprintf (stderr, " (II) unrar_callback: UCM_NEEDPASSWORD message, P1 = %ld, P2 = %ld, (char*)P1 = '%s', maxlen = %ld \n", P1, P2, (char*)P1, P2);
char *passwd = NULL;
int res = FALSE;
@@ -258,8 +266,8 @@ int unrar_callback(UINT msg, LONG UserData, LONG P1, LONG P2)
if (res && passwd) {
fprintf(stderr, " (II) unrar_callback: setting password to '%s'\n", passwd);
if (strlen (passwd) > 0) {
- strncpy((char *)P1, passwd, P2);
- if (globs->password) g_free (globs->password);
+ strncpy ((char *)P1, passwd, P2);
+ g_free (globs->password);
globs->password = g_strdup (passwd);
}
g_free (passwd);
@@ -277,22 +285,25 @@ int unrar_callback(UINT msg, LONG UserData, LONG P1, LONG P2)
return 0;
}
-int PASCAL unrar_changevol_proc(char *ArcName, int Mode)
+static int PASCAL
+unrar_changevol_proc (char *ArcName, int Mode)
{
- fprintf(stderr, "(II) unrar_changevol_proc called: ArcName = '%s', Mode = %d\n", ArcName, Mode);
+ fprintf (stderr, "(II) unrar_changevol_proc called: ArcName = '%s', Mode = %d\n", ArcName, Mode);
return 0;
}
-int PASCAL unrar_process_data_proc(unsigned char *Addr, int Size)
+static int PASCAL
+unrar_process_data_proc (unsigned char *Addr, int Size)
{
- fprintf(stderr, "(II) unrar_process_data_proc called: Addr = '%s', Size = %d\n", Addr, Size);
+ fprintf (stderr, "(II) unrar_process_data_proc called: Addr = '%s', Size = %d\n", Addr, Size);
return 0;
}
-time_t rar_time_to_unix(unsigned int FileTime)
+static time_t
+rar_time_to_unix (unsigned int FileTime)
{
struct tm t;
t.tm_sec = (FileTime & 0x1f) * 2;
@@ -303,146 +314,155 @@ time_t rar_time_to_unix(unsigned int FileTime)
t.tm_year = (FileTime >> 25) + 80;
t.tm_isdst = -1;
// printf("date: %d-%.2d-%.2d %d:%.2d:%.2d \n", t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
- return(mktime(&t));
+ return (mktime(&t));
}
-TVFSResult VFSOpenArchive(struct TVFSGlobs *globs, char *sName)
+/* ----------------------------------------------------------------------------------------------------------- */
+
+TVFSResult
+VFSOpenArchive (struct TVFSGlobs *globs, const char *sName)
{
- TVFSResult Result = cVFS_OK;
+ TVFSResult Result;
+ HANDLE PASCAL handle;
+ struct RAROpenArchiveDataEx *archive_data;
- globs->files = filelist_tree_new();
- globs->vfs_filelist = vfs_filelist_new(globs->files);
+ Result = cVFS_OK;
+
+ globs->files = filelist_tree_new ();
+ globs->vfs_filelist = vfs_filelist_new (globs->files);
globs->curr_dir = NULL;
- globs->archive_path = strdup(sName);
+ globs->archive_path = g_strdup (sName);
globs->total_size = 0;
globs->failed_passwd_callback = FALSE;
globs->volume_missing_abort = FALSE;
- fprintf(stderr, "(--) VFSOpenArchive: trying to open archive '%s'...\n", globs->archive_path);
-
- HANDLE PASCAL handle;
- struct RAROpenArchiveDataEx *archive_data;
+ fprintf (stderr, "(--) VFSOpenArchive: trying to open archive '%s'...\n", globs->archive_path);
- archive_data = (struct RAROpenArchiveDataEx*) malloc(sizeof(struct RAROpenArchiveDataEx));
- memset(archive_data, 0, sizeof(struct RAROpenArchiveDataEx));
+ /* WARNING: do not use g_malloc0() here, leads to memory corruption */
+ archive_data = malloc (sizeof (struct RAROpenArchiveDataEx));
+ memset (archive_data, 0, sizeof (struct RAROpenArchiveDataEx));
archive_data->ArcName = globs->archive_path;
archive_data->CmtBuf = NULL;
archive_data->CmtBufSize = 0;
archive_data->OpenMode = RAR_OM_LIST;
- handle = RAROpenArchiveEx(archive_data);
+ handle = RAROpenArchiveEx (archive_data);
// printf(" handle = %lu \n", (unsigned long int)handle);
// printf(" archive_data->OpenResult = %d \n", archive_data->OpenResult);
// printf(" archive_data->CmtState = %d \n", archive_data->CmtState);
// printf(" archive_data->CmtSize = %d \n", archive_data->CmtSize);
- if ((handle) && (! archive_data->OpenResult))
- {
- // Set callbacks
- RARSetCallback(handle, unrar_callback, (LONG)globs);
-// RARSetChangeVolProc(handle, unrar_changevol_proc);
-// RARSetProcessDataProc(handle, unrar_process_data_proc);
-
- if (globs->password) {
- fprintf(stderr, "(II) VFSOpenArchive: Setting password... \n");
- RARSetPassword(handle, globs->password);
- }
-
- struct RARHeaderDataEx *header;
- header = (struct RARHeaderDataEx*) malloc(sizeof(struct RARHeaderDataEx));
- memset(header, 0, sizeof(struct RARHeaderDataEx));
- header->CmtBuf = NULL;
- header->CmtBufSize = 0;
-
- int PASCAL res = 0;
- while ((res = RARReadHeaderEx(handle, header)) == 0)
- {
-// printf(" header->FileName = '%s', Flags = 0x%x\n", header->FileName, header->Flags);
-
- // Create a TVFSItem entry and fill all info
- struct TVFSItem *item = (struct TVFSItem*)malloc(sizeof(struct TVFSItem));
- memset(item, 0, sizeof(struct TVFSItem));
-
- item->iSize = (int64_t)((int64_t)(header->UnpSizeHigh * 0x100000000) + (int64_t)header->UnpSize);
- item->iPackedSize = (int64_t)((int64_t)(header->PackSizeHigh * 0x100000000) + (int64_t)header->PackSize);
- globs->total_size += item->iSize;
- if ((header->Flags & 0x00e0 /* LHD_WINDOWMASK */ ) == 0x00e0 /* LHD_DIRECTORY */)
- item->ItemType = vDirectory;
- else item->ItemType = vRegular;
- if ((header->Flags & 0x0004) == 0x0004) globs->need_password = TRUE;
-
- switch (header->HostOS)
- {
- case HOST_MSDOS:
- case HOST_OS2:
- case HOST_WIN32:
- if (header->FileAttr & 0x10) header->FileAttr = 0x41ff | header->FileAttr;
- else
- if (header->FileAttr & 1) header->FileAttr = 0x8124 | header->FileAttr;
- else header->FileAttr = 0x81b6 | header->FileAttr;
- break;
- }
-
- item->iMode = header->FileAttr;
- item->iUID = geteuid();
- item->iGID = getegid();
- item->m_time = rar_time_to_unix(header->FileTime);
- item->c_time = item->m_time;
- item->a_time = item->m_time;
-
-// g_print (" valid = %d\n", g_utf8_validate (header->FileName, -1, NULL));
-
- char *s;
- if (g_utf8_validate (header->FileName, -1, NULL))
- s = g_strdup (header->FileName);
- else
- s = wide_to_utf8 (header->FileNameW);
-// g_print (" ansi = '%s'\n wide = '%ls'\n utf8 = '%s'\n", header->FileName, header->FileNameW, s);
-
- // Add item to the global list and continue with next file
- filelist_tree_add_item(globs->files, s, header->FileName, item, 0);
- g_free (s);
-
- int PASCAL res2 = RARProcessFile(handle, RAR_SKIP, NULL, NULL);
- if (res2) printf("RARProcessFile result = %d\n", res2);
- }
-// printf("\nRARReadHeader result = %d\n", res);
- if (res != ERAR_END_ARCHIVE || globs->volume_missing_abort) {
- fprintf(stderr, "(EE) VFSOpenArchive: RARReadHeader result = %d\n", res);
- Result = cVFS_Failed;
- if ((res == ERAR_MISSING_PASSWORD) || ((res == ERAR_BAD_DATA) && (globs->failed_passwd_callback)))
- Result = cVFS_BadPassword;
- }
- free(header);
-
- res = RARCloseArchive(handle);
- if (res) {
- fprintf(stderr, "(EE) VFSOpenArchive: RARCloseArchive result = %d\n", res);
- }
+ if (handle && ! archive_data->OpenResult) {
+ // Set callbacks
+ RARSetCallback (handle, unrar_callback, (LONG)globs);
+// RARSetChangeVolProc(handle, unrar_changevol_proc);
+// RARSetProcessDataProc(handle, unrar_process_data_proc);
+
+ if (globs->password) {
+ fprintf (stderr, "(II) VFSOpenArchive: Setting password... \n");
+ RARSetPassword (handle, globs->password);
+ }
+
+ struct RARHeaderDataEx *header;
+ /* WARNING: do not use g_malloc0() here, leads to memory corruption */
+ header = malloc (sizeof (struct RARHeaderDataEx));
+ memset (header, 0, sizeof (struct RARHeaderDataEx));
+
+ int PASCAL res = 0;
+ while ((res = RARReadHeaderEx(handle, header)) == 0) {
+// printf(" header->FileName = '%s', Flags = 0x%x\n", header->FileName, header->Flags);
+
+ /* Create a TVFSItem entry and fill all info */
+ struct TVFSItem *item = g_malloc0 (sizeof (struct TVFSItem));
+
+ item->iSize = (guint64)((guint64)(header->UnpSizeHigh * 0x100000000) + (guint64)header->UnpSize);
+ item->iPackedSize = (guint64)((guint64)(header->PackSizeHigh * 0x100000000) + (guint64)header->PackSize);
+ globs->total_size += item->iSize;
+ if ((header->Flags & 0x00e0 /* LHD_WINDOWMASK */ ) == 0x00e0 /* LHD_DIRECTORY */)
+ item->ItemType = vDirectory;
+ else
+ item->ItemType = vRegular;
+ if ((header->Flags & 0x0004) == 0x0004)
+ globs->need_password = TRUE;
+
+ switch (header->HostOS) {
+ case HOST_MSDOS:
+ case HOST_OS2:
+ case HOST_WIN32:
+ if (header->FileAttr & 0x10)
+ header->FileAttr = 0x41ff | header->FileAttr;
+ else
+ if (header->FileAttr & 1)
+ header->FileAttr = 0x8124 | header->FileAttr;
+ else
+ header->FileAttr = 0x81b6 | header->FileAttr;
+ break;
+ }
+
+ item->iMode = header->FileAttr;
+ item->iUID = geteuid ();
+ item->iGID = getegid ();
+ item->m_time = rar_time_to_unix (header->FileTime);
+ item->c_time = item->m_time;
+ item->a_time = item->m_time;
+
+// g_print (" valid = %d\n", g_utf8_validate (header->FileName, -1, NULL));
+
+ char *s;
+ if (g_utf8_validate (header->FileName, -1, NULL))
+ s = g_strdup (header->FileName);
+ else
+ s = wide_to_utf8 (header->FileNameW);
+// g_print (" ansi = '%s'\n wide = '%ls'\n utf8 = '%s'\n", header->FileName, header->FileNameW, s);
+
+ // Add item to the global list and continue with next file
+ filelist_tree_add_item (globs->files, s, item, header->FileName, 0);
+ g_free (s);
+
+ int PASCAL res2 = RARProcessFile (handle, RAR_SKIP, NULL, NULL);
+ if (res2)
+ printf ("RARProcessFile result = %d\n", res2);
+ }
+// printf("\nRARReadHeader result = %d\n", res);
+ if (res != ERAR_END_ARCHIVE || globs->volume_missing_abort) {
+ fprintf (stderr, "(EE) VFSOpenArchive: RARReadHeader result = %d\n", res);
+ Result = cVFS_Failed;
+ if (res == ERAR_MISSING_PASSWORD || (res == ERAR_BAD_DATA && globs->failed_passwd_callback))
+ Result = cVFS_BadPassword;
+ }
+ free (header);
+
+ res = RARCloseArchive(handle);
+ if (res)
+ fprintf (stderr, "(EE) VFSOpenArchive: RARCloseArchive result = %d\n", res);
} else {
- fprintf(stderr, "(EE) VFSOpenArchive: error occured when opening archive: OpenResult = %d\n", archive_data->OpenResult);
- Result = cVFS_Failed;
+ fprintf (stderr, "(EE) VFSOpenArchive: error occured when opening archive: OpenResult = %d\n", archive_data->OpenResult);
+ Result = cVFS_Failed;
}
- free(archive_data);
- fprintf(stderr, "(II) VFSOpenArchive: done. \n");
- if (globs->need_password) printf("Password present.\n");
- printf("\n\nList of items:\n");
- filelist_tree_print(globs->files);
+ free (archive_data);
+ fprintf (stderr, "(II) VFSOpenArchive: done. \n");
+ if (globs->need_password)
+ printf ("Password present.\n");
+ printf ("\n\nList of items:\n");
+ filelist_tree_print (globs->files);
return Result;
}
-TVFSResult VFSClose(struct TVFSGlobs *globs)
+TVFSResult
+VFSClose (struct TVFSGlobs *globs)
{
if (globs) {
- fprintf(stderr, "(II) VFSClose: Freeing objects...\n");
- if (globs->vfs_filelist) vfs_filelist_free(globs->vfs_filelist);
- if (globs->files) filelist_tree_free(globs->files);
- if (globs->archive_path) free(globs->archive_path);
- if (globs->curr_dir) free(globs->curr_dir);
- if (globs->password) free(globs->password);
+ fprintf (stderr, "(II) VFSClose: Freeing objects...\n");
+ if (globs->vfs_filelist)
+ vfs_filelist_free(globs->vfs_filelist);
+ if (globs->files)
+ filelist_tree_free(globs->files);
+ g_free (globs->archive_path);
+ g_free (globs->curr_dir);
+ g_free (globs->password);
}
return cVFS_OK;
}
@@ -453,42 +473,48 @@ VFSGetPath (struct TVFSGlobs *globs)
return include_trailing_path_sep (globs->curr_dir);
}
-u_int64_t VFSGetFileSystemFree(struct TVFSGlobs *globs, char *APath)
+TVFSResult
+VFSGetFileSystemInfo (struct TVFSGlobs *globs, const char *APath, gint64 *FSSize, gint64 *FSFree, char **FSLabel)
{
- return 0;
-}
-
-u_int64_t VFSGetFileSystemSize(struct TVFSGlobs *globs, char *APath)
-{
- return globs->total_size;
+ if (FSSize)
+ *FSSize = globs->total_size;
+ if (FSFree)
+ *FSFree = 0;
+ if (FSLabel)
+ *FSLabel = NULL;
+ return cVFS_OK;
}
-
-
/******************************************************************************************************/
-TVFSResult VFSChangeDir(struct TVFSGlobs *globs, char *NewPath)
+TVFSResult
+VFSChangeDir (struct TVFSGlobs *globs, const char *NewPath)
{
if (NewPath == NULL) {
- printf("(EE) VFSChangeDir: NewPath is NULL!\n");
+ printf ("(EE) VFSChangeDir: NewPath is NULL!\n");
return cVFS_Failed;
}
- globs->curr_dir = vfs_filelist_change_dir(globs->vfs_filelist, NewPath);
- if (globs->curr_dir) return cVFS_OK;
- else return cVFS_Failed;
+ globs->curr_dir = vfs_filelist_change_dir (globs->vfs_filelist, NewPath);
+ if (globs->curr_dir)
+ return cVFS_OK;
+ else
+ return cVFS_Failed;
}
-int VFSGetPasswordRequired(struct TVFSGlobs *globs)
+gboolean
+VFSGetPasswordRequired (struct TVFSGlobs *globs)
{
- if (globs) return globs->need_password;
+ if (globs)
+ return globs->need_password;
return FALSE;
}
-void VFSResetPassword(struct TVFSGlobs *globs)
+void
+VFSResetPassword (struct TVFSGlobs *globs)
{
- if (globs && globs->password) {
+ if (globs) {
g_free (globs->password);
globs->password = NULL;
}
@@ -497,40 +523,41 @@ void VFSResetPassword(struct TVFSGlobs *globs)
/******************************************************************************************************/
-TVFSResult VFSListFirst(struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item)
+TVFSResult
+VFSListFirst (struct TVFSGlobs *globs, const char *sDir, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath)
{
if (sDir == NULL) {
- printf("(EE) VFSListFirst: sDir is NULL!\n");
+ printf ("(EE) VFSListFirst: sDir is NULL!\n");
return cVFS_Failed;
}
printf ("(--) VFSListFirst: Going to list all items in '%s'\n", sDir);
- return vfs_filelist_list_first(globs->vfs_filelist, sDir, Item);
+ return vfs_filelist_list_first (globs->vfs_filelist, sDir, Item, FollowSymlinks, AddFullPath);
}
-TVFSResult VFSListNext(struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item)
+TVFSResult
+VFSListNext (struct TVFSGlobs *globs, struct TVFSItem *Item)
{
- return vfs_filelist_list_next(globs->vfs_filelist, sDir, Item);
+ return vfs_filelist_list_next (globs->vfs_filelist, Item);
}
-TVFSResult VFSListClose(struct TVFSGlobs *globs)
+TVFSResult
+VFSListClose (struct TVFSGlobs *globs)
{
- return vfs_filelist_list_close(globs->vfs_filelist);
+ return vfs_filelist_list_close (globs->vfs_filelist);
}
/******************************************************************************************************/
-long VFSFileExists(struct TVFSGlobs *globs, const char *FileName, const long Use_lstat)
-{
- if (! globs) return FALSE;
- return vfs_filelist_file_exists(globs->vfs_filelist, FileName, Use_lstat);
-}
-TVFSResult VFSFileInfo(struct TVFSGlobs *globs, char *AFileName, struct TVFSItem *Item)
+TVFSResult
+VFSFileInfo (struct TVFSGlobs *globs, const char *AFileName, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath)
{
- printf("(--) VFSFileInfo: requested info for object '%s'\n", AFileName);
- if (!globs) return cVFS_Failed;
- return vfs_filelist_file_info(globs->vfs_filelist, AFileName, Item);
+ printf ("(--) VFSFileInfo: requested info for object '%s'\n", AFileName);
+ if (! globs)
+ return cVFS_Failed;
+
+ return vfs_filelist_file_info (globs->vfs_filelist, AFileName, Item, FollowSymlinks, AddFullPath);
}
@@ -538,16 +565,21 @@ TVFSResult VFSFileInfo(struct TVFSGlobs *globs, char *AFileName, struct TVFSItem
/** Recursive tree size counting */
/************** ****************/
-u_int64_t VFSGetDirSize(struct TVFSGlobs *globs, char *APath)
+guint64
+VFSGetDirSize (struct TVFSGlobs *globs, const char *APath)
{
- if (! globs) return 0;
- return vfs_filelist_get_dir_size(globs->vfs_filelist, APath);
+ if (! globs)
+ return 0;
+
+ return vfs_filelist_get_dir_size (globs->vfs_filelist, APath);
}
-void VFSBreakGetDirSize(struct TVFSGlobs *globs)
+void
+VFSBreakGetDirSize (struct TVFSGlobs *globs)
{
- printf("(WW) VFSBreakGetDirSize: calling break\n");
- if (globs) vfs_filelist_get_dir_size_break(globs->vfs_filelist);
+ printf ("(WW) VFSBreakGetDirSize: calling break\n");
+ if (globs)
+ vfs_filelist_get_dir_size_break (globs->vfs_filelist);
}
@@ -555,45 +587,45 @@ void VFSBreakGetDirSize(struct TVFSGlobs *globs)
/** Methods modifying the archive */
/************** ****************/
-TVFSResult VFSMkDir(struct TVFSGlobs *globs, const char *sDirName)
+TVFSResult VFSMkDir (struct TVFSGlobs *globs, const char *sDirName)
{
- printf("(WW) VFSMkDir: Not supported in UNRAR plugin.\n");
+ printf ("(WW) VFSMkDir: Not supported in UNRAR plugin.\n");
return cVFS_Not_Supported;
}
-TVFSResult VFSRemove(struct TVFSGlobs *globs, const char *APath)
+TVFSResult VFSRemove (struct TVFSGlobs *globs, const char *APath)
{
- printf("(WW) VFSRemove: Not supported in UNRAR plugin.\n");
+ printf ("(WW) VFSRemove: Not supported in UNRAR plugin.\n");
return cVFS_Not_Supported;
}
-TVFSResult VFSRename(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName)
+TVFSResult VFSRename (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName)
{
- printf("(WW) VFSRename: Not supported in UNRAR plugin.\n");
+ printf ("(WW) VFSRename: Not supported in UNRAR plugin.\n");
return cVFS_Not_Supported;
}
-TVFSResult VFSMakeSymLink(struct TVFSGlobs *globs, const char *NewFileName, const char *PointTo)
+TVFSResult VFSMakeSymLink (struct TVFSGlobs *globs, const char *NewFileName, const char *PointTo)
{
- printf("(WW) VFSMakeSymLink: Not supported in UNRAR plugin.\n");
+ printf ("(WW) VFSMakeSymLink: Not supported in UNRAR plugin.\n");
return cVFS_Not_Supported;
}
-TVFSResult VFSChmod(struct TVFSGlobs *globs, const char *FileName, const uint Mode)
+TVFSResult VFSChmod (struct TVFSGlobs *globs, const char *FileName, guint32 Mode)
{
- printf("(WW) VFSChmod: Not supported in UNRAR plugin.\n");
+ printf ("(WW) VFSChmod: Not supported in UNRAR plugin.\n");
return cVFS_Not_Supported;
}
-TVFSResult VFSChown(struct TVFSGlobs *globs, const char *FileName, const uint UID, const uint GID)
+TVFSResult VFSChown (struct TVFSGlobs *globs, const char *FileName, guint32 UID, guint32 GID)
{
- printf("(WW) VFSChown: Not supported in UNRAR plugin.\n");
+ printf ("(WW) VFSChown: Not supported in UNRAR plugin.\n");
return cVFS_Not_Supported;
}
-TVFSResult VFSChangeTimes(struct TVFSGlobs *globs, char *APath, long mtime, long atime)
+TVFSResult VFSChangeTimes (struct TVFSGlobs *globs, const char *APath, guint32 mtime, guint32 atime)
{
- printf("(WW) VFSChangeTimes: Not supported in UNRAR plugin.\n");
+ printf ("(WW) VFSChangeTimes: Not supported in UNRAR plugin.\n");
return cVFS_Not_Supported;
}
@@ -631,21 +663,25 @@ int VFSWriteFile(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, void *Buff
return 0;
}
-void VFSSetBlockSize(struct TVFSGlobs *globs, int Value)
+void
+VFSSetBlockSize (struct TVFSGlobs *globs, guint32 Value)
{
- globs->block_size = Value;
+ if (globs)
+ globs->block_size = Value;
}
-int VFSIsOnSameFS(struct TVFSGlobs *globs, const char *Path1, const char *Path2)
+gboolean
+VFSIsOnSameFS (struct TVFSGlobs *globs, const char *Path1, const char *Path2, gboolean FollowSymlinks)
{
- printf("(WW) VFSIsOnSameFS: Not supported in UNRAR plugin.\n");
+ printf ("(WW) VFSIsOnSameFS: Not supported in UNRAR plugin.\n");
return TRUE;
}
-int VFSTwoSameFiles(struct TVFSGlobs *globs, const char *Path1, const char *Path2)
+gboolean
+VFSTwoSameFiles (struct TVFSGlobs *globs, const char *Path1, const char *Path2, gboolean FollowSymlinks)
{
- printf("(WW) VFSTwoSameFiles: Not supported in RAR archives, comparing by paths.\n");
- return compare_two_same_files(Path1, Path2);
+ printf ("(WW) VFSTwoSameFiles: Not supported in RAR archives, comparing by paths.\n");
+ return compare_two_same_files (Path1, Path2);
}
@@ -653,168 +689,166 @@ int VFSTwoSameFiles(struct TVFSGlobs *globs, const char *Path1, const char *Path
////////////////////////
-TVFSResult VFSCopyToLocal(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, int Append)
+TVFSResult
+VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append)
{
- if ((sSrcName == NULL) || (sDstName == NULL) || (strlen(sSrcName) < 1) || (strlen(sDstName) < 1)) {
- printf("(EE) VFSCopyToLocal: The value of 'sSrcName' or 'sDstName' is NULL or empty\n");
+ struct PathTree *node;
+ TVFSResult Result;
+ gboolean found;
+ char *src;
+
+ if (sSrcName == NULL || sDstName == NULL || strlen (sSrcName) < 1 || strlen (sDstName) < 1) {
+ printf ("(EE) VFSCopyToLocal: The value of 'sSrcName' or 'sDstName' is NULL or empty\n");
return cVFS_Failed;
}
- printf("(II) VFSCopyToLocal: copying file '%s' out to '%s'\n", sSrcName, sDstName);
+ printf ("(II) VFSCopyToLocal: copying file '%s' out to '%s'\n", sSrcName, sDstName);
- struct PathTree *node = filelist_tree_find_node_by_path(globs->files, sSrcName);
+ node = filelist_tree_find_node_by_path (globs->files, sSrcName);
if (! node) {
- fprintf(stderr, "(EE) VFSCopyToLocal: cannot find file '%s'\n", sSrcName);
+ fprintf (stderr, "(EE) VFSCopyToLocal: cannot find file '%s'\n", sSrcName);
return cVFS_ReadErr;
}
- TVFSResult Result = cVFS_OK;
- gboolean found = FALSE;
+ Result = cVFS_OK;
+ found = FALSE;
- char *src = node->original_pathstr;
+ src = node->original_pathstr;
if (! src) {
- fprintf(stderr, "(WW) VFSCopyToLocal: cannot determine original filename\n");
- src = (char *)sSrcName;
+ fprintf (stderr, "(WW) VFSCopyToLocal: cannot determine original filename\n");
+ src = (char *) sSrcName;
}
- printf("(II) VFSCopyToLocal: new src path: '%s'\n", src);
+ printf ("(II) VFSCopyToLocal: new src path: '%s'\n", src);
HANDLE PASCAL handle;
struct RAROpenArchiveDataEx *archive_data;
- archive_data = (struct RAROpenArchiveDataEx*) malloc(sizeof(struct RAROpenArchiveDataEx));
- memset(archive_data, 0, sizeof(struct RAROpenArchiveDataEx));
+ /* WARNING: do not use g_malloc0() here, leads to memory corruption */
+ archive_data = malloc (sizeof (struct RAROpenArchiveDataEx));
+ memset (archive_data, 0, sizeof (struct RAROpenArchiveDataEx));
archive_data->ArcName = globs->archive_path;
- archive_data->CmtBuf = NULL;
- archive_data->CmtBufSize = 0;
archive_data->OpenMode = RAR_OM_EXTRACT;
- handle = RAROpenArchiveEx(archive_data);
+ handle = RAROpenArchiveEx (archive_data);
// printf(" handle = %lu \n", (unsigned long int)handle);
// printf(" archive_data->OpenResult = %d \n", archive_data->OpenResult);
// printf(" archive_data->CmtState = %d \n", archive_data->CmtState);
// printf(" archive_data->CmtSize = %d \n", archive_data->CmtSize);
// printf("sizeof(TVFSResult) = %ld \n", sizeof(TVFSResult));
- if ((handle) && (! archive_data->OpenResult))
+ if (handle && ! archive_data->OpenResult)
{
- // Set callbacks
-// printf(" setting callback: globs = 0x%lX, (unsigned long int)globs = 0x%lX, (LONG)globs = 0x%lX\n", globs, (unsigned long int)globs, (LONG)globs);
- RARSetCallback(handle, unrar_callback, (LONG)globs);
-// RARSetChangeVolProc(handle, unrar_changevol_proc);
-// RARSetProcessDataProc(handle, unrar_process_data_proc);
-
- if (globs->password) {
- printf("(II) VFSCopyToLocal: Setting password... \n");
- RARSetPassword(handle, globs->password);
- }
-
- struct RARHeaderDataEx *header;
- header = (struct RARHeaderDataEx*) malloc(sizeof(struct RARHeaderDataEx));
- memset(header, 0, sizeof(struct RARHeaderDataEx));
- header->CmtBuf = NULL;
- header->CmtBufSize = 0;
-
- int res = 0;
- while ((res = RARReadHeaderEx(handle, header)) == 0)
- {
- char *ssrc = src;
- char *asrc = header->FileName;
- if (IS_DIR_SEP(*ssrc)) ssrc++;
- if (IS_DIR_SEP(*asrc)) asrc++;
- if (strcmp(ssrc, asrc) == 0) {
-// fprintf(stderr, "(II) VFSCopyToLocal: extract_file_path(sDstName) = '%s', extract_file_name(sDstName) = '%s' \n", extract_file_path(sDstName), extract_file_name(sDstName));
- globs->extract_done = 0;
- globs->extract_file_size = (int64_t)((int64_t)(header->UnpSizeHigh * 0x100000000) + (int64_t)header->UnpSize);
- globs->extract_cancelled = FALSE;
- found = TRUE;
-
- int res2 = RARProcessFile(handle, RAR_EXTRACT, NULL, (char *)sDstName);
-
- if (globs->extract_cancelled) {
- fprintf(stderr, "(WW) VFSCopyToLocal: cancelled !\n");
- Result = cVFS_Cancelled;
- }
- else
- if (res2) {
- fprintf(stderr, "(EE) VFSCopyToLocal: RARProcessFile result = %d\n", res2);
- Result = cVFS_ReadErr;
- }
- break;
- } else {
- int res2 = RARProcessFile(handle, RAR_SKIP, NULL, NULL);
- if (res2) {
- fprintf(stderr, "(EE) VFSCopyToLocal: RARProcessFile result = %d\n", res2);
- Result = cVFS_ReadErr;
- }
- }
- }
-
- if ((res != ERAR_END_ARCHIVE) && (res)) {
- if (globs->extract_cancelled) {
- fprintf(stderr, "(WW) VFSCopyToLocal: cancelled !\n");
- Result = cVFS_Cancelled;
- }
- else {
- fprintf(stderr, "(EE) VFSCopyToLocal: RARReadHeader result = %d\n", res);
- switch (res) {
- case ERAR_NO_MEMORY:
- case ERAR_SMALL_BUF:
- Result = cVFS_mallocFailed;
- break;
- case ERAR_BAD_DATA:
- case ERAR_BAD_ARCHIVE:
- case ERAR_UNKNOWN_FORMAT:
- case ERAR_EOPEN:
- case ERAR_ECLOSE:
- case ERAR_EREAD:
- Result = cVFS_ReadErr;
- break;
- case ERAR_ECREATE:
- case ERAR_EWRITE:
- Result = cVFS_WriteErr;
- break;
- case ERAR_MISSING_PASSWORD:
- Result = cVFS_BadPassword;
- if (globs->password) {
- g_free (globs->password);
- globs->password = NULL;
- }
- break;
- case ERAR_UNKNOWN:
- default:
- Result = cVFS_WriteErr;
- break;
- }
- }
- }
-
- free(header);
-
- res = RARCloseArchive(handle);
- if (res) {
- fprintf(stderr, "(EE) VFSCopyToLocal: RARCloseArchive result = %d\n", res);
- Result = cVFS_ReadErr;
- }
+ // Set callbacks
+// printf(" setting callback: globs = 0x%lX, (unsigned long int)globs = 0x%lX, (LONG)globs = 0x%lX\n", globs, (unsigned long int)globs, (LONG)globs);
+ RARSetCallback (handle, unrar_callback, (LONG)globs);
+// RARSetChangeVolProc(handle, unrar_changevol_proc);
+// RARSetProcessDataProc(handle, unrar_process_data_proc);
+
+ if (globs->password) {
+ printf ("(II) VFSCopyToLocal: Setting password... \n");
+ RARSetPassword (handle, globs->password);
+ }
+
+ struct RARHeaderDataEx *header;
+ /* WARNING: do not use g_malloc0() here, leads to memory corruption */
+ header = malloc (sizeof (struct RARHeaderDataEx));
+ memset (header, 0, sizeof (struct RARHeaderDataEx));
+
+ int res = 0;
+ while ((res = RARReadHeaderEx(handle, header)) == 0) {
+ if (g_strcmp0 (src, header->FileName) == 0) {
+// fprintf(stderr, "(II) VFSCopyToLocal: extract_file_path(sDstName) = '%s', extract_file_name(sDstName) = '%s' \n", extract_file_path(sDstName), extract_file_name(sDstName));
+ globs->extract_done = 0;
+ globs->extract_file_size = (guint64)((guint64)(header->UnpSizeHigh * 0x100000000) + (guint64)header->UnpSize);
+ globs->extract_cancelled = FALSE;
+ found = TRUE;
+
+ int res2 = RARProcessFile (handle, RAR_EXTRACT, NULL, (char *)sDstName);
+
+ if (globs->extract_cancelled) {
+ fprintf (stderr, "(WW) VFSCopyToLocal: cancelled !\n");
+ Result = cVFS_Cancelled;
+ }
+ else
+ if (res2) {
+ fprintf (stderr, "(EE) VFSCopyToLocal: RARProcessFile result = %d\n", res2);
+ Result = cVFS_ReadErr;
+ }
+ break;
+ } else {
+ int res2 = RARProcessFile (handle, RAR_SKIP, NULL, NULL);
+ if (res2) {
+ fprintf (stderr, "(EE) VFSCopyToLocal: RARProcessFile result = %d\n", res2);
+ Result = cVFS_ReadErr;
+ }
+ }
+ }
+
+ if (res != ERAR_END_ARCHIVE && res) {
+ if (globs->extract_cancelled) {
+ fprintf (stderr, "(WW) VFSCopyToLocal: cancelled !\n");
+ Result = cVFS_Cancelled;
+ }
+ else {
+ fprintf (stderr, "(EE) VFSCopyToLocal: RARReadHeader result = %d\n", res);
+ switch (res) {
+ case ERAR_NO_MEMORY:
+ case ERAR_SMALL_BUF:
+ Result = cVFS_mallocFailed;
+ break;
+ case ERAR_BAD_DATA:
+ case ERAR_BAD_ARCHIVE:
+ case ERAR_UNKNOWN_FORMAT:
+ case ERAR_EOPEN:
+ case ERAR_ECLOSE:
+ case ERAR_EREAD:
+ Result = cVFS_ReadErr;
+ break;
+ case ERAR_ECREATE:
+ case ERAR_EWRITE:
+ Result = cVFS_WriteErr;
+ break;
+ case ERAR_MISSING_PASSWORD:
+ Result = cVFS_BadPassword;
+ g_free (globs->password);
+ globs->password = NULL;
+ break;
+ case ERAR_UNKNOWN:
+ default:
+ Result = cVFS_WriteErr;
+ break;
+ }
+ }
+ }
+
+ free (header);
+
+ res = RARCloseArchive (handle);
+ if (res) {
+ fprintf (stderr, "(EE) VFSCopyToLocal: RARCloseArchive result = %d\n", res);
+ Result = cVFS_ReadErr;
+ }
} else {
- fprintf(stderr, "(EE) VFSCopyToLocal: error occured when opening archive: OpenResult = %d\n", archive_data->OpenResult);
- Result = cVFS_ReadErr;
+ fprintf (stderr, "(EE) VFSCopyToLocal: error occured when opening archive: OpenResult = %d\n", archive_data->OpenResult);
+ Result = cVFS_ReadErr;
}
- free(archive_data);
+ free (archive_data);
- if ((! found) && Result == cVFS_OK) {
- fprintf(stderr, "(EE) VFSCopyToLocal: file not found in archive.\n");
+ if (! found && Result == cVFS_OK) {
+ fprintf (stderr, "(EE) VFSCopyToLocal: file not found in archive.\n");
Result = cVFS_ReadErr;
}
- fprintf(stderr, "(II) VFSCopyToLocal: finished. \n");
+ fprintf (stderr, "(II) VFSCopyToLocal: finished. \n");
return Result;
}
-TVFSResult VFSCopyFromLocal(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, int Append)
+TVFSResult
+VFSCopyFromLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append)
{
- printf("(WW) VFSCopyFromLocal: Not supported in UNRAR plugin.\n");
+ printf ("(WW) VFSCopyFromLocal: Not supported in UNRAR plugin.\n");
return cVFS_Not_Supported;
}
@@ -824,7 +858,7 @@ TVFSResult VFSCopyFromLocal(struct TVFSGlobs *globs, const char *sSrcName, const
/**********
* TODO:
*
- * - UTF-8, FName/FDisplayName and absolute/relative paths revision needed!
+ * DONE - UTF-8, FName/FDisplayName and absolute/relative paths revision needed!
* - find a reliable way to catch bad password errors and free the cached invalid password
* - no error reporting when archive is corrupted -- hopefully fixed by ask_question callback
* - archive testing (needs new VFS API)
diff --git a/unrar/vfs_types.h b/unrar/vfs_types.h
deleted file mode 120000
index c2235a2..0000000
--- a/unrar/vfs_types.h
+++ /dev/null
@@ -1 +0,0 @@
-../common/vfs_types.h \ No newline at end of file
diff --git a/zip/Makefile b/zip/Makefile
index 15e4f11..59a2534 100644
--- a/zip/Makefile
+++ b/zip/Makefile
@@ -1,29 +1,29 @@
# path definitions
DESTDIR = /usr
-INSTALL=install -c
+INSTALL = install -c
INSTALL_DATA = ${INSTALL} -m 644
DIR_ZIPARCHIVE = ./ZipArchive/
# compiler options
CC = gcc
CPP = g++
-CFLAGS =-I. -I$(DIR_ZIPARCHIVE) -I/usr/include \
- -Wall -fPIC -O2 -g \
- -DG_DISABLE_DEPRECATED -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE \
- -D__VERBOSE_DEBUGx
+CFLAGS = -I. -I$(DIR_ZIPARCHIVE) -I/usr/include \
+ -Wall -fPIC -O2 -g \
+ -DG_DISABLE_DEPRECATED -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE \
+ -D__VERBOSE_DEBUGx
-LIB_SUFFIX=`if test \`uname -m\` = x86_64 -o \`uname -m\` = ppc64; then echo 64; fi`
+LIB_SUFFIX = `if test \`uname -m\` = x86_64 -o \`uname -m\` = ppc64; then echo 64; fi`
-VFS_COMMON_OBJECTS=strutils.o treepathutils.o treepath_vfs.o vfsutils.o
+VFS_COMMON_OBJECTS = filelist.o filelist-vfs-intf.o strutils.o vfsutils.o
-VFS_C_OBJECTS=
-VFS_CPP_OBJECTS=zip.o
+VFS_C_OBJECTS =
+VFS_CPP_OBJECTS = zip.o
.SUFFIXES: .c .cpp
.c.o:
- $(CPP) $(CFLAGS) `pkg-config glib-2.0 --cflags` -c $<
+ $(CC) $(CFLAGS) `pkg-config glib-2.0 --cflags` -c $<
.cpp.o:
$(CPP) $(CFLAGS) `pkg-config glib-2.0 --cflags` -c $<
@@ -36,10 +36,10 @@ libzip_plugin.so: ziparchive $(VFS_COMMON_OBJECTS) $(VFS_CPP_OBJECTS) $(VFS_C_OB
ziparchive:
( cd $(DIR_ZIPARCHIVE) && make -f ../Makefile.ziparch ) || exit 1
-strutils.o: strutils.c strutils.h
-treepathutils.o: treepathutils.c treepathutils.h
-vfsutils.o: vfsutils.c vfsutils.h
-treepath_vfs.o: treepath_vfs.c treepath_vfs.h
+filelist.o: filelist.h filelist.c
+filelist-vfs-intf.o: filelist-vfs-intf.h filelist-vfs-intf.c
+strutils.o: strutils.h strutils.c
+vfsutils.o: vfsutils.h vfsutils.c
install::
diff --git a/zip/filelist-vfs-intf.c b/zip/filelist-vfs-intf.c
new file mode 120000
index 0000000..68d7a7c
--- /dev/null
+++ b/zip/filelist-vfs-intf.c
@@ -0,0 +1 @@
+../common/filelist-vfs-intf.c \ No newline at end of file
diff --git a/zip/filelist-vfs-intf.h b/zip/filelist-vfs-intf.h
new file mode 120000
index 0000000..f7afe49
--- /dev/null
+++ b/zip/filelist-vfs-intf.h
@@ -0,0 +1 @@
+../common/filelist-vfs-intf.h \ No newline at end of file
diff --git a/zip/filelist.c b/zip/filelist.c
new file mode 120000
index 0000000..9504563
--- /dev/null
+++ b/zip/filelist.c
@@ -0,0 +1 @@
+../common/filelist.c \ No newline at end of file
diff --git a/zip/filelist.h b/zip/filelist.h
new file mode 120000
index 0000000..90a52e1
--- /dev/null
+++ b/zip/filelist.h
@@ -0,0 +1 @@
+../common/filelist.h \ No newline at end of file
diff --git a/zip/treepath_vfs.c b/zip/treepath_vfs.c
deleted file mode 120000
index f4b41b3..0000000
--- a/zip/treepath_vfs.c
+++ /dev/null
@@ -1 +0,0 @@
-../common/treepath_vfs.c \ No newline at end of file
diff --git a/zip/treepath_vfs.h b/zip/treepath_vfs.h
deleted file mode 120000
index a1e19e7..0000000
--- a/zip/treepath_vfs.h
+++ /dev/null
@@ -1 +0,0 @@
-../common/treepath_vfs.h \ No newline at end of file
diff --git a/zip/treepathutils.c b/zip/treepathutils.c
deleted file mode 120000
index ae760bc..0000000
--- a/zip/treepathutils.c
+++ /dev/null
@@ -1 +0,0 @@
-../common/treepathutils.c \ No newline at end of file
diff --git a/zip/treepathutils.h b/zip/treepathutils.h
deleted file mode 120000
index 4e3c904..0000000
--- a/zip/treepathutils.h
+++ /dev/null
@@ -1 +0,0 @@
-../common/treepathutils.h \ No newline at end of file
diff --git a/zip/tuxcmd-vfs.h b/zip/tuxcmd-vfs.h
new file mode 120000
index 0000000..b7f193e
--- /dev/null
+++ b/zip/tuxcmd-vfs.h
@@ -0,0 +1 @@
+../common/tuxcmd-vfs.h \ No newline at end of file
diff --git a/zip/vfs_types.h b/zip/vfs_types.h
deleted file mode 120000
index c2235a2..0000000
--- a/zip/vfs_types.h
+++ /dev/null
@@ -1 +0,0 @@
-../common/vfs_types.h \ No newline at end of file
diff --git a/zip/zip.cpp b/zip/zip.cpp
index 8998d8b..0432b6f 100644
--- a/zip/zip.cpp
+++ b/zip/zip.cpp
@@ -1,6 +1,6 @@
/* ZIP plugin for Tux Commander
- * version 0.5.6, designed for ZipArchive v3.2.0
- * Copyright (C) 2008 Tomas Bzatek <tbzatek@users.sourceforge.net>
+ * version 0.6.0, designed for ZipArchive v3.2.0
+ * Copyright (C) 2004-2009 Tomas Bzatek <tbzatek@users.sourceforge.net>
* Check for updates on tuxcmd.sourceforge.net
*
* Uses ZipArchive library
@@ -35,11 +35,11 @@
#include <unistd.h>
#include <glib.h>
-#include "vfs_types.h"
+#include "tuxcmd-vfs.h"
#include "strutils.h"
#include "vfsutils.h"
-#include "treepathutils.h"
-#include "treepath_vfs.h"
+#include "filelist.h"
+#include "filelist-vfs-intf.h"
#include "ZipArchive.h"
#include "ZipPlatform.h"
@@ -47,8 +47,8 @@
-#define VERSION "0.5.6"
-#define BUILD_DATE "2009-10-25"
+#define VERSION "0.6.0"
+#define BUILD_DATE "2009-11-28"
#define DEFAULT_BLOCK_SIZE 65536
@@ -60,7 +60,8 @@ extern "C" {
/** Utilities */
/************** ****************/
-TVFSResult get_vfs_errorcode(int m_iCause)
+static TVFSResult
+get_vfs_errorcode (int m_iCause)
{
switch (m_iCause) {
case 13: return cVFS_WriteErr; // Permission denied
@@ -132,9 +133,9 @@ struct TVFSGlobs {
CZipArchive *zip;
CVFSZipActionCallback *extract_callback;
- bool archive_opened;
- unsigned long block_size;
- bool archive_modified;
+ gboolean archive_opened;
+ guint32 block_size;
+ gboolean archive_modified;
struct PathTree *files;
struct VfsFilelistData *vfs_filelist;
@@ -159,7 +160,7 @@ struct ZIP_API CVFSZipActionCallback : public CZipActionCallback
virtual bool Callback(ZIP_SIZE_TYPE uProgress)
{
- fprintf(stderr, "(II) Callback called, position = %lu; m_uTotalToProcess = %lu; m_uProcessed = %lu\n",
+ fprintf (stderr, "(II) Callback called, position = %lu; m_uTotalToProcess = %lu; m_uProcessed = %lu\n",
uProgress, m_uTotalToProcess, m_uProcessed);
bool ret = true;
try {
@@ -167,7 +168,7 @@ struct ZIP_API CVFSZipActionCallback : public CZipActionCallback
ret = globs->callback_progress (m_uProcessed, m_uTotalToProcess, globs->callback_data);
}
catch (...) {
- fprintf(stderr, "(EE) extract_callback: Fatal error occured when calling pCallBackProgress\n");
+ fprintf (stderr, "(EE) extract_callback: Fatal error occured when calling pCallBackProgress\n");
}
return ret;
}
@@ -180,60 +181,69 @@ struct ZIP_API CVFSZipActionCallback : public CZipActionCallback
* Internal tree functions
********/
-void build_global_filelist(struct TVFSGlobs *globs)
+static void
+build_global_filelist (struct TVFSGlobs *globs)
{
- int iCount = globs->zip->GetCount();
- // Ensure the filelist is freed
- if (globs->files) filelist_tree_free(globs->files);
+ int iCount;
+ int i;
+ CZipFileHeader *fh;
+ struct TVFSItem *item;
+ char *s;
+
+ /* Ensure the filelist is freed */
+ if (globs->vfs_filelist)
+ vfs_filelist_free (globs->vfs_filelist);
+ if (globs->files)
+ filelist_tree_free (globs->files);
globs->files = filelist_tree_new();
- vfs_filelist_set_files(globs->vfs_filelist, globs->files);
+ globs->vfs_filelist = vfs_filelist_new (globs->files);
- // list files in archive
- for (int i = 0; i < iCount; i++) {
- CZipFileHeader *fh = globs->zip->GetFileInfo(i);
+ iCount = globs->zip->GetCount();
+ /* list files in the archive */
+ for (i = 0; i < iCount; i++) {
+ fh = globs->zip->GetFileInfo (i);
if (fh != NULL)
printf(" No: %i, '%s', IsDir: %i, Size: %lu, SystemAttr = 0x%lX, OriginalAttr = 0x%lX, encrypted = %d\n",
i, (LPCTSTR)fh->GetFileName(), fh->IsDirectory(), fh->m_uUncomprSize, fh->GetSystemAttr(), fh->GetOriginalAttributes(), fh->IsEncrypted());
}
printf("\n\n");
- for (int i = 0; i < iCount; i++) {
- CZipFileHeader *fh = globs->zip->GetFileInfo(i);
+ for (i = 0; i < iCount; i++) {
+ fh = globs->zip->GetFileInfo (i);
if (fh != NULL) {
- // Create a TVFSItem entry and fill all info
- struct TVFSItem *item = (struct TVFSItem*)malloc(sizeof(struct TVFSItem));
- memset(item, 0, sizeof(struct TVFSItem));
-
- item->iSize = (int64_t)fh->m_uUncomprSize;
- item->iPackedSize = (int64_t)fh->m_uComprSize;
- if (fh->IsDirectory())
- item->ItemType = vDirectory;
- else item->ItemType = vRegular;
- item->iMode = fh->GetSystemAttr();
- item->iUID = geteuid();
- item->iGID = getegid();
- item->m_time = (__time_t)fh->GetTime();
- item->c_time = item->m_time;
- item->a_time = item->m_time;
-
- if (fh->IsEncrypted()) globs->need_password = TRUE;
-
- char *s;
-
- s = g_filename_display_name ((LPCTSTR)fh->GetFileName());
-
- // Add item to the global list and continue with next file
- filelist_tree_add_item(globs->files, s, s, item, i + 1);
- g_free (s);
- printf("\n");
+ /* Create a TVFSItem entry and fill all info */
+ item = (struct TVFSItem *) g_malloc0 (sizeof (struct TVFSItem));
+
+ item->iSize = (guint64) fh->m_uUncomprSize;
+ item->iPackedSize = (guint64) fh->m_uComprSize;
+ if (fh->IsDirectory ())
+ item->ItemType = vDirectory;
+ else
+ item->ItemType = vRegular;
+ item->iMode = fh->GetSystemAttr ();
+ item->iUID = geteuid ();
+ item->iGID = getegid ();
+ item->m_time = (__time_t) fh->GetTime ();
+ item->c_time = item->m_time;
+ item->a_time = item->m_time;
+
+ if (fh->IsEncrypted ())
+ globs->need_password = TRUE;
+
+ /* Add item to the global list and continue with next file */
+ s = g_filename_display_name ((LPCTSTR) fh->GetFileName ());
+ filelist_tree_add_item (globs->files, s, item, (LPCTSTR) fh->GetFileName (), i + 1);
+ g_free (s);
+ printf ("\n");
}
}
- if (globs->need_password) printf("Password present.\n");
+ if (globs->need_password)
+ printf ("Password present.\n");
- printf("\n\n\n\nPrinting the contents of the global filelist:\n\n");
- filelist_tree_print(globs->files);
+ printf ("\n\n\n\nPrinting the contents of the global filelist:\n\n");
+ filelist_tree_print (globs->files);
}
@@ -245,12 +255,11 @@ VFSNew (TVFSLogFunc log_func)
{
struct TVFSGlobs * globs;
- globs = (struct TVFSGlobs *) malloc (sizeof (struct TVFSGlobs));
- memset (globs, 0, sizeof (struct TVFSGlobs));
+ globs = (struct TVFSGlobs *) g_malloc0 (sizeof (struct TVFSGlobs));
- globs->archive_opened = false;
+ globs->archive_opened = FALSE;
globs->block_size = DEFAULT_BLOCK_SIZE;
- globs->archive_modified = false;
+ globs->archive_modified = FALSE;
globs->need_password = FALSE;
globs->callback_data = NULL;
@@ -259,7 +268,8 @@ VFSNew (TVFSLogFunc log_func)
globs->callback_progress = NULL;
globs->log_func = log_func;
- if (globs->log_func != NULL) globs->log_func("zip plugin: VFSInit");
+ if (globs->log_func != NULL)
+ globs->log_func ("zip plugin: VFSInit");
return globs;
}
@@ -280,19 +290,23 @@ VFSSetCallbacks (struct TVFSGlobs *globs,
void
VFSFree (struct TVFSGlobs *globs)
{
- if (globs->log_func != NULL) globs->log_func("zip plugin: VFSDestroy");
- free (globs);
+ if (globs->log_func != NULL)
+ globs->log_func ("zip plugin: VFSFree");
+ g_free (globs);
}
-int VFSVersion()
+int
+VFSVersion ()
{
return cVFSVersion;
}
struct TVFSInfo *
-VFSGetInfo()
+VFSGetInfo ()
{
- struct TVFSInfo *module_info = (TVFSInfo*) g_malloc0 (sizeof (struct TVFSInfo));
+ struct TVFSInfo *module_info;
+
+ module_info = (TVFSInfo*) g_malloc0 (sizeof (struct TVFSInfo));
module_info->ID = g_strdup ("zip_plugin");
module_info->Name = g_strdup ("ZIP plugin");
@@ -303,7 +317,7 @@ VFSGetInfo()
}
char *
-VFSGetArchiveExts()
+VFSGetArchiveExts ()
{
return g_strdup ("zip");
}
@@ -312,110 +326,118 @@ VFSGetArchiveExts()
/**************************************************************************************************************************************/
/**************************************************************************************************************************************/
-TVFSResult VFSOpenArchive(struct TVFSGlobs *globs, char *sName)
+TVFSResult
+VFSOpenArchive (struct TVFSGlobs *globs, const char *sName)
{
- // Initialize the objects
+ int iCount;
+
globs->files = NULL;
- globs->vfs_filelist = vfs_filelist_new(NULL);
+ globs->vfs_filelist = NULL;
globs->curr_dir = NULL;
globs->zip = new CZipArchive;
- try
- {
- fprintf(stderr, "(--) VFSOpenArchive: trying to open the file...\n");
+ try {
+ fprintf (stderr, "(--) VFSOpenArchive: trying to open the file...\n");
try {
- if (! globs->zip->Open(sName, CZipArchive::zipOpen, 0)) {
- printf("(EE) VFSOpenArchive: error opening zip archive\n");
- return cVFS_Failed;
+ if (! globs->zip->Open (sName, CZipArchive::zipOpen, 0)) {
+ printf ("(EE) VFSOpenArchive: error opening zip archive\n");
+ return cVFS_Failed;
}
}
catch (...) {
- printf("(!!) VFSOpenArchive: error opening readwrite zip, trying readonly...\n");
+ printf ("(!!) VFSOpenArchive: error opening readwrite zip, trying readonly...\n");
try {
- // try to open in read only mode (required if there's no write access on the media)
- if (! globs->zip->Open(sName, CZipArchive::zipOpenReadOnly, 0)) {
- printf("(EE) VFSOpenArchive: error opening readonly zip archive\n");
+ /* try to open in read only mode (required if there's no write access on the media) */
+ if (! globs->zip->Open (sName, CZipArchive::zipOpenReadOnly, 0)) {
+ printf ("(EE) VFSOpenArchive: error opening readonly zip archive\n");
return cVFS_Failed;
}
}
catch (...) {
- printf("(EE) VFSOpenArchive: error opening readonly zip\n");
+ printf ("(EE) VFSOpenArchive: error opening readonly zip\n");
return cVFS_Failed;
}
}
- int iCount = globs->zip->GetCount(false);
- printf("(II) VFSOpenArchive: %i records found, %i files.\n", iCount, globs->zip->GetCount(true));
- if (iCount < 1) return cVFS_Failed;
+ iCount = globs->zip->GetCount (false);
+ printf ("(II) VFSOpenArchive: %i records found, %i files.\n", iCount, globs->zip->GetCount (true));
+ if (iCount < 1)
+ return cVFS_Failed;
- // Build the global file list
- build_global_filelist(globs);
+ /* build global file list */
+ build_global_filelist (globs);
- // Set the progress callback
+ /* set progress callback */
globs->extract_callback = new CVFSZipActionCallback;
globs->extract_callback->globs = globs;
- globs->zip->SetCallback(globs->extract_callback, CZipActionCallback::cbExtract);
- globs->zip->SetCallback(globs->extract_callback, CZipActionCallback::cbAdd);
+ globs->zip->SetCallback (globs->extract_callback, CZipActionCallback::cbExtract);
+ globs->zip->SetCallback (globs->extract_callback, CZipActionCallback::cbAdd);
- // Set automatic flushing of changes to disk
- globs->zip->SetAutoFlush(true);
+ /* set automatic flushing of changes to disk */
+ globs->zip->SetAutoFlush (true);
}
catch (CZipException e) {
printf ("(EE) VFSOpenArchive: Error while processing archive %s\n%s\n", (LPCTSTR) sName, (LPCTSTR)e.GetErrorDescription());
- if (e.m_szFileName.IsEmpty()) printf("\n");
- else printf("(EE) VFSOpenArchive: Filename in error object: %s\n\n", (LPCTSTR)e.m_szFileName);
- globs->zip->Close(true);
+ if (e.m_szFileName.IsEmpty())
+ printf ("\n");
+ else
+ printf ("(EE) VFSOpenArchive: Filename in error object: %s\n\n", (LPCTSTR)e.m_szFileName);
+ globs->zip->Close (true);
return cVFS_Failed;
}
catch (...) {
printf ("(EE) VFSOpenArchive: Unknown error while processing archive %s\n\n", (LPCTSTR) sName);
- globs->zip->Close(true);
+ globs->zip->Close (true);
return cVFS_Failed;
}
- globs->archive_path = strdup(sName);
- globs->archive_modified = false;
+ globs->archive_path = g_strdup (sName);
+ globs->archive_modified = FALSE;
return cVFS_OK;
}
-TVFSResult VFSClose(struct TVFSGlobs *globs)
+TVFSResult
+VFSClose (struct TVFSGlobs *globs)
{
if (globs) {
- // Closing the archive...
- fprintf(stderr, "(II) VFSClose: Closing the archive...\n");
- try {
- if (globs->archive_modified) globs->zip->Flush();
- globs->zip->Close(CZipArchive::afNoException, false);
- //*** In case of inconsistency, try using afWriteDir value
- // (Use when an exception was thrown. The Close method writes the
- // central directory structure to the archive, so that the archive should be usable.)
- }
- catch (CZipException e) {
- fprintf(stderr, "(EE) VFSClose: Error while closing archive: %s\n", (LPCTSTR)e.GetErrorDescription());
- return cVFS_Failed;
- }
-
-
- // Freeing the ZIP objects...
- fprintf(stderr, "(II) VFSClose: Freeing ZipArchive objects...\n");
- try {
- delete globs->extract_callback;
- delete globs->zip;
- }
- catch (...) {
- fprintf(stderr, "(EE) VFSClose: Error freeing ZipArchive objects\n");
- return cVFS_Failed;
- }
-
- // Freeing the filelist
- fprintf(stderr, "(II) VFSClose: Freeing filelist...\n");
- if (globs->vfs_filelist) vfs_filelist_free(globs->vfs_filelist);
- if (globs->files) filelist_tree_free(globs->files);
-
- // Free the rest...
- free(globs->archive_path);
+ /* close the archive... */
+ fprintf (stderr, "(II) VFSClose: Closing the archive...\n");
+ try {
+ if (globs->archive_modified)
+ globs->zip->Flush ();
+ /* In case of inconsistency, try using afWriteDir value.
+ * (use when an exception was thrown, yhe Close method writes the
+ * central directory structure to the archive, so that the archive should be usable.)
+ */
+ globs->zip->Close (CZipArchive::afNoException, false);
+ }
+ catch (CZipException e) {
+ fprintf (stderr, "(EE) VFSClose: Error while closing archive: %s\n", (LPCTSTR)e.GetErrorDescription());
+ return cVFS_Failed;
+ }
+
+ /* free the ZIP objects... */
+ fprintf (stderr, "(II) VFSClose: Freeing ZipArchive objects...\n");
+ try {
+ delete globs->extract_callback;
+ delete globs->zip;
+ }
+ catch (...) {
+ fprintf (stderr, "(EE) VFSClose: Error freeing ZipArchive objects\n");
+ return cVFS_Failed;
+ }
+
+ /* free the filelist */
+ fprintf (stderr, "(II) VFSClose: Freeing filelist...\n");
+ if (globs->vfs_filelist)
+ vfs_filelist_free (globs->vfs_filelist);
+ if (globs->files)
+ filelist_tree_free (globs->files);
+
+ /* free the rest... */
+ g_free (globs->archive_path);
}
return cVFS_OK;
}
@@ -426,115 +448,108 @@ VFSGetPath (struct TVFSGlobs *globs)
return g_strdup (globs->curr_dir);
}
-u_int64_t VFSGetFileSystemFree(struct TVFSGlobs *globs, char *APath)
+TVFSResult
+VFSGetFileSystemInfo (struct TVFSGlobs *globs, const char *APath, gint64 *FSSize, gint64 *FSFree, char **FSLabel)
{
- return 0;
-}
-
-u_int64_t VFSGetFileSystemSize(struct TVFSGlobs *globs, char *APath)
-{
- return globs->zip->GetOccupiedSpace();
+ if (FSSize)
+ *FSSize = globs->zip->GetOccupiedSpace ();
+ if (FSFree)
+ *FSFree = 0;
+ if (FSLabel)
+ *FSLabel = NULL;
+ return cVFS_OK;
}
-
-
/******************************************************************************************************/
-TVFSResult VFSChangeDir(struct TVFSGlobs *globs, char *NewPath)
+TVFSResult
+VFSChangeDir (struct TVFSGlobs *globs, const char *NewPath)
{
if (NewPath == NULL) {
- printf("(EE) VFSChangeDir: NewPath is NULL!\n");
+ printf ("(EE) VFSChangeDir: NewPath is NULL!\n");
return cVFS_Failed;
}
- globs->curr_dir = vfs_filelist_change_dir(globs->vfs_filelist, NewPath);
- if (globs->curr_dir) return cVFS_OK;
- else return cVFS_Failed;
-}
-
-/*
-int VFSSetPassword(struct TVFSGlobs *globs, char *pass)
-{
- printf ("(II) VFSSetPassword: Going to set the password...\n");
- try {
- globs->zip->SetPassword(pass);
- }
- catch (...)
- {
- printf ("(EE) VFSSetPassword: Changing password failed. Maybe closed archive ?\n");
+ globs->curr_dir = vfs_filelist_change_dir (globs->vfs_filelist, NewPath);
+ if (globs->curr_dir)
+ return cVFS_OK;
+ else
return cVFS_Failed;
- }
- return cVFS_OK;
}
-*/
-int VFSGetPasswordRequired(struct TVFSGlobs *globs)
+gboolean
+VFSGetPasswordRequired (struct TVFSGlobs *globs)
{
- if (globs) return globs->need_password;
+ if (globs)
+ return globs->need_password;
return FALSE;
}
void
-VFSResetPassword(struct TVFSGlobs *globs)
+VFSResetPassword (struct TVFSGlobs *globs)
{
if (globs)
- globs->zip->SetPassword(NULL);
+ globs->zip->SetPassword (NULL);
}
/******************************************************************************************************/
-TVFSResult VFSListFirst(struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item)
+TVFSResult
+VFSListFirst (struct TVFSGlobs *globs, const char *sDir, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath)
{
if (sDir == NULL) {
- printf("(EE) VFSListFirst: sDir is NULL!\n");
+ printf ("(EE) VFSListFirst: sDir is NULL!\n");
return cVFS_Failed;
}
printf ("(--) VFSListFirst: Going to list all items in '%s'\n", sDir);
-
- return vfs_filelist_list_first(globs->vfs_filelist, sDir, Item);
+
+ return vfs_filelist_list_first (globs->vfs_filelist, sDir, Item, FollowSymlinks, AddFullPath);
}
-TVFSResult VFSListNext(struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item)
+TVFSResult
+VFSListNext (struct TVFSGlobs *globs, struct TVFSItem *Item)
{
- return vfs_filelist_list_next(globs->vfs_filelist, sDir, Item);
+ return vfs_filelist_list_next (globs->vfs_filelist, Item);
}
-TVFSResult VFSListClose(struct TVFSGlobs *globs)
+TVFSResult
+VFSListClose (struct TVFSGlobs *globs)
{
- return vfs_filelist_list_close(globs->vfs_filelist);
+ return vfs_filelist_list_close (globs->vfs_filelist);
}
/******************************************************************************************************/
-long VFSFileExists(struct TVFSGlobs *globs, const char *FileName, const long Use_lstat)
-{
- if (! globs) return FALSE;
- return vfs_filelist_file_exists(globs->vfs_filelist, FileName, Use_lstat);
-}
-TVFSResult VFSFileInfo(struct TVFSGlobs *globs, char *AFileName, struct TVFSItem *Item)
+TVFSResult
+VFSFileInfo (struct TVFSGlobs *globs, const char *AFileName, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath)
{
- printf("(--) VFSFileInfo: requested info for object '%s'\n", AFileName);
- if (!globs) return cVFS_Failed;
- return vfs_filelist_file_info(globs->vfs_filelist, AFileName, Item);
+ printf ("(--) VFSFileInfo: requested info for object '%s'\n", AFileName);
+ if (! globs)
+ return cVFS_Failed;
+ return vfs_filelist_file_info (globs->vfs_filelist, AFileName, Item, FollowSymlinks, AddFullPath);
}
/******************************************************************************************************/
/** Recursive tree size counting */
/************** ****************/
-u_int64_t VFSGetDirSize(struct TVFSGlobs *globs, char *APath)
+guint64
+VFSGetDirSize (struct TVFSGlobs *globs, const char *APath)
{
- if (! globs) return 0;
- return vfs_filelist_get_dir_size(globs->vfs_filelist, APath);
+ if (! globs)
+ return 0;
+ return vfs_filelist_get_dir_size (globs->vfs_filelist, APath);
}
-void VFSBreakGetDirSize(struct TVFSGlobs *globs)
+void
+VFSBreakGetDirSize (struct TVFSGlobs *globs)
{
- printf("(WW) VFSBreakGetDirSize: calling break\n");
- if (globs) vfs_filelist_get_dir_size_break(globs->vfs_filelist);
+ printf ("(WW) VFSBreakGetDirSize: calling break\n");
+ if (globs)
+ vfs_filelist_get_dir_size_break (globs->vfs_filelist);
}
@@ -542,133 +557,153 @@ void VFSBreakGetDirSize(struct TVFSGlobs *globs)
/** Methods modifying the archive */
/************** ****************/
-TVFSResult VFSMkDir(struct TVFSGlobs *globs, const char *sDirName)
+TVFSResult
+VFSMkDir (struct TVFSGlobs *globs, const char *sDirName)
{
- if ((sDirName == NULL) || (strlen(sDirName) < 1)) {
- printf("(EE) VFSMkDir: The value of 'sDirName' is NULL or empty\n");
- return cVFS_Failed;
+ CZipFileHeader header;
+ char *s;
+ bool bRet;
+
+ if (sDirName == NULL || strlen (sDirName) < 1) {
+ printf ("(EE) VFSMkDir: The value of 'sDirName' is NULL or empty\n");
+ return cVFS_Failed;
}
- if ((strlen(sDirName) < 1) || (strcmp(sDirName, "/") == 0)) {
- printf("(EE) VFSMkDir: Invalid value '%s' (duplicate root entry?)\n", sDirName);
+ if (strcmp (sDirName, "/") == 0) {
+ printf ("(EE) VFSMkDir: Invalid value '%s' (duplicate root entry?)\n", sDirName);
return cVFS_Failed;
}
printf ("(II) VFSMkDir: Going to create new directory '%s'...\n", sDirName);
try {
- try {
- CZipFileHeader header;
-// globs->zip->SetFileHeaderAttr(header, 0x41ED0010); // alternatively use ZipPlatform::GetDefaultAttributes();
- globs->zip->SetFileHeaderAttr(header, 0x41ED); // alternatively use ZipPlatform::GetDefaultAttributes();
- char *s = exclude_leading_path_sep(sDirName);
+ try {
+// globs->zip->SetFileHeaderAttr (header, 0x41ED0010);
+ globs->zip->SetFileHeaderAttr (header, 0x41ED); /* alternatively use ZipPlatform::GetDefaultAttributes(); */
+ s = exclude_leading_path_sep (sDirName);
header.SetFileName(s);
- free(s);
- header.SetTime(time(NULL));
- bool bRet = globs->zip->OpenNewFile(header, 0, NULL);
- globs->zip->CloseNewFile();
+ g_free (s);
+ header.SetTime (time (NULL));
+ bRet = globs->zip->OpenNewFile (header, 0, NULL);
+ globs->zip->CloseNewFile ();
if (! bRet) {
- printf("(EE) VFSMkDir: Error creating new directory '%s'\n", sDirName);
+ printf ("(EE) VFSMkDir: Error creating new directory '%s'\n", sDirName);
return cVFS_Failed;
}
- globs->archive_modified = true;
- build_global_filelist(globs);
+ globs->archive_modified = TRUE;
+ build_global_filelist (globs);
return cVFS_OK;
- }
+ }
catch (CZipException e) {
- globs->zip->CloseNewFile(true);
- fprintf(stderr, "(EE) VFSMkDir: Error creating new directory '%s': [%d] %s, archive closed = %d.\n",
- sDirName, e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed());
- return get_vfs_errorcode(e.m_iCause);
+ globs->zip->CloseNewFile (true);
+ fprintf (stderr, "(EE) VFSMkDir: Error creating new directory '%s': [%d] %s, archive closed = %d.\n",
+ sDirName, e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed ());
+ return get_vfs_errorcode (e.m_iCause);
}
}
catch (...)
{
- printf("(EE) VFSMkDir: Error creating new directory '%s'\n", sDirName);
+ printf ("(EE) VFSMkDir: Error creating new directory '%s'\n", sDirName);
return cVFS_Failed;
}
}
-TVFSResult VFSRemove(struct TVFSGlobs *globs, const char *APath)
+
+TVFSResult
+VFSRemove (struct TVFSGlobs *globs, const char *APath)
{
- printf("(II) VFSRemove: Going to remove the file '%s'...\n", APath);
+ char *AFile, *AFile1, *AFile2, *AFile3;
+ unsigned long int file_no;
+
+
+ printf ("(II) VFSRemove: Going to remove the file '%s'...\n", APath);
- char *AFile = exclude_trailing_path_sep(APath);
- unsigned long int file_no = filelist_find_index_by_path(globs->files, AFile) - 1;
- free(AFile);
+ AFile = exclude_trailing_path_sep (APath);
+ file_no = filelist_find_original_index_by_path (globs->files, AFile) - 1;
+ g_free (AFile);
if (file_no < 0) {
- printf("(EE) VFSRemove: can't find the file specified: '%s'\n", APath);
+ printf ("(EE) VFSRemove: can't find the file specified: '%s'\n", APath);
return cVFS_Failed;
}
try {
try {
- if (! globs->zip->RemoveFile(file_no)) {
- printf("(EE) VFSRemove: Delete file '%s' failed.\n", APath);
+ if (! globs->zip->RemoveFile (file_no)) {
+ printf ("(EE) VFSRemove: Delete file '%s' failed.\n", APath);
return cVFS_Failed;
}
- build_global_filelist(globs);
- globs->archive_modified = true;
- printf("(II) VFSRemove OK.\n");
+ build_global_filelist (globs);
+ globs->archive_modified = TRUE;
+ printf ("(II) VFSRemove OK.\n");
- // Test for the sparse ZIP central directory
- char *AFile1 = exclude_trailing_path_sep(APath);
- char *AFile2 = g_path_get_dirname(AFile1);
- char *AFile3 = exclude_trailing_path_sep(AFile2);
- if ((strlen(AFile3) > 0) && (strcmp(AFile3, "/") != 0)) {
- printf("(II) VFSRemove: AFile1: '%s', AFile2: '%s', AFile3: '%s'\n", AFile1, AFile2, AFile3);
- file_no = filelist_find_index_by_path(globs->files, AFile2) - 1;
- printf("(II) VFSRemove: deleted: '%s', parent: '%s', file_no = %ld\n", APath, AFile3, file_no);
+ /* If we delete last file from a directory, we should make an empty one.
+ * Some archives store pathnames only with filenames, no separate records for directories.
+ **/
+ AFile1 = exclude_trailing_path_sep (APath);
+ AFile2 = g_path_get_dirname (AFile1);
+ AFile3 = exclude_trailing_path_sep (AFile2);
+ if (strlen (AFile3) > 0 && g_strcmp0 (AFile3, "/") != 0) {
+ printf ("(II) VFSRemove: AFile1: '%s', AFile2: '%s', AFile3: '%s'\n", AFile1, AFile2, AFile3);
+ file_no = filelist_find_original_index_by_path (globs->files, AFile2) - 1;
+ printf ("(II) VFSRemove: deleted: '%s', parent: '%s', file_no = %ld\n", APath, AFile3, file_no);
if (file_no < 0) {
- printf("(WW) VFSRemove: sparse ZIP archive detected, adding empty directory: '%s'\n", AFile3);
- VFSMkDir(globs, AFile3);
+ printf ("(WW) VFSRemove: sparse ZIP archive detected, adding empty directory: '%s'\n", AFile3);
+ VFSMkDir (globs, AFile3);
}
}
- free(AFile1); free(AFile2); free(AFile3);
+ g_free (AFile1);
+ g_free (AFile2);
+ g_free (AFile3);
return cVFS_OK;
}
catch (CZipException e) {
- fprintf(stderr, "(EE) VFSRemove: Delete file '%s' failed: [%d] %s, archive closed = %d.\n",
- APath, e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed());
- return get_vfs_errorcode(e.m_iCause);
+ fprintf (stderr, "(EE) VFSRemove: Delete file '%s' failed: [%d] %s, archive closed = %d.\n",
+ APath, e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed ());
+ return get_vfs_errorcode (e.m_iCause);
}
}
catch (...)
{
- printf("(EE) VFSRemove: Delete file '%s' failed.\n", APath);
+ printf ("(EE) VFSRemove: Delete file '%s' failed.\n", APath);
return cVFS_Failed;
}
}
-TVFSResult VFSRename(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName)
+
+TVFSResult
+VFSRename (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName)
{
+ char *AFile;
+ char *ADestFile;
+ unsigned long int file_no;
+
printf ("(II) VFSRename: Going to rename/move the file '%s' to '%s'...\n", sSrcName, sDstName);
- char *AFile = exclude_trailing_path_sep(sSrcName);
- char *ADestFile = exclude_trailing_path_sep(sDstName);
- unsigned long int file_no = filelist_find_index_by_path(globs->files, AFile) - 1;
- free(AFile);
+ AFile = exclude_trailing_path_sep (sSrcName);
+ ADestFile = exclude_trailing_path_sep (sDstName);
+ file_no = filelist_find_original_index_by_path (globs->files, AFile) - 1;
+ g_free (AFile);
if (file_no < 0) {
- printf("(EE) VFSRename: can't find the file specified: '%s'\n", sSrcName);
+ printf ("(EE) VFSRename: can't find the file specified: '%s'\n", sSrcName);
return cVFS_Failed;
}
try {
try {
- if (! globs->zip->RenameFile(file_no, ADestFile)) {
+ if (! globs->zip->RenameFile (file_no, ADestFile)) {
printf ("(EE) VFSRename: Rename/move file '%s' failed.\n", sSrcName);
return cVFS_Failed;
}
- free(ADestFile);
- build_global_filelist(globs);
- globs->archive_modified = true;
+ g_free (ADestFile);
+ build_global_filelist (globs);
+ globs->archive_modified = TRUE;
return cVFS_OK;
}
catch (CZipException e) {
- fprintf(stderr, "(EE) VFSRename: Rename/move file '%s' failed: [%d] %s, archive closed = %d.\n",
- sSrcName, e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed());
- return get_vfs_errorcode(e.m_iCause);
+ fprintf (stderr, "(EE) VFSRename: Rename/move file '%s' failed: [%d] %s, archive closed = %d.\n",
+ sSrcName, e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed ());
+ return get_vfs_errorcode (e.m_iCause);
}
}
catch (...)
@@ -678,37 +713,45 @@ TVFSResult VFSRename(struct TVFSGlobs *globs, const char *sSrcName, const char *
}
}
-TVFSResult VFSMakeSymLink(struct TVFSGlobs *globs, const char *NewFileName, const char *PointTo)
+
+TVFSResult
+VFSMakeSymLink (struct TVFSGlobs *globs, const char *NewFileName, const char *PointTo)
{
- fprintf(stderr, "(EE) VFSMakeSymLink: Symbolic links not supported in ZIP archives.\n");
+ fprintf (stderr, "(EE) VFSMakeSymLink: Symbolic links not supported in ZIP archives.\n");
return cVFS_Not_Supported;
}
-TVFSResult VFSChmod(struct TVFSGlobs *globs, const char *FileName, const uint Mode)
+
+TVFSResult
+VFSChmod (struct TVFSGlobs *globs, const char *FileName, guint32 Mode)
{
- printf("(II) VFSChmod: Going to change permissions of the file '%s'...\n", FileName);
+ char *AFile;
+ unsigned long int file_no;
+ CZipFileHeader *header;
+
+ printf ("(II) VFSChmod: Going to change permissions of the file '%s'...\n", FileName);
- char *AFile = exclude_trailing_path_sep(FileName);
- unsigned long int file_no = filelist_find_index_by_path(globs->files, AFile) - 1;
- free(AFile);
+ AFile = exclude_trailing_path_sep (FileName);
+ file_no = filelist_find_original_index_by_path (globs->files, AFile) - 1;
+ g_free (AFile);
if (file_no < 0) {
- printf("(EE) VFSChmod: can't find the file specified: '%s'\n", FileName);
+ printf ("(EE) VFSChmod: can't find the file specified: '%s'\n", FileName);
return cVFS_Failed;
}
try {
try {
- // Set system compatibility first
- if (! globs->zip->SetSystemCompatibility(ZipCompatibility::zcUnix)) {
- printf("(EE) VFSChmod: Unable to set system compatibility\n");
+ /* set system compatibility first */
+ if (! globs->zip->SetSystemCompatibility (ZipCompatibility::zcUnix)) {
+ printf ("(EE) VFSChmod: Unable to set system compatibility\n");
}
- // Change the header data
- globs->zip->ReadLocalHeader(file_no);
- CZipFileHeader *header = globs->zip->GetFileInfo(file_no);
+ /* change the header data */
+ globs->zip->ReadLocalHeader (file_no);
+ header = globs->zip->GetFileInfo (file_no);
if (! header) {
- printf("(EE) VFSChmod: Permissions modification of the file '%s' failed: NULL returned by GetFileInfo()\n", FileName);
+ printf ("(EE) VFSChmod: Permissions modification of the file '%s' failed: NULL returned by GetFileInfo()\n", FileName);
return cVFS_Failed;
}
// We need to change only 0xF000FFFF mask
@@ -718,75 +761,82 @@ TVFSResult VFSChmod(struct TVFSGlobs *globs, const char *FileName, const uint Mo
// header->GetSystemAttr(), header->GetSystemAttr() & 0xF000FFFF, Mode & 0xFFF, (header->GetSystemAttr() & 0xF000FFFF) + ((Mode & 0xFFF) << 16));
// globs->zip->SetFileHeaderAttr(*header, (header->GetSystemAttr() & 0xF000FFFF) + ((Mode & 0xFFF) << 16));
- printf("(II) VFSChmod: Current permissions: 0x%lX, stripped: 0x%lX, setting to: 0x%X, modified: 0x%lX\n",
+ printf ("(II) VFSChmod: Current permissions: 0x%lX, stripped: 0x%lX, setting to: 0x%X, modified: 0x%lX\n",
header->GetSystemAttr(), header->GetSystemAttr() & 0xFFFFF000,
Mode & 0xFFF, (header->GetSystemAttr() & 0xFFFFF000) + (Mode & 0xFFF));
- globs->zip->SetFileHeaderAttr(*header, (header->GetSystemAttr() & 0xFFFFF000) + (Mode & 0xFFF));
+ globs->zip->SetFileHeaderAttr (*header, (header->GetSystemAttr() & 0xFFFFF000) + (Mode & 0xFFF));
- // write the local header information
- globs->zip->OverwriteLocalHeader(file_no);
+ /* write local header information */
+ globs->zip->OverwriteLocalHeader (file_no);
-/*
+#if 0
// Re-encrypt the file
if (header->IsEncrypted()) {
printf("(II) VFSChmod: Re-encrypting the file...\n");
if (! globs->zip->EncryptFile(file_no))
printf("(EE) VFSChmod: Unable to encrypt the file\n");
}
-*/
- globs->zip->RemoveCentralDirectoryFromArchive();
- globs->zip->Flush();
+#endif
+ globs->zip->RemoveCentralDirectoryFromArchive ();
+ globs->zip->Flush ();
-
- printf("(II) VFSChmod OK.\n");
- build_global_filelist(globs);
- globs->archive_modified = true;
+ printf ("(II) VFSChmod OK.\n");
+ build_global_filelist (globs);
+ globs->archive_modified = TRUE;
return cVFS_OK;
}
catch (CZipException e) {
- globs->zip->CloseNewFile(true);
- fprintf(stderr, "(EE) VFSChmod: permissions modification of the file '%s' failed: [%d] %s, archive closed = %d.\n",
+ globs->zip->CloseNewFile (true);
+ fprintf (stderr, "(EE) VFSChmod: permissions modification of the file '%s' failed: [%d] %s, archive closed = %d.\n",
FileName, e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed());
- return get_vfs_errorcode(e.m_iCause);
+ return get_vfs_errorcode (e.m_iCause);
}
}
catch (...)
{
- printf("(EE) VFSChmod: permissions modification of the file '%s' failed.\n", FileName);
+ printf ("(EE) VFSChmod: permissions modification of the file '%s' failed.\n", FileName);
return cVFS_Failed;
}
}
-TVFSResult VFSChown(struct TVFSGlobs *globs, const char *FileName, const uint UID, const uint GID)
+
+TVFSResult
+VFSChown (struct TVFSGlobs *globs, const char *FileName, guint32 UID, guint32 GID)
{
- fprintf(stderr, "(EE) VFSChown: Owner changing is not supported in ZIP archives.\n");
+ fprintf (stderr, "(EE) VFSChown: Owner changing is not supported in ZIP archives.\n");
return cVFS_Not_Supported;
}
-TVFSResult VFSChangeTimes(struct TVFSGlobs *globs, char *APath, long mtime, long atime)
+
+TVFSResult
+VFSChangeTimes (struct TVFSGlobs *globs, const char *APath, guint32 mtime, guint32 atime)
{
+ char *AFile;
+ unsigned long int file_no;
+ CZipFileHeader *header;
+
printf ("(II) VFSChangeTimes: Going to change date/times of the file '%s'...\n", APath);
- char *AFile = exclude_trailing_path_sep(APath);
- unsigned long int file_no = filelist_find_index_by_path(globs->files, AFile) - 1;
- free(AFile);
+ AFile = exclude_trailing_path_sep (APath);
+ file_no = filelist_find_original_index_by_path (globs->files, AFile) - 1;
+ g_free (AFile);
if (file_no < 0) {
- printf("(EE) VFSChangeTimes: can't find the file specified: '%s'\n", APath);
+ printf ("(EE) VFSChangeTimes: can't find the file specified: '%s'\n", APath);
return cVFS_Failed;
}
try {
try {
- // read the local header information
- globs->zip->ReadLocalHeader(file_no);
- CZipFileHeader *header = globs->zip->GetFileInfo(file_no);
+ /* read the local header information */
+ globs->zip->ReadLocalHeader (file_no);
+ header = globs->zip->GetFileInfo (file_no);
if (! header) {
- printf("(EE) VFSChangeTimes: DateTime modification of the file '%s' failed: NULL returned by GetFileInfo()\n", APath);
+ printf ("(EE) VFSChangeTimes: DateTime modification of the file '%s' failed: NULL returned by GetFileInfo()\n", APath);
return cVFS_Failed;
}
- // Change the header data
- header->SetTime(mtime);
+ /* change the header data */
+ header->SetTime (mtime);
/* // Re-encrypt the file
if (header->IsEncrypted()) {
@@ -795,25 +845,24 @@ TVFSResult VFSChangeTimes(struct TVFSGlobs *globs, char *APath, long mtime, long
printf("(EE) VFSChangeTimes: Unable to encrypt the file\n");
}
*/
- // write the local header information
- globs->zip->OverwriteLocalHeader(file_no);
- globs->zip->RemoveCentralDirectoryFromArchive();
+ /* write local header information */
+ globs->zip->OverwriteLocalHeader (file_no);
+ globs->zip->RemoveCentralDirectoryFromArchive ();
- printf("(II) VFSChangeTimes OK.\n");
- build_global_filelist(globs);
- globs->archive_modified = true;
+ printf ("(II) VFSChangeTimes OK.\n");
+ build_global_filelist (globs);
+ globs->archive_modified = TRUE;
return cVFS_OK;
}
catch (CZipException e) {
- globs->zip->CloseNewFile(true);
- fprintf(stderr, "(EE) VFSChangeTimes: DateTime modification of the file '%s' failed: [%d] %s, archive closed = %d.\n",
- APath, e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed());
- return get_vfs_errorcode(e.m_iCause);
+ globs->zip->CloseNewFile (true);
+ fprintf (stderr, "(EE) VFSChangeTimes: DateTime modification of the file '%s' failed: [%d] %s, archive closed = %d.\n",
+ APath, e.m_iCause, (LPCTSTR)e.GetErrorDescription (), globs->zip->IsClosed ());
+ return get_vfs_errorcode (e.m_iCause);
}
}
- catch (...)
- {
- printf("(EE) VFSChangeTimes: DateTime modification of the file '%s' failed.\n", APath);
+ catch (...) {
+ printf ("(EE) VFSChangeTimes: DateTime modification of the file '%s' failed.\n", APath);
return cVFS_Failed;
}
}
@@ -852,21 +901,25 @@ int VFSWriteFile(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, void *Buff
return 0;
}
-void VFSSetBlockSize(struct TVFSGlobs *globs, int Value)
+void
+VFSSetBlockSize (struct TVFSGlobs *globs, guint32 Value)
{
- globs->block_size = Value;
+ if (globs)
+ globs->block_size = Value;
}
-int VFSIsOnSameFS(struct TVFSGlobs *globs, const char *Path1, const char *Path2)
+gboolean
+VFSIsOnSameFS (struct TVFSGlobs *globs, const char *Path1, const char *Path2, gboolean FollowSymlinks)
{
- printf("(II) VFSIsOnSameFS: Not supported in ZIP archives.\n");
- return true;
+ printf ("(II) VFSIsOnSameFS: Not supported in ZIP archives.\n");
+ return TRUE;
}
-int VFSTwoSameFiles(struct TVFSGlobs *globs, const char *Path1, const char *Path2)
+gboolean
+VFSTwoSameFiles (struct TVFSGlobs *globs, const char *Path1, const char *Path2, gboolean FollowSymlinks)
{
- printf("(II) VFSTwoSameFiles: Not supported in ZIP archives, comparing by paths.\n");
- return compare_two_same_files(Path1, Path2);
+ printf ("(II) VFSTwoSameFiles: Not supported in ZIP archives, comparing by paths.\n");
+ return compare_two_same_files (Path1, Path2);
}
@@ -874,108 +927,127 @@ int VFSTwoSameFiles(struct TVFSGlobs *globs, const char *Path1, const char *Path
////////////////////////
-// Known issues: - crashes when no space left on NFS mounts, probably unhandled exception in further ZipArchive code (repro: Gentoo, Ubuntu)
-TVFSResult VFSCopyToLocal(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, int Append)
+/* Known issues:
+ * - crashes when no space left on NFS mounts, probably unhandled exception in further ZipArchive code (repro: Gentoo, Ubuntu)
+ *
+ **/
+TVFSResult
+VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append)
{
gboolean try_again;
+ unsigned long int file_no;
+ char *s;
+ char *dest_path;
+ char *dest_filename;
+ char *passwd;
+ int res;
+
- if ((sSrcName == NULL) || (sDstName == NULL) || (strlen(sSrcName) < 1) || (strlen(sDstName) < 1)) {
- printf("(EE) VFSCopyToLocal: The value of 'sSrcName' or 'sDstName' is NULL or empty\n");
+ if (sSrcName == NULL || sDstName == NULL || strlen (sSrcName) < 1 || strlen (sDstName) < 1) {
+ printf ("(EE) VFSCopyToLocal: The value of 'sSrcName' or 'sDstName' is NULL or empty\n");
return cVFS_Failed;
}
- printf("(II) VFSCopyToLocal: copying file '%s' out to '%s'\n", sSrcName, sDstName);
+ printf ("(II) VFSCopyToLocal: copying file '%s' out to '%s'\n", sSrcName, sDstName);
- unsigned long int file_no = filelist_find_index_by_path(globs->files, sSrcName) - 1;
+ file_no = filelist_find_original_index_by_path (globs->files, sSrcName) - 1;
if (file_no < 0) {
- printf("(EE) VFSCopyToLocal: can't find source file '%s'\n", sSrcName);
+ printf ("(EE) VFSCopyToLocal: can't find source file '%s'\n", sSrcName);
return cVFS_ReadErr;
}
- char *s = exclude_trailing_path_sep(sDstName);
- char *dest_path = extract_file_path(s);
- char *dest_filename = extract_file_name(s);
- free(s);
+ s = exclude_trailing_path_sep (sDstName);
+ dest_path = g_path_get_dirname (s);
+ dest_filename = g_path_get_basename (s);
+ g_free (s);
- // Perform extract
+ /* Perform extract */
try {
do {
try {
try_again = FALSE;
- if (! globs->zip->ExtractFile(file_no, dest_path, false, dest_filename, globs->block_size)) {
- globs->zip->CloseFile(NULL, true);
- fprintf(stderr, "(EE) VFSCopyToLocal: Error while copying out, archive closed = %d.\n", globs->zip->IsClosed());
+ if (! globs->zip->ExtractFile (file_no, dest_path, false, dest_filename, globs->block_size)) {
+ globs->zip->CloseFile (NULL, true);
+ fprintf (stderr, "(EE) VFSCopyToLocal: Error while copying out, archive closed = %d.\n", globs->zip->IsClosed ());
return cVFS_WriteErr;
}
- fprintf(stderr, "(II) VFSCopyToLocal: copy OK, archive closed = %d.\n", globs->zip->IsClosed());
+ fprintf (stderr, "(II) VFSCopyToLocal: copy OK, archive closed = %d.\n", globs->zip->IsClosed ());
}
catch (CZipException e) {
- globs->zip->CloseFile(NULL, true);
- fprintf(stderr, "(EE) VFSCopyToLocal: Error while copying out: [%d] %s, archive closed = %d.\n",
- e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed());
+ globs->zip->CloseFile (NULL, true);
+ fprintf (stderr, "(EE) VFSCopyToLocal: Error while copying out: [%d] %s, archive closed = %d.\n",
+ e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed());
switch (e.m_iCause) {
case CZipException::badPassword:
if (globs->callback_ask_password) {
- char *passwd = NULL;
- int res = globs->callback_ask_password ("The archive is encrypted and requires password",
- NULL, NULL, NULL, (TVFSAskPasswordFlags)(VFS_ASK_PASSWORD_NEED_PASSWORD | VFS_ASK_PASSWORD_ARCHIVE_MODE),
- NULL, &passwd, NULL, NULL, NULL,
- globs->callback_data);
+ passwd = NULL;
+ res = globs->callback_ask_password ("The archive is encrypted and requires password",
+ NULL, NULL, NULL, (TVFSAskPasswordFlags)(VFS_ASK_PASSWORD_NEED_PASSWORD | VFS_ASK_PASSWORD_ARCHIVE_MODE),
+ NULL, &passwd, NULL, NULL, NULL,
+ globs->callback_data);
if (res && passwd) {
- fprintf(stderr, " (II) VFSCopyToLocal: setting password to '%s'\n", passwd);
- globs->zip->SetPassword(passwd);
+ fprintf (stderr, " (II) VFSCopyToLocal: setting password to '%s'\n", passwd);
+ globs->zip->SetPassword (passwd);
try_again = TRUE;
break;
} else
return cVFS_Cancelled;
}
default:
- return get_vfs_errorcode(e.m_iCause);
+ return get_vfs_errorcode (e.m_iCause);
}
}
} while (try_again);
}
catch (...)
{
- fprintf(stderr, "(EE) VFSCopyToLocal: Fatal error while copying out..., archive closed = %d.\n", globs->zip->IsClosed());
+ fprintf (stderr, "(EE) VFSCopyToLocal: Fatal error while copying out..., archive closed = %d.\n", globs->zip->IsClosed());
return cVFS_WriteErr;
}
+ g_free (dest_path);
+ g_free (dest_filename);
- free(dest_path);
- free(dest_filename);
return cVFS_OK;
}
-// Known issues: - archive corruption when no space left on device
-// - encrypted files are unreadable after copy in
-TVFSResult VFSCopyFromLocal(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, int Append)
+
+/* Known issues:
+ * - archive corruption when no space left on device
+ * - encrypted files are unreadable after copy in
+ *
+ **/
+TVFSResult
+VFSCopyFromLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append)
{
gboolean try_again;
+ char *s;
+ char *passwd;
+ int res;
- if ((sSrcName == NULL) || (sDstName == NULL) || (strlen(sSrcName) < 1) || (strlen(sDstName) < 1)) {
- printf("(EE) VFSCopyFromLocal: The value of 'sSrcName' or 'sDstName' is NULL or empty\n");
+ if (sSrcName == NULL || sDstName == NULL || strlen (sSrcName) < 1 || strlen (sDstName) < 1) {
+ printf ("(EE) VFSCopyFromLocal: The value of 'sSrcName' or 'sDstName' is NULL or empty\n");
return cVFS_Failed;
}
- printf("(II) VFSCopyFromLocal: copying file '%s' in to '%s'\n", sSrcName, sDstName);
+ printf ("(II) VFSCopyFromLocal: copying file '%s' in to '%s'\n", sSrcName, sDstName);
try {
do {
try {
try_again = FALSE;
- char *s = exclude_leading_path_sep(sDstName);
- if (! globs->zip->AddNewFile(sSrcName, s, -1, CZipArchive::zipsmSafeSmart, globs->block_size)) {
- globs->zip->CloseNewFile(true);
- globs->zip->CloseFile(NULL, true);
- build_global_filelist(globs);
- fprintf(stderr, "(EE) VFSCopyFromLocal: Error while copying in, archive closed = %d.\n", globs->zip->IsClosed());
+ s = exclude_leading_path_sep (sDstName);
+ if (! globs->zip->AddNewFile (sSrcName, s, -1, CZipArchive::zipsmSafeSmart, globs->block_size)) {
+ globs->zip->CloseNewFile (true);
+ globs->zip->CloseFile (NULL, true);
+ build_global_filelist (globs);
+ fprintf (stderr, "(EE) VFSCopyFromLocal: Error while copying in, archive closed = %d.\n", globs->zip->IsClosed ());
return cVFS_WriteErr;
}
- globs->zip->Flush();
- printf("(II) VFSCopyFromLocal: copy OK, archive closed = %d.\n", globs->zip->IsClosed());
- build_global_filelist(globs);
- globs->archive_modified = true;
+ globs->zip->Flush ();
+ printf ("(II) VFSCopyFromLocal: copy OK, archive closed = %d.\n", globs->zip->IsClosed ());
+ build_global_filelist (globs);
+ globs->archive_modified = TRUE;
/*
// Encrypt the file if archive contains any encrypted files
@@ -991,39 +1063,38 @@ TVFSResult VFSCopyFromLocal(struct TVFSGlobs *globs, const char *sSrcName, const
}
*/
- free(s);
+ g_free (s);
}
catch (CZipException e) {
- globs->zip->CloseNewFile(true);
- globs->zip->CloseFile(NULL, true);
- build_global_filelist(globs);
- fprintf(stderr, "(EE) VFSCopyFromLocal: Error while copying in: [%d] %s, archive closed = %d.\n",
- e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed());
+ globs->zip->CloseNewFile (true);
+ globs->zip->CloseFile (NULL, true);
+ build_global_filelist (globs);
+ fprintf (stderr, "(EE) VFSCopyFromLocal: Error while copying in: [%d] %s, archive closed = %d.\n",
+ e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed());
switch (e.m_iCause) {
case CZipException::badPassword:
if (globs->callback_ask_password) {
- char *passwd = NULL;
- int res = globs->callback_ask_password ("The archive is encrypted and requires password",
- NULL, NULL, NULL, (TVFSAskPasswordFlags)(VFS_ASK_PASSWORD_NEED_PASSWORD | VFS_ASK_PASSWORD_ARCHIVE_MODE),
- NULL, &passwd, NULL, NULL, NULL,
- globs->callback_data);
+ passwd = NULL;
+ res = globs->callback_ask_password ("The archive is encrypted and requires password",
+ NULL, NULL, NULL, (TVFSAskPasswordFlags)(VFS_ASK_PASSWORD_NEED_PASSWORD | VFS_ASK_PASSWORD_ARCHIVE_MODE),
+ NULL, &passwd, NULL, NULL, NULL,
+ globs->callback_data);
if (res && passwd) {
- fprintf(stderr, " (II) VFSCopyFromLocal: setting password to '%s'\n", passwd);
- globs->zip->SetPassword(passwd);
+ fprintf (stderr, " (II) VFSCopyFromLocal: setting password to '%s'\n", passwd);
+ globs->zip->SetPassword (passwd);
try_again = TRUE;
break;
} else
return cVFS_Cancelled;
}
default:
- return get_vfs_errorcode(e.m_iCause);
+ return get_vfs_errorcode (e.m_iCause);
}
}
} while (try_again);
}
- catch (...)
- {
- fprintf(stderr, "(EE) VFSCopyFromLocal: Fatal error while copying in..., archive closed = %d.\n", globs->zip->IsClosed());
+ catch (...) {
+ fprintf (stderr, "(EE) VFSCopyFromLocal: Fatal error while copying in..., archive closed = %d.\n", globs->zip->IsClosed());
return cVFS_WriteErr;
}