[gvfs] afp: add an urimapper for afp



commit 0aab50b4a7f21cc82afcd55e210fe1fd74040604
Author: Carl-Anton Ingmarsson <ca ingmarsson gmail com>
Date:   Mon Jun 6 23:23:08 2011 +0200

    afp: add an urimapper for afp

 client/Makefile.am      |    1 +
 client/afpuri.c         |  269 +++++++++++++++++++++++++++++++++++++++++++++++
 daemon/Makefile.am      |    2 +-
 daemon/afp.mount.in     |    2 +-
 daemon/gvfsbackendafp.c |    3 +-
 5 files changed, 274 insertions(+), 3 deletions(-)
---
diff --git a/client/Makefile.am b/client/Makefile.am
index 1a77502..925300b 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -22,6 +22,7 @@ gvfsclientinclude_HEADERS = \
 URI_PARSER_SOURCES = \
 	smburi.c \
 	httpuri.c \
+	afpuri.c \
 	$(NULL)
 
 vfssources = \
diff --git a/client/afpuri.c b/client/afpuri.c
new file mode 100644
index 0000000..8669eae
--- /dev/null
+++ b/client/afpuri.c
@@ -0,0 +1,269 @@
+/* GIO - GLib Input, Output and Streaming Library
+ * 
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ * Copyright (C) Carl-Anton Ingmarsson 2011 <ca ingmarsson gmail com>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl redhat com>
+ *         Carl-Anton Ingmarsson <ca ingmarsson gmail com>
+ */
+
+#include <config.h>
+#include <string.h>
+
+#include <stdlib.h>
+#include <gio/gio.h>
+#include <gvfsurimapper.h>
+#include <gvfsuriutils.h>
+
+typedef struct _GVfsUriMapperAfp GVfsUriMapperAfp;
+typedef struct _GVfsUriMapperAfpClass GVfsUriMapperAfpClass;
+
+struct _GVfsUriMapperAfp
+{
+  GVfsUriMapper parent;
+};
+
+struct _GVfsUriMapperAfpClass
+{
+  GVfsUriMapperClass parent_class;
+};
+
+GType g_vfs_uri_mapper_afp_get_type (void);
+void g_vfs_uri_mapper_afp_register (GIOModule *module);
+
+G_DEFINE_DYNAMIC_TYPE (GVfsUriMapperAfp, g_vfs_uri_mapper_afp, G_VFS_TYPE_URI_MAPPER)
+
+static void
+g_vfs_uri_mapper_afp_init (GVfsUriMapperAfp *vfs)
+{
+}
+
+static const char * const *
+afp_get_handled_schemes (GVfsUriMapper *mapper)
+{
+  static const char *schemes[] = {
+    "afp",
+    NULL
+  };
+  return schemes;
+}
+
+static GVfsUriMountInfo *
+afp_from_uri (GVfsUriMapper *mapper,
+              const char *uri_str)
+{
+  const char *p;
+  GDecodedUri *uri;
+  GVfsUriMountInfo *info;
+
+  uri = g_vfs_decode_uri (uri_str);
+  if (uri == NULL)
+    return NULL;
+
+  if (uri->host == NULL || strlen (uri->host) == 0)
+  {
+    g_vfs_decoded_uri_free (uri);
+    return NULL;
+  }
+  else
+  {
+    /* host set */
+    p = uri->path;
+    while (p && *p == '/')
+      p++;
+
+    if (p == NULL || *p == 0)
+    {
+      /* uri form: afp://$host/ */
+       info = g_vfs_uri_mount_info_new ("afp-server");
+
+       g_vfs_uri_mount_info_set (info, "host", uri->host);
+       info->path = g_strdup ("/");
+    }
+    else
+    {
+      const char *volume, *volume_end;
+      
+      volume = p;
+      volume_end = strchr (volume, '/');
+      if (volume_end == NULL)
+        volume_end = volume + strlen (volume);
+
+      p = volume_end;
+
+      while (*p == '/')
+        p++;
+
+      if (*p == 0)
+      {
+        /* uri form: afp://$host/$volume/
+         * Here we special case afp-server files by adding "._" to the names in the uri */
+        if (volume[0] == '.' && volume[1] == '_')
+        {
+          char *tmp;
+          
+          info = g_vfs_uri_mount_info_new ("afp-server");
+          
+          g_vfs_uri_mount_info_set  (info, "host", uri->host);
+          
+          tmp = g_strndup (volume + 2, volume_end - (volume + 2));
+          info->path = g_strconcat ("/", tmp, NULL);
+          g_free (tmp);
+        }
+        else
+        {
+          char *tmp;
+          
+          info = g_vfs_uri_mount_info_new ("afp-volume");
+
+          g_vfs_uri_mount_info_set  (info, "host", uri->host);
+
+          tmp = g_strndup (volume, volume_end - volume);
+          g_vfs_uri_mount_info_set  (info, "volume", tmp);
+          g_free (tmp);
+          info->path = g_strdup ("/");
+        }
+      }
+      else
+      {
+        char *tmp;
+        
+        info = g_vfs_uri_mount_info_new ("afp-volume");
+
+        g_vfs_uri_mount_info_set  (info, "host", uri->host);
+
+        tmp = g_strndup (volume, volume_end - volume);
+        g_vfs_uri_mount_info_set  (info, "volume", tmp);
+        g_free (tmp);
+
+        info->path = g_strconcat ("/", p, NULL);
+      }
+    }
+  }
+
+  if (uri->userinfo)
+  {
+    g_vfs_uri_mount_info_set  (info, "user", uri->userinfo);
+  }
+
+  g_vfs_decoded_uri_free (uri);
+           
+  return info;
+}
+
+static const char * const *
+afp_get_handled_mount_types (GVfsUriMapper *mapper)
+{
+  static const char *types[] = {
+    "afp-server", 
+    "afp-volume", 
+    NULL
+  };
+  return types;
+}
+
+static char *
+afp_to_uri (GVfsUriMapper *mapper,
+            GVfsUriMountInfo *info,
+            gboolean allow_utf8)
+{
+  const char *type;
+  const char *host;
+  const char *port;
+  const char *user;
+  char *s;
+  GDecodedUri *uri;
+
+  uri = g_new0 (GDecodedUri, 1);
+
+  type = g_vfs_uri_mount_info_get (info, "type");
+
+  uri->scheme = g_strdup ("afp");
+
+  host = g_vfs_uri_mount_info_get (info, "host");
+  uri->host = g_strdup (host);
+
+  port = g_vfs_uri_mount_info_get (info, "port");
+  if (port)
+    uri->port = atoi (port);
+  else
+    uri->port = -1;
+
+  user = g_vfs_uri_mount_info_get (info, "user");
+  uri->userinfo = g_strdup (user);
+
+  if (strcmp (type, "afp-server") == 0)
+  {
+    /* Map the mountables in server to ._share because the actual share mount maps to afp://host/share */
+     if (info->path && info->path[0] == '/' && info->path[1] != 0)
+     uri->path = g_strconcat ("/._", info->path + 1, NULL);
+     else
+     uri->path = g_strdup ("/");
+  }
+  else if (strcmp (type, "afp-volume") == 0)
+  {
+    const char *volume;
+
+    volume = g_vfs_uri_mount_info_get (info, "volume");
+    if (info->path[0] == '/')
+      uri->path = g_strconcat ("/", volume, info->path, NULL);
+    else
+      uri->path = g_strconcat ("/", volume, "/", info->path, NULL);
+  }
+
+  s = g_vfs_encode_uri (uri, allow_utf8);
+  g_vfs_decoded_uri_free (uri);
+  return s;
+}
+
+static const char *
+afp_to_uri_scheme (GVfsUriMapper *mapper,
+                   GVfsUriMountInfo *info)
+{
+  const gchar *type = g_vfs_uri_mount_info_get (info, "type");
+
+  if (strcmp ("afp-server", type) == 0 ||
+      strcmp ("afp-volume", type) == 0)
+    return "afp";
+  else
+    return NULL;
+}
+
+static void
+g_vfs_uri_mapper_afp_class_finalize (GVfsUriMapperAfpClass *klass)
+{
+}
+
+static void
+g_vfs_uri_mapper_afp_class_init (GVfsUriMapperAfpClass *class)
+{
+  GVfsUriMapperClass *mapper_class;
+
+  mapper_class = G_VFS_URI_MAPPER_CLASS (class);
+  mapper_class->get_handled_schemes = afp_get_handled_schemes;
+  mapper_class->from_uri = afp_from_uri;
+  mapper_class->get_handled_mount_types = afp_get_handled_mount_types;
+  mapper_class->to_uri = afp_to_uri;
+  mapper_class->to_uri_scheme = afp_to_uri_scheme;
+}
+
+void
+g_vfs_uri_mapper_afp_register (GIOModule *module)
+{
+  g_vfs_uri_mapper_afp_register_type (G_TYPE_MODULE (module));
+}
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 9256e74..b47e1d0 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -483,7 +483,7 @@ gvfsd_afp_CPPFLAGS = \
 	-DBACKEND_HEADER=gvfsbackendafp.h \
 	-DDEFAULT_BACKEND_TYPE=afp \
 	-DMAX_JOB_THREADS=1 \
