~ubuntu-branches/ubuntu/oneiric/gvfs/oneiric-updates

« back to all changes in this revision

Viewing changes to daemon/gvfsafpconnection.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2011-09-06 09:24:10 UTC
  • mfrom: (1.1.74 upstream)
  • Revision ID: package-import@ubuntu.com-20110906092410-bdt13pvj6ns5f5n2
Tags: 1.9.5-0ubuntu1
* debian/watch: Fix syntax.
* New upstream release.
* debian/control.in: Add libgcrypt11-dev build dependency as per
  configure.ac.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 /* GIO - GLib Input, Output and Streaming Library
 
2
 * 
 
3
 * Copyright (C) Carl-Anton Ingmarsson 2011 <ca.ingmarsson@gmail.com>
 
4
 *
 
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.
 
9
 *
 
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.
 
14
 *
 
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.
 
19
 *
 
20
 * Author: Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com>
 
21
 */
 
22
 
 
23
#include <string.h>
 
24
#include <glib/gi18n.h>
 
25
 
 
26
 
 
27
#include "gvfsafpconnection.h"
 
28
 
 
29
/*
 
30
 * GVfsAfpName
 
31
 */
 
32
 
 
33
static void
 
34
_g_vfs_afp_name_free (GVfsAfpName *afp_name)
 
35
{
 
36
  g_free (afp_name->str);
 
37
  g_slice_free (GVfsAfpName, afp_name);
 
38
}
 
39
 
 
40
void
 
41
g_vfs_afp_name_unref (GVfsAfpName *afp_name)
 
42
{
 
43
  if (g_atomic_int_dec_and_test (&afp_name->ref_count))
 
44
    _g_vfs_afp_name_free (afp_name);
 
45
}
 
46
 
 
47
void
 
48
g_vfs_afp_name_ref (GVfsAfpName *afp_name)
 
49
{
 
50
  g_atomic_int_inc (&afp_name->ref_count);
 
51
}
 
52
 
 
53
char *
 
54
g_vfs_afp_name_get_string (GVfsAfpName *afp_name)
 
55
{
 
56
  return g_utf8_normalize (afp_name->str, afp_name->len, G_NORMALIZE_DEFAULT_COMPOSE);
 
57
}
 
58
 
 
59
GVfsAfpName *
 
60
g_vfs_afp_name_new (guint32 text_encoding, gchar *str, gsize len)
 
61
{
 
62
  GVfsAfpName *afp_name;
 
63
 
 
64
  afp_name = g_slice_new (GVfsAfpName);
 
65
  afp_name->ref_count = 1;
 
66
  
 
67
  afp_name->text_encoding = text_encoding;
 
68
 
 
69
  afp_name->str = str;
 
70
  afp_name->len = len;
 
71
 
 
72
  return afp_name;
 
73
}
 
74
 
 
75
/*
 
76
 * GVfsAfpReply
 
77
 */
 
78
struct _GVfsAfpReplyClass
 
79
{
 
80
  GObjectClass parent_class;
 
81
};
 
82
 
 
83
struct _GVfsAfpReply
 
84
{
 
85
  GObject parent_instance;
 
86
 
 
87
  AfpResultCode result_code;
 
88
 
 
89
  char *data;
 
90
  gsize len;
 
91
  gboolean free_data;
 
92
 
 
93
  goffset pos;
 
94
};
 
95
 
 
96
G_DEFINE_TYPE (GVfsAfpReply, g_vfs_afp_reply, G_TYPE_OBJECT);
 
97
 
 
98
static void
 
99
g_vfs_afp_reply_init (GVfsAfpReply *reply)
 
100
{
 
101
  reply->data = NULL;
 
102
  reply->len = 0;
 
103
  reply->pos = 0;
 
104
}
 
105
 
 
106
static void
 
107
g_vfs_afp_reply_finalize (GObject *object)
 
108
{
 
109
  GVfsAfpReply *reply = (GVfsAfpReply *)object;
 
110
 
 
111
  if (reply->free_data)
 
112
    g_free (reply->data);
 
113
}
 
114
 
 
115
static void
 
116
g_vfs_afp_reply_class_init (GVfsAfpReplyClass *klass)
 
117
{
 
118
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
119
 
 
120
  object_class->finalize = g_vfs_afp_reply_finalize;
 
121
}
 
122
 
 
123
static GVfsAfpReply *
 
124
g_vfs_afp_reply_new (AfpResultCode result_code, char *data, gsize len, gboolean take_data)
 
125
{
 
126
  GVfsAfpReply *reply;
 
127
 
 
128
  reply = g_object_new (G_VFS_TYPE_AFP_REPLY, NULL);
 
129
 
 
130
  reply->result_code = result_code;
 
131
  reply->len = len;
 
132
  reply->data = data;
 
133
  reply->free_data = take_data;
 
134
  
 
135
  return reply;
 
136
}
 
137
 
 
138
gboolean
 
139
g_vfs_afp_reply_read_byte (GVfsAfpReply *reply, guint8 *byte)
 
140
{
 
141
  if ((reply->len - reply->pos) < 1)
 
142
    return FALSE;
 
143
 
 
144
  if (byte)
 
145
    *byte = reply->data[reply->pos];
 
146
 
 
147
  reply->pos++;
 
148
 
 
149
  return TRUE;
 
150
}
 
151
 
 
152
gboolean
 
153
g_vfs_afp_reply_read_int64 (GVfsAfpReply *reply, gint64 *val)
 
154
{
 
155
  if ((reply->len - reply->pos) < 8)
 
156
    return FALSE;
 
157
 
 
158
  if (val)
 
159
    *val = GINT64_FROM_BE (*((gint64 *)(reply->data + reply->pos)));
 
160
 
 
161
  reply->pos += 8;
 
162
  
 
163
  return TRUE;
 
164
}
 
165
 
 
166
gboolean
 
167
g_vfs_afp_reply_read_int32 (GVfsAfpReply *reply, gint32 *val)
 
168
{
 
169
  if ((reply->len - reply->pos) < 4)
 
170
    return FALSE;
 
171
 
 
172
  if (val)
 
173
    *val = GINT32_FROM_BE (*((gint32 *)(reply->data + reply->pos)));
 
174
 
 
175
  reply->pos += 4;
 
176
  
 
177
  return TRUE;
 
178
}
 
179
 
 
180
gboolean
 
181
g_vfs_afp_reply_read_int16 (GVfsAfpReply *reply, gint16 *val)
 
182
{
 
183
  if ((reply->len - reply->pos) < 2)
 
184
    return FALSE;
 
185
 
 
186
  if (val)
 
187
    *val = GINT16_FROM_BE (*((gint16 *)(reply->data + reply->pos)));
 
188
 
 
189
  reply->pos += 2;
 
190
  
 
191
  return TRUE;
 
192
}
 
193
 
 
194
gboolean
 
195
g_vfs_afp_reply_read_uint64 (GVfsAfpReply *reply, guint64 *val)
 
196
{
 
197
  if ((reply->len - reply->pos) < 8)
 
198
    return FALSE;
 
199
 
 
200
  if (val)
 
201
    *val = GUINT64_FROM_BE (*((guint64 *)(reply->data + reply->pos)));
 
202
 
 
203
  reply->pos += 8;
 
204
  
 
205
  return TRUE;
 
206
}
 
