~ubuntu-branches/debian/squeeze/meanwhile/squeeze

« back to all changes in this revision

Viewing changes to src/srvc_dir.c

  • Committer: Bazaar Package Importer
  • Author(s): Chris Vanden Berghe
  • Date: 2005-06-01 13:33:23 UTC
  • Revision ID: james.westby@ubuntu.com-20050601133323-fpkk8vr7asaj0tzo
Tags: upstream-0.4.2
ImportĀ upstreamĀ versionĀ 0.4.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*
 
3
  Meanwhile - Unofficial Lotus Sametime Community Client Library
 
4
  Copyright (C) 2004  Christopher (siege) O'Brien
 
5
  
 
6
  This library is free software; you can redistribute it and/or
 
7
  modify it under the terms of the GNU Library General Public
 
8
  License as published by the Free Software Foundation; either
 
9
  version 2 of the License, or (at your option) any later version.
 
10
  
 
11
  This library is distributed in the hope that it will be useful,
 
12
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
  Library General Public License for more details.
 
15
  
 
16
  You should have received a copy of the GNU Library General Public
 
17
  License along with this library; if not, write to the Free
 
18
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
19
*/
 
20
 
 
21
#include <glib/ghash.h>
 
22
 
 
23
#include "mw_channel.h"
 
24
#include "mw_common.h"
 
25
#include "mw_debug.h"
 
26
#include "mw_error.h"
 
27
#include "mw_message.h"
 
28
#include "mw_service.h"
 
29
#include "mw_session.h"
 
30
#include "mw_srvc_dir.h"
 
31
#include "mw_util.h"
 
32
 
 
33
 
 
34
#define PROTOCOL_TYPE  0x0000001c
 
35
#define PROTOCOL_VER   0x00000005
 
36
 
 
37
 
 
38
enum dir_action {
 
39
  action_list    = 0x0000,  /**< list address books */
 
40
  action_open    = 0x0001,  /**< open an addressbook as a directory */
 
41
  action_close   = 0x0002,  /**< close a directory */
 
42
  action_search  = 0x0003,  /**< search an open directory */
 
43
};
 
44
 
 
45
 
 
46
struct mwServiceDirectory {
 
47
  struct mwService service;
 
48
 
 
49
  struct mwDirectoryHandler *handler;
 
50
 
 
51
  struct mwChannel *channel;
 
52
 
 
53
  guint32 counter;       /**< counter of request IDs */
 
54
  GHashTable *requests;  /**< map of request ID:directory */
 
55
  GHashTable *books;     /**< book->name:mwAddressBook */
 
56
};
 
57
 
 
58
 
 
59
struct mwAddressBook {
 
60
  struct mwServiceDirectory *service;
 
61
 
 
62
  guint32 id;        /**< id or type or something */
 
63
  char *name;        /**< name of address book */
 
64
  GHashTable *dirs;  /**< dir->id:mwDirectory */
 
65
};
 
66
 
 
67
 
 
68
struct mwDirectory {
 
69
  struct mwServiceDirectory *service;
 
70
  struct mwAddressBook *book;
 
71
 
 
72
  enum mwDirectoryState state;
 
73
 
 
74
  guint32 id;         /**< id of directory, assigned by server */
 
75
  guint32 search_id;  /**< id of current search, from srvc->counter++ */
 
76
 
 
77
  mwSearchHandler handler;
 
78
  struct mw_datum client_data;
 
79
};
 
80
 
 
81
 
 
82
#define next_request_id(srvc) ( ++((srvc)->counter) )
 
83
 
 
84
 
 
85
static guint32 map_request(struct mwDirectory *dir) {
 
86
  struct mwServiceDirectory *srvc = dir->service;
 
87
  guint32 id = next_request_id(srvc);
 
88
 
 
89
  dir->search_id = id;
 
90
  map_guint_insert(srvc->requests, id, dir);
 
91
 
 
92
  return id;
 
93
}
 
94
 
 
95
 
 
96
/** called when directory is removed from the service directory map */
 
97
static void dir_free(struct mwDirectory *dir) {
 
98
  map_guint_remove(dir->service->requests, dir->search_id);
 
99
  g_free(dir);
 
100
}
 
101
 
 
102
 
 
103
/** remove the directory from the service list and its owning address
 
104
    book, then frees the directory */
 
105
static void dir_remove(struct mwDirectory *dir) {
 
106
  struct mwAddressBook *book = dir->book;
 
107
  map_guint_remove(book->dirs, dir->id);
 
108
}
 
