Blame src/srvc_dir.c.fix-glib-headers

Packit ee6627
Packit ee6627
/*
Packit ee6627
  Meanwhile - Unofficial Lotus Sametime Community Client Library
Packit ee6627
  Copyright (C) 2004  Christopher (siege) O'Brien
Packit ee6627
  
Packit ee6627
  This library is free software; you can redistribute it and/or
Packit ee6627
  modify it under the terms of the GNU Library General Public
Packit ee6627
  License as published by the Free Software Foundation; either
Packit ee6627
  version 2 of the License, or (at your option) any later version.
Packit ee6627
  
Packit ee6627
  This library is distributed in the hope that it will be useful,
Packit ee6627
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit ee6627
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit ee6627
  Library General Public License for more details.
Packit ee6627
  
Packit ee6627
  You should have received a copy of the GNU Library General Public
Packit ee6627
  License along with this library; if not, write to the Free
Packit ee6627
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Packit ee6627
*/
Packit ee6627
Packit ee6627
#include <glib/ghash.h>
Packit ee6627
Packit ee6627
#include "mw_channel.h"
Packit ee6627
#include "mw_common.h"
Packit ee6627
#include "mw_debug.h"
Packit ee6627
#include "mw_error.h"
Packit ee6627
#include "mw_message.h"
Packit ee6627
#include "mw_service.h"
Packit ee6627
#include "mw_session.h"
Packit ee6627
#include "mw_srvc_dir.h"
Packit ee6627
#include "mw_util.h"
Packit ee6627
Packit ee6627
Packit ee6627
#define PROTOCOL_TYPE  0x0000001c
Packit ee6627
#define PROTOCOL_VER   0x00000005
Packit ee6627
Packit ee6627
Packit ee6627
enum dir_action {
Packit ee6627
  action_list    = 0x0000,  /**< list address books */
Packit ee6627
  action_open    = 0x0001,  /**< open an addressbook as a directory */
Packit ee6627
  action_close   = 0x0002,  /**< close a directory */
Packit ee6627
  action_search  = 0x0003,  /**< search an open directory */
Packit ee6627
};
Packit ee6627
Packit ee6627
Packit ee6627
struct mwServiceDirectory {
Packit ee6627
  struct mwService service;
Packit ee6627
Packit ee6627
  struct mwDirectoryHandler *handler;
Packit ee6627
Packit ee6627
  struct mwChannel *channel;
Packit ee6627
 
Packit ee6627
  guint32 counter;       /**< counter of request IDs */
Packit ee6627
  GHashTable *requests;  /**< map of request ID:directory */
Packit ee6627
  GHashTable *books;     /**< book->name:mwAddressBook */
Packit ee6627
};
Packit ee6627
Packit ee6627
Packit ee6627
struct mwAddressBook {
Packit ee6627
  struct mwServiceDirectory *service;
Packit ee6627
Packit ee6627
  guint32 id;        /**< id or type or something */
Packit ee6627
  char *name;        /**< name of address book */
Packit ee6627
  GHashTable *dirs;  /**< dir->id:mwDirectory */
Packit ee6627
};
Packit ee6627
Packit ee6627
Packit ee6627
struct mwDirectory {
Packit ee6627
  struct mwServiceDirectory *service;
Packit ee6627
  struct mwAddressBook *book;
Packit ee6627
Packit ee6627
  enum mwDirectoryState state;
Packit ee6627
Packit ee6627
  guint32 id;         /**< id of directory, assigned by server */
Packit ee6627
  guint32 search_id;  /**< id of current search, from srvc->counter++ */
Packit ee6627
Packit ee6627
  mwSearchHandler handler;
Packit ee6627
  struct mw_datum client_data;
Packit ee6627
};
Packit ee6627
Packit ee6627
Packit ee6627
#define next_request_id(srvc) ( ++((srvc)->counter) )
Packit ee6627
Packit ee6627
Packit ee6627
static guint32 map_request(struct mwDirectory *dir) {
Packit ee6627
  struct mwServiceDirectory *srvc = dir->service;
Packit ee6627
  guint32 id = next_request_id(srvc);
Packit ee6627
Packit ee6627
  dir->search_id = id;
Packit ee6627
  map_guint_insert(srvc->requests, id, dir);
Packit ee6627
Packit ee6627
  return id;
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
/** called when directory is removed from the service directory map */
Packit ee6627
static void dir_free(struct mwDirectory *dir) {
Packit ee6627
  map_guint_remove(dir->service->requests, dir->search_id);
Packit ee6627
  g_free(dir);
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
/** remove the directory from the service list and its owning address
Packit ee6627
    book, then frees the directory */
Packit ee6627
static void dir_remove(struct mwDirectory *dir) {
Packit ee6627
  struct mwAddressBook *book = dir->book;
Packit ee6627
  map_guint_remove(book->dirs, dir->id);
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
__attribute__((used))
Packit ee6627
static struct mwDirectory *dir_new(struct mwAddressBook *book, guint32 id) {
Packit ee6627
  struct mwDirectory *dir = g_new0(struct mwDirectory, 1);
Packit ee6627
  dir->service = book->service;
Packit ee6627
  dir->book = book;
Packit ee6627
  dir->id = id;
Packit ee6627
  map_guint_insert(book->dirs, id, dir);
Packit ee6627
  return dir;
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
/** called when book is removed from the service book map. Removed all
Packit ee6627
    directories as well */
Packit ee6627
static void book_free(struct mwAddressBook *book) {
Packit ee6627
  g_hash_table_destroy(book->dirs);
Packit ee6627
  g_free(book->name);
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
__attribute__((used))
Packit ee6627
static void book_remove(struct mwAddressBook *book) {
Packit ee6627
  struct mwServiceDirectory *srvc = book->service;
Packit ee6627
  g_hash_table_remove(srvc->books, book->name);
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
static struct mwAddressBook *book_new(struct mwServiceDirectory *srvc,
Packit ee6627
				      const char *name, guint32 id) {
Packit ee6627
  struct mwAddressBook *book = g_new0(struct mwAddressBook, 1);
Packit ee6627
  book->service = srvc;
Packit ee6627
  book->id = id;
Packit ee6627
  book->name = g_strdup(name);
Packit ee6627
  book->dirs = map_guint_new_full((GDestroyNotify) dir_free);
Packit ee6627
  g_hash_table_insert(srvc->books, book->name, book);
Packit ee6627
  return book;
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
static const char *getName(struct mwService *srvc) {
Packit ee6627
  return "Address Book and Directory";
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
static const char *getDesc(struct mwService *srvc) {
Packit ee6627
  return "Address book directory service for user and group lookups";
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
static struct mwChannel *make_channel(struct mwServiceDirectory *srvc) {
Packit ee6627
  struct mwSession *session;
Packit ee6627
  struct mwChannelSet *cs;
Packit ee6627
  struct mwChannel *chan;
Packit ee6627
Packit ee6627
  session = mwService_getSession(MW_SERVICE(srvc));
Packit ee6627
  cs = mwSession_getChannels(session);
Packit ee6627
  chan = mwChannel_newOutgoing(cs);
Packit ee6627
Packit ee6627
  mwChannel_setService(chan, MW_SERVICE(srvc));
Packit ee6627
  mwChannel_setProtoType(chan, PROTOCOL_TYPE);
Packit ee6627
  mwChannel_setProtoVer(chan, PROTOCOL_VER);
Packit ee6627
Packit ee6627
  return mwChannel_create(chan)? NULL: chan;
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
static void start(struct mwServiceDirectory *srvc) {
Packit ee6627
  struct mwChannel *chan;
Packit ee6627
Packit ee6627
  chan = make_channel(srvc);
Packit ee6627
  if(chan) {
Packit ee6627
    srvc->channel = chan;
Packit ee6627
  } else {
Packit ee6627
    mwService_stopped(MW_SERVICE(srvc));
Packit ee6627
    return;
Packit ee6627
  }
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
static void stop(struct mwServiceDirectory *srvc) {
Packit ee6627
  /* XXX */
Packit ee6627
Packit ee6627
  if(srvc->channel) {
Packit ee6627
    mwChannel_destroy(srvc->channel, ERR_SUCCESS, NULL);
Packit ee6627
    srvc->channel = NULL;
Packit ee6627
  }
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
static void clear(struct mwServiceDirectory *srvc) {
Packit ee6627
  struct mwDirectoryHandler *handler;
Packit ee6627
Packit ee6627
  if(srvc->books) {
Packit ee6627
    g_hash_table_destroy(srvc->books);
Packit ee6627
    srvc->books = NULL;
Packit ee6627
  }
Packit ee6627
  
Packit ee6627
  /* clear the handler */
Packit ee6627
  handler = srvc->handler;
Packit ee6627
  if(handler && handler->clear)
Packit ee6627
    handler->clear(srvc);
Packit ee6627
  srvc->handler = NULL;
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
static void recv_create(struct mwServiceDirectory *srvc,
Packit ee6627
			struct mwChannel *chan,
Packit ee6627
			struct mwMsgChannelCreate *msg) {
Packit ee6627
Packit ee6627
  /* no way man, we call the shots around here */
Packit ee6627
  mwChannel_destroy(chan, ERR_FAILURE, NULL);
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
static void recv_accept(struct mwServiceDirectory *srvc,
Packit ee6627
			struct mwChannel *chan,
Packit ee6627
			struct mwMsgChannelAccept *msg) {
Packit ee6627
Packit ee6627
  g_return_if_fail(srvc->channel != NULL);
Packit ee6627
  g_return_if_fail(srvc->channel == chan);
Packit ee6627
Packit ee6627
  if(MW_SERVICE_IS_STARTING(srvc)) {
Packit ee6627
    mwService_started(MW_SERVICE(srvc));
Packit ee6627
      
Packit ee6627
  } else {
Packit ee6627
    mwChannel_destroy(chan, ERR_FAILURE, NULL);
Packit ee6627
  }
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
static void recv_destroy(struct mwServiceDirectory *srvc,
Packit ee6627
			 struct mwChannel *chan,
Packit ee6627
			 struct mwMsgChannelDestroy *msg) {
Packit ee6627
Packit ee6627
  srvc->channel = NULL;
Packit ee6627
  mwService_stop(MW_SERVICE(srvc));
Packit ee6627
  /** @todo session sense service */
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
static void recv_list(struct mwServiceDirectory *srvc,
Packit ee6627
		      struct mwOpaque *data) {
Packit ee6627
Packit ee6627
  struct mwGetBuffer *b;
Packit ee6627
  guint32 request, code, count;
Packit ee6627
  gboolean foo_1;
Packit ee6627
  guint16 foo_2;
Packit ee6627
  
Packit ee6627
  b = mwGetBuffer_wrap(data);
Packit ee6627
  
Packit ee6627
  guint32_get(b, &request);
Packit ee6627
  guint32_get(b, &code);
Packit ee6627
  guint32_get(b, &count);
Packit ee6627
Packit ee6627
  gboolean_get(b, &foo_1);
Packit ee6627
  guint16_get(b, &foo_2);
Packit ee6627
Packit ee6627
  if(foo_1 || foo_2) {
Packit ee6627
    mw_mailme_opaque(data, "received strange address book list");
Packit ee6627
    mwGetBuffer_free(b);
Packit ee6627
    return;
Packit ee6627
  }
Packit ee6627
Packit ee6627
  while(!mwGetBuffer_error(b) && count--) {
Packit ee6627
    guint32 id;
Packit ee6627
    char *name = NULL;
Packit ee6627
Packit ee6627
    guint32_get(b, &id;;
Packit ee6627
    mwString_get(b, &name);
Packit ee6627
Packit ee6627
    book_new(srvc, name, id);
Packit ee6627
    g_free(name);
Packit ee6627
  }
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
static void recv_open(struct mwServiceDirectory *srvc,
Packit ee6627
		      struct mwOpaque *data) {
Packit ee6627
Packit ee6627
  /* look up the directory associated with this request id, 
Packit ee6627
     mark it as open, and trigger the event */
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
static void recv_search(struct mwServiceDirectory *srvc,
Packit ee6627
			struct mwOpaque *data) {
Packit ee6627
Packit ee6627
  /* look up the directory associated with this request id,
Packit ee6627
     trigger the event */
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
static void recv(struct mwServiceDirectory *srvc,
Packit ee6627
		 struct mwChannel *chan,
Packit ee6627
		 guint16 msg_type, struct mwOpaque *data) {
Packit ee6627
  
Packit ee6627
  g_return_if_fail(srvc != NULL);
Packit ee6627
  g_return_if_fail(chan != NULL);
Packit ee6627
  g_return_if_fail(chan == srvc->channel);
Packit ee6627
  g_return_if_fail(data != NULL);
Packit ee6627
Packit ee6627
  switch(msg_type) {
Packit ee6627
  case action_list:
Packit ee6627
    recv_list(srvc, data);
Packit ee6627
    break;
Packit ee6627
Packit ee6627
  case action_open:
Packit ee6627
    recv_open(srvc, data);
Packit ee6627
    break;
Packit ee6627
Packit ee6627
  case action_close:
Packit ee6627
    ; /* I don't think we should receive these */
Packit ee6627
    break;
Packit ee6627
Packit ee6627
  case action_search:
Packit ee6627
    recv_search(srvc, data);
Packit ee6627
    break;
Packit ee6627
Packit ee6627
  default:
Packit ee6627
    mw_mailme_opaque(data, "msg type 0x%04x in directory service", msg_type);
Packit ee6627
  }
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
struct mwServiceDirectory *
Packit ee6627
mwServiceDirectory_new(struct mwSession *session,
Packit ee6627
		       struct mwDirectoryHandler *handler) {
Packit ee6627
Packit ee6627
  struct mwServiceDirectory *srvc;
Packit ee6627
  struct mwService *service;
Packit ee6627
Packit ee6627
  g_return_val_if_fail(session != NULL, NULL);
Packit ee6627
  g_return_val_if_fail(handler != NULL, NULL);
Packit ee6627
Packit ee6627
  srvc = g_new0(struct mwServiceDirectory, 1);
Packit ee6627
  service = MW_SERVICE(srvc);
Packit ee6627
Packit ee6627
  mwService_init(service, session, SERVICE_DIRECTORY);
Packit ee6627
  service->get_name = getName;
Packit ee6627
  service->get_desc = getDesc;
Packit ee6627
  service->start = (mwService_funcStart) start;
Packit ee6627
  service->stop = (mwService_funcStop) stop;
Packit ee6627
  service->clear = (mwService_funcClear) clear;
Packit ee6627
  service->recv_create = (mwService_funcRecvCreate) recv_create;
Packit ee6627
  service->recv_accept = (mwService_funcRecvAccept) recv_accept;
Packit ee6627
  service->recv_destroy = (mwService_funcRecvDestroy) recv_destroy;
Packit ee6627
  service->recv = (mwService_funcRecv) recv;
Packit ee6627
Packit ee6627
  srvc->handler = handler;
Packit ee6627
  srvc->requests = map_guint_new();
Packit ee6627
  srvc->books = g_hash_table_new_full(g_str_hash, g_str_equal,
Packit ee6627
				      NULL, (GDestroyNotify) book_free);
Packit ee6627
  return srvc;
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
struct mwDirectoryHandler *
Packit ee6627
mwServiceDirectory_getHandler(struct mwServiceDirectory *srvc) {
Packit ee6627
  g_return_val_if_fail(srvc != NULL, NULL);
Packit ee6627
  return srvc->handler;
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
int mwServiceDirectory_refreshAddressBooks(struct mwServiceDirectory *srvc) {
Packit ee6627
  struct mwChannel *chan;
Packit ee6627
  struct mwPutBuffer *b;
Packit ee6627
  struct mwOpaque o;
Packit ee6627
  int ret;
Packit ee6627
Packit ee6627
  g_return_val_if_fail(srvc != NULL, -1);
Packit ee6627
Packit ee6627
  chan = srvc->channel;
Packit ee6627
  g_return_val_if_fail(chan != NULL, -1);
Packit ee6627
Packit ee6627
  b = mwPutBuffer_new();
Packit ee6627
  guint32_put(b, next_request_id(srvc));
Packit ee6627
Packit ee6627
  mwPutBuffer_finalize(&o, b);
Packit ee6627
  ret = mwChannel_send(chan, action_list, &o);
Packit ee6627
  mwOpaque_clear(&o);
Packit ee6627
Packit ee6627
  return ret;
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
GList *mwServiceDirectory_getAddressBooks(struct mwServiceDirectory *srvc) {
Packit ee6627
  g_return_val_if_fail(srvc != NULL, NULL);
Packit ee6627
  g_return_val_if_fail(srvc->books != NULL, NULL);
Packit ee6627
Packit ee6627
  return map_collect_values(srvc->books);
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
GList *mwServiceDirectory_getDirectories(struct mwServiceDirectory *srvc) {
Packit ee6627
  GList *bl, *ret = NULL;
Packit ee6627
  
Packit ee6627
  g_return_val_if_fail(srvc != NULL, NULL);
Packit ee6627
  g_return_val_if_fail(srvc->books != NULL, NULL);
Packit ee6627
Packit ee6627
  bl = map_collect_values(srvc->books);
Packit ee6627
  for( ; bl; bl = g_list_delete_link(bl, bl)) {
Packit ee6627
    struct mwAddressBook *book = bl->data;
Packit ee6627
    ret = g_list_concat(ret, map_collect_values(book->dirs));
Packit ee6627
  }
Packit ee6627
Packit ee6627
  return ret;
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
GList *mwAddressBook_getDirectories(struct mwAddressBook *book) {
Packit ee6627
  g_return_val_if_fail(book != NULL, NULL);
Packit ee6627
  g_return_val_if_fail(book->dirs != NULL, NULL);
Packit ee6627
Packit ee6627
  return map_collect_values(book->dirs);
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
const char *mwAddressBook_getName(struct mwAddressBook *book) {
Packit ee6627
  g_return_val_if_fail(book != NULL, NULL);
Packit ee6627
  return book->name;
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
struct mwDirectory *mwDirectory_new(struct mwAddressBook *book) {
Packit ee6627
  struct mwDirectory *dir;
Packit ee6627
Packit ee6627
  g_return_val_if_fail(book != NULL, NULL);
Packit ee6627
  g_return_val_if_fail(book->service != NULL, NULL);
Packit ee6627
Packit ee6627
  dir = g_new0(struct mwDirectory, 1);
Packit ee6627
  dir->service = book->service;
Packit ee6627
  dir->book = book;
Packit ee6627
  dir->state = mwDirectory_NEW;
Packit ee6627
Packit ee6627
  return dir;
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
enum mwDirectoryState mwDirectory_getState(struct mwDirectory *dir) {
Packit ee6627
  g_return_val_if_fail(dir != NULL, mwDirectory_UNKNOWN);
Packit ee6627
  return dir->state;
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
void mwDirectory_setClientData(struct mwDirectory *dir,
Packit ee6627
			       gpointer data, GDestroyNotify clear) {
Packit ee6627
Packit ee6627
  g_return_if_fail(dir != NULL);
Packit ee6627
  mw_datum_set(&dir->client_data, data, clear);
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
gpointer mwDirectory_getClientData(struct mwDirectory *dir) {
Packit ee6627
  g_return_val_if_fail(dir != NULL, NULL);
Packit ee6627
  return mw_datum_get(&dir->client_data);
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
void mwDirectory_removeClientData(struct mwDirectory *dir) {
Packit ee6627
  g_return_if_fail(dir != NULL);
Packit ee6627
  mw_datum_clear(&dir->client_data);
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
struct mwServiceDirectory *mwDirectory_getService(struct mwDirectory *dir) {
Packit ee6627
  g_return_val_if_fail(dir != NULL, NULL);
Packit ee6627
  g_return_val_if_fail(dir->book != NULL, NULL);
Packit ee6627
  return dir->book->service;
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
struct mwAddressBook *mwDirectory_getAddressBook(struct mwDirectory *dir) {
Packit ee6627
  g_return_val_if_fail(dir != NULL, NULL);
Packit ee6627
  return dir->book;
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
static int dir_open(struct mwDirectory *dir) {
Packit ee6627
  struct mwServiceDirectory *srvc;
Packit ee6627
  struct mwChannel *chan;
Packit ee6627
  struct mwPutBuffer *b;
Packit ee6627
  struct mwOpaque o;
Packit ee6627
  int ret;
Packit ee6627
Packit ee6627
  g_return_val_if_fail(dir != NULL, -1);
Packit ee6627
Packit ee6627
  srvc = dir->service;
Packit ee6627
  g_return_val_if_fail(srvc != NULL, -1);
Packit ee6627
Packit ee6627
  chan = srvc->channel;
Packit ee6627
  g_return_val_if_fail(chan != NULL, -1);
Packit ee6627
Packit ee6627
  b = mwPutBuffer_new();
Packit ee6627
  guint32_put(b, map_request(dir));
Packit ee6627
Packit ee6627
  /* unsure about these three bytes */
Packit ee6627
  gboolean_put(b, FALSE);
Packit ee6627
  guint16_put(b, 0x0000);
Packit ee6627
Packit ee6627
  guint32_put(b, dir->book->id);
Packit ee6627
  mwString_put(b, dir->book->name);
Packit ee6627
Packit ee6627
  mwPutBuffer_finalize(&o, b);
Packit ee6627
  ret = mwChannel_send(chan, action_open, &o);
Packit ee6627
  mwOpaque_clear(&o);
Packit ee6627
Packit ee6627
  return ret;
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
int mwDirectory_open(struct mwDirectory *dir, mwSearchHandler cb) {
Packit ee6627
  g_return_val_if_fail(dir != NULL, -1);
Packit ee6627
  g_return_val_if_fail(cb != NULL, -1);
Packit ee6627
  g_return_val_if_fail(MW_DIRECTORY_IS_NEW(dir), -1);
Packit ee6627
Packit ee6627
  dir->state = mwDirectory_PENDING;
Packit ee6627
  dir->handler = cb;
Packit ee6627
Packit ee6627
  return dir_open(dir);
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
int mwDirectory_next(struct mwDirectory *dir) {  
Packit ee6627
  struct mwServiceDirectory *srvc;
Packit ee6627
  struct mwChannel *chan;
Packit ee6627
  struct mwPutBuffer *b;
Packit ee6627
  struct mwOpaque o;
Packit ee6627
  int ret;
Packit ee6627
Packit ee6627
  g_return_val_if_fail(dir != NULL, -1);
Packit ee6627
  g_return_val_if_fail(MW_DIRECTORY_IS_OPEN(dir), -1);
Packit ee6627
Packit ee6627
  srvc = dir->service;
Packit ee6627
  g_return_val_if_fail(srvc != NULL, -1);
Packit ee6627
Packit ee6627
  chan = srvc->channel;
Packit ee6627
  g_return_val_if_fail(chan != NULL, -1);
Packit ee6627
Packit ee6627
  b = mwPutBuffer_new();
Packit ee6627
  guint32_put(b, map_request(dir));
Packit ee6627
  guint32_put(b, dir->id);
Packit ee6627
  guint16_put(b, 0xffff);      /* some magic? */
Packit ee6627
  guint32_put(b, 0x00000000);  /* next results */
Packit ee6627
Packit ee6627
  mwPutBuffer_finalize(&o, b);
Packit ee6627
  ret = mwChannel_send(chan, action_search, &o);
Packit ee6627
  mwOpaque_clear(&o);
Packit ee6627
Packit ee6627
  return ret;
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
int mwDirectory_previous(struct mwDirectory *dir) {
Packit ee6627
  struct mwServiceDirectory *srvc;
Packit ee6627
  struct mwChannel *chan;
Packit ee6627
  struct mwPutBuffer *b;
Packit ee6627
  struct mwOpaque o;
Packit ee6627
  int ret;
Packit ee6627
Packit ee6627
  g_return_val_if_fail(dir != NULL, -1);
Packit ee6627
  g_return_val_if_fail(MW_DIRECTORY_IS_OPEN(dir), -1);
Packit ee6627
Packit ee6627
  srvc = dir->service;
Packit ee6627
  g_return_val_if_fail(srvc != NULL, -1);
Packit ee6627
Packit ee6627
  chan = srvc->channel;
Packit ee6627
  g_return_val_if_fail(chan != NULL, -1);
Packit ee6627
Packit ee6627
  b = mwPutBuffer_new();
Packit ee6627
  guint32_put(b, map_request(dir));
Packit ee6627
  guint32_put(b, dir->id);
Packit ee6627
  guint16_put(b, 0x0061);      /* some magic? */
Packit ee6627
  guint32_put(b, 0x00000001);  /* prev results */
Packit ee6627
Packit ee6627
  mwPutBuffer_finalize(&o, b);
Packit ee6627
  ret = mwChannel_send(chan, action_search, &o);
Packit ee6627
  mwOpaque_clear(&o);
Packit ee6627
Packit ee6627
  return ret;
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
int mwDirectory_search(struct mwDirectory *dir, const char *query) {
Packit ee6627
  struct mwServiceDirectory *srvc;
Packit ee6627
  struct mwChannel *chan;
Packit ee6627
  struct mwPutBuffer *b;
Packit ee6627
  struct mwOpaque o;
Packit ee6627
  int ret;
Packit ee6627
Packit ee6627
  g_return_val_if_fail(dir != NULL, -1);
Packit ee6627
  g_return_val_if_fail(MW_DIRECTORY_IS_OPEN(dir), -1);
Packit ee6627
  g_return_val_if_fail(query != NULL, -1);
Packit ee6627
  g_return_val_if_fail(*query != '\0', -1);
Packit ee6627
Packit ee6627
  srvc = dir->service;
Packit ee6627
  g_return_val_if_fail(srvc != NULL, -1);
Packit ee6627
Packit ee6627
  chan = srvc->channel;
Packit ee6627
  g_return_val_if_fail(chan != NULL, -1);
Packit ee6627
Packit ee6627
  b = mwPutBuffer_new();
Packit ee6627
  guint32_put(b, map_request(dir));
Packit ee6627
  guint32_put(b, dir->id);
Packit ee6627
  guint16_put(b, 0x0061);      /* some magic? */
Packit ee6627
  guint32_put(b, 0x00000008);  /* seek results */
Packit ee6627
  mwString_put(b, query);
Packit ee6627
Packit ee6627
  mwPutBuffer_finalize(&o, b);
Packit ee6627
  ret = mwChannel_send(chan, action_search, &o);
Packit ee6627
  mwOpaque_clear(&o);
Packit ee6627
Packit ee6627
  return ret;
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
static int dir_close(struct mwDirectory *dir) {
Packit ee6627
  struct mwServiceDirectory *srvc;
Packit ee6627
  struct mwChannel *chan;
Packit ee6627
  struct mwPutBuffer *b;
Packit ee6627
  struct mwOpaque o;
Packit ee6627
  int ret;
Packit ee6627
Packit ee6627
  g_return_val_if_fail(dir != NULL, -1);
Packit ee6627
Packit ee6627
  srvc = dir->service;
Packit ee6627
  g_return_val_if_fail(srvc != NULL, -1);
Packit ee6627
Packit ee6627
  chan = srvc->channel;
Packit ee6627
  g_return_val_if_fail(chan != NULL, -1);
Packit ee6627
Packit ee6627
  b = mwPutBuffer_new();
Packit ee6627
  guint32_put(b, next_request_id(dir->service));
Packit ee6627
  guint32_put(b, dir->id);
Packit ee6627
Packit ee6627
  mwPutBuffer_finalize(&o, b);
Packit ee6627
  ret = mwChannel_send(chan, action_close, &o);
Packit ee6627
  mwOpaque_clear(&o);
Packit ee6627
Packit ee6627
  return ret;
Packit ee6627
}
Packit ee6627
Packit ee6627
Packit ee6627
int mwDirectory_destroy(struct mwDirectory *dir) {
Packit ee6627
  int ret = 0;
Packit ee6627
Packit ee6627
  g_return_val_if_fail(dir != NULL, -1);
Packit ee6627
Packit ee6627
  if(MW_DIRECTORY_IS_OPEN(dir) || MW_DIRECTORY_IS_PENDING(dir)) {
Packit ee6627
    ret = dir_close(dir);
Packit ee6627
  }
Packit ee6627
  dir_remove(dir);
Packit ee6627
Packit ee6627
  return ret;
Packit ee6627
}
Packit ee6627