207
 
 
208
gboolean
 
209
g_vfs_afp_reply_read_uint32 (GVfsAfpReply *reply, guint32 *val)
 
210
{
 
211
  if ((reply->len - reply->pos) < 4)
 
212
    return FALSE;
 
213
 
 
214
  if (val)
 
215
    *val = GUINT32_FROM_BE (*((guint32 *)(reply->data + reply->pos)));
 
216
 
 
217
  reply->pos += 4;
 
218
  
 
219
  return TRUE;
 
220
}
 
221
 
 
222
gboolean
 
223
g_vfs_afp_reply_read_uint16 (GVfsAfpReply *reply, guint16 *val)
 
224
{
 
225
  if ((reply->len - reply->pos) < 2)
 
226
    return FALSE;
 
227
 
 
228
  if (val)
 
229
    *val = GUINT16_FROM_BE (*((guint16 *)(reply->data + reply->pos)));
 
230
 
 
231
  reply->pos += 2;
 
232
  
 
233
  return TRUE;
 
234
}
 
235
 
 
236
gboolean
 
237
g_vfs_afp_reply_get_data (GVfsAfpReply *reply, gsize size, guint8 **data)
 
238
{
 
239
  if ((reply->len - reply->pos) < size)
 
240
    return FALSE;
 
241
 
 
242
  if (data)
 
243
    *data = (guint8 *)(reply->data + reply->pos);
 
244
 
 
245
  reply->pos += size;
 
246
 
 
247
  return TRUE;
 
248
}
 
249
 
 
250
gboolean
 
251
g_vfs_afp_reply_dup_data (GVfsAfpReply *reply, gsize size, guint8 **data)
 
252
{
 
253
  if ((reply->len - reply->pos) < size)
 
254
    return FALSE;
 
255
 
 
256
  if (data)
 
257
  {
 
258
    *data = g_malloc (size);
 
259
    memcpy (*data, reply->data + reply->pos, size);
 
260
  }
 
261
 
 
262
  reply->pos += size;
 
263
 
 
264
  return TRUE;
 
265
}
 
266
 
 
267
gboolean
 
268
g_vfs_afp_reply_read_pascal (GVfsAfpReply *reply, char **str)
 
269
{
 
270
  guint8 strsize;
 
271
  
 
272
  if (!g_vfs_afp_reply_read_byte (reply, &strsize))
 
273
    return FALSE;
 
274
 
 
275
  if (strsize > (reply->len - reply->pos))
 
276
  {
 
277
    reply->pos--;
 
278
    return FALSE;
 
279
  }
 
280
 
 
281
  if (str)
 
282
    *str = g_strndup (reply->data + reply->pos, strsize);
 
283
 
 
284
  reply->pos += strsize;
 
285
  
 
286
  return TRUE;
 
287
}
 
288
 
 
289
gboolean
 
290
g_vfs_afp_reply_read_afp_name (GVfsAfpReply *reply, gboolean read_text_encoding,
 
291
                               GVfsAfpName **afp_name)
 
292
{
 
293
  gint old_pos;
 
294
  
 
295
  guint32 text_encoding;
 
296
  guint16 len;
 
297
  gchar *str;
 
298
 
 
299
  old_pos = reply->pos;
 
300
  
 
301
  if (read_text_encoding)
 
302
  {
 
303
    if (!g_vfs_afp_reply_read_uint32 (reply, &text_encoding))
 
304
      return FALSE;
 
305
  }
 
306
  else
 
307
    text_encoding = 0;
 
308
  
 
309
  if (!g_vfs_afp_reply_read_uint16 (reply, &len))
 
310
  {
 
311
    reply->pos = old_pos;
 
312
    return FALSE;
 
313
  }  
 
314
  
 
315
  if (!g_vfs_afp_reply_get_data (reply, len, (guint8 **)&str))
 
316
  {
 
317
    reply->pos = old_pos;
 
318
    return FALSE;
 
319
  }
 
320
 
 
321
  if (afp_name)
 
322
    *afp_name = g_vfs_afp_name_new (text_encoding, g_strndup (str, len), len);
 
323
 
 
324
  return TRUE;
 
325
    
 
326
}
 
327
 
 
328
gboolean
 
329
g_vfs_afp_reply_seek (GVfsAfpReply *reply, goffset offset, GSeekType type)
 
330
{
 
331
  goffset absolute;
 
332
  
 
333
  switch (type)
 
334
  {
 
335
    case G_SEEK_CUR:
 
336
      absolute = reply->pos + offset;
 
337
      break;
 
338
 
 
339
    case G_SEEK_SET:
 
340
      absolute = offset;
 
341
      break;
 
342
      
 
343
    case G_SEEK_END:
 
344
      absolute = reply->len + offset;
 
345
      break;
 
346
 
 
347
    default:
 
348
      return FALSE;
 
349
  }
 
350
 
 
351
  if (absolute < 0 || absolute >= reply->len)
 
352
    return FALSE;
 
353
 
 
354
  reply->pos = absolute;
 
355
  return TRUE;
 
356
}
 
357
 
 
358
gboolean
 
359
g_vfs_afp_reply_skip_to_even (GVfsAfpReply *reply)
 
360
{
 
361
  if ((reply->pos % 2) == 0)
 
362
    return TRUE;
 
363
 
 
364
  if ((reply->len - reply->pos) < 1)
 
365
    return FALSE;
 
366
 
 
367
  reply->pos++;
 
368
 
 
369
  return TRUE;
 
370
}
 
371
 
 
372
goffset
 
373
g_vfs_afp_reply_get_pos (GVfsAfpReply *reply)
 
374
{
 
375
  return reply->pos;
 
376
}
 
377
 
 
378
gsize
 
379
g_vfs_afp_reply_get_size (GVfsAfpReply *reply)
 
380
{
 
381
  return reply->len;
 
382
}
 
383
 
 
384
AfpResultCode
 
385
g_vfs_afp_reply_get_result_code (GVfsAfpReply *reply)
 
386
{
 
387
  return reply->result_code;
 
388
}
 
389
 
 
390
/*
 
391
 * GVfsAfpCommand
 
392
 */
 
393
struct _GVfsAfpCommandClass
 
394
{
 
395
  GDataOutputStreamClass parent_class;
 
396
};
 
397
 
 
398
struct _GVfsAfpCommand
 
399
{
 
400
  GDataOutputStream parent_instance;
 
401
  
 
402
  AfpCommandType type;
 
403
 
 
404
  char *buf;
 
405
  gsize buf_size;
 
406
};
 
407
 
 
408
G_DEFINE_TYPE (GVfsAfpCommand, g_vfs_afp_command, G_TYPE_DATA_OUTPUT_STREAM);
 
409
 
 
410
 
 
411
static void
 
412
g_vfs_afp_command_init (GVfsAfpCommand *comm)
 
413
{
 
414
}
 
415
 
 
416
static void
 
417
g_vfs_afp_command_class_init (GVfsAfpCommandClass *klass)
 
418
{
 
419
}
 
420
 
 
421
GVfsAfpCommand *
 
422
g_vfs_afp_command_new (AfpCommandType type)
 