109
 
 
110
 
 
111
__attribute__((used))
 
112
static struct mwDirectory *dir_new(struct mwAddressBook *book, guint32 id) {
 
113
  struct mwDirectory *dir = g_new0(struct mwDirectory, 1);
 
114
  dir->service = book->service;
 
115
  dir->book = book;
 
116
  dir->id = id;
 
117
  map_guint_insert(book->dirs, id, dir);
 
118
  return dir;
 
119
}
 
120
 
 
121
 
 
122
/** called when book is removed from the service book map. Removed all
 
123
    directories as well */
 
124
static void book_free(struct mwAddressBook *book) {
 
125
  g_hash_table_destroy(book->dirs);
 
126
  g_free(book->name);
 
127
}
 
128
 
 
129
 
 
130
__attribute__((used))
 
131
static void book_remove(struct mwAddressBook *book) {
 
132
  struct mwServiceDirectory *srvc = book->service;
 
133
  g_hash_table_remove(srvc->books, book->name);
 
134
}
 
135
 
 
136
 
 
137
static struct mwAddressBook *book_new(struct mwServiceDirectory *srvc,
 
138
                                      const char *name, guint32 id) {
 
139
  struct mwAddressBook *book = g_new0(struct mwAddressBook, 1);
 
140
  book->service = srvc;
 
141
  book->id = id;
 
142
  book->name = g_strdup(name);
 
143
  book->dirs = map_guint_new_full((GDestroyNotify) dir_free);
 
144
  g_hash_table_insert(srvc->books, book->name, book);
 
145
  return book;
 
146
}
 
147
 
 
148
 
 
149
static const char *getName(struct mwService *srvc) {
 
150
  return "Address Book and Directory";
 
151
}
 
152
 
 
153
 
 
154
static const char *getDesc(struct mwService *srvc) {
 
155
  return "Address book directory service for user and group lookups";
 
156
}
 
157
 
 
158
 
 
159
static struct mwChannel *make_channel(struct mwServiceDirectory *srvc) {
 
160
  struct mwSession *session;
 
161
  struct mwChannelSet *cs;
 
162
  struct mwChannel *chan;
 
163
 
 
164
  session = mwService_getSession(MW_SERVICE(srvc));
 
165
  cs = mwSession_getChannels(session);
 
166
  chan = mwChannel_newOutgoing(cs);
 
167
 
 
168
  mwChannel_setService(chan, MW_SERVICE(srvc));
 
169
  mwChannel_setProtoType(chan, PROTOCOL_TYPE);
 
170
  mwChannel_setProtoVer(chan, PROTOCOL_VER);
 
171
 
 
172
  return mwChannel_create(chan)? NULL: chan;
 
173
}
 
174
 
 
175
 
 
176
static void start(struct mwServiceDirectory *srvc) {
 
177
  struct mwChannel *chan;
 
178
 
 
179
  chan = make_channel(srvc);
 
180
  if(chan) {
 
181
    srvc->channel = chan;
 
182
  } else {
 
183
    mwService_stopped(MW_SERVICE(srvc));
 
184
    return;
 
185
  }
 
186
}
 
187
 
 
188
 
 
189
static void stop(struct mwServiceDirectory *srvc) {
 
190
  /* XXX */
 
191
 
 
192
  if(srvc->channel) {
 
193
    mwChannel_destroy(srvc->channel, ERR_SUCCESS, NULL);
 
194
    srvc->channel = NULL;
 
195
  }
 
196
}
 
197
 
 
198
 
 
199
static void clear(struct mwServiceDirectory *srvc) {
 
200
  struct mwDirectoryHandler *handler;
 
201
 
 
202
  if(srvc->books) {
 
203
    g_hash_table_destroy(srvc->books);
 
204
    srvc->books = NULL;
 
205
  }
 
206
  
 
207
  /* clear the handler */
 
208
  handler = srvc->handler;
 
209
  if(handler && handler->clear)
 
210
    handler->clear(srvc);
 
211
  srvc->handler = NULL;
 
212
}
 
213
 
 
214
 
 
215
static void recv_create(struct mwServiceDirectory *srvc,
 
216
                        struct mwChannel *chan,
 
217
                        struct mwMsgChannelCreate *msg) {
 
218
 
 
219
  /* no way man, we call the shots around here */
 
220
  mwChannel_destroy(chan, ERR_FAILURE, NULL);
 
221
}
 
