Changeset e35d1a1


Ignore:
Timestamp:
2007-04-22T20:44:27Z (17 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
43671b9
Parents:
c737ba7
Message:

Read-only support for Jabber conferences (non-anonymous rooms only).
Just don't use this, you're really not going to like it. :-)

Files:
1 added
13 edited

Legend:

Unmodified
Added
Removed
  • protocols/jabber/Makefile

    rc737ba7 re35d1a1  
    1010
    1111# [SH] Program variables
    12 objects = io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o xmltree.o
     12objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o xmltree.o
    1313
    1414CFLAGS += -Wall
  • protocols/jabber/jabber.c

    rc737ba7 re35d1a1  
    324324}
    325325
     326static struct groupchat *jabber_chat_join_( struct im_connection *ic, char *room, char *nick, char *password )
     327{
     328        if( strchr( room, '@' ) == NULL )
     329                imcb_error( ic, "Invalid room name: %s", room );
     330        else if( jabber_chat_by_name( ic, room ) )
     331                imcb_error( ic, "Already present in chat `%s'", room );
     332        else
     333                return jabber_chat_join( ic, room, nick, password );
     334       
     335        return NULL;
     336}
     337
     338static void jabber_chat_leave_( struct groupchat *c )
     339{
     340        if( c )
     341                jabber_chat_leave( c, NULL );
     342}
     343
    326344static void jabber_keepalive( struct im_connection *ic )
    327345{
     
    396414//      ret->chat_msg = jabber_chat_msg;
    397415//      ret->chat_invite = jabber_chat_invite;
    398 //      ret->chat_leave = jabber_chat_leave;
    399 //      ret->chat_open = jabber_chat_open;
     416        ret->chat_leave = jabber_chat_leave_;
     417        ret->chat_join = jabber_chat_join_;
    400418        ret->keepalive = jabber_keepalive;
    401419        ret->send_typing = jabber_send_typing;
  • protocols/jabber/jabber.h

    rc737ba7 re35d1a1  
    5050        JBFLAG_DOES_XEP85 = 2,          /* Set this when the resource seems to support
    5151                                           XEP85 (typing notification shite). */
     52        JBFLAG_IS_CHATROOM = 4,         /* It's convenient to use this JID thingy for
     53                                           groupchat state info too. */
    5254} jabber_buddy_flags_t;
    5355
     
    101103        char *resource;
    102104       
     105        /* Groupchat-only */
     106        char *orig_jid;
     107       
    103108        int priority;
    104109        struct jabber_away_state *away_state;
     
    109114       
    110115        struct jabber_buddy *next;
     116};
     117
     118struct jabber_chat
     119{
     120        int flags;
     121        char *name;
     122        struct jabber_buddy *me;
    111123};
    112124
     
    134146#define XMLNS_CHATSTATES   "http://jabber.org/protocol/chatstates"  /* 0085 */
    135147#define XMLNS_DISCOVER     "http://jabber.org/protocol/disco#info"  /* 0030 */
     148#define XMLNS_MUC          "http://jabber.org/protocol/muc"     /* XEP-0045 */
     149#define XMLNS_MUC_USER     "http://jabber.org/protocol/muc#user"/* XEP-0045 */
    136150
    137151/* iq.c */
     
    164178const struct jabber_away_state *jabber_away_state_by_name( char *name );
    165179void jabber_buddy_ask( struct im_connection *ic, char *handle );
    166 char *jabber_normalize( char *orig );
     180char *jabber_normalize( const char *orig );
    167181
    168182typedef enum
    169183{
    170184        GET_BUDDY_CREAT = 1,    /* Try to create it, if necessary. */
    171         GET_BUDDY_EXACT = 2,    /* Get an exact message (only makes sense with bare JIDs). */
     185        GET_BUDDY_EXACT = 2,    /* Get an exact match (only makes sense with bare JIDs). */
     186        GET_BUDDY_FIRST = 4,    /* No selection, simply get the first resource for this JID. */
    172187} get_buddy_flags_t;
    173188
     
    176191int jabber_buddy_remove( struct im_connection *ic, char *full_jid );
    177192int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid );
     193struct groupchat *jabber_chat_by_name( struct im_connection *ic, const char *name );
    178194
    179195extern const struct jabber_away_state jabber_away_state_list[];
     
    193209gboolean sasl_supported( struct im_connection *ic );
    194210
     211/* conference.c */
     212struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char *nick, char *password );
     213int jabber_chat_leave( struct groupchat *c, const char *reason );
     214void jabber_chat_pkt_presence( struct im_connection *ic, struct jabber_buddy *bud, struct xt_node *node );
     215void jabber_chat_pkt_message( struct im_connection *ic, struct jabber_buddy *bud, struct xt_node *node );
     216
    195217#endif
  • protocols/jabber/jabber_util.c

    rc737ba7 re35d1a1  
    4848                   call p_s_u() now to send the new prio setting, it would
    4949                   send the old setting because the set->value gets changed
    50                    when the eval returns a non-NULL value.
     50                   after the (this) eval returns a non-NULL value.
    5151                   
    5252                   So now I can choose between implementing post-set
     
    129129/* Cache a node/packet for later use. Mainly useful for IQ packets if you need
    130130   them when you receive the response. Use this BEFORE sending the packet so
    131    it'll get a new id= tag, and do NOT free() the packet after writing it! */
     131   it'll get a new id= tag, and do NOT free() the packet after sending it! */
    132132void jabber_cache_add( struct im_connection *ic, struct xt_node *node, jabber_cache_event func )
    133133{
     
    252252
    253253/* Returns a new string. Don't leak it! */
    254 char *jabber_normalize( char *orig )
     254char *jabber_normalize( const char *orig )
    255255{
    256256        int len, i;
     
    353353        if( ( s = strchr( jid, '/' ) ) )
    354354        {
     355                int none_found = 0;
     356               
    355357                *s = 0;
    356358                if( ( bud = g_hash_table_lookup( jd->buddies, jid ) ) )
     
    370372                        }
    371373                }
    372                
    373                 if( bud == NULL && ( flags & GET_BUDDY_CREAT ) && imcb_find_buddy( ic, jid ) )
     374                else
     375                {
     376                        /* This hack is there to make sure that O_CREAT will
     377                           work if there's already another resouce present
     378                           for this JID, even if it's an unknown buddy. This
     379                           is done to handle conferences properly. */
     380                        none_found = 1;
     381                }
     382               
     383                if( bud == NULL && ( flags & GET_BUDDY_CREAT ) && ( imcb_find_buddy( ic, jid ) || !none_found ) )
    374384                {
    375385                        *s = '/';
     
    531541        }
    532542}
     543
     544struct groupchat *jabber_chat_by_name( struct im_connection *ic, const char *name )
     545{
     546        char *normalized = jabber_normalize( name );
     547        struct groupchat *ret;
     548        struct jabber_chat *jc;
     549       
     550        for( ret = ic->groupchats; ret; ret = ret->next )
     551        {
     552                jc = ret->data;
     553                if( strcmp( normalized, jc->name ) == 0 )
     554                        break;
     555        }
     556        g_free( normalized );
     557       
     558        return ret;
     559}
  • protocols/jabber/message.c

    rc737ba7 re35d1a1  
    3030        char *type = xt_find_attr( node, "type" );
    3131        struct xt_node *body = xt_find_node( node->children, "body" ), *c;
     32        struct jabber_buddy *bud = NULL;
    3233        char *s;
     34       
     35        if( !from )
     36                return XT_HANDLED; /* Consider this packet corrupted. */
     37       
     38        bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT );
    3339       
    3440        if( type && strcmp( type, "error" ) == 0 )
     
    3642                /* Handle type=error packet. */
    3743        }
    38         else if( type && strcmp( type, "groupchat" ) == 0 )
     44        else if( type && from && strcmp( type, "groupchat" ) == 0 )
    3945        {
    40                 /* TODO! */
     46                jabber_chat_pkt_message( ic, bud, node );
    4147        }
    4248        else /* "chat", "normal", "headline", no-type or whatever. Should all be pretty similar. */
    4349        {
    44                 struct jabber_buddy *bud = NULL;
    4550                GString *fullmsg = g_string_new( "" );
    4651               
    4752                if( ( s = strchr( from, '/' ) ) )
    4853                {
    49                         if( ( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT ) ) )
     54                        if( bud )
    5055                                bud->last_act = time( NULL );
    5156                        else
  • protocols/jabber/presence.c

    rc737ba7 re35d1a1  
    3131        struct xt_node *c;
    3232        struct jabber_buddy *bud;
     33        int is_chat = 0;
    3334        char *s;
    3435       
    3536        if( !from )
    3637                return XT_HANDLED;
     38       
     39        if( ( s = strchr( from, '/' ) ) )
     40        {
     41                *s = 0;
     42                if( jabber_chat_by_name( ic, from ) )
     43                        is_chat = 1;
     44                *s = '/';
     45        }
    3746       
    3847        if( type == NULL )
     
    7281                        bud->priority = 0;
    7382               
    74                 if( bud == jabber_buddy_by_jid( ic, bud->bare_jid, 0 ) )
     83                if( is_chat )
     84                        jabber_chat_pkt_presence( ic, bud, node );
     85                else if( bud == jabber_buddy_by_jid( ic, bud->bare_jid, 0 ) )
    7586                        imcb_buddy_status( ic, bud->bare_jid, OPT_LOGGED_IN | is_away,
    7687                                           ( is_away && bud->away_state ) ? bud->away_state->full_name : NULL,
     
    7990        else if( strcmp( type, "unavailable" ) == 0 )
    8091        {
    81                 if( jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT ) == NULL )
     92                if( ( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT ) ) == NULL )
    8293                {
    8394                        if( set_getbool( &ic->irc->set, "debug" ) )
     
    8697                }
    8798               
     99                /* Handle this before we delete the JID. */
     100                if( is_chat )
     101                {
     102                        jabber_chat_pkt_presence( ic, bud, node );
     103                }
     104               
    88105                jabber_buddy_remove( ic, from );
    89106               
    90                 if( ( s = strchr( from, '/' ) ) )
     107                if( is_chat )
     108                {
     109                        /* Nothing else to do for now? */
     110                }
     111                else if( ( s = strchr( from, '/' ) ) )
    91112                {
    92113                        *s = 0;
     
    96117                        if( jabber_buddy_by_jid( ic, from, 0 ) == NULL )
    97118                                imcb_buddy_status( ic, from, 0, NULL, NULL );
     119                        /* FIXME: If this resource was not away and another resource is,
     120                           we should definitely send an update here. */
    98121                       
    99122                        *s = '/';
  • protocols/jabber/xmltree.c

    rc737ba7 re35d1a1  
    188188                                               g_strcasecmp( xt->handlers[i].parent, "<root>" ) == 0 ) ) )
    189189                        {
     190                                xt_print( node );
     191                               
    190192                                st = xt->handlers[i].func( node, xt->data );
    191193                               
  • protocols/msn/sb.c

    rc737ba7 re35d1a1  
    232232        if( sb->chat )
    233233        {
    234                 imcb_chat_removed( sb->chat );
     234                imcb_chat_free( sb->chat );
    235235        }
    236236       
  • protocols/nogaim.c

    rc737ba7 re35d1a1  
    554554                u->online = 0;
    555555               
    556                 /* Remove him/her from the conversations to prevent PART messages after he/she QUIT already */
    557                 for( c = ic->conversations; c; c = c->next )
     556                /* Remove him/her from the groupchats to prevent PART messages after he/she QUIT already */
     557                for( c = ic->groupchats; c; c = c->next )
    558558                        remove_chat_buddy_silent( c, (char*) handle );
    559559        }
     
    685685}
    686686
    687 void imcb_chat_removed( struct groupchat *c )
     687void imcb_chat_free( struct groupchat *c )
    688688{
    689689        struct im_connection *ic = c->ic;
    690         struct groupchat *l = NULL;
     690        struct groupchat *l;
    691691        GList *ir;
    692692       
     
    708708                }
    709709               
     710                /* Find the previous chat in the linked list. */
     711                for( l = ic->groupchats; l && l->next != c; l = l->next );
     712               
    710713                if( l )
    711714                        l->next = c->next;
    712715                else
    713                         ic->conversations = c->next;
     716                        ic->groupchats = c->next;
    714717               
    715718                for( ir = c->in_room; ir; ir = ir->next )
     
    749752        /* This one just creates the conversation structure, user won't see anything yet */
    750753       
    751         if( ic->conversations )
    752         {
    753                 for( c = ic->conversations; c->next; c = c->next );
     754        if( ic->groupchats )
     755        {
     756                for( c = ic->groupchats; c->next; c = c->next );
    754757                c = c->next = g_new0( struct groupchat, 1 );
    755758        }
    756759        else
    757                 ic->conversations = c = g_new0( struct groupchat, 1 );
     760                ic->groupchats = c = g_new0( struct groupchat, 1 );
    758761       
    759762        c->ic = ic;
     
    863866        {
    864867                ic = l->data;
    865                 for( c = ic->conversations; c && g_strcasecmp( c->channel, channel ) != 0; c = c->next );
     868                for( c = ic->groupchats; c && g_strcasecmp( c->channel, channel ) != 0; c = c->next );
    866869                if( c )
    867870                        return c;
  • protocols/nogaim.h

    rc737ba7 re35d1a1  
    9191        irc_t *irc;
    9292       
    93         struct groupchat *conversations;
     93        struct groupchat *groupchats;
    9494};
    9595
     
    9797        struct im_connection *ic;
    9898
    99         /* stuff used just for chat */
    10099        GList *in_room;
    101100        GList *ignored;
    102101       
    103         /* BitlBee */
    104102        struct groupchat *next;
    105103        char *channel;
     
    208206G_MODULE_EXPORT void imcb_chat_remove_buddy( struct groupchat *b, char *handle, char *reason );
    209207G_MODULE_EXPORT void imcb_chat_msg( struct groupchat *c, char *who, char *msg, u_int32_t flags, time_t sent_at );
    210 G_MODULE_EXPORT void imcb_chat_removed( struct groupchat *c );
     208G_MODULE_EXPORT void imcb_chat_free( struct groupchat *c );
    211209struct groupchat *chat_by_channel( char *channel );
    212210
  • protocols/oscar/oscar.c

    rc737ba7 re35d1a1  
    25132513
    25142514        /* Notify the conversation window that we've left the chat */
    2515         imcb_chat_removed(cc->cnv);
     2515        imcb_chat_free(cc->cnv);
    25162516
    25172517        /* Destroy the chat_connection */
  • protocols/yahoo/yahoo.c

    rc737ba7 re35d1a1  
    145145        GSList *l;
    146146       
    147         while( ic->conversations )
    148                 imcb_chat_removed( ic->conversations );
     147        while( ic->groupchats )
     148                imcb_chat_free( ic->groupchats );
    149149       
    150150        for( l = yd->buddygroups; l; l = l->next )
     
    318318       
    319319        yahoo_conference_logoff( yd->y2_id, NULL, c->data, c->title );
    320         imcb_chat_removed( c );
     320        imcb_chat_free( c );
    321321}
    322322
     
    798798{
    799799        yahoo_conference_decline( inv->yid, NULL, inv->members, inv->name, "User rejected groupchat" );
    800         imcb_chat_removed( inv->c );
     800        imcb_chat_free( inv->c );
    801801        g_free( inv->name );
    802802        g_free( inv );
     
    841841        struct groupchat *c;
    842842       
    843         for( c = ic->conversations; c && strcmp( c->title, room ) != 0; c = c->next );
     843        for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
    844844       
    845845        if( c )
     
    853853        struct groupchat *c;
    854854       
    855         for( c = ic->conversations; c && strcmp( c->title, room ) != 0; c = c->next );
     855        for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
    856856       
    857857        if( c )
     
    865865        struct groupchat *c;
    866866       
    867         for( c = ic->conversations; c && strcmp( c->title, room ) != 0; c = c->next );
     867        for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
    868868       
    869869        if( c )
  • root_commands.c

    rc737ba7 re35d1a1  
    924924        if( cmd[3] && cmd[4] )
    925925                nick = cmd[4];
     926        else
     927                nick = irc->nick;
    926928        if( cmd[3] && cmd[4] && cmd[5] )
    927929                password = cmd[5];
    928930       
    929         c = a->prpl->chat_join( ic, chat, nick, password );
    930        
    931         g_free( channel );
     931        if( ( c = a->prpl->chat_join( ic, chat, nick, password ) ) )
     932        {
     933                g_free( c->channel );
     934                c->channel = channel;
     935        }
     936        else
     937        {
     938                irc_usermsg( irc, "Tried to join chat, not sure if this was successful" );
     939                g_free( channel );
     940        }
    932941}
    933942
Note: See TracChangeset for help on using the changeset viewer.