423
{
 
424
  GOutputStream *mem_stream;
 
425
  GVfsAfpCommand *comm;
 
426
 
 
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,
 
430
                       NULL);
 
431
 
 
432
  g_object_unref (mem_stream);
 
433
  
 
434
  comm->type = type;
 
435
  g_vfs_afp_command_put_byte (comm, type);
 
436
 
 
437
  return comm;
 
438
}
 
439
 
 
440
void
 
441
g_vfs_afp_command_put_byte (GVfsAfpCommand *comm, guint8 byte)
 
442
{
 
443
  g_data_output_stream_put_byte (G_DATA_OUTPUT_STREAM (comm), byte, NULL, NULL);
 
444
}
 
445
 
 
446
void
 
447
g_vfs_afp_command_put_int16 (GVfsAfpCommand *comm, gint16 val)
 
448
{
 
449
  g_data_output_stream_put_int16 (G_DATA_OUTPUT_STREAM (comm), val, NULL, NULL);
 
450
}
 
451
 
 
452
void
 
453
g_vfs_afp_command_put_int32 (GVfsAfpCommand *comm, gint32 val)
 
454
{
 
455
  g_data_output_stream_put_int32 (G_DATA_OUTPUT_STREAM (comm), val, NULL, NULL);
 
456
}
 
457
 
 
458
void
 
459
g_vfs_afp_command_put_int64 (GVfsAfpCommand *comm, gint64 val)
 
460
{
 
461
  g_data_output_stream_put_int64 (G_DATA_OUTPUT_STREAM (comm), val, NULL, NULL);
 
462
}
 
463
 
 
464
void
 
465
g_vfs_afp_command_put_uint16 (GVfsAfpCommand *comm, guint16 val)
 
466
{
 
467
  g_data_output_stream_put_uint16 (G_DATA_OUTPUT_STREAM (comm), val, NULL, NULL);
 
468
}
 
469
 
 
470
void
 
471
g_vfs_afp_command_put_uint32 (GVfsAfpCommand *comm, guint32 val)
 
472
{
 
473
  g_data_output_stream_put_uint32 (G_DATA_OUTPUT_STREAM (comm), val, NULL, NULL);
 
474
}
 
475
 
 
476
void
 
477
g_vfs_afp_command_put_uint64 (GVfsAfpCommand *comm, guint64 val)
 
478
{
 
479
  g_data_output_stream_put_uint64 (G_DATA_OUTPUT_STREAM (comm), val, NULL, NULL);
 
480
}
 
481
 
 
482
void
 
483
g_vfs_afp_command_put_pascal (GVfsAfpCommand *comm, const char *str)
 
484
{
 
485
  size_t len;
 
486
 
 
487
  len = MIN (strlen (str), 256);
 
488
 
 
489
  g_vfs_afp_command_put_byte (comm, len);
 
490
  g_output_stream_write (G_OUTPUT_STREAM (comm), str, len, NULL, NULL);
 
491
}
 
492
 
 
493
void
 
494
g_vfs_afp_command_put_afp_name (GVfsAfpCommand *comm, GVfsAfpName *afp_name)
 
495
{
 
496
  g_vfs_afp_command_put_uint32 (comm, afp_name->text_encoding);
 
497
  g_vfs_afp_command_put_uint16 (comm, afp_name->len);
 
498
 
 
499
  if (afp_name->len > 0)
 
500
  {
 
501
    g_output_stream_write_all (G_OUTPUT_STREAM (comm), afp_name->str,
 
502
                               afp_name->len, NULL, NULL, NULL);
 
503
  }
 
504
}
 
505
 
 
506
void
 
507
g_vfs_afp_command_pad_to_even (GVfsAfpCommand *comm)
 
508
 
509
  if (g_vfs_afp_command_get_size (comm) % 2 == 1)
 
510
    g_vfs_afp_command_put_byte (comm, 0);
 
511
}
 
512
 
 
513
gsize
 
514
g_vfs_afp_command_get_size (GVfsAfpCommand *comm)
 
515
{
 
516
  GMemoryOutputStream *mem_stream;
 
517
 
 
518
  mem_stream =
 
519
    G_MEMORY_OUTPUT_STREAM (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (comm)));
 
520
 
 
521
  return g_memory_output_stream_get_data_size (mem_stream);
 
522
}
 
523
 
 
524
char *
 
525
g_vfs_afp_command_get_data (GVfsAfpCommand *comm)
 
526
{
 
527
  GMemoryOutputStream *mem_stream;
 
528
 
 
529
  mem_stream =
 
530
    G_MEMORY_OUTPUT_STREAM (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (comm)));
 
531
 
 
532
  return g_memory_output_stream_get_data (mem_stream);
 
533
}
 
534
 
 
535
void
 
536
g_vfs_afp_command_set_buffer (GVfsAfpCommand *comm, char *buf, gsize size)
 
537
{
 
538
  g_return_if_fail (buf != NULL);
 
539
  g_return_if_fail (size > 0);
 
540
 
 
541
  comm->buf = buf;
 
542
  comm->buf_size = size;
 
543
}
 
544
 
 
545
/*
 
546
 * GVfsAfpConnection
 
547
 */
 
548
 
 
549
enum {
 
550
  ATTENTION,
 
551
  LAST_SIGNAL
 
552
};
 
553
 
 
554
static guint signals[LAST_SIGNAL] = {0,};
 
555
 
 
556
G_DEFINE_TYPE (GVfsAfpConnection, g_vfs_afp_connection, G_TYPE_OBJECT);
 
557
 
 
558
typedef struct {
 
559
  guint8 flags;
 
560
  guint8 command;
 
561
  guint16 requestID;
 
562
  union {
 
563
    guint32 errorCode;
 
564
    guint32 writeOffset;
 
565
  };
 
566
  guint32 totalDataLength;
 
567
  guint32 reserved;
 
568
} DSIHeader;
 
569
 
 
570
struct _GVfsAfpConnectionPrivate
 
571
{
 
572
  GSocketConnectable *addr;
 
573
  GIOStream *conn;
 
574
 
 
575
  guint16 request_id;
 
576
 
 
577
  guint32 kRequestQuanta;
 
578
  guint32 kServerReplayCacheSize;
 
579
 
 
580
  GQueue     *request_queue;
 
581
  GHashTable *request_hash;
 
582
 
 
583
  /* send loop */
 
584
  gboolean send_loop_running;
 
585
  DSIHeader write_dsi_header;
 
586
 
 
587
  /* read loop */
 
588
  gboolean read_loop_running;
 
589
  DSIHeader read_dsi_header;
 
590
  char *reply_buf;
 
591
  gboolean free_reply_buf;
 
592
};
 
593
 
 
594
typedef enum
 
595
{
 
596
  DSI_CLOSE_SESSION = 1,
 
597
  DSI_COMMAND       = 2,
 
598
  DSI_GET_STATUS    = 3,
 
599
  DSI_OPEN_SESSION  = 4,
 
600
  DSI_TICKLE        = 5,
 
601
  DSI_WRITE         = 6,
 
602
  DSI_ATTENTION     = 8
 
603
} DsiCommand;
 
604
 
 
605
static void read_reply (GVfsAfpConnection *afp_connection);
 
606
static void send_request (GVfsAfpConnection *afp_connection);
 