222
 
 
223
 
 
224
static void recv_accept(struct mwServiceDirectory *srvc,
 
225
                        struct mwChannel *chan,
 
226
                        struct mwMsgChannelAccept *msg) {
 
227
 
 
228
  g_return_if_fail(srvc->channel != NULL);
 
229
  g_return_if_fail(srvc->channel == chan);
 
230
 
 
231
  if(MW_SERVICE_IS_STARTING(srvc)) {
 
232
    mwService_started(MW_SERVICE(srvc));
 
233
      
 
234
  } else {
 
235
    mwChannel_destroy(chan, ERR_FAILURE, NULL);
 
236
  }
 
237
}
 
238
 
 
239
 
 
240
static void recv_destroy(struct mwServiceDirectory *srvc,
 
241
                         struct mwChannel *chan,
 
242
                         struct mwMsgChannelDestroy *msg) {
 
243
 
 
244
  srvc->channel = NULL;
 
245
  mwService_stop(MW_SERVICE(srvc));
 
246
  /** @todo session sense service */
 
247
}
 
248
 
 
249
 
 
250
static void recv_list(struct mwServiceDirectory *srvc,
 
251
                      struct mwOpaque *data) {
 
252
 
 
253
  struct mwGetBuffer *b;
 
254
  guint32 request, code, count;
 
255
  gboolean foo_1;
 
256
  guint16 foo_2;
 
257
  
 
258
  b = mwGetBuffer_wrap(data);
 
259
  
 
260
  guint32_get(b, &request);
 
261
  guint32_get(b, &code);
 
262
  guint32_get(b, &count);
 
263
 
 
264
  gboolean_get(b, &foo_1);
 
265
  guint16_get(b, &foo_2);
 
266
 
 
267
  if(foo_1 || foo_2) {
 
268
    mw_debug_mailme(data, "received strange address book list");
 
269
    mwGetBuffer_free(b);
 
270
    return;
 
271
  }
 
272
 
 
273
  while(!mwGetBuffer_error(b) && count--) {
 
274
    guint32 id;
 
275
    char *name = NULL;
 
276
 
 
277
    guint32_get(b, &id);
 
278
    mwString_get(b, &name);
 
279
 
 
280
    book_new(srvc, name, id);
 
281
    g_free(name);
 
282
  }
 
283
}
 
284
 
 
285
 
 
286
static void recv_open(struct mwServiceDirectory *srvc,
 
287
                      struct mwOpaque *data) {
 
288
 
 
289
  /* look up the directory associated with this request id, 
 
290
     mark it as open, and trigger the event */
 
291
}
 
292
 
 
293
 
 
294
static void recv_search(struct mwServiceDirectory *srvc,
 
295
                        struct mwOpaque *data) {
 
296
 
 
297
  /* look up the directory associated with this request id,
 
298
     trigger the event */
 
299
}
 
300
 
 
301
 
 
302
static void recv(struct mwServiceDirectory *srvc,
 
303
                 struct mwChannel *chan,
 
304
                 guint16 msg_type, struct mwOpaque *data) {
 
305
  
 
306
  g_return_if_fail(srvc != NULL);
 
307
  g_return_if_fail(chan != NULL);
 
308
  g_return_if_fail(chan == srvc->channel);
 
309
  g_return_if_fail(data != NULL);
 
310
 
 
311
  switch(msg_type) {
 
312
  case action_list:
 
313
    recv_list(srvc, data);
 
314
    break;
 
315
 
 
316
  case action_open:
 
317
    recv_open(srvc, data);
 
318
    break;
 
319
 
 
320
  case action_close:
 
321
    ; /* I don't think we should receive these */
 
322
    break;
 
323
 
 
324
  case action_search:
 
325
    recv_search(srvc, data);
 
326
    break;
 
327
 
 
328
  default:
 
329
    mw_debug_mailme(data, "msg type 0x%04x in directory service", msg_type);
 
330
  }
 
331
}
 
332
 
 
333
 
 
334
struct mwServiceDirectory *
 
