mirror of https://gitee.com/openkylin/gvfs.git
266 lines
6.2 KiB
C
266 lines
6.2 KiB
C
|
/* 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., 51 Franklin Street, Fifth Floor,
|
||
|
* Boston, MA 02110-1301, 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 GMountSpec *
|
||
|
afp_from_uri (GVfsUriMapper *mapper,
|
||
|
const char *uri_str,
|
||
|
char **path)
|
||
|
{
|
||
|
const char *p;
|
||
|
GDecodedUri *uri;
|
||
|
GMountSpec *spec;
|
||
|
|
||
|
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/ */
|
||
|
spec = g_mount_spec_new ("afp-server");
|
||
|
|
||
|
g_mount_spec_set (spec, "host", uri->host);
|
||
|
*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;
|
||
|
|
||
|
spec = g_mount_spec_new ("afp-server");
|
||
|
g_mount_spec_set (spec, "host", uri->host);
|
||
|
|
||
|
tmp = g_strndup (volume + 2, volume_end - (volume + 2));
|
||
|
*path = g_strconcat ("/", tmp, NULL);
|
||
|
g_free (tmp);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
char *tmp;
|
||
|
|
||
|
spec = g_mount_spec_new ("afp-volume");
|
||
|
g_mount_spec_set (spec, "host", uri->host);
|
||
|
|
||
|
tmp = g_strndup (volume, volume_end - volume);
|
||
|
g_mount_spec_take (spec, "volume", tmp);
|
||
|
|
||
|
*path = g_strdup ("/");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
char *tmp;
|
||
|
|
||
|
spec = g_mount_spec_new ("afp-volume");
|
||
|
g_mount_spec_set (spec, "host", uri->host);
|
||
|
|
||
|
tmp = g_strndup (volume, volume_end - volume);
|
||
|
g_mount_spec_take (spec, "volume", tmp);
|
||
|
|
||
|
*path = g_strconcat ("/", p, NULL);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (uri->userinfo)
|
||
|
g_mount_spec_set (spec, "user", uri->userinfo);
|
||
|
|
||
|
g_vfs_decoded_uri_free (uri);
|
||
|
|
||
|
return spec;
|
||
|
}
|
||
|
|
||
|
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,
|
||
|
GMountSpec *spec,
|
||
|
const char *path,
|
||
|
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_mount_spec_get (spec, "type");
|
||
|
|
||
|
uri->scheme = g_strdup ("afp");
|
||
|
|
||
|
host = g_mount_spec_get (spec, "host");
|
||
|
uri->host = g_strdup (host);
|
||
|
|
||
|
port = g_mount_spec_get (spec, "port");
|
||
|
if (port)
|
||
|
uri->port = atoi (port);
|
||
|
else
|
||
|
uri->port = -1;
|
||
|
|
||
|
user = g_mount_spec_get (spec, "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 (path && path[0] == '/' && path[1] != 0)
|
||
|
uri->path = g_strconcat ("/._", path + 1, NULL);
|
||
|
else
|
||
|
uri->path = g_strdup ("/");
|
||
|
}
|
||
|
else if (strcmp (type, "afp-volume") == 0)
|
||
|
{
|
||
|
const char *volume;
|
||
|
|
||
|
volume = g_mount_spec_get (spec, "volume");
|
||
|
if (path[0] == '/')
|
||
|
uri->path = g_strconcat ("/", volume, path, NULL);
|
||
|
else
|
||
|
uri->path = g_strconcat ("/", volume, "/", 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,
|
||
|
GMountSpec *spec)
|
||
|
{
|
||
|
const gchar *type = g_mount_spec_get (spec, "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));
|
||
|
}
|