summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--daemon/gvfsafpserver.c140
-rw-r--r--daemon/gvfsafpserver.h15
-rw-r--r--daemon/gvfsbackendafpbrowse.c104
3 files changed, 178 insertions, 81 deletions
diff --git a/daemon/gvfsafpserver.c b/daemon/gvfsafpserver.c
index 613e210a..58456645 100644
--- a/daemon/gvfsafpserver.c
+++ b/daemon/gvfsafpserver.c
@@ -1141,12 +1141,11 @@ done:
* @volume_id: id of the volume whose parameters should be received.
* @vol_bitmap: bitmap describing the parameters that should be received.
* @cancellable: optional #GCancellable object, %NULL to ignore.
- * @error: a #GError, %NULL to ignore.
* @callback: callback to call when the request is satisfied.
* @user_data: the data to pass to callback function.
*
* Asynchronously retrives the parameters specified by @vol_bitmap of the volume
- * with id $volume_id.
+ * with id @volume_id.
*/
void
g_vfs_afp_server_get_vol_parms (GVfsAfpServer *server,
@@ -1208,3 +1207,140 @@ g_vfs_afp_server_get_vol_parms_finish (GVfsAfpServer *server,
return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
}
+
+static void
+volume_data_free (GVfsAfpVolumeData *vol_data)
+{
+ g_free (vol_data->name);
+ g_slice_free (GVfsAfpVolumeData, vol_data);
+}
+
+
+static void
+get_volumes_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+ GVfsAfpConnection *afp_conn = G_VFS_AFP_CONNECTION (source_object);
+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
+
+ GVfsAfpReply *reply;
+ GError *err = NULL;
+ AfpResultCode res_code;
+
+ guint8 num_volumes, i;
+ GPtrArray *volumes;
+
+ reply = g_vfs_afp_connection_send_command_finish (afp_conn, res, &err);
+ if (!reply)
+ {
+ g_simple_async_result_take_error (simple, err);
+ goto done;
+ }
+
+ res_code = g_vfs_afp_reply_get_result_code (reply);
+ if (res_code != AFP_RESULT_NO_ERROR)
+ {
+ g_object_unref (reply);
+
+ g_simple_async_result_take_error (simple, afp_result_code_to_gerror (res_code));
+ goto done;
+ }
+
+ /* server time */
+ g_vfs_afp_reply_read_int32 (reply, NULL);
+
+ /* NumVolStructures */
+ g_vfs_afp_reply_read_byte (reply, &num_volumes);
+
+ volumes = g_ptr_array_sized_new (num_volumes);
+ g_ptr_array_set_free_func (volumes, (GDestroyNotify)volume_data_free);
+ for (i = 0; i < num_volumes; i++)
+ {
+ guint8 flags;
+ char *vol_name;
+
+ GVfsAfpVolumeData *volume_data;
+
+ g_vfs_afp_reply_read_byte (reply, &flags);
+ g_vfs_afp_reply_read_pascal (reply, &vol_name);
+ if (!vol_name)
+ continue;
+
+ volume_data = g_slice_new (GVfsAfpVolumeData);
+ volume_data->flags = flags;
+ volume_data->name = vol_name;
+
+ g_ptr_array_add (volumes, volume_data);
+ }
+ g_object_unref (reply);
+
+ g_simple_async_result_set_op_res_gpointer (simple, volumes,
+ (GDestroyNotify)g_ptr_array_unref);
+done:
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+}
+
+/*
+ * g_vfs_afp_server_get_volumes:
+ *
+ * @server: a #GVfsAfpServer
+ * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @callback: callback to call when the request is satisfied.
+ * @user_data: the data to pass to callback function.
+ *
+ * Asynchronously retrieves the volumes available on @server.
+ */
+void
+g_vfs_afp_server_get_volumes (GVfsAfpServer *server,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GVfsAfpCommand *comm;
+ GSimpleAsyncResult *simple;
+
+ /* Get Server Parameters */
+ comm = g_vfs_afp_command_new (AFP_COMMAND_GET_SRVR_PARMS);
+ /* pad byte */
+ g_vfs_afp_command_put_byte (comm, 0);
+
+ simple = g_simple_async_result_new (G_OBJECT (server), callback, user_data,
+ g_vfs_afp_server_get_volumes);
+
+ g_vfs_afp_connection_send_command (server->conn, comm, NULL, get_volumes_cb,
+ cancellable, simple);
+}
+
+/*
+ * g_vfs_afp_server_get_vol_parms_finish:
+ *
+ * @server: a #GVfsAfpServer.
+ * @result: a #GAsyncResult.
+ * @error: a #GError, %NULL to ignore.
+ *
+ * Finalizes the asynchronous operation started by
+ * g_vfs_afp_server_get_volumes.
+ *
+ * Returns: A #GPtrArray containing the volumes #GVfsAfpVolumeData structures or
+ * %NULL on error.
+ *
+ */
+GPtrArray *
+g_vfs_afp_server_get_volumes_finish (GVfsAfpServer *server,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (g_simple_async_result_is_valid (result,
+ G_OBJECT (server),
+ g_vfs_afp_server_get_volumes),
+ NULL);
+
+ simple = (GSimpleAsyncResult *)result;
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return NULL;
+
+ return g_ptr_array_ref ((GPtrArray *)g_simple_async_result_get_op_res_gpointer (simple));
+} \ No newline at end of file
diff --git a/daemon/gvfsafpserver.h b/daemon/gvfsafpserver.h
index fc642bea..0688ff10 100644
--- a/daemon/gvfsafpserver.h
+++ b/daemon/gvfsafpserver.h
@@ -95,6 +95,21 @@ GFileInfo * g_vfs_afp_server_get_vol_parms_finish (GVfsAfpServer *s
GAsyncResult *result,
GError **error);
+typedef struct _GVfsAfpVolumeData GVfsAfpVolumeData;
+struct _GVfsAfpVolumeData
+{
+ char *name;
+ guint16 flags;
+};
+
+void g_vfs_afp_server_get_volumes (GVfsAfpServer *server,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+GPtrArray * g_vfs_afp_server_get_volumes_finish (GVfsAfpServer *server,
+ GAsyncResult *result,
+ GError **error);
+
G_END_DECLS
#endif /* _GVFSAFPSERVER_H_ */
diff --git a/daemon/gvfsbackendafpbrowse.c b/daemon/gvfsbackendafpbrowse.c
index 5226ce85..1b5f1fc4 100644
--- a/daemon/gvfsbackendafpbrowse.c
+++ b/daemon/gvfsbackendafpbrowse.c
@@ -58,26 +58,13 @@ struct _GVfsBackendAfpBrowse
GVfsAfpServer *server;
char *logged_in_user;
- GSList *volumes;
+ GPtrArray *volumes;
};
G_DEFINE_TYPE (GVfsBackendAfpBrowse, g_vfs_backend_afp_browse, G_VFS_TYPE_BACKEND);
-typedef struct
-{
- char *name;
- guint16 flags;
-} VolumeData;
-
-static void
-volume_data_free (VolumeData *vol_data)
-{
- g_free (vol_data->name);
- g_slice_free (VolumeData, vol_data);
-}
-
static gboolean
is_root (const char *filename)
{
@@ -91,62 +78,27 @@ is_root (const char *filename)
}
static void
-get_srvr_parms_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
+get_volumes_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
{
- GVfsAfpConnection *afp_conn = G_VFS_AFP_CONNECTION (source_object);
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
+ GVfsAfpServer *server = G_VFS_AFP_SERVER (source_object);
+ GSimpleAsyncResult *simple = user_data;
GVfsBackendAfpBrowse *afp_backend;
- GVfsAfpReply *reply;
+ GPtrArray *volumes;
GError *err = NULL;
- AfpResultCode res_code;
- guint8 num_volumes, i;
-
afp_backend = G_VFS_BACKEND_AFP_BROWSE (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
- reply = g_vfs_afp_connection_send_command_finish (afp_conn, res, &err);
- if (!reply)
+ volumes = g_vfs_afp_server_get_volumes_finish (server, res, &err);
+ if (!volumes)
{
g_simple_async_result_take_error (simple, err);
goto done;
}
- res_code = g_vfs_afp_reply_get_result_code (reply);
- if (res_code != AFP_RESULT_NO_ERROR)
- {
- g_object_unref (reply);
-
- g_simple_async_result_take_error (simple, afp_result_code_to_gerror (res_code));
- goto done;
- }
-
- /* server time */
- g_vfs_afp_reply_read_int32 (reply, NULL);
-
- g_slist_free_full (afp_backend->volumes, (GDestroyNotify) volume_data_free);
- afp_backend->volumes = NULL;
-
- g_vfs_afp_reply_read_byte (reply, &num_volumes);
- for (i = 0; i < num_volumes; i++)
- {
- guint8 flags;
- char *vol_name;
-
- VolumeData *volume_data;
-
- g_vfs_afp_reply_read_byte (reply, &flags);
- g_vfs_afp_reply_read_pascal (reply, &vol_name);
- if (!vol_name)
- continue;
-
- volume_data = g_slice_new (VolumeData);
- volume_data->flags = flags;
- volume_data->name = vol_name;
-
- afp_backend->volumes = g_slist_prepend (afp_backend->volumes, volume_data);
- }
- g_object_unref (reply);
+ if (afp_backend->volumes)
+ g_ptr_array_unref (afp_backend->volumes);
+ afp_backend->volumes = volumes;
done:
g_simple_async_result_complete (simple);
@@ -159,20 +111,13 @@ update_cache (GVfsBackendAfpBrowse *afp_backend,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GVfsAfpCommand *comm;
GSimpleAsyncResult *simple;
- comm = g_vfs_afp_command_new (AFP_COMMAND_GET_SRVR_PARMS);
- /* pad byte */
- g_vfs_afp_command_put_byte (comm, 0);
-
simple = g_simple_async_result_new (G_OBJECT (afp_backend), callback,
user_data, update_cache);
-
- g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, NULL,
- get_srvr_parms_cb,
- cancellable, simple);
- g_object_unref (comm);
+
+ g_vfs_afp_server_get_volumes (afp_backend->server, cancellable, get_volumes_cb,
+ simple);
}
static gboolean
@@ -194,13 +139,13 @@ update_cache_finish (GVfsBackendAfpBrowse *afp_backend,
return TRUE;
}
-static VolumeData *
+static GVfsAfpVolumeData *
find_volume (GVfsBackendAfpBrowse *afp_backend,
char *filename)
{
char *end;
guint len;
- GSList *l;
+ guint i;
while (*filename == '/')
filename++;
@@ -219,9 +164,9 @@ find_volume (GVfsBackendAfpBrowse *afp_backend,
else
len = strlen (filename);
- for (l = afp_backend->volumes; l; l = g_slist_next (l))
+ for (i = 0; i < afp_backend->volumes->len; i++)
{
- VolumeData *vol_data = (VolumeData *)l->data;
+ GVfsAfpVolumeData *vol_data = g_ptr_array_index (afp_backend->volumes, i);
if (strlen (vol_data->name) == len && strncmp (vol_data->name, filename, len) == 0)
return vol_data;
@@ -239,7 +184,7 @@ mount_mountable_cb (GObject *source_object,
GVfsJobMountMountable *job = G_VFS_JOB_MOUNT_MOUNTABLE (user_data);
GError *err;
- VolumeData *vol_data;
+ GVfsAfpVolumeData *vol_data;
GMountSpec *mount_spec;
if (!update_cache_finish (afp_backend, res, &err))
@@ -292,7 +237,7 @@ try_mount_mountable (GVfsBackend *backend,
}
static void
-fill_info (GFileInfo *info, VolumeData *vol_data, GVfsBackendAfpBrowse *afp_backend)
+fill_info (GFileInfo *info, GVfsAfpVolumeData *vol_data, GVfsBackendAfpBrowse *afp_backend)
{
GIcon *icon;
GMountSpec *mount_spec;
@@ -346,7 +291,7 @@ enumerate_cache_updated_cb (GObject *source_object,
GVfsJobEnumerate *job = G_VFS_JOB_ENUMERATE (user_data);
GError *err = NULL;
- GSList *l;
+ guint i;
if (!update_cache_finish (afp_backend, res, &err))
{
@@ -357,9 +302,9 @@ enumerate_cache_updated_cb (GObject *source_object,
g_vfs_job_succeeded (G_VFS_JOB (job));
- for (l = afp_backend->volumes; l; l = l->next)
+ for (i = 0; i < afp_backend->volumes->len; i++)
{
- VolumeData *vol_data = l->data;
+ GVfsAfpVolumeData *vol_data = g_ptr_array_index (afp_backend->volumes, i);
GFileInfo *info;
@@ -405,7 +350,7 @@ query_info_cb (GObject *source_object,
GVfsJobQueryInfo *job = G_VFS_JOB_QUERY_INFO (user_data);
GError *err = NULL;
- VolumeData *vol_data;
+ GVfsAfpVolumeData *vol_data;
if (!update_cache_finish (afp_backend, res, &err))
{
@@ -577,7 +522,8 @@ g_vfs_backend_afp_browse_finalize (GObject *object)
g_free (afp_backend->user);
g_free (afp_backend->logged_in_user);
- g_slist_free_full (afp_backend->volumes, (GDestroyNotify)volume_data_free);
+ if (afp_backend->volumes)
+ g_ptr_array_unref (afp_backend->volumes);
G_OBJECT_CLASS (g_vfs_backend_afp_browse_parent_class)->finalize (object);
}