335
mwServiceDirectory_new(struct mwSession *session,
 
336
                       struct mwDirectoryHandler *handler) {
 
337
 
 
338
  struct mwServiceDirectory *srvc;
 
339
  struct mwService *service;
 
340
 
 
341
  g_return_val_if_fail(session != NULL, NULL);
 
342
  g_return_val_if_fail(handler != NULL, NULL);
 
343
 
 
344
  srvc = g_new0(struct mwServiceDirectory, 1);
 
345
  service = MW_SERVICE(srvc);
 
346
 
 
347
  mwService_init(service, session, SERVICE_DIRECTORY);
 
348
  service->get_name = getName;
 
349
  service->get_desc = getDesc;
 
350
  service->start = (mwService_funcStart) start;
 
351
  service->stop = (mwService_funcStop) stop;
 
352
  service->clear = (mwService_funcClear) clear;
 
353
  service->recv_create = (mwService_funcRecvCreate) recv_create;
 
354
  service->recv_accept = (mwService_funcRecvAccept) recv_accept;
 
355
  service->recv_destroy = (mwService_funcRecvDestroy) recv_destroy;
 
356
  service->recv = (mwService_funcRecv) recv;
 
357
 
 
358
  srvc->handler = handler;
 
359
  srvc->requests = map_guint_new();
 
360
  srvc->books = g_hash_table_new_full(g_str_hash, g_str_equal,
 
361
                                      NULL, (GDestroyNotify) book_free);
 
362
  return srvc;
 
363
}
 
364
 
 
365
 
 
366
struct mwDirectoryHandler *
 
367
mwServiceDirectory_getHandler(struct mwServiceDirectory *srvc) {
 
368
  g_return_val_if_fail(srvc != NULL, NULL);
 
369
  return srvc->handler;
 
370
}
 
371
 
 
372
 
 
373
int mwServiceDirectory_refreshAddressBooks(struct mwServiceDirectory *srvc) {
 
374
  struct mwChannel *chan;
 
375
  struct mwPutBuffer *b;
 
376
  struct mwOpaque o;
 
377
  int ret;
 
378
 
 
379
  g_return_val_if_fail(srvc != NULL, -1);
 
380
 
 
381
  chan = srvc->channel;
 
382
  g_return_val_if_fail(chan != NULL, -1);
 
383
 
 
384
  b = mwPutBuffer_new();
 
385
  guint32_put(b, next_request_id(srvc));
 
386
 
 
387
  mwPutBuffer_finalize(&o, b);
 
388
  ret = mwChannel_send(chan, action_list, &o);
 
389
  mwOpaque_clear(&o);
 
390
 
 
391
  return ret;
 
392
}
 
393
 
 
394
 
 
395
GList *mwServiceDirectory_getAddressBooks(struct mwServiceDirectory *srvc) {
 
396
  g_return_val_if_fail(srvc != NULL, NULL);
 
397
  g_return_val_if_fail(srvc->books != NULL, NULL);
 
398
 
 
399
  return map_collect_values(srvc->books);
 
400
}
 
401
 
 
402
 
 
403
GList *mwServiceDirectory_getDirectories(struct mwServiceDirectory *srvc) {
 
404
  GList *bl, *ret = NULL;
 
405
  
 
406
  g_return_val_if_fail(srvc != NULL, NULL);
 
407
  g_return_val_if_fail(srvc->books != NULL, NULL);
 
408
 
 
409
  bl = map_collect_values(srvc->books);
 
410
  for( ; bl; bl = g_list_delete_link(bl, bl)) {
 
411
    struct mwAddressBook *book = bl->data;
 
412
    ret = g_list_concat(ret, map_collect_values(book->dirs));
 
413
  }
 
414
 
 
415
  return ret;
 
416
}
 
417
 
 
418
 
 
419
GList *mwAddressBook_getDirectories(struct mwAddressBook *book) {
 
420
  g_return_val_if_fail(book != NULL, NULL);
 
421
  g_return_val_if_fail(book->dirs != NULL, NULL);
 
422
 
 
423
  return map_collect_values(book->dirs);
 
424
}
 
425
 
 
426
 
 
427
const char *mwAddressBook_getName(struct mwAddressBook *book) {
 
428
  g_return_val_if_fail(book != NULL, NULL);
 
429
  return book->name;
 
430
}
 
431
 
 
432
 
 
433
struct mwDirectory *mwDirectory_new(struct mwAddressBook *book) {
 
434
  struct mwDirectory *dir;
 
435
 
 
436
  g_return_val_if_fail(book != NULL, NULL);
 
437
  g_return_val_if_fail(book->service != NULL, NULL);
 
438
 
 
439
  dir = g_new0(struct mwDirectory, 1);
 
440
  dir->service = book->service;
 
441
  dir->book = book;
 
442
  dir->state = mwDirectory_NEW;
 
443
 
 
444
  return dir;
 
445
}
 
446
 
 
447
 
 
448
enum mwDirectoryState mwDirectory_getState(struct mwDirectory *dir) {
 
449
  g_return_val_if_fail(dir != NULL, mwDirectory_UNKNOWN);
 
450
  return dir->state;
 
451
}
 
