Added function vfs_path_url_split() for parse VFS parameters

Signed-off-by: Slava Zanko <slavazanko@gmail.com>
This commit is contained in:
Slava Zanko 2011-06-13 13:19:47 +03:00
parent 3d1e2df9b7
commit e9ed6a41cf
3 changed files with 147 additions and 7 deletions

View File

@ -86,10 +86,32 @@ 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_SERIALIZED_PATH "g14:path-element-0p4:pathv12:/local/path/p10:class-namev7:localfsp4:portv1:0" \
"g14:path-element-1p4:pathv18:bla-bla/some/path/p10:class-namev7:testfs1p11:raw_url_strv31:test1:user:pass@some.host:12345p4:portv1:0" \
"g14:path-element-2p4:pathv17:bla-bla/some/pathp10:class-namev7:testfs2p8:encodingv6:KOI8-Rp11:raw_url_strv6:test2:p4:portv1:0" \
"g14:path-element-3p4:pathv9:111/22/33p10:class-namev7:testfs3p11:raw_url_strv6:test3:p4:portv1:0"
#define ETALON_SERIALIZED_PATH \
"g14:path-element-0" \
"p4:pathv12:/local/path/" \
"p10:class-namev7:localfs" \
"g14:path-element-1" \
"p4:pathv18:bla-bla/some/path/" \
"p10:class-namev7:testfs1" \
"p11:raw_url_strv31:test1:user:pass@some.host:12345" \
"p10:vfs_prefixv5:test1" \
"p4:userv4:user" \
"p8:passwordv4:pass" \
"p4:hostv9:some.host" \
"p4:portv5:12345" \
"g14:path-element-2" \
"p4:pathv17:bla-bla/some/path" \
"p10:class-namev7:testfs2" \
"p8:encodingv6:KOI8-R" \
"p11:raw_url_strv6:test2:" \
"p10:vfs_prefixv5:test2" \
"p4:hostv0:" \
"g14:path-element-3" \
"p4:pathv9:111/22/33" \
"p10:class-namev7:testfs3" \
"p11:raw_url_strv6:test3:" \
"p10:vfs_prefixv5:test3" \
"p4:hostv0:"
START_TEST (test_path_serialize_deserialize)
{
@ -110,7 +132,7 @@ START_TEST (test_path_serialize_deserialize)
fail_unless (
strcmp (serialized_vpath, ETALON_SERIALIZED_PATH ) == 0,
"serialized_vpath (%s) doesn't equal to etalon (%s)", serialized_vpath, ETALON_SERIALIZED_PATH
"\nserialized_vpath (%s)\nnot equal to etalon (%s)", serialized_vpath, ETALON_SERIALIZED_PATH
);
vpath = vfs_path_deserialize (serialized_vpath, &error);

View File

@ -161,7 +161,6 @@ vfs_canon (const char *path)
}
/* --------------------------------------------------------------------------------------------- */
/** get encoding after last #enc: or NULL, if part does not contain #enc:
*
* @param path string
@ -199,6 +198,106 @@ vfs_get_encoding (const char *path)
}
}
/* --------------------------------------------------------------------------------------------- */
/** Extract the hostname and username from the path
*
* Format of the path is [user@]hostname:port/remote-dir, e.g.:
*
* ftp://sunsite.unc.edu/pub/linux
* ftp://miguel@sphinx.nuclecu.unam.mx/c/nc
* ftp://tsx-11.mit.edu:8192/
* ftp://joe@foo.edu:11321/private
* ftp://joe:password@foo.se
*
* @param path_element is an input string to be parsed
* @param path is an input string to be parsed
*
* @return g_malloc()ed url info.
* If the user is empty, e.g. ftp://@roxanne/private, and URL_USE_ANONYMOUS
* is not set, then the current login name is supplied.
* Return value is a g_malloc()ed structure with the pathname relative to the
* host.
*/
static void
vfs_path_url_split (vfs_path_element_t * path_element, const char *path)
{
char *pcopy;
const char *pend;
char *dir, *colon, *inner_colon, *at, *rest;
path_element->port = 0;
pcopy = g_strdup (path);
pend = pcopy + strlen (pcopy);
dir = pcopy;
/* search for any possible user */
at = strrchr (pcopy, '@');
/* We have a username */
if (at == NULL)
rest = pcopy;
else
{
*at = '\0';
inner_colon = strchr (pcopy, ':');
if (inner_colon != NULL)
{
*inner_colon = '\0';
inner_colon++;
path_element->password = g_strdup (inner_colon);
}
if (*pcopy != '\0')
path_element->user = g_strdup (pcopy);
if (pend == at + 1)
rest = at;
else
rest = at + 1;
}
/* Check if the host comes with a port spec, if so, chop it */
if (*rest != '[')
colon = strchr (rest, ':');
else
{
colon = strchr (++rest, ']');
if (colon != NULL)
{
colon[0] = '\0';
colon[1] = '\0';
colon++;
}
}
if (colon != NULL)
{
*colon = '\0';
if (sscanf (colon + 1, "%d", &path_element->port) == 1)
{
if (path_element->port <= 0 || path_element->port >= 65536)
path_element->port = 0;
}
else
while (*(++colon) != '\0')
{
switch (*colon)
{
case 'C':
path_element->port = 1;
break;
case 'r':
path_element->port = 2;
break;
}
}
}
path_element->host = g_strdup (rest);
g_free (pcopy);
}
/* --------------------------------------------------------------------------------------------- */
/**
* get VFS class for the given name
@ -321,6 +420,7 @@ vfs_path_from_str (const char *path_str)
while ((class = _vfs_split_with_semi_skip_count (path, &local, &op, 0)) != NULL)
{
char *url_params;
element = g_new0 (vfs_path_element_t, 1);
element->class = vfs_prefix_to_class (op);
if (local == NULL)
@ -331,6 +431,18 @@ vfs_path_from_str (const char *path_str)
element->dir.converter = INVALID_CONV;
element->raw_url_str = g_strdup (op);
url_params = strchr (op, ':'); /* skip VFS prefix */
if (url_params != NULL)
{
*url_params = '\0';
url_params++;
vfs_path_url_split (element, url_params);
}
if (*op != '\0')
element->vfs_prefix = g_strdup (op);
vpath->path = g_list_prepend (vpath->path, element);
}
if (path[0] != '\0')
@ -425,6 +537,7 @@ vfs_path_element_clone (const vfs_path_element_t * element)
new_element->host = g_strdup (element->host);
new_element->path = g_strdup (element->path);
new_element->encoding = g_strdup (element->encoding);
new_element->vfs_prefix = g_strdup (element->vfs_prefix);
return new_element;
}
@ -448,6 +561,7 @@ vfs_path_element_free (vfs_path_element_t * element)
g_free (element->host);
g_free (element->path);
g_free (element->encoding);
g_free (element->vfs_prefix);
if (vfs_path_element_need_cleanup_converter (element))
{
@ -607,10 +721,12 @@ vfs_path_serialize (const vfs_path_t * vpath, GError ** error)
mc_config_set_string_raw (cpath, groupname, "encoding", element->encoding);
mc_config_set_string_raw (cpath, groupname, "raw_url_str", element->raw_url_str);
mc_config_set_string_raw (cpath, groupname, "vfs_prefix", element->vfs_prefix);
mc_config_set_string_raw (cpath, groupname, "user", element->user);
mc_config_set_string_raw (cpath, groupname, "password", element->password);
mc_config_set_string_raw (cpath, groupname, "host", element->host);
if (element->port != 0)
mc_config_set_int (cpath, groupname, "port", element->port);
g_free (groupname);
@ -676,6 +792,7 @@ vfs_path_deserialize (const char *data, GError ** error)
element->encoding = mc_config_get_string_raw (cpath, groupname, "encoding", NULL);
element->raw_url_str = mc_config_get_string_raw (cpath, groupname, "raw_url_str", NULL);
element->vfs_prefix = mc_config_get_string_raw (cpath, groupname, "vfs_prefix", NULL);
element->user = mc_config_get_string_raw (cpath, groupname, "user", NULL);
element->password = mc_config_get_string_raw (cpath, groupname, "password", NULL);

View File

@ -24,6 +24,7 @@ typedef struct
char *path;
struct vfs_class *class;
char *encoding;
char *vfs_prefix;
struct
{