summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@users.sourceforge.net>2008-06-08 11:04:43 +0200
committerTomas Bzatek <tbzatek@users.sourceforge.net>2008-06-08 11:04:43 +0200
commit16f738ecee689c6feb2acb7e4ef4d9bb4144ae7d (patch)
tree3d22f54f7298f81b18ed66d05a62fa8bfab359ab /common
downloadtuxcmd-modules-0.6.36.tar.xz
Diffstat (limited to 'common')
-rw-r--r--common/strutils.c91
-rw-r--r--common/strutils.h48
-rw-r--r--common/treepath_vfs.c232
-rw-r--r--common/treepath_vfs.h61
-rw-r--r--common/treepathutils.c313
-rw-r--r--common/treepathutils.h53
-rw-r--r--common/vfs_types.h114
-rw-r--r--common/vfsutils.c65
-rw-r--r--common/vfsutils.h39
9 files changed, 1016 insertions, 0 deletions
diff --git a/common/strutils.c b/common/strutils.c
new file mode 100644
index 0000000..3f390d9
--- /dev/null
+++ b/common/strutils.c
@@ -0,0 +1,91 @@
+/* Tux Commandern VFS: String utilities
+ * 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 "strutils.h"
+
+
+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;
+}
+
+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;
+}
+
+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;
+}
+
+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;
+}
+
+
+char* extract_file_name(const char *APath)
+{
+ if (APath == NULL) return NULL;
+// log("xxx = %s\n", (APath + strlen(APath) - 1));
+ 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);
+}
+
+// Extracts file path starting with "/" and ending with "/"
+char* extract_file_path(const char *APath)
+{
+ if (APath == NULL) return NULL;
+// log("xxx = %s\n", (APath + strlen(APath) - 1));
+ 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;
+}
diff --git a/common/strutils.h b/common/strutils.h
new file mode 100644
index 0000000..a301c53
--- /dev/null
+++ b/common/strutils.h
@@ -0,0 +1,48 @@
+/* Tux Commander VFS: String utilities
+ * 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 __STRUTILS_H__
+#define __STRUTILS_H__
+
+
+
+#include <string.h>
+#include <stdlib.h>
+
+
+#ifdef __VERBOSE_DEBUG
+ #define log(msg...) printf(msg)
+#else
+ #define log(msg...) { }
+#endif
+
+#define IS_DIR_SEP(ch) ((ch) == '/')
+
+
+
+// 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);
+
+
+#endif /* __STRUTILS_H__ */
diff --git a/common/treepath_vfs.c b/common/treepath_vfs.c
new file mode 100644
index 0000000..6e6a0a1
--- /dev/null
+++ b/common/treepath_vfs.c
@@ -0,0 +1,232 @@
+/* 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) {
+// printf("internal_get_dir_size: found item '%s', size = %lu \n", n->node, n->data->iSize);
+ Size += n->data->iSize;
+ if ((n->items) && (n->items->len > 0))
+ Size += internal_get_dir_size(data, n);
+ }
+ 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->sFileName = strdup(AFileName);
+ printf("(II) VFSFileInfo: found file: '%s'\n", Item->sFileName);
+ 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->sFileName);
+ 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->sFileName);
+ 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
new file mode 100644
index 0000000..2f78414
--- /dev/null
+++ b/common/treepath_vfs.h
@@ -0,0 +1,61 @@
+/* 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
new file mode 100644
index 0000000..301f173
--- /dev/null
+++ b/common/treepathutils.c
@@ -0,0 +1,313 @@
+/* Tux Commander VFS: String utilities
+ * Copyright (C) 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("/");
+
+ // create placeholder data
+ tree->data = (struct TVFSItem*)malloc(sizeof(struct TVFSItem));
+ memset(tree->data, 0, sizeof(struct TVFSItem));
+ tree->data->sFileName = 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->sFileName) free(tree->data->sFileName);
+ if (tree->data->sLinkTo) free(tree->data->sLinkTo);
+ free(tree->data);
+ }
+ if (tree->node)
+ free(tree->node);
+ 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)
+{
+ 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, struct TVFSItem *item, unsigned long index)
+{
+ 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 (t->data) t->data->sFileName = 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);
+
+ // create placeholder data
+ node->data = (struct TVFSItem*)malloc(sizeof(struct TVFSItem));
+ memset(node->data, 0, sizeof(struct TVFSItem));
+ node->data->sFileName = 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, item, index);
+ }
+
+ free(first_part);
+ free(last_part);
+}
+
+
+gboolean filelist_tree_add_item(struct PathTree *tree, const char *path, 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)) {
+ fprintf(stderr, "filelist_tree_add_item: path '%s' is not a valid path\n", path);
+ return FALSE;
+ }
+
+ // 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);
+
+ struct PathTree* found = filelist_tree_find_node_by_path(tree, p);
+
+ 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->sFileName = strdup(found->node);
+ } else
+ // create new item recursively
+ filelist_tree_add_item_recurr(tree, p, item, index);
+
+ free(p);
+ 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;
+}
+
diff --git a/common/treepathutils.h b/common/treepathutils.h
new file mode 100644
index 0000000..658f582
--- /dev/null
+++ b/common/treepathutils.h
@@ -0,0 +1,53 @@
+/* Tux Commander VFS: String utilities
+ * 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 __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;
+};
+
+
+struct PathTree* filelist_tree_new();
+void filelist_tree_free(struct PathTree *tree);
+void filelist_tree_print(struct PathTree *tree);
+
+gboolean filelist_tree_add_item(struct PathTree *tree, const char *path, 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/vfs_types.h
new file mode 100644
index 0000000..609a78b
--- /dev/null
+++ b/common/vfs_types.h
@@ -0,0 +1,114 @@
+/* Tux Commander VFS: Virtual File System types and definitions
+ * - prototypes functions and types
+ * draft version 3
+ *
+ * Copyright (C) 2003 Radek Cervinka <radek.cervinka@centrum.cz>
+ * Copyright (C) 2008 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
+ * 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 __VFS_TYPES_H__
+#define __VFS_TYPES_H__
+
+
+#include <stdio.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+typedef int TVFSResult;
+
+
+typedef void (* TVFSLogFunc)(char *s);
+typedef int (* TVFSCopyCallBackFunc)(u_int64_t iPos, u_int64_t iMax, void *data);
+typedef void *TVFSFileDes;
+
+static const int cVFSVersion = 3; // 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)
+enum {
+ cVFS_OK = 0,
+ 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_LoginFailed = 7,
+ cVFS_PermissionDenied = 8,
+ cVFS_NoSpaceLeft = 9,
+ cVFS_mallocFailed = 10,
+ cVFS_BadPassword = 11,
+ cVFS_MissingVolume = 12,
+ cVFS_CorruptedArchive = 13
+};
+
+
+// Open modes
+enum {
+ cVFS_OpenRead,
+ cVFS_OpenWrite,
+ cVFS_OpenAppend
+};
+
+
+// Item Type enum
+enum TVFSItemType {
+ vRegular = 0,
+ vSymlink = 1,
+ vChardev = 2,
+ vBlockdev = 3,
+ vDirectory = 4,
+ vFifo = 5,
+ vSock = 6,
+ vOther = 7
+};
+
+
+struct TVFSItem {
+ char *sFileName;
+ u_int64_t iSize;
+ __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;
+ enum TVFSItemType ItemType;
+};
+
+struct TVFSInfo {
+ const char *Name;
+ const char *Description;
+ const char *About;
+ const char *Copyright;
+};
+
+
+#endif /* __VFS_TYPES_H__ */
diff --git a/common/vfsutils.c b/common/vfsutils.c
new file mode 100644
index 0000000..cc54828
--- /dev/null
+++ b/common/vfsutils.c
@@ -0,0 +1,65 @@
+/* Tux Commander VFS: String utilities
+ * 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 "strutils.h"
+#include "vfs_types.h"
+
+
+
+
+
+void copy_vfs_item(struct TVFSItem *src, struct TVFSItem *dst)
+{
+/*
+ dst->ItemType = src->ItemType;
+ dst->a_time = src->a_time;
+ dst->c_time = src->c_time;
+ dst->iGID = src->iGID;
+ dst->iMode = src->iMode;
+ dst->iSize = src->iSize;
+ dst->iUID = src->iUID;
+ dst->m_time = src->m_time;
+ dst->sFileName = src->sFileName;
+ dst->sLinkTo = src->sLinkTo;
+ */
+ memcpy(dst, src, sizeof(struct TVFSItem));
+}
+
+void free_vfs_item(struct TVFSItem *item)
+{
+ if (item) {
+ if (item->sFileName) free(item->sFileName);
+ if (item->sLinkTo) free(item->sLinkTo);
+ free(item);
+ }
+}
+
+int 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);
+ return b;
+}
diff --git a/common/vfsutils.h b/common/vfsutils.h
new file mode 100644
index 0000000..5dd61f2
--- /dev/null
+++ b/common/vfsutils.h
@@ -0,0 +1,39 @@
+/* Tux Commander VFS: String utilities
+ * 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 __VFSUTILS_H__
+#define __VFSUTILS_H__
+
+
+#include <stdio.h>
+#include <string.h>
+#include <glib.h>
+
+#include "vfs_types.h"
+
+
+void copy_vfs_item(struct TVFSItem *src, struct TVFSItem *dst);
+void free_vfs_item(struct TVFSItem *item);
+
+int compare_two_same_files(const char *Path1, const char *Path2);
+
+
+
+
+#endif /* __VFSUTILS_H__ */