452
 
 
453
 
 
454
void mwDirectory_setClientData(struct mwDirectory *dir,
 
455
                               gpointer data, GDestroyNotify clear) {
 
456
 
 
457
  g_return_if_fail(dir != NULL);
 
458
  mw_datum_set(&dir->client_data, data, clear);
 
459
}
 
460
 
 
461
 
 
462
gpointer mwDirectory_getClientData(struct mwDirectory *dir) {
 
463
  g_return_val_if_fail(dir != NULL, NULL);
 
464
  return mw_datum_get(&dir->client_data);
 
465
}
 
466
 
 
467
 
 
468
void mwDirectory_removeClientData(struct mwDirectory *dir) {
 
469
  g_return_if_fail(dir != NULL);
 
470
  mw_datum_clear(&dir->client_data);
 
471
}
 
472
 
 
473
 
 
474
struct mwServiceDirectory *mwDirectory_getService(struct mwDirectory *dir) {
 
475
  g_return_val_if_fail(dir != NULL, NULL);
 
476
  g_return_val_if_fail(dir->book != NULL, NULL);
 
477
  return dir->book->service;
 
478
}
 
479
 
 
480
 
 
481
struct mwAddressBook *mwDirectory_getAddressBook(struct mwDirectory *dir) {
 
482
  g_return_val_if_fail(dir != NULL, NULL);
 
483
  return dir->book;
 
484
}
 
485
 
 
486
 
 
487
static int dir_open(struct mwDirectory *dir) {
 
488
  struct mwServiceDirectory *srvc;
 
489
  struct mwChannel *chan;
 
490
  struct mwPutBuffer *b;
 
491
  struct mwOpaque o;
 
492
  int ret;
 
493
 
 
494
  g_return_val_if_fail(dir != NULL, -1);
 
495
 
 
496
  srvc = dir->service;
 
497
  g_return_val_if_fail(srvc != NULL, -1);
 
498
 
 
499
  chan = srvc->channel;
 
500
  g_return_val_if_fail(chan != NULL, -1);
 
501
 
 
502
  b = mwPutBuffer_new();
 
503
  guint32_put(b, map_request(dir));
 
504
 
 
505
  /* unsure about these three bytes */
 
506
  gboolean_put(b, FALSE);
 
507
  guint16_put(b, 0x0000);
 
508
 
 
509
  guint32_put(b, dir->book->id);
 
510
  mwString_put(b, dir->book->name);
 
511
 
 
512
  mwPutBuffer_finalize(&o, b);
 
513
  ret = mwChannel_send(chan, action_open, &o);
 
514
  mwOpaque_clear(&o);
 
515
 
 
516
  return ret;
 
517
}
 
518
 
 
519
 
 
520
int mwDirectory_open(struct mwDirectory *dir, mwSearchHandler cb) {
 
521
  g_return_val_if_fail(dir != NULL, -1);
 
522
  g_return_val_if_fail(cb != NULL, -1);
 
523
  g_return_val_if_fail(MW_DIRECTORY_IS_NEW(dir), -1);
 
524
 
 
525
  dir->state = mwDirectory_PENDING;
 
526
  dir->handler = cb;
 
527
 
 
528
  return dir_open(dir);
 
529
}
 
530
 
 
531
 
 
532
int mwDirectory_next(struct mwDirectory *dir) {  
 
533
  struct mwServiceDirectory *srvc;
 
534
  struct mwChannel *chan;
 
535
  struct mwPutBuffer *b;
 
536
  struct mwOpaque o;
 
537
  int ret;
 
538
 
 
539
  g_return_val_if_fail(dir != NULL, -1);
 
540
  g_return_val_if_fail(MW_DIRECTORY_IS_OPEN(dir), -1);
 
541
 
 
542
  srvc = dir->service;
 
543
  g_return_val_if_fail(srvc != NULL, -1);
 
544
 
 
545
  chan = srvc->channel;
 
546
  g_return_val_if_fail(chan != NULL, -1);
 
547
 
 
548
  b = mwPutBuffer_new();
 
549
  guint32_put(b, map_request(dir));
 
550
  guint32_put(b, dir->id);
 
551
  guint16_put(b, 0xffff);      /* some magic? */
 
552
  guint32_put(b, 0x00000000);  /* next results */
 
553
 
 
554
  mwPutBuffer_finalize(&o, b);
 
555
  ret = mwChannel_send(chan, action_search, &o);
 
556
  mwOpaque_clear(&o);
 
557
 
 
558
  return ret;
 
559
}
 
