summaryrefslogtreecommitdiff
path: root/client/smburi.c
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 /client/smburi.c
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
Diffstat (limited to 'client/smburi.c')
-rw-r--r--client/smburi.c178
1 files changed, 178 insertions, 0 deletions
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 }
+};