1
/* GIO - GLib Input, Output and Streaming Library
3
* Copyright (C) Carl-Anton Ingmarsson 2011 <ca.ingmarsson@gmail.com>
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General
16
* Public License along with this library; if not, write to the
17
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18
* Boston, MA 02111-1307, USA.
20
* Author: Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com>
24
#include <glib/gi18n.h>
27
#include "gvfsafpconnection.h"
34
_g_vfs_afp_name_free (GVfsAfpName *afp_name)
36
g_free (afp_name->str);
37
g_slice_free (GVfsAfpName, afp_name);
41
g_vfs_afp_name_unref (GVfsAfpName *afp_name)
43
if (g_atomic_int_dec_and_test (&afp_name->ref_count))
44
_g_vfs_afp_name_free (afp_name);
48
g_vfs_afp_name_ref (GVfsAfpName *afp_name)
50
g_atomic_int_inc (&afp_name->ref_count);
54
g_vfs_afp_name_get_string (GVfsAfpName *afp_name)
56
return g_utf8_normalize (afp_name->str, afp_name->len, G_NORMALIZE_DEFAULT_COMPOSE);
60
g_vfs_afp_name_new (guint32 text_encoding, gchar *str, gsize len)
62
GVfsAfpName *afp_name;
64
afp_name = g_slice_new (GVfsAfpName);
65
afp_name->ref_count = 1;
67
afp_name->text_encoding = text_encoding;
78
struct _GVfsAfpReplyClass
80
GObjectClass parent_class;
85
GObject parent_instance;
87
AfpResultCode result_code;
96
G_DEFINE_TYPE (GVfsAfpReply, g_vfs_afp_reply, G_TYPE_OBJECT);
99
g_vfs_afp_reply_init (GVfsAfpReply *reply)
107
g_vfs_afp_reply_finalize (GObject *object)
109
GVfsAfpReply *reply = (GVfsAfpReply *)object;
111
if (reply->free_data)
112
g_free (reply->data);
116
g_vfs_afp_reply_class_init (GVfsAfpReplyClass *klass)
118
GObjectClass *object_class = G_OBJECT_CLASS (klass);
120
object_class->finalize = g_vfs_afp_reply_finalize;
123
static GVfsAfpReply *
124
g_vfs_afp_reply_new (AfpResultCode result_code, char *data, gsize len, gboolean take_data)
128
reply = g_object_new (G_VFS_TYPE_AFP_REPLY, NULL);
130
reply->result_code = result_code;
133
reply->free_data = take_data;
139
g_vfs_afp_reply_read_byte (GVfsAfpReply *reply, guint8 *byte)
141
if ((reply->len - reply->pos) < 1)
145
*byte = reply->data[reply->pos];
153
g_vfs_afp_reply_read_int64 (GVfsAfpReply *reply, gint64 *val)
155
if ((reply->len - reply->pos) < 8)
159
*val = GINT64_FROM_BE (*((gint64 *)(reply->data + reply->pos)));
167
g_vfs_afp_reply_read_int32 (GVfsAfpReply *reply, gint32 *val)
169
if ((reply->len - reply->pos) < 4)
173
*val = GINT32_FROM_BE (*((gint32 *)(reply->data + reply->pos)));
181
g_vfs_afp_reply_read_int16 (GVfsAfpReply *reply, gint16 *val)
183
if ((reply->len - reply->pos) < 2)
187
*val = GINT16_FROM_BE (*((gint16 *)(reply->data + reply->pos)));
195
g_vfs_afp_reply_read_uint64 (GVfsAfpReply *reply, guint64 *val)
197
if ((reply->len - reply->pos) < 8)
201
*val = GUINT64_FROM_BE (*((guint64 *)(reply->data + reply->pos)));
209
g_vfs_afp_reply_read_uint32 (GVfsAfpReply *reply, guint32 *val)
211
if ((reply->len - reply->pos) < 4)
215
*val = GUINT32_FROM_BE (*((guint32 *)(reply->data + reply->pos)));
223
g_vfs_afp_reply_read_uint16 (GVfsAfpReply *reply, guint16 *val)
225
if ((reply->len - reply->pos) < 2)
229
*val = GUINT16_FROM_BE (*((guint16 *)(reply->data + reply->pos)));
237
g_vfs_afp_reply_get_data (GVfsAfpReply *reply, gsize size, guint8 **data)
239
if ((reply->len - reply->pos) < size)
243
*data = (guint8 *)(reply->data + reply->pos);
251
g_vfs_afp_reply_dup_data (GVfsAfpReply *reply, gsize size, guint8 **data)
253
if ((reply->len - reply->pos) < size)
258
*data = g_malloc (size);
259
memcpy (*data, reply->data + reply->pos, size);
268
g_vfs_afp_reply_read_pascal (GVfsAfpReply *reply, char **str)
272
if (!g_vfs_afp_reply_read_byte (reply, &strsize))
275
if (strsize > (reply->len - reply->pos))
282
*str = g_strndup (reply->data + reply->pos, strsize);
284
reply->pos += strsize;
290
g_vfs_afp_reply_read_afp_name (GVfsAfpReply *reply, gboolean read_text_encoding,
291
GVfsAfpName **afp_name)
295
guint32 text_encoding;
299
old_pos = reply->pos;
301
if (read_text_encoding)
303
if (!g_vfs_afp_reply_read_uint32 (reply, &text_encoding))
309
if (!g_vfs_afp_reply_read_uint16 (reply, &len))
311
reply->pos = old_pos;
315
if (!g_vfs_afp_reply_get_data (reply, len, (guint8 **)&str))
317
reply->pos = old_pos;
322
*afp_name = g_vfs_afp_name_new (text_encoding, g_strndup (str, len), len);
329
g_vfs_afp_reply_seek (GVfsAfpReply *reply, goffset offset, GSeekType type)
336
absolute = reply->pos + offset;
344
absolute = reply->len + offset;
351
if (absolute < 0 || absolute >= reply->len)
354
reply->pos = absolute;
359
g_vfs_afp_reply_skip_to_even (GVfsAfpReply *reply)
361
if ((reply->pos % 2) == 0)
364
if ((reply->len - reply->pos) < 1)
373
g_vfs_afp_reply_get_pos (GVfsAfpReply *reply)
379
g_vfs_afp_reply_get_size (GVfsAfpReply *reply)
385
g_vfs_afp_reply_get_result_code (GVfsAfpReply *reply)
387
return reply->result_code;
393
struct _GVfsAfpCommandClass
395
GDataOutputStreamClass parent_class;
398
struct _GVfsAfpCommand
400
GDataOutputStream parent_instance;
408
G_DEFINE_TYPE (GVfsAfpCommand, g_vfs_afp_command, G_TYPE_DATA_OUTPUT_STREAM);
412
g_vfs_afp_command_init (GVfsAfpCommand *comm)
417
g_vfs_afp_command_class_init (GVfsAfpCommandClass *klass)
422
g_vfs_afp_command_new (AfpCommandType type)
424
GOutputStream *mem_stream;
425
GVfsAfpCommand *comm;
427
mem_stream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
428
comm = g_object_new (G_VFS_TYPE_AFP_COMMAND,
429
"base-stream", mem_stream,
432
g_object_unref (mem_stream);
435
g_vfs_afp_command_put_byte (comm, type);
441
g_vfs_afp_command_put_byte (GVfsAfpCommand *comm, guint8 byte)
443
g_data_output_stream_put_byte (G_DATA_OUTPUT_STREAM (comm), byte, NULL, NULL);
447
g_vfs_afp_command_put_int16 (GVfsAfpCommand *comm, gint16 val)
449
g_data_output_stream_put_int16 (G_DATA_OUTPUT_STREAM (comm), val, NULL, NULL);
453
g_vfs_afp_command_put_int32 (GVfsAfpCommand *comm, gint32 val)
455
g_data_output_stream_put_int32 (G_DATA_OUTPUT_STREAM (comm), val, NULL, NULL);
459
g_vfs_afp_command_put_int64 (GVfsAfpCommand *comm, gint64 val)
461
g_data_output_stream_put_int64 (G_DATA_OUTPUT_STREAM (comm), val, NULL, NULL);
465
g_vfs_afp_command_put_uint16 (GVfsAfpCommand *comm, guint16 val)
467
g_data_output_stream_put_uint16 (G_DATA_OUTPUT_STREAM (comm), val, NULL, NULL);
471
g_vfs_afp_command_put_uint32 (GVfsAfpCommand *comm, guint32 val)
473
g_data_output_stream_put_uint32 (G_DATA_OUTPUT_STREAM (comm), val, NULL, NULL);
477
g_vfs_afp_command_put_uint64 (GVfsAfpCommand *comm, guint64 val)
479
g_data_output_stream_put_uint64 (G_DATA_OUTPUT_STREAM (comm), val, NULL, NULL);
483
g_vfs_afp_command_put_pascal (GVfsAfpCommand *comm, const char *str)
487
len = MIN (strlen (str), 256);
489
g_vfs_afp_command_put_byte (comm, len);
490
g_output_stream_write (G_OUTPUT_STREAM (comm), str, len, NULL, NULL);
494
g_vfs_afp_command_put_afp_name (GVfsAfpCommand *comm, GVfsAfpName *afp_name)
496
g_vfs_afp_command_put_uint32 (comm, afp_name->text_encoding);
497
g_vfs_afp_command_put_uint16 (comm, afp_name->len);
499
if (afp_name->len > 0)
501
g_output_stream_write_all (G_OUTPUT_STREAM (comm), afp_name->str,
502
afp_name->len, NULL, NULL, NULL);
507
g_vfs_afp_command_pad_to_even (GVfsAfpCommand *comm)
509
if (g_vfs_afp_command_get_size (comm) % 2 == 1)
510
g_vfs_afp_command_put_byte (comm, 0);
514
g_vfs_afp_command_get_size (GVfsAfpCommand *comm)
516
GMemoryOutputStream *mem_stream;
519
G_MEMORY_OUTPUT_STREAM (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (comm)));
521
return g_memory_output_stream_get_data_size (mem_stream);
525
g_vfs_afp_command_get_data (GVfsAfpCommand *comm)
527
GMemoryOutputStream *mem_stream;
530
G_MEMORY_OUTPUT_STREAM (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (comm)));
532
return g_memory_output_stream_get_data (mem_stream);
536
g_vfs_afp_command_set_buffer (GVfsAfpCommand *comm, char *buf, gsize size)
538
g_return_if_fail (buf != NULL);
539
g_return_if_fail (size > 0);
542
comm->buf_size = size;
554
static guint signals[LAST_SIGNAL] = {0,};
556
G_DEFINE_TYPE (GVfsAfpConnection, g_vfs_afp_connection, G_TYPE_OBJECT);
566
guint32 totalDataLength;
570
struct _GVfsAfpConnectionPrivate
572
GSocketConnectable *addr;
577
guint32 kRequestQuanta;
578
guint32 kServerReplayCacheSize;
580
GQueue *request_queue;
581
GHashTable *request_hash;
584
gboolean send_loop_running;
585
DSIHeader write_dsi_header;
588
gboolean read_loop_running;
589
DSIHeader read_dsi_header;
591
gboolean free_reply_buf;
596
DSI_CLOSE_SESSION = 1,
599
DSI_OPEN_SESSION = 4,
605
static void read_reply (GVfsAfpConnection *afp_connection);
606
static void send_request (GVfsAfpConnection *afp_connection);
609
get_request_id (GVfsAfpConnection *afp_connection)
611
GVfsAfpConnectionPrivate *priv = afp_connection->priv;
613
return priv->request_id++;
618
REQUEST_TYPE_COMMAND,
626
GVfsAfpCommand *command;
628
GSimpleAsyncResult *simple;
629
GCancellable *cancellable;
633
free_request_data (RequestData *req_data)
635
if (req_data->command)
636
g_object_unref (req_data->command);
637
if (req_data->simple)
638
g_object_unref (req_data->simple);
639
if (req_data->cancellable)
640
g_object_unref (req_data->cancellable);
642
g_slice_free (RequestData, req_data);
646
run_loop (GVfsAfpConnection *afp_connection)
648
GVfsAfpConnectionPrivate *priv = afp_connection->priv;
650
if (!priv->send_loop_running)
652
priv->send_loop_running = TRUE;
653
send_request (afp_connection);
655
if (!priv->read_loop_running)
657
priv->read_loop_running = TRUE;
658
read_reply (afp_connection);
667
GCancellable *cancellable;
672
free_read_all_data (ReadAllData *read_data)
674
if (read_data->cancellable)
675
g_object_unref (read_data->cancellable);
677
g_slice_free (ReadAllData, read_data);
681
read_all_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
683
GInputStream *stream = G_INPUT_STREAM (source_object);
684
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
688
ReadAllData *read_data;
690
bytes_read = g_input_stream_read_finish (stream, res, &err);
691
if (bytes_read == -1)
693
g_simple_async_result_take_error (simple, err);
697
read_data = g_simple_async_result_get_op_res_gpointer (simple);
699
read_data->bytes_read += bytes_read;
700
if (read_data->bytes_read < read_data->count)
702
g_input_stream_read_async (stream,
703
(guint8 *)read_data->buffer + read_data->bytes_read,
704
read_data->count - read_data->bytes_read, 0,
705
read_data->cancellable, read_all_cb, simple);
710
g_simple_async_result_complete (simple);
711
g_object_unref (simple);
715
read_all_async (GInputStream *stream,
719
GCancellable *cancellable,
720
GAsyncReadyCallback callback,
723
ReadAllData *read_data;
724
GSimpleAsyncResult *simple;
726
read_data = g_slice_new0 (ReadAllData);
727
read_data->buffer = buffer;
728
read_data->count = count;
729
read_data->io_priority = io_priority;
731
read_data->cancellable = g_object_ref (cancellable);
733
simple = g_simple_async_result_new (G_OBJECT (stream), callback, user_data,
735
g_simple_async_result_set_op_res_gpointer (simple, read_data,
736
(GDestroyNotify)free_read_all_data);
738
g_input_stream_read_async (stream, buffer, count, io_priority, cancellable,
739
read_all_cb, simple);
743
read_all_finish (GInputStream *stream,
748
GSimpleAsyncResult *simple;
750
g_return_val_if_fail (g_simple_async_result_is_valid (res, G_OBJECT (stream),
754
simple = (GSimpleAsyncResult *)res;
756
if (g_simple_async_result_propagate_error (simple, error))
761
ReadAllData *read_data;
763
read_data = g_simple_async_result_get_op_res_gpointer (simple);
764
*bytes_read = read_data->bytes_read;
771
dispatch_reply (GVfsAfpConnection *afp_connection)
773
GVfsAfpConnectionPrivate *priv = afp_connection->priv;
774
DSIHeader *dsi_header = &priv->read_dsi_header;
776
switch (dsi_header->command)
778
case DSI_CLOSE_SESSION:
780
g_warning ("Server closed session\n");
786
RequestData *req_data;
788
/* Send back a tickle message */
789
req_data = g_slice_new0 (RequestData);
790
req_data->type = REQUEST_TYPE_TICKLE;
792
g_queue_push_head (priv->request_queue, req_data);
793
run_loop (afp_connection);
799
guint8 attention_code;
801
attention_code = priv->reply_buf[0] >> 4;
803
g_signal_emit (afp_connection, signals[ATTENTION], 0, attention_code);
810
RequestData *req_data;
812
req_data = g_hash_table_lookup (priv->request_hash,
813
GUINT_TO_POINTER ((guint)dsi_header->requestID));
818
reply = g_vfs_afp_reply_new (dsi_header->errorCode, priv->reply_buf,
819
dsi_header->totalDataLength, priv->free_reply_buf);
820
priv->free_reply_buf = FALSE;
822
g_simple_async_result_set_op_res_gpointer (req_data->simple, reply,
824
g_simple_async_result_complete (req_data->simple);
826
g_hash_table_remove (priv->request_hash,
827
GUINT_TO_POINTER ((guint)dsi_header->requestID));
833
g_assert_not_reached ();
838
read_data_cb (GObject *object, GAsyncResult *res, gpointer user_data)
840
GInputStream *input = G_INPUT_STREAM (object);
841
GVfsAfpConnection *afp_connection = G_VFS_AFP_CONNECTION (user_data);
842
GVfsAfpConnectionPrivate *priv = afp_connection->priv;
847
result = read_all_finish (input, res, NULL, &err);
850
g_warning ("FAIL!!! \"%s\"\n", err->message);
854
dispatch_reply (afp_connection);
856
if (priv->free_reply_buf)
857
g_free (priv->reply_buf);
859
read_reply (afp_connection);
863
read_dsi_header_cb (GObject *object, GAsyncResult *res, gpointer user_data)
865
GInputStream *input = G_INPUT_STREAM (object);
866
GVfsAfpConnection *afp_conn = G_VFS_AFP_CONNECTION (user_data);
867
GVfsAfpConnectionPrivate *priv = afp_conn->priv;
871
DSIHeader *dsi_header;
873
result = read_all_finish (input, res, NULL, &err);
876
g_warning ("FAIL!!! \"%s\"\n", err->message);
880
dsi_header = &priv->read_dsi_header;
882
dsi_header->requestID = GUINT16_FROM_BE (dsi_header->requestID);
883
dsi_header->errorCode = GUINT32_FROM_BE (dsi_header->errorCode);
884
dsi_header->totalDataLength = GUINT32_FROM_BE (dsi_header->totalDataLength);
886
if (dsi_header->totalDataLength > 0)
888
RequestData *req_data;
890
req_data = g_hash_table_lookup (priv->request_hash,
891
GUINT_TO_POINTER ((guint)dsi_header->requestID));
892
if (req_data && req_data->reply_buf)
894
priv->reply_buf = req_data->reply_buf;
895
priv->free_reply_buf = FALSE;
899
priv->reply_buf = g_malloc (dsi_header->totalDataLength);
900
priv->free_reply_buf = TRUE;
903
read_all_async (input, priv->reply_buf, dsi_header->totalDataLength,
904
0, NULL, read_data_cb, afp_conn);
909
dispatch_reply (afp_conn);
910
read_reply (afp_conn);
914
read_reply (GVfsAfpConnection *afp_connection)
916
GVfsAfpConnectionPrivate *priv = afp_connection->priv;
920
input = g_io_stream_get_input_stream (priv->conn);
922
read_all_async (input, &priv->read_dsi_header, sizeof (DSIHeader), 0, NULL,
923
read_dsi_header_cb, afp_connection);
931
GCancellable *cancellable;
932
gssize bytes_written;
936
free_write_all_data (WriteAllData *write_data)
938
if (write_data->cancellable)
939
g_object_unref (write_data->cancellable);
941
g_slice_free (WriteAllData, write_data);
945
write_all_cb (GObject *source_object,
949
GOutputStream *stream = G_OUTPUT_STREAM (source_object);
950
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
952
gssize bytes_written;
954
WriteAllData *write_data;
956
bytes_written = g_output_stream_write_finish (stream, res, &err);
957
if (bytes_written == -1)
959
g_simple_async_result_take_error (simple, err);
963
write_data = g_simple_async_result_get_op_res_gpointer (simple);
965
write_data->bytes_written += bytes_written;
966
if (write_data->bytes_written < write_data->count)
968
g_output_stream_write_async (stream,
969
(const guint8 *)write_data->buffer + write_data->bytes_written,
970
write_data->count - write_data->bytes_written,
971
write_data->io_priority, write_data->cancellable,
972
write_all_cb, simple);
977
g_simple_async_result_complete (simple);
978
g_object_unref (simple);
982
write_all_async (GOutputStream *stream,
986
GCancellable *cancellable,
987
GAsyncReadyCallback callback,
990
GSimpleAsyncResult *simple;
991
WriteAllData *write_data;
993
write_data = g_slice_new0 (WriteAllData);
994
write_data->buffer = buffer;
995
write_data->count = count;
996
write_data->io_priority = io_priority;
998
write_data->cancellable = g_object_ref (cancellable);
1000
simple = g_simple_async_result_new (G_OBJECT (stream), callback, user_data,
1002
g_simple_async_result_set_op_res_gpointer (simple, write_data,
1003
(GDestroyNotify)free_write_all_data);
1005
g_output_stream_write_async (stream, buffer, count, io_priority, cancellable,
1006
write_all_cb, simple);
1010
write_all_finish (GOutputStream *stream,
1012
gsize *bytes_written,
1015
GSimpleAsyncResult *simple;
1017
g_return_val_if_fail (g_simple_async_result_is_valid (res, G_OBJECT (stream),
1021
simple = (GSimpleAsyncResult *)res;
1022
if (g_simple_async_result_propagate_error (simple, error))
1028
WriteAllData *write_data;
1030
write_data = g_simple_async_result_get_op_res_gpointer (simple);
1031
*bytes_written = write_data->bytes_written;
1038
remove_first (GQueue *request_queue)
1040
RequestData *req_data;
1042
req_data = g_queue_pop_head (request_queue);
1043
free_request_data (req_data);
1046
#define HANDLE_RES() { \
1048
GError *err = NULL; \
1050
result = write_all_finish (output, res, NULL, &err); \
1053
if (req_data->simple) \
1055
g_simple_async_result_set_from_error (req_data->simple, err); \
1056
g_simple_async_result_complete (req_data->simple); \
1059
remove_first (priv->request_queue); \
1060
g_error_free (err); \
1062
send_request (afp_conn); \
1069
write_buf_cb (GObject *object, GAsyncResult *res, gpointer user_data)
1071
GOutputStream *output = G_OUTPUT_STREAM (object);
1072
GVfsAfpConnection *afp_conn = G_VFS_AFP_CONNECTION (user_data);
1073
GVfsAfpConnectionPrivate *priv = afp_conn->priv;
1075
RequestData *req_data;
1077
req_data = g_queue_peek_head (priv->request_queue);
1081
g_hash_table_insert (priv->request_hash,
1082
GUINT_TO_POINTER ((guint)GUINT16_FROM_BE (priv->write_dsi_header.requestID)),
1084
g_queue_pop_head (priv->request_queue);
1086
send_request (afp_conn);
1090
write_command_cb (GObject *object, GAsyncResult *res, gpointer user_data)
1092
GOutputStream *output = G_OUTPUT_STREAM (object);
1093
GVfsAfpConnection *afp_conn = G_VFS_AFP_CONNECTION (user_data);
1094
GVfsAfpConnectionPrivate *priv = afp_conn->priv;
1096
RequestData *req_data;
1098
req_data = g_queue_peek_head (priv->request_queue);
1102
if (priv->write_dsi_header.command == DSI_WRITE &&
1103
req_data->command->buf)
1105
write_all_async (output, req_data->command->buf, req_data->command->buf_size,
1106
0, NULL, write_buf_cb, afp_conn);
1110
g_hash_table_insert (priv->request_hash,
1111
GUINT_TO_POINTER ((guint)GUINT16_FROM_BE (priv->write_dsi_header.requestID)),
1113
g_queue_pop_head (priv->request_queue);
1115
send_request (afp_conn);
1119
write_dsi_header_cb (GObject *object, GAsyncResult *res, gpointer user_data)
1121
GOutputStream *output = G_OUTPUT_STREAM (object);
1122
GVfsAfpConnection *afp_conn = G_VFS_AFP_CONNECTION (user_data);
1123
GVfsAfpConnectionPrivate *priv = afp_conn->priv;
1125
RequestData *req_data;
1130
req_data = g_queue_peek_head (priv->request_queue);
1134
if (req_data->type == REQUEST_TYPE_TICKLE)
1136
remove_first (priv->request_queue);
1137
send_request (afp_conn);
1141
data = g_vfs_afp_command_get_data (req_data->command);
1142
size = g_vfs_afp_command_get_size (req_data->command);
1144
write_all_async (output, data, size, 0, NULL, write_command_cb, afp_conn);
1148
send_request (GVfsAfpConnection *afp_connection)
1150
GVfsAfpConnectionPrivate *priv = afp_connection->priv;
1152
RequestData *req_data;
1153
guint32 writeOffset;
1156
while ((req_data = g_queue_peek_head (priv->request_queue)))
1158
if (req_data->cancellable && g_cancellable_is_cancelled (req_data->cancellable))
1160
if (req_data->simple)
1164
g_cancellable_set_error_if_cancelled (req_data->cancellable, &err);
1165
g_simple_async_result_take_error (req_data->simple, err);
1166
g_simple_async_result_complete (req_data->simple);
1168
remove_first (priv->request_queue);
1175
priv->send_loop_running = FALSE;
1179
switch (req_data->type)
1181
case REQUEST_TYPE_TICKLE:
1182
priv->write_dsi_header.flags = 0x00;
1183
priv->write_dsi_header.command = DSI_TICKLE;
1184
priv->write_dsi_header.requestID = GUINT16_TO_BE (get_request_id (afp_connection));
1185
priv->write_dsi_header.writeOffset = 0;
1186
priv->write_dsi_header.totalDataLength = 0;
1187
priv->write_dsi_header.reserved = 0;
1190
case REQUEST_TYPE_COMMAND:
1194
switch (req_data->command->type)
1196
case AFP_COMMAND_WRITE:
1198
dsi_command = DSI_WRITE;
1200
case AFP_COMMAND_WRITE_EXT:
1202
dsi_command = DSI_WRITE;
1207
dsi_command = DSI_COMMAND;
1211
priv->write_dsi_header.flags = 0x00;
1212
priv->write_dsi_header.command = dsi_command;
1213
priv->write_dsi_header.requestID = GUINT16_TO_BE (get_request_id (afp_connection));
1214
priv->write_dsi_header.writeOffset = GUINT32_TO_BE (writeOffset);
1216
/* totalDataLength */
1217
size = g_vfs_afp_command_get_size (req_data->command);
1218
if (dsi_command == DSI_WRITE && req_data->command->buf)
1219
size += req_data->command->buf_size;
1220
priv->write_dsi_header.totalDataLength = GUINT32_TO_BE (size);
1222
priv->write_dsi_header.reserved = 0;
1227
g_assert_not_reached ();
1231
write_all_async (g_io_stream_get_output_stream (priv->conn),
1232
&priv->write_dsi_header, sizeof (DSIHeader), 0,
1233
NULL, write_dsi_header_cb, afp_connection);
1237
g_vfs_afp_connection_send_command (GVfsAfpConnection *afp_connection,
1238
GVfsAfpCommand *command,
1240
GAsyncReadyCallback callback,
1241
GCancellable *cancellable,
1244
GVfsAfpConnectionPrivate *priv = afp_connection->priv;
1246
RequestData *req_data;
1248
req_data = g_slice_new0 (RequestData);
1249
req_data->type = REQUEST_TYPE_COMMAND;
1250
req_data->command = g_object_ref (command);
1251
req_data->reply_buf = reply_buf;
1253
req_data->simple = g_simple_async_result_new (G_OBJECT (afp_connection), callback,
1255
g_vfs_afp_connection_send_command);
1257
req_data->cancellable = g_object_ref (cancellable);
1259
g_queue_push_tail (priv->request_queue, req_data);
1261
run_loop (afp_connection);
1265
g_vfs_afp_connection_send_command_finish (GVfsAfpConnection *afp_connection,
1269
GSimpleAsyncResult *simple;
1271
g_return_val_if_fail (g_simple_async_result_is_valid (res,
1272
G_OBJECT (afp_connection),
1273
g_vfs_afp_connection_send_command),
1276
simple = (GSimpleAsyncResult *)res;
1278
if (g_simple_async_result_propagate_error (simple, error))
1281
return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
1285
read_reply_sync (GInputStream *input,
1286
DSIHeader *dsi_header,
1288
GCancellable *cancellable,
1292
gsize read_count, bytes_read;
1294
g_assert (dsi_header != NULL);
1296
read_count = sizeof (DSIHeader);
1297
res = g_input_stream_read_all (input, dsi_header, read_count, &bytes_read,
1298
cancellable, error);
1302
if (bytes_read < read_count)
1304
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
1309
dsi_header->requestID = GUINT16_FROM_BE (dsi_header->requestID);
1310
dsi_header->errorCode = GUINT32_FROM_BE (dsi_header->errorCode);
1311
dsi_header->totalDataLength = GUINT32_FROM_BE (dsi_header->totalDataLength);
1313
if (dsi_header->totalDataLength == 0)
1319
*data = g_malloc (dsi_header->totalDataLength);
1320
read_count = dsi_header->totalDataLength;
1322
res = g_input_stream_read_all (input, *data, read_count, &bytes_read, cancellable, error);
1328
if (bytes_read < read_count)
1331
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
1340
g_vfs_afp_connection_read_reply_sync (GVfsAfpConnection *afp_connection,
1341
GCancellable *cancellable,
1344
GVfsAfpConnectionPrivate *priv = afp_connection->priv;
1348
DSIHeader dsi_header;
1350
res = read_reply_sync (g_io_stream_get_input_stream (priv->conn), &dsi_header,
1351
&data, cancellable, error);
1355
return g_vfs_afp_reply_new (dsi_header.errorCode, data, dsi_header.totalDataLength, TRUE);
1359
send_request_sync (GOutputStream *output,
1362
guint32 writeOffset,
1365
GCancellable *cancellable,
1368
DSIHeader dsi_header;
1370
gsize write_count, bytes_written;
1372
dsi_header.flags = 0x00;
1373
dsi_header.command = command;
1374
dsi_header.requestID = GUINT16_TO_BE (request_id);
1375
dsi_header.writeOffset = GUINT32_TO_BE (writeOffset);
1376
dsi_header.totalDataLength = GUINT32_TO_BE (len);
1377
dsi_header.reserved = 0;
1379
write_count = sizeof (DSIHeader);
1380
res = g_output_stream_write_all (output, &dsi_header, write_count,
1381
&bytes_written, cancellable, error);
1389
res = g_output_stream_write_all (output, data, write_count, &bytes_written,
1390
cancellable, error);
1398
g_vfs_afp_connection_send_command_sync (GVfsAfpConnection *afp_connection,
1399
GVfsAfpCommand *afp_command,
1400
GCancellable *cancellable,
1403
GVfsAfpConnectionPrivate *priv = afp_connection->priv;
1405
DsiCommand dsi_command;
1407
guint32 writeOffset;
1409
/* set dsi_command */
1410
switch (afp_command->type)
1412
case AFP_COMMAND_WRITE:
1414
dsi_command = DSI_WRITE;
1416
case AFP_COMMAND_WRITE_EXT:
1418
dsi_command = DSI_WRITE;
1423
dsi_command = DSI_COMMAND;
1427
req_id = get_request_id (afp_connection);
1428
return send_request_sync (g_io_stream_get_output_stream (priv->conn),
1429
dsi_command, req_id, writeOffset,
1430
g_vfs_afp_command_get_size (afp_command),
1431
g_vfs_afp_command_get_data (afp_command),
1432
cancellable, error);
1436
g_vfs_afp_connection_close (GVfsAfpConnection *afp_connection,
1437
GCancellable *cancellable,
1440
GVfsAfpConnectionPrivate *priv = afp_connection->priv;
1445
/* close DSI session */
1446
req_id = get_request_id (afp_connection);
1447
res = send_request_sync (g_io_stream_get_output_stream (priv->conn),
1448
DSI_CLOSE_SESSION, req_id, 0, 0, NULL,
1449
cancellable, error);
1452
g_io_stream_close (priv->conn, cancellable, NULL);
1453
g_object_unref (priv->conn);
1457
res = g_io_stream_close (priv->conn, cancellable, error);
1458
g_object_unref (priv->conn);
1464
g_vfs_afp_connection_open (GVfsAfpConnection *afp_connection,
1465
GCancellable *cancellable,
1468
GVfsAfpConnectionPrivate *priv = afp_connection->priv;
1470
GSocketClient *client;
1475
DSIHeader dsi_header;
1478
client = g_socket_client_new ();
1479
priv->conn = G_IO_STREAM (g_socket_client_connect (client, priv->addr, cancellable, error));
1480
g_object_unref (client);
1485
req_id = get_request_id (afp_connection);
1486
res = send_request_sync (g_io_stream_get_output_stream (priv->conn),
1487
DSI_OPEN_SESSION, req_id, 0, 0, NULL,
1488
cancellable, error);
1492
res = read_reply_sync (g_io_stream_get_input_stream (priv->conn),
1493
&dsi_header, &reply, cancellable, error);
1498
while ((dsi_header.totalDataLength - pos) > 2)
1501
guint8 optionLength;
1503
optionType = reply[pos++];
1504
optionLength = reply[pos++];
1510
if (optionLength == 4 && (dsi_header.totalDataLength - pos) >= 4)
1511
priv->kRequestQuanta = GUINT32_FROM_BE (*(guint32 *)(reply + pos));
1516
if (optionLength == 4 && (dsi_header.totalDataLength - pos) >= 4)
1517
priv->kServerReplayCacheSize = GUINT32_FROM_BE (*(guint32 *)(reply + pos));
1523
g_debug ("Unknown DSI option\n");
1526
pos += optionLength;
1534
g_vfs_afp_connection_get_server_info (GVfsAfpConnection *afp_connection,
1535
GCancellable *cancellable,
1538
GVfsAfpConnectionPrivate *priv = afp_connection->priv;
1540
GSocketClient *client;
1543
DSIHeader dsi_header;
1546
client = g_socket_client_new ();
1547
conn = G_IO_STREAM (g_socket_client_connect (client, priv->addr, cancellable, error));
1548
g_object_unref (client);
1553
res = send_request_sync (g_io_stream_get_output_stream (conn), DSI_GET_STATUS,
1554
0, 0, 0, NULL, cancellable, error);
1557
g_object_unref (conn);
1561
res = read_reply_sync (g_io_stream_get_input_stream (conn), &dsi_header,
1562
&data, cancellable, error);
1565
g_object_unref (conn);
1569
g_object_unref (conn);
1571
return g_vfs_afp_reply_new (dsi_header.errorCode, data,
1572
dsi_header.totalDataLength, TRUE);
1576
g_vfs_afp_connection_new (GSocketConnectable *addr)
1578
GVfsAfpConnection *afp_connection;
1579
GVfsAfpConnectionPrivate *priv;
1581
afp_connection = g_object_new (G_VFS_TYPE_AFP_CONNECTION, NULL);
1582
priv = afp_connection->priv;
1584
priv->addr = g_object_ref (addr);
1586
return afp_connection;
1590
g_vfs_afp_connection_init (GVfsAfpConnection *afp_connection)
1592
GVfsAfpConnectionPrivate *priv;
1594
afp_connection->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (afp_connection,
1595
G_VFS_TYPE_AFP_CONNECTION,
1596
GVfsAfpConnectionPrivate);
1600
priv->request_id = 0;
1602
priv->kRequestQuanta = -1;
1603
priv->kServerReplayCacheSize = -1;
1605
priv->request_queue = g_queue_new ();
1606
priv->request_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal,
1607
NULL, (GDestroyNotify)free_request_data);
1609
priv->send_loop_running = FALSE;
1610
priv->read_loop_running = FALSE;
1614
g_vfs_afp_connection_finalize (GObject *object)
1616
GVfsAfpConnection *afp_connection = (GVfsAfpConnection *)object;
1617
GVfsAfpConnectionPrivate *priv = afp_connection->priv;
1620
g_object_unref (priv->addr);
1623
g_object_unref (priv->conn);
1625
G_OBJECT_CLASS (g_vfs_afp_connection_parent_class)->finalize (object);
1629
g_vfs_afp_connection_class_init (GVfsAfpConnectionClass *klass)
1631
GObjectClass* object_class = G_OBJECT_CLASS (klass);
1633
g_type_class_add_private (klass, sizeof (GVfsAfpConnectionPrivate));
1635
object_class->finalize = g_vfs_afp_connection_finalize;
1637
signals[ATTENTION] =
1638
g_signal_new ("attention",
1639
G_TYPE_FROM_CLASS (object_class),
1640
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
1641
0, NULL, NULL, g_cclosure_marshal_VOID__UINT,
1642
G_TYPE_NONE, 1, G_TYPE_UINT);