560
 
 
561
 
 
562
int mwDirectory_previous(struct mwDirectory *dir) {
 
563
  struct mwServiceDirectory *srvc;
 
564
  struct mwChannel *chan;
 
565
  struct mwPutBuffer *b;
 
566
  struct mwOpaque o;
 
567
  int ret;
 
568
 
 
569
  g_return_val_if_fail(dir != NULL, -1);
 
570
  g_return_val_if_fail(MW_DIRECTORY_IS_OPEN(dir), -1);
 
571
 
 
572
  srvc = dir->service;
 
573
  g_return_val_if_fail(srvc != NULL, -1);
 
574
 
 
575
  chan = srvc->channel;
 
576
  g_return_val_if_fail(chan != NULL, -1);
 
577
 
 
578
  b = mwPutBuffer_new();
 
579
  guint32_put(b, map_request(dir));
 
580
  guint32_put(b, dir->id);
 
581
  guint16_put(b, 0x0061);      /* some magic? */
 
582
  guint32_put(b, 0x00000001);  /* prev results */
 
583
 
 
584
  mwPutBuffer_finalize(&o, b);
 
585
  ret = mwChannel_send(chan, action_search, &o);
 
586
  mwOpaque_clear(&o);
 
587
 
 
588
  return ret;
 
589
}
 
590
 
 
591
 
 
592
int mwDirectory_search(struct mwDirectory *dir, const char *query) {
 
593
  struct mwServiceDirectory *srvc;
 
594
  struct mwChannel *chan;
 
595
  struct mwPutBuffer *b;
 
596
  struct mwOpaque o;
 
597
  int ret;
 
598
 
 
599
  g_return_val_if_fail(dir != NULL, -1);
 
600
  g_return_val_if_fail(MW_DIRECTORY_IS_OPEN(dir), -1);
 
601
  g_return_val_if_fail(query != NULL, -1);
 
602
  g_return_val_if_fail(*query != '\0', -1);
 
603
 
 
604
  srvc = dir->service;
 
605
  g_return_val_if_fail(srvc != NULL, -1);
 
606
 
 
607
  chan = srvc->channel;
 
608
  g_return_val_if_fail(chan != NULL, -1);
 
609
 
 
610
  b = mwPutBuffer_new();
 
611
  guint32_put(b, map_request(dir));
 
612
  guint32_put(b, dir->id);
 
613
  guint16_put(b, 0x0061);      /* some magic? */
 
614
  guint32_put(b, 0x00000008);  /* seek results */
 
615
  mwString_put(b, query);
 
616
 
 
617
  mwPutBuffer_finalize(&o, b);
 
618
  ret = mwChannel_send(chan, action_search, &o);
 
619
  mwOpaque_clear(&o);
 
620
 
 
621
  return ret;
 
622
}
 
623
 
 
624
 
 
625
static int dir_close(struct mwDirectory *dir) {
 
626
  struct mwServiceDirectory *srvc;
 
627
  struct mwChannel *chan;
 
628
  struct mwPutBuffer *b;
 
629
  struct mwOpaque o;
 
630
  int ret;
 
631
 
 
632
  g_return_val_if_fail(dir != NULL, -1);
 
633
 
 
634
  srvc = dir->service;
 
635
  g_return_val_if_fail(srvc != NULL, -1);
 
636
 
 
637
  chan = srvc->channel;
 
638
  g_return_val_if_fail(chan != NULL, -1);
 
639
 
 
640
  b = mwPutBuffer_new();
 
641
  guint32_put(b, next_request_id(dir->service));
 
642
  guint32_put(b, dir->id);
 
643
 
 
644
  mwPutBuffer_finalize(&o, b);
 
645
  ret = mwChannel_send(chan, action_close, &o);
 
646
  mwOpaque_clear(&o);
 
647
 
 
648
  return ret;
 
649
}
 
650
 
 
651
 
 
652
int mwDirectory_destroy(struct mwDirectory *dir) {
 
653
  int ret = 0;
 
654
 
 
655
  g_return_val_if_fail(dir != NULL, -1);
 
656
 
 
657
  if(MW_DIRECTORY_IS_OPEN(dir) || MW_DIRECTORY_IS_PENDING(dir)) {
 
658
    ret = dir_close(dir);
 
659
  }
 
660
  dir_remove(dir);
 
661
 
 
662
  return ret;
 
663
}
 
664