607
 
 
608
static guint16
 
609
get_request_id (GVfsAfpConnection *afp_connection)
 
610
{
 
611
  GVfsAfpConnectionPrivate *priv = afp_connection->priv;
 
612
 
 
613
  return priv->request_id++;
 
614
}
 
615
 
 
616
typedef enum
 
617
{
 
618
  REQUEST_TYPE_COMMAND,
 
619
  REQUEST_TYPE_TICKLE
 
620
} RequestType;
 
621
 
 
622
typedef struct
 
623
{
 
624
  RequestType type;
 
625
  
 
626
  GVfsAfpCommand *command;
 
627
  char           *reply_buf;
 
628
  GSimpleAsyncResult *simple;
 
629
  GCancellable *cancellable;
 
630
} RequestData;
 
631
 
 
632
static void
 
633
free_request_data (RequestData *req_data)
 
634
{
 
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);
 
641
 
 
642
  g_slice_free (RequestData, req_data);
 
643
}
 
644
 
 
645
static void
 
646
run_loop (GVfsAfpConnection *afp_connection)
 
647
{
 
648
  GVfsAfpConnectionPrivate *priv = afp_connection->priv;
 
649
 
 
650
  if (!priv->send_loop_running)
 
651
  {
 
652
    priv->send_loop_running = TRUE;
 
653
    send_request (afp_connection);
 
654
  }
 
655
  if (!priv->read_loop_running)
 
656
  {
 
657
    priv->read_loop_running = TRUE;
 
658
    read_reply (afp_connection);
 
659
  }
 
660
}
 
661
 
 
662
typedef struct
 
663
{
 
664
  void         *buffer;
 
665
  gsize         count;
 
666
  int           io_priority;
 
667
  GCancellable *cancellable;
 
668
  gsize         bytes_read;
 
669
} ReadAllData;
 
670
 
 
671
static void
 
672
free_read_all_data (ReadAllData *read_data)
 
673
{
 
674
  if (read_data->cancellable)
 
675
    g_object_unref (read_data->cancellable);
 
676
 
 
677
  g_slice_free (ReadAllData, read_data);
 
678
}
 
679
 
 
680
static void
 
681
read_all_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
 
682
{
 
683
  GInputStream *stream = G_INPUT_STREAM (source_object);
 
684
  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
 
685
 
 
686
  gsize bytes_read;
 
687
  GError *err = NULL;
 
688
  ReadAllData *read_data;
 
689
 
 
690
  bytes_read = g_input_stream_read_finish (stream, res, &err);
 
691
  if (bytes_read == -1)
 
692
  {
 
693
    g_simple_async_result_take_error (simple, err);
 
694
    goto done;
 
695
  }
 
696
 
 
697
  read_data = g_simple_async_result_get_op_res_gpointer (simple);
 
698
 
 
699
  read_data->bytes_read += bytes_read;
 
700
  if (read_data->bytes_read < read_data->count)
 
701
  {
 
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);
 
706
    return;
 
707
  }
 
708
 
 
709
done:
 
710
  g_simple_async_result_complete (simple);
 
711
  g_object_unref (simple);
 
712
}
 
713
 
 
714
static void
 
715
read_all_async (GInputStream        *stream,
 
716
                void                *buffer,
 
717
                gsize                count,
 
718
                int                  io_priority,
 
719
                GCancellable        *cancellable,
 
720
                GAsyncReadyCallback  callback,
 
721
                gpointer             user_data)
 
722
{
 
723
  ReadAllData *read_data;
 
724
  GSimpleAsyncResult *simple;
 
725
 
 
726
  read_data = g_slice_new0 (ReadAllData);
 
727
  read_data->buffer = buffer;
 
728
  read_data->count = count;
 
729
  read_data->io_priority = io_priority;
 
730
  if (cancellable)
 
731
    read_data->cancellable = g_object_ref (cancellable);
 
732
  
 
733
  simple = g_simple_async_result_new (G_OBJECT (stream), callback, user_data,
 
734
                                      read_all_async);
 
735
  g_simple_async_result_set_op_res_gpointer (simple, read_data,
 
736
                                             (GDestroyNotify)free_read_all_data);
 
737
 
 
738
  g_input_stream_read_async (stream, buffer, count, io_priority, cancellable,
 
739
                             read_all_cb, simple);
 
740
}
 
741
 
 
742
static gboolean
 
743
read_all_finish (GInputStream *stream,
 
744
                 GAsyncResult *res,
 
745
                 gsize        *bytes_read,
 
746
                 GError      **error)
 
747
{
 
748
  GSimpleAsyncResult *simple;
 
749
 
 
750
  g_return_val_if_fail (g_simple_async_result_is_valid (res, G_OBJECT (stream),
 
751
                                                        read_all_async),
 
752
                        FALSE);
 
753
 
 
754
  simple = (GSimpleAsyncResult *)res;
 
755
 
 
756
  if (g_simple_async_result_propagate_error (simple, error))
 
757
    return FALSE;
 
758
 
 
759
  if (bytes_read)
 
760
  {
 
761
    ReadAllData *read_data;
 
762
 
 
763
    read_data = g_simple_async_result_get_op_res_gpointer (simple);
 
764
    *bytes_read = read_data->bytes_read;
 
765
  }
 
766
 
 
767
  return TRUE;
 
768
}
 
769
 
 
770
static void
 
771
dispatch_reply (GVfsAfpConnection *afp_connection)
 
772
{
 
773
  GVfsAfpConnectionPrivate *priv = afp_connection->priv;
 
774
  DSIHeader *dsi_header = &priv->read_dsi_header;
 
775
  
 
776
  switch (dsi_header->command)
 
777
  {
 
778
    case DSI_CLOSE_SESSION:
 
779
    {
 
780
      g_warning ("Server closed session\n");
 
781
      break;
 
782
    }
 
783
 
 
784
    case DSI_TICKLE:
 
785
    {
 
786
      RequestData *req_data;
 
787
 
 
788
      /* Send back a tickle message */
 
789
      req_data = g_slice_new0 (RequestData);
 
790
      req_data->type = REQUEST_TYPE_TICKLE;
 
791
 
 
792
      g_queue_push_head (priv->request_queue, req_data);
 
793
      run_loop (afp_connection);
 
794
      break;
 
795
    }
 
796
 
 
797
    case DSI_ATTENTION:
 
798
    {
 
799
      guint8 attention_code;
 
800
 
 
801
      attention_code = priv->reply_buf[0] >> 4;
 
802
 
 
803
      g_signal_emit (afp_connection, signals[ATTENTION], 0, attention_code);
 
804
      break;
 
805
    }
 
806
 
 
807
    case DSI_COMMAND:
 
808
    case DSI_WRITE:
 
809
    {
 
810
      RequestData *req_data;
 
811
      
 
812
      req_data = g_hash_table_lookup (priv->request_hash,
 
813
                                      GUINT_TO_POINTER ((guint)dsi_header->requestID));
 
814
      if (req_data)
 
815
      {
 
816
        GVfsAfpReply *reply;
 
817
 
 
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;
 
821
 
 
822
        g_simple_async_result_set_op_res_gpointer (req_data->simple, reply,
 
823
                                                   g_object_unref);
 
824
        g_simple_async_result_complete (req_data->simple);
 
825
 
 
826
        g_hash_table_remove (priv->request_hash,
 
827
                             GUINT_TO_POINTER ((guint)dsi_header->requestID));
 
828
      }
 
829
      break;
 
830
    }
 
831
 
 
832
    default:
 
833
      g_assert_not_reached ();
 
834
  }
 
835
}
 
