From bba132381e9bc6e647b701c6f92d2f3b14962179 Mon Sep 17 00:00:00 2001 From: Slava Zanko Date: Tue, 14 Jun 2011 15:09:59 +0300 Subject: [PATCH] vfs_path_to_str() now return URL string instead of old representation Signed-off-by: Slava Zanko --- lib/tests/Makefile.am | 4 -- lib/tests/vfs/Makefile.am | 4 ++ lib/tests/{ => vfs}/canonicalize_pathname.c | 24 +++++++++- lib/tests/vfs/current_dir.c | 27 +++++++---- lib/tests/vfs/path_serialize.c | 5 +- lib/tests/vfs/vfs_path_string_convert.c | 46 +++++++++--------- lib/tests/vfs/vfs_s_get_path_mangle.c | 9 ++-- lib/util.c | 20 +++++--- lib/utilunix.c | 61 ++++++++++++++++++++---- lib/vfs/direntry.c | 2 +- lib/vfs/path.c | 36 ++++++++------- lib/vfs/path.h | 2 + lib/vfs/vfs.c | 30 ++++-------- lib/vfs/xdirentry.h | 2 +- misc/mc.ext.in | 72 ++++++++++++++--------------- src/filemanager/panel.c | 17 +++++-- src/vfs/extfs/extfs.c | 4 +- 17 files changed, 225 insertions(+), 140 deletions(-) rename lib/tests/{ => vfs}/canonicalize_pathname.c (84%) diff --git a/lib/tests/Makefile.am b/lib/tests/Makefile.am index 21cf210cd..20e92dd32 100644 --- a/lib/tests/Makefile.am +++ b/lib/tests/Makefile.am @@ -4,15 +4,11 @@ AM_CFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir) @CHECK_CFLAGS@ LIBS=@CHECK_LIBS@ $(top_builddir)/lib/libmc.la TESTS = \ - canonicalize_pathname \ library_independ \ serialize check_PROGRAMS = $(TESTS) -canonicalize_pathname_SOURCES = \ - canonicalize_pathname.c - library_independ_SOURCES = \ library_independ.c diff --git a/lib/tests/vfs/Makefile.am b/lib/tests/vfs/Makefile.am index 27d4508c5..4fdc0530e 100644 --- a/lib/tests/vfs/Makefile.am +++ b/lib/tests/vfs/Makefile.am @@ -7,6 +7,7 @@ LIBS=@CHECK_LIBS@ \ $(top_builddir)/lib/libmc.la TESTS = \ + canonicalize_pathname \ current_dir \ path_serialize \ vfs_path_string_convert \ @@ -16,6 +17,9 @@ TESTS = \ check_PROGRAMS = $(TESTS) +canonicalize_pathname_SOURCES = \ + canonicalize_pathname.c + current_dir_SOURCES = \ current_dir.c diff --git a/lib/tests/canonicalize_pathname.c b/lib/tests/vfs/canonicalize_pathname.c similarity index 84% rename from lib/tests/canonicalize_pathname.c rename to lib/tests/vfs/canonicalize_pathname.c index fd56f8d35..041d24fce 100644 --- a/lib/tests/canonicalize_pathname.c +++ b/lib/tests/vfs/canonicalize_pathname.c @@ -20,22 +20,33 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#define TEST_SUITE_NAME "/lib" +#define TEST_SUITE_NAME "/lib/vfs" #include #include "lib/global.h" +#include "lib/strutil.h" #include "lib/util.h" +#include "lib/vfs/xdirentry.h" + +#include "src/vfs/local/local.c" static void setup (void) { + str_init_strings (NULL); + + vfs_init (); + init_localfs (); + vfs_setup_work_dir (); } static void teardown (void) { + vfs_shut (); + str_uninit_strings (); } /* --------------------------------------------------------------------------------------------- */ @@ -53,6 +64,16 @@ teardown (void) START_TEST (test_canonicalize_path) { char *path; + static struct vfs_s_subclass test_subclass; + static struct vfs_class vfs_test_ops; + + vfs_s_init_class (&vfs_test_ops, &test_subclass); + + vfs_test_ops.name = "testfs"; + vfs_test_ops.flags = VFSF_NOLINKS; + vfs_test_ops.prefix = "ftp"; + test_subclass.flags = VFS_S_REMOTE; + vfs_register_class (&vfs_test_ops); /* UNC path */ check_canonicalize ("//some_server/ww", "//some_server/ww"); @@ -80,7 +101,6 @@ START_TEST (test_canonicalize_path) check_canonicalize ("ftp://user:pass@host.net/path/../../", "."); check_canonicalize ("ftp://user/../../", ".."); - } END_TEST diff --git a/lib/tests/vfs/current_dir.c b/lib/tests/vfs/current_dir.c index f04d6306d..c19e7b336 100644 --- a/lib/tests/vfs/current_dir.c +++ b/lib/tests/vfs/current_dir.c @@ -75,7 +75,6 @@ START_TEST (set_up_current_dir) static struct vfs_class vfs_test_ops; char buffer[MC_MAXPATHLEN]; - test_subclass.flags = VFS_S_REMOTE; vfs_s_init_class (&vfs_test_ops, &test_subclass); vfs_test_ops.name = "testfs"; @@ -85,9 +84,11 @@ START_TEST (set_up_current_dir) vfs_register_class (&vfs_test_ops); - cd_and_check ("/dev/some.file#test/bla-bla", "/dev/some.file#test/bla-bla"); + cd_and_check ("/dev/some.file#test", "/dev/some.file/test://"); + + cd_and_check ("/dev/some.file#test/bla-bla", "/dev/some.file/test://bla-bla"); - cd_and_check ("..", "/dev/some.file#test"); + cd_and_check ("..", "/dev/some.file/test://"); cd_and_check ("..", "/dev"); @@ -95,9 +96,9 @@ START_TEST (set_up_current_dir) cd_and_check ("..", "/"); - cd_and_check ("/dev/some.file/#test/bla-bla", "/dev/some.file/#test/bla-bla"); + cd_and_check ("/dev/some.file/#test/bla-bla", "/dev/some.file/test://bla-bla"); - cd_and_check ("..", "/dev/some.file/#test"); + cd_and_check ("..", "/dev/some.file/test://"); cd_and_check ("..", "/dev"); @@ -115,17 +116,20 @@ START_TEST (set_up_current_dir_url) static struct vfs_class vfs_test_ops; char buffer[MC_MAXPATHLEN]; - test_subclass.flags = VFS_S_REMOTE; vfs_s_init_class (&vfs_test_ops, &test_subclass); vfs_test_ops.name = "testfs"; vfs_test_ops.flags = VFSF_NOLINKS; - vfs_test_ops.prefix = "test:"; + vfs_test_ops.prefix = "test"; vfs_test_ops.chdir = test_chdir; vfs_register_class (&vfs_test_ops); - cd_and_check ("/dev/some.file/test://bla-bla", "/dev/some.file/#test:bla-bla"); + cd_and_check ("/dev/some.file/test://", "/dev/some.file/test://"); + + cd_and_check ("/dev/some.file/test://bla-bla", "/dev/some.file/test://bla-bla"); + + cd_and_check ("..", "/dev/some.file/test://"); cd_and_check ("..", "/dev"); @@ -133,9 +137,12 @@ START_TEST (set_up_current_dir_url) cd_and_check ("..", "/"); - test_subclass.flags &= ~VFS_S_REMOTE; + test_subclass.flags = VFS_S_REMOTE; + + cd_and_check ("/test://user:pass@host.net/path", "/test://user:pass@host.net/path"); + cd_and_check ("..", "/test://user:pass@host.net"); - cd_and_check ("/dev/some.file/test://bla-bla", "/dev/some.file/#test/bla-bla"); + cd_and_check ("..", "/"); } END_TEST diff --git a/lib/tests/vfs/path_serialize.c b/lib/tests/vfs/path_serialize.c index 0135b1a48..f86ddb985 100644 --- a/lib/tests/vfs/path_serialize.c +++ b/lib/tests/vfs/path_serialize.c @@ -86,6 +86,7 @@ teardown (void) /* --------------------------------------------------------------------------------------------- */ #define ETALON_PATH_STR "/local/path/#test1:user:pass@some.host:12345/bla-bla/some/path/#test2/#enc:KOI8-R/bla-bla/some/path#test3/111/22/33" +#define ETALON_PATH_URL_STR "/local/path/test1://user:pass@some.host:12345/bla-bla/some/path/test2://#enc:KOI8-R/bla-bla/some/path/test3://111/22/33" #define ETALON_SERIALIZED_PATH \ "g14:path-element-0" \ "p4:pathv12:/local/path/" \ @@ -142,8 +143,8 @@ START_TEST (test_path_serialize_deserialize) serialized_vpath = vfs_path_to_str (vpath); fail_unless ( - strcmp (serialized_vpath, ETALON_PATH_STR) == 0, - "\ndeserialized path (%s)\nnot equal to etalon (%s)", serialized_vpath, ETALON_PATH_STR + strcmp (serialized_vpath, ETALON_PATH_URL_STR) == 0, + "\ndeserialized path (%s)\nnot equal to etalon (%s)", serialized_vpath, ETALON_PATH_URL_STR ); vfs_path_free(vpath); g_free(serialized_vpath); diff --git a/lib/tests/vfs/vfs_path_string_convert.c b/lib/tests/vfs/vfs_path_string_convert.c index 0867fd73b..fd96c9390 100644 --- a/lib/tests/vfs/vfs_path_string_convert.c +++ b/lib/tests/vfs/vfs_path_string_convert.c @@ -81,6 +81,7 @@ teardown (void) /* --------------------------------------------------------------------------------------------- */ #define ETALON_PATH_STR "/#test1/bla-bla/some/path/#test2/bla-bla/some/path#test3/111/22/33" +#define ETALON_PATH_URL_STR "/test1://bla-bla/some/path/test2://bla-bla/some/path/test3://111/22/33" START_TEST (test_vfs_path_from_to_string) { vfs_path_t *vpath; @@ -93,7 +94,7 @@ START_TEST (test_vfs_path_from_to_string) fail_unless(vpath_len == 4, "vpath length should be 4 (actial: %d)",vpath_len); result = vfs_path_to_str(vpath); - fail_unless(strcmp(ETALON_PATH_STR, result) == 0, "expected(%s) doesn't equal to actual(%s)", ETALON_PATH_STR, result); + fail_unless(strcmp(ETALON_PATH_URL_STR, result) == 0, "expected(%s) doesn't equal to actual(%s)", ETALON_PATH_URL_STR, result); g_free(result); vfs_path_free(vpath); @@ -137,14 +138,14 @@ START_TEST (test_vfs_path_from_to_partial_string_by_class) result = vfs_path_to_str_elements_count(vpath, -1); fail_unless( - strcmp("/#test1/bla-bla/some/path/#test2/bla-bla/some/path", result) == 0, - "expected(%s) doesn't equal to actual(%s)", "/#test1/bla-bla/some/path/#test2/bla-bla/some/path", result); + strcmp("/test1://bla-bla/some/path/test2://bla-bla/some/path", result) == 0, + "expected(%s) doesn't equal to actual(%s)", "/test1://bla-bla/some/path/test2://bla-bla/some/path", result); g_free(result); result = vfs_path_to_str_elements_count(vpath, -2); fail_unless( - strcmp("/#test1/bla-bla/some/path/", result) == 0, - "expected(%s) doesn't equal to actual(%s)", "/#test1/bla-bla/some/path/", result); + strcmp("/test1://bla-bla/some/path/", result) == 0, + "expected(%s) doesn't equal to actual(%s)", "/test1://bla-bla/some/path/", result); g_free(result); result = vfs_path_to_str_elements_count(vpath, -3); @@ -169,27 +170,27 @@ START_TEST (test_vfs_path_from_to_partial_string_by_class) result = vfs_path_to_str_elements_count(vpath, 2); fail_unless( - strcmp("/#test1/bla-bla/some/path/", result) == 0, - "expected(%s) doesn't equal to actual(%s)", "/#test1/bla-bla/some/path/", result); + strcmp("/test1://bla-bla/some/path/", result) == 0, + "expected(%s) doesn't equal to actual(%s)", "/test1://bla-bla/some/path/", result); g_free(result); result = vfs_path_to_str_elements_count(vpath, 3); fail_unless( - strcmp("/#test1/bla-bla/some/path/#test2/bla-bla/some/path", result) == 0, - "expected(%s) doesn't equal to actual(%s)", "/#test1/bla-bla/some/path/#test2/bla-bla/some/path", result); + strcmp("/test1://bla-bla/some/path/test2://bla-bla/some/path", result) == 0, + "expected(%s) doesn't equal to actual(%s)", "/test1://bla-bla/some/path/test2://bla-bla/some/path", result); g_free(result); result = vfs_path_to_str_elements_count(vpath, 4); fail_unless( - strcmp(ETALON_PATH_STR, result) == 0, - "expected(%s) doesn't equal to actual(%s)", ETALON_PATH_STR, result); + strcmp(ETALON_PATH_URL_STR, result) == 0, + "expected(%s) doesn't equal to actual(%s)", ETALON_PATH_URL_STR, result); g_free(result); /* index out of bound*/ result = vfs_path_to_str_elements_count(vpath, 5); fail_unless( - strcmp(ETALON_PATH_STR, result) == 0, - "expected(%s) doesn't equal to actual(%s)", ETALON_PATH_STR, result); + strcmp(ETALON_PATH_URL_STR, result) == 0, + "expected(%s) doesn't equal to actual(%s)", ETALON_PATH_URL_STR, result); g_free(result); vfs_path_free(vpath); @@ -218,32 +219,32 @@ START_TEST (test_vfs_path_from_to_string_encoding) encoding_check ( "/#test1/bla-bla1/some/path/#test2/bla-bla2/#enc:KOI8-R/some/path#test3/111/22/33", - "/#test1/bla-bla1/some/path/#test2/#enc:KOI8-R/bla-bla2/some/path#test3/111/22/33" + "/test1://bla-bla1/some/path/test2://#enc:KOI8-R/bla-bla2/some/path/test3://111/22/33" ); encoding_check ( "/#test1/bla-bla1/#enc:IBM866/some/path/#test2/bla-bla2/#enc:KOI8-R/some/path#test3/111/22/33", - "/#test1/#enc:IBM866/bla-bla1/some/path/#test2/#enc:KOI8-R/bla-bla2/some/path#test3/111/22/33" + "/test1://#enc:IBM866/bla-bla1/some/path/test2://#enc:KOI8-R/bla-bla2/some/path/test3://111/22/33" ); encoding_check ( "/#test1/bla-bla1/some/path/#test2/bla-bla2/#enc:IBM866/#enc:KOI8-R/some/path#test3/111/22/33", - "/#test1/bla-bla1/some/path/#test2/#enc:KOI8-R/bla-bla2/some/path#test3/111/22/33" + "/test1://bla-bla1/some/path/test2://#enc:KOI8-R/bla-bla2/some/path/test3://111/22/33" ); encoding_check ( "/#test1/bla-bla1/some/path/#test2/bla-bla2/#enc:IBM866/some/#enc:KOI8-R/path#test3/111/22/33", - "/#test1/bla-bla1/some/path/#test2/#enc:KOI8-R/bla-bla2/some/path#test3/111/22/33" + "/test1://bla-bla1/some/path/test2://#enc:KOI8-R/bla-bla2/some/path/test3://111/22/33" ); encoding_check ( "/#test1/bla-bla1/some/path/#test2/#enc:IBM866/bla-bla2/#enc:KOI8-R/some/path#test3/111/22/33", - "/#test1/bla-bla1/some/path/#test2/#enc:KOI8-R/bla-bla2/some/path#test3/111/22/33" + "/test1://bla-bla1/some/path/test2://#enc:KOI8-R/bla-bla2/some/path/test3://111/22/33" ); encoding_check ( "/#test1/bla-bla1/some/path/#enc:IBM866/#test2/bla-bla2/#enc:KOI8-R/some/path#test3/111/22/33", - "/#test1/#enc:IBM866/bla-bla1/some/path/#test2/#enc:KOI8-R/bla-bla2/some/path#test3/111/22/33" + "/test1://#enc:IBM866/bla-bla1/some/path/test2://#enc:KOI8-R/bla-bla2/some/path/test3://111/22/33" ); free_codepages_list (); @@ -251,7 +252,7 @@ START_TEST (test_vfs_path_from_to_string_encoding) END_TEST /* --------------------------------------------------------------------------------------------- */ -#define ETALON_STR "/path/to/file.ext#test1/#enc:KOI8-R" +#define ETALON_STR "/path/to/file.ext/test1://#enc:KOI8-R" START_TEST (test_vfs_path_encoding_at_end) { vfs_path_t *vpath; @@ -282,14 +283,13 @@ END_TEST /* --------------------------------------------------------------------------------------------- */ #undef ETALON_PATH_STR -#define ETALON_PATH_STR "/#test1/bla-bla/some/path/#test2:user:passwd@some.host:1234/bla-bla/some/path/#test3/111/22/33" -#define INPUT_PATH_STR "/test1://bla-bla/some/path/test2://user:passwd@some.host:1234/bla-bla/some/path/test3://111/22/33" +#define ETALON_PATH_STR "/test1://bla-bla/some/path/test2://user:passwd@some.host:1234/bla-bla/some/path/test3://111/22/33" START_TEST (test_vfs_path_from_to_string_uri) { vfs_path_t *vpath; size_t vpath_len; char *result; - vpath = vfs_path_from_str (INPUT_PATH_STR); + vpath = vfs_path_from_str (ETALON_PATH_STR); vpath_len = vfs_path_elements_count(vpath); fail_unless(vpath_len == 4, "vpath length should be 4 (actial: %d)",vpath_len); diff --git a/lib/tests/vfs/vfs_s_get_path_mangle.c b/lib/tests/vfs/vfs_s_get_path_mangle.c index 246839b92..b9b762e49 100644 --- a/lib/tests/vfs/vfs_s_get_path_mangle.c +++ b/lib/tests/vfs/vfs_s_get_path_mangle.c @@ -34,6 +34,7 @@ #define ARCH_NAME "/path/to/some/file.ext" #define ETALON_PATH "path/to/test1_file.ext" #define ETALON_VFS_NAME "#test2:user:pass@host.net" +#define ETALON_VFS_URL_NAME "test2://user:pass@host.net" struct vfs_s_subclass test_subclass1, test_subclass2, test_subclass3; struct vfs_class vfs_test_ops1, vfs_test_ops2, vfs_test_ops3; @@ -44,8 +45,8 @@ test1_mock_open_archive(struct vfs_s_super *super, const vfs_path_t *vpath, cons struct vfs_s_inode *root; char *spath = vfs_path_to_str (vpath); - fail_unless(strcmp("/" ETALON_VFS_NAME ARCH_NAME, spath) == 0, - "etalon(%s) doesn't equal to actual(%s)", "/" ETALON_VFS_NAME ARCH_NAME, spath); + fail_unless(strcmp("/" ETALON_VFS_URL_NAME ARCH_NAME, spath) == 0, + "etalon(%s) doesn't equal to actual(%s)", "/" ETALON_VFS_URL_NAME ARCH_NAME, spath); super->name = g_strdup (spath); super->data = g_new (char *, 1); @@ -131,8 +132,8 @@ START_TEST (test_vfs_s_get_path_mangle) fail_unless(strcmp(ETALON_PATH, result) == 0, "expected(%s) doesn't equal to actual(%s)", ETALON_PATH, result); - fail_unless(strcmp("/" ETALON_VFS_NAME ARCH_NAME,archive->name) == 0, - "expected(%s) doesn't equal to actual(%s)", "/" ETALON_VFS_NAME ARCH_NAME, archive->name); + fail_unless(strcmp("/" ETALON_VFS_URL_NAME ARCH_NAME,archive->name) == 0, + "expected(%s) doesn't equal to actual(%s)", "/" ETALON_VFS_URL_NAME ARCH_NAME, archive->name); g_free(vpath); diff --git a/lib/util.c b/lib/util.c index c70e7e201..25e0f726c 100644 --- a/lib/util.c +++ b/lib/util.c @@ -669,7 +669,15 @@ const char * x_basename (const char *s) { const char *where; - return ((where = strrchr (s, PATH_SEP))) ? where + 1 : s; + + where = g_strrstr (s, VFS_PATH_URL_DELIMITER); + if (where == NULL) + return ((where = strrchr (s, PATH_SEP))) ? where + 1 : s; + + while (--where > s && *where != PATH_SEP); + while (--where > s && *where != PATH_SEP); + + return (where == s ) ? s: where + 1; } /* --------------------------------------------------------------------------------------------- */ @@ -890,15 +898,15 @@ decompress_extension (int type) switch (type) { case COMPRESSION_GZIP: - return "#ugz"; + return "/ugz" VFS_PATH_URL_DELIMITER; case COMPRESSION_BZIP: - return "#ubz"; + return "/ubz" VFS_PATH_URL_DELIMITER; case COMPRESSION_BZIP2: - return "#ubz2"; + return "/ubz2" VFS_PATH_URL_DELIMITER; case COMPRESSION_LZMA: - return "#ulzma"; + return "/ulzma" VFS_PATH_URL_DELIMITER; case COMPRESSION_XZ: - return "#uxz"; + return "/uxz" VFS_PATH_URL_DELIMITER; } /* Should never reach this place */ fprintf (stderr, "Fatal: decompress_extension called with an unknown argument\n"); diff --git a/lib/utilunix.c b/lib/utilunix.c index 687fb4e05..ef284da3a 100644 --- a/lib/utilunix.c +++ b/lib/utilunix.c @@ -56,6 +56,7 @@ #include "lib/strutil.h" /* str_move() */ #include "lib/util.h" #include "lib/widget.h" /* message() */ +#include "lib/vfs/xdirentry.h" #ifdef HAVE_CHARSET #include "lib/charsets.h" @@ -543,8 +544,9 @@ void custom_canonicalize_pathname (char *path, CANON_PATH_FLAGS flags) { char *p, *s; - int len; + size_t len; char *lpath = path; /* path without leading UNC part */ + const size_t url_delim_len = strlen (VFS_PATH_URL_DELIMITER); /* Detect and preserve UNC paths: //server/... */ if ((flags & CANON_PATH_GUARDUNC) && path[0] == PATH_SEP && path[1] == PATH_SEP) @@ -593,7 +595,12 @@ custom_canonicalize_pathname (char *path, CANON_PATH_FLAGS flags) /* Remove trailing slashes */ p = lpath + strlen (lpath) - 1; while (p > lpath && *p == PATH_SEP) + { + if (p >= lpath - (url_delim_len + 1) + && strncmp (p - url_delim_len + 1, VFS_PATH_URL_DELIMITER, url_delim_len) == 0) + break; *p-- = 0; + } /* Remove leading "./" */ if (lpath[0] == '.' && lpath[1] == PATH_SEP) @@ -613,9 +620,12 @@ custom_canonicalize_pathname (char *path, CANON_PATH_FLAGS flags) len = strlen (lpath); if (len < 2) return; - if (lpath[len - 1] == PATH_SEP) + if (lpath[len - 1] == PATH_SEP + && (len < url_delim_len + || strncmp (lpath + len - url_delim_len, VFS_PATH_URL_DELIMITER, + url_delim_len) != 0)) { - lpath[len - 1] = 0; + lpath[len - 1] = '\0'; } else { @@ -623,12 +633,12 @@ custom_canonicalize_pathname (char *path, CANON_PATH_FLAGS flags) { if (len == 2) { - lpath[1] = 0; + lpath[1] = '\0'; return; } else { - lpath[len - 2] = 0; + lpath[len - 2] = '\0'; } } } @@ -650,13 +660,40 @@ custom_canonicalize_pathname (char *path, CANON_PATH_FLAGS flags) /* search for the previous token */ s = p - 1; + if (s >= lpath + url_delim_len - 2 + && strncmp (s - url_delim_len + 2, VFS_PATH_URL_DELIMITER, url_delim_len) == 0) + { + s -= (url_delim_len - 2); + while (s >= lpath && *s-- != PATH_SEP); + } + while (s >= lpath) { - if (s >= lpath + 2 && strncmp (s - 2, "://", 3) == 0) + if (s - url_delim_len > lpath + && strncmp (s - url_delim_len, VFS_PATH_URL_DELIMITER, url_delim_len) == 0) { - s -= 2; - continue; + char *vfs_prefix = s - url_delim_len; + struct vfs_class *vclass; + + while (vfs_prefix > lpath && *--vfs_prefix != PATH_SEP); + if (*vfs_prefix == PATH_SEP) + vfs_prefix++; + *(s - url_delim_len) = '\0'; + + vclass = vfs_prefix_to_class (vfs_prefix); + *(s - url_delim_len) = *VFS_PATH_URL_DELIMITER; + + if (vclass != NULL) + { + struct vfs_s_subclass *sub = (struct vfs_s_subclass *) vclass->data; + if (sub != NULL && sub->flags & VFS_S_REMOTE) + { + s = vfs_prefix; + continue; + } + } } + if (*s == PATH_SEP) { /* skip VFS prefix */ @@ -748,7 +785,13 @@ custom_canonicalize_pathname (char *path, CANON_PATH_FLAGS flags) } #endif /* HAVE_CHARSET */ else - s[-1] = 0; + { + if (s >= lpath + url_delim_len + && strncmp (s - url_delim_len, VFS_PATH_URL_DELIMITER, url_delim_len) == 0) + *s = '\0'; + else + s[-1] = '\0'; + } break; } diff --git a/lib/vfs/direntry.c b/lib/vfs/direntry.c index 1b99a12e8..bc9cfff85 100644 --- a/lib/vfs/direntry.c +++ b/lib/vfs/direntry.c @@ -758,7 +758,7 @@ vfs_s_fill_names (struct vfs_class *me, fill_names_f func) const struct vfs_s_super *super = (const struct vfs_s_super *) iter->data; char *name; - name = g_strconcat (super->name, "#", me->prefix, "/", + name = g_strconcat (super->name, "/", me->prefix, VFS_PATH_URL_DELIMITER, /* super->current_dir->name, */ (char *) NULL); func (name); g_free (name); diff --git a/lib/vfs/path.c b/lib/vfs/path.c index 2525a126e..4cbb82d35 100644 --- a/lib/vfs/path.c +++ b/lib/vfs/path.c @@ -48,8 +48,6 @@ extern GPtrArray *vfs__classes_list; /*** file scope macro definitions ****************************************************************/ -#define URL_DELIMITER "://" - /*** file scope type declarations ****************************************************************/ /*** file scope variables ************************************************************************/ @@ -384,7 +382,7 @@ vfs_get_class_by_name (const char *class_name) static gboolean vfs_path_is_str_path_deprecated (const char *path_str) { - return strstr (path_str, URL_DELIMITER) == NULL; + return strstr (path_str, VFS_PATH_URL_DELIMITER) == NULL; } /* --------------------------------------------------------------------------------------------- */ @@ -462,12 +460,12 @@ vfs_path_from_str_uri_parser (char *path) vpath = vfs_path_new (); - while ((url_delimiter = g_strrstr (path, URL_DELIMITER)) != NULL) + while ((url_delimiter = g_strrstr (path, VFS_PATH_URL_DELIMITER)) != NULL) { char *vfs_prefix_start; char *real_vfs_prefix_start = url_delimiter; char *slash_pointer; - struct vfs_s_subclass *sub; + struct vfs_s_subclass *sub = NULL; while (real_vfs_prefix_start > path && *(real_vfs_prefix_start) != PATH_SEP) real_vfs_prefix_start--; @@ -475,18 +473,18 @@ vfs_path_from_str_uri_parser (char *path) if (*(vfs_prefix_start) == PATH_SEP) vfs_prefix_start += 1; - *(url_delimiter + 1) = '\0'; + + *url_delimiter = '\0'; element = g_new0 (vfs_path_element_t, 1); element->class = vfs_prefix_to_class (vfs_prefix_start); - *url_delimiter = '\0'; element->vfs_prefix = g_strdup (vfs_prefix_start); element->dir.converter = INVALID_CONV; - url_delimiter += 3; + url_delimiter += strlen (VFS_PATH_URL_DELIMITER); sub = VFSDATA (element); - if (sub->flags & VFS_S_REMOTE) + if (sub != NULL && sub->flags & VFS_S_REMOTE) { slash_pointer = strchr (url_delimiter, PATH_SEP); if (slash_pointer == NULL) @@ -508,7 +506,7 @@ vfs_path_from_str_uri_parser (char *path) } vpath->path = g_list_prepend (vpath->path, element); - if (real_vfs_prefix_start > path && *(real_vfs_prefix_start) != PATH_SEP) + if (real_vfs_prefix_start > path && *(real_vfs_prefix_start) == PATH_SEP) *real_vfs_prefix_start = '\0'; else *(real_vfs_prefix_start + 1) = '\0'; @@ -563,25 +561,31 @@ vfs_path_to_str_elements_count (const vfs_path_t * vpath, int elements_count) if (element->vfs_prefix != NULL) { char *url_str; - g_string_append_c (buffer, '#'); + + if (buffer->str[buffer->len - 1] != '/') + g_string_append_c (buffer, '/'); + g_string_append (buffer, element->vfs_prefix); + g_string_append (buffer, VFS_PATH_URL_DELIMITER); url_str = vfs_path_build_url_params_str (element); if (*url_str != '\0') - { - g_string_append_c (buffer, ':'); g_string_append (buffer, url_str); - } + g_free (url_str); } if (element->encoding != NULL) { - g_string_append (buffer, PATH_SEP_STR VFS_ENCODING_PREFIX); + if (buffer->str[buffer->len - 1] != PATH_SEP) + g_string_append (buffer, PATH_SEP_STR); + g_string_append (buffer, VFS_ENCODING_PREFIX); g_string_append (buffer, element->encoding); } - if ((*element->path != PATH_SEP) && (*element->path != '\0')) + if ((*element->path != PATH_SEP) && (*element->path != '\0') + && (buffer->str[buffer->len - 1] != PATH_SEP)) g_string_append_c (buffer, PATH_SEP); + g_string_append (buffer, element->path); } return g_string_free (buffer, FALSE); diff --git a/lib/vfs/path.h b/lib/vfs/path.h index 071a39ade..9690977d4 100644 --- a/lib/vfs/path.h +++ b/lib/vfs/path.h @@ -3,6 +3,8 @@ /*** typedefs(not structures) and defined constants **********************************************/ +#define VFS_PATH_URL_DELIMITER "://" + /*** enums ***************************************************************************************/ /*** structures declarations (and typedefs of structures)*****************************************/ diff --git a/lib/vfs/vfs.c b/lib/vfs/vfs.c index 327b6f813..709d7c9d5 100644 --- a/lib/vfs/vfs.c +++ b/lib/vfs/vfs.c @@ -295,37 +295,25 @@ vfs_register_class (struct vfs_class * vfs) char * vfs_strip_suffix_from_filename (const char *filename) { - guint i; - char *semi; - char *p; + char *semi, *p, *vfs_prefix; if (filename == NULL) vfs_die ("vfs_strip_suffix_from_path got NULL: impossible"); p = g_strdup (filename); - semi = strrchr (p, '#'); + semi = g_strrstr (p, VFS_PATH_URL_DELIMITER); if (semi == NULL) return p; - /* Avoid first class (localfs) that would accept any prefix */ - for (i = 1; i < vfs__classes_list->len; i++) + *semi = '\0'; + vfs_prefix = strrchr (p, PATH_SEP); + if (vfs_prefix == NULL) { - struct vfs_class *vfs = (struct vfs_class *) g_ptr_array_index (vfs__classes_list, i); - - if (vfs->which != NULL) - { - if (vfs->which (vfs, semi + 1) == -1) - continue; - *semi = '\0'; /* Found valid suffix */ - break; - } - - if (vfs->prefix != NULL && strncmp (semi + 1, vfs->prefix, strlen (vfs->prefix)) == 0) - { - *semi = '\0'; /* Found valid suffix */ - break; - } + *semi = *VFS_PATH_URL_DELIMITER; + return p; } + *vfs_prefix = '\0'; + return p; } diff --git a/lib/vfs/xdirentry.h b/lib/vfs/xdirentry.h index c4bf56abf..e1fc86281 100644 --- a/lib/vfs/xdirentry.h +++ b/lib/vfs/xdirentry.h @@ -40,7 +40,7 @@ #define MEDATA ((struct vfs_s_subclass *) me->data) -#define VFSDATA(a) ((struct vfs_s_subclass *) a->class->data) +#define VFSDATA(a) ((a->class != NULL) ? (struct vfs_s_subclass *) a->class->data : NULL) #define FH ((vfs_file_handler_t *) fh) #define FH_SUPER FH->ino->super diff --git a/misc/mc.ext.in b/misc/mc.ext.in index 7b7349e39..68962bd25 100644 --- a/misc/mc.ext.in +++ b/misc/mc.ext.in @@ -108,149 +108,149 @@ # .tgz, .tpz, .tar.gz, .tar.z, .tar.Z, .ipk regex/\.t([gp]?z|ar\.g?[zZ])$|\.ipk$ - Open=%cd %p#utar + Open=%cd %p/utar:// View=%view{ascii} gzip -dc %f 2>/dev/null | tar tvvf - regex/\.tar\.bz$ - # Open=%cd %p#utar + # Open=%cd %p/utar:// View=%view{ascii} bzip -dc %f 2>/dev/null | tar tvvf - regex/\.t(ar\.bz2|bz2?|b2)$ - Open=%cd %p#utar + Open=%cd %p/utar:// View=%view{ascii} bzip2 -dc %f 2>/dev/null | tar tvvf - # .tar.lzma, .tlz regex/\.t(ar\.lzma|lz)$ - Open=%cd %p#utar + Open=%cd %p/utar:// View=%view{ascii} lzma -dc %f 2>/dev/null | tar tvvf - # .tar.xz, .txz regex/\.t(ar\.xz|xz)$ - Open=%cd %p#utar + Open=%cd %p/utar:// View=%view{ascii} xz -dc %f 2>/dev/null | tar tvvf - # .tar.F - used in QNX regex/\.tar\.F$ - # Open=%cd %p#utar + # Open=%cd %p/utar:// View=%view{ascii} freeze -dc %f 2>/dev/null | tar tvvf - # .qpr/.qpk - QNX Neutrino package installer files regex/\.(qp[rk])$ - Open=%cd %p#utar + Open=%cd %p/utar:// View=%view{ascii} gzip -dc %f 2>/dev/null | tar tvvf - # tar regex/\.(tar|TAR)$ - Open=%cd %p#utar + Open=%cd %p/utar:// View=%view{ascii} tar tvvf - < %f # lha type/^LHa\ .*archive - Open=%cd %p#ulha + Open=%cd %p/ulha:// View=%view{ascii} lha l %f # arj regex/\.a(rj|[0-9][0-9])$ - Open=%cd %p#uarj + Open=%cd %p/uarj:// View=%view{ascii} unarj l %f # cab regex/\.([cC][aA][bB])$ - Open=%cd %p#ucab + Open=%cd %p/ucab:// View=%view{ascii} cabextract -l %f # ha regex/\.([Hh][Aa])$ - Open=%cd %p#uha + Open=%cd %p/uha:// View=%view{ascii} ha lf %f # rar regex/\.[rR]([aA][rR]|[0-9][0-9])$ - Open=%cd %p#urar + Open=%cd %p/urar:// View=%view{ascii} rar v -c- %f # ALZip regex/\.(alz|ALZ)$ - Open=%cd %p#ualz + Open=%cd %p/ualz:// View=%view{ascii} unalz -l %f # cpio shell/.cpio.Z - Open=%cd %p#ucpio + Open=%cd %p/ucpio:// View=%view{ascii} gzip -dc %f | cpio -itv 2>/dev/null shell/.cpio.gz - Open=%cd %p#ucpio + Open=%cd %p/ucpio:// View=%view{ascii} gzip -dc %f | cpio -itv 2>/dev/null shell/.cpio - Open=%cd %p#ucpio + Open=%cd %p/ucpio:// View=%view{ascii} cpio -itv < %f 2>/dev/null # ls-lR regex/(^|\.)ls-?lR(\.gz|Z|bz2)$ - Open=%cd %p#lslR + Open=%cd %p/lslR:// # patch regex/\.(diff|patch)(\.bz2)$ - Open=%cd %p#patchfs + Open=%cd %p/patchfs:// View=%view{ascii} bzip2 -dc %f 2>/dev/null regex/\.(diff|patch)(\.(gz|Z))$ - Open=%cd %p#patchfs + Open=%cd %p/patchfs:// View=%view{ascii} gzip -dc %f 2>/dev/null regex/\.(diff|patch)$ - Open=%cd %p#patchfs + Open=%cd %p/patchfs:// View=%view{ascii} /bin/cat %f 2>/dev/null # ar library regex/\.s?a$ - Open=%cd %p#uar + Open=%cd %p/uar:// #Open=%view{ascii} ar tv %f View=%view{ascii} file %f && nm -C %f # trpm regex/\.trpm$ - Open=%cd %p#trpm + Open=%cd %p/trpm:// View=%view{ascii} rpm -qivl --scripts `basename %p .trpm` # RPM packages (SuSE uses *.spm for source packages) regex/\.(src\.rpm|spm)$ - Open=%cd %p#rpm + Open=%cd %p/rpm:// View=%view{ascii} if rpm --nosignature --version >/dev/null 2>&1; then RPM="rpm --nosignature" ; else RPM="rpm" ; fi ; $RPM -qivlp --scripts %f regex/\.rpm$ - Open=%cd %p#rpm + Open=%cd %p/rpm:// View=%view{ascii} if rpm --nosignature --version >/dev/null 2>&1; then RPM="rpm --nosignature" ; else RPM="rpm" ; fi ; $RPM -qivlp --scripts %f # deb regex/\.u?deb$ - Open=%cd %p#deb + Open=%cd %p/deb:// View=%view{ascii} dpkg-deb -I %f && echo && dpkg-deb -c %f # dpkg shell/.debd - Open=%cd %p#debd + Open=%cd %p/debd:// View=%view{ascii} dpkg -s `echo %p | sed 's/\([0-9a-z.-]*\).*/\1/'` # apt shell/.deba - Open=%cd %p#deba + Open=%cd %p/deba:// View=%view{ascii} apt-cache show `echo %p | sed 's/\([0-9a-z.-]*\).*/\1/'` # ISO9660 regex/\.([iI][sS][oO])$ - Open=%cd %p#iso9660 + Open=%cd %p/iso9660:// View=%view{ascii} isoinfo -l -i %f # 7zip archives (they are not man pages) regex/\.(7z|7Z)$ - Open=%cd %p#u7z + Open=%cd %p/u7z:// View=%view{ascii} 7za l %f 2>/dev/null # Mailboxes type/^ASCII\ mail\ text - Open=%cd %p#mailfs + Open=%cd %p/mailfs:// ### Sources ### @@ -574,7 +574,7 @@ regex/\.(rexx?|cmd)$ # Disk images for Commodore computers (VIC20, C64, C128) regex/\.(d64|D64)$ - Open=%cd %p#uc1541 + Open=%cd %p/uc1541:// View=%view{ascii} c1541 %f -list Extract=c1541 %f -extract @@ -595,25 +595,25 @@ regex/\.(lyx|LYX)$ # ace regex/\.(ace|ACE)$ - Open=%cd %p#uace + Open=%cd %p/uace:// View=%view{ascii} unace l %f Extract=unace x %f # arc regex/\.(arc|ARC)$ - Open=%cd %p#uarc + Open=%cd %p/uarc:// View=%view{ascii} arc l %f Extract=arc x %f '*' Extract (with flags)=I=%{Enter any Arc flags:}; if test -n "$I"; then arc x $I %f; fi # zip type/^([Zz][Ii][Pp])\ archive - Open=%cd %p#uzip + Open=%cd %p/uzip:// View=%view{ascii} unzip -v %f # zoo regex/\.([Zz][Oo][Oo])$ - Open=%cd %p#uzoo + Open=%cd %p/uzoo:// View=%view{ascii} zoo l %f # gzip diff --git a/src/filemanager/panel.c b/src/filemanager/panel.c index 3533e4504..2794580fa 100644 --- a/src/filemanager/panel.c +++ b/src/filemanager/panel.c @@ -2582,14 +2582,18 @@ static const char * get_parent_dir_name (const char *cwd, const char *lwd) { size_t llen, clen; + const char *p; llen = strlen (lwd); clen = strlen (cwd); - if (llen > clen) - { - const char *p; + if (llen <= clen) + return NULL; + p = g_strrstr (lwd, VFS_PATH_URL_DELIMITER); + + if (p == NULL) + { p = strrchr (lwd, PATH_SEP); if ((p != NULL) @@ -2597,9 +2601,14 @@ get_parent_dir_name (const char *cwd, const char *lwd) && (clen == (size_t) (p - lwd) || ((p == lwd) && (cwd[0] == PATH_SEP) && (cwd[1] == '\0')))) return (p + 1); + + return NULL; } - return NULL; + while (--p > lwd && *p != PATH_SEP); + while (--p > lwd && *p != PATH_SEP); + + return (p != lwd) ? p + 1 : NULL; } /* --------------------------------------------------------------------------------------------- */ diff --git a/src/vfs/extfs/extfs.c b/src/vfs/extfs/extfs.c index a0e4a8286..62d5e47e2 100644 --- a/src/vfs/extfs/extfs.c +++ b/src/vfs/extfs/extfs.c @@ -350,7 +350,9 @@ extfs_fill_names (struct vfs_class *me, fill_names_f func) char *name; info = &g_array_index (extfs_plugins, extfs_plugin_info_t, a->fstype); - name = g_strconcat (a->name ? a->name : "", "#", info->prefix, (char *) NULL); + name = + g_strconcat (a->name ? a->name : "", "/", info->prefix, VFS_PATH_URL_DELIMITER, + (char *) NULL); func (name); g_free (name); a = a->next; -- 2.11.4.GIT