summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@src.gnome.org>2007-09-13 13:42:03 +0000
committerAlexander Larsson <alexl@src.gnome.org>2007-09-13 13:42:03 +0000
commitcfe629c134e41e8ade484a2b8294c7a11137220b (patch)
tree39918cd966f0486e5f9252524f48935e4a4a4a5e
parentf366fe009d8d4f66738ad541d7c8fd05ae762d4f (diff)
downloadgvfs-cfe629c134e41e8ade484a2b8294c7a11137220b.tar.gz
Move the uri parsing to modules
Original git commit by Alexander Larsson <alexl@redhat.com> at 1179152686 +0200 svn path=/trunk/; revision=564
-rw-r--r--client/Makefile.am23
-rw-r--r--client/gdaemonfile.c24
-rw-r--r--client/gdaemonvfs.c236
-rw-r--r--client/gdaemonvfs.h24
-rw-r--r--client/gvfsmapuri.h33
-rw-r--r--client/gvfsuriutils.c57
-rw-r--r--client/gvfsuriutils.h5
-rw-r--r--client/smburi.c178
-rw-r--r--common/Makefile.am7
-rw-r--r--daemon/Makefile.am2
10 files changed, 440 insertions, 149 deletions
diff --git a/client/Makefile.am b/client/Makefile.am
index 1077b786..6b4ec290 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -4,12 +4,13 @@ INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/gvfs \
-I$(top_srcdir)/common \
$(GLIB_CFLAGS) $(DBUS_CFLAGS) \
-DG_LOG_DOMAIN=\"GVFS\" -DG_DISABLE_DEPRECATED \
+ -DGVFS_MODULE_DIR=\"$(libdir)/gvfs/modules\" \
-DDBUS_API_SUBJECT_TO_CHANGE
-module_flags = -export_dynamic -avoid-version -module -no-undefined
-modulesdir = $(libdir)/gio/gvfs-modules
+giomodule_flags = -export_dynamic -avoid-version -module -no-undefined
+giomodulesdir = $(libdir)/gio/gvfs-modules
-modules_LTLIBRARIES = libgvfsdbus.la
+giomodules_LTLIBRARIES = libgvfsdbus.la
libgvfsdbus_la_LDFLAGS = $(module_flags)
libgvfsdbus_la_SOURCES = \
@@ -26,6 +27,20 @@ libgvfsdbus_la_SOURCES = \
libgvfsdbus_la_LIBADD = \
$(top_builddir)/gio/libgio.la \
- $(top_builddir)/common/libcommon.la \
+ $(top_builddir)/common/libgvfscommon.la \
$(DBUS_LIBS) \
$(GLIB_LIBS)
+
+libvfsomodule_flags = -export_dynamic -avoid-version -module -no-undefined
+libvfsmodules_LTLIBRARIES = libsmb.la
+libvfsmodulesdir = $(libdir)/gvfs/modules
+
+libsmb_la_LDFLAGS = $(module_flags)
+libsmb_la_SOURCES = \
+ smburi.c \
+ $(NULL)
+
+libsmb_la_LIBADD = \
+ $(top_builddir)/gio/libgio.la \
+ $(top_builddir)/common/libgvfscommon.la \
+ $(GLIB_LIBS)
diff --git a/client/gdaemonfile.c b/client/gdaemonfile.c
index d79c9fd4..27eb200c 100644
--- a/client/gdaemonfile.c
+++ b/client/gdaemonfile.c
@@ -170,15 +170,31 @@ g_daemon_file_get_path (GFile *file)
static char *
g_daemon_file_get_uri (GFile *file)
{
- /* TODO: implement to-uri */
- return NULL;
+ GDaemonFile *daemon_file = G_DAEMON_FILE (file);
+ GDecodedUri *uri;
+
+ uri = _g_daemon_vfs_get_uri_for_mountspec (daemon_file->mount_spec,
+ daemon_file->path);
+
+ if (uri == NULL)
+ return NULL;
+
+ return _g_encode_uri (uri, FALSE);
}
static char *
g_daemon_file_get_parse_name (GFile *file)
{
- /* TODO: implement to-iri */
- return NULL;
+ GDaemonFile *daemon_file = G_DAEMON_FILE (file);
+ GDecodedUri *uri;
+
+ uri = _g_daemon_vfs_get_uri_for_mountspec (daemon_file->mount_spec,
+ daemon_file->path);
+
+ if (uri == NULL)
+ return NULL;
+
+ return _g_encode_uri (uri, TRUE);
}
static GFile *
diff --git a/client/gdaemonvfs.c b/client/gdaemonvfs.c
index 1cc9b98f..701eaa35 100644
--- a/client/gdaemonvfs.c
+++ b/client/gdaemonvfs.c
@@ -6,9 +6,11 @@
#include "gdaemonfile.h"
#include <gio/glocalvfs.h>
#include <gvfsdaemonprotocol.h>
+#include <gmodule.h>
#include "gvfsdaemondbus.h"
#include "gdbusutils.h"
#include "gmountspec.h"
+#include "gvfsmapuri.h"
static void g_daemon_vfs_class_init (GDaemonVfsClass *class);
static void g_daemon_vfs_vfs_iface_init (GVfsIface *iface);
@@ -22,6 +24,10 @@ struct _GDaemonVfs
GVfs *wrapped_vfs;
GList *mount_cache;
+
+
+ GHashTable *from_uri_hash;
+ GHashTable *to_uri_hash;
};
static GDaemonVfs *the_vfs = NULL;
@@ -44,37 +50,29 @@ g_daemon_vfs_class_init (GDaemonVfsClass *class)
static void
g_daemon_vfs_finalize (GObject *object)
{
- /* must chain up */
- G_OBJECT_CLASS (g_daemon_vfs_parent_class)->finalize (object);
-}
+ GDaemonVfs *vfs;
-static char *
-normalize_smb_name (const char *name, gssize len)
-{
- gboolean valid_utf8;
+ vfs = G_DAEMON_VFS (object);
- valid_utf8 = g_utf8_validate (name, len, NULL);
+ g_hash_table_destroy (vfs->from_uri_hash);
+ g_hash_table_destroy (vfs->to_uri_hash);
- if (valid_utf8)
- return g_utf8_casefold (name, len);
- else
- return g_ascii_strdown (name, len);
+ /* must chain up */
+ G_OBJECT_CLASS (g_daemon_vfs_parent_class)->finalize (object);
}
static void
-get_mountspec_from_uri (GDecodedUri *uri,
+get_mountspec_from_uri (GDaemonVfs *vfs,
+ GDecodedUri *uri,
GMountSpec **spec_out,
char **path_out)
{
GMountSpec *spec;
- char *path, *tmp;
- const char *p;
- const char *share, *share_end;
+ char *path;
+ g_mountspec_from_uri_func func;
/* TODO: Share MountSpec objects between files (its refcounted) */
- /* TODO: Make less hardcoded */
-
spec = NULL;
if (strcmp (uri->scheme, "test") == 0)
@@ -82,112 +80,88 @@ get_mountspec_from_uri (GDecodedUri *uri,
spec = g_mount_spec_new ("test");
path = g_strdup (uri->path);
}
- else if (strcmp (uri->scheme, "smb") == 0)
+ else
{
- if (uri->host == NULL || strlen (uri->host) == 0)
- {
- /* uri form: smb:/// or smb:///$path */
- spec = g_mount_spec_new ("smb-network");
- if (uri->path == NULL || *uri->path == 0)
- path = g_strdup ("/");
- else
- path = g_strdup (uri->path);
- }
- else
+ func = g_hash_table_lookup (vfs->from_uri_hash, uri->scheme);
+ if (func)
+ func (uri, &spec, &path);
+ }
+
+ if (spec == NULL)
+ {
+ spec = g_mount_spec_new (uri->scheme);
+ path = g_strdup (uri->path);
+ }
+
+ *spec_out = spec;
+ *path_out = path;
+}
+
+static void
+load_vfs_module (GDaemonVfs *vfs,
+ const char *filename)
+{
+ GModule *module;
+ gpointer ptr;
+
+ module = g_module_open (filename, G_MODULE_BIND_LOCAL);
+ if (module)
+ {
+ if (g_module_symbol (module, G_STRINGIFY(G_VFS_MAP_FROM_URI_TABLE_NAME), &ptr))
{
- /* host set */
- p = uri->path;
- while (p && *p == '/')
- p++;
+ GVfsMapFromUri *from_uri_table = ptr;
- if (p == NULL || *p == 0)
+ while (from_uri_table->scheme != NULL)
{
- /* uri form: smb://$host/ */
- spec = g_mount_spec_new ("smb-server");
- tmp = normalize_smb_name (uri->host, -1);
- g_mount_spec_set (spec, "server", tmp);
- g_free (tmp);
- path = g_strdup ("/");
- }
- else
- {
- share = p;
- share_end = strchr (share, '/');
- if (share_end == NULL)
- share_end = share + strlen (share);
-
- p = share_end;
-
- while (*p == '/')
- p++;
-
- if (*p == 0)
- {
- /* uri form: smb://$host/$share/
- * Here we special case smb-server files by adding "_." to the names in the uri */
- if (share[0] == '_' && share[1] == '.')
- {
- spec = g_mount_spec_new ("smb-server");
- tmp = normalize_smb_name (uri->host, -1);
- g_mount_spec_set (spec, "server", tmp);
- g_free (tmp);
- tmp = normalize_smb_name (share + 2, share_end - (share + 2));
- path = g_strconcat ("/", tmp, NULL);
- g_free (tmp);
- }
- else
- {
- spec = g_mount_spec_new ("smb-share");
- tmp = normalize_smb_name (uri->host, -1);
- g_mount_spec_set (spec, "server", tmp);
- g_free (tmp);
- tmp = normalize_smb_name (share, share_end - share);
- g_mount_spec_set (spec, "share", tmp);
- g_free (tmp);
- path = g_strdup ("/");
- }
- }
- else
- {
- spec = g_mount_spec_new ("smb-share");
-
- tmp = normalize_smb_name (uri->host, -1);
- g_mount_spec_set (spec, "server", tmp);
- g_free (tmp);
-
- tmp = normalize_smb_name (share, share_end - share);
- g_mount_spec_set (spec, "share", tmp);
- g_free (tmp);
-
- path = g_strconcat ("/", p, NULL);
- }
+ g_print ("from %s: %p\n", from_uri_table->scheme, from_uri_table->func);
+ g_hash_table_insert (vfs->from_uri_hash,
+ from_uri_table->scheme, from_uri_table->func);
+ from_uri_table++;
}
}
- if (uri->userinfo)
+
+ if (g_module_symbol (module, G_STRINGIFY(G_VFS_MAP_TO_URI_TABLE_NAME), &ptr))
{
- const char *user = uri->userinfo;
- p = strchr (uri->userinfo, ';');
- if (p)
+ GVfsMapToUri *to_uri_table = ptr;
+
+ while (to_uri_table->mount_type != NULL)
{
- if (p != user)
- g_mount_spec_set_with_len (spec, "domain", user, p - user);
- user = p + 1;
+ g_print ("to %s: %p\n", to_uri_table->mount_type, to_uri_table->func);
+ g_hash_table_insert (vfs->to_uri_hash,
+ to_uri_table->mount_type, to_uri_table->func);
+ to_uri_table++;
}
- if (*user != 0)
- g_mount_spec_set (spec, "user", user);
}
}
+}
- if (spec == NULL)
+static void
+load_vfs_module_dir (GDaemonVfs *vfs,
+ const char *dirname)
+{
+ GDir *dir;
+
+ dir = g_dir_open (dirname, 0, NULL);
+ if (dir)
{
- tmp = g_strdup_printf ("unknown-%s", uri->scheme);
- spec = g_mount_spec_new (tmp);
- g_free (tmp);
- path = g_strdup (uri->path);
+ const char *name;
+
+ while ((name = g_dir_read_name (dir)))
+ {
+ if (g_str_has_suffix (name, "." G_MODULE_SUFFIX))
+ {
+ char *filename;
+
+ filename = g_build_filename (dirname,
+ name,
+ NULL);
+ load_vfs_module (vfs, filename);
+ g_free (filename);
+ }
+ }
+
+ g_dir_close (dir);
}
-
- *spec_out = spec;
- *path_out = path;
}
static void
@@ -195,6 +169,9 @@ g_daemon_vfs_init (GDaemonVfs *vfs)
{
g_assert (the_vfs == NULL);
the_vfs = vfs;
+
+ vfs->from_uri_hash = g_hash_table_new (g_str_hash, g_str_equal);
+ vfs->to_uri_hash = g_hash_table_new (g_str_hash, g_str_equal);
vfs->wrapped_vfs = g_local_vfs_new ();
@@ -205,6 +182,9 @@ g_daemon_vfs_init (GDaemonVfs *vfs)
if (vfs->bus)
_g_dbus_connection_integrate_with_main (vfs->bus);
+
+
+ load_vfs_module_dir (vfs, GVFS_MODULE_DIR);
}
GDaemonVfs *
@@ -242,7 +222,7 @@ g_daemon_vfs_get_file_for_uri (GVfs *vfs,
file = g_daemon_vfs_get_file_for_path (vfs, decoded->path);
else
{
- get_mountspec_from_uri (decoded, &spec, &path);
+ get_mountspec_from_uri (daemon_vfs, decoded, &spec, &path);
file = g_daemon_file_new (spec, path);
g_mount_spec_unref (spec);
g_free (path);
@@ -253,6 +233,37 @@ g_daemon_vfs_get_file_for_uri (GVfs *vfs,
return file;
}
+GDecodedUri *
+_g_daemon_vfs_get_uri_for_mountspec (GMountSpec *spec,
+ char *path)
+{
+ GDecodedUri *uri;
+ const char *type;
+ g_mountspec_to_uri_func func;
+
+ uri = g_new0 (GDecodedUri, 1);
+ uri->port = -1;
+
+ type = g_mount_spec_get_type (spec);
+ if (type == NULL)
+ {
+ uri->scheme = g_strdup ("unknown");
+ uri->path = g_strdup (path);
+ return uri;
+ }
+
+ func = g_hash_table_lookup (the_vfs->to_uri_hash, type);
+ if (func)
+ func (spec, path, uri);
+
+ if (uri->scheme == NULL)
+ {
+ uri->scheme = g_strdup (type);
+ uri->path = g_strdup (path);
+ }
+
+ return uri;
+}
static GMountRef *
mount_ref_ref (GMountRef *ref)
@@ -261,7 +272,6 @@ mount_ref_ref (GMountRef *ref)
return ref;
}
-
void
_g_mount_ref_unref (GMountRef *ref)
{
@@ -533,7 +543,7 @@ _g_daemon_vfs_get_mount_ref_sync (GMountSpec *spec,
static GFile *
g_daemon_vfs_parse_name (GVfs *vfs,
- const char *parse_name)
+ const char *parse_name)
{
GFile *file;
char *path;
diff --git a/client/gdaemonvfs.h b/client/gdaemonvfs.h
index 4b8905e1..2e797710 100644
--- a/client/gdaemonvfs.h
+++ b/client/gdaemonvfs.h
@@ -4,6 +4,7 @@
#include <gio/gvfs.h>
#include <dbus/dbus.h>
#include "gmountspec.h"
+#include "gvfsuriutils.h"
G_BEGIN_DECLS
@@ -37,16 +38,19 @@ GType g_daemon_vfs_get_type (void) G_GNUC_CONST;
GDaemonVfs *g_daemon_vfs_new (void);
-void _g_daemon_vfs_get_mount_ref_async (GMountSpec *spec,
- const char *path,
- GMountRefLookupCallback callback,
- gpointer user_data);
-GMountRef *_g_daemon_vfs_get_mount_ref_sync (GMountSpec *spec,
- const char *path,
- GError **error);
-const char *_g_mount_ref_resolve_path (GMountRef *ref,
- const char *path);
-void _g_mount_ref_unref (GMountRef *ref);
+GDecodedUri *_g_daemon_vfs_get_uri_for_mountspec (GMountSpec *spec,
+ char *path);
+void _g_daemon_vfs_get_mount_ref_async (GMountSpec *spec,
+ const char *path,
+ GMountRefLookupCallback callback,
+ gpointer user_data);
+GMountRef * _g_daemon_vfs_get_mount_ref_sync (GMountSpec *spec,
+ const char *path,
+ GError **error);
+const char * _g_mount_ref_resolve_path (GMountRef *ref,
+ const char *path);
+void _g_mount_ref_unref (GMountRef *ref);
+
G_END_DECLS
diff --git a/client/gvfsmapuri.h b/client/gvfsmapuri.h
new file mode 100644
index 00000000..b6a0dbb1
--- /dev/null
+++ b/client/gvfsmapuri.h
@@ -0,0 +1,33 @@
+#ifndef __G_VFS_MAP_URI_H__
+#define __G_VFS_MAP_URI_H__
+
+#include <glib.h>
+#include <gvfsuriutils.h>
+#include <gmountspec.h>
+
+G_BEGIN_DECLS
+
+typedef void (*g_mountspec_from_uri_func) (GDecodedUri *uri,
+ GMountSpec **spec_out,
+ char **path_out);
+typedef void (*g_mountspec_to_uri_func) (GMountSpec *spec,
+ char *path,
+ GDecodedUri *uri);
+
+
+typedef struct {
+ char *scheme;
+ g_mountspec_from_uri_func func;
+} GVfsMapFromUri;
+
+typedef struct {
+ char *mount_type;
+ g_mountspec_to_uri_func func;
+} GVfsMapToUri;
+
+#define G_VFS_MAP_FROM_URI_TABLE_NAME g_vfs_map_from_uri_table
+#define G_VFS_MAP_TO_URI_TABLE_NAME g_vfs_map_to_uri_table
+
+G_END_DECLS
+
+#endif /* __G_VFS_MAP_URI_H__ */
diff --git a/client/gvfsuriutils.c b/client/gvfsuriutils.c
index 8acf8055..9510bf2d 100644
--- a/client/gvfsuriutils.c
+++ b/client/gvfsuriutils.c
@@ -81,6 +81,17 @@ _g_decoded_uri_free (GDecodedUri *decoded)
}
GDecodedUri *
+_g_decoded_uri_new (void)
+{
+ GDecodedUri *uri;
+
+ uri = g_new0 (GDecodedUri, 1);
+ uri->port = -1;
+
+ return uri;
+}
+
+GDecodedUri *
_g_decode_uri (const char *uri)
{
GDecodedUri *decoded;
@@ -115,8 +126,7 @@ _g_decode_uri (const char *uri)
return NULL;
}
- decoded = g_new0 (GDecodedUri, 1);
- decoded->port = -1;
+ decoded = _g_decoded_uri_new ();
decoded->scheme = g_malloc (p - uri);
out = decoded->scheme;
@@ -248,44 +258,65 @@ is_valid (char c, const char *reserved_chars_allowed)
return FALSE;
}
+static gboolean
+gunichar_ok (gunichar c)
+{
+ return
+ (c != (gunichar) -2) &&
+ (c != (gunichar) -1);
+}
+
static void
g_string_append_encoded (GString *string, const char *encoded,
- const char *reserved_chars_allowed)
+ const char *reserved_chars_allowed,
+ gboolean allow_utf8)
{
- char c;
+ unsigned char c;
+ const char *end;
static const gchar hex[16] = "0123456789ABCDEF";
+
+ end = encoded + strlen (encoded);
- while ((c = *encoded++) != 0)
+ while ((c = *encoded) != 0)
{
- if (is_valid (c, reserved_chars_allowed))
- g_string_append_c (string, c);
+ if (c >= 0x80 && allow_utf8 &&
+ gunichar_ok (g_utf8_get_char_validated (encoded, end - encoded)))
+ {
+ int len = g_utf8_skip [c];
+ g_string_append_len (string, encoded, len);
+ encoded += len;
+ }
+ else if (is_valid (c, reserved_chars_allowed))
+ {
+ g_string_append_c (string, c);
+ encoded++;
+ }
else
{
g_string_append_c (string, '%');
g_string_append_c (string, hex[((guchar)c) >> 4]);
g_string_append_c (string, hex[((guchar)c) & 0xf]);
+ encoded++;
}
}
}
char *
-_g_encode_uri (GDecodedUri *decoded)
+_g_encode_uri (GDecodedUri *decoded, gboolean allow_utf8)
{
GString *uri;
uri = g_string_new (NULL);
g_string_append (uri, decoded->scheme);
- g_string_append_c (uri, ':');
+ g_string_append (uri, "://");
if (decoded->host != NULL)
{
- g_string_append (uri, "//");
-
if (decoded->userinfo)
{
/* userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) */
- g_string_append_encoded (uri, decoded->userinfo, SUB_DELIM_CHARS ":");
+ g_string_append_encoded (uri, decoded->userinfo, SUB_DELIM_CHARS ":", allow_utf8);
g_string_append_c (uri, '@');
}
@@ -298,7 +329,7 @@ _g_encode_uri (GDecodedUri *decoded)
}
}
- g_string_append_encoded (uri, decoded->path, SUB_DELIM_CHARS ":@/");
+ g_string_append_encoded (uri, decoded->path, SUB_DELIM_CHARS ":@/", allow_utf8);
if (decoded->query)
{
diff --git a/client/gvfsuriutils.h b/client/gvfsuriutils.h
index 76f8e3a6..6e5fea1c 100644
--- a/client/gvfsuriutils.h
+++ b/client/gvfsuriutils.h
@@ -15,9 +15,12 @@ typedef struct {
char *fragment;
} GDecodedUri;
-char * _g_encode_uri (GDecodedUri *decoded);
+char * _g_encode_uri (GDecodedUri *decoded,
+ gboolean allow_utf8);
void _g_decoded_uri_free (GDecodedUri *decoded);
GDecodedUri *_g_decode_uri (const char *uri);
+GDecodedUri *_g_decoded_uri_new (void);
+
G_END_DECLS
diff --git a/client/smburi.c b/client/smburi.c
new file mode 100644
index 00000000..70724ecf
--- /dev/null
+++ b/client/smburi.c
@@ -0,0 +1,178 @@
+#include <config.h>
+#include <string.h>
+
+#include <gvfsmapuri.h>
+
+
+static char *
+normalize_smb_name (const char *name, gssize len)
+{
+ gboolean valid_utf8;
+
+ valid_utf8 = g_utf8_validate (name, len, NULL);
+
+ if (valid_utf8)
+ return g_utf8_casefold (name, len);
+ else
+ return g_ascii_strdown (name, len);
+}
+
+static void
+smb_from_uri (GDecodedUri *uri,
+ GMountSpec **spec_out,
+ char **path_out)
+{
+ GMountSpec *spec;
+ char *path, *tmp;
+ const char *p;
+ const char *share, *share_end;
+
+ if (uri->host == NULL || strlen (uri->host) == 0)
+ {
+ /* uri form: smb:/// or smb:///$path */
+ spec = g_mount_spec_new ("smb-network");
+ if (uri->path == NULL || *uri->path == 0)
+ path = g_strdup ("/");
+ else
+ path = g_strdup (uri->path);
+ }
+ else
+ {
+ /* host set */
+ p = uri->path;
+ while (p && *p == '/')
+ p++;
+
+ if (p == NULL || *p == 0)
+ {
+ /* uri form: smb://$host/ */
+ spec = g_mount_spec_new ("smb-server");
+ tmp = normalize_smb_name (uri->host, -1);
+ g_mount_spec_set (spec, "server", tmp);
+ g_free (tmp);
+ path = g_strdup ("/");
+ }
+ else
+ {
+ share = p;
+ share_end = strchr (share, '/');
+ if (share_end == NULL)
+ share_end = share + strlen (share);
+
+ p = share_end;
+
+ while (*p == '/')
+ p++;
+
+ if (*p == 0)
+ {
+ /* uri form: smb://$host/$share/
+ * Here we special case smb-server files by adding "._" to the names in the uri */
+ if (share[0] == '.' && share[1] == '_')
+ {
+ spec = g_mount_spec_new ("smb-server");
+ tmp = normalize_smb_name (uri->host, -1);
+ g_mount_spec_set (spec, "server", tmp);
+ g_free (tmp);
+ tmp = normalize_smb_name (share + 2, share_end - (share + 2));
+ path = g_strconcat ("/", tmp, NULL);
+ g_free (tmp);
+ }
+ else
+ {
+ spec = g_mount_spec_new ("smb-share");
+ tmp = normalize_smb_name (uri->host, -1);
+ g_mount_spec_set (spec, "server", tmp);
+ g_free (tmp);
+ tmp = normalize_smb_name (share, share_end - share);
+ g_mount_spec_set (spec, "share", tmp);
+ g_free (tmp);
+ path = g_strdup ("/");
+ }
+ }
+ else
+ {
+ spec = g_mount_spec_new ("smb-share");
+
+ tmp = normalize_smb_name (uri->host, -1);
+ g_mount_spec_set (spec, "server", tmp);
+ g_free (tmp);
+
+ tmp = normalize_smb_name (share, share_end - share);
+ g_mount_spec_set (spec, "share", tmp);
+ g_free (tmp);
+
+ path = g_strconcat ("/", p, NULL);
+ }
+ }
+ }
+
+ if (uri->userinfo)
+ {
+ const char *user = uri->userinfo;
+ p = strchr (uri->userinfo, ';');
+ if (p)
+ {
+ if (p != user)
+ g_mount_spec_set_with_len (spec, "domain", user, p - user);
+ user = p + 1;
+ }
+ if (*user != 0)
+ g_mount_spec_set (spec, "user", user);
+ }
+
+ *spec_out = spec;
+ *path_out = path;
+}
+
+static void
+smb_to_uri (GMountSpec *spec,
+ char *path,
+ GDecodedUri *uri_out)
+{
+ const char *type;
+ const char *server;
+ const char *share;
+
+ type = g_mount_spec_get_type (spec);
+
+ uri_out->scheme = g_strdup ("smb");
+
+ if (strcmp (type, "smb-network") == 0)
+ {
+ uri_out->path = g_strdup (path);
+ }
+ else if (strcmp (type, "smb-server") == 0)
+ {
+ server = g_mount_spec_get (spec, "server");
+ uri_out->host = g_strdup (server);
+
+ /* Map the mountables in server to ._share because the actual share mount maps to smb://server/share */
+ if (path && path[0] == '/' && path[1] != 0)
+ uri_out->path = g_strconcat ("/._", path + 1, NULL);
+ else
+ uri_out->path = g_strdup ("/");
+ }
+ else if (strcmp (type, "smb-share") == 0)
+ {
+ server = g_mount_spec_get (spec, "server");
+ uri_out->host = g_strdup (server);
+ share = g_mount_spec_get (spec, "share");
+ if (path[0] == '/')
+ uri_out->path = g_strconcat ("/", share, path, NULL);
+ else
+ uri_out->path = g_strconcat ("/", share, "/", path, NULL);
+ }
+}
+
+GVfsMapFromUri G_VFS_MAP_FROM_URI_TABLE_NAME [] = {
+ { "smb", smb_from_uri },
+ { NULL }
+};
+
+GVfsMapToUri G_VFS_MAP_TO_URI_TABLE_NAME [] = {
+ { "smb-network", smb_to_uri },
+ { "smb-server", smb_to_uri },
+ { "smb-share", smb_to_uri },
+ { NULL }
+};
diff --git a/common/Makefile.am b/common/Makefile.am
index 522bebea..ef83ae74 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -1,6 +1,6 @@
NULL =
-noinst_LTLIBRARIES=libcommon.la
+lib_LTLIBRARIES=libgvfscommon.la
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/gvfs \
-I$(top_srcdir)/daemon \
@@ -8,7 +8,7 @@ INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/gvfs \
-DG_LOG_DOMAIN=\"GVFS\" -DG_DISABLE_DEPRECATED \
-DDBUS_API_SUBJECT_TO_CHANGE
-libcommon_la_SOURCES = \
+libgvfscommon_la_SOURCES = \
gsysutils.c gsysutils.h \
gdbusutils.c gdbusutils.h \
gmountspec.c gmountspec.h \
@@ -16,8 +16,9 @@ libcommon_la_SOURCES = \
gmountsource.c gmountsource.h \
gmounttracker.c gmounttracker.h \
gvfsdaemonprotocol.h \
+ gvfsmapuri.h \
$(NULL)
-libcommon_la_LIBADD = \
+ligvfsbcommon_la_LIBADD = \
$(DBUS_LIBS) \
$(GLIB_LIBS)
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index fb7bf8b2..fca81c22 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -15,7 +15,7 @@ noinst_LTLIBRARIES=libdaemon.la
libraries = \
$(top_builddir)/gio/libgio.la \
libdaemon.la \
- $(top_builddir)/common/libcommon.la \
+ $(top_builddir)/common/libgvfscommon.la \
$(GLIB_LIBS) $(DBUS_LIBS)
# D-BUS service file