836
    
 
837
static void
 
838
read_data_cb (GObject *object, GAsyncResult *res, gpointer user_data)
 
839
{
 
840
  GInputStream *input = G_INPUT_STREAM (object);
 
841
  GVfsAfpConnection *afp_connection = G_VFS_AFP_CONNECTION (user_data);
 
842
  GVfsAfpConnectionPrivate *priv = afp_connection->priv;
 
843
 
 
844
  gboolean result;
 
845
  GError *err = NULL;
 
846
 
 
847
  result = read_all_finish (input, res, NULL, &err);
 
848
  if (!result)
 
849
  {
 
850
    g_warning ("FAIL!!! \"%s\"\n", err->message);
 
851
    g_error_free (err);
 
852
  }
 
853
 
 
854
  dispatch_reply (afp_connection);
 
855
 
 
856
  if (priv->free_reply_buf)
 
857
    g_free (priv->reply_buf);
 
858
  
 
859
  read_reply (afp_connection);
 
860
}
 
861
 
 
862
static void
 
863
read_dsi_header_cb (GObject *object, GAsyncResult *res, gpointer user_data)
 
864
{
 
865
  GInputStream *input = G_INPUT_STREAM (object);
 
866
  GVfsAfpConnection *afp_conn = G_VFS_AFP_CONNECTION (user_data);
 
867
  GVfsAfpConnectionPrivate *priv = afp_conn->priv;
 
868
  
 
869
  gboolean result;
 
870
  GError *err = NULL;
 
871
  DSIHeader *dsi_header;
 
872
  
 
873
  result = read_all_finish (input, res, NULL, &err);
 
874
  if (!result)
 
875
  {
 
876
    g_warning ("FAIL!!! \"%s\"\n", err->message);
 
877
    g_error_free (err);
 
878
  }
 
879
 
 
880
  dsi_header = &priv->read_dsi_header;
 
881
  
 
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);
 
885
  
 
886
  if (dsi_header->totalDataLength > 0)
 
887
  {
 
888
    RequestData *req_data;
 
889
 
 
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)
 
893
    {
 
894
        priv->reply_buf = req_data->reply_buf;
 
895
        priv->free_reply_buf = FALSE;
 
896
    }
 
897
    else
 
898
    {
 
899
      priv->reply_buf = g_malloc (dsi_header->totalDataLength);
 
900
      priv->free_reply_buf = TRUE;
 
901
    }
 
902
    
 
903
    read_all_async (input, priv->reply_buf, dsi_header->totalDataLength,
 
904
                    0, NULL, read_data_cb, afp_conn);
 
905
    
 
906
    return;
 
907
  }
 
908
 
 
909
  dispatch_reply (afp_conn);
 
910
  read_reply (afp_conn);
 
911
}
 
912
 
 
913
static void
 
914
read_reply (GVfsAfpConnection *afp_connection)
 
915
{
 
916
  GVfsAfpConnectionPrivate *priv = afp_connection->priv;
 
917
  
 
918
  GInputStream *input;
 
919
 
 
920
  input = g_io_stream_get_input_stream (priv->conn);
 
921
  
 
922
  read_all_async (input, &priv->read_dsi_header, sizeof (DSIHeader), 0, NULL,
 
923
                  read_dsi_header_cb, afp_connection);
 
924
}
 
925
 
 
926
typedef struct
 
927
{
 
928
  const void *buffer;
 
929
  gsize count;
 
930
  int io_priority;
 
931
  GCancellable *cancellable;
 
932
  gssize bytes_written;
 
933
} WriteAllData;
 
934
 
 
935
inline static void
 
936
free_write_all_data (WriteAllData *write_data)
 
937
{
 
938
  if (write_data->cancellable)
 
939
    g_object_unref (write_data->cancellable);
 
940
  
 
941
  g_slice_free (WriteAllData, write_data);
 
942
}
 
943
 
 
944
static void
 
945
write_all_cb (GObject      *source_object,
 
946
              GAsyncResult *res,
 
947
              gpointer      user_data)
 
948
{
 
949
  GOutputStream *stream = G_OUTPUT_STREAM (source_object);
 
950
  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
 
951
 
 
952
  gssize bytes_written;
 
953
  GError *err = NULL;
 
954
  WriteAllData *write_data;
 
955
 
 
956
  bytes_written = g_output_stream_write_finish (stream, res, &err);
 
957
  if (bytes_written == -1)
 
958
  {
 
959
    g_simple_async_result_take_error (simple, err);
 
960
    goto done;
 
961
  }
 
962
  
 
963
  write_data = g_simple_async_result_get_op_res_gpointer (simple);
 
964
 
 
965
  write_data->bytes_written += bytes_written;
 
966
  if (write_data->bytes_written < write_data->count)
 
967
  {
 
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);
 
973
    return;
 
974
  }
 
975
 
 
976
done:
 
977
  g_simple_async_result_complete (simple);
 
978
  g_object_unref (simple);
 
979
}
 
980
 
 
981
static void
 
982
write_all_async (GOutputStream      *stream,
 
983
                 const void         *buffer,
 
984
                 gsize               count,
 
985
                 int                 io_priority,
 
986
                 GCancellable       *cancellable,
 
987
                 GAsyncReadyCallback callback,
 
988
                 gpointer            user_data)
 
989
{
 
990
  GSimpleAsyncResult *simple;
 
991
  WriteAllData *write_data;
 
992
 
 
993
  write_data = g_slice_new0 (WriteAllData);
 
994
  write_data->buffer = buffer;
 
995
  write_data->count = count;
 
996
  write_data->io_priority = io_priority;
 
997
  if (cancellable)
 
998
    write_data->cancellable = g_object_ref (cancellable);
 
999
  
 
1000
  simple = g_simple_async_result_new (G_OBJECT (stream), callback, user_data,
 
1001
                                      write_all_async);
 
1002
  g_simple_async_result_set_op_res_gpointer (simple, write_data,
 
1003
                                             (GDestroyNotify)free_write_all_data);
 
1004
  
 
1005
  g_output_stream_write_async (stream, buffer, count, io_priority, cancellable,
 
1006
                               write_all_cb, simple);
 
1007
}
 
1008
 
 
1009
static gboolean
 
1010
write_all_finish (GOutputStream *stream,
 
1011
                  GAsyncResult  *res,
 
1012
                  gsize         *bytes_written,
 
1013
                  GError       **error)
 
1014
{
 
1015
  GSimpleAsyncResult *simple;
 
1016
  
 
1017
  g_return_val_if_fail (g_simple_async_result_is_valid (res, G_OBJECT (stream),
 
1018
                                                        write_all_async),
 
1019
                        FALSE);
 
1020
 
 
1021
  simple = (GSimpleAsyncResult *)res;
 
1022
  if (g_simple_async_result_propagate_error (simple, error))
 
1023
    return FALSE;
 
1024
  
 
1025
  
 
1026
  if (bytes_written)
 
1027
  {
 
1028
    WriteAllData *write_data;
 
1029
  
 
1030
    write_data = g_simple_async_result_get_op_res_gpointer (simple);
 
1031
    *bytes_written = write_data->bytes_written;
 
1032
  }
 
1033
 
 
1034
  return TRUE;
 
1035
}
 
