diff options
| author | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2009-11-28 13:11:51 +0100 |
|---|---|---|
| committer | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2009-11-28 13:11:51 +0100 |
| commit | 9382f127ccebdd59917c97c61d008ed0e127cd75 (patch) | |
| tree | 0a48c8296199b343c76ef532eef014f908bc2e4d /common/treepathutils.c | |
| parent | 70eeaa4ec712895539ca6ecd60a42b93ec9b0904 (diff) | |
| download | tuxcmd-modules-0.6.72.tar.xz | |
Engine and VFS API cleanupv0.6.72
Also enable symlink resolving by default.
Diffstat (limited to 'common/treepathutils.c')
| -rw-r--r-- | common/treepathutils.c | 386 |
1 files changed, 0 insertions, 386 deletions
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"); -} - |
