GVfsAfpReply * g_vfs_afp_connection_read_reply_sync (GVfsAfpConnection *afp_connection, GCancellable *cancellable, GError **error) { GVfsAfpConnectionPrivate *priv = afp_connection->priv; gboolean res; char *data; DSIHeader dsi_header; res = read_reply_sync (g_io_stream_get_input_stream (priv->conn), &dsi_header, &data, cancellable, error); if (!res) return NULL; return g_vfs_afp_reply_new (dsi_header.errorCode, data, dsi_header.totalDataLength, TRUE); }
GVfsAfpReply * g_vfs_afp_connection_get_server_info (GVfsAfpConnection *afp_connection, GCancellable *cancellable, GError **error) { GVfsAfpConnectionPrivate *priv = afp_connection->priv; GSocketClient *client; GIOStream *conn; gboolean res; DSIHeader dsi_header; char *data; client = g_socket_client_new (); conn = G_IO_STREAM (g_socket_client_connect (client, priv->addr, cancellable, error)); g_object_unref (client); if (!conn) return NULL; res = send_request_sync (g_io_stream_get_output_stream (conn), DSI_GET_STATUS, 0, 0, 0, NULL, cancellable, error); if (!res) { g_object_unref (conn); return NULL; } res = read_reply_sync (g_io_stream_get_input_stream (conn), &dsi_header, &data, cancellable, error); if (!res) { g_object_unref (conn); return NULL; } g_object_unref (conn); return g_vfs_afp_reply_new (dsi_header.errorCode, data, dsi_header.totalDataLength, TRUE); }
gboolean g_vfs_afp_connection_open (GVfsAfpConnection *afp_connection, GCancellable *cancellable, GError **error) { GVfsAfpConnectionPrivate *priv = afp_connection->priv; GSocketClient *client; guint16 req_id; gboolean res; char *reply; DSIHeader dsi_header; guint pos; client = g_socket_client_new (); priv->conn = G_IO_STREAM (g_socket_client_connect (client, priv->addr, cancellable, error)); g_object_unref (client); if (!priv->conn) return FALSE; req_id = get_request_id (afp_connection); res = send_request_sync (g_io_stream_get_output_stream (priv->conn), DSI_OPEN_SESSION, req_id, 0, 0, NULL, cancellable, error); if (!res) return FALSE; res = read_reply_sync (g_io_stream_get_input_stream (priv->conn), &dsi_header, &reply, cancellable, error); if (!res) return FALSE; pos = 0; while ((dsi_header.totalDataLength - pos) > 2) { guint8 optionType; guint8 optionLength; optionType = reply[pos++]; optionLength = reply[pos++]; switch (optionType) { case 0x00: if (optionLength == 4 && (dsi_header.totalDataLength - pos) >= 4) priv->kRequestQuanta = GUINT32_FROM_BE (*(guint32 *)(reply + pos)); break; case 0x02: if (optionLength == 4 && (dsi_header.totalDataLength - pos) >= 4) priv->kServerReplayCacheSize = GUINT32_FROM_BE (*(guint32 *)(reply + pos)); break; default: g_debug ("Unknown DSI option\n"); } pos += optionLength; } g_free (reply); return TRUE; }
static gpointer open_thread_func (gpointer user_data) { SyncData *data = user_data; GVfsAfpConnection *conn = data->conn; GVfsAfpConnectionPrivate *priv = conn->priv; GSocketClient *client; guint16 req_id; gboolean res = FALSE; char *reply; DSIHeader dsi_header; guint pos; client = g_socket_client_new (); priv->stream = G_IO_STREAM (g_socket_client_connect (client, priv->addr, data->cancellable, data->error)); g_object_unref (client); if (!priv->stream) goto out; req_id = get_request_id (conn); res = send_request_sync (g_io_stream_get_output_stream (priv->stream), DSI_OPEN_SESSION, req_id, 0, 0, NULL, data->cancellable, data->error); if (!res) goto out; res = read_reply_sync (g_io_stream_get_input_stream (priv->stream), &dsi_header, &reply, data->cancellable, data->error); if (!res) goto out; pos = 0; while ((dsi_header.totalDataLength - pos) > 2) { guint8 optionType; guint8 optionLength; optionType = reply[pos++]; optionLength = reply[pos++]; switch (optionType) { case 0x00: if (optionLength == 4 && (dsi_header.totalDataLength - pos) >= 4) priv->kRequestQuanta = GUINT32_FROM_BE (*(guint32 *)(reply + pos)); break; case 0x02: if (optionLength == 4 && (dsi_header.totalDataLength - pos) >= 4) priv->kServerReplayCacheSize = GUINT32_FROM_BE (*(guint32 *)(reply + pos)); break; default: g_debug ("Unknown DSI option\n"); } pos += optionLength; } g_free (reply); out: if (res) g_atomic_int_set (&priv->atomic_state, STATE_CONNECTED); /* Signal sync call thread */ data->res = res; sync_data_signal (data); /* Return from thread on failure */ if (!res) { g_clear_object (&priv->stream); return NULL; } /* Create MainLoop */ priv->worker_context = g_main_context_new (); priv->worker_loop = g_main_loop_new (priv->worker_context, TRUE); read_reply (conn); /* Run mainloop */ g_main_loop_run (priv->worker_loop); return NULL; }