1036
 
 
1037
static void
 
1038
remove_first (GQueue *request_queue)
 
1039
{
 
1040
  RequestData *req_data;
 
1041
 
 
1042
  req_data = g_queue_pop_head (request_queue);
 
1043
  free_request_data (req_data);
 
1044
}
 
1045
 
 
1046
#define HANDLE_RES() { \
 
1047
  gboolean result; \
 
1048
  GError *err = NULL; \
 
1049
\
 
1050
 result = write_all_finish (output, res, NULL, &err); \
 
1051
 if (!result) \
 
1052
  { \
 
1053
    if (req_data->simple) \
 
1054
    { \
 
1055
      g_simple_async_result_set_from_error (req_data->simple, err); \
 
1056
      g_simple_async_result_complete (req_data->simple); \
 
1057
    } \
 
1058
\
 
1059
    remove_first (priv->request_queue); \
 
1060
    g_error_free (err); \
 
1061
\
 
1062
    send_request (afp_conn); \
 
1063
    return; \
 
1064
  } \
 
1065
}
 
1066
    
 
1067
 
 
1068
static void
 
1069
write_buf_cb (GObject *object, GAsyncResult *res, gpointer user_data)
 
1070
{
 
1071
  GOutputStream *output = G_OUTPUT_STREAM (object);
 
1072
  GVfsAfpConnection *afp_conn = G_VFS_AFP_CONNECTION (user_data);
 
1073
  GVfsAfpConnectionPrivate *priv = afp_conn->priv;
 
1074
 
 
1075
  RequestData *req_data;
 
1076
 
 
1077
  req_data = g_queue_peek_head (priv->request_queue);
 
1078
  
 
1079
  HANDLE_RES ();
 
1080
 
 
1081
  g_hash_table_insert (priv->request_hash,
 
1082
                       GUINT_TO_POINTER ((guint)GUINT16_FROM_BE (priv->write_dsi_header.requestID)),
 
1083
                       req_data);
 
1084
  g_queue_pop_head (priv->request_queue);
 
1085
 
 
1086
  send_request (afp_conn);
 
1087
}
 
1088
 
 
1089
static void
 
1090
write_command_cb (GObject *object, GAsyncResult *res, gpointer user_data)
 
1091
{
 
1092
  GOutputStream *output = G_OUTPUT_STREAM (object);
 
1093
  GVfsAfpConnection *afp_conn = G_VFS_AFP_CONNECTION (user_data);
 
1094
  GVfsAfpConnectionPrivate *priv = afp_conn->priv;
 
1095
 
 
1096
  RequestData *req_data;
 
1097
 
 
1098
  req_data = g_queue_peek_head (priv->request_queue);
 
1099
  
 
1100
  HANDLE_RES ();
 
1101
 
 
1102
  if (priv->write_dsi_header.command == DSI_WRITE &&
 
1103
     req_data->command->buf)
 
1104
  {
 
1105
    write_all_async (output, req_data->command->buf, req_data->command->buf_size,
 
1106
                     0, NULL, write_buf_cb, afp_conn);
 
1107
    return;
 
1108
  }
 
1109
  
 
1110
  g_hash_table_insert (priv->request_hash,
 
1111
                       GUINT_TO_POINTER ((guint)GUINT16_FROM_BE (priv->write_dsi_header.requestID)),
 
1112
                       req_data);
 
1113
  g_queue_pop_head (priv->request_queue);
 
1114
 
 
1115
  send_request (afp_conn);
 
1116
}
 
1117
 
 
1118
static void
 
1119
write_dsi_header_cb (GObject *object, GAsyncResult *res, gpointer user_data)
 
1120
{
 
1121
  GOutputStream *output = G_OUTPUT_STREAM (object);
 
1122
  GVfsAfpConnection *afp_conn = G_VFS_AFP_CONNECTION (user_data);
 
1123
  GVfsAfpConnectionPrivate *priv = afp_conn->priv;
 
1124
  
 
1125
  RequestData *req_data;
 
1126
 
 
1127
  char *data;
 
1128
  gsize size;
 
1129
 
 
1130
  req_data = g_queue_peek_head (priv->request_queue);
 
1131
  
 
1132
  HANDLE_RES ();
 
1133
 
 
1134
  if (req_data->type == REQUEST_TYPE_TICKLE)
 
1135
  {
 
1136
    remove_first (priv->request_queue);
 
1137
    send_request (afp_conn);
 
1138
    return;
 
1139
  }
 
1140
 
 
1141
  data = g_vfs_afp_command_get_data (req_data->command);
 
1142
  size = g_vfs_afp_command_get_size (req_data->command);
 
1143
 
 
1144
  write_all_async (output, data, size, 0, NULL, write_command_cb, afp_conn);
 
1145
}
 
1146
 
 
1147
static void
 
1148
send_request (GVfsAfpConnection *afp_connection)
 
1149
{
 
1150
  GVfsAfpConnectionPrivate *priv = afp_connection->priv;
 
1151
 
 
1152
  RequestData *req_data;
 
1153
  guint32 writeOffset;
 
1154
  guint8 dsi_command;
 
1155
 
 
1156
  while ((req_data = g_queue_peek_head (priv->request_queue)))
 
1157
  {
 
1158
    if (req_data->cancellable && g_cancellable_is_cancelled (req_data->cancellable))
 
1159
    {
 
1160
      if (req_data->simple)
 
1161
      {
 
1162
        GError *err = NULL;
 
1163
 
 
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);
 
1167
      }
 
1168
      remove_first (priv->request_queue);
 
1169
    }
 
1170
    else
 
1171
      break;
 
1172
  }
 
1173
 
 
1174
  if (!req_data) {
 
1175
    priv->send_loop_running = FALSE;
 
1176
    return;
 
1177
  }
 
1178
 
 
1179
  switch (req_data->type)
 
1180
  {
 
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;
 
1188
      break;
 
1189
 
 
1190
    case REQUEST_TYPE_COMMAND:
 
1191
    {
 
1192
      gsize size;
 
1193
      
 
1194
      switch (req_data->command->type)
 
1195
      {
 
1196
        case AFP_COMMAND_WRITE:
 
1197
          writeOffset = 8;
 
1198
          dsi_command = DSI_WRITE;
 
1199
          break;
 
1200
        case AFP_COMMAND_WRITE_EXT:
 
1201
          writeOffset = 20;
 
1202
          dsi_command = DSI_WRITE;
 
1203
          break;
 
1204
 
 
1205
        default:
 
1206
          writeOffset = 0;
 
1207
          dsi_command = DSI_COMMAND;
 
1208
          break;
 
1209
      }
 
1210
 
 
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);
 
1215
 
 
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);
 
1221
      
 
1222
      priv->write_dsi_header.reserved = 0;
 
1223
      break;
 
1224
    }
 
1225
 
 
1226
    default:
 
1227
      g_assert_not_reached ();
 
1228
  }
 
