mirror of https://github.com/MidnightCommander/mc
vfs_path: Fixed broken relative paths processing.
Signed-off-by: Slava Zanko <slavazanko@gmail.com>
This commit is contained in:
parent
2f744e86a2
commit
05d220a9c6
|
@ -436,7 +436,7 @@ mc_opendir (const vfs_path_t * vpath)
|
|||
path_element->dir.info = info;
|
||||
|
||||
path_element->dir.converter = (path_element->encoding != NULL) ?
|
||||
str_crt_conv_from (path_element->encoding) : str_cnv_from_term;
|
||||
str_crt_conv_from (path_element->encoding) : str_cnv_from_term;
|
||||
if (path_element->dir.converter == INVALID_CONV)
|
||||
path_element->dir.converter = str_cnv_from_term;
|
||||
|
||||
|
@ -612,7 +612,7 @@ mc_getlocalcopy (const vfs_path_t * pathname_vpath)
|
|||
if (vfs_path_element_valid (path_element))
|
||||
{
|
||||
result = path_element->class->getlocalcopy != NULL ?
|
||||
path_element->class-> getlocalcopy (pathname_vpath) :
|
||||
path_element->class->getlocalcopy (pathname_vpath) :
|
||||
mc_def_getlocalcopy (pathname_vpath);
|
||||
if (result == NULL)
|
||||
errno = vfs_ferrno (path_element->class);
|
||||
|
@ -658,6 +658,7 @@ mc_chdir (const vfs_path_t * vpath)
|
|||
vfsid old_vfsid;
|
||||
int result;
|
||||
const vfs_path_element_t *path_element;
|
||||
vfs_path_t *abcolute_vpath;
|
||||
|
||||
if (vpath == NULL)
|
||||
return -1;
|
||||
|
@ -669,10 +670,13 @@ mc_chdir (const vfs_path_t * vpath)
|
|||
return -1;
|
||||
}
|
||||
|
||||
result = (*path_element->class->chdir) (vpath);
|
||||
abcolute_vpath = vfs_path_to_absolute (vpath);
|
||||
|
||||
result = (*path_element->class->chdir) (abcolute_vpath);
|
||||
|
||||
if (result == -1)
|
||||
{
|
||||
vfs_path_free (abcolute_vpath);
|
||||
errno = vfs_ferrno (path_element->class);
|
||||
return -1;
|
||||
}
|
||||
|
@ -681,7 +685,8 @@ mc_chdir (const vfs_path_t * vpath)
|
|||
old_vfs = current_vfs;
|
||||
|
||||
/* Actually change directory */
|
||||
vfs_set_raw_current_dir (vfs_path_clone (vpath));
|
||||
vfs_set_raw_current_dir (abcolute_vpath);
|
||||
|
||||
current_vfs = path_element->class;
|
||||
|
||||
/* This function uses the new current_dir implicitly */
|
||||
|
|
|
@ -352,13 +352,14 @@ vfs_path_is_str_path_deprecated (const char *path_str)
|
|||
*/
|
||||
|
||||
static vfs_path_t *
|
||||
vfs_path_from_str_deprecated_parser (char *path)
|
||||
vfs_path_from_str_deprecated_parser (char *path, vfs_path_flag_t flags)
|
||||
{
|
||||
vfs_path_t *vpath;
|
||||
vfs_path_element_t *element;
|
||||
struct vfs_class *class;
|
||||
const char *local, *op;
|
||||
|
||||
(void) flags;
|
||||
vpath = vfs_path_new ();
|
||||
|
||||
while ((class = _vfs_split_with_semi_skip_count (path, &local, &op, 0)) != NULL)
|
||||
|
@ -411,7 +412,7 @@ vfs_path_from_str_deprecated_parser (char *path)
|
|||
*/
|
||||
|
||||
static vfs_path_t *
|
||||
vfs_path_from_str_uri_parser (char *path)
|
||||
vfs_path_from_str_uri_parser (char *path, vfs_path_flag_t flags)
|
||||
{
|
||||
vfs_path_t *vpath;
|
||||
vfs_path_element_t *element;
|
||||
|
@ -419,6 +420,7 @@ vfs_path_from_str_uri_parser (char *path)
|
|||
char *url_delimiter;
|
||||
|
||||
vpath = vfs_path_new ();
|
||||
vpath->relative = (flags & VPF_NO_CANON) != 0;
|
||||
|
||||
while ((url_delimiter = g_strrstr (path, VFS_PATH_URL_DELIMITER)) != NULL)
|
||||
{
|
||||
|
@ -573,7 +575,7 @@ vfs_path_strip_home (const char *dir)
|
|||
* @return pointer to newly created string.
|
||||
*/
|
||||
|
||||
#define vfs_append_from_path(appendfrom) \
|
||||
#define vfs_append_from_path(appendfrom, is_relative) \
|
||||
{ \
|
||||
if ((flags & VPF_STRIP_HOME) && element_index == 0 && (element->class->flags & VFSF_LOCAL) != 0) \
|
||||
{ \
|
||||
|
@ -584,8 +586,8 @@ vfs_path_strip_home (const char *dir)
|
|||
} \
|
||||
else \
|
||||
{ \
|
||||
if ((*appendfrom != PATH_SEP) && (*appendfrom != '\0') \
|
||||
&& (buffer->str[buffer->len - 1] != PATH_SEP)) \
|
||||
if ((!is_relative) && (*appendfrom != PATH_SEP) && (*appendfrom != '\0') \
|
||||
&& (buffer->len == 0 || buffer->str[buffer->len - 1] != PATH_SEP)) \
|
||||
g_string_append_c (buffer, PATH_SEP); \
|
||||
g_string_append (buffer, appendfrom); \
|
||||
} \
|
||||
|
@ -613,14 +615,13 @@ vfs_path_to_str_flags (const vfs_path_t * vpath, int elements_count, vfs_path_fl
|
|||
for (element_index = 0; element_index < elements_count; element_index++)
|
||||
{
|
||||
const vfs_path_element_t *element;
|
||||
gboolean is_relative = vpath->relative && (element_index == 0);
|
||||
|
||||
element = vfs_path_get_by_index (vpath, element_index);
|
||||
|
||||
if (element->vfs_prefix != NULL)
|
||||
{
|
||||
char *url_str;
|
||||
|
||||
if (buffer->len == 0 || buffer->str[buffer->len - 1] != PATH_SEP)
|
||||
if ((!is_relative) && (buffer->len == 0 || buffer->str[buffer->len - 1] != PATH_SEP))
|
||||
g_string_append_c (buffer, PATH_SEP);
|
||||
|
||||
g_string_append (buffer, element->vfs_prefix);
|
||||
|
@ -638,18 +639,19 @@ vfs_path_to_str_flags (const vfs_path_t * vpath, int elements_count, vfs_path_fl
|
|||
{
|
||||
if ((flags & VPF_HIDE_CHARSET) == 0)
|
||||
{
|
||||
if (buffer->len == 0 || buffer->str[buffer->len - 1] != PATH_SEP)
|
||||
if ((!is_relative)
|
||||
&& (buffer->len == 0 || 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);
|
||||
}
|
||||
str_vfs_convert_from (element->dir.converter, element->path, recode_buffer);
|
||||
vfs_append_from_path (recode_buffer->str);
|
||||
vfs_append_from_path (recode_buffer->str, is_relative);
|
||||
g_string_set_size (recode_buffer, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
vfs_append_from_path (element->path);
|
||||
vfs_append_from_path (element->path, is_relative);
|
||||
}
|
||||
}
|
||||
g_string_free (recode_buffer, TRUE);
|
||||
|
@ -717,9 +719,9 @@ vfs_path_from_str_flags (const char *path_str, vfs_path_flag_t flags)
|
|||
return NULL;
|
||||
|
||||
if ((flags & VPF_USE_DEPRECATED_PARSER) != 0 && vfs_path_is_str_path_deprecated (path))
|
||||
vpath = vfs_path_from_str_deprecated_parser (path);
|
||||
vpath = vfs_path_from_str_deprecated_parser (path, flags);
|
||||
else
|
||||
vpath = vfs_path_from_str_uri_parser (path);
|
||||
vpath = vfs_path_from_str_uri_parser (path, flags);
|
||||
|
||||
g_free (path);
|
||||
|
||||
|
@ -884,14 +886,14 @@ vfs_path_clone (const vfs_path_t * vpath)
|
|||
return NULL;
|
||||
|
||||
new_vpath = vfs_path_new ();
|
||||
new_vpath->relative = vpath->relative;
|
||||
|
||||
for (vpath_element_index = 0; vpath_element_index < vfs_path_elements_count (vpath);
|
||||
vpath_element_index++)
|
||||
{
|
||||
vfs_path_element_t *path_element;
|
||||
|
||||
path_element =
|
||||
vfs_path_element_clone (vfs_path_get_by_index (vpath, vpath_element_index));
|
||||
path_element = vfs_path_element_clone (vfs_path_get_by_index (vpath, vpath_element_index));
|
||||
g_array_append_val (new_vpath->path, path_element);
|
||||
}
|
||||
|
||||
|
@ -1217,8 +1219,7 @@ vfs_path_append_vpath_new (const vfs_path_t * first_vpath, ...)
|
|||
{
|
||||
vfs_path_element_t *path_element;
|
||||
|
||||
path_element =
|
||||
vfs_path_element_clone (vfs_path_get_by_index (current_vpath, vindex));
|
||||
path_element = vfs_path_element_clone (vfs_path_get_by_index (current_vpath, vindex));
|
||||
g_array_append_val (ret_vpath->path, path_element);
|
||||
}
|
||||
current_vpath = va_arg (args, const vfs_path_t *);
|
||||
|
@ -1512,3 +1513,27 @@ vfs_path_len (const vfs_path_t * vpath)
|
|||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Convert relative vpath object to absolute
|
||||
*
|
||||
* @param vpath path object
|
||||
*
|
||||
* @return absolute path object
|
||||
*/
|
||||
|
||||
vfs_path_t *
|
||||
vfs_path_to_absolute (const vfs_path_t * vpath)
|
||||
{
|
||||
vfs_path_t *absolute_vpath;
|
||||
char *path_str;
|
||||
|
||||
if (!vpath->relative)
|
||||
return vfs_path_clone (vpath);
|
||||
|
||||
path_str = vfs_path_to_str (vpath);
|
||||
absolute_vpath = vfs_path_from_str (path_str);
|
||||
g_free (path_str);
|
||||
return absolute_vpath;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
|
|
@ -25,6 +25,7 @@ struct vfs_url_struct;
|
|||
|
||||
typedef struct
|
||||
{
|
||||
gboolean relative;
|
||||
GArray *path;
|
||||
} vfs_path_t;
|
||||
|
||||
|
@ -85,6 +86,7 @@ char *vfs_path_build_url_params_str (const vfs_path_element_t * element, gboolea
|
|||
size_t vfs_path_len (const vfs_path_t * vpath);
|
||||
int vfs_path_cmp (const vfs_path_t * vpath1, const vfs_path_t * vpath2);
|
||||
int vfs_path_ncmp (const vfs_path_t * vpath1, const vfs_path_t * vpath2, size_t len);
|
||||
vfs_path_t *vfs_path_to_absolute (const vfs_path_t * vpath);
|
||||
|
||||
/*** inline functions ****************************************************************************/
|
||||
|
||||
|
|
|
@ -574,7 +574,7 @@ nice_cd (const char *text, const char *xtext, const char *help,
|
|||
{
|
||||
vfs_path_t *cd_vpath;
|
||||
|
||||
cd_vpath = vfs_path_from_str (cd_path);
|
||||
cd_vpath = vfs_path_from_str_flags (cd_path, VPF_NO_CANON);
|
||||
if (!do_panel_cd (MENU_PANEL, cd_vpath, cd_parse_command))
|
||||
message (D_ERROR, MSG_ERROR, _("Cannot chdir to \"%s\""), cd_path);
|
||||
vfs_path_free (cd_vpath);
|
||||
|
|
|
@ -426,7 +426,7 @@ do_cd_command (char *orig_cmd)
|
|||
if (*path == '\0')
|
||||
q_vpath = vfs_path_from_str (mc_config_get_home_dir());
|
||||
else
|
||||
q_vpath = vfs_path_from_str (path);
|
||||
q_vpath = vfs_path_from_str_flags (path, VPF_NO_CANON);
|
||||
|
||||
ok = do_cd (q_vpath, cd_parse_command);
|
||||
if (!ok)
|
||||
|
|
|
@ -366,7 +366,7 @@ exec_extension (const char *filename, const char *lc_data, int *move_dir, int st
|
|||
q--;
|
||||
q[1] = 0;
|
||||
|
||||
p_vpath = vfs_path_from_str (p);
|
||||
p_vpath = vfs_path_from_str_flags (p, VPF_NO_CANON);
|
||||
do_cd (p_vpath, cd_parse_command);
|
||||
vfs_path_free (p_vpath);
|
||||
}
|
||||
|
|
|
@ -2967,34 +2967,18 @@ static gboolean
|
|||
_do_panel_cd (WPanel * panel, const vfs_path_t * new_dir_vpath, enum cd_enum cd_type)
|
||||
{
|
||||
char *olddir;
|
||||
char temp[MC_MAXPATHLEN];
|
||||
char *new_dir, *_new_dir;
|
||||
|
||||
_new_dir = new_dir = vfs_path_to_str (new_dir_vpath);
|
||||
|
||||
if (cd_type == cd_parse_command)
|
||||
{
|
||||
while (*new_dir == ' ')
|
||||
new_dir++;
|
||||
}
|
||||
|
||||
olddir = vfs_path_to_str (panel->cwd_vpath);
|
||||
|
||||
/* Convert *new_path to a suitable pathname, handle ~user */
|
||||
|
||||
if (cd_type == cd_parse_command)
|
||||
{
|
||||
if (strcmp (new_dir, "-") == 0)
|
||||
{
|
||||
char *tmp_path;
|
||||
const vfs_path_element_t *element;
|
||||
|
||||
tmp_path = vfs_path_to_str (panel->lwd_vpath);
|
||||
strcpy (temp, tmp_path);
|
||||
new_dir = temp;
|
||||
g_free (tmp_path);
|
||||
}
|
||||
element = vfs_path_get_by_index (new_dir_vpath, 0);
|
||||
if (strcmp (element->path, "-") == 0)
|
||||
new_dir_vpath = panel->lwd_vpath;
|
||||
}
|
||||
g_free (_new_dir);
|
||||
|
||||
if (mc_chdir (new_dir_vpath) == -1)
|
||||
{
|
||||
|
|
|
@ -232,6 +232,43 @@ END_TEST
|
|||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
START_TEST (test_vfs_path_relative)
|
||||
{
|
||||
vfs_path_t *vpath, *copy_vpath;
|
||||
char *path_str;
|
||||
|
||||
vpath = vfs_path_from_str_flags("../bla-bla", VPF_NO_CANON);
|
||||
fail_unless (vpath->relative, "relative flag fail!\n");
|
||||
|
||||
path_str = vfs_path_to_str (vpath);
|
||||
|
||||
fail_unless (strcmp(path_str, "../bla-bla") == 0, "relative fail!\nactual: [%s]\n", path_str);
|
||||
g_free (path_str);
|
||||
|
||||
path_str = (char *) vfs_path_get_last_path_str (vpath);
|
||||
fail_unless (strcmp(path_str, "../bla-bla") == 0, "relative fail!\nactual: element->path=[%s]\n", path_str);
|
||||
|
||||
copy_vpath = vfs_path_clone (vpath);
|
||||
|
||||
path_str = vfs_path_to_str (copy_vpath);
|
||||
|
||||
fail_unless (strcmp(path_str, "../bla-bla") == 0, "relative fail!\nactual: [%s]\n", path_str);
|
||||
g_free (path_str);
|
||||
|
||||
vfs_path_free (copy_vpath);
|
||||
vfs_path_free (vpath);
|
||||
|
||||
vpath = vfs_path_from_str_flags ("../path/test1://user:pass@some.host:12345/bla-bla/some/path/", VPF_NO_CANON);
|
||||
path_str = vfs_path_to_str (vpath);
|
||||
fail_unless (strcmp(path_str, "../path/test1://user:pass@some.host:12345/bla-bla/some/path/") == 0, "relative fail!\nactual: [%s]\n", path_str);
|
||||
g_free (path_str);
|
||||
vfs_path_free (vpath);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
|
@ -247,6 +284,7 @@ main (void)
|
|||
tcase_add_test (tc_core, test_vfs_path_tokens_count);
|
||||
tcase_add_test (tc_core, test_vfs_path_tokens_get);
|
||||
tcase_add_test (tc_core, test_vfs_path_append_vpath);
|
||||
tcase_add_test (tc_core, test_vfs_path_relative);
|
||||
/* *********************************** */
|
||||
|
||||
suite_add_tcase (s, tc_core);
|
||||
|
|
Loading…
Reference in New Issue