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