summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/strutils.c17
-rw-r--r--common/strutils.h5
-rw-r--r--common/treepathutils.c82
3 files changed, 56 insertions, 48 deletions
diff --git a/common/strutils.c b/common/strutils.c
index 5d9fa65..47494de 100644
--- a/common/strutils.c
+++ b/common/strutils.c
@@ -100,15 +100,16 @@ char* extract_file_path(const char *APath)
// canonicalize_filename() is stolen from glib-2.16
// Copyright (C) 2006-2007 Alexander Larsson <alexl@redhat.com>
-static char *
+char *
canonicalize_filename (const char *filename)
{
char *canon, *start, *p, *q;
int i;
-
+
canon = g_strdup (filename);
start = (char *)g_path_skip_root (canon);
+ if (start == NULL) start = canon;
/* POSIX allows double slashes at the start to
* mean something special (as does windows too).
@@ -127,7 +128,7 @@ canonicalize_filename (const char *filename)
start -= i;
memmove (start, start+i, strlen (start+i)+1);
}
-
+
p = start;
while (*p != 0)
{
@@ -153,7 +154,7 @@ canonicalize_filename (const char *filename)
/* Skip until next separator */
while (*p != 0 && !G_IS_DIR_SEPARATOR (*p))
p++;
-
+
if (*p != 0)
{
/* Canonicalize one separator */
@@ -173,7 +174,7 @@ canonicalize_filename (const char *filename)
/* Remove trailing slashes */
if (p > start && G_IS_DIR_SEPARATOR (*(p-1)))
*(p-1) = 0;
-
+
return canon;
}
@@ -183,12 +184,12 @@ 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;
+
+ return canon;
}
diff --git a/common/strutils.h b/common/strutils.h
index 95cc16b..872365c 100644
--- a/common/strutils.h
+++ b/common/strutils.h
@@ -26,11 +26,11 @@
#include <stdlib.h>
-#ifdef __VERBOSE_DEBUG
+#ifdef __VERBOSE_DEBUG
#define log(msg...) printf(msg)
#else
#define log(msg...) { }
-#endif
+#endif
#define IS_DIR_SEP(ch) ((ch) == '/')
@@ -44,6 +44,7 @@ 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);
#endif /* __STRUTILS_H__ */
diff --git a/common/treepathutils.c b/common/treepathutils.c
index f898fea..d249444 100644
--- a/common/treepathutils.c
+++ b/common/treepathutils.c
@@ -43,7 +43,7 @@ struct PathTree* filelist_tree_new()
tree->index = 0;
tree->node = strdup("/");
- // create placeholder data
+ // create placeholder data
tree->data = (struct TVFSItem*)malloc(sizeof(struct TVFSItem));
memset(tree->data, 0, sizeof(struct TVFSItem));
tree->data->sFileName = strdup(tree->node);
@@ -55,7 +55,7 @@ struct PathTree* filelist_tree_new()
tree->data->c_time = tree->data->m_time;
tree->data->a_time = tree->data->m_time;
- return tree;
+ return tree;
}
@@ -90,16 +90,16 @@ 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);
-
+ 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++)
+ 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);
}
@@ -142,10 +142,10 @@ struct PathTree* filelist_tree_find_node_by_path(struct PathTree *tree, const ch
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++)
+ 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) {
@@ -153,7 +153,7 @@ struct PathTree* filelist_tree_find_node_by_path(struct PathTree *tree, const ch
if (! last_part) {
node = t;
log(" filelist_tree_find_node_by_path: found final node '%s', returning.\n", t->node);
- } else
+ } 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);
@@ -196,8 +196,8 @@ void filelist_tree_add_item_recurr(struct PathTree *tree, const char *path, stru
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)
+
+ 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));
@@ -207,7 +207,7 @@ void filelist_tree_add_item_recurr(struct PathTree *tree, const char *path, stru
t->index = index;
t->node = strdup(path);
if (t->data) t->data->sFileName = strdup(path);
- // create new list of subitems and add new item
+ // 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
@@ -215,10 +215,10 @@ void filelist_tree_add_item_recurr(struct PathTree *tree, const char *path, stru
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;
+ struct PathTree *node = NULL;
if (tree->items->len > 0) {
unsigned int i;
- for (i = 0; i < tree->items->len; 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) {
@@ -228,8 +228,8 @@ void filelist_tree_add_item_recurr(struct PathTree *tree, const char *path, stru
}
}
}
-
- // create new path holder node
+
+ // 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));
@@ -238,7 +238,7 @@ void filelist_tree_add_item_recurr(struct PathTree *tree, const char *path, stru
node->index = 0;
node->node = strdup(first_part);
- // create placeholder data
+ // create placeholder data
node->data = (struct TVFSItem*)malloc(sizeof(struct TVFSItem));
memset(node->data, 0, sizeof(struct TVFSItem));
node->data->sFileName = strdup(node->node);
@@ -252,7 +252,7 @@ void filelist_tree_add_item_recurr(struct PathTree *tree, const char *path, stru
g_ptr_array_add(tree->items, node);
}
-
+
// and recurse one level deeper
filelist_tree_add_item_recurr(node, last_part, item, index);
}
@@ -277,17 +277,22 @@ gboolean filelist_tree_add_item(struct PathTree *tree, const char *path, struct
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)
+
+ 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
@@ -296,10 +301,11 @@ gboolean filelist_tree_add_item(struct PathTree *tree, const char *path, struct
if (found->data) found->data->sFileName = strdup(found->node);
} else
// create new item recursively
- filelist_tree_add_item_recurr(tree, p, item, index);
+ filelist_tree_add_item_recurr(tree, pp, item, index);
free(p);
- return TRUE;
+ free(pp);
+ return TRUE;
}
struct PathTree* filelist_tree_get_item_by_index(struct PathTree *tree, unsigned long index)
@@ -309,7 +315,7 @@ struct PathTree* filelist_tree_get_item_by_index(struct PathTree *tree, unsigned
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)
@@ -317,11 +323,11 @@ void filelist_tree_resolve_symlinks_recurr(struct PathTree *tree, struct PathTre
if (tree) {
if ((tree->items) && (tree->items->len > 0)) {
unsigned int i;
- for (i = 0; i < tree->items->len; 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);
@@ -330,14 +336,14 @@ void filelist_tree_resolve_symlinks_recurr(struct PathTree *tree, struct PathTre
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;
+ // 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);
}
@@ -350,7 +356,7 @@ void filelist_tree_resolve_symlinks_recurr(struct PathTree *tree, struct PathTre
filelist_tree_resolve_symlinks_recurr(t, root_tree, new_path);
g_free(new_path);
}
- }
+ }
}
}