-	-DBACKEND_TYPES='"afp", G_VFS_TYPE_BACKEND_AFP,'
+	-DBACKEND_TYPES='"afp-server", G_VFS_TYPE_BACKEND_AFP,'
 
 gvfsd_afp_LDADD = $(libraries)
 
diff --git a/daemon/afp.mount.in b/daemon/afp.mount.in
index 6bd9e40..e10f288 100644
--- a/daemon/afp.mount.in
+++ b/daemon/afp.mount.in
@@ -1,5 +1,5 @@
 [Mount]
-Type=afp
+Type=afp-server
 Exec= libexecdir@/gvfsd-afp
 AutoMount=false
 Scheme=afp
diff --git a/daemon/gvfsbackendafp.c b/daemon/gvfsbackendafp.c
index 09109b6..22df933 100644
--- a/daemon/gvfsbackendafp.c
+++ b/daemon/gvfsbackendafp.c
@@ -402,7 +402,7 @@ do_mount (GVfsBackend *backend,
     goto error;
 
   /* set mount info */
-  afp_mount_spec = g_mount_spec_new ("afp");
+  afp_mount_spec = g_mount_spec_new ("afp-server");
   g_mount_spec_set (afp_mount_spec, "host",
                     g_network_address_get_hostname (G_NETWORK_ADDRESS (afp_backend->addr)));
   if (afp_backend->user)
@@ -416,6 +416,7 @@ do_mount (GVfsBackend *backend,
   g_free (display_name);
 
   g_vfs_backend_set_icon_name (backend, "network-server");
+  g_vfs_backend_set_user_visible (backend, FALSE);
 
     
   g_vfs_job_succeeded (G_VFS_JOB (job));



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]