Changeset 2288705 for protocols


Ignore:
Timestamp:
2009-12-07T21:54:19Z (12 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
1c3008a
Parents:
aac4017 (diff), 36cf9fd (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merging head.

Location:
protocols
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • protocols/jabber/conference.c

    raac4017 r2288705  
    2626static xt_status jabber_chat_join_failed( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );
    2727
    28 struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char *nick, char *password )
     28struct groupchat *jabber_chat_join( struct im_connection *ic, const char *room, const char *nick, const char *password )
    2929{
    3030        struct jabber_chat *jc;
     
    3636        node = xt_new_node( "x", NULL, NULL );
    3737        xt_add_attr( node, "xmlns", XMLNS_MUC );
    38         node = jabber_make_packet( "presence", NULL, roomjid, node );
    3938        if( password )
    4039                xt_add_child( node, xt_new_node( "password", password, NULL ) );
     40        node = jabber_make_packet( "presence", NULL, roomjid, node );
    4141        jabber_cache_add( ic, node, jabber_chat_join_failed );
    4242       
     
    234234                            ( strcmp( s, XMLNS_MUC_USER ) == 0 ) )
    235235                        {
    236                                 c = xt_find_node( c->children, "item" );
    237                                 if( ( s = xt_find_attr( c, "jid" ) ) )
     236                                struct xt_node *item;
     237                               
     238                                item = xt_find_node( c->children, "item" );
     239                                if( ( s = xt_find_attr( item, "jid" ) ) )
    238240                                {
    239241                                        /* Yay, found what we need. :-) */
     
    283285        else if( type ) /* type can only be NULL or "unavailable" in this function */
    284286        {
    285                 s = strchr( bud->ext_jid, '/' );
    286                 if( s ) *s = 0;
    287                 imcb_chat_remove_buddy( chat, bud->ext_jid, NULL );
    288                 if( bud != jc->me && bud->flags & JBFLAG_IS_ANONYMOUS )
    289                         imcb_remove_buddy( ic, bud->ext_jid, NULL );
    290                 if( s ) *s = '/';
     287                if( ( bud->flags & JBFLAG_IS_CHATROOM ) && bud->ext_jid )
     288                {
     289                        s = strchr( bud->ext_jid, '/' );
     290                        if( s ) *s = 0;
     291                        imcb_chat_remove_buddy( chat, bud->ext_jid, NULL );
     292                        if( bud != jc->me && bud->flags & JBFLAG_IS_ANONYMOUS )
     293                                imcb_remove_buddy( ic, bud->ext_jid, NULL );
     294                        if( s ) *s = '/';
     295                }
    291296               
    292297                if( bud == jc->me )
  • protocols/jabber/iq.c

    raac4017 r2288705  
    5151        {
    5252                if( !( ( c = xt_find_node( node->children, "query" ) ) ||
    53                        ( c = xt_find_node( node->children, "ping" ) ) ) || /* O_o WHAT is wrong with just <query/> ????? */
     53                       ( c = xt_find_node( node->children, "ping" ) ) ) ||
    5454                    !( s = xt_find_attr( c, "xmlns" ) ) )
    5555                {
    56                         imcb_log( ic, "Warning: Received incomplete IQ-%s packet", type );
     56                        /* Sigh. Who decided to suddenly invent new elements
     57                           instead of just sticking with <query/>? */
    5758                        return XT_HANDLED;
    5859                }
  • protocols/jabber/jabber.c

    raac4017 r2288705  
    7070       
    7171        s = set_add( &acc->set, "server", NULL, set_eval_account, acc );
    72         s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY;
     72        s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY | SET_NULL_OK;
    7373       
    7474        s = set_add( &acc->set, "ssl", "false", set_eval_bool, acc );
     
    439439}
    440440
    441 static struct groupchat *jabber_chat_join_( struct im_connection *ic, char *room, char *nick, char *password )
     441static struct groupchat *jabber_chat_join_( struct im_connection *ic, const char *room, const char *nick, const char *password )
    442442{
    443443        if( strchr( room, '@' ) == NULL )
  • protocols/jabber/jabber.h

    raac4017 r2288705  
    2727#include <glib.h>
    2828
     29#include "bitlbee.h"
     30#include "md5.h"
    2931#include "xmltree.h"
    30 #include "bitlbee.h"
    3132
    3233extern GSList *jabber_connections;
     
    302303
    303304/* conference.c */
    304 struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char *nick, char *password );
     305struct groupchat *jabber_chat_join( struct im_connection *ic, const char *room, const char *nick, const char *password );
    305306struct groupchat *jabber_chat_by_jid( struct im_connection *ic, const char *name );
    306307void jabber_chat_free( struct groupchat *c );
  • protocols/jabber/jabber_util.c

    raac4017 r2288705  
    3737                /* Priority is a signed 8-bit integer, according to RFC 3921. */
    3838                if( i < -128 || i > 127 )
    39                         return NULL;
     39                        return SET_INVALID;
    4040        }
    4141        else
    42                 return NULL;
     42                return SET_INVALID;
    4343       
    4444        /* Only run this stuff if the account is online ATM,
  • protocols/jabber/presence.c

    raac4017 r2288705  
    4949                if( !( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT | GET_BUDDY_CREAT ) ) )
    5050                {
    51                         if( set_getbool( &ic->irc->set, "debug" ) )
    52                                 imcb_log( ic, "Warning: Could not handle presence information from JID: %s", from );
     51                        /*
     52                        imcb_log( ic, "Warning: Could not handle presence information from JID: %s", from );
     53                        */
    5354                        return XT_HANDLED;
    5455                }
     
    106107                if( ( bud = jabber_buddy_by_jid( ic, from, 0 ) ) == NULL )
    107108                {
    108                         if( set_getbool( &ic->irc->set, "debug" ) )
    109                                 imcb_log( ic, "Warning: Received presence information from unknown JID: %s", from );
     109                        /*
     110                        imcb_log( ic, "Warning: Received presence information from unknown JID: %s", from );
     111                        */
    110112                        return XT_HANDLED;
    111113                }
  • protocols/nogaim.c

    raac4017 r2288705  
    3333
    3434#define BITLBEE_CORE
     35#include <ctype.h>
     36
    3537#include "nogaim.h"
    36 #include <ctype.h>
     38#include "chat.h"
    3739
    3840static int remove_chat_buddy_silent( struct groupchat *b, const char *handle );
     
    249251void imcb_connected( struct im_connection *ic )
    250252{
     253        irc_t *irc = ic->irc;
     254        struct chat *c;
    251255        user_t *u;
    252256       
     
    271275           exponential backoff timer. */
    272276        ic->acc->auto_reconnect_delay = 0;
     277       
     278        for( c = irc->chatrooms; c; c = c->next )
     279        {
     280                if( c->acc != ic->acc )
     281                        continue;
     282               
     283                if( set_getbool( &c->set, "auto_join" ) )
     284                        chat_join( irc, c, NULL );
     285        }
    273286}
    274287
     
    309322        ic->acc->prpl->logout( ic );
    310323        b_event_remove( ic->inpa );
     324       
     325        g_free( ic->away );
     326        ic->away = NULL;
    311327       
    312328        u = irc->users;
     
    492508}
    493509
    494 /* prpl.c */
    495 
    496 struct show_got_added_data
     510
     511struct imcb_ask_cb_data
    497512{
    498513        struct im_connection *ic;
     
    500515};
    501516
    502 void show_got_added_no( void *data )
    503 {
    504         g_free( ((struct show_got_added_data*)data)->handle );
     517static void imcb_ask_auth_cb_no( void *data )
     518{
     519        struct imcb_ask_cb_data *cbd = data;
     520       
     521        cbd->ic->acc->prpl->auth_deny( cbd->ic, cbd->handle );
     522       
     523        g_free( cbd->handle );
     524        g_free( cbd );
     525}
     526
     527static void imcb_ask_auth_cb_yes( void *data )
     528{
     529        struct imcb_ask_cb_data *cbd = data;
     530       
     531        cbd->ic->acc->prpl->auth_allow( cbd->ic, cbd->handle );
     532       
     533        g_free( cbd->handle );
     534        g_free( cbd );
     535}
     536
     537void imcb_ask_auth( struct im_connection *ic, const char *handle, const char *realname )
     538{
     539        struct imcb_ask_cb_data *data = g_new0( struct imcb_ask_cb_data, 1 );
     540        char *s, *realname_ = NULL;
     541       
     542        if( realname != NULL )
     543                realname_ = g_strdup_printf( " (%s)", realname );
     544       
     545        s = g_strdup_printf( "The user %s%s wants to add you to his/her buddy list.",
     546                             handle, realname_ ?: "" );
     547       
     548        g_free( realname_ );
     549       
     550        data->ic = ic;
     551        data->handle = g_strdup( handle );
     552        query_add( ic->irc, ic, s, imcb_ask_auth_cb_yes, imcb_ask_auth_cb_no, data );
     553}
     554
     555
     556static void imcb_ask_add_cb_no( void *data )
     557{
     558        g_free( ((struct imcb_ask_cb_data*)data)->handle );
    505559        g_free( data );
    506560}
    507561
    508 void show_got_added_yes( void *data )
    509 {
    510         struct show_got_added_data *sga = data;
    511        
    512         sga->ic->acc->prpl->add_buddy( sga->ic, sga->handle, NULL );
    513         /* imcb_add_buddy( sga->ic, NULL, sga->handle, sga->handle ); */
    514        
    515         return show_got_added_no( data );
    516 }
    517 
    518 void imcb_ask_add( struct im_connection *ic, char *handle, const char *realname )
    519 {
    520         struct show_got_added_data *data = g_new0( struct show_got_added_data, 1 );
     562static void imcb_ask_add_cb_yes( void *data )
     563{
     564        struct imcb_ask_cb_data *cbd = data;
     565       
     566        cbd->ic->acc->prpl->add_buddy( cbd->ic, cbd->handle, NULL );
     567       
     568        return imcb_ask_add_cb_no( data );
     569}
     570
     571void imcb_ask_add( struct im_connection *ic, const char *handle, const char *realname )
     572{
     573        struct imcb_ask_cb_data *data = g_new0( struct imcb_ask_cb_data, 1 );
    521574        char *s;
    522575       
     
    529582        data->ic = ic;
    530583        data->handle = g_strdup( handle );
    531         query_add( ic->irc, ic, s, show_got_added_yes, show_got_added_no, data );
     584        query_add( ic->irc, ic, s, imcb_ask_add_cb_yes, imcb_ask_add_cb_no, data );
    532585}
    533586
     
    699752}
    700753
    701 struct groupchat *imcb_chat_new( struct im_connection *ic, char *handle )
     754struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle )
    702755{
    703756        struct groupchat *c;
     
    928981        int st;
    929982       
    930         if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 0 ) )
    931                 st = 1;
    932         else if( ( g_strcasecmp( value, "false" ) == 0 ) || ( g_strcasecmp( value, "no" ) == 0 ) || ( g_strcasecmp( value, "off" ) == 0 ) )
    933                 st = 0;
    934         else if( sscanf( value, "%d", &st ) != 1 )
    935                 return( NULL );
    936        
    937         st = st != 0;
     983        if( !is_bool( value ) )
     984                return SET_INVALID;
     985       
     986        st = bool2int( value );
    938987       
    939988        /* Horror.... */
     
    9791028        }
    9801029       
    981         return( set_eval_bool( set, value ) );
     1030        return value;
    9821031}
    9831032
  • protocols/nogaim.h

    raac4017 r2288705  
    3939#define _NOGAIM_H
    4040
     41#include <stdint.h>
     42
    4143#include "bitlbee.h"
    4244#include "account.h"
     
    210212         * not implement this. */
    211213        struct groupchat *
    212              (* chat_join)      (struct im_connection *, char *room, char *nick, char *password);
     214             (* chat_join)      (struct im_connection *, const char *room, const char *nick, const char *password);
    213215        /* Change the topic, if supported. Note that BitlBee expects the IM
    214216           server to confirm the topic change with a regular topic change
     
    225227         * - Most protocols will just want to set this to g_strcasecmp().*/
    226228        int (* handle_cmp) (const char *who1, const char *who2);
     229
     230        /* Implement these callbacks if you want to use imcb_ask_auth() */
     231        void (* auth_allow)     (struct im_connection *, const char *who);
     232        void (* auth_deny)      (struct im_connection *, const char *who);
    227233
    228234        /* Incoming transfer request */
     
    243249 * the account_t parameter. */
    244250G_MODULE_EXPORT struct im_connection *imcb_new( account_t *acc );
    245 G_MODULE_EXPORT void imcb_free( struct im_connection *ic );
     251G_MODULE_EXPORT void imc_free( struct im_connection *ic );
    246252/* Once you're connected, you should call this function, so that the user will
    247253 * see the success. */
     
    256262/* To tell the user an error, ie. before logging out when an error occurs. */
    257263G_MODULE_EXPORT void imcb_error( struct im_connection *ic, char *format, ... ) G_GNUC_PRINTF( 2, 3 );
     264
    258265/* To ask a your about something.
    259266 * - 'msg' is the question.
     
    262269 */
    263270G_MODULE_EXPORT void imcb_ask( struct im_connection *ic, char *msg, void *data, query_callback doit, query_callback dont );
    264 G_MODULE_EXPORT void imcb_ask_add( struct im_connection *ic, char *handle, const char *realname );
     271
     272/* Two common questions you may want to ask:
     273 * - X added you to his contact list, allow?
     274 * - X is not in your contact list, want to add?
     275 */
     276G_MODULE_EXPORT void imcb_ask_auth( struct im_connection *ic, const char *handle, const char *realname );
     277G_MODULE_EXPORT void imcb_ask_add( struct im_connection *ic, const char *handle, const char *realname );
    265278
    266279/* Buddy management */
     
    294307 *   the user her/himself. At that point the group chat will be visible to the
    295308 *   user, too. */
    296 G_MODULE_EXPORT struct groupchat *imcb_chat_new( struct im_connection *ic, char *handle );
     309G_MODULE_EXPORT struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle );
    297310G_MODULE_EXPORT void imcb_chat_add_buddy( struct groupchat *b, char *handle );
    298311/* To remove a handle from a group chat. Reason can be NULL. */
  • protocols/oscar/aim.h

    raac4017 r2288705  
    144144}
    145145
     146#define AIM_CLIENTINFO_KNOWNGOOD_5_1_3036 { \
     147        "AOL Instant Messenger, version 5.1.3036/WIN32", \
     148        0x0109, \
     149        0x0005, \
     150        0x0001, \
     151        0x0000, \
     152        0x0bdc, \
     153        "us", \
     154        "en", \
     155}
     156
    146157/*
    147158 * I would make 4.1.2010 the default, but they seem to have found
     
    152163 * around. (see login.c::memrequest())
    153164 */
    154 #define AIM_CLIENTINFO_KNOWNGOOD AIM_CLIENTINFO_KNOWNGOOD_3_5_1670
     165#define AIM_CLIENTINFO_KNOWNGOOD AIM_CLIENTINFO_KNOWNGOOD_5_1_3036
    155166
    156167#ifndef TRUE
  • protocols/oscar/oscar.c

    raac4017 r2288705  
    9191        GSList *oscar_chats;
    9292
    93         gboolean killme;
     93        gboolean killme, no_reconnect;
    9494        gboolean icq;
    9595        GSList *evilhack;
     
    181181static int gaim_parse_auth_resp  (aim_session_t *, aim_frame_t *, ...);
    182182static int gaim_parse_login      (aim_session_t *, aim_frame_t *, ...);
     183static int gaim_parse_logout     (aim_session_t *, aim_frame_t *, ...);
    183184static int gaim_handle_redirect  (aim_session_t *, aim_frame_t *, ...);
    184185static int gaim_parse_oncoming   (aim_session_t *, aim_frame_t *, ...);
     
    294295                        aim_rxdispatch(odata->sess);
    295296                               if (odata->killme)
    296                                        imc_logout(ic, TRUE);
     297                                       imc_logout(ic, !odata->no_reconnect);
    297298                } else {
    298299                        if ((conn->type == AIM_CONN_TYPE_BOS) ||
     
    520521                case 0x18:
    521522                        /* connecting too frequently */
     523                        od->no_reconnect = TRUE;
    522524                        imcb_error(ic, _("You have been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer."));
    523525                        break;
     
    572574        aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO, gaim_parseaiminfo, 0);
    573575        aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MTN, gaim_parsemtn, 0);
     576        aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, gaim_parse_logout, 0);
    574577
    575578        ((struct oscar_data *)ic->proto_data)->conn = bosconn;
     
    747750
    748751        aim_send_login(sess, fr->conn, ic->acc->user, ic->acc->pass, &info, key);
     752
     753        return 1;
     754}
     755
     756static int gaim_parse_logout(aim_session_t *sess, aim_frame_t *fr, ...) {
     757        struct im_connection *ic = sess->aux_data;
     758        struct oscar_data *odata = ic->proto_data;
     759        int code;
     760        va_list ap;
     761
     762        va_start(ap, fr);
     763        code = va_arg(ap, int);
     764        va_end(ap);
     765       
     766        imcb_error( ic, "Connection aborted by server: %s", code == 1 ?
     767                        "someone else logged in with your account" :
     768                        "unknown reason" );
     769       
     770        /* Tell BitlBee to disable auto_reconnect if code == 1, since that
     771           means a concurrent login somewhere else. */
     772        odata->no_reconnect = code == 1;
     773       
     774        /* DO NOT log out here! Just tell the callback to do it. */
     775        odata->killme = TRUE;
    749776
    750777        return 1;
     
    19391966        aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_NORMAL);
    19401967
    1941         if (ic->away)
    1942                 g_free(ic->away);
     1968        g_free(ic->away);
    19431969        ic->away = NULL;
    19441970
     
    19601986static void oscar_set_away_icq(struct im_connection *ic, struct oscar_data *od, const char *state, const char *message)
    19611987{
    1962     const char *msg = NULL;
     1988        const char *msg = NULL;
    19631989        gboolean no_message = FALSE;
    19641990
    19651991        /* clean old states */
    1966     if (ic->away) {
    1967                 g_free(ic->away);
    1968                 ic->away = NULL;
    1969     }
     1992        g_free(ic->away);
     1993        ic->away = NULL;
    19701994        od->sess->aim_icq_state = 0;
    19711995
    19721996        /* if no message, then use an empty message */
    1973     if (message) {
    1974         msg = message;
    1975     } else {
    1976         msg = "";
     1997        if (message) {
     1998                msg = message;
     1999        } else {
     2000                msg = "";
    19772001                no_message = TRUE;
    1978     }
     2002        }
    19792003
    19802004        if (!g_strcasecmp(state, "Online")) {
     
    19822006        } else if (!g_strcasecmp(state, "Away")) {
    19832007                aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY);
    1984         ic->away = g_strdup(msg);
     2008                ic->away = g_strdup(msg);
    19852009                od->sess->aim_icq_state = AIM_MTYPE_AUTOAWAY;
    19862010        } else if (!g_strcasecmp(state, "Do Not Disturb")) {
    19872011                aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_DND | AIM_ICQ_STATE_BUSY);
    1988         ic->away = g_strdup(msg);
     2012                ic->away = g_strdup(msg);
    19892013                od->sess->aim_icq_state = AIM_MTYPE_AUTODND;
    19902014        } else if (!g_strcasecmp(state, "Not Available")) {
    19912015                aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_OUT | AIM_ICQ_STATE_AWAY);
    1992         ic->away = g_strdup(msg);
     2016                ic->away = g_strdup(msg);
    19932017                od->sess->aim_icq_state = AIM_MTYPE_AUTONA;
    19942018        } else if (!g_strcasecmp(state, "Occupied")) {
    19952019                aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_BUSY);
    1996         ic->away = g_strdup(msg);
     2020                ic->away = g_strdup(msg);
    19972021                od->sess->aim_icq_state = AIM_MTYPE_AUTOBUSY;
    19982022        } else if (!g_strcasecmp(state, "Free For Chat")) {
    19992023                aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_CHAT);
    2000         ic->away = g_strdup(msg);
     2024                ic->away = g_strdup(msg);
    20012025                od->sess->aim_icq_state = AIM_MTYPE_AUTOFFC;
    20022026        } else if (!g_strcasecmp(state, "Invisible")) {
    20032027                aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_INVISIBLE);
    2004         ic->away = g_strdup(msg);
     2028                ic->away = g_strdup(msg);
    20052029        } else if (!g_strcasecmp(state, GAIM_AWAY_CUSTOM)) {
    20062030                if (no_message) {
     
    20082032                } else {
    20092033                        aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY);
    2010             ic->away = g_strdup(msg);
     2034                        ic->away = g_strdup(msg);
    20112035                        od->sess->aim_icq_state = AIM_MTYPE_AUTOAWAY;
    20122036                }
     
    20202044        struct oscar_data *od = (struct oscar_data *)ic->proto_data;
    20212045
    2022     oscar_set_away_aim(ic, od, state, message);
     2046        oscar_set_away_aim(ic, od, state, message);
    20232047        if (od->icq)
    20242048                oscar_set_away_icq(ic, od, state, message);
     
    25812605}
    25822606
    2583 struct groupchat *oscar_chat_join(struct im_connection * ic, char * room, char * nick, char * password )
     2607struct groupchat *oscar_chat_join(struct im_connection * ic, const char * room, const char * nick, const char * password )
    25842608{
    25852609        struct oscar_data * od = (struct oscar_data *)ic->proto_data;
  • protocols/yahoo/libyahoo2.c

    raac4017 r2288705  
    8989
    9090#include "base64.h"
     91#include "http_client.h"
    9192
    9293#ifdef USE_STRUCT_CALLBACKS
     
    169170        YAHOO_SERVICE_GOTGROUPRENAME, /* < 1, 36(old), 37(new) */
    170171        YAHOO_SERVICE_SYSMESSAGE = 0x14,
     172        YAHOO_SERVICE_SKINNAME = 0x15,
    171173        YAHOO_SERVICE_PASSTHROUGH2 = 0x16,
    172174        YAHOO_SERVICE_CONFINVITE = 0x18,
     
    192194        YAHOO_SERVICE_LIST,
    193195        YAHOO_SERVICE_AUTH = 0x57,
     196        YAHOO_SERVICE_AUTHBUDDY = 0x6d,
    194197        YAHOO_SERVICE_ADDBUDDY = 0x83,
    195198        YAHOO_SERVICE_REMBUDDY,
     
    197200        YAHOO_SERVICE_REJECTCONTACT,
    198201        YAHOO_SERVICE_GROUPRENAME = 0x89, /* > 1, 65(new), 66(0), 67(old) */
     202        YAHOO_SERVICE_Y7_PING = 0x8A, /* 0 - id and that's it?? */
    199203        YAHOO_SERVICE_CHATONLINE = 0x96, /* > 109(id), 1, 6(abcde) < 0,1*/
    200204        YAHOO_SERVICE_CHATGOTO,
     
    202206        YAHOO_SERVICE_CHATLEAVE,
    203207        YAHOO_SERVICE_CHATEXIT = 0x9b,
     208        YAHOO_SERVICE_CHATADDINVITE = 0x9d,
    204209        YAHOO_SERVICE_CHATLOGOUT = 0xa0,
    205210        YAHOO_SERVICE_CHATPING,
     
    209214        YAHOO_SERVICE_PICTURE = 0xbe,
    210215        YAHOO_SERVICE_PICTURE_UPDATE = 0xc1,
    211         YAHOO_SERVICE_PICTURE_UPLOAD = 0xc2
     216        YAHOO_SERVICE_PICTURE_UPLOAD = 0xc2,
     217        YAHOO_SERVICE_Y6_VISIBILITY=0xc5,
     218        YAHOO_SERVICE_Y6_STATUS_UPDATE=0xc6,
     219        YAHOO_PHOTOSHARE_INIT=0xd2,     
     220        YAHOO_SERVICE_CONTACT_YMSG13=0xd6,
     221        YAHOO_PHOTOSHARE_PREV=0xd7,
     222        YAHOO_PHOTOSHARE_KEY=0xd8,
     223        YAHOO_PHOTOSHARE_TRANS=0xda,
     224        YAHOO_FILE_TRANSFER_INIT_YMSG13=0xdc,
     225        YAHOO_FILE_TRANSFER_GET_YMSG13=0xdd,
     226        YAHOO_FILE_TRANSFER_PUT_YMSG13=0xde,
     227        YAHOO_SERVICE_YMSG15_STATUS=0xf0,
     228        YAHOO_SERVICE_YMSG15_BUDDY_LIST=0xf1,
    212229};
    213230
     
    733750
    734751        memcpy(data + pos, "YMSG", 4); pos += 4;
    735         pos += yahoo_put16(data + pos, 0x000c);
     752        pos += yahoo_put16(data + pos, YAHOO_PROTO_VER);
    736753        pos += yahoo_put16(data + pos, 0x0000);
    737754        pos += yahoo_put16(data + pos, pktlen + extra_pad);
     
    747764                yahoo_send_data(yid->fd, data, len);
    748765        else
    749         yahoo_add_to_send_queue(yid, data, len);
     766                yahoo_add_to_send_queue(yid, data, len);
    750767        FREE(data);
    751768}
     
    14671484
    14681485                if (u->name != NULL) {
    1469                         if (pkt->service == YAHOO_SERVICE_LOGOFF || u->flags == 0) {
     1486                        if (pkt->service == YAHOO_SERVICE_LOGOFF) { /* || u->flags == 0) { Not in YMSG16 */
    14701487                                YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, u->name, YAHOO_STATUS_OFFLINE, NULL, 1, 0, 0);
    14711488                        } else {
     1489                                /* Key 47 always seems to be 1 for YMSG16 */
     1490                                if(!u->state)
     1491                                        u->away = 0;
     1492                                else
     1493                                        u->away = 1;
     1494
    14721495                                YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, u->name, u->state, u->msg, u->away, u->idle, u->mobile);
    14731496                        }
     
    14771500                y_list_free_1(t);
    14781501                FREE(u);
     1502        }
     1503}
     1504
     1505static void yahoo_process_buddy_list(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     1506{
     1507        struct yahoo_data *yd = yid->yd;
     1508        YList *l;
     1509        int last_packet = 0;
     1510        char *cur_group = NULL;
     1511        struct yahoo_buddy *newbud = NULL;
     1512
     1513        /* we could be getting multiple packets here */
     1514        for (l = pkt->hash; l; l = l->next) {
     1515                struct yahoo_pair *pair = l->data;
     1516
     1517                switch(pair->key) {
     1518                case 300:
     1519                case 301:
     1520                case 302:
     1521                case 303:
     1522                        if ( 315 == atoi(pair->value) )
     1523                                last_packet = 1;
     1524                        break;
     1525                case 65:
     1526                        g_free(cur_group);
     1527                        cur_group = strdup(pair->value);
     1528                        break;
     1529                case 7:
     1530                        newbud = y_new0(struct yahoo_buddy, 1);
     1531                        newbud->id = strdup(pair->value);
     1532                        if(cur_group)
     1533                                newbud->group = strdup(cur_group);
     1534                        else {
     1535                                struct yahoo_buddy *lastbud = (struct yahoo_buddy *)y_list_nth(
     1536                                                                yd->buddies, y_list_length(yd->buddies)-1)->data;
     1537                                newbud->group = strdup(lastbud->group);
     1538                        }
     1539
     1540                        yd->buddies = y_list_append(yd->buddies, newbud);
     1541
     1542                        break;
     1543                }
     1544        }
     1545       
     1546        g_free(cur_group);
     1547
     1548        /* we could be getting multiple packets here */
     1549        if (last_packet)
     1550                return;
     1551
     1552        YAHOO_CALLBACK(ext_yahoo_got_buddies)(yd->client_id, yd->buddies);
     1553
     1554        /*** We login at the very end of the packet communication */
     1555        if (!yd->logged_in) {
     1556                yd->logged_in = TRUE;
     1557                if(yd->current_status < 0)
     1558                        yd->current_status = yd->initial_status;
     1559                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_OK, NULL);
    14791560        }
    14801561}
     
    15491630                        }
    15501631
    1551                         if(yd->cookie_y && yd->cookie_t && yd->cookie_c)
     1632                        if(yd->cookie_y && yd->cookie_t)
    15521633                                YAHOO_CALLBACK(ext_yahoo_got_cookies)(yd->client_id);
    15531634
     
    22262307}
    22272308
     2309struct yahoo_https_auth_data
     2310{
     2311        struct yahoo_input_data *yid;
     2312        char *token;
     2313        char *chal;
     2314};
     2315
     2316static void yahoo_https_auth_token_init(struct yahoo_https_auth_data *had);
     2317static void yahoo_https_auth_token_finish(struct http_request *req);
     2318static void yahoo_https_auth_init(struct yahoo_https_auth_data *had);
     2319static void yahoo_https_auth_finish(struct http_request *req);
     2320
     2321/* Extract a value from a login.yahoo.com response. Assume CRLF-linebreaks
     2322   and FAIL miserably if they're not there... */
     2323static char *yahoo_ha_find_key(char *response, char *key)
     2324{
     2325        char *s, *end;
     2326        int len = strlen(key);
     2327       
     2328        s = response;
     2329        do {
     2330                if (strncmp(s, key, len) == 0 && s[len] == '=') {
     2331                        s += len + 1;
     2332                        if ((end = strchr(s, '\r')))
     2333                                return g_strndup(s, end - s);
     2334                        else
     2335                                return g_strdup(s);
     2336                }
     2337               
     2338                if ((s = strchr(s, '\n')))
     2339                        s ++;
     2340        } while (s && *s);
     2341       
     2342        return NULL;
     2343}
     2344
     2345static enum yahoo_status yahoo_https_status_parse(int code)
     2346{
     2347        switch (code)
     2348        {
     2349                case 1212: return YAHOO_LOGIN_PASSWD;
     2350                case 1213: return YAHOO_LOGIN_LOCK;
     2351                case 1235: return YAHOO_LOGIN_UNAME;
     2352                default: return (enum yahoo_status) code;
     2353        }
     2354}
     2355
     2356static void yahoo_process_auth_0x10(struct yahoo_input_data *yid, const char *seed, const char *sn)
     2357{
     2358        struct yahoo_https_auth_data *had = g_new0(struct yahoo_https_auth_data, 1);
     2359       
     2360        had->yid = yid;
     2361        had->chal = g_strdup(seed);
     2362       
     2363        yahoo_https_auth_token_init(had);
     2364}
     2365
     2366static void yahoo_https_auth_token_init(struct yahoo_https_auth_data *had)
     2367{
     2368        struct yahoo_input_data *yid = had->yid;
     2369        struct yahoo_data *yd = yid->yd;
     2370        struct http_request *req;
     2371        char *login, *passwd, *chal;
     2372        char *url;
     2373       
     2374        login = g_strndup(yd->user, 3 * strlen(yd->user));
     2375        http_encode(login);
     2376        passwd = g_strndup(yd->password, 3 * strlen(yd->password));
     2377        http_encode(passwd);
     2378        chal = g_strndup(had->chal, 3 * strlen(had->chal));
     2379        http_encode(chal);
     2380       
     2381        url = g_strdup_printf("https://login.yahoo.com/config/pwtoken_get?src=ymsgr&ts=%d&login=%s&passwd=%s&chal=%s",
     2382                               (int) time(NULL), login, passwd, chal);
     2383       
     2384        req = http_dorequest_url(url, yahoo_https_auth_token_finish, had);
     2385       
     2386        g_free(url);
     2387        g_free(chal);
     2388        g_free(passwd);
     2389        g_free(login);
     2390}
     2391
     2392static void yahoo_https_auth_token_finish(struct http_request *req)
     2393{
     2394        struct yahoo_https_auth_data *had = req->data;
     2395        struct yahoo_input_data *yid = had->yid;
     2396        struct yahoo_data *yd = yid->yd;
     2397        int st;
     2398       
     2399        if (req->status_code != 200) {
     2400                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 2000 + req->status_code, NULL);
     2401                goto fail;
     2402        }
     2403       
     2404        if (sscanf(req->reply_body, "%d", &st) != 1 || st != 0) {
     2405                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, yahoo_https_status_parse(st), NULL);
     2406                goto fail;
     2407        }
     2408       
     2409        if ((had->token = yahoo_ha_find_key(req->reply_body, "ymsgr")) == NULL) {
     2410                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 3001, NULL);
     2411                goto fail;
     2412        }
     2413       
     2414        return yahoo_https_auth_init(had);
     2415       
     2416fail:
     2417        g_free(had->token);
     2418        g_free(had->chal);
     2419        g_free(had);
     2420}
     2421
     2422static void yahoo_https_auth_init(struct yahoo_https_auth_data *had)
     2423{
     2424        struct http_request *req;
     2425        char *url;
     2426       
     2427        url = g_strdup_printf("https://login.yahoo.com/config/pwtoken_login?src=ymsgr&ts=%d&token=%s",
     2428                              (int) time(NULL), had->token);
     2429       
     2430        req = http_dorequest_url(url, yahoo_https_auth_finish, had);
     2431       
     2432        g_free(url);
     2433}
     2434
     2435static void yahoo_https_auth_finish(struct http_request *req)
     2436{
     2437        struct yahoo_https_auth_data *had = req->data;
     2438        struct yahoo_input_data *yid = had->yid;
     2439        struct yahoo_data *yd = yid->yd;
     2440        struct yahoo_packet *pack;
     2441        char *crumb;
     2442        int st;
     2443       
     2444        md5_byte_t result[16];
     2445        md5_state_t ctx;
     2446       
     2447        unsigned char yhash[32];
     2448
     2449        if (req->status_code != 200) {
     2450                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 2000 + req->status_code, NULL);
     2451                goto fail;
     2452        }
     2453       
     2454        if (sscanf(req->reply_body, "%d", &st) != 1 || st != 0) {
     2455                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, yahoo_https_status_parse(st), NULL);
     2456                goto fail;
     2457        }
     2458       
     2459        if ((yd->cookie_y = yahoo_ha_find_key(req->reply_body, "Y")) == NULL ||
     2460            (yd->cookie_t = yahoo_ha_find_key(req->reply_body, "T")) == NULL ||
     2461            (crumb = yahoo_ha_find_key(req->reply_body, "crumb")) == NULL) {
     2462                YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 3002, NULL);
     2463                goto fail;
     2464        }
     2465       
     2466        md5_init(&ctx); 
     2467        md5_append(&ctx, (unsigned char*) crumb, 11);
     2468        md5_append(&ctx, (unsigned char*) had->chal, strlen(had->chal));
     2469        md5_finish(&ctx, result);
     2470        to_y64(yhash, result, 16);
     2471
     2472        pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yd->initial_status, yd->session_id);
     2473        yahoo_packet_hash(pack, 1, yd->user);
     2474        yahoo_packet_hash(pack, 0, yd->user);
     2475        yahoo_packet_hash(pack, 277, yd->cookie_y);
     2476        yahoo_packet_hash(pack, 278, yd->cookie_t);
     2477        yahoo_packet_hash(pack, 307, (char*) yhash);
     2478        yahoo_packet_hash(pack, 244, "524223");
     2479        yahoo_packet_hash(pack, 2, yd->user);
     2480        yahoo_packet_hash(pack, 2, "1");
     2481        yahoo_packet_hash(pack, 98, "us");
     2482        yahoo_packet_hash(pack, 135, "7.5.0.647");
     2483       
     2484        yahoo_send_packet(yid, pack, 0);
     2485               
     2486        yahoo_packet_free(pack);
     2487       
     2488fail:
     2489        g_free(crumb);
     2490        g_free(had->token);
     2491        g_free(had->chal);
     2492        g_free(had);
     2493}
     2494
    22282495static void yahoo_process_auth(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
    22292496{
     
    22532520                case 1:
    22542521                        yahoo_process_auth_0x0b(yid, seed, sn);
     2522                        break;
     2523                case 2:
     2524                        yahoo_process_auth_0x10(yid, seed, sn);
    22552525                        break;
    22562526                default:
     
    24082678               
    24092679                yd->buddies = y_list_append(yd->buddies, bud);
    2410                
     2680       
    24112681                /* Possibly called already, but at least the call above doesn't
    24122682                   seem to happen every time (not anytime I tried). */
     
    24152685
    24162686/*      YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, who, status, NULL, (status==YAHOO_STATUS_AVAILABLE?0:1)); */
     2687}
     2688
     2689static void yahoo_process_contact_ymsg13(struct yahoo_input_data *yid, struct yahoo_packet *pkt)
     2690{
     2691        char* who=NULL;
     2692        char* me=NULL; 
     2693        char* msg=NULL;
     2694        YList *l;
     2695        for (l = pkt->hash; l; l = l->next) {
     2696                struct yahoo_pair *pair = l->data;
     2697                if (pair->key == 4)
     2698                        who = pair->value;
     2699                else if (pair->key == 5)
     2700                        me = pair->value;
     2701                else
     2702                        DEBUG_MSG(("unknown key: %d = %s", pair->key, pair->value));
     2703        }
     2704
     2705        if(pkt->status==3)
     2706                YAHOO_CALLBACK(ext_yahoo_contact_auth_request)(yid->yd->client_id, me, who, msg);
    24172707}
    24182708
     
    26282918
    26292919        YList *l;
    2630         yahoo_dump_unhandled(pkt);
     2920        // yahoo_dump_unhandled(pkt);
    26312921        for (l = pkt->hash; l; l = l->next) {
    26322922                struct yahoo_pair *pair = l->data;
     
    26502940{
    26512941        DEBUG_MSG(("yahoo_packet_process: 0x%02x", pkt->service));
     2942        yahoo_dump_unhandled(pkt);
    26522943        switch (pkt->service)
    26532944        {
     
    26612952        case YAHOO_SERVICE_IDACT:
    26622953        case YAHOO_SERVICE_IDDEACT:
     2954        case YAHOO_SERVICE_Y6_STATUS_UPDATE:
     2955        case YAHOO_SERVICE_YMSG15_STATUS:
    26632956                yahoo_process_status(yid, pkt);
    26642957                break;
     
    26742967                yahoo_process_mail(yid, pkt);
    26752968                break;
     2969        case YAHOO_SERVICE_REJECTCONTACT:
    26762970        case YAHOO_SERVICE_NEWCONTACT:
    26772971                yahoo_process_contact(yid, pkt);
     
    27143008                yahoo_process_buddyadd(yid, pkt);
    27153009                break;
     3010        case YAHOO_SERVICE_CONTACT_YMSG13:
     3011                yahoo_process_contact_ymsg13(yid,pkt);
     3012                break;
    27163013        case YAHOO_SERVICE_REMBUDDY:
    27173014                yahoo_process_buddydel(yid, pkt);
     
    27423039        case YAHOO_SERVICE_CHATLOGOFF:
    27433040        case YAHOO_SERVICE_CHATMSG:
    2744         case YAHOO_SERVICE_REJECTCONTACT:
    27453041        case YAHOO_SERVICE_PEERTOPEER:
    27463042                WARNING(("unhandled service 0x%02x", pkt->service));
     
    27563052                yahoo_process_picture_upload(yid, pkt);
    27573053                break; 
     3054        case YAHOO_SERVICE_YMSG15_BUDDY_LIST:   /* Buddy List */
     3055                yahoo_process_buddy_list(yid, pkt);
    27583056        default:
    27593057                WARNING(("unknown service 0x%02x", pkt->service));
     
    35393837        yahoo_process_webcam_connection,
    35403838        yahoo_process_chatcat_connection,
    3541         yahoo_process_search_connection
     3839        yahoo_process_search_connection,
    35423840};
    35433841
     
    35573855        } while(len == -1 && errno == EINTR);
    35583856
    3559         if(len == -1 && errno == EAGAIN)        /* we'll try again later */
     3857        if(len == -1 && (errno == EAGAIN||errno == EINTR))      /* we'll try again later */
    35603858                return 1;
    35613859
     
    37604058
    37614059        yahoo_packet_hash(pkt, 5, who);
    3762         yahoo_packet_hash(pkt, 4, from?from:yd->user);
     4060        yahoo_packet_hash(pkt, 1, from?from:yd->user);
    37634061        yahoo_packet_hash(pkt, 14, " ");
    37644062        yahoo_packet_hash(pkt, 13, typ ? "1" : "0");
     
    37754073        struct yahoo_data *yd;
    37764074        struct yahoo_packet *pkt = NULL;
    3777         int service;
     4075        int old_status;
    37784076        char s[4];
    37794077
     
    37834081        yd = yid->yd;
    37844082
    3785         if (msg) {
     4083        old_status = yd->current_status;
     4084
     4085        if (msg && strncmp(msg,"Invisible",9)) {
    37864086                yd->current_status = YAHOO_STATUS_CUSTOM;
    37874087        } else {
     
    37894089        }
    37904090
    3791         if (yd->current_status == YAHOO_STATUS_AVAILABLE)
    3792                 service = YAHOO_SERVICE_ISBACK;
    3793         else
    3794                 service = YAHOO_SERVICE_ISAWAY;
     4091        /* Thank you libpurple :) */
     4092        if (yd->current_status == YAHOO_STATUS_INVISIBLE) {
     4093                pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBILITY, YAHOO_STATUS_AVAILABLE, 0);
     4094                yahoo_packet_hash(pkt, 13, "2");
     4095                yahoo_send_packet(yid, pkt, 0);
     4096                yahoo_packet_free(pkt);
     4097
     4098                return;
     4099        }
     4100
     4101        pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_STATUS_UPDATE, yd->current_status, yd->session_id);
     4102        snprintf(s, sizeof(s), "%d", yd->current_status);
     4103        yahoo_packet_hash(pkt, 10, s);
    37954104         
    3796         if ((away == 2) && (yd->current_status == YAHOO_STATUS_AVAILABLE)) {
    3797                 pkt = yahoo_packet_new(YAHOO_SERVICE_ISAWAY, YAHOO_STATUS_BRB, yd->session_id);
    3798                 yahoo_packet_hash(pkt, 10, "999");
    3799                 yahoo_packet_hash(pkt, 47, "2");
    3800         }else {
    3801                 pkt = yahoo_packet_new(service, YAHOO_STATUS_AVAILABLE, yd->session_id);
    3802                 snprintf(s, sizeof(s), "%d", yd->current_status);
    3803                 yahoo_packet_hash(pkt, 10, s);
    3804                 if (yd->current_status == YAHOO_STATUS_CUSTOM) {
    3805                         yahoo_packet_hash(pkt, 19, msg);
    3806                         yahoo_packet_hash(pkt, 47, (away == 2)? "2": (away) ?"1":"0");
    3807                 } else {
    3808                         yahoo_packet_hash(pkt, 47, (away == 2)? "2": (away) ?"1":"0");
    3809                 }
    3810                
    3811                
    3812                
    3813         }
     4105        if (yd->current_status == YAHOO_STATUS_CUSTOM) {
     4106                yahoo_packet_hash(pkt, 19, msg);
     4107        } else {
     4108                yahoo_packet_hash(pkt, 19, "");
     4109        }
     4110       
     4111        yahoo_packet_hash(pkt, 47, (away == 2)? "2": (away) ?"1":"0");
    38144112
    38154113        yahoo_send_packet(yid, pkt, 0);
    38164114        yahoo_packet_free(pkt);
     4115
     4116        if(old_status == YAHOO_STATUS_INVISIBLE) {
     4117                pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBILITY, YAHOO_STATUS_AVAILABLE, 0);
     4118                yahoo_packet_hash(pkt, 13, "1");
     4119                yahoo_send_packet(yid, pkt, 0);
     4120                yahoo_packet_free(pkt);
     4121        }
    38174122}
    38184123
     
    38294134        LOG(("yahoo_logoff: current status: %d", yd->current_status));
    38304135
    3831         if(yd->current_status != -1) {
     4136        if(yd->current_status != -1 && 0) {
     4137                /* Meh. Don't send this. The event handlers are not going to
     4138                   get to do this so it'll just leak memory. And the TCP
     4139                   connection reset will hopefully be clear enough. */
    38324140                pkt = yahoo_packet_new(YAHOO_SERVICE_LOGOFF, YAHOO_STATUS_AVAILABLE, yd->session_id);
    38334141                yd->current_status = -1;
     
    40624370                return;
    40634371
    4064         pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, yd->session_id);
    4065         yahoo_packet_hash(pkt, 1, yd->user);
    4066         yahoo_packet_hash(pkt, 7, who);
    4067         yahoo_packet_hash(pkt, 65, group);
     4372        pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YPACKET_STATUS_DEFAULT, yd->session_id);
     4373
    40684374        if (msg != NULL) /* add message/request "it's me add me" */
    40694375                yahoo_packet_hash(pkt, 14, msg);
     4376        else
     4377                yahoo_packet_hash(pkt,14,"");
     4378
     4379        yahoo_packet_hash(pkt, 65, group);
     4380        yahoo_packet_hash(pkt, 97, "1");
     4381        yahoo_packet_hash(pkt, 1, yd->user);
     4382        yahoo_packet_hash(pkt, 302, "319");
     4383        yahoo_packet_hash(pkt, 300, "319");
     4384        yahoo_packet_hash(pkt, 7, who);
     4385        yahoo_packet_hash(pkt, 334, "0");
     4386        yahoo_packet_hash(pkt, 301, "319");
     4387        yahoo_packet_hash(pkt, 303, "319");
     4388
     4389
    40704390        yahoo_send_packet(yid, pkt, 0);
    40714391        yahoo_packet_free(pkt);
     
    40894409        yahoo_send_packet(yid, pkt, 0);
    40904410        yahoo_packet_free(pkt);
     4411}
     4412
     4413void yahoo_accept_buddy_ymsg13(int id,const char* me,const char* who){
     4414        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4415        struct yahoo_data *yd;
     4416
     4417        if(!yid)
     4418                return;
     4419        yd = yid->yd;
     4420
     4421        struct yahoo_packet* pkt=NULL;
     4422        pkt= yahoo_packet_new(YAHOO_SERVICE_CONTACT_YMSG13,YAHOO_STATUS_AVAILABLE,0);
     4423
     4424        yahoo_packet_hash(pkt,1,me ?: yd->user);       
     4425        yahoo_packet_hash(pkt,5,who);
     4426        yahoo_packet_hash(pkt,13,"1");
     4427        yahoo_packet_hash(pkt,334,"0");
     4428        yahoo_send_packet(yid, pkt, 0);
     4429        yahoo_packet_free(pkt);
     4430}
     4431
     4432void yahoo_reject_buddy_ymsg13(int id,const char* me,const char* who,const char* msg){
     4433        struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
     4434        struct yahoo_data *yd;
     4435
     4436        if(!yid)
     4437                return;
     4438        yd = yid->yd;
     4439
     4440        struct yahoo_packet* pkt=NULL;
     4441        pkt= yahoo_packet_new(YAHOO_SERVICE_CONTACT_YMSG13,YAHOO_STATUS_AVAILABLE,0);
     4442
     4443        yahoo_packet_hash(pkt,1,me ?: yd->user);       
     4444        yahoo_packet_hash(pkt,5,who);
     4445//      yahoo_packet_hash(pkt,241,YAHOO_PROTO_VER);
     4446        yahoo_packet_hash(pkt,13,"2");
     4447        yahoo_packet_hash(pkt,334,"0");
     4448        yahoo_packet_hash(pkt,97,"1");
     4449        yahoo_packet_hash(pkt,14,msg?:"");
     4450
     4451        yahoo_send_packet(yid, pkt, 0);
     4452        yahoo_packet_free(pkt);
     4453
    40914454}
    40924455
  • protocols/yahoo/yahoo.c

    raac4017 r2288705  
    197197{
    198198        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
    199        
    200         ic->away = NULL;
     199        char *away;
     200       
     201        away = NULL;
    201202       
    202203        if( state && msg && g_strcasecmp( state, msg ) != 0 )
    203204        {
    204205                yd->current_status = YAHOO_STATUS_CUSTOM;
    205                 ic->away = "";
     206                away = "";
    206207        }
    207208        else if( state )
     
    212213                msg = NULL;
    213214               
    214                 ic->away = "";
     215                away = "";
    215216                if( g_strcasecmp( state, "Available" ) == 0 )
    216217                {
    217218                        yd->current_status = YAHOO_STATUS_AVAILABLE;
    218                         ic->away = NULL;
     219                        away = NULL;
    219220                }
    220221                else if( g_strcasecmp( state, "Be Right Back" ) == 0 )
     
    242243                        yd->current_status = YAHOO_STATUS_AVAILABLE;
    243244                       
    244                         ic->away = NULL;
     245                        away = NULL;
    245246                }
    246247        }
     
    248249                yd->current_status = YAHOO_STATUS_AVAILABLE;
    249250       
    250         yahoo_set_away( yd->y2_id, yd->current_status, msg, ic->away != NULL ? 2 : 0 );
     251        yahoo_set_away( yd->y2_id, yd->current_status, msg, away != NULL ? 2 : 0 );
    251252}
    252253
    253254static GList *byahoo_away_states( struct im_connection *ic )
    254255{
    255         GList *m = NULL;
    256 
    257         m = g_list_append( m, "Available" );
    258         m = g_list_append( m, "Be Right Back" );
    259         m = g_list_append( m, "Busy" );
    260         m = g_list_append( m, "Not At Home" );
    261         m = g_list_append( m, "Not At Desk" );
    262         m = g_list_append( m, "Not In Office" );
    263         m = g_list_append( m, "On Phone" );
    264         m = g_list_append( m, "On Vacation" );
    265         m = g_list_append( m, "Out To Lunch" );
    266         m = g_list_append( m, "Stepped Out" );
    267         m = g_list_append( m, "Invisible" );
    268         m = g_list_append( m, GAIM_AWAY_CUSTOM );
     256        static GList *m = NULL;
     257
     258        if( m == NULL )
     259        {
     260                m = g_list_append( m, "Available" );
     261                m = g_list_append( m, "Be Right Back" );
     262                m = g_list_append( m, "Busy" );
     263                m = g_list_append( m, "Not At Home" );
     264                m = g_list_append( m, "Not At Desk" );
     265                m = g_list_append( m, "Not In Office" );
     266                m = g_list_append( m, "On Phone" );
     267                m = g_list_append( m, "On Vacation" );
     268                m = g_list_append( m, "Out To Lunch" );
     269                m = g_list_append( m, "Stepped Out" );
     270                m = g_list_append( m, "Invisible" );
     271                m = g_list_append( m, GAIM_AWAY_CUSTOM );
     272        }
    269273       
    270274        return m;
     
    345349       
    346350        return c;
     351}
     352
     353static void byahoo_auth_allow( struct im_connection *ic, const char *who )
     354{
     355        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
     356       
     357        yahoo_accept_buddy_ymsg13( yd->y2_id, NULL, who );
     358}
     359
     360static void byahoo_auth_deny( struct im_connection *ic, const char *who )
     361{
     362        struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
     363       
     364        yahoo_reject_buddy_ymsg13( yd->y2_id, NULL, who, NULL );
    347365}
    348366
     
    372390        ret->handle_cmp = g_strcasecmp;
    373391       
     392        ret->auth_allow = byahoo_auth_allow;
     393        ret->auth_deny = byahoo_auth_deny;
     394       
    374395        register_protocol(ret);
    375396}
     
    451472        struct byahoo_write_ready_data *d = data;
    452473       
    453         yahoo_write_ready( d->id, d->fd, d->data );
    454        
    455         return FALSE;
     474        return yahoo_write_ready( d->id, d->fd, d->data );
    456475}
    457476
     
    790809{
    791810        struct byahoo_conf_invitation *inv = data;
    792        
    793         yahoo_conference_logon( inv->yid, NULL, inv->members, inv->name );
    794         imcb_chat_add_buddy( inv->c, inv->ic->acc->user );
     811        struct groupchat *b;
     812       
     813        for( b = inv->ic->groupchats; b; b = b->next )
     814                if( b == inv->c )
     815                        break;
     816       
     817        if( b != NULL )
     818        {
     819                yahoo_conference_logon( inv->yid, NULL, inv->members, inv->name );
     820                imcb_chat_add_buddy( inv->c, inv->ic->acc->user );
     821        }
     822        else
     823        {
     824                imcb_log( inv->ic, "Duplicate/corrupted invitation to `%s'.", inv->name );
     825        }
     826       
    795827        g_free( inv->name );
    796828        g_free( inv );
     
    908940}
    909941
     942void ext_yahoo_contact_auth_request( int id, const char *myid, const char *who, const char *msg )
     943{
     944        struct im_connection *ic = byahoo_get_ic_by_id( id );
     945       
     946        imcb_ask_auth( ic, who, NULL );
     947}
     948
    910949void ext_yahoo_contact_added( int id, const char *myid, const char *who, const char *msg )
    911950{
    912         /* Groups schmoups. If I want to handle groups properly I can get the
    913            buddy data from some internal libyahoo2 structure. */
    914         imcb_add_buddy( byahoo_get_ic_by_id( id ), (char*) who, NULL );
     951        struct im_connection *ic = byahoo_get_ic_by_id( id );
     952       
     953        imcb_add_buddy( ic, (char*) who, NULL );
    915954}
    916955
  • protocols/yahoo/yahoo2.h

    raac4017 r2288705  
    217217void yahoo_buddyicon_request(int id, const char *who);
    218218
     219void yahoo_accept_buddy_ymsg13(int,const char*,const char*);
     220void yahoo_reject_buddy_ymsg13(int,const char*,const char*,const char*);
     221
    219222#include "yahoo_httplib.h"
    220223
  • protocols/yahoo/yahoo2_callbacks.h

    raac4017 r2288705  
    361361
    362362/*
     363 * Name: ext_yahoo_contact_auth_request
     364 *      Called when a contact wants to add you to his/her contact list
     365 * Params:
     366 *      id   - the id that identifies the server connection
     367 *      myid - the identity s/he added
     368 *      who  - who did it
     369 *      msg  - any message sent
     370 */
     371void YAHOO_CALLBACK_TYPE(ext_yahoo_contact_auth_request)(int id, const char *myid, const char *who, const char *msg);
     372
     373
     374/*
    363375 * Name: ext_yahoo_contact_added
    364376 *      Called when a contact is added to your list
  • protocols/yahoo/yahoo2_types.h

    raac4017 r2288705  
    5757        YAHOO_LOGIN_LOCK = 14,
    5858        YAHOO_LOGIN_DUPL = 99,
    59         YAHOO_LOGIN_SOCK = -1
     59        YAHOO_LOGIN_SOCK = -1,
     60};
     61
     62enum ypacket_status {
     63        YPACKET_STATUS_DISCONNECTED = -1,
     64        YPACKET_STATUS_DEFAULT = 0,
     65        YPACKET_STATUS_SERVERACK = 1,
     66        YPACKET_STATUS_GAME     = 0x2,
     67        YPACKET_STATUS_AWAY     = 0x4,
     68        YPACKET_STATUS_CONTINUED = 0x5,
     69        YPACKET_STATUS_INVISIBLE = 12,
     70        YPACKET_STATUS_NOTIFY = 0x16, /* TYPING */
     71        YPACKET_STATUS_WEBLOGIN = 0x5a55aa55,
     72        YPACKET_STATUS_OFFLINE = 0x5a55aa56
    6073};
    6174
     
    8598};
    8699
    87 #define YAHOO_PROTO_VER 0x000b
     100#define YAHOO_PROTO_VER 0x0010
    88101
    89102/* Yahoo style/color directives */
     
    115128        YAHOO_CONNECTION_WEBCAM,
    116129        YAHOO_CONNECTION_CHATCAT,
    117         YAHOO_CONNECTION_SEARCH
     130        YAHOO_CONNECTION_SEARCH,
     131        YAHOO_CONNECTION_AUTH,
    118132};
    119133
     
    131145/* chat member attribs */
    132146#define YAHOO_CHAT_MALE 0x8000
    133 #define YAHOO_CHAT_FEMALE 0x10000
    134147#define YAHOO_CHAT_FEMALE 0x10000
    135148#define YAHOO_CHAT_DUNNO 0x400
Note: See TracChangeset for help on using the changeset viewer.