|
Packit |
16808d |
|
|
Packit |
16808d |
/*
|
|
Packit |
16808d |
Meanwhile - Unofficial Lotus Sametime Community Client Library
|
|
Packit |
16808d |
Copyright (C) 2004 Christopher (siege) O'Brien
|
|
Packit |
16808d |
|
|
Packit |
16808d |
This library is free software; you can redistribute it and/or
|
|
Packit |
16808d |
modify it under the terms of the GNU Library General Public
|
|
Packit |
16808d |
License as published by the Free Software Foundation; either
|
|
Packit |
16808d |
version 2 of the License, or (at your option) any later version.
|
|
Packit |
16808d |
|
|
Packit |
16808d |
This library is distributed in the hope that it will be useful,
|
|
Packit |
16808d |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
16808d |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
16808d |
Library General Public License for more details.
|
|
Packit |
16808d |
|
|
Packit |
16808d |
You should have received a copy of the GNU Library General Public
|
|
Packit |
16808d |
License along with this library; if not, write to the Free
|
|
Packit |
16808d |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
Packit |
16808d |
*/
|
|
Packit |
16808d |
|
|
Packit |
16808d |
#include <glib.h>
|
|
Packit |
16808d |
#include <glib/ghash.h>
|
|
Packit |
16808d |
#include <glib/glist.h>
|
|
Packit |
16808d |
#include <string.h>
|
|
Packit |
16808d |
|
|
Packit |
16808d |
#include "mw_channel.h"
|
|
Packit |
16808d |
#include "mw_debug.h"
|
|
Packit |
16808d |
#include "mw_error.h"
|
|
Packit |
16808d |
#include "mw_message.h"
|
|
Packit |
16808d |
#include "mw_service.h"
|
|
Packit |
16808d |
#include "mw_session.h"
|
|
Packit |
16808d |
#include "mw_srvc_aware.h"
|
|
Packit |
16808d |
#include "mw_util.h"
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwServiceAware {
|
|
Packit |
16808d |
struct mwService service;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwAwareHandler *handler;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/** map of ENTRY_KEY(aware_entry):aware_entry */
|
|
Packit |
16808d |
GHashTable *entries;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/** set of guint32:attrib_watch_entry attribute keys */
|
|
Packit |
16808d |
GHashTable *attribs;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/** collection of lists of awareness for this service. Each item is
|
|
Packit |
16808d |
a mwAwareList */
|
|
Packit |
16808d |
GList *lists;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/** the buddy list channel */
|
|
Packit |
16808d |
struct mwChannel *channel;
|
|
Packit |
16808d |
};
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwAwareList {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/** the owning service */
|
|
Packit |
16808d |
struct mwServiceAware *service;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/** map of ENTRY_KEY(aware_entry):aware_entry */
|
|
Packit |
16808d |
GHashTable *entries;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/** set of guint32:attrib_watch_entry attribute keys */
|
|
Packit |
16808d |
GHashTable *attribs;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwAwareListHandler *handler;
|
|
Packit |
16808d |
struct mw_datum client_data;
|
|
Packit |
16808d |
};
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwAwareAttribute {
|
|
Packit |
16808d |
guint32 key;
|
|
Packit |
16808d |
struct mwOpaque data;
|
|
Packit |
16808d |
};
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct attrib_entry {
|
|
Packit |
16808d |
guint32 key;
|
|
Packit |
16808d |
GList *membership;
|
|
Packit |
16808d |
};
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/** an actual awareness entry, belonging to any number of aware lists */
|
|
Packit |
16808d |
struct aware_entry {
|
|
Packit |
16808d |
struct mwAwareSnapshot aware;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/** list of mwAwareList containing this entry */
|
|
Packit |
16808d |
GList *membership;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/** collection of attribute values for this entry.
|
|
Packit |
16808d |
map of ATTRIB_KEY(mwAwareAttribute):mwAwareAttribute */
|
|
Packit |
16808d |
GHashTable *attribs;
|
|
Packit |
16808d |
};
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
#define ENTRY_KEY(entry) &entry->aware.id
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/** the channel send types used by this service */
|
|
Packit |
16808d |
enum msg_types {
|
|
Packit |
16808d |
msg_AWARE_ADD = 0x0068, /**< remove an aware */
|
|
Packit |
16808d |
msg_AWARE_REMOVE = 0x0069, /**< add an aware */
|
|
Packit |
16808d |
|
|
Packit |
16808d |
msg_OPT_DO_SET = 0x00c9, /**< set an attribute */
|
|
Packit |
16808d |
msg_OPT_DO_UNSET = 0x00ca, /**< unset an attribute */
|
|
Packit |
16808d |
msg_OPT_WATCH = 0x00cb, /**< set the attribute watch list */
|
|
Packit |
16808d |
|
|
Packit |
16808d |
msg_AWARE_SNAPSHOT = 0x01f4, /**< recv aware snapshot */
|
|
Packit |
16808d |
msg_AWARE_UPDATE = 0x01f5, /**< recv aware update */
|
|
Packit |
16808d |
msg_AWARE_GROUP = 0x01f6, /**< recv group aware */
|
|
Packit |
16808d |
|
|
Packit |
16808d |
msg_OPT_GOT_SET = 0x0259, /**< recv attribute set update */
|
|
Packit |
16808d |
msg_OPT_GOT_UNSET = 0x025a, /**< recv attribute unset update */
|
|
Packit |
16808d |
|
|
Packit |
16808d |
msg_OPT_GOT_UNKNOWN = 0x025b, /**< UNKNOWN */
|
|
Packit |
16808d |
|
|
Packit |
16808d |
msg_OPT_DID_SET = 0x025d, /**< attribute set response */
|
|
Packit |
16808d |
msg_OPT_DID_UNSET = 0x025e, /**< attribute unset response */
|
|
Packit |
16808d |
msg_OPT_DID_ERROR = 0x025f, /**< attribute set/unset error */
|
|
Packit |
16808d |
};
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void aware_entry_free(struct aware_entry *ae) {
|
|
Packit |
16808d |
mwAwareSnapshot_clear(&ae->aware);
|
|
Packit |
16808d |
g_list_free(ae->membership);
|
|
Packit |
16808d |
g_hash_table_destroy(ae->attribs);
|
|
Packit |
16808d |
g_free(ae);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void attrib_entry_free(struct attrib_entry *ae) {
|
|
Packit |
16808d |
g_list_free(ae->membership);
|
|
Packit |
16808d |
g_free(ae);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void attrib_free(struct mwAwareAttribute *attrib) {
|
|
Packit |
16808d |
mwOpaque_clear(&attrib->data);
|
|
Packit |
16808d |
g_free(attrib);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static struct aware_entry *aware_find(struct mwServiceAware *srvc,
|
|
Packit |
16808d |
struct mwAwareIdBlock *srch) {
|
|
Packit |
16808d |
g_return_val_if_fail(srvc != NULL, NULL);
|
|
Packit |
16808d |
g_return_val_if_fail(srvc->entries != NULL, NULL);
|
|
Packit |
16808d |
g_return_val_if_fail(srch != NULL, NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return g_hash_table_lookup(srvc->entries, srch);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static struct aware_entry *list_aware_find(struct mwAwareList *list,
|
|
Packit |
16808d |
struct mwAwareIdBlock *srch) {
|
|
Packit |
16808d |
g_return_val_if_fail(list != NULL, NULL);
|
|
Packit |
16808d |
g_return_val_if_fail(list->entries != NULL, NULL);
|
|
Packit |
16808d |
g_return_val_if_fail(srch != NULL, NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return g_hash_table_lookup(list->entries, srch);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void compose_list(struct mwPutBuffer *b, GList *id_list) {
|
|
Packit |
16808d |
guint32_put(b, g_list_length(id_list));
|
|
Packit |
16808d |
for(; id_list; id_list = id_list->next)
|
|
Packit |
16808d |
mwAwareIdBlock_put(b, id_list->data);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static int send_add(struct mwChannel *chan, GList *id_list) {
|
|
Packit |
16808d |
struct mwPutBuffer *b = mwPutBuffer_new();
|
|
Packit |
16808d |
struct mwOpaque o;
|
|
Packit |
16808d |
int ret;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(chan != NULL, 0);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
compose_list(b, id_list);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwPutBuffer_finalize(&o, b);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
ret = mwChannel_send(chan, msg_AWARE_ADD, &o);
|
|
Packit |
16808d |
mwOpaque_clear(&o);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static int send_rem(struct mwChannel *chan, GList *id_list) {
|
|
Packit |
16808d |
struct mwPutBuffer *b = mwPutBuffer_new();
|
|
Packit |
16808d |
struct mwOpaque o;
|
|
Packit |
16808d |
int ret;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(chan != NULL, 0);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
compose_list(b, id_list);
|
|
Packit |
16808d |
mwPutBuffer_finalize(&o, b);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
ret = mwChannel_send(chan, msg_AWARE_REMOVE, &o);
|
|
Packit |
16808d |
mwOpaque_clear(&o);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static gboolean collect_dead(gpointer key, gpointer val, gpointer data) {
|
|
Packit |
16808d |
struct aware_entry *aware = val;
|
|
Packit |
16808d |
GList **dead = data;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(aware->membership == NULL) {
|
|
Packit |
16808d |
g_info(" removing %s, %s",
|
|
Packit |
16808d |
NSTR(aware->aware.id.user), NSTR(aware->aware.id.community));
|
|
Packit |
16808d |
*dead = g_list_append(*dead, aware);
|
|
Packit |
16808d |
return TRUE;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
} else {
|
|
Packit |
16808d |
return FALSE;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static int remove_unused(struct mwServiceAware *srvc) {
|
|
Packit |
16808d |
/* - create a GList of all the unused aware entries
|
|
Packit |
16808d |
- remove each unused aware from the service
|
|
Packit |
16808d |
- if the service is alive, send a removal message for the collected
|
|
Packit |
16808d |
unused.
|
|
Packit |
16808d |
*/
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int ret = 0;
|
|
Packit |
16808d |
GList *dead = NULL, *l;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(srvc->entries) {
|
|
Packit |
16808d |
g_info("bring out your dead *clang*");
|
|
Packit |
16808d |
g_hash_table_foreach_steal(srvc->entries, collect_dead, &dead);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(dead) {
|
|
Packit |
16808d |
if(MW_SERVICE_IS_LIVE(srvc))
|
|
Packit |
16808d |
ret = send_rem(srvc->channel, dead) || ret;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
for(l = dead; l; l = l->next)
|
|
Packit |
16808d |
aware_entry_free(l->data);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_list_free(dead);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static int send_attrib_list(struct mwServiceAware *srvc) {
|
|
Packit |
16808d |
struct mwPutBuffer *b;
|
|
Packit |
16808d |
struct mwOpaque o;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int tmp;
|
|
Packit |
16808d |
GList *l;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(srvc != NULL, -1);
|
|
Packit |
16808d |
g_return_val_if_fail(srvc->channel != NULL, 0);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
l = map_collect_keys(srvc->attribs);
|
|
Packit |
16808d |
tmp = g_list_length(l);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
b = mwPutBuffer_new();
|
|
Packit |
16808d |
guint32_put(b, 0x00);
|
|
Packit |
16808d |
guint32_put(b, tmp);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
for(; l; l = g_list_delete_link(l, l)) {
|
|
Packit |
16808d |
guint32_put(b, GPOINTER_TO_UINT(l->data));
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwPutBuffer_finalize(&o, b);
|
|
Packit |
16808d |
tmp = mwChannel_send(srvc->channel, msg_OPT_WATCH, &o);
|
|
Packit |
16808d |
mwOpaque_clear(&o);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return tmp;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static gboolean collect_attrib_dead(gpointer key, gpointer val,
|
|
Packit |
16808d |
gpointer data) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct attrib_entry *attrib = val;
|
|
Packit |
16808d |
GList **dead = data;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(attrib->membership == NULL) {
|
|
Packit |
16808d |
g_info(" removing 0x%08x", GPOINTER_TO_UINT(key));
|
|
Packit |
16808d |
*dead = g_list_append(*dead, attrib);
|
|
Packit |
16808d |
return TRUE;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
} else {
|
|
Packit |
16808d |
return FALSE;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static int remove_unused_attrib(struct mwServiceAware *srvc) {
|
|
Packit |
16808d |
GList *dead = NULL;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(srvc->attribs) {
|
|
Packit |
16808d |
g_info("collecting dead attributes");
|
|
Packit |
16808d |
g_hash_table_foreach_steal(srvc->attribs, collect_attrib_dead, &dead);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/* since we stole them, we'll have to clean 'em up manually */
|
|
Packit |
16808d |
for(; dead; dead = g_list_delete_link(dead, dead)) {
|
|
Packit |
16808d |
attrib_entry_free(dead->data);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return MW_SERVICE_IS_LIVE(srvc)? send_attrib_list(srvc): 0;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void recv_accept(struct mwServiceAware *srvc,
|
|
Packit |
16808d |
struct mwChannel *chan,
|
|
Packit |
16808d |
struct mwMsgChannelAccept *msg) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_if_fail(srvc->channel != NULL);
|
|
Packit |
16808d |
g_return_if_fail(srvc->channel == chan);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(MW_SERVICE_IS_STARTING(MW_SERVICE(srvc))) {
|
|
Packit |
16808d |
GList *list = NULL;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
list = map_collect_values(srvc->entries);
|
|
Packit |
16808d |
send_add(chan, list);
|
|
Packit |
16808d |
g_list_free(list);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
send_attrib_list(srvc);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwService_started(MW_SERVICE(srvc));
|
|
Packit |
16808d |
|
|
Packit |
16808d |
} else {
|
|
Packit |
16808d |
mwChannel_destroy(chan, ERR_FAILURE, NULL);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void recv_destroy(struct mwServiceAware *srvc,
|
|
Packit |
16808d |
struct mwChannel *chan,
|
|
Packit |
16808d |
struct mwMsgChannelDestroy *msg) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc->channel = NULL;
|
|
Packit |
16808d |
mwService_stop(MW_SERVICE(srvc));
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/** @todo session sense service and mwService_start */
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/** called from SNAPSHOT_recv, UPDATE_recv, and
|
|
Packit |
16808d |
mwServiceAware_setStatus */
|
|
Packit |
16808d |
static void status_recv(struct mwServiceAware *srvc,
|
|
Packit |
16808d |
struct mwAwareSnapshot *idb) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct aware_entry *aware;
|
|
Packit |
16808d |
GList *l;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
aware = aware_find(srvc, &idb->id);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(! aware) {
|
|
Packit |
16808d |
/* we don't deal with receiving status for something we're not
|
|
Packit |
16808d |
monitoring, but it will happen sometimes, eg from manually set
|
|
Packit |
16808d |
status */
|
|
Packit |
16808d |
return;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/* clear the existing status, then clone in the new status */
|
|
Packit |
16808d |
mwAwareSnapshot_clear(&aware->aware);
|
|
Packit |
16808d |
mwAwareSnapshot_clone(&aware->aware, idb);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/* trigger each of the entry's lists */
|
|
Packit |
16808d |
for(l = aware->membership; l; l = l->next) {
|
|
Packit |
16808d |
struct mwAwareList *alist = l->data;
|
|
Packit |
16808d |
struct mwAwareListHandler *handler = alist->handler;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(handler && handler->on_aware)
|
|
Packit |
16808d |
handler->on_aware(alist, idb);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void attrib_recv(struct mwServiceAware *srvc,
|
|
Packit |
16808d |
struct mwAwareIdBlock *idb,
|
|
Packit |
16808d |
struct mwAwareAttribute *attrib) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct aware_entry *aware;
|
|
Packit |
16808d |
struct mwAwareAttribute *old_attrib = NULL;
|
|
Packit |
16808d |
GList *l;
|
|
Packit |
16808d |
guint32 key;
|
|
Packit |
16808d |
gpointer k;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
aware = aware_find(srvc, idb);
|
|
Packit |
16808d |
g_return_if_fail(aware != NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
key = attrib->key;
|
|
Packit |
16808d |
k = GUINT_TO_POINTER(key);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(aware->attribs)
|
|
Packit |
16808d |
old_attrib = g_hash_table_lookup(aware->attribs, k);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(! old_attrib) {
|
|
Packit |
16808d |
old_attrib = g_new0(struct mwAwareAttribute, 1);
|
|
Packit |
16808d |
old_attrib->key = key;
|
|
Packit |
16808d |
g_hash_table_insert(aware->attribs, k, old_attrib);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwOpaque_clear(&old_attrib->data);
|
|
Packit |
16808d |
mwOpaque_clone(&old_attrib->data, &attrib->data);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
for(l = aware->membership; l; l = l->next) {
|
|
Packit |
16808d |
struct mwAwareList *list = l->data;
|
|
Packit |
16808d |
struct mwAwareListHandler *h = list->handler;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(h && h->on_attrib &&
|
|
Packit |
16808d |
list->attribs && g_hash_table_lookup(list->attribs, k))
|
|
Packit |
16808d |
|
|
Packit |
16808d |
h->on_attrib(list, idb, old_attrib);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static gboolean list_add(struct mwAwareList *list,
|
|
Packit |
16808d |
struct mwAwareIdBlock *id) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwServiceAware *srvc = list->service;
|
|
Packit |
16808d |
struct aware_entry *aware;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(id->user != NULL, FALSE);
|
|
Packit |
16808d |
g_return_val_if_fail(strlen(id->user) > 0, FALSE);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(! list->entries)
|
|
Packit |
16808d |
list->entries = g_hash_table_new((GHashFunc) mwAwareIdBlock_hash,
|
|
Packit |
16808d |
(GEqualFunc) mwAwareIdBlock_equal);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
aware = list_aware_find(list, id);
|
|
Packit |
16808d |
if(aware) return FALSE;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
aware = aware_find(srvc, id);
|
|
Packit |
16808d |
if(! aware) {
|
|
Packit |
16808d |
aware = g_new0(struct aware_entry, 1);
|
|
Packit |
16808d |
aware->attribs = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
|
|
Packit |
16808d |
(GDestroyNotify) attrib_free);
|
|
Packit |
16808d |
mwAwareIdBlock_clone(ENTRY_KEY(aware), id);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_hash_table_insert(srvc->entries, ENTRY_KEY(aware), aware);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
aware->membership = g_list_append(aware->membership, list);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_hash_table_insert(list->entries, ENTRY_KEY(aware), aware);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return TRUE;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void group_member_recv(struct mwServiceAware *srvc,
|
|
Packit |
16808d |
struct mwAwareSnapshot *idb) {
|
|
Packit |
16808d |
/* @todo
|
|
Packit |
16808d |
- look up group by id
|
|
Packit |
16808d |
- find each list group belongs to
|
|
Packit |
16808d |
- add user to lists
|
|
Packit |
16808d |
*/
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwAwareIdBlock gsrch = { mwAware_GROUP, idb->group, NULL };
|
|
Packit |
16808d |
struct aware_entry *grp;
|
|
Packit |
16808d |
GList *l, *m;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
grp = aware_find(srvc, &gsrch);
|
|
Packit |
16808d |
g_return_if_fail(grp != NULL); /* this could happen, with timing. */
|
|
Packit |
16808d |
|
|
Packit |
16808d |
l = g_list_prepend(NULL, &idb->id);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
for(m = grp->membership; m; m = m->next) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/* if we just list_add, we won't receive updates for attributes,
|
|
Packit |
16808d |
so annoyingly we have to turn around and send out an add aware
|
|
Packit |
16808d |
message for each incoming group member */
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/* list_add(m->data, &idb->id); */
|
|
Packit |
16808d |
mwAwareList_addAware(m->data, l);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_list_free(l);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void recv_SNAPSHOT(struct mwServiceAware *srvc,
|
|
Packit |
16808d |
struct mwGetBuffer *b) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint32 count;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwAwareSnapshot *snap;
|
|
Packit |
16808d |
snap = g_new0(struct mwAwareSnapshot, 1);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint32_get(b, &count);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
while(count--) {
|
|
Packit |
16808d |
mwAwareSnapshot_get(b, snap);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(mwGetBuffer_error(b)) {
|
|
Packit |
16808d |
mwAwareSnapshot_clear(snap);
|
|
Packit |
16808d |
break;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(snap->group)
|
|
Packit |
16808d |
group_member_recv(srvc, snap);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
status_recv(srvc, snap);
|
|
Packit |
16808d |
mwAwareSnapshot_clear(snap);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_free(snap);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void recv_UPDATE(struct mwServiceAware *srvc,
|
|
Packit |
16808d |
struct mwGetBuffer *b) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwAwareSnapshot *snap;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
snap = g_new0(struct mwAwareSnapshot, 1);
|
|
Packit |
16808d |
mwAwareSnapshot_get(b, snap);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(snap->group)
|
|
Packit |
16808d |
group_member_recv(srvc, snap);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(! mwGetBuffer_error(b))
|
|
Packit |
16808d |
status_recv(srvc, snap);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwAwareSnapshot_clear(snap);
|
|
Packit |
16808d |
g_free(snap);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void recv_GROUP(struct mwServiceAware *srvc,
|
|
Packit |
16808d |
struct mwGetBuffer *b) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwAwareIdBlock idb = { 0, 0, 0 };
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/* really nothing to be done with this. The group should have
|
|
Packit |
16808d |
already been added to the list and service, and is now simply
|
|
Packit |
16808d |
awaiting a snapshot/update with users listed as belonging in said
|
|
Packit |
16808d |
group. */
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwAwareIdBlock_get(b, &idb);
|
|
Packit |
16808d |
mwAwareIdBlock_clear(&idb);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void recv_OPT_GOT_SET(struct mwServiceAware *srvc,
|
|
Packit |
16808d |
struct mwGetBuffer *b) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwAwareAttribute attrib;
|
|
Packit |
16808d |
struct mwAwareIdBlock idb;
|
|
Packit |
16808d |
guint32 junk, check;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint32_get(b, &junk);
|
|
Packit |
16808d |
mwAwareIdBlock_get(b, &idb);
|
|
Packit |
16808d |
guint32_get(b, &junk);
|
|
Packit |
16808d |
guint32_get(b, &check);
|
|
Packit |
16808d |
guint32_get(b, &junk);
|
|
Packit |
16808d |
guint32_get(b, &attrib.key);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(check) {
|
|
Packit |
16808d |
mwOpaque_get(b, &attrib.data);
|
|
Packit |
16808d |
} else {
|
|
Packit |
16808d |
attrib.data.len = 0;
|
|
Packit |
16808d |
attrib.data.data = NULL;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
attrib_recv(srvc, &idb, &attrib);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwAwareIdBlock_clear(&idb);
|
|
Packit |
16808d |
mwOpaque_clear(&attrib.data);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void recv_OPT_GOT_UNSET(struct mwServiceAware *srvc,
|
|
Packit |
16808d |
struct mwGetBuffer *b) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwAwareAttribute attrib;
|
|
Packit |
16808d |
struct mwAwareIdBlock idb;
|
|
Packit |
16808d |
guint32 junk;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
attrib.key = 0;
|
|
Packit |
16808d |
attrib.data.len = 0;
|
|
Packit |
16808d |
attrib.data.data = NULL;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint32_get(b, &junk);
|
|
Packit |
16808d |
mwAwareIdBlock_get(b, &idb);
|
|
Packit |
16808d |
guint32_get(b, &attrib.key);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
attrib_recv(srvc, &idb, &attrib);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwAwareIdBlock_clear(&idb);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void recv(struct mwService *srvc, struct mwChannel *chan,
|
|
Packit |
16808d |
guint16 type, struct mwOpaque *data) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwServiceAware *srvc_aware = (struct mwServiceAware *) srvc;
|
|
Packit |
16808d |
struct mwGetBuffer *b;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_if_fail(srvc_aware->channel == chan);
|
|
Packit |
16808d |
g_return_if_fail(srvc->session == mwChannel_getSession(chan));
|
|
Packit |
16808d |
g_return_if_fail(data != NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
b = mwGetBuffer_wrap(data);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
switch(type) {
|
|
Packit |
16808d |
case msg_AWARE_SNAPSHOT:
|
|
Packit |
16808d |
recv_SNAPSHOT(srvc_aware, b);
|
|
Packit |
16808d |
break;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
case msg_AWARE_UPDATE:
|
|
Packit |
16808d |
recv_UPDATE(srvc_aware, b);
|
|
Packit |
16808d |
break;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
case msg_AWARE_GROUP:
|
|
Packit |
16808d |
recv_GROUP(srvc_aware, b);
|
|
Packit |
16808d |
break;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
case msg_OPT_GOT_SET:
|
|
Packit |
16808d |
recv_OPT_GOT_SET(srvc_aware, b);
|
|
Packit |
16808d |
break;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
case msg_OPT_GOT_UNSET:
|
|
Packit |
16808d |
recv_OPT_GOT_UNSET(srvc_aware, b);
|
|
Packit |
16808d |
break;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
case msg_OPT_GOT_UNKNOWN:
|
|
Packit |
16808d |
case msg_OPT_DID_SET:
|
|
Packit |
16808d |
case msg_OPT_DID_UNSET:
|
|
Packit |
16808d |
case msg_OPT_DID_ERROR:
|
|
Packit |
16808d |
break;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
default:
|
|
Packit |
16808d |
mw_mailme_opaque(data, "unknown message in aware service: 0x%04x", type);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwGetBuffer_free(b);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void clear(struct mwService *srvc) {
|
|
Packit |
16808d |
struct mwServiceAware *srvc_aware = (struct mwServiceAware *) srvc;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_if_fail(srvc != NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
while(srvc_aware->lists)
|
|
Packit |
16808d |
mwAwareList_free( (struct mwAwareList *) srvc_aware->lists->data );
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_hash_table_destroy(srvc_aware->entries);
|
|
Packit |
16808d |
srvc_aware->entries = NULL;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_hash_table_destroy(srvc_aware->attribs);
|
|
Packit |
16808d |
srvc_aware->attribs = NULL;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static const char *name(struct mwService *srvc) {
|
|
Packit |
16808d |
return "Presence Awareness";
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static const char *desc(struct mwService *srvc) {
|
|
Packit |
16808d |
return "Buddy list service with support for server-side groups";
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static struct mwChannel *make_blist(struct mwServiceAware *srvc,
|
|
Packit |
16808d |
struct mwChannelSet *cs) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwChannel *chan = mwChannel_newOutgoing(cs);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwChannel_setService(chan, MW_SERVICE(srvc));
|
|
Packit |
16808d |
mwChannel_setProtoType(chan, 0x00000011);
|
|
Packit |
16808d |
mwChannel_setProtoVer(chan, 0x00030005);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return mwChannel_create(chan)? NULL: chan;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void start(struct mwService *srvc) {
|
|
Packit |
16808d |
struct mwServiceAware *srvc_aware;
|
|
Packit |
16808d |
struct mwChannel *chan = NULL;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc_aware = (struct mwServiceAware *) srvc;
|
|
Packit |
16808d |
chan = make_blist(srvc_aware, mwSession_getChannels(srvc->session));
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(chan != NULL) {
|
|
Packit |
16808d |
srvc_aware->channel = chan;
|
|
Packit |
16808d |
} else {
|
|
Packit |
16808d |
mwService_stopped(srvc);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void stop(struct mwService *srvc) {
|
|
Packit |
16808d |
struct mwServiceAware *srvc_aware;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc_aware = (struct mwServiceAware *) srvc;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(srvc_aware->channel) {
|
|
Packit |
16808d |
mwChannel_destroy(srvc_aware->channel, ERR_SUCCESS, NULL);
|
|
Packit |
16808d |
srvc_aware->channel = NULL;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwService_stopped(srvc);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwServiceAware *
|
|
Packit |
16808d |
mwServiceAware_new(struct mwSession *session,
|
|
Packit |
16808d |
struct mwAwareHandler *handler) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwService *service;
|
|
Packit |
16808d |
struct mwServiceAware *srvc;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(session != NULL, NULL);
|
|
Packit |
16808d |
g_return_val_if_fail(handler != NULL, NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc = g_new0(struct mwServiceAware, 1);
|
|
Packit |
16808d |
srvc->handler = handler;
|
|
Packit |
16808d |
srvc->entries = g_hash_table_new_full((GHashFunc) mwAwareIdBlock_hash,
|
|
Packit |
16808d |
(GEqualFunc) mwAwareIdBlock_equal,
|
|
Packit |
16808d |
NULL,
|
|
Packit |
16808d |
(GDestroyNotify) aware_entry_free);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc->attribs = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
|
|
Packit |
16808d |
(GDestroyNotify) attrib_entry_free);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
service = MW_SERVICE(srvc);
|
|
Packit |
16808d |
mwService_init(service, session, mwService_AWARE);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
service->recv_accept = (mwService_funcRecvAccept) recv_accept;
|
|
Packit |
16808d |
service->recv_destroy = (mwService_funcRecvDestroy) recv_destroy;
|
|
Packit |
16808d |
service->recv = recv;
|
|
Packit |
16808d |
service->start = start;
|
|
Packit |
16808d |
service->stop = stop;
|
|
Packit |
16808d |
service->clear = clear;
|
|
Packit |
16808d |
service->get_name = name;
|
|
Packit |
16808d |
service->get_desc = desc;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return srvc;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int mwServiceAware_setAttribute(struct mwServiceAware *srvc,
|
|
Packit |
16808d |
guint32 key, struct mwOpaque *data) {
|
|
Packit |
16808d |
struct mwPutBuffer *b;
|
|
Packit |
16808d |
struct mwOpaque o;
|
|
Packit |
16808d |
int ret;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
b = mwPutBuffer_new();
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint32_put(b, 0x00);
|
|
Packit |
16808d |
guint32_put(b, data->len);
|
|
Packit |
16808d |
guint32_put(b, 0x00);
|
|
Packit |
16808d |
guint32_put(b, key);
|
|
Packit |
16808d |
mwOpaque_put(b, data);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwPutBuffer_finalize(&o, b);
|
|
Packit |
16808d |
ret = mwChannel_send(srvc->channel, msg_OPT_DO_SET, &o);
|
|
Packit |
16808d |
mwOpaque_clear(&o);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int mwServiceAware_setAttributeBoolean(struct mwServiceAware *srvc,
|
|
Packit |
16808d |
guint32 key, gboolean val) {
|
|
Packit |
16808d |
int ret;
|
|
Packit |
16808d |
struct mwPutBuffer *b;
|
|
Packit |
16808d |
struct mwOpaque o;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
b = mwPutBuffer_new();
|
|
Packit |
16808d |
|
|
Packit |
16808d |
gboolean_put(b, FALSE);
|
|
Packit |
16808d |
gboolean_put(b, val);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwPutBuffer_finalize(&o, b);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
ret = mwServiceAware_setAttribute(srvc, key, &o);
|
|
Packit |
16808d |
mwOpaque_clear(&o);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int mwServiceAware_setAttributeInteger(struct mwServiceAware *srvc,
|
|
Packit |
16808d |
guint32 key, guint32 val) {
|
|
Packit |
16808d |
int ret;
|
|
Packit |
16808d |
struct mwPutBuffer *b;
|
|
Packit |
16808d |
struct mwOpaque o;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
b = mwPutBuffer_new();
|
|
Packit |
16808d |
guint32_put(b, val);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwPutBuffer_finalize(&o, b);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
ret = mwServiceAware_setAttribute(srvc, key, &o);
|
|
Packit |
16808d |
mwOpaque_clear(&o);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int mwServiceAware_setAttributeString(struct mwServiceAware *srvc,
|
|
Packit |
16808d |
guint32 key, const char *str) {
|
|
Packit |
16808d |
int ret;
|
|
Packit |
16808d |
struct mwPutBuffer *b;
|
|
Packit |
16808d |
struct mwOpaque o;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
b = mwPutBuffer_new();
|
|
Packit |
16808d |
mwString_put(b, str);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwPutBuffer_finalize(&o, b);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
ret = mwServiceAware_setAttribute(srvc, key, &o);
|
|
Packit |
16808d |
mwOpaque_clear(&o);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int mwServiceAware_unsetAttribute(struct mwServiceAware *srvc,
|
|
Packit |
16808d |
guint32 key) {
|
|
Packit |
16808d |
struct mwPutBuffer *b;
|
|
Packit |
16808d |
struct mwOpaque o;
|
|
Packit |
16808d |
int ret;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
b = mwPutBuffer_new();
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint32_put(b, 0x00);
|
|
Packit |
16808d |
guint32_put(b, key);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwPutBuffer_finalize(&o, b);
|
|
Packit |
16808d |
ret = mwChannel_send(srvc->channel, msg_OPT_DO_UNSET, &o);
|
|
Packit |
16808d |
mwOpaque_clear(&o);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint32 mwAwareAttribute_getKey(const struct mwAwareAttribute *attrib) {
|
|
Packit |
16808d |
g_return_val_if_fail(attrib != NULL, 0x00);
|
|
Packit |
16808d |
return attrib->key;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
gboolean mwAwareAttribute_asBoolean(const struct mwAwareAttribute *attrib) {
|
|
Packit |
16808d |
struct mwGetBuffer *b;
|
|
Packit |
16808d |
gboolean ret;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(! attrib) return FALSE;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
b = mwGetBuffer_wrap(&attrib->data);
|
|
Packit |
16808d |
if(attrib->data.len >= 4) {
|
|
Packit |
16808d |
guint32 r32 = 0x00;
|
|
Packit |
16808d |
guint32_get(b, &r32);
|
|
Packit |
16808d |
ret = !! r32;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
} else if(attrib->data.len >= 2) {
|
|
Packit |
16808d |
guint16 r16 = 0x00;
|
|
Packit |
16808d |
guint16_get(b, &r16);
|
|
Packit |
16808d |
ret = !! r16;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
} else if(attrib->data.len) {
|
|
Packit |
16808d |
gboolean_get(b, &ret;;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwGetBuffer_free(b);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint32 mwAwareAttribute_asInteger(const struct mwAwareAttribute *attrib) {
|
|
Packit |
16808d |
struct mwGetBuffer *b;
|
|
Packit |
16808d |
guint32 r32 = 0x00;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(! attrib) return 0x00;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
b = mwGetBuffer_wrap(&attrib->data);
|
|
Packit |
16808d |
if(attrib->data.len >= 4) {
|
|
Packit |
16808d |
guint32_get(b, &r32);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
} else if(attrib->data.len == 3) {
|
|
Packit |
16808d |
gboolean rb = FALSE;
|
|
Packit |
16808d |
guint16 r16 = 0x00;
|
|
Packit |
16808d |
gboolean_get(b, &rb);
|
|
Packit |
16808d |
guint16_get(b, &r16);
|
|
Packit |
16808d |
r32 = (guint32) r16;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
} else if(attrib->data.len == 2) {
|
|
Packit |
16808d |
guint16 r16 = 0x00;
|
|
Packit |
16808d |
guint16_get(b, &r16);
|
|
Packit |
16808d |
r32 = (guint32) r16;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
} else if(attrib->data.len) {
|
|
Packit |
16808d |
gboolean rb = FALSE;
|
|
Packit |
16808d |
gboolean_get(b, &rb);
|
|
Packit |
16808d |
r32 = (guint32) rb;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwGetBuffer_free(b);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return r32;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
char *mwAwareAttribute_asString(const struct mwAwareAttribute *attrib) {
|
|
Packit |
16808d |
struct mwGetBuffer *b;
|
|
Packit |
16808d |
char *ret = NULL;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(! attrib) return NULL;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
b = mwGetBuffer_wrap(&attrib->data);
|
|
Packit |
16808d |
mwString_get(b, &ret;;
|
|
Packit |
16808d |
mwGetBuffer_free(b);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
const struct mwOpaque *
|
|
Packit |
16808d |
mwAwareAttribute_asOpaque(const struct mwAwareAttribute *attrib) {
|
|
Packit |
16808d |
g_return_val_if_fail(attrib != NULL, NULL);
|
|
Packit |
16808d |
return &attrib->data;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwAwareList *
|
|
Packit |
16808d |
mwAwareList_new(struct mwServiceAware *srvc,
|
|
Packit |
16808d |
struct mwAwareListHandler *handler) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwAwareList *al;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(srvc != NULL, NULL);
|
|
Packit |
16808d |
g_return_val_if_fail(handler != NULL, NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
al = g_new0(struct mwAwareList, 1);
|
|
Packit |
16808d |
al->service = srvc;
|
|
Packit |
16808d |
al->handler = handler;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc->lists = g_list_prepend(srvc->lists, al);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return al;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
void mwAwareList_free(struct mwAwareList *list) {
|
|
Packit |
16808d |
struct mwServiceAware *srvc;
|
|
Packit |
16808d |
struct mwAwareListHandler *handler;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_if_fail(list != NULL);
|
|
Packit |
16808d |
g_return_if_fail(list->service != NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc = list->service;
|
|
Packit |
16808d |
srvc->lists = g_list_remove_all(srvc->lists, list);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
handler = list->handler;
|
|
Packit |
16808d |
if(handler && handler->clear) {
|
|
Packit |
16808d |
handler->clear(list);
|
|
Packit |
16808d |
list->handler = NULL;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mw_datum_clear(&list->client_data);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwAwareList_unwatchAllAttributes(list);
|
|
Packit |
16808d |
mwAwareList_removeAllAware(list);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
list->service = NULL;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_free(list);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwAwareListHandler *mwAwareList_getHandler(struct mwAwareList *list) {
|
|
Packit |
16808d |
g_return_val_if_fail(list != NULL, NULL);
|
|
Packit |
16808d |
return list->handler;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void watch_add(struct mwAwareList *list, guint32 key) {
|
|
Packit |
16808d |
struct mwServiceAware *srvc;
|
|
Packit |
16808d |
struct attrib_entry *watch;
|
|
Packit |
16808d |
gpointer k = GUINT_TO_POINTER(key);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(! list->attribs)
|
|
Packit |
16808d |
list->attribs = g_hash_table_new(g_direct_hash, g_direct_equal);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(g_hash_table_lookup(list->attribs, k))
|
|
Packit |
16808d |
return;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc = list->service;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
watch = g_hash_table_lookup(srvc->attribs, k);
|
|
Packit |
16808d |
if(! watch) {
|
|
Packit |
16808d |
watch = g_new0(struct attrib_entry, 1);
|
|
Packit |
16808d |
watch->key = key;
|
|
Packit |
16808d |
g_hash_table_insert(srvc->attribs, k, watch);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_hash_table_insert(list->attribs, k, watch);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
watch->membership = g_list_prepend(watch->membership, list);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void watch_remove(struct mwAwareList *list, guint32 key) {
|
|
Packit |
16808d |
struct attrib_entry *watch = NULL;
|
|
Packit |
16808d |
gpointer k = GUINT_TO_POINTER(key);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(list->attribs)
|
|
Packit |
16808d |
watch = g_hash_table_lookup(list->attribs, k);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_if_fail(watch != NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_hash_table_remove(list->attribs, k);
|
|
Packit |
16808d |
watch->membership = g_list_remove(watch->membership, list);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int mwAwareList_watchAttributeArray(struct mwAwareList *list,
|
|
Packit |
16808d |
guint32 *keys) {
|
|
Packit |
16808d |
guint32 k;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(list != NULL, -1);
|
|
Packit |
16808d |
g_return_val_if_fail(list->service != NULL, -1);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(! keys) return 0;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
for(k = *keys; k; keys++)
|
|
Packit |
16808d |
watch_add(list, k);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return send_attrib_list(list->service);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int mwAwareList_watchAttributes(struct mwAwareList *list,
|
|
Packit |
16808d |
guint32 key, ...) {
|
|
Packit |
16808d |
guint32 k;
|
|
Packit |
16808d |
va_list args;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(list != NULL, -1);
|
|
Packit |
16808d |
g_return_val_if_fail(list->service != NULL, -1);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
va_start(args, key);
|
|
Packit |
16808d |
for(k = key; k; k = va_arg(args, guint32))
|
|
Packit |
16808d |
watch_add(list, k);
|
|
Packit |
16808d |
va_end(args);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return send_attrib_list(list->service);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int mwAwareList_unwatchAttributeArray(struct mwAwareList *list,
|
|
Packit |
16808d |
guint32 *keys) {
|
|
Packit |
16808d |
guint32 k;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(list != NULL, -1);
|
|
Packit |
16808d |
g_return_val_if_fail(list->service != NULL, -1);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(! keys) return 0;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
for(k = *keys; k; keys++)
|
|
Packit |
16808d |
watch_add(list, k);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return remove_unused_attrib(list->service);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int mwAwareList_unwatchAttributes(struct mwAwareList *list,
|
|
Packit |
16808d |
guint32 key, ...) {
|
|
Packit |
16808d |
guint32 k;
|
|
Packit |
16808d |
va_list args;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(list != NULL, -1);
|
|
Packit |
16808d |
g_return_val_if_fail(list->service != NULL, -1);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
va_start(args, key);
|
|
Packit |
16808d |
for(k = key; k; k = va_arg(args, guint32))
|
|
Packit |
16808d |
watch_remove(list, k);
|
|
Packit |
16808d |
va_end(args);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return remove_unused_attrib(list->service);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void dismember_attrib(gpointer k, struct attrib_entry *watch,
|
|
Packit |
16808d |
struct mwAwareList *list) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
watch->membership = g_list_remove(watch->membership, list);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int mwAwareList_unwatchAllAttributes(struct mwAwareList *list) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwServiceAware *srvc;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(list != NULL, -1);
|
|
Packit |
16808d |
srvc = list->service;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(list->attribs) {
|
|
Packit |
16808d |
g_hash_table_foreach(list->attribs, (GHFunc) dismember_attrib, list);
|
|
Packit |
16808d |
g_hash_table_destroy(list->attribs);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return remove_unused_attrib(srvc);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void collect_attrib_keys(gpointer key, struct attrib_entry *attrib,
|
|
Packit |
16808d |
guint32 **ck) {
|
|
Packit |
16808d |
guint32 *keys = (*ck)++;
|
|
Packit |
16808d |
*keys = GPOINTER_TO_UINT(key);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint32 *mwAwareList_getWatchedAttributes(struct mwAwareList *list) {
|
|
Packit |
16808d |
guint32 *keys, **ck;
|
|
Packit |
16808d |
guint count;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(list != NULL, NULL);
|
|
Packit |
16808d |
g_return_val_if_fail(list->attribs != NULL, NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
count = g_hash_table_size(list->attribs);
|
|
Packit |
16808d |
keys = g_new0(guint32, count + 1);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
ck = &keys;
|
|
Packit |
16808d |
g_hash_table_foreach(list->attribs, (GHFunc) collect_attrib_keys, ck);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return keys;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int mwAwareList_addAware(struct mwAwareList *list, GList *id_list) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/* for each awareness id:
|
|
Packit |
16808d |
- if it's already in the list, continue
|
|
Packit |
16808d |
- if it's not in the service list:
|
|
Packit |
16808d |
- create an awareness
|
|
Packit |
16808d |
- add it to the service list
|
|
Packit |
16808d |
- add this list to the membership
|
|
Packit |
16808d |
- add to the list
|
|
Packit |
16808d |
*/
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwServiceAware *srvc;
|
|
Packit |
16808d |
GList *additions = NULL;
|
|
Packit |
16808d |
int ret = 0;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(list != NULL, -1);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc = list->service;
|
|
Packit |
16808d |
g_return_val_if_fail(srvc != NULL, -1);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
for(; id_list; id_list = id_list->next) {
|
|
Packit |
16808d |
if(list_add(list, id_list->data))
|
|
Packit |
16808d |
additions = g_list_prepend(additions, id_list->data);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/* if the service is alive-- or getting there-- we'll need to send
|
|
Packit |
16808d |
these additions upstream */
|
|
Packit |
16808d |
if(MW_SERVICE_IS_LIVE(srvc) && additions)
|
|
Packit |
16808d |
ret = send_add(srvc->channel, additions);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_list_free(additions);
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int mwAwareList_removeAware(struct mwAwareList *list, GList *id_list) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/* for each awareness id:
|
|
Packit |
16808d |
- if it's not in the list, forget it
|
|
Packit |
16808d |
- remove from the list
|
|
Packit |
16808d |
- remove list from the membership
|
|
Packit |
16808d |
|
|
Packit |
16808d |
- call remove round
|
|
Packit |
16808d |
*/
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwServiceAware *srvc;
|
|
Packit |
16808d |
struct mwAwareIdBlock *id;
|
|
Packit |
16808d |
struct aware_entry *aware;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(list != NULL, -1);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc = list->service;
|
|
Packit |
16808d |
g_return_val_if_fail(srvc != NULL, -1);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
for(; id_list; id_list = id_list->next) {
|
|
Packit |
16808d |
id = id_list->data;
|
|
Packit |
16808d |
aware = list_aware_find(list, id);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(! aware) {
|
|
Packit |
16808d |
g_warning("buddy %s, %s not in list",
|
|
Packit |
16808d |
NSTR(id->user),
|
|
Packit |
16808d |
NSTR(id->community));
|
|
Packit |
16808d |
continue;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
aware->membership = g_list_remove(aware->membership, list);
|
|
Packit |
16808d |
g_hash_table_remove(list->entries, id);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return remove_unused(srvc);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void dismember_aware(gpointer k, struct aware_entry *aware,
|
|
Packit |
16808d |
struct mwAwareList *list) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
aware->membership = g_list_remove(aware->membership, list);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int mwAwareList_removeAllAware(struct mwAwareList *list) {
|
|
Packit |
16808d |
struct mwServiceAware *srvc;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(list != NULL, -1);
|
|
Packit |
16808d |
srvc = list->service;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(srvc != NULL, -1);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/* for each entry, remove the aware list from the service entry's
|
|
Packit |
16808d |
membership collection */
|
|
Packit |
16808d |
if(list->entries) {
|
|
Packit |
16808d |
g_hash_table_foreach(list->entries, (GHFunc) dismember_aware, list);
|
|
Packit |
16808d |
g_hash_table_destroy(list->entries);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return remove_unused(srvc);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
void mwAwareList_setClientData(struct mwAwareList *list,
|
|
Packit |
16808d |
gpointer data, GDestroyNotify clear) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_if_fail(list != NULL);
|
|
Packit |
16808d |
mw_datum_set(&list->client_data, data, clear);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
gpointer mwAwareList_getClientData(struct mwAwareList *list) {
|
|
Packit |
16808d |
g_return_val_if_fail(list != NULL, NULL);
|
|
Packit |
16808d |
return mw_datum_get(&list->client_data);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
void mwAwareList_removeClientData(struct mwAwareList *list) {
|
|
Packit |
16808d |
g_return_if_fail(list != NULL);
|
|
Packit |
16808d |
mw_datum_clear(&list->client_data);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
void mwServiceAware_setStatus(struct mwServiceAware *srvc,
|
|
Packit |
16808d |
struct mwAwareIdBlock *user,
|
|
Packit |
16808d |
struct mwUserStatus *stat) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwAwareSnapshot idb;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_if_fail(srvc != NULL);
|
|
Packit |
16808d |
g_return_if_fail(user != NULL);
|
|
Packit |
16808d |
g_return_if_fail(stat != NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/* just reference the strings. then we don't need to free them */
|
|
Packit |
16808d |
idb.id.type = user->type;
|
|
Packit |
16808d |
idb.id.user = user->user;
|
|
Packit |
16808d |
idb.id.community = user->community;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
idb.group = NULL;
|
|
Packit |
16808d |
idb.online = TRUE;
|
|
Packit |
16808d |
idb.alt_id = NULL;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
idb.status.status = stat->status;
|
|
Packit |
16808d |
idb.status.time = stat->time;
|
|
Packit |
16808d |
idb.status.desc = stat->desc;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
idb.name = NULL;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
status_recv(srvc, &idb);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
const struct mwAwareAttribute *
|
|
Packit |
16808d |
mwServiceAware_getAttribute(struct mwServiceAware *srvc,
|
|
Packit |
16808d |
struct mwAwareIdBlock *user,
|
|
Packit |
16808d |
guint32 key) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct aware_entry *aware;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(srvc != NULL, NULL);
|
|
Packit |
16808d |
g_return_val_if_fail(user != NULL, NULL);
|
|
Packit |
16808d |
g_return_val_if_fail(key != 0x00, NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
aware = aware_find(srvc, user);
|
|
Packit |
16808d |
g_return_val_if_fail(aware != NULL, NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return g_hash_table_lookup(aware->attribs, GUINT_TO_POINTER(key));
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
const char *mwServiceAware_getText(struct mwServiceAware *srvc,
|
|
Packit |
16808d |
struct mwAwareIdBlock *user) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct aware_entry *aware;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(srvc != NULL, NULL);
|
|
Packit |
16808d |
g_return_val_if_fail(user != NULL, NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
aware = aware_find(srvc, user);
|
|
Packit |
16808d |
if(! aware) return NULL;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return aware->aware.status.desc;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|