1229
 
 
1230
 
 
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);
 
1234
}
 
1235
 
 
1236
void
 
1237
g_vfs_afp_connection_send_command (GVfsAfpConnection   *afp_connection,
 
1238
                                   GVfsAfpCommand      *command,
 
1239
                                   char                *reply_buf,
 
1240
                                   GAsyncReadyCallback  callback,
 
1241
                                   GCancellable        *cancellable,
 
1242
                                   gpointer             user_data)
 
1243
{
 
1244
  GVfsAfpConnectionPrivate *priv = afp_connection->priv;
 
1245
 
 
1246
  RequestData *req_data;
 
1247
  
 
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;
 
1252
 
 
1253
  req_data->simple = g_simple_async_result_new (G_OBJECT (afp_connection), callback,
 
1254
                                                user_data,
 
1255
                                                g_vfs_afp_connection_send_command);
 
1256
  if (cancellable)
 
1257
    req_data->cancellable = g_object_ref (cancellable);
 
1258
 
 
1259
  g_queue_push_tail (priv->request_queue, req_data);
 
1260
 
 
1261
  run_loop (afp_connection);
 
1262
}
 
1263
 
 
1264
GVfsAfpReply *
 
1265
g_vfs_afp_connection_send_command_finish (GVfsAfpConnection *afp_connection,
 
1266
                                          GAsyncResult *res,
 
1267
                                          GError **error)
 
1268
{
 
1269
  GSimpleAsyncResult *simple;
 
1270
  
 
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),
 
1274
                        NULL);
 
1275
 
 
1276
  simple = (GSimpleAsyncResult *)res;
 
1277
  
 
1278
  if (g_simple_async_result_propagate_error (simple, error))
 
1279
    return NULL;
 
1280
 
 
1281
  return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
 
1282
}
 
1283
 
 
1284
static gboolean
 
1285
read_reply_sync (GInputStream      *input,
 
1286
                 DSIHeader         *dsi_header,
 
1287
                 char              **data,
 
1288
                 GCancellable      *cancellable,
 
1289
                 GError            **error)
 
1290
{
 
1291
  gboolean res;
 
1292
  gsize read_count, bytes_read;
 
1293
 
 
1294
  g_assert (dsi_header != NULL);
 
1295
 
 
1296
  read_count = sizeof (DSIHeader);
 
1297
  res = g_input_stream_read_all (input, dsi_header, read_count, &bytes_read,
 
1298
                                 cancellable, error);
 
1299
  if (!res)
 
1300
    return FALSE;
 
1301
 
 
1302
  if (bytes_read < read_count)
 
1303
  {
 
1304
    g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
 
1305
                         _("Got EOS"));
 
1306
    return FALSE;
 
1307
  }
 
1308
 
 
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);
 
1312
 
 
1313
  if (dsi_header->totalDataLength == 0)
 
1314
  {
 
1315
    *data = NULL;
 
1316
    return TRUE;    
 
1317
  }
 
1318
  
 
1319
  *data = g_malloc (dsi_header->totalDataLength);
 
1320
  read_count = dsi_header->totalDataLength;
 
1321
 
 
1322
  res = g_input_stream_read_all (input, *data, read_count, &bytes_read, cancellable, error);
 
1323
  if (!res)
 
1324
  {
 
1325
    g_free (*data);
 
1326
    return FALSE;
 
1327
  }
 
1328
  if (bytes_read < read_count)
 
1329
  {
 
1330
    g_free (*data);
 
1331
    g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
 
1332
                         _("Got EOS"));
 
1333
    return FALSE;
 
1334
  }
 
1335
 
 
1336
  return TRUE;
 
1337
}
 
1338
 
 
1339
GVfsAfpReply *
 
1340
g_vfs_afp_connection_read_reply_sync (GVfsAfpConnection *afp_connection,
 
1341
                                      GCancellable *cancellable,
 
1342
                                      GError **error)
 
1343
{
 
1344
  GVfsAfpConnectionPrivate *priv = afp_connection->priv;
 
1345
  
 
1346
  gboolean res;
 
1347
  char *data;
 
1348
  DSIHeader dsi_header;
 
1349
 
 
1350
  res = read_reply_sync (g_io_stream_get_input_stream (priv->conn), &dsi_header,
 
1351
                         &data, cancellable, error);
 
1352
  if (!res)
 
1353
    return NULL;
 
1354
 
 
1355
  return g_vfs_afp_reply_new (dsi_header.errorCode, data, dsi_header.totalDataLength, TRUE);
 
1356
}
 
1357
 
 
1358
static gboolean
 
1359
send_request_sync (GOutputStream     *output,
 
1360
                   DsiCommand        command,
 
1361
                   guint16           request_id,
 
1362
                   guint32           writeOffset,
 
1363
                   gsize             len,
 
1364
                   const char        *data,
 
1365
                   GCancellable      *cancellable,
 
1366
                   GError            **error)
 
1367
{
 
1368
  DSIHeader dsi_header;
 
1369
  gboolean res;
 
1370
  gsize write_count, bytes_written;
 
1371
 
 
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;
 
1378
 
 
1379
  write_count = sizeof (DSIHeader);
 
1380
  res = g_output_stream_write_all (output, &dsi_header, write_count,
 
1381
                                   &bytes_written, cancellable, error);
 
1382
  if (!res)
 
1383
    return FALSE;
 
1384
 
 
1385
  if (data == NULL)
 
1386
    return TRUE;
 
1387
 
 
1388
  write_count = len;
 
1389
  res = g_output_stream_write_all (output, data, write_count, &bytes_written,
 
1390
                                   cancellable, error);
 
1391
  if (!res)
 
1392
    return FALSE;
 
1393
 
 
1394
  return TRUE;
 
1395
}
 
1396
 
 
1397
gboolean
 
1398
g_vfs_afp_connection_send_command_sync (GVfsAfpConnection *afp_connection,
 
1399
                                        GVfsAfpCommand    *afp_command,
 
1400
                                        GCancellable      *cancellable,
 
1401
                                        GError            **error)
 
1402
{
 
1403
  GVfsAfpConnectionPrivate *priv = afp_connection->priv;
 
1404
  
 
1405
  DsiCommand dsi_command;
 
1406
  guint16 req_id;
 
1407
  guint32 writeOffset;
 
1408
 
 
1409
  /* set dsi_command */
 
1410
  switch (afp_command->type)
 
1411
  {
 
1412
    case AFP_COMMAND_WRITE:
 
1413
      writeOffset = 8;
 
1414
      dsi_command = DSI_WRITE;
 
1415
      break;
 
1416
    case AFP_COMMAND_WRITE_EXT:
 
1417
      writeOffset = 20;
 
1418
      dsi_command = DSI_WRITE;
 
1419
      break;
 
1420
 
 
1421
    default:
 
1422
      writeOffset = 0;
 
1423
      dsi_command = DSI_COMMAND;
 
1424
      break;
 
1425
  }
 
1426
 
 
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);
 
1433
}
 
1434
 
 
1435
gboolean
 
1436
g_vfs_afp_connection_close (GVfsAfpConnection *afp_connection,
 
1437
                            GCancellable      *cancellable,
 
1438
                            GError            **error)
 
