summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-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
13 files changed, 1038 insertions, 937 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__ */