diff options
Diffstat (limited to 'net-im')
-rw-r--r-- | net-im/meanwhile-gaim/Makefile | 5 | ||||
-rw-r--r-- | net-im/meanwhile-gaim/files/patch-src_mwgaim.c | 1086 |
2 files changed, 1080 insertions, 11 deletions
diff --git a/net-im/meanwhile-gaim/Makefile b/net-im/meanwhile-gaim/Makefile index e9426603fde..44b8142378b 100644 --- a/net-im/meanwhile-gaim/Makefile +++ b/net-im/meanwhile-gaim/Makefile @@ -7,6 +7,7 @@ PORTNAME= meanwhile PORTVERSION= 0.78 +PORTREVISION= 1 CATEGORIES= net MASTER_SITES= ${MASTER_SITE_SOURCEFORGE} MASTER_SITE_SUBDIR= ${PORTNAME} @@ -16,7 +17,7 @@ DISTNAME= ${PORTNAME}${PKGNAMESUFFIX}-${PORTVERSION} MAINTAINER= marcus@FreeBSD.org COMMENT= Provides Lotus Sametime support for Gaim -BUILD_DEPENDS= ${NONEXISTENT}:${PORTSDIR}/net/gaim:configure +BUILD_DEPENDS= ${X11BASE}/include/gaim/config.h:${PORTSDIR}/net/gaim LIB_DEPENDS= meanwhile.0:${PORTSDIR}/net/meanwhile RUN_DEPENDS= gaim:${PORTSDIR}/net/gaim @@ -24,7 +25,7 @@ USE_X_PREFIX= yes USE_GMAKE= yes USE_GNOME= gnomeprefix gnomehack lthack gtk20 USE_LIBTOOL_VER=13 -CONFIGURE_ARGS= --with-gaim-source=${WRKDIRPREFIX}${.CURDIR}/../../net/gaim/work/gaim-${PORTVERSION}/src +CONFIGURE_ARGS= --with-gaim-source=${X11BASE}/include/gaim CONFIGURE_ENV= CPPFLAGS="-I${LOCALBASE}/include" \ LDFLAGS="-L${LOCALBASE}/lib" diff --git a/net-im/meanwhile-gaim/files/patch-src_mwgaim.c b/net-im/meanwhile-gaim/files/patch-src_mwgaim.c index e6aa8438cc8..58a00009e26 100644 --- a/net-im/meanwhile-gaim/files/patch-src_mwgaim.c +++ b/net-im/meanwhile-gaim/files/patch-src_mwgaim.c @@ -1,20 +1,1088 @@ ---- src/mwgaim.c.orig Thu Jun 24 20:55:29 2004 -+++ src/mwgaim.c Thu Jun 24 20:56:30 2004 -@@ -723,11 +723,14 @@ +--- src/mwgaim.c Tue Jun 1 19:29:17 2004 ++++ src/mwgaim.c Wed Jun 23 03:53:08 2004 +@@ -1,24 +1,23 @@ + +-/* +-Meanwhile Gaim Protocol Plugin (prpl). Adds Lotus Sametime support to Gaim. ++/* Meanwhile Gaim Protocol Plugin (prpl). Adds Lotus Sametime support ++to Gaim. + +-Copyright (C) 2004 Christopher (siege) O'Brien <obriencj@us.ibm.com> +-Copyright (C) 2004 IBM Corporation ++Copyright (C) 2004 Christopher (siege) O'Brien <siege@preoccupied.net> + +-This program is free software; you can redistribute it and/or +-modify it under the terms of the GNU General Public License +-as published by the Free Software Foundation; either version 2 +-of the License, or (at your option) any later version. +- +-This program is distributed in the hope that it will be useful, +-but WITHOUT ANY WARRANTY; without even the implied warranty of +-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-GNU General Public License for more details. ++This program is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 2 of the License, or (at ++your option) any later version. ++ ++This program is distributed in the hope that it will be useful, but ++WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software +-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-*/ ++Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, ++USA. */ + + + #define GAIM_PLUGINS +@@ -41,10 +40,75 @@ + #include <meanwhile/srvc_aware.h> + #include <meanwhile/srvc_conf.h> + #include <meanwhile/srvc_im.h> ++#include <meanwhile/srvc_store.h> ++#include <meanwhile/st_list.h> + +-#include "mwgaim.h" ++ ++/* considering that there's no display of this information for prpls, ++ I don't know why I even bother providing these. Oh valiant reader, ++ I do it all for you. */ ++#define PLUGIN_ID "prpl-meanwhile" ++#define PLUGIN_NAME "Meanwhile" ++#define PLUGIN_SUMMARY "Meanwhile Protocol Plugin" ++#define PLUGIN_DESC "Open implementation of a Lotus Sametime client" ++#define PLUGIN_AUTHOR "Christopher (siege) O'Brien <siege@preoccupied.net>" ++#define PLUGIN_HOMEPAGE "http://meanwhile.sf.net/" ++ ++#define MW_CONNECT_STEPS 7 ++#define MW_CONNECT_1 _("Looking up server") ++#define MW_CONNECT_2 _("Sending Handshake") ++#define MW_CONNECT_3 _("Waiting for Handshake Acknowledgement") ++#define MW_CONNECT_4 _("Handshake Acknowledged, Sending Login") ++#define MW_CONNECT_5 _("Waiting for Login Acknowledgement") ++#define MW_CONNECT_6 _("Login Acknowledged") ++ ++#define UC_NORMAL 0x10 ++ ++#define MW_STATE_OFFLINE _("Offline") ++#define MW_STATE_ACTIVE _("Active") ++#define MW_STATE_AWAY _("Away") ++#define MW_STATE_BUSY _("Do Not Disturb") ++#define MW_STATE_IDLE _("Idle") ++#define MW_STATE_UNKNOWN _("Unknown") ++ ++ ++/* keys to get/set chat information */ ++#define CHAT_CREATOR_KEY "chat_creator" ++#define CHAT_NAME_KEY "chat_name" ++#define CHAT_TOPIC_KEY "chat_topic" ++#define CHAT_INVITE_KEY "chat_invite" ++ ++ ++/* keys to get/set gaim plugin information */ ++#define MW_KEY_HOST "server" ++#define MW_KEY_PORT "port" ++ ++ ++/** default host for the gaim plugin. You can specialize a build to ++ default to your server by supplying this at compile time */ ++#ifndef PLUGIN_DEFAULT_HOST ++#define PLUGIN_DEFAULT_HOST "" ++#endif ++ ++ ++/** default port for the gaim plugin. You can specialize a build to ++ default to your server by supplying this at compile time */ ++#ifndef PLUGIN_DEFAULT_PORT ++#define PLUGIN_DEFAULT_PORT 1533 ++#endif ++ ++ ++/** the amount of data the plugin will attempt to read from a socket ++ in a single call */ ++#define READ_BUFFER_SIZE 1024 ++ ++ ++/** default inactivity threshold for the gaim plugin to pass to ++ mwChannel_destroyInactive. length in seconds */ ++#define INACTIVE_THRESHOLD 30 + + ++/* there's probably a better way, I just never bothered finding it */ + #ifndef os_write + # ifndef _WIN32 + # define os_write(fd, buffer, len) write(fd, buffer, len) +@@ -54,6 +118,7 @@ + #endif + + ++/* there's probably a better way, I just never bothered finding it */ + #ifndef os_read + # ifndef _WIN32 + # define os_read(fd, buffer, size) read(fd, buffer, size) +@@ -63,6 +128,7 @@ + #endif + + ++/* there's probably a better way, I just never bothered finding it */ + #ifndef os_close + # ifndef _WIN32 + # define os_close(fd) close(fd) +@@ -72,34 +138,44 @@ + #endif + + +-#define DEBUG_ERROR(a) gaim_debug_error(G_LOG_DOMAIN, a) +-#define DEBUG_INFO(a) gaim_debug_info(G_LOG_DOMAIN, a) +-#define DEBUG_MISC(a) gaim_debug_misc(G_LOG_DOMAIN, a) +-#define DEBUG_WARN(a) gaim_debug_warning(G_LOG_DOMAIN, a) ++#define DEBUG_ERROR(a) gaim_debug_error(G_LOG_DOMAIN, a "\n") ++#define DEBUG_INFO(a) gaim_debug_info(G_LOG_DOMAIN, a "\n") ++#define DEBUG_MISC(a) gaim_debug_misc(G_LOG_DOMAIN, a "\n") ++#define DEBUG_WARN(a) gaim_debug_warning(G_LOG_DOMAIN, a "\n") + + ++/** get the mw_handler from a mwSession */ + #define SESSION_HANDLER(session) \ + ((struct mw_handler *) (session)->handler) + + ++/** get the mw_plugin_data from a GaimConnection */ + #define PLUGIN_DATA(gc) \ + ((struct mw_plugin_data *) (gc)->proto_data) + + ++/** get the mwSession from a GaimConnection */ + #define GC_TO_SESSION(gc) \ + ((PLUGIN_DATA(gc))->session) + + ++/** get the GaimConnection from a mwSession */ + #define SESSION_TO_GC(session) \ + ((SESSION_HANDLER(session))->gc) + + + struct mw_plugin_data { + struct mwSession *session; +- struct mwServiceIM *srvc_im; ++ + struct mwServiceAware *srvc_aware; ++ + struct mwServiceConf *srvc_conf; + ++ struct mwServiceIM *srvc_im; ++ ++ struct mwServiceStorage *srvc_store; ++ ++ GHashTable *list_map; + GHashTable *convo_map; + }; + +@@ -111,33 +187,29 @@ + }; + + +-/* returns 0 if all bytes were written successfully, -1 for any sort of +- failure. */ ++/** returns 0 if all bytes were written successfully, -1 for any sort ++ of failure. */ + static int mw_handler_write(struct mwSessionHandler *this, + const char *b, gsize n) { + + struct mw_handler *h = (struct mw_handler *) this; +- int ret; ++ int ret = 0; + + while(n) { +- /* this looks weird, but it's almost sane. I'm going from an unsigned int +- length to a signed int length. The likely-hood of n ever being that +- large is super-duper-minimal, but I don't like chances. So mask off the +- sign bit and only write that many bytes at a time. The normal write +- loop then continues writing until n is decremented to zero, or os_write +- errors */ +- ret = os_write(h->sock_fd, b, (n & 0xefffffff)); ++ ret = os_write(h->sock_fd, b, n); + if(ret <= 0) break; + n -= ret; + } + +- if( (ret = n) ) { ++ if(n > 0) { ++ /* if there's data left over, something must have failed */ + gaim_debug_error(G_LOG_DOMAIN, "mw_handler_write returning %i\n", ret); + gaim_connection_error(h->gc, "Connection died"); +- ret = -1; +- } ++ return -1; + +- return ret; ++ } else { ++ return 0; ++ } + } + + +@@ -169,18 +241,18 @@ + char buf[READ_BUFFER_SIZE]; + int len = READ_BUFFER_SIZE; + ++ /* note, don't use gsize. len might be -1 */ ++ + len = os_read(h->sock_fd, buf, len); + if(len > 0) { +- gaim_debug_info("meanwhile", "reading %u bytes\n", len); ++ gaim_debug_info(G_LOG_DOMAIN, "read %i bytes\n", len); + mwSession_recv(session, buf, (unsigned int) len); +- +- } else { +- gaim_connection_destroy(gc); ++ return; + } +- +- } else { +- gaim_connection_destroy(gc); + } ++ ++ /* fall-through indicates an error */ ++ gaim_connection_destroy(gc); + } + + +@@ -191,18 +263,14 @@ + struct mwSession *session = GC_TO_SESSION(gc); + struct mw_handler *h; + +- DEBUG_INFO(" --> mw_login_callback\n"); +- + if(! g_list_find(gaim_connections_get_all(), data)) { + os_close(source); +- DEBUG_INFO(" <-- mw_login_callback (connection not found)\n"); +- return; ++ g_return_if_reached(); + } + + if(source < 0) { + gaim_connection_error(gc, "Unable to connect"); +- DEBUG_ERROR(" unable to connect in mw_login_callback\n"); +- DEBUG_INFO(" <-- mw_login_callback (unable to connect)\n"); ++ DEBUG_ERROR(" unable to connect in mw_login_callback"); + return; + } + +@@ -211,9 +279,7 @@ + session->handler = (struct mwSessionHandler *) h; + + gc->inpa = gaim_input_add(source, GAIM_INPUT_READ, mw_read_callback, gc); +- mwSession_initConnect(session); +- +- DEBUG_INFO(" <-- mw_login_callback\n"); ++ mwSession_start(session); + } + + +@@ -224,13 +290,14 @@ + g_return_if_fail(s); + + if(mw_handler_write(s->handler, &c, 1)) { +- DEBUG_WARN("looks like keepalive byte failed\n"); ++ DEBUG_WARN("looks like keepalive byte failed"); + + } else { +- /* close any OPEN or WAIT channels which have been inactive for +- at least the INACTIVE_THRESHOLD seconds, but only if we're +- still connected. */ +- mwChannelSet_destroyInactive(s->channels, time(NULL) - INACTIVE_THRESHOLD); ++ /* close any OPEN or WAIT channels which have been inactive for at ++ least the INACTIVE_THRESHOLD seconds, but only if we're still ++ connected. */ ++ mwChannelSet_destroyInactive(s->channels, ++ time(NULL) - INACTIVE_THRESHOLD); + } + } + +@@ -238,19 +305,15 @@ + static void on_initConnect(struct mwSession *s) { + GaimConnection *gc = SESSION_TO_GC(s); + +- DEBUG_INFO(" --> on_initConnect\n"); + gaim_connection_update_progress(gc, MW_CONNECT_2, 2, MW_CONNECT_STEPS); +- initConnect_sendHandshake(s); +- DEBUG_INFO(" <-- on_initConnect\n"); ++ onStart_sendHandshake(s); + } + + + static void on_handshake(struct mwSession *s, struct mwMsgHandshake *msg) { + GaimConnection *gc = SESSION_TO_GC(s); + +- DEBUG_INFO(" --> on_handshake\n"); + gaim_connection_update_progress(gc, MW_CONNECT_3, 3, MW_CONNECT_STEPS); +- DEBUG_INFO(" <-- on_handshake\n"); + } + + +@@ -259,100 +322,186 @@ + + GaimConnection *gc = SESSION_TO_GC(s); + +- DEBUG_INFO(" --> on_handshakeAck\n"); + gaim_connection_update_progress(gc, MW_CONNECT_4, 4, MW_CONNECT_STEPS); +- handshakeAck_sendLogin(s, msg); +- DEBUG_INFO(" <-- on_handshakeAck\n"); ++ onHandshakeAck_sendLogin(s, msg); + } + + + static void on_login(struct mwSession *s, struct mwMsgLogin *msg) { + GaimConnection *gc = SESSION_TO_GC(s); + +- DEBUG_INFO(" --> on_login\n"); + gaim_connection_update_progress(gc, MW_CONNECT_5, 5, MW_CONNECT_STEPS); +- DEBUG_INFO(" <-- on_login\n"); ++} ++ ++ ++static GaimGroup *ensure_group(GaimConnection *gc, ++ struct mwSametimeGroup *stgroup) { ++ GaimGroup *group; ++ const char *name = mwSametimeGroup_getName(stgroup); ++ ++ group = gaim_find_group(name); ++ if(! group) { ++ group = gaim_group_new(name); ++ gaim_blist_add_group(group, NULL); ++ } ++ ++ return group; ++} ++ ++ ++static GaimBuddy *ensure_buddy(GaimConnection *gc, GaimGroup *group, ++ struct mwSametimeUser *stuser) { ++ ++ GaimBuddy *buddy; ++ ++ GaimAccount *acct = gaim_connection_get_account(gc); ++ ++ const char *name = mwSametimeUser_getUser(stuser); ++ const char *alias = mwSametimeUser_getAlias(stuser); ++ ++ buddy = gaim_find_buddy_in_group(acct, name, group); ++ if(! buddy) { ++ buddy = gaim_buddy_new(acct, name, alias); ++ gaim_blist_add_buddy(buddy, NULL, group, NULL); ++ ++ } ++ ++ return buddy; ++} ++ ++ ++static void import_blist(GaimConnection *gc, struct mwSametimeList *stlist) { ++ struct mwSametimeGroup *stgroup; ++ struct mwSametimeUser *stuser; ++ ++ GaimGroup *group; ++ GaimBuddy *buddy; ++ ++ GList *gl, *gtl, *ul, *utl; ++ ++ gl = gtl = mwSametimeList_getGroups(stlist); ++ for(; gl; gl = gl->next) { ++ ++ stgroup = (struct mwSametimeGroup *) gl->data; ++ group = ensure_group(gc, stgroup); ++ ++ ul = utl = mwSametimeGroup_getUsers(stgroup); ++ for(; ul; ul = ul->next) { ++ ++ stuser = (struct mwSametimeUser *) ul->data; ++ buddy = ensure_buddy(gc, group, stuser); ++ } ++ g_list_free(utl); ++ } ++ g_list_free(gtl); ++} ++ ++ ++static void storage_load_cb(struct mwServiceStorage *srvc, guint result, ++ struct mwStorageUnit *item, gpointer dat) { ++ ++ struct mwSametimeList *stlist; ++ char *b, *tmp; ++ gsize n; ++ ++ g_message(" storage_cb, key = 0x%08x, result = 0x%08x, length = 0x%08x", ++ item->key, result, item->data.len); ++ ++ if(result) return; ++ ++ b = tmp = mwStorageUnit_asString(item); ++ n = strlen(b); ++ ++ if(! n) return; ++ ++ stlist = mwSametimeList_new(); ++ mwSametimeList_get(&b, &n, stlist); ++ ++ import_blist(SESSION_TO_GC(mwService_getSession(MW_SERVICE(srvc))), stlist); ++ ++ mwSametimeList_free(stlist); ++ ++ /* no need to free the storage unit, that will happen automatically ++ after this callback */ ++ g_free(tmp); ++} ++ ++ ++static void fetch_blist(struct mwServiceStorage *srvc) { ++ struct mwStorageUnit *unit = mwStorageUnit_new(mwStore_AWARE_LIST); ++ mwServiceStorage_load(srvc, unit, storage_load_cb, NULL); + } + + + static void on_loginAck(struct mwSession *s, struct mwMsgLoginAck *msg) { + GaimConnection *gc = SESSION_TO_GC(s); +- /* struct mwUserStatus stat = { mwStatus_ACTIVE, 0, NULL }; */ ++ struct mw_plugin_data *pd = (struct mw_plugin_data *) gc->proto_data; + +- DEBUG_INFO(" --> on_loginAck\n"); + gaim_connection_update_progress(gc, MW_CONNECT_6, 6, MW_CONNECT_STEPS); +- +- DEBUG_INFO(" 1\n"); + gaim_connection_set_state(gc, GAIM_CONNECTED); +- +- DEBUG_INFO(" 2\n"); + serv_finish_login(gc); + +- /* Have to do this. Would be nicer if this happened in the session +- code. */ +- /* DEBUG_INFO(" 3\n"); +- mwSession_setUserStatus(s, &stat); */ ++ /* later this won't be necessary, as the session will auto-start ++ services on receipt of the service available message */ + +- DEBUG_INFO(" <-- on_loginAck\n"); ++ mwService_start(MW_SERVICE(pd->srvc_conf)); ++ mwService_start(MW_SERVICE(pd->srvc_im)); ++ ++ mwService_start(MW_SERVICE(pd->srvc_store)); ++ fetch_blist(pd->srvc_store); ++ ++ /* do this last, otherwise the storage stuff won't receive initial ++ presence notification */ ++ mwService_start(MW_SERVICE(pd->srvc_aware)); + } + + + static void on_closeConnect(struct mwSession *session, guint32 reason) { +- + GaimConnection *gc; + +- DEBUG_INFO(" --> on_closeConnect\n"); ++ g_return_if_fail(SESSION_HANDLER(session)); + +- if(SESSION_HANDLER(session)) { +- gc = SESSION_TO_GC(session); +- if(! gc) return; +- +- if(reason & ERR_FAILURE) { +- gchar *text = mwError(reason); +- gaim_connection_error(gc, text); +- g_free(text); +- +- } else if(gc->inpa) { +- /* remove the input checker, so that closing the socket won't be +- seen as an error, and won't trigger a re-connect */ +- gaim_input_remove(gc->inpa); +- gc->inpa = 0; +- } +- } ++ gc = SESSION_TO_GC(session); ++ g_return_if_fail(gc); + +- DEBUG_INFO(" <-- on_closeConnect\n"); ++ if(reason & ERR_FAILURE) { ++ gchar *text = mwError(reason); ++ gaim_connection_error(gc, text); ++ g_free(text); ++ ++ } else if(gc->inpa) { ++ /* remove the input checker, so that closing the socket won't be ++ seen as an error, and won't trigger a re-connect */ ++ gaim_input_remove(gc->inpa); ++ gc->inpa = 0; ++ } + } + + + static void on_setUserStatus(struct mwSession *s, + struct mwMsgSetUserStatus *msg) { + +- /* this plugin allows the user to add themselves to their buddy list. the +- server's aware service doesn't always honor that by sending updates back +- to us. so we're going to ensure our status is updated by passing it back +- to the aware service when we receive a SetUserStatus message */ ++ /* this plugin allows the user to add themselves to their buddy ++ list. the server's aware service doesn't always honor that by ++ sending updates back to us. so we're going to ensure our status ++ is updated by passing it back to the aware service when we ++ receive a SetUserStatus message */ + + GaimConnection *gc = SESSION_TO_GC(s); + struct mw_plugin_data *pd = PLUGIN_DATA(gc); + struct mwServiceAware *srvc = pd->srvc_aware; + + struct mwAwareIdBlock id = { mwAware_USER, +- s->login.user_id, s->login.community }; ++ s->login.user_id, ++ s->login.community }; + + mwServiceAware_setStatus(srvc, &id, &msg->status); + } + + + static void on_admin(struct mwSession *s, struct mwMsgAdmin *msg) { +- DEBUG_INFO(" admin message:\n"); +- DEBUG_INFO(msg->text); +- +- gaim_connection_notice(SESSION_TO_GC(s), msg->text); +- +- /* + gaim_notify_message(SESSION_TO_GC(s), GAIM_NOTIFY_MSG_INFO, + _("Admin Alert"), msg->text, NULL, NULL, NULL); +- */ + } + + +@@ -387,30 +536,32 @@ + + + static void got_typing(struct mwServiceIM *srvc, +- struct mwIdBlock *who, int typing) { ++ struct mwIdBlock *who, gboolean typing) { + + /* if user@community split, compose buddy name */ + + struct mwSession *s = srvc->service.session; + +- if(typing) ++ if(typing) { + serv_got_typing(SESSION_TO_GC(s), who->user, 0, GAIM_TYPING); +- else +- serv_got_typing_stopped(SESSION_TO_GC(s), who->user); ++ } else { ++ serv_got_typing_stopped(SESSION_TO_GC(s), who->user); ++ } + } + + +-static void update_buddy(struct mwSession *s, +- struct mwSnapshotAwareIdBlock *idb) { +- +- GaimConnection *gc = SESSION_TO_GC(s); ++static void got_aware(struct mwAwareList *list, ++ struct mwSnapshotAwareIdBlock *idb, gpointer data) { + ++ GaimConnection *gc = (GaimConnection *) data; + time_t idle = 0; +- /* unsigned int i = idb->status.time; */ + +- /* deadbeef or 0 from the client means not idle (unless the status indicates +- otherwise), but deadbeef to the blist causes idle with no time */ ++ /* deadbeef or 0 from the client means not idle (unless the status ++ indicates otherwise), but deadbeef to the blist causes idle with ++ no time */ + /* ++ unsigned int i = idb->status.time; ++ + if( (idb->status.status == mwStatus_IDLE) || + ((i > 0) && (i != 0xdeadbeef)) ) { + +@@ -418,7 +569,7 @@ + } + */ + +- /* over-riding idle times until fixed in a later release */ ++ /* idle times unused until fixed in a later release */ + if(idb->status.status == mwStatus_IDLE) + idle = -1; + +@@ -427,28 +578,19 @@ + } + + +-static void got_aware(struct mwServiceAware *srvc, +- struct mwSnapshotAwareIdBlock *idb, unsigned int c) { +- +- struct mwSession *s = srvc->service.session; +- while(c--) update_buddy(s, idb + c); +-} +- +- + static void got_invite(struct mwConference *conf, struct mwIdBlock *id, + const char *text) { + + GaimConnection *gc; + GHashTable *ht; + +- /* the trick here is that we want these strings cleaned up when we're done, +- but not until then. When we return, the originals will be cleaned up. The +- copies are in the hash table, so when the hash table goes, they'll be +- free'd too. Just don't try to free the keys */ ++ /* the trick here is that we want these strings cleaned up when ++ we're done, but not until then. When we return, the originals ++ will be cleaned up. The copies are in the hash table, so when the ++ hash table goes, they'll be free'd too. Just don't try to free ++ the keys */ + char *a, *b, *c, *d; + +- DEBUG_INFO(" --> got invite\n"); +- + gc = SESSION_TO_GC(conf->channel->session); + ht = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free); + +@@ -462,14 +604,12 @@ + g_hash_table_insert(ht, CHAT_TOPIC_KEY, c); + g_hash_table_insert(ht, CHAT_INVITE_KEY, d); + +- gaim_debug_info("meanwhile", +- "invitor: '%s', name: '%s', topic: '%s', text: '%s'\n", ++ gaim_debug_info(G_LOG_DOMAIN, ++ "Got invite: '%s', name: '%s', topic: '%s', text: '%s'\n", + a, b, c, d); + +- DEBUG_INFO(" triggering serv_got_invite\n"); ++ DEBUG_INFO(" triggering serv_got_invite"); + serv_got_chat_invite(gc, c, a, d, ht); +- +- DEBUG_INFO(" <-- got invite\n"); + } + + +@@ -480,7 +620,7 @@ + struct mw_plugin_data *pd = PLUGIN_DATA(gc); + GaimConversation *conv; + +- DEBUG_INFO(" got welcome\n"); ++ DEBUG_INFO(" got welcome"); + + conv = serv_got_joined_chat(gc, conf->channel->id, conf->topic); + gaim_conv_chat_set_id(GAIM_CONV_CHAT(conv), conf->channel->id); +@@ -500,7 +640,7 @@ + struct mw_plugin_data *pd = PLUGIN_DATA(gc); + GaimConversation *conv; + +- DEBUG_INFO(" got closed\n"); ++ DEBUG_INFO(" got closed"); + + conv = (GaimConversation *) g_hash_table_lookup(pd->convo_map, conf); + +@@ -516,10 +656,10 @@ + GaimConversation *conv; + + conv = (GaimConversation *) g_hash_table_lookup(pd->convo_map, conf); +- if(conv) { +- DEBUG_INFO(" got join\n"); +- gaim_conv_chat_add_user(GAIM_CONV_CHAT(conv), id->user, NULL); +- } ++ g_return_if_fail(conv); ++ ++ DEBUG_INFO(" got join"); ++ gaim_conv_chat_add_user(GAIM_CONV_CHAT(conv), id->user, NULL); + } + + +@@ -529,10 +669,10 @@ + GaimConversation *conv; + + conv = (GaimConversation *) g_hash_table_lookup(pd->convo_map, conf); +- if(conv) { +- DEBUG_INFO(" got part\n"); +- gaim_conv_chat_remove_user(GAIM_CONV_CHAT(conv), id->user, NULL); +- } ++ g_return_if_fail(conv); ++ ++ DEBUG_INFO(" got part"); ++ gaim_conv_chat_remove_user(GAIM_CONV_CHAT(conv), id->user, NULL); + } + + +@@ -544,18 +684,17 @@ + GaimConversation *conv; + + conv = (GaimConversation *) g_hash_table_lookup(pd->convo_map, conf); +- if(conv) { +- gaim_debug_info("meanwhile", " got conf text: '%s'\n", text); +- serv_got_chat_in(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(conv)), +- id->user, 0, text, time(NULL)); +- } ++ g_return_if_fail(conv); ++ ++ serv_got_chat_in(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(conv)), ++ id->user, 0, text, time(NULL)); + } + + + static void got_conf_typing(struct mwConference *conf, struct mwIdBlock *id, +- int typing) { ++ gboolean typing) { + +- /* no gaim support for this?? oh no! */ ++ ; /* no gaim support for this?? oh no! */ + } + + +@@ -567,11 +706,12 @@ + struct mwServiceAware *srvc_aware; + struct mwServiceIM *srvc_im; + struct mwServiceConf *srvc_conf; ++ struct mwServiceStorage *srvc_store; + + const char *host; + unsigned int port; + +- DEBUG_INFO(" --> mw_login\n"); ++ DEBUG_INFO(" --> mw_login"); + + gc->proto_data = pd = g_new0(struct mw_plugin_data, 1); + +@@ -581,31 +721,25 @@ + session->on_handshakeAck = on_handshakeAck; + session->on_login = on_login; + session->on_loginAck = on_loginAck; +- session->on_initConnect = on_initConnect; +- session->on_closeConnect = on_closeConnect; ++ session->on_start = on_initConnect; ++ session->on_stop = on_closeConnect; + session->on_setUserStatus = on_setUserStatus; + session->on_admin = on_admin; + +- /* user_id, community */ ++ /* user_id, password */ + session->login.user_id = g_strdup(gaim_account_get_username(acct)); +- /* session->login.community = +- g_strdup(gaim_account_get_string(acct, MW_KEY_COMMUNITY, +- PLUGIN_DEFAULT_COMMUNITY)); */ +- +- /* password */ + session->auth.password = g_strdup(gaim_account_get_password(acct)); + + /* aware service and call-backs */ + pd->srvc_aware = srvc_aware = mwServiceAware_new(session); +- srvc_aware->got_aware = got_aware; +- mwSession_putService(session, (struct mwService *) srvc_aware); ++ mwSession_putService(session, MW_SERVICE(srvc_aware)); + + /* im service and call-backs */ + pd->srvc_im = srvc_im = mwServiceIM_new(session); + srvc_im->got_error = got_error; + srvc_im->got_text = got_text; + srvc_im->got_typing = got_typing; +- mwSession_putService(session, (struct mwService *) srvc_im); ++ mwSession_putService(session, MW_SERVICE(srvc_im)); + + /* conference service and call-backs */ + pd->srvc_conf = srvc_conf = mwServiceConf_new(session); +@@ -616,9 +750,14 @@ + srvc_conf->got_part = got_part; + srvc_conf->got_text = got_conf_text; + srvc_conf->got_typing = got_conf_typing; +- mwSession_putService(session, (struct mwService *) srvc_conf); ++ mwSession_putService(session, MW_SERVICE(srvc_conf)); + + pd->convo_map = g_hash_table_new(NULL, NULL); ++ pd->list_map = g_hash_table_new(NULL, NULL); ++ ++ /* storage service */ ++ pd->srvc_store = srvc_store = mwServiceStorage_new(session); ++ mwSession_putService(session, MW_SERVICE(srvc_store)); + + /* server:port */ + host = gaim_account_get_string(acct, "server", PLUGIN_DEFAULT_HOST); +@@ -629,7 +768,7 @@ + if(gaim_proxy_connect(acct, host, port, mw_login_callback, gc)) + gaim_connection_error(gc, "Unable to connect"); + +- DEBUG_INFO(" <-- mw_login\n"); ++ DEBUG_INFO(" <-- mw_login"); + } + + +@@ -637,26 +776,24 @@ + struct mwSession *session; + struct mw_plugin_data *pd = PLUGIN_DATA(gc); + +- DEBUG_INFO(" --> mw_close\n"); +- +- if(pd) { +- session = GC_TO_SESSION(gc); ++ g_return_if_fail(pd != NULL); + +- if(session) { +- mwSession_closeConnect(session, ERR_SUCCESS); ++ session = pd->session; ++ if(session) { ++ mwSession_stop(session, ERR_SUCCESS); + +- /* we created it, so we need to clean it up */ +- g_free(session->handler); +- session->handler = NULL; +- mwSession_free(&session); +- } ++ mwService_free(MW_SERVICE(pd->srvc_aware)); ++ mwService_free(MW_SERVICE(pd->srvc_conf)); ++ mwService_free(MW_SERVICE(pd->srvc_im)); ++ mwService_free(MW_SERVICE(pd->srvc_store)); + +- gc->proto_data = NULL; +- g_hash_table_destroy(pd->convo_map); +- g_free(pd); ++ g_free(session->handler); ++ mwSession_free(session); + } + +- DEBUG_INFO(" <-- mw_close\n"); ++ gc->proto_data = NULL; ++ g_hash_table_destroy(pd->convo_map); ++ g_free(pd); + } + + +@@ -669,6 +806,9 @@ + careful to center it. Then, just change the color saturation to + bring the red down a bit, and voila! */ + ++ /* then, throw all of that away and use sodipodi to make a new ++ icon. You know, LIKE A REAL MAN. */ ++ + return "meanwhile"; + } + +@@ -723,12 +863,13 @@ static char *mw_list_status_text(GaimBuddy *b) { -+ struct mw_plugin_data *pd; -+ struct mwIdBlock i = { b->name, NULL }; +- g_return_val_if_fail(b, NULL); ++ GaimConnection *gc = b->account->gc; ++ struct mw_plugin_data *pd = PLUGIN_DATA(gc); ++ struct mwAwareIdBlock i = { mwAware_USER, b->name, NULL }; + const char *t; -+ - g_return_val_if_fail(b, NULL); - struct mw_plugin_data *pd = PLUGIN_DATA(b->account->gc); - struct mwIdBlock i = { b->name, NULL }; - const char *t = mwServiceAware_getText(pd->srvc_aware, &i); -+ pd = PLUGIN_DATA(b->account->gc); +- return t? g_strdup(t): NULL; + t = mwServiceAware_getText(pd->srvc_aware, &i); - return t? g_strdup(t): NULL; ++ return t ? g_strdup(t) : NULL; } + +@@ -736,7 +877,7 @@ + GaimConnection *gc = b->account->gc; + struct mw_plugin_data *pd = PLUGIN_DATA(gc); + +- struct mwIdBlock t = { b->name, NULL }; ++ struct mwAwareIdBlock t = { mwAware_USER, b->name, NULL }; + + char *stat, *ret; + stat = mw_status_text(b); +@@ -773,9 +914,10 @@ + + mwUserStatus_clone(&stat, &s->status); + +- /* re-reading the specification, this is incorrect. It should be the count +- of minutes since last action. In order to fix this, I am going to turn +- off all idle-time reporting for the next meanwhile version. */ ++ /* re-reading the specification, this is incorrect. It should be the ++ count of minutes since last action. In order to fix this, I am ++ going to turn off all idle-time reporting for the next meanwhile ++ version. */ + + /* stat.time = (t > 0)? time(NULL) - t: 0; */ + +@@ -815,12 +957,12 @@ + mwUserStatus_clone(&stat, &s->status); + + if(state != NULL) { +- /* when we go to/from a standard state, the state indicates whether we're +- away or not */ ++ /* when we go to/from a standard state, the state indicates ++ whether we're away or not */ + + if(! strcmp(state, GAIM_AWAY_CUSTOM)) { +- /* but when we go to/from a custom state, then it's the message which +- indicates whether we're away or not */ ++ /* but when we go to/from a custom state, then it's the message ++ which indicates whether we're away or not */ + + if(message != NULL) { + stat.status = mwStatus_AWAY; +@@ -877,61 +1019,47 @@ + } + + +-static void mw_add_buddy(GaimConnection *gc, const char *name, +- GaimGroup *group) { ++static struct mwAwareList *ensure_list(GaimConnection *gc, GaimGroup *group) { + + struct mw_plugin_data *pd = PLUGIN_DATA(gc); ++ struct mwAwareList *list; + +- /* later support name@community splits */ +- struct mwIdBlock t = { (char *) name, NULL }; ++ list = (struct mwAwareList *) g_hash_table_lookup(pd->list_map, group); ++ if(! list) { + +- mwServiceAware_add(pd->srvc_aware, &t, 1); ++ g_message("creating aware list for group %s", group->name); ++ list = mwAwareList_new(pd->srvc_aware); ++ mwAwareList_setOnAware(list, got_aware, gc); ++ g_hash_table_replace(pd->list_map, group, list); ++ } ++ ++ return list; + } + + +-static void mw_add_buddies(GaimConnection *gc, GList *buddies) { +- struct mw_plugin_data *pd = PLUGIN_DATA(gc); +- unsigned int count, c; +- struct mwIdBlock *t; ++static void mw_add_buddy(GaimConnection *gc, ++ GaimBuddy *buddy, GaimGroup *group) { + +- count = g_list_length(buddies); +- t = g_new0(struct mwIdBlock, count); ++ struct mwAwareIdBlock t = { mwAware_USER, (char *) buddy->name, NULL }; ++ struct mwAwareList *list; + +- for(c = count; c--; buddies = buddies->next) +- (t + c)->user = (char *) buddies->data; +- +- mwServiceAware_add(pd->srvc_aware, t, count); +- g_free(t); ++ GaimGroup *found = gaim_find_buddys_group(buddy); ++ list = ensure_list(gc, found); ++ ++ mwAwareList_addAware(list, &t, 1); + } + + + static void mw_remove_buddy(GaimConnection *gc, +- const char *name, const char *group) { ++ GaimBuddy *buddy, GaimGroup *group) { + +- struct mw_plugin_data *pd = PLUGIN_DATA(gc); +- +- /* later support name@community splits */ +- struct mwIdBlock t = { (char *) name, NULL }; +- +- mwServiceAware_remove(pd->srvc_aware, &t, 1); +-} +- ++ struct mwAwareIdBlock t = { mwAware_USER, (char *) buddy->name, NULL }; ++ struct mwAwareList *list = ensure_list(gc, group); + +-static void mw_remove_buddies(GaimConnection *gc, GList *buddies, +- const char *group) { ++ GaimGroup *found = gaim_find_buddys_group(buddy); ++ list = ensure_list(gc, found); + +- struct mw_plugin_data *pd = PLUGIN_DATA(gc); +- unsigned int count, c; +- struct mwIdBlock *t; +- +- count = g_list_length(buddies); +- t = g_new0(struct mwIdBlock, count); +- +- for(c = count; c--; buddies = buddies->next) +- (t + c)->user = (char *) buddies->data; +- +- mwServiceAware_remove(pd->srvc_aware, t, count); +- g_free(t); ++ mwAwareList_removeAware(list, &t, 1); + } + + +@@ -958,13 +1086,13 @@ + char *name = g_hash_table_lookup(components, CHAT_NAME_KEY); + + if(name) { +- DEBUG_INFO(" accepting conference invite\n"); ++ DEBUG_INFO(" accepting conference invite"); + conf = mwConference_findByName(srvc, name); + if(conf) mwConference_accept(conf); + + } else { + char *topic; +- DEBUG_INFO(" creating new conference\n"); ++ DEBUG_INFO(" creating new conference"); + + topic = (char *) g_hash_table_lookup(components, CHAT_TOPIC_KEY); + conf = mwConference_new(srvc); +@@ -972,7 +1100,7 @@ + mwConference_create(conf); + } + +- DEBUG_INFO(" ... leaving mw_chat_join\n"); ++ DEBUG_INFO(" ... leaving mw_chat_join"); + } + + +@@ -1029,9 +1157,10 @@ + + static GaimPluginProtocolInfo prpl_info = { + GAIM_PRPL_API_VERSION, /* options */ +- 0, /* flags? */ ++ 0, /* flags */ + NULL, + NULL, ++ NO_BUDDY_ICONS, /* icon spec */ + mw_blist_icon, + mw_blist_emblems, + mw_list_status_text, +@@ -1049,9 +1178,9 @@ + mw_set_idle, + NULL, /* change password, */ + mw_add_buddy, +- mw_add_buddies, ++ NULL, /* mw_add_buddies, */ + mw_remove_buddy, +- mw_remove_buddies, ++ NULL, /* mw_remove_buddies, */ + NULL, /* mw_add_permit, */ + NULL, /* mw_add_deny, */ + NULL, /* mw_rem_permit, */ +@@ -1107,7 +1236,7 @@ + NULL, /**< ui_info */ + &prpl_info, /**< extra_info */ + NULL, /**< prefs info */ +- NULL ++ NULL /**< actions */ + }; + + +@@ -1121,16 +1250,11 @@ + opt = gaim_account_option_int_new("Port", MW_KEY_PORT, PLUGIN_DEFAULT_PORT); + prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, opt); + +- /* +- opt = gaim_account_option_string_new("Community", MW_KEY_COMMUNITY, +- PLUGIN_DEFAULT_COMMUNITY); +- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, opt); +- */ +- + meanwhile_plugin = plugin; + } + + +-GAIM_INIT_PLUGIN(meanwhile, init_plugin, info) ++GAIM_INIT_PLUGIN(meanwhile, init_plugin, info); + + ++/* The End. */ |