summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@tbzatek.englab.brq.redhat.com>2008-06-13 14:17:54 +0200
committerTomas Bzatek <tbzatek@tbzatek.englab.brq.redhat.com>2008-06-13 14:17:54 +0200
commit892e407c5f5e06fa8c0ca9250b3bc99851c6a61d (patch)
treefbca968b4f12c18cc755c0436925b744c6bb04ea
parent4e58288e8e2e76e8d518b21273f787be16a486c3 (diff)
downloadtuxcmd-modules-892e407c5f5e06fa8c0ca9250b3bc99851c6a61d.tar.xz
Symlink resolving code, disabled by default
-rw-r--r--common/strutils.c103
-rw-r--r--common/strutils.h1
-rw-r--r--common/treepathutils.c50
-rw-r--r--common/treepathutils.h6
-rw-r--r--libarchive/libarchive.c10
5 files changed, 165 insertions, 5 deletions
diff --git a/common/strutils.c b/common/strutils.c
index 3f390d9..5d9fa65 100644
--- a/common/strutils.c
+++ b/common/strutils.c
@@ -19,6 +19,7 @@
#include <stdio.h>
#include <string.h>
+#include <glib.h>
#include "strutils.h"
@@ -89,3 +90,105 @@ char* extract_file_path(const char *APath)
snprintf(ANewPath, file_part - APath + 2, "%s", APath);
return ANewPath;
}
+
+
+
+
+
+
+
+
+// canonicalize_filename() is stolen from glib-2.16
+// Copyright (C) 2006-2007 Alexander Larsson <alexl@redhat.com>
+static char *
+canonicalize_filename (const char *filename)
+{
+ char *canon, *start, *p, *q;
+ int i;
+
+ canon = g_strdup (filename);
+
+ start = (char *)g_path_skip_root (canon);
+
+ /* POSIX allows double slashes at the start to
+ * mean something special (as does windows too).
+ * So, "//" != "/", but more than two slashes
+ * is treated as "/".
+ */
+ i = 0;
+ for (p = start - 1;
+ (p >= canon) &&
+ G_IS_DIR_SEPARATOR (*p);
+ p--)
+ i++;
+ if (i > 2)
+ {
+ i -= 1;
+ start -= i;
+ memmove (start, start+i, strlen (start+i)+1);
+ }
+
+ p = start;
+ while (*p != 0)
+ {
+ if (p[0] == '.' && (p[1] == 0 || G_IS_DIR_SEPARATOR (p[1])))
+ {
+ memmove (p, p+1, strlen (p+1)+1);
+ }
+ else if (p[0] == '.' && p[1] == '.' && (p[2] == 0 || G_IS_DIR_SEPARATOR (p[2])))
+ {
+ q = p + 2;
+ /* Skip previous separator */
+ p = p - 2;
+ if (p < start)
+ p = start;
+ while (p > start && !G_IS_DIR_SEPARATOR (*p))
+ p--;
+ if (G_IS_DIR_SEPARATOR (*p))
+ *p++ = G_DIR_SEPARATOR;
+ memmove (p, q, strlen (q)+1);
+ }
+ else
+ {
+ /* Skip until next separator */
+ while (*p != 0 && !G_IS_DIR_SEPARATOR (*p))
+ p++;
+
+ if (*p != 0)
+ {
+ /* Canonicalize one separator */
+ *p++ = G_DIR_SEPARATOR;
+ }
+ }
+
+ /* Remove additional separators */
+ q = p;
+ while (*q && G_IS_DIR_SEPARATOR (*q))
+ q++;
+
+ if (p != q)
+ memmove (p, q, strlen (q)+1);
+ }
+
+ /* Remove trailing slashes */
+ if (p > start && G_IS_DIR_SEPARATOR (*(p-1)))
+ *(p-1) = 0;
+
+ return canon;
+}
+
+
+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;
+}
diff --git a/common/strutils.h b/common/strutils.h
index a301c53..95cc16b 100644
--- a/common/strutils.h
+++ b/common/strutils.h
@@ -43,6 +43,7 @@ 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);
#endif /* __STRUTILS_H__ */
diff --git a/common/treepathutils.c b/common/treepathutils.c
index 301f173..6215a14 100644
--- a/common/treepathutils.c
+++ b/common/treepathutils.c
@@ -1,5 +1,5 @@
/* Tux Commander VFS: String utilities
- * Copyright (C) 2008 Tomas Bzatek <tbzatek@users.sourceforge.net>
+ * 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
@@ -311,3 +311,51 @@ struct PathTree* filelist_tree_get_item_by_index(struct PathTree *tree, unsigned
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);
+ 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
index 658f582..13f3057 100644
--- a/common/treepathutils.h
+++ b/common/treepathutils.h
@@ -1,5 +1,5 @@
/* Tux Commander VFS: String utilities
- * Copyright (C) 2007 Tomas Bzatek <tbzatek@users.sourceforge.net>
+ * 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
@@ -40,6 +40,10 @@ 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, 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);
diff --git a/libarchive/libarchive.c b/libarchive/libarchive.c
index 5554cab..c15d844 100644
--- a/libarchive/libarchive.c
+++ b/libarchive/libarchive.c
@@ -1,5 +1,5 @@
/* libarchive plugin for Tux Commander
- * version 0.0.4, designed for libarchive 2.4.17
+ * version 0.0.5, designed for libarchive 2.4.17
* Copyright (C) 2008 Tomas Bzatek <tbzatek@users.sourceforge.net>
* Check for updates on tuxcmd.sourceforge.net
*
@@ -47,8 +47,8 @@
-#define VERSION "0.0.4"
-#define BUILD_DATE "2008-05-18"
+#define VERSION "0.0.5"
+#define BUILD_DATE "2008-06-11"
#define DEFAULT_BLOCK_SIZE 65536
@@ -237,6 +237,10 @@ TVFSResult VFSOpen(struct TVFSGlobs *globs, char *sName)
}
archive_read_finish(a);
fprintf(stderr, "(II) VFSOpen: done. \n");
+
+ /* FIXME: temporarily disabled */
+// filelist_tree_resolve_symlinks(globs->files);
+
printf("\n\nList of items:\n");
filelist_tree_print(globs->files);