# HG changeset patch # User Eric Warmenhoven # Date 977228505 0 # Node ID 338b8ac6bdabd156ec9cc8b815b8b235905a2915 # Parent 035945fca2d522b04a9ff9c0a8d08d39b3032f58 [gaim-migrate @ 1321] lots of changes to the build process. plugins and libfaim don't compile with things they probably won't need. jabber got added, for real, instead of just in cvs. hopefully now i can get it working committer: Tailor Script diff -r 035945fca2d5 -r 338b8ac6bdab ChangeLog --- a/ChangeLog Tue Dec 19 10:23:23 2000 +0000 +++ b/ChangeLog Tue Dec 19 12:21:45 2000 +0000 @@ -1,8 +1,10 @@ GAIM: The Pimpin' Penguin IM Clone thats good for the soul! -version 0.11.0: +version 0.11.0-pre4: * ICQ upgraded to use icqlib 1.1.0 * An enormous amount of bug fixes + * Even More Protocol Plugins: + Jabber (plugins/jabber) [CVS - currently disabled] version 0.11.0-pre3 (12/15/2000): * Away messages arranged alphabetically (Thanks Justin) diff -r 035945fca2d5 -r 338b8ac6bdab STATUS --- a/STATUS Tue Dec 19 10:23:23 2000 +0000 +++ b/STATUS Tue Dec 19 12:21:45 2000 +0000 @@ -1,4 +1,4 @@ -STATUS of GAIM CVS tree. Last modified $Date: 2000-12-14 14:40:47 -0500 (Thu, 14 Dec 2000) $ by $Author: robflynn $. +STATUS of GAIM CVS tree. Last modified $Date: 2000-12-19 07:21:45 -0500 (Tue, 19 Dec 2000) $ by $Author: warmenhoven $. This file is meant to provide gaim users who use the CVS version to see whether they actually want to compile what they just checked out. Gaim CVS is usually @@ -115,3 +115,11 @@ sending/receiving messages, and receiving URLs. Keepalives are sent regardless of whether or not you want them; it's necessary since it's a UDP protocol. Chat and file transfer are planned but not yet implemented. + + +Jabber +====== + +Um, Jabber can't do much yet. I don't even remember what it can do; I didn't +write it, Adam of libfaim did. I just wanted to get it added; hopefully it'll +be ready before 0.11.0 is finished. diff -r 035945fca2d5 -r 338b8ac6bdab configure.in --- a/configure.in Tue Dec 19 10:23:23 2000 +0000 +++ b/configure.in Tue Dec 19 12:21:45 2000 +0000 @@ -1,7 +1,7 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(src/aim.c) AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE([gaim], [0.11.0pre3]) +AM_INIT_AUTOMAKE([gaim], [0.11.0pre4]) dnl Checks for programs. AM_PROG_LIBTOOL @@ -46,7 +46,8 @@ AM_CONDITIONAL(GNOMEAPPLET, test "x$enable_panel" = "xyes") AC_ARG_ENABLE(esd, [ --disable-esd Turn off ESD (default=auto)],,enable_esd=yes) AC_ARG_ENABLE(nas, [ --enable-nas Enable NAS (Network Audio System) support],,enable_nas=no) -AC_ARG_ENABLE(plugins, [ --disable-plugins compile with out plugin support],,enable_plugins=yes) +AC_ARG_ENABLE(plugins, [ --disable-plugins compile without plugin support],,enable_plugins=yes) +AC_ARG_ENABLE(jabber, [ --enable-jabber compile the jabber plugin (requires libxode and libjabber)],,enable_jabber=no) AC_ARG_ENABLE(perl, [ --disable-perl compile without perl scripting],,enable_perl=yes) AC_ARG_ENABLE(debug, [ --enable-debug compile with debugging support],,enable_debug=no) AC_ARG_ENABLE(screensaver, [ --disable-screensaver compile without X screensaver extension],,enable_xss=yes) @@ -58,9 +59,6 @@ AC_DEFINE(DEBUG) fi -CFLAGS="$CFLAGS -I\$(top_srcdir)/libfaim -I\$(top_srcdir)/libfaim/faim" -LDADD="$LDADD -L../libfaim -lfaim" - if test "x$enable_gnome" = "xyes" ; then if test "x$enable_panel" = "xyes" ; then GNOME_INIT(gnomeui applets) @@ -95,7 +93,6 @@ fi fi fi -AM_CONDITIONAL(GNOMEBITS, test "x$enable_gnome" = "xyes") if test "x$enable_gnome" != "xyes" ; then AM_PATH_GLIB(1.2.0) @@ -116,30 +113,18 @@ #include ],[],[],[ AC_DEFINE(USE_SCREENSAVER) - LIBS="$LIBS $XSS_LIBS" + AC_SUBST(XSS_LIBS) ]) else - XSS_LIBS="" + XSS_LIBS=no fi else - XSS_LIBS="" + XSS_LIBS=no fi -if test "x$enable_multi" != "xyes" ; then - AC_DEFINE(NO_MULTI) -fi - -if test "x$enable_plugins" = xyes ; then - dnl checks for icqlib - AC_CHECK_HEADERS(asm/byteorder.h byteswap.h endian.h machine/endian.h arpa/nameser_compat.h) - AC_CHECK_FUNCS(bswap_32 bswap_16) - - AC_DEFINE(GAIM_PLUGINS) -fi - dnl This was taken straight from X-Chat. dnl X-Chat is the greatest application ever, not only dnl because it's a rocking IRC client but also because @@ -153,17 +138,17 @@ AC_MSG_RESULT([not found, building without perl.]) enable_perl = no else - PERL_LDFLAGS=`$perlpath -MExtUtils::Embed -e ldopts 2>/dev/null |$sedpath 's/-lgdbm //'` - PERL_LDFLAGS=`echo $PERL_LDFLAGS |$sedpath 's/-ldb //'` - PERL_LDFLAGS=`echo $PERL_LDFLAGS |$sedpath 's/-lndbm //'` + PERL_LIBS=`$perlpath -MExtUtils::Embed -e ldopts 2>/dev/null |$sedpath 's/-lgdbm //'` + PERL_LIBS=`echo $PERL_LIBS |$sedpath 's/-ldb //'` + PERL_LIBS=`echo $PERL_LIBS |$sedpath 's/-lndbm //'` if test "$system" = "Linux"; then - PERL_LDFLAGS=`echo $PERL_LDFLAGS |$sedpath 's/-lnsl //'` - PERL_LDFLAGS=`echo $PERL_LDFLAGS |$sedpath 's/-lposix //'` + PERL_LIBS=`echo $PERL_LIBS |$sedpath 's/-lnsl //'` + PERL_LIBS=`echo $PERL_LIBS |$sedpath 's/-lposix //'` fi - PERL_LDFLAGS=`echo $PERL_LDFLAGS |$sedpath 's/-lc //'` + PERL_LIBS=`echo $PERL_LIBS |$sedpath 's/-lc //'` AC_MSG_RESULT(ok) - CFLAGS="$CFLAGS $PERL_CFLAGS" - LIBS="$LIBS $PERL_LDFLAGS" + AC_SUBST(PERL_CFLAGS) + AC_SUBST(PERL_LIBS) AC_DEFINE(USE_PERL) AC_CHECK_FUNCS(Perl_eval_pv) fi @@ -195,6 +180,27 @@ AC_SUBST(LDADD) AC_SUBST(LIBS) +if test "x$enable_multi" != "xyes" ; then + AC_DEFINE(NO_MULTI) +fi + +if test "x$enable_plugins" = xyes ; then + dnl checks for icqlib + AC_CHECK_HEADERS(asm/byteorder.h byteswap.h endian.h machine/endian.h arpa/nameser_compat.h) + AC_CHECK_FUNCS(bswap_32 bswap_16) + + AC_DEFINE(GAIM_PLUGINS) +else + enable_jabber=no +fi + +if test "$enable_jabber" = yes ; then + AC_CHECK_FUNCS(snprintf) + AC_CHECK_LIB(nsl, gethostent) + AC_CHECK_FUNCS(connect) + AM_CONDITIONAL(JABBER, test "x$enable_jabber" = "xyes") +fi + AC_OUTPUT([Makefile src/Makefile intl/Makefile @@ -203,6 +209,7 @@ plugins/yay/Makefile plugins/icq/Makefile plugins/msn/Makefile + plugins/jabber/Makefile pixmaps/Makefile libfaim/Makefile po/Makefile.in @@ -215,12 +222,19 @@ echo $PACKAGE $VERSION echo +if test "$XSS_LIBS" = "no" ; then + echo Build with X scrnsvr ext... : no +else + echo X screensaver libs......... : $XSS_LIBS +fi echo Build with GNOME bits...... : $enable_gnome echo Build as GNOME applet...... : $enable_panel echo echo Build with Plugin support.. : $enable_plugins echo Build with Perl support.... : $enable_perl echo +#echo Build Jabber PRPL.......... : $enable_jabber +#echo echo Build with ESD............. : $enable_esd echo Build with NAS............. : $enable_nas echo diff -r 035945fca2d5 -r 338b8ac6bdab libfaim/Makefile.am --- a/libfaim/Makefile.am Tue Dec 19 10:23:23 2000 +0000 +++ b/libfaim/Makefile.am Tue Dec 19 12:21:45 2000 +0000 @@ -1,3 +1,5 @@ +CFLAGS = -I\$(top_srcdir)/libfaim -I\$(top_srcdir)/libfaim/faim + noinst_LIBRARIES = libfaim.a EXTRA_DIST = faim/aim.h faim/aim_cbtypes.h faim/faimconfig.h md5.h README \ diff -r 035945fca2d5 -r 338b8ac6bdab plugins/Makefile.am --- a/plugins/Makefile.am Tue Dec 19 10:23:23 2000 +0000 +++ b/plugins/Makefile.am Tue Dec 19 12:21:45 2000 +0000 @@ -5,7 +5,11 @@ if PLUGINS +if JABBER +SUBDIRS = yay icq msn jabber +else SUBDIRS = yay icq msn +endif plugin_DATA = autorecon.so iconaway.so irc.so notify.so spellchk.so lagmeter.so plugindir = $(libdir)/gaim diff -r 035945fca2d5 -r 338b8ac6bdab plugins/jabber.c --- a/plugins/jabber.c Tue Dec 19 10:23:23 2000 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,778 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ -/* - * gaim - * - * Some code copyright (C) 1998-1999, Mark Spencer - * libfaim code copyright 1998, 1999 Adam Fritzler - * - * 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 - * - */ - -#ifdef HAVE_CONFIG_H -#include "../config.h" -#endif - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "multi.h" -#include "prpl.h" -#include "gaim.h" -#include - -/* The priv member of gjconn's is a gaim_connection for now. */ -#define GJ_GC(x) ((struct gaim_connection *)(x)->priv) - -#define IQ_NONE -1 -#define IQ_AUTH 0 -#define IQ_ROSTER 1 - -typedef struct gjconn_struct -{ - /* Core structure */ - pool p; /* Memory allocation pool */ - int state; /* Connection state flag */ - int fd; /* Connection file descriptor */ - jid user; /* User info */ - char *pass; /* User passwd */ - - /* Stream stuff */ - int id; /* id counter for jab_getid() function */ - char idbuf[9]; /* temporary storage for jab_getid() */ - char *sid; /* stream id from server, for digest auth */ - XML_Parser parser; /* Parser instance */ - xmlnode current; /* Current node in parsing instance.. */ - - /* Event callback ptrs */ - void (*on_state)(struct gjconn_struct *j, int state); - void (*on_packet)(struct gjconn_struct *j, jpacket p); - - void *priv; - -} *gjconn, gjconn_struct; - -typedef void (*gjconn_state_h)(gjconn j, int state); -typedef void (*gjconn_packet_h)(gjconn j, jpacket p); - -static gjconn gjab_new(char *user, char *pass, void *priv); -static void gjab_delete(gjconn j); -static void gjab_state_handler(gjconn j, gjconn_state_h h); -static void gjab_packet_handler(gjconn j, gjconn_packet_h h); -static void gjab_start(gjconn j); -static void gjab_stop(gjconn j); -static int gjab_getfd(gjconn j); -static jid gjab_getjid(gjconn j); -static char *gjab_getsid(gjconn j); -static char *gjab_getid(gjconn j); -static void gjab_send(gjconn j, xmlnode x); -static void gjab_send_raw(gjconn j, const char *str); -static void gjab_recv(gjconn j); -static char *gjab_auth(gjconn j); - -struct jabber_data { - gjconn jc; -}; - -static char *jabber_name() { - return "Jabber"; -} - -char *name() { - return "Jabber"; -} - -char *description() { - return "Allows gaim to use the Jabber protocol"; -} - -#define STATE_EVT(arg) if(j->on_state) { (j->on_state)(j, (arg) ); } - -static gjconn gjab_new(char *user, char *pass, void *priv) -{ - pool p; - gjconn j; - - if(!user) - return(NULL); - - p = pool_new(); - if(!p) - return(NULL); - j = pmalloc_x(p, sizeof(gjconn_struct), 0); - if(!j) - return(NULL); - j->p = p; - - j->user = jid_new(p, user); - j->pass = pstrdup(p, pass); - - j->state = JCONN_STATE_OFF; - j->id = 1; - j->fd = -1; - - j->priv = priv; - - return j; -} - -static void gjab_delete(gjconn j) -{ - if(!j) - return; - - gjab_stop(j); - pool_free(j->p); -} - -static void gjab_state_handler(gjconn j, gjconn_state_h h) -{ - if(!j) - return; - - j->on_state = h; -} - -static void gjab_packet_handler(gjconn j, gjconn_packet_h h) -{ - if(!j) - return; - - j->on_packet = h; -} - -static void gjab_stop(gjconn j) -{ - if(!j || j->state == JCONN_STATE_OFF) - return; - - j->state = JCONN_STATE_OFF; - close(j->fd); - j->fd = -1; - XML_ParserFree(j->parser); -} - -static int gjab_getfd(gjconn j) -{ - if(j) - return j->fd; - else - return -1; -} - -static jid gjab_getjid(gjconn j) -{ - if(j) - return(j->user); - else - return NULL; -} - -static char *gjab_getsid(gjconn j) -{ - if(j) - return(j->sid); - else - return NULL; -} - -static char *gjab_getid(gjconn j) -{ - snprintf(j->idbuf, 8, "%d", j->id++); - return &j->idbuf[0]; -} - -static void gjab_send(gjconn j, xmlnode x) -{ - if (j && j->state != JCONN_STATE_OFF) { - char *buf = xmlnode2str(x); - if (buf) - write(j->fd, buf, strlen(buf)); - debug_printf("gjab_send: %s\n", buf); - } -} - -static void gjab_send_raw(gjconn j, const char *str) -{ - if (j && j->state != JCONN_STATE_OFF) { - write(j->fd, str, strlen(str)); - debug_printf("gjab_send_raw: %s\n", str); - } -} - -static void gjab_reqroster(gjconn j) -{ - xmlnode x; - char *id; - - x = jutil_iqnew(JPACKET__GET, NS_ROSTER); - id = gjab_getid(j); - xmlnode_put_attrib(x, "id", id); - - gjab_send(j, x); - xmlnode_free(x); -} - -static char *gjab_auth(gjconn j) -{ - xmlnode x,y,z; - char *hash, *user, *id; - - if(!j) - return NULL; - - x = jutil_iqnew(JPACKET__SET, NS_AUTH); - id = gjab_getid(j); - xmlnode_put_attrib(x, "id", id); - y = xmlnode_get_tag(x,"query"); - - user = j->user->user; - - if (user) { - z = xmlnode_insert_tag(y, "username"); - xmlnode_insert_cdata(z, user, -1); - } - - z = xmlnode_insert_tag(y, "resource"); - xmlnode_insert_cdata(z, j->user->resource, -1); - - if (j->sid) { - z = xmlnode_insert_tag(y, "digest"); - hash = pmalloc(x->p, strlen(j->sid)+strlen(j->pass)+1); - strcpy(hash, j->sid); - strcat(hash, j->pass); - hash = shahash(hash); - xmlnode_insert_cdata(z, hash, 40); - } else { - z = xmlnode_insert_tag(y, "password"); - xmlnode_insert_cdata(z, j->pass, -1); - } - - gjab_send(j, x); - xmlnode_free(x); - - return id; -} - -static void gjab_recv(gjconn j) -{ - static char buf[4096]; - int len; - - if(!j || j->state == JCONN_STATE_OFF) - return; - - if ((len = read(j->fd, buf, sizeof(buf)-1))) { - buf[len] = '\0'; - debug_printf("input: %s\n", buf); - XML_Parse(j->parser, buf, len, 0); - } else if (len < 0) { - STATE_EVT(JCONN_STATE_OFF); - gjab_stop(j); - } -} - -static void startElement(void *userdata, const char *name, const char **attribs) -{ - xmlnode x; - gjconn j = (gjconn)userdata; - - if(j->current) { - /* Append the node to the current one */ - x = xmlnode_insert_tag(j->current, name); - xmlnode_put_expat_attribs(x, attribs); - - j->current = x; - } else { - x = xmlnode_new_tag(name); - xmlnode_put_expat_attribs(x, attribs); - if(strcmp(name, "stream:stream") == 0) { - /* special case: name == stream:stream */ - /* id attrib of stream is stored for digest auth */ - j->sid = xmlnode_get_attrib(x, "id"); - /* STATE_EVT(JCONN_STATE_AUTH) */ - } else { - j->current = x; - } - } -} - -static void endElement(void *userdata, const char *name) -{ - gjconn j = (gjconn)userdata; - xmlnode x; - jpacket p; - - if(j->current == NULL) { - /* we got */ - STATE_EVT(JCONN_STATE_OFF) - return; - } - - x = xmlnode_get_parent(j->current); - - if(!x) { - /* it is time to fire the event */ - p = jpacket_new(j->current); - - if(j->on_packet) - (j->on_packet)(j, p); - else - xmlnode_free(j->current); - } - - j->current = x; -} - -static void charData(void *userdata, const char *s, int slen) -{ - gjconn j = (gjconn)userdata; - - if (j->current) - xmlnode_insert_cdata(j->current, s, slen); -} - -static void gjab_start(gjconn j) -{ - xmlnode x; - char *t,*t2; - - if(!j || j->state != JCONN_STATE_OFF) - return; - - j->parser = XML_ParserCreate(NULL); - XML_SetUserData(j->parser, (void *)j); - XML_SetElementHandler(j->parser, startElement, endElement); - XML_SetCharacterDataHandler(j->parser, charData); - - j->fd = make_netsocket(5222, j->user->server, NETSOCKET_CLIENT); - if(j->fd < 0) { - STATE_EVT(JCONN_STATE_OFF) - return; - } - j->state = JCONN_STATE_CONNECTED; - STATE_EVT(JCONN_STATE_CONNECTED) - - /* start stream */ - x = jutil_header(NS_CLIENT, j->user->server); - t = xmlnode2str(x); - /* this is ugly, we can create the string here instead of jutil_header */ - /* what do you think about it? -madcat */ - t2 = strstr(t,"/>"); - *t2++ = '>'; - *t2 = '\0'; - gjab_send_raw(j,""); - gjab_send_raw(j,t); - xmlnode_free(x); - - j->state = JCONN_STATE_ON; - STATE_EVT(JCONN_STATE_ON) -} - -static void jabber_callback(gpointer data, gint source, GdkInputCondition condition) { - struct gaim_connection *gc = (struct gaim_connection *)data; - struct jabber_data *jd = (struct jabber_data *)gc->proto_data; - - debug_printf("jabber_callback!\n"); - - gjab_recv(jd->jc); -} - -static void jabber_handlemessage(gjconn j, jpacket p) -{ - xmlnode y; - - char *from = NULL, *msg = NULL; - - from = jid_full(p->from); - if ((y = xmlnode_get_tag(p->x, "body"))) { - msg = xmlnode_get_data(y); - } - - if (!from || !msg) { - return; - } - - debug_printf("jabber: msg from %s: %s\n", from, msg); - - serv_got_im(GJ_GC(j), from, msg, 0); - - return; -} - -static void jabber_handlepresence(gjconn j, jpacket p) -{ - char *to, *from, *type; - struct buddy *b; - - to = xmlnode_get_attrib(p->x, "to"); - from = xmlnode_get_attrib(p->x, "from"); - type = xmlnode_get_attrib(p->x, "type"); - - debug_printf("jabber: presence: %s, %s %s\n", to, from, type); - - if (!(b = find_buddy(GJ_GC(j), from))) - add_buddy(GJ_GC(j), "Extra", from, from); - - if (type && (strcasecmp(type, "unavailable") == 0)) - serv_got_update(GJ_GC(j), from, 0, 0, 0, 0, 0, 0); - else - serv_got_update(GJ_GC(j), from, 1, 0, 0, 0, 0, 0); - - return; -} - -static void jabber_handleroster(gjconn j, xmlnode querynode) -{ - xmlnode x; - - x = xmlnode_get_firstchild(querynode); - while (x) { - xmlnode g; - char *jid, *name, *sub, *ask; - - jid = xmlnode_get_attrib(x, "jid"); - name = xmlnode_get_attrib(x, "name"); - if (name) - printf("name = %s\n", name); - sub = xmlnode_get_attrib(x, "subscription"); - ask = xmlnode_get_attrib(x, "ask"); - - if (ask) { - /* XXX do something */ - debug_printf("jabber: unhandled subscription request (%s/%s/%s/%s)\n", jid, name, sub, ask); - } - - if ((g = xmlnode_get_firstchild(x))) { - while (g) { - if (strncasecmp(xmlnode_get_name(g), "group", 5) == 0) { - struct buddy *b; - char *groupname; - - groupname = xmlnode_get_data(xmlnode_get_firstchild(g)); - if (!(b = find_buddy(GJ_GC(j), jid))) { - printf("adding buddy: %s\n", jid); - b = add_buddy(GJ_GC(j), groupname, jid, name?name:jid); - } else { - printf("updating buddy: %s/%s\n", jid, name); - g_snprintf(b->name, sizeof(b->name), "%s", jid); - g_snprintf(b->show, sizeof(b->show), "%s", name?name:jid); - } - //serv_got_update(GJ_GC(j), b->name, 1, 0, 0, 0, 0, 0); - } - g = xmlnode_get_nextsibling(g); - } - } else { - struct buddy *b; - if (!(b = find_buddy(GJ_GC(j), jid))) { - b = add_buddy(GJ_GC(j), "Extra", jid, name?name:jid); - } - } - - x = xmlnode_get_nextsibling(x); - } -} - -static void jabber_handlepacket(gjconn j, jpacket p) -{ - switch (p->type) { - case JPACKET_MESSAGE: - jabber_handlemessage(j, p); - break; - case JPACKET_PRESENCE: - jabber_handlepresence(j, p); - break; - case JPACKET_IQ: { - - if (jpacket_subtype(p) == JPACKET__RESULT) { - xmlnode querynode; - char *xmlns; - - querynode = xmlnode_get_tag(p->x, "query"); - xmlns = xmlnode_get_attrib(querynode, "xmlns"); - - /* XXX this just doesn't look right */ - if (!xmlns || NSCHECK(querynode, NS_AUTH)) { - xmlnode x; - - debug_printf("auth success\n"); - x = jutil_presnew(0, NULL, NULL); - gjab_send(j, x); - xmlnode_free(x); - - account_online(GJ_GC(j)); - serv_finish_login(GJ_GC(j)); - - gjab_reqroster(j); - - } else if (NSCHECK(querynode, NS_ROSTER)) { - jabber_handleroster(j, querynode); - } else { - debug_printf("jabber:iq:query: %s\n", xmlns); - } - - } else { - xmlnode x; - - debug_printf("auth failed\n"); - x = xmlnode_get_tag(p->x, "error"); - if (x) { - debug_printf("error %d: %s\n\n", - atoi(xmlnode_get_attrib(x, "code")), - xmlnode_get_data(xmlnode_get_firstchild(x))); - hide_login_progress(GJ_GC(j), xmlnode_get_data(xmlnode_get_firstchild(x))); - - } else - hide_login_progress(GJ_GC(j), "unknown error"); - - signoff(GJ_GC(j)); - } - break; - } - default: - debug_printf("jabber: packet type %d (%s)\n", p->type, xmlnode2str(p->x)); - } - - xmlnode_free(p->x); - - return; -} - -static void jabber_handlestate(gjconn j, int state) -{ - switch (state) { - case JCONN_STATE_OFF: - debug_printf("jabber: connection closed\n"); - hide_login_progress(GJ_GC(j), "Unable to connect"); - signoff(GJ_GC(j)); - break; - case JCONN_STATE_CONNECTED: - debug_printf("jabber: connected.\n"); - set_login_progress(GJ_GC(j), 1, "Connected"); - break; - case JCONN_STATE_ON: - debug_printf("jabber: logging in...\n"); - set_login_progress(GJ_GC(j), 1, "Logging in..."); - gjab_auth(j); - break; - default: - debug_printf("state change: %d\n", state); - } - return; -} - -static void jabber_login(struct aim_user *user) { - struct gaim_connection *gc = new_gaim_conn(user); - struct jabber_data *jd = gc->proto_data = g_new0(struct jabber_data, 1); - - debug_printf("jabber_login (u=%s/p=%s)\n", user->username, user->password); - - set_login_progress(gc, 1, "Connecting"); - while (gtk_events_pending()) - gtk_main_iteration(); - - if (!(jd->jc = gjab_new(user->username, user->password, gc))) { - debug_printf("jabber: unable to connect (jab_new failed)\n"); - hide_login_progress(gc, "Unable to connect"); - signoff(gc); - return; - } - - gjab_state_handler(jd->jc, jabber_handlestate); - gjab_packet_handler(jd->jc, jabber_handlepacket); - gjab_start(jd->jc); - - - gc->user = user; /* XXX I assume this is okay...OSCAR does it */ - - gc->inpa = gdk_input_add(jd->jc->fd, - GDK_INPUT_READ | GDK_INPUT_EXCEPTION, - jabber_callback, gc); - - return; - - //signoff(gc); - -#if 0 - struct yahoo_options opt; - struct yahoo_context *ctxt; - opt.connect_mode = YAHOO_CONNECT_NORMAL; - opt.proxy_host = NULL; - ctxt = yahoo_init(user->username, user->password, &opt); - yd->ctxt = ctxt; - - set_login_progress(gc, 1, "Connecting"); - while (gtk_events_pending()) - gtk_main_iteration(); - - if (!ctxt || !yahoo_connect(ctxt)) { - debug_printf("Yahoo: Unable to connect\n"); - hide_login_progress(gc, "Unable to connect"); - signoff(gc); - return; - } - - debug_printf("Yahoo: connected\n"); - - set_login_progress(gc, 3, "Getting Config"); - while (gtk_events_pending()) - gtk_main_iteration(); - - yahoo_get_config(ctxt); - - if (yahoo_cmd_logon(ctxt, YAHOO_STATUS_AVAILABLE)) { - debug_printf("Yahoo: Unable to login\n"); - hide_login_progress(gc, "Unable to login"); - signoff(gc); - return; - } - - if (ctxt->buddies) { - struct yahoo_buddy **buddies; - - for (buddies = ctxt->buddies; *buddies; buddies++) { - struct yahoo_buddy *bud = *buddies; - struct buddy *b; - struct group *g; - - b = find_buddy(gc, bud->id); - if (!b) add_buddy(gc, bud->group, bud->id, bud->id); - } - } - - debug_printf("Yahoo: logged in %s\n", gc->username); - account_online(gc); - serv_finish_login(gc); - - gc->inpa = gdk_input_add(ctxt->sockfd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, - yahoo_callback, gc); -#endif -} - -static void jabber_close(struct gaim_connection *gc) { -#if 0 - struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; - if (gc->inpa) - gdk_input_remove(gc->inpa); - gc->inpa = -1; - yahoo_cmd_logoff(yd->ctxt); - g_free(yd); -#endif -} - -static void jabber_send_im(struct gaim_connection *gc, char *who, char *message, int away) { - xmlnode x, y; - - if (!who || !message) - return; - - x = xmlnode_new_tag("message"); - xmlnode_put_attrib(x, "to", who); - - xmlnode_put_attrib(x, "type", "chat"); - - if (message && strlen(message)) { - y = xmlnode_insert_tag(x, "body"); - xmlnode_insert_cdata(y, message, -1); - } - - gjab_send(((struct jabber_data *)gc->proto_data)->jc, x); -} - -static void jabber_keepalive(struct gaim_connection *gc) { -#if 0 - yahoo_cmd_ping(((struct yahoo_data *)gc->proto_data)->ctxt); -#endif -} - -static void jabber_add_buddy(struct gaim_connection *gc, char *name) { -#if 0 - struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; - struct yahoo_buddy *tmpbuddy; - struct group *g = find_group_by_buddy(gc, name); - char *group = NULL; - - if (g) { - group = g->name; - } else if (yd->ctxt && yd->ctxt->buddies[0]) { - tmpbuddy = yd->ctxt->buddies[0]; - group = tmpbuddy->group; - } - - if (group) - yahoo_add_buddy(yd->ctxt, name, gc->username, group, ""); -#endif -} - -static struct prpl *my_protocol = NULL; - -void Jabber_init(struct prpl *ret) { - /* the NULL's aren't required but they're nice to have */ - ret->protocol = PROTO_JABBER; - ret->name = jabber_name; - ret->list_icon = NULL; - ret->action_menu = NULL; - ret->login = jabber_login; - ret->close = jabber_close; - ret->send_im = jabber_send_im; - ret->set_info = NULL; - ret->get_info = NULL; - ret->set_away = NULL; - ret->get_away_msg = NULL; - ret->set_dir = NULL; - ret->get_dir = NULL; - ret->dir_search = NULL; - ret->set_idle = NULL; - ret->change_passwd = NULL; - ret->add_buddy = jabber_add_buddy; - ret->add_buddies = NULL; - ret->remove_buddy = NULL; - ret->add_permit = NULL; - ret->add_deny = NULL; - ret->rem_permit = NULL; - ret->rem_deny = NULL; - ret->set_permit_deny = NULL; - ret->warn = NULL; - ret->accept_chat = NULL; - ret->join_chat = NULL; - ret->chat_invite = NULL; - ret->chat_leave = NULL; - ret->chat_whisper = NULL; - ret->chat_send = NULL; - ret->keepalive = jabber_keepalive; - - my_protocol = ret; -} - -char *gaim_plugin_init(GModule *handle) { - load_protocol(Jabber_init); - return NULL; -} - -void gaim_plugin_remove() { - struct prpl *p = find_prpl(PROTO_JABBER); - if (p == my_protocol) - unload_protocol(p); -} diff -r 035945fca2d5 -r 338b8ac6bdab plugins/jabber/.cvsignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/jabber/.cvsignore Tue Dec 19 12:21:45 2000 +0000 @@ -0,0 +1,6 @@ +Makefile.in +Makefile +.deps +.libs +jabber.lo +libjabber.la diff -r 035945fca2d5 -r 338b8ac6bdab plugins/jabber/Makefile.am --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/jabber/Makefile.am Tue Dec 19 12:21:45 2000 +0000 @@ -0,0 +1,7 @@ +CFLAGS += -I\$(top_srcdir)/src +LIBS += $(GTK_LIBS) -lxode -ljabber + +pkgdir = $(libdir)/gaim +pkg_LTLIBRARIES = libjabber.la + +libjabber_la_SOURCES = jabber.c diff -r 035945fca2d5 -r 338b8ac6bdab plugins/jabber/jabber.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/jabber/jabber.c Tue Dec 19 12:21:45 2000 +0000 @@ -0,0 +1,778 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* + * gaim + * + * Some code copyright (C) 1998-1999, Mark Spencer + * libfaim code copyright 1998, 1999 Adam Fritzler + * + * 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 + * + */ + +#ifdef HAVE_CONFIG_H +#include "../config.h" +#endif + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "multi.h" +#include "prpl.h" +#include "gaim.h" +#include + +/* The priv member of gjconn's is a gaim_connection for now. */ +#define GJ_GC(x) ((struct gaim_connection *)(x)->priv) + +#define IQ_NONE -1 +#define IQ_AUTH 0 +#define IQ_ROSTER 1 + +typedef struct gjconn_struct +{ + /* Core structure */ + pool p; /* Memory allocation pool */ + int state; /* Connection state flag */ + int fd; /* Connection file descriptor */ + jid user; /* User info */ + char *pass; /* User passwd */ + + /* Stream stuff */ + int id; /* id counter for jab_getid() function */ + char idbuf[9]; /* temporary storage for jab_getid() */ + char *sid; /* stream id from server, for digest auth */ + XML_Parser parser; /* Parser instance */ + xmlnode current; /* Current node in parsing instance.. */ + + /* Event callback ptrs */ + void (*on_state)(struct gjconn_struct *j, int state); + void (*on_packet)(struct gjconn_struct *j, jpacket p); + + void *priv; + +} *gjconn, gjconn_struct; + +typedef void (*gjconn_state_h)(gjconn j, int state); +typedef void (*gjconn_packet_h)(gjconn j, jpacket p); + +static gjconn gjab_new(char *user, char *pass, void *priv); +static void gjab_delete(gjconn j); +static void gjab_state_handler(gjconn j, gjconn_state_h h); +static void gjab_packet_handler(gjconn j, gjconn_packet_h h); +static void gjab_start(gjconn j); +static void gjab_stop(gjconn j); +static int gjab_getfd(gjconn j); +static jid gjab_getjid(gjconn j); +static char *gjab_getsid(gjconn j); +static char *gjab_getid(gjconn j); +static void gjab_send(gjconn j, xmlnode x); +static void gjab_send_raw(gjconn j, const char *str); +static void gjab_recv(gjconn j); +static char *gjab_auth(gjconn j); + +struct jabber_data { + gjconn jc; +}; + +static char *jabber_name() { + return "Jabber"; +} + +char *name() { + return "Jabber"; +} + +char *description() { + return "Allows gaim to use the Jabber protocol"; +} + +#define STATE_EVT(arg) if(j->on_state) { (j->on_state)(j, (arg) ); } + +static gjconn gjab_new(char *user, char *pass, void *priv) +{ + pool p; + gjconn j; + + if(!user) + return(NULL); + + p = pool_new(); + if(!p) + return(NULL); + j = pmalloc_x(p, sizeof(gjconn_struct), 0); + if(!j) + return(NULL); + j->p = p; + + j->user = jid_new(p, user); + j->pass = pstrdup(p, pass); + + j->state = JCONN_STATE_OFF; + j->id = 1; + j->fd = -1; + + j->priv = priv; + + return j; +} + +static void gjab_delete(gjconn j) +{ + if(!j) + return; + + gjab_stop(j); + pool_free(j->p); +} + +static void gjab_state_handler(gjconn j, gjconn_state_h h) +{ + if(!j) + return; + + j->on_state = h; +} + +static void gjab_packet_handler(gjconn j, gjconn_packet_h h) +{ + if(!j) + return; + + j->on_packet = h; +} + +static void gjab_stop(gjconn j) +{ + if(!j || j->state == JCONN_STATE_OFF) + return; + + j->state = JCONN_STATE_OFF; + close(j->fd); + j->fd = -1; + XML_ParserFree(j->parser); +} + +static int gjab_getfd(gjconn j) +{ + if(j) + return j->fd; + else + return -1; +} + +static jid gjab_getjid(gjconn j) +{ + if(j) + return(j->user); + else + return NULL; +} + +static char *gjab_getsid(gjconn j) +{ + if(j) + return(j->sid); + else + return NULL; +} + +static char *gjab_getid(gjconn j) +{ + snprintf(j->idbuf, 8, "%d", j->id++); + return &j->idbuf[0]; +} + +static void gjab_send(gjconn j, xmlnode x) +{ + if (j && j->state != JCONN_STATE_OFF) { + char *buf = xmlnode2str(x); + if (buf) + write(j->fd, buf, strlen(buf)); + debug_printf("gjab_send: %s\n", buf); + } +} + +static void gjab_send_raw(gjconn j, const char *str) +{ + if (j && j->state != JCONN_STATE_OFF) { + write(j->fd, str, strlen(str)); + debug_printf("gjab_send_raw: %s\n", str); + } +} + +static void gjab_reqroster(gjconn j) +{ + xmlnode x; + char *id; + + x = jutil_iqnew(JPACKET__GET, NS_ROSTER); + id = gjab_getid(j); + xmlnode_put_attrib(x, "id", id); + + gjab_send(j, x); + xmlnode_free(x); +} + +static char *gjab_auth(gjconn j) +{ + xmlnode x,y,z; + char *hash, *user, *id; + + if(!j) + return NULL; + + x = jutil_iqnew(JPACKET__SET, NS_AUTH); + id = gjab_getid(j); + xmlnode_put_attrib(x, "id", id); + y = xmlnode_get_tag(x,"query"); + + user = j->user->user; + + if (user) { + z = xmlnode_insert_tag(y, "username"); + xmlnode_insert_cdata(z, user, -1); + } + + z = xmlnode_insert_tag(y, "resource"); + xmlnode_insert_cdata(z, j->user->resource, -1); + + if (j->sid) { + z = xmlnode_insert_tag(y, "digest"); + hash = pmalloc(x->p, strlen(j->sid)+strlen(j->pass)+1); + strcpy(hash, j->sid); + strcat(hash, j->pass); + hash = shahash(hash); + xmlnode_insert_cdata(z, hash, 40); + } else { + z = xmlnode_insert_tag(y, "password"); + xmlnode_insert_cdata(z, j->pass, -1); + } + + gjab_send(j, x); + xmlnode_free(x); + + return id; +} + +static void gjab_recv(gjconn j) +{ + static char buf[4096]; + int len; + + if(!j || j->state == JCONN_STATE_OFF) + return; + + if ((len = read(j->fd, buf, sizeof(buf)-1))) { + buf[len] = '\0'; + debug_printf("input: %s\n", buf); + XML_Parse(j->parser, buf, len, 0); + } else if (len < 0) { + STATE_EVT(JCONN_STATE_OFF); + gjab_stop(j); + } +} + +static void startElement(void *userdata, const char *name, const char **attribs) +{ + xmlnode x; + gjconn j = (gjconn)userdata; + + if(j->current) { + /* Append the node to the current one */ + x = xmlnode_insert_tag(j->current, name); + xmlnode_put_expat_attribs(x, attribs); + + j->current = x; + } else { + x = xmlnode_new_tag(name); + xmlnode_put_expat_attribs(x, attribs); + if(strcmp(name, "stream:stream") == 0) { + /* special case: name == stream:stream */ + /* id attrib of stream is stored for digest auth */ + j->sid = xmlnode_get_attrib(x, "id"); + /* STATE_EVT(JCONN_STATE_AUTH) */ + } else { + j->current = x; + } + } +} + +static void endElement(void *userdata, const char *name) +{ + gjconn j = (gjconn)userdata; + xmlnode x; + jpacket p; + + if(j->current == NULL) { + /* we got */ + STATE_EVT(JCONN_STATE_OFF) + return; + } + + x = xmlnode_get_parent(j->current); + + if(!x) { + /* it is time to fire the event */ + p = jpacket_new(j->current); + + if(j->on_packet) + (j->on_packet)(j, p); + else + xmlnode_free(j->current); + } + + j->current = x; +} + +static void charData(void *userdata, const char *s, int slen) +{ + gjconn j = (gjconn)userdata; + + if (j->current) + xmlnode_insert_cdata(j->current, s, slen); +} + +static void gjab_start(gjconn j) +{ + xmlnode x; + char *t,*t2; + + if(!j || j->state != JCONN_STATE_OFF) + return; + + j->parser = XML_ParserCreate(NULL); + XML_SetUserData(j->parser, (void *)j); + XML_SetElementHandler(j->parser, startElement, endElement); + XML_SetCharacterDataHandler(j->parser, charData); + + j->fd = make_netsocket(5222, j->user->server, NETSOCKET_CLIENT); + if(j->fd < 0) { + STATE_EVT(JCONN_STATE_OFF) + return; + } + j->state = JCONN_STATE_CONNECTED; + STATE_EVT(JCONN_STATE_CONNECTED) + + /* start stream */ + x = jutil_header(NS_CLIENT, j->user->server); + t = xmlnode2str(x); + /* this is ugly, we can create the string here instead of jutil_header */ + /* what do you think about it? -madcat */ + t2 = strstr(t,"/>"); + *t2++ = '>'; + *t2 = '\0'; + gjab_send_raw(j,""); + gjab_send_raw(j,t); + xmlnode_free(x); + + j->state = JCONN_STATE_ON; + STATE_EVT(JCONN_STATE_ON) +} + +static void jabber_callback(gpointer data, gint source, GdkInputCondition condition) { + struct gaim_connection *gc = (struct gaim_connection *)data; + struct jabber_data *jd = (struct jabber_data *)gc->proto_data; + + debug_printf("jabber_callback!\n"); + + gjab_recv(jd->jc); +} + +static void jabber_handlemessage(gjconn j, jpacket p) +{ + xmlnode y; + + char *from = NULL, *msg = NULL; + + from = jid_full(p->from); + if ((y = xmlnode_get_tag(p->x, "body"))) { + msg = xmlnode_get_data(y); + } + + if (!from || !msg) { + return; + } + + debug_printf("jabber: msg from %s: %s\n", from, msg); + + serv_got_im(GJ_GC(j), from, msg, 0); + + return; +} + +static void jabber_handlepresence(gjconn j, jpacket p) +{ + char *to, *from, *type; + struct buddy *b; + + to = xmlnode_get_attrib(p->x, "to"); + from = xmlnode_get_attrib(p->x, "from"); + type = xmlnode_get_attrib(p->x, "type"); + + debug_printf("jabber: presence: %s, %s %s\n", to, from, type); + + if (!(b = find_buddy(GJ_GC(j), from))) + add_buddy(GJ_GC(j), "Extra", from, from); + + if (type && (strcasecmp(type, "unavailable") == 0)) + serv_got_update(GJ_GC(j), from, 0, 0, 0, 0, 0, 0); + else + serv_got_update(GJ_GC(j), from, 1, 0, 0, 0, 0, 0); + + return; +} + +static void jabber_handleroster(gjconn j, xmlnode querynode) +{ + xmlnode x; + + x = xmlnode_get_firstchild(querynode); + while (x) { + xmlnode g; + char *jid, *name, *sub, *ask; + + jid = xmlnode_get_attrib(x, "jid"); + name = xmlnode_get_attrib(x, "name"); + if (name) + printf("name = %s\n", name); + sub = xmlnode_get_attrib(x, "subscription"); + ask = xmlnode_get_attrib(x, "ask"); + + if (ask) { + /* XXX do something */ + debug_printf("jabber: unhandled subscription request (%s/%s/%s/%s)\n", jid, name, sub, ask); + } + + if ((g = xmlnode_get_firstchild(x))) { + while (g) { + if (strncasecmp(xmlnode_get_name(g), "group", 5) == 0) { + struct buddy *b; + char *groupname; + + groupname = xmlnode_get_data(xmlnode_get_firstchild(g)); + if (!(b = find_buddy(GJ_GC(j), jid))) { + printf("adding buddy: %s\n", jid); + b = add_buddy(GJ_GC(j), groupname, jid, name?name:jid); + } else { + printf("updating buddy: %s/%s\n", jid, name); + g_snprintf(b->name, sizeof(b->name), "%s", jid); + g_snprintf(b->show, sizeof(b->show), "%s", name?name:jid); + } + //serv_got_update(GJ_GC(j), b->name, 1, 0, 0, 0, 0, 0); + } + g = xmlnode_get_nextsibling(g); + } + } else { + struct buddy *b; + if (!(b = find_buddy(GJ_GC(j), jid))) { + b = add_buddy(GJ_GC(j), "Extra", jid, name?name:jid); + } + } + + x = xmlnode_get_nextsibling(x); + } +} + +static void jabber_handlepacket(gjconn j, jpacket p) +{ + switch (p->type) { + case JPACKET_MESSAGE: + jabber_handlemessage(j, p); + break; + case JPACKET_PRESENCE: + jabber_handlepresence(j, p); + break; + case JPACKET_IQ: { + + if (jpacket_subtype(p) == JPACKET__RESULT) { + xmlnode querynode; + char *xmlns; + + querynode = xmlnode_get_tag(p->x, "query"); + xmlns = xmlnode_get_attrib(querynode, "xmlns"); + + /* XXX this just doesn't look right */ + if (!xmlns || NSCHECK(querynode, NS_AUTH)) { + xmlnode x; + + debug_printf("auth success\n"); + x = jutil_presnew(0, NULL, NULL); + gjab_send(j, x); + xmlnode_free(x); + + account_online(GJ_GC(j)); + serv_finish_login(GJ_GC(j)); + + gjab_reqroster(j); + + } else if (NSCHECK(querynode, NS_ROSTER)) { + jabber_handleroster(j, querynode); + } else { + debug_printf("jabber:iq:query: %s\n", xmlns); + } + + } else { + xmlnode x; + + debug_printf("auth failed\n"); + x = xmlnode_get_tag(p->x, "error"); + if (x) { + debug_printf("error %d: %s\n\n", + atoi(xmlnode_get_attrib(x, "code")), + xmlnode_get_data(xmlnode_get_firstchild(x))); + hide_login_progress(GJ_GC(j), xmlnode_get_data(xmlnode_get_firstchild(x))); + + } else + hide_login_progress(GJ_GC(j), "unknown error"); + + signoff(GJ_GC(j)); + } + break; + } + default: + debug_printf("jabber: packet type %d (%s)\n", p->type, xmlnode2str(p->x)); + } + + xmlnode_free(p->x); + + return; +} + +static void jabber_handlestate(gjconn j, int state) +{ + switch (state) { + case JCONN_STATE_OFF: + debug_printf("jabber: connection closed\n"); + hide_login_progress(GJ_GC(j), "Unable to connect"); + signoff(GJ_GC(j)); + break; + case JCONN_STATE_CONNECTED: + debug_printf("jabber: connected.\n"); + set_login_progress(GJ_GC(j), 1, "Connected"); + break; + case JCONN_STATE_ON: + debug_printf("jabber: logging in...\n"); + set_login_progress(GJ_GC(j), 1, "Logging in..."); + gjab_auth(j); + break; + default: + debug_printf("state change: %d\n", state); + } + return; +} + +static void jabber_login(struct aim_user *user) { + struct gaim_connection *gc = new_gaim_conn(user); + struct jabber_data *jd = gc->proto_data = g_new0(struct jabber_data, 1); + + debug_printf("jabber_login (u=%s/p=%s)\n", user->username, user->password); + + set_login_progress(gc, 1, "Connecting"); + while (gtk_events_pending()) + gtk_main_iteration(); + + if (!(jd->jc = gjab_new(user->username, user->password, gc))) { + debug_printf("jabber: unable to connect (jab_new failed)\n"); + hide_login_progress(gc, "Unable to connect"); + signoff(gc); + return; + } + + gjab_state_handler(jd->jc, jabber_handlestate); + gjab_packet_handler(jd->jc, jabber_handlepacket); + gjab_start(jd->jc); + + + gc->user = user; /* XXX I assume this is okay...OSCAR does it */ + + gc->inpa = gdk_input_add(jd->jc->fd, + GDK_INPUT_READ | GDK_INPUT_EXCEPTION, + jabber_callback, gc); + + return; + + //signoff(gc); + +#if 0 + struct yahoo_options opt; + struct yahoo_context *ctxt; + opt.connect_mode = YAHOO_CONNECT_NORMAL; + opt.proxy_host = NULL; + ctxt = yahoo_init(user->username, user->password, &opt); + yd->ctxt = ctxt; + + set_login_progress(gc, 1, "Connecting"); + while (gtk_events_pending()) + gtk_main_iteration(); + + if (!ctxt || !yahoo_connect(ctxt)) { + debug_printf("Yahoo: Unable to connect\n"); + hide_login_progress(gc, "Unable to connect"); + signoff(gc); + return; + } + + debug_printf("Yahoo: connected\n"); + + set_login_progress(gc, 3, "Getting Config"); + while (gtk_events_pending()) + gtk_main_iteration(); + + yahoo_get_config(ctxt); + + if (yahoo_cmd_logon(ctxt, YAHOO_STATUS_AVAILABLE)) { + debug_printf("Yahoo: Unable to login\n"); + hide_login_progress(gc, "Unable to login"); + signoff(gc); + return; + } + + if (ctxt->buddies) { + struct yahoo_buddy **buddies; + + for (buddies = ctxt->buddies; *buddies; buddies++) { + struct yahoo_buddy *bud = *buddies; + struct buddy *b; + struct group *g; + + b = find_buddy(gc, bud->id); + if (!b) add_buddy(gc, bud->group, bud->id, bud->id); + } + } + + debug_printf("Yahoo: logged in %s\n", gc->username); + account_online(gc); + serv_finish_login(gc); + + gc->inpa = gdk_input_add(ctxt->sockfd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, + yahoo_callback, gc); +#endif +} + +static void jabber_close(struct gaim_connection *gc) { +#if 0 + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + if (gc->inpa) + gdk_input_remove(gc->inpa); + gc->inpa = -1; + yahoo_cmd_logoff(yd->ctxt); + g_free(yd); +#endif +} + +static void jabber_send_im(struct gaim_connection *gc, char *who, char *message, int away) { + xmlnode x, y; + + if (!who || !message) + return; + + x = xmlnode_new_tag("message"); + xmlnode_put_attrib(x, "to", who); + + xmlnode_put_attrib(x, "type", "chat"); + + if (message && strlen(message)) { + y = xmlnode_insert_tag(x, "body"); + xmlnode_insert_cdata(y, message, -1); + } + + gjab_send(((struct jabber_data *)gc->proto_data)->jc, x); +} + +static void jabber_keepalive(struct gaim_connection *gc) { +#if 0 + yahoo_cmd_ping(((struct yahoo_data *)gc->proto_data)->ctxt); +#endif +} + +static void jabber_add_buddy(struct gaim_connection *gc, char *name) { +#if 0 + struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; + struct yahoo_buddy *tmpbuddy; + struct group *g = find_group_by_buddy(gc, name); + char *group = NULL; + + if (g) { + group = g->name; + } else if (yd->ctxt && yd->ctxt->buddies[0]) { + tmpbuddy = yd->ctxt->buddies[0]; + group = tmpbuddy->group; + } + + if (group) + yahoo_add_buddy(yd->ctxt, name, gc->username, group, ""); +#endif +} + +static struct prpl *my_protocol = NULL; + +void Jabber_init(struct prpl *ret) { + /* the NULL's aren't required but they're nice to have */ + ret->protocol = PROTO_JABBER; + ret->name = jabber_name; + ret->list_icon = NULL; + ret->action_menu = NULL; + ret->login = jabber_login; + ret->close = jabber_close; + ret->send_im = jabber_send_im; + ret->set_info = NULL; + ret->get_info = NULL; + ret->set_away = NULL; + ret->get_away_msg = NULL; + ret->set_dir = NULL; + ret->get_dir = NULL; + ret->dir_search = NULL; + ret->set_idle = NULL; + ret->change_passwd = NULL; + ret->add_buddy = jabber_add_buddy; + ret->add_buddies = NULL; + ret->remove_buddy = NULL; + ret->add_permit = NULL; + ret->add_deny = NULL; + ret->rem_permit = NULL; + ret->rem_deny = NULL; + ret->set_permit_deny = NULL; + ret->warn = NULL; + ret->accept_chat = NULL; + ret->join_chat = NULL; + ret->chat_invite = NULL; + ret->chat_leave = NULL; + ret->chat_whisper = NULL; + ret->chat_send = NULL; + ret->keepalive = jabber_keepalive; + + my_protocol = ret; +} + +char *gaim_plugin_init(GModule *handle) { + load_protocol(Jabber_init); + return NULL; +} + +void gaim_plugin_remove() { + struct prpl *p = find_prpl(PROTO_JABBER); + if (p == my_protocol) + unload_protocol(p); +} diff -r 035945fca2d5 -r 338b8ac6bdab src/Makefile.am --- a/src/Makefile.am Tue Dec 19 10:23:23 2000 +0000 +++ b/src/Makefile.am Tue Dec 19 12:21:45 2000 +0000 @@ -64,6 +64,19 @@ gaim_LDADD = @LDADD@ @LIBOBJS@ endif +# libfaim stuff. should be here instead of configure.in, since plugins/prpls shouldn't +# rely on libfaim (the only file that should depend on it is oscar.c) +CFLAGS += -I\$(top_srcdir)/libfaim -I\$(top_srcdir)/libfaim/faim +LIBS += -L../libfaim -lfaim + +# Perl stuff. plugins shouldn't need this either (right?) +CFLAGS += $(PERL_CFLAGS) +LIBS += $(PERL_LIBS) + +# X screensaver extension +LIBS += $(XSS_LIBS) + +# any other stuff CFLAGS += -DLOCALEDIR=\"$(datadir)/locale\" -DLIBDIR=\"$(libdir)/gaim/\" $(DEBUG_CFLAGS) LIBS += $(DEBUG_LIBS)