1439
{
 
1440
  GVfsAfpConnectionPrivate *priv = afp_connection->priv;
 
1441
  
 
1442
  guint16 req_id;
 
1443
  gboolean res;
 
1444
  
 
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);
 
1450
  if (!res)
 
1451
  {
 
1452
    g_io_stream_close (priv->conn, cancellable, NULL);
 
1453
    g_object_unref (priv->conn);
 
1454
    return FALSE;
 
1455
  }
 
1456
 
 
1457
  res = g_io_stream_close (priv->conn, cancellable, error);
 
1458
  g_object_unref (priv->conn);
 
1459
  
 
1460
  return res;
 
1461
}
 
1462
 
 
1463
gboolean
 
1464
g_vfs_afp_connection_open (GVfsAfpConnection *afp_connection,
 
1465
                           GCancellable      *cancellable,
 
1466
                           GError            **error)
 
1467
{
 
1468
  GVfsAfpConnectionPrivate *priv = afp_connection->priv;
 
1469
 
 
1470
  GSocketClient *client;
 
1471
 
 
1472
  guint16 req_id;
 
1473
  gboolean res;
 
1474
  char *reply;
 
1475
  DSIHeader dsi_header;
 
1476
  guint pos;
 
1477
 
 
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);
 
1481
 
 
1482
  if (!priv->conn)
 
1483
    return FALSE;
 
1484
 
 
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);
 
1489
  if (!res)
 
1490
    return FALSE;
 
1491
 
 
1492
  res = read_reply_sync (g_io_stream_get_input_stream (priv->conn),
 
1493
                         &dsi_header, &reply, cancellable, error);
 
1494
  if (!res)
 
1495
    return FALSE;
 
1496
 
 
1497
  pos = 0;
 
1498
  while ((dsi_header.totalDataLength - pos) > 2)
 
1499
  {
 
1500
    guint8 optionType;
 
1501
    guint8 optionLength;
 
1502
 
 
1503
    optionType = reply[pos++];
 
1504
    optionLength = reply[pos++];
 
1505
 
 
1506
    switch (optionType)
 
1507
    {
 
1508
      
 
1509
      case 0x00:
 
1510
        if (optionLength == 4 && (dsi_header.totalDataLength - pos) >= 4)
 
1511
          priv->kRequestQuanta = GUINT32_FROM_BE (*(guint32 *)(reply + pos));
 
1512
 
 
1513
        break;
 
1514
        
 
1515
      case 0x02:
 
1516
        if (optionLength == 4 && (dsi_header.totalDataLength - pos) >= 4)
 
1517
         priv->kServerReplayCacheSize = GUINT32_FROM_BE (*(guint32 *)(reply + pos));
 
1518
 
 
1519
        break;
 
1520
      
 
1521
 
 
1522
      default:
 
1523
        g_debug ("Unknown DSI option\n");
 
1524
    }
 
1525
 
 
1526
    pos += optionLength;
 
1527
  }
 
1528
  g_free (reply);
 
1529
 
 
1530
  return TRUE;
 
1531
}
 
1532
 
 
1533
GVfsAfpReply *
 
1534
g_vfs_afp_connection_get_server_info (GVfsAfpConnection *afp_connection,
 
1535
                                      GCancellable *cancellable,
 
1536
                                      GError **error)
 
1537
{
 
1538
  GVfsAfpConnectionPrivate *priv = afp_connection->priv;
 
1539
  
 
1540
  GSocketClient *client;
 
1541
  GIOStream *conn;
 
1542
  gboolean res;
 
1543
  DSIHeader dsi_header;
 
1544
  char *data;
 
1545
 
 
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);
 
1549
 
 
1550
  if (!conn)
 
1551
    return NULL;
 
1552
 
 
1553
  res = send_request_sync (g_io_stream_get_output_stream (conn), DSI_GET_STATUS,
 
1554
                           0, 0, 0, NULL, cancellable, error);
 
1555
  if (!res)
 
1556
  {
 
1557
    g_object_unref (conn);
 
1558
    return NULL;
 
1559
  }
 
1560
 
 
1561
  res = read_reply_sync (g_io_stream_get_input_stream (conn), &dsi_header,
 
1562
                         &data, cancellable, error);
 
1563
  if (!res)
 
1564
  {
 
1565
    g_object_unref (conn);
 
1566
    return NULL;
 
1567
  }
 
1568
 
 
1569
  g_object_unref (conn);
 
1570
  
 
1571
  return g_vfs_afp_reply_new (dsi_header.errorCode, data,
 
1572
                              dsi_header.totalDataLength, TRUE);
 
1573
}
 
1574
 
 
1575
GVfsAfpConnection *
 
1576
g_vfs_afp_connection_new (GSocketConnectable *addr)
 
1577
{
 
1578
  GVfsAfpConnection        *afp_connection;
 
1579
  GVfsAfpConnectionPrivate *priv;
 
1580
 
 
1581
  afp_connection = g_object_new (G_VFS_TYPE_AFP_CONNECTION, NULL);
 
1582
  priv = afp_connection->priv;
 
1583
 
 
1584
  priv->addr = g_object_ref (addr);
 
1585
 
 
1586
  return afp_connection;
 
1587
}
 
1588
 
 
1589
static void
 
1590
g_vfs_afp_connection_init (GVfsAfpConnection *afp_connection)
 
1591
{
 
1592
  GVfsAfpConnectionPrivate *priv;
 
1593
  
 
1594
  afp_connection->priv = priv =  G_TYPE_INSTANCE_GET_PRIVATE (afp_connection,
 
1595
                                                              G_VFS_TYPE_AFP_CONNECTION,
 
1596
                                                              GVfsAfpConnectionPrivate);
 
1597
 
 
1598
  priv->addr = NULL;
 
1599
  priv->conn = NULL;
 
1600
  priv->request_id = 0;
 
1601
 
 
1602
  priv->kRequestQuanta = -1;
 
1603
  priv->kServerReplayCacheSize = -1;
 
1604
 
 
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);
 
1608
 
 
1609
  priv->send_loop_running = FALSE;
 
1610
  priv->read_loop_running = FALSE;
 
1611
}
 
1612
 
 
1613
static void
 
1614
g_vfs_afp_connection_finalize (GObject *object)
 
1615
{
 
1616
  GVfsAfpConnection *afp_connection = (GVfsAfpConnection *)object;
 
1617
  GVfsAfpConnectionPrivate *priv = afp_connection->priv;
 
1618
 
 
1619
  if (priv->addr)
 
1620
    g_object_unref (priv->addr);
 
1621
  
 
1622
  if (priv->conn)
 
1623
    g_object_unref (priv->conn);
 
1624
 
 
1625
  G_OBJECT_CLASS (g_vfs_afp_connection_parent_class)->finalize (object);
 
1626
}
 
1627
 
 
1628
static void
 
1629
g_vfs_afp_connection_class_init (GVfsAfpConnectionClass *klass)
 
1630
{
 
1631
  GObjectClass* object_class = G_OBJECT_CLASS (klass);
 
1632
 
 
1633
  g_type_class_add_private (klass, sizeof (GVfsAfpConnectionPrivate));
 
1634
 
 
1635
  object_class->finalize = g_vfs_afp_connection_finalize;
 
1636
 
 
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);
 
1643
}
 
1644