Changes in / [256899f:cd428e4]


Ignore:
Files:
1 deleted
25 edited

Legend:

Unmodified
Added
Removed
  • doc/user-guide/commands.xml

    r256899f rcd428e4  
    685685        </bitlbee-setting>
    686686
    687         <bitlbee-setting name="xmlconsole" type="boolean" scope="account">
    688                 <default>false</default>
    689 
    690                 <description>
    691                         <para>
    692                                 The Jabber module allows you to add a buddy <emphasis>xmlconsole</emphasis> to your contact list, which will then show you the raw XMPP stream between you and the server. You can also send XMPP packets to this buddy, which will then be sent to the server.
    693                         </para>
    694                         <para>
    695                                 If you want to enable this XML console permanently (and at login time already), you can set this setting.
    696                         </para>
    697                 </description>
    698         </bitlbee-setting>
    699 
    700687        <bitlbee-command name="rename">
    701688                <short-description>Rename (renick) a buddy</short-description>
  • doc/user-guide/misc.xml

    r256899f rcd428e4  
    8181
    8282<para>
    83 Some protocols (like Jabber) also support named groupchats. BitlBee now supports these too. You can use the <emphasis>join_chat</emphasis> command to join them. See <emphasis>help join_chat</emphasis> for more information.
    84 </para>
    85 
    86 <para>
    8783This is all you'll probably need to know. If you have any problems, please read <emphasis>help groupchats3</emphasis>.
    8884</para>
  • irc.c

    r256899f rcd428e4  
    641641                }
    642642        }
    643         else if( ( c = irc_chat_by_channel( irc, channel ) ) )
     643        else if( ( c = chat_by_channel( channel ) ) )
    644644        {
    645645                GList *l;
     
    788788void irc_topic( irc_t *irc, char *channel )
    789789{
    790         struct groupchat *c = irc_chat_by_channel( irc, channel );
    791        
    792         if( c && c->topic )
    793                 irc_reply( irc, 332, "%s :%s", channel, c->topic );
    794         else if( g_strcasecmp( channel, irc->channel ) == 0 )
     790        if( g_strcasecmp( channel, irc->channel ) == 0 )
     791        {
    795792                irc_reply( irc, 332, "%s :%s", channel, CONTROL_TOPIC );
     793        }
    796794        else
    797                 irc_reply( irc, 331, "%s :No topic for this channel", channel );
     795        {
     796                struct groupchat *c = chat_by_channel( channel );
     797               
     798                if( c )
     799                        irc_reply( irc, 332, "%s :BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!", channel, c->title );
     800                else
     801                        irc_reply( irc, 331, "%s :No topic for this channel", channel );
     802        }
    798803}
    799804
     
    927932        if( *nick == '#' || *nick == '&' )
    928933        {
    929                 if( !( c = irc_chat_by_channel( irc, nick ) ) )
     934                if( !( c = chat_by_channel( nick ) ) )
    930935                {
    931936                        irc_reply( irc, 403, "%s :Channel does not exist", nick );
     
    11931198        return TRUE;
    11941199}
    1195 
    1196 struct groupchat *irc_chat_by_channel( irc_t *irc, char *channel )
    1197 {
    1198         struct groupchat *c;
    1199         account_t *a;
    1200        
    1201         /* This finds the connection which has a conversation which belongs to this channel */
    1202         for( a = irc->accounts; a; a = a->next )
    1203         {
    1204                 if( a->ic == NULL )
    1205                         continue;
    1206                
    1207                 c = a->ic->groupchats;
    1208                 while( c )
    1209                 {
    1210                         if( c->channel && g_strcasecmp( c->channel, channel ) == 0 )
    1211                                 return c;
    1212                        
    1213                         c = c->next;
    1214                 }
    1215         }
    1216        
    1217         return NULL;
    1218 }
  • irc.h

    r256899f rcd428e4  
    140140
    141141void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags );
    142 struct groupchat *irc_chat_by_channel( irc_t *irc, char *channel );
    143142
    144143#endif
  • irc_commands.c

    r256899f rcd428e4  
    144144                irc_join( irc, u, irc->channel );
    145145        }
    146         else if( ( c = irc_chat_by_channel( irc, cmd[1] ) ) )
     146        else if( ( c = chat_by_channel( cmd[1] ) ) )
    147147        {
    148148                user_t *u = user_find( irc, irc->nick );
     
    201201{
    202202        char *nick = cmd[1], *channel = cmd[2];
    203         struct groupchat *c = irc_chat_by_channel( irc, channel );
     203        struct groupchat *c = chat_by_channel( channel );
    204204        user_t *u = user_find( irc, nick );
    205205       
     
    287287                        u = u->next;
    288288                }
    289         else if( ( c = irc_chat_by_channel( irc, channel ) ) )
     289        else if( ( c = chat_by_channel( channel ) ) )
    290290                for( l = c->in_room; l; l = l->next )
    291291                {
     
    421421static void irc_cmd_topic( irc_t *irc, char **cmd )
    422422{
    423         char *channel = cmd[1];
    424         char *topic = cmd[2];
    425        
    426         if( topic )
    427         {
    428                 /* Send the topic */
    429                 struct groupchat *c = irc_chat_by_channel( irc, channel );
    430                 if( c && c->ic && c->ic->acc->prpl->chat_topic )
    431                         c->ic->acc->prpl->chat_topic( c, topic );
    432         }
    433         else
    434         {
    435                 /* Get the topic */
    436                 irc_topic( irc, channel );
    437         }
     423        if( cmd[2] )
     424                irc_reply( irc, 482, "%s :Cannot change topic", cmd[1] );
     425        else
     426                irc_topic( irc, cmd[1] );
    438427}
    439428
  • nick.c

    r256899f rcd428e4  
    5757        static char nick[MAX_NICK_LENGTH+1];
    5858        char *store_handle, *found_nick;
     59        int inf_protection = 256;
    5960       
    6061        memset( nick, 0, MAX_NICK_LENGTH + 1 );
     
    8182        }
    8283        g_free( store_handle );
    83        
    84         /* Make sure the nick doesn't collide with an existing one by adding
    85            underscores and that kind of stuff, if necessary. */
    86         nick_dedupe( acc, handle, nick );
    87        
    88         return nick;
    89 }
    90 
    91 void nick_dedupe( account_t *acc, const char *handle, char nick[MAX_NICK_LENGTH+1] )
    92 {
    93         int inf_protection = 256;
    9484       
    9585        /* Now, find out if the nick is already in use at the moment, and make
     
    130120                }
    131121        }
     122       
     123        return nick;
    132124}
    133125
  • nick.h

    r256899f rcd428e4  
    2626void nick_set( account_t *acc, const char *handle, const char *nick );
    2727char *nick_get( account_t *acc, const char *handle );
    28 void nick_dedupe( account_t *acc, const char *handle, char nick[MAX_NICK_LENGTH+1] );
    2928int nick_saved( account_t *acc, const char *handle );
    3029void nick_del( account_t *acc, const char *handle );
  • protocols/jabber/Makefile

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

    r256899f rcd428e4  
    4444        struct jabber_data *jd = ic->proto_data;
    4545        gboolean ret;
    46        
    47         if( jd->flags & JFLAG_XMLCONSOLE )
    48         {
    49                 char *msg;
    50                
    51                 msg = g_strdup_printf( "TX: %s", buf );
    52                 imcb_buddy_msg( ic, JABBER_XMLCONSOLE_HANDLE, msg, 0, 0 );
    53                 g_free( msg );
    54         }
    5546       
    5647        if( jd->tx_len == 0 )
     
    436427{
    437428        struct im_connection *ic = data;
     429        struct xt_node *c;
     430        char *s, *type = NULL, *text = NULL;
    438431        int allow_reconnect = TRUE;
    439         struct jabber_error *err;
    440        
    441         err = jabber_error_parse( node, XMLNS_STREAM_ERROR );
     432       
     433        for( c = node->children; c; c = c->next )
     434        {
     435                if( !( s = xt_find_attr( c, "xmlns" ) ) ||
     436                    strcmp( s, XMLNS_STREAM_ERROR ) != 0 )
     437                        continue;
     438               
     439                if( strcmp( c->name, "text" ) != 0 )
     440                {
     441                        type = c->name;
     442                }
     443                /* Only use the text if it doesn't have an xml:lang attribute,
     444                   if it's empty or if it's set to something English. */
     445                else if( !( s = xt_find_attr( c, "xml:lang" ) ) ||
     446                         !*s || strncmp( s, "en", 2 ) == 0 )
     447                {
     448                        text = c->text;
     449                }
     450        }
    442451       
    443452        /* Tssk... */
    444         if( err->code == NULL )
     453        if( type == NULL )
    445454        {
    446455                imcb_error( ic, "Unknown stream error reported by server" );
    447456                imc_logout( ic, allow_reconnect );
    448                 jabber_error_free( err );
    449457                return XT_ABORT;
    450458        }
     
    453461           should turn off auto-reconnect to make sure we won't get some nasty
    454462           infinite loop! */
    455         if( strcmp( err->code, "conflict" ) == 0 )
     463        if( strcmp( type, "conflict" ) == 0 )
    456464        {
    457465                imcb_error( ic, "Account and resource used from a different location" );
     
    460468        else
    461469        {
    462                 imcb_error( ic, "Stream error: %s%s%s", err->code, err->text ? ": " : "",
    463                             err->text ? err->text : "" );
    464         }
    465        
    466         jabber_error_free( err );
     470                imcb_error( ic, "Stream error: %s%s%s", type, text ? ": " : "", text ? text : "" );
     471        }
     472       
    467473        imc_logout( ic, allow_reconnect );
    468474       
     
    470476}
    471477
    472 static xt_status jabber_xmlconsole( struct xt_node *node, gpointer data )
    473 {
    474         struct im_connection *ic = data;
    475         struct jabber_data *jd = ic->proto_data;
    476        
    477         if( jd->flags & JFLAG_XMLCONSOLE )
    478         {
    479                 char *msg, *pkt;
    480                
    481                 pkt = xt_to_string( node );
    482                 msg = g_strdup_printf( "RX: %s", pkt );
    483                 imcb_buddy_msg( ic, JABBER_XMLCONSOLE_HANDLE, msg, 0, 0 );
    484                 g_free( msg );
    485                 g_free( pkt );
    486         }
    487        
    488         return XT_NEXT;
    489 }
    490 
    491478static const struct xt_handler_entry jabber_handlers[] = {
    492         { NULL,                 "stream:stream",        jabber_xmlconsole },
    493479        { "stream:stream",      "<root>",               jabber_end_of_stream },
    494480        { "message",            "stream:stream",        jabber_pkt_message },
  • protocols/jabber/iq.c

    r256899f rcd428e4  
    9999                else if( strcmp( s, XMLNS_DISCOVER ) == 0 )
    100100                {
    101                         const char *features[] = { XMLNS_VERSION,
    102                                                    XMLNS_TIME,
    103                                                    XMLNS_CHATSTATES,
    104                                                    XMLNS_MUC,
    105                                                    NULL };
    106                         const char **f;
    107                        
    108101                        c = xt_new_node( "identity", NULL, NULL );
    109102                        xt_add_attr( c, "category", "client" );
     
    112105                        xt_add_child( reply, c );
    113106                       
    114                         for( f = features; *f; f ++ )
    115                         {
    116                                 c = xt_new_node( "feature", NULL, NULL );
    117                                 xt_add_attr( c, "var", *f );
    118                                 xt_add_child( reply, c );
    119                         }
     107                        c = xt_new_node( "feature", NULL, NULL );
     108                        xt_add_attr( c, "var", XMLNS_VERSION );
     109                        xt_add_child( reply, c );
     110                       
     111                        c = xt_new_node( "feature", NULL, NULL );
     112                        xt_add_attr( c, "var", XMLNS_TIME );
     113                        xt_add_child( reply, c );
     114                       
     115                        c = xt_new_node( "feature", NULL, NULL );
     116                        xt_add_attr( c, "var", XMLNS_CHATSTATES );
     117                        xt_add_child( reply, c );
     118                       
     119                        /* Later this can be useful to announce things like
     120                           MUC support. */
    120121                }
    121122                else
     
    372373                                                                   group->text : NULL );
    373374                               
    374                                 if( name )
    375                                         imcb_rename_buddy( ic, jid, name );
     375                                imcb_rename_buddy( ic, jid, name );
    376376                        }
    377377                        else if( strcmp( sub, "remove" ) == 0 )
    378378                        {
     379                                /* Don't have any API call for this yet! So let's
     380                                   just try to handle this as well as we can. */
    379381                                jabber_buddy_remove_bare( ic, jid );
    380                                 imcb_remove_buddy( ic, jid, NULL );
     382                                imcb_buddy_status( ic, jid, 0, NULL, NULL );
     383                                /* FIXME! */
    381384                        }
    382385                }
  • protocols/jabber/jabber.c

    r256899f rcd428e4  
    5454       
    5555        s = set_add( &acc->set, "tls", "try", set_eval_tls, acc );
    56         s->flags |= ACC_SET_OFFLINE_ONLY;
    57        
    58         s = set_add( &acc->set, "xmlconsole", "false", set_eval_bool, acc );
    5956        s->flags |= ACC_SET_OFFLINE_ONLY;
    6057}
     
    192189                imc_logout( ic, TRUE );
    193190        }
    194        
    195         if( set_getbool( &acc->set, "xmlconsole" ) )
    196         {
    197                 jd->flags |= JFLAG_XMLCONSOLE;
    198                 /* Shouldn't really do this at this stage already, maybe. But
    199                    I think this shouldn't break anything. */
    200                 imcb_add_buddy( ic, JABBER_XMLCONSOLE_HANDLE, NULL );
    201         }
    202191}
    203192
     
    207196       
    208197        jabber_end_stream( ic );
    209        
    210         while( ic->groupchats )
    211                 jabber_chat_free( ic->groupchats );
    212198       
    213199        if( jd->r_inpa >= 0 )
     
    238224        struct jabber_buddy *bud;
    239225        struct xt_node *node;
    240         char *s;
    241226        int st;
    242227       
    243         if( g_strcasecmp( who, JABBER_XMLCONSOLE_HANDLE ) == 0 )
    244                 return jabber_write( ic, message, strlen( message ) );
    245        
    246         if( ( s = strchr( who, '=' ) ) && jabber_chat_by_name( ic, s + 1 ) )
    247                 bud = jabber_buddy_by_ext_jid( ic, who, 0 );
    248         else
    249                 bud = jabber_buddy_by_jid( ic, who, 0 );
     228        bud = jabber_buddy_by_jid( ic, who, 0 );
    250229       
    251230        node = xt_new_node( "body", message, NULL );
     
    332311static void jabber_add_buddy( struct im_connection *ic, char *who, char *group )
    333312{
    334         struct jabber_data *jd = ic->proto_data;
    335        
    336         if( g_strcasecmp( who, JABBER_XMLCONSOLE_HANDLE ) == 0 )
    337         {
    338                 jd->flags |= JFLAG_XMLCONSOLE;
    339                 imcb_add_buddy( ic, JABBER_XMLCONSOLE_HANDLE, NULL );
    340                 return;
    341         }
    342        
    343313        if( jabber_add_to_roster( ic, who, NULL ) )
    344314                presence_send_request( ic, who, "subscribe" );
     
    347317static void jabber_remove_buddy( struct im_connection *ic, char *who, char *group )
    348318{
    349         struct jabber_data *jd = ic->proto_data;
    350        
    351         if( g_strcasecmp( who, JABBER_XMLCONSOLE_HANDLE ) == 0 )
    352         {
    353                 jd->flags &= ~JFLAG_XMLCONSOLE;
    354                 /* Not necessary for now. And for now the code isn't too
    355                    happy if the buddy is completely gone right after calling
    356                    this function already.
    357                 imcb_remove_buddy( ic, JABBER_XMLCONSOLE_HANDLE, NULL );
    358                 */
    359                 return;
    360         }
    361        
    362319        /* We should always do this part. Clean up our administration a little bit. */
    363320        jabber_buddy_remove_bare( ic, who );
     
    365322        if( jabber_remove_from_roster( ic, who ) )
    366323                presence_send_request( ic, who, "unsubscribe" );
    367 }
    368 
    369 static struct groupchat *jabber_chat_join_( struct im_connection *ic, char *room, char *nick, char *password )
    370 {
    371         if( strchr( room, '@' ) == NULL )
    372                 imcb_error( ic, "Invalid room name: %s", room );
    373         else if( jabber_chat_by_name( ic, room ) )
    374                 imcb_error( ic, "Already present in chat `%s'", room );
    375         else
    376                 return jabber_chat_join( ic, room, nick, password );
    377        
    378         return NULL;
    379 }
    380 
    381 static void jabber_chat_msg_( struct groupchat *c, char *message, int flags )
    382 {
    383         if( c && message )
    384                 jabber_chat_msg( c, message, flags );
    385 }
    386 
    387 static void jabber_chat_topic_( struct groupchat *c, char *topic )
    388 {
    389         if( c && topic )
    390                 jabber_chat_topic( c, topic );
    391 }
    392 
    393 static void jabber_chat_leave_( struct groupchat *c )
    394 {
    395         if( c )
    396                 jabber_chat_leave( c, NULL );
    397324}
    398325
     
    461388        ret->buddy_msg = jabber_buddy_msg;
    462389        ret->away_states = jabber_away_states;
     390//      ret->get_status_string = jabber_get_status_string;
    463391        ret->set_away = jabber_set_away;
    464392//      ret->set_info = jabber_set_info;
     
    466394        ret->add_buddy = jabber_add_buddy;
    467395        ret->remove_buddy = jabber_remove_buddy;
    468         ret->chat_msg = jabber_chat_msg_;
    469         ret->chat_topic = jabber_chat_topic_;
     396//      ret->chat_msg = jabber_chat_msg;
    470397//      ret->chat_invite = jabber_chat_invite;
    471         ret->chat_leave = jabber_chat_leave_;
    472         ret->chat_join = jabber_chat_join_;
     398//      ret->chat_leave = jabber_chat_leave;
     399//      ret->chat_open = jabber_chat_open;
    473400        ret->keepalive = jabber_keepalive;
    474401        ret->send_typing = jabber_send_typing;
  • protocols/jabber/jabber.h

    r256899f rcd428e4  
    3232typedef enum
    3333{
    34         JFLAG_STREAM_STARTED = 1,       /* Set when we detected the beginning of the stream
     34        JFLAG_STREAM_STARTED = 1,       /* Set when we detected the beginning of the stream
    3535                                           and want to do auth. */
    36         JFLAG_AUTHENTICATED = 2,        /* Set when we're successfully authenticatd. */
    37         JFLAG_STREAM_RESTART = 4,       /* Set when we want to restart the stream (after
     36        JFLAG_AUTHENTICATED = 2,        /* Set when we're successfully authenticatd. */
     37        JFLAG_STREAM_RESTART = 4,       /* Set when we want to restart the stream (after
    3838                                           SASL or TLS). */
    39         JFLAG_WAIT_SESSION = 8,         /* Set if we sent a <session> tag and need a reply
     39        JFLAG_WAIT_SESSION = 8,         /* Set if we sent a <session> tag and need a reply
    4040                                           before we continue. */
    41         JFLAG_WAIT_BIND = 16,           /* ... for <bind> tag. */
    42         JFLAG_WANT_TYPING = 32,         /* Set if we ever sent a typing notification, this
     41        JFLAG_WAIT_BIND = 16,           /* ... for <bind> tag. */
     42        JFLAG_WANT_TYPING = 32,         /* Set if we ever sent a typing notification, this
    4343                                           activates all XEP-85 related code. */
    44         JFLAG_XMLCONSOLE = 64,          /* If the user added an xmlconsole buddy. */
    4544} jabber_flags_t;
    4645
     
    5150        JBFLAG_DOES_XEP85 = 2,          /* Set this when the resource seems to support
    5251                                           XEP85 (typing notification shite). */
    53         JBFLAG_IS_CHATROOM = 4,         /* It's convenient to use this JID thingy for
    54                                            groupchat state info too. */
    55         JBFLAG_IS_ANONYMOUS = 8,        /* For anonymous chatrooms, when we don't have
    56                                            have a real JID. */
    5752} jabber_buddy_flags_t;
     53
     54#define JABBER_PORT_DEFAULT "5222"
     55#define JABBER_PORT_MIN 5220
     56#define JABBER_PORT_MAX 5229
    5857
    5958struct jabber_data
     
    102101        char *resource;
    103102       
    104         char *ext_jid; /* The JID to use in BitlBee. The real JID if possible, */
    105                        /* otherwise something similar to the conference JID. */
    106        
    107103        int priority;
    108104        struct jabber_away_state *away_state;
     
    114110        struct jabber_buddy *next;
    115111};
    116 
    117 struct jabber_chat
    118 {
    119         int flags;
    120         char *name;
    121         char *my_full_jid; /* Separate copy because of case sensitivity. */
    122         struct jabber_buddy *me;
    123 };
    124 
    125 #define JABBER_XMLCONSOLE_HANDLE "xmlconsole"
    126 
    127 #define JABBER_PORT_DEFAULT "5222"
    128 #define JABBER_PORT_MIN 5220
    129 #define JABBER_PORT_MAX 5229
    130112
    131113/* Prefixes to use for packet IDs (mainly for IQ packets ATM). Usually the
     
    150132#define XMLNS_TIME         "jabber:iq:time"                     /* XEP-0090 */
    151133#define XMLNS_VCARD        "vcard-temp"                         /* XEP-0054 */
    152 #define XMLNS_DELAY        "jabber:x:delay"                     /* XEP-0091 */
    153134#define XMLNS_CHATSTATES   "http://jabber.org/protocol/chatstates"  /* 0085 */
    154135#define XMLNS_DISCOVER     "http://jabber.org/protocol/disco#info"  /* 0030 */
    155 #define XMLNS_MUC          "http://jabber.org/protocol/muc"     /* XEP-0045 */
    156 #define XMLNS_MUC_USER     "http://jabber.org/protocol/muc#user"/* XEP-0045 */
    157136
    158137/* iq.c */
     
    185164const struct jabber_away_state *jabber_away_state_by_name( char *name );
    186165void jabber_buddy_ask( struct im_connection *ic, char *handle );
    187 char *jabber_normalize( const char *orig );
     166char *jabber_normalize( char *orig );
    188167
    189168typedef enum
    190169{
    191170        GET_BUDDY_CREAT = 1,    /* Try to create it, if necessary. */
    192         GET_BUDDY_EXACT = 2,    /* Get an exact match (only makes sense with bare JIDs). */
    193         GET_BUDDY_FIRST = 4,    /* No selection, simply get the first resource for this JID. */
     171        GET_BUDDY_EXACT = 2,    /* Get an exact message (only makes sense with bare JIDs). */
    194172} get_buddy_flags_t;
    195 
    196 struct jabber_error
    197 {
    198         char *code, *text, *type;
    199 };
    200173
    201174struct jabber_buddy *jabber_buddy_add( struct im_connection *ic, char *full_jid );
    202175struct jabber_buddy *jabber_buddy_by_jid( struct im_connection *ic, char *jid, get_buddy_flags_t flags );
    203 struct jabber_buddy *jabber_buddy_by_ext_jid( struct im_connection *ic, char *jid, get_buddy_flags_t flags );
    204176int jabber_buddy_remove( struct im_connection *ic, char *full_jid );
    205177int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid );
    206 struct groupchat *jabber_chat_by_name( struct im_connection *ic, const char *name );
    207 time_t jabber_get_timestamp( struct xt_node *xt );
    208 struct jabber_error *jabber_error_parse( struct xt_node *node, char *xmlns );
    209 void jabber_error_free( struct jabber_error *err );
    210178
    211179extern const struct jabber_away_state jabber_away_state_list[];
     
    225193gboolean sasl_supported( struct im_connection *ic );
    226194
    227 /* conference.c */
    228 struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char *nick, char *password );
    229 void jabber_chat_free( struct groupchat *c );
    230 int jabber_chat_msg( struct groupchat *ic, char *message, int flags );
    231 int jabber_chat_topic( struct groupchat *c, char *topic );
    232 int jabber_chat_leave( struct groupchat *c, const char *reason );
    233 void jabber_chat_pkt_presence( struct im_connection *ic, struct jabber_buddy *bud, struct xt_node *node );
    234 void jabber_chat_pkt_message( struct im_connection *ic, struct jabber_buddy *bud, struct xt_node *node );
    235 
    236195#endif
  • protocols/jabber/jabber_util.c

    r256899f rcd428e4  
    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                    after the (this) eval returns a non-NULL value.
     50                   when the 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 sending it! */
     131   it'll get a new id= tag, and do NOT free() the packet after writing 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( const char *orig )
     254char *jabber_normalize( char *orig )
    255255{
    256256        int len, i;
     
    320320        else
    321321        {
    322                 /* Keep in mind that full_jid currently isn't really
    323                    a full JID... */
    324322                new->bare_jid = g_strdup( full_jid );
    325323                g_hash_table_insert( jd->buddies, new->bare_jid, new );
     
    335333        {
    336334                /* Let's waste some more bytes of RAM instead of to make
    337                    memory management a total disaster here. And it saves
    338                    me one g_free() call in this function. :-P */
     335                   memory management a total disaster here.. */
    339336                new->full_jid = full_jid;
    340337        }
     
    356353        if( ( s = strchr( jid, '/' ) ) )
    357354        {
    358                 int none_found = 0;
    359                
    360355                *s = 0;
    361356                if( ( bud = g_hash_table_lookup( jd->buddies, jid ) ) )
     
    375370                        }
    376371                }
    377                 else
    378                 {
    379                         /* This hack is there to make sure that O_CREAT will
    380                            work if there's already another resouce present
    381                            for this JID, even if it's an unknown buddy. This
    382                            is done to handle conferences properly. */
    383                         none_found = 1;
    384                 }
    385                
    386                 if( bud == NULL && ( flags & GET_BUDDY_CREAT ) && ( imcb_find_buddy( ic, jid ) || !none_found ) )
     372               
     373                if( bud == NULL && ( flags & GET_BUDDY_CREAT ) && imcb_find_buddy( ic, jid ) )
    387374                {
    388375                        *s = '/';
     
    431418}
    432419
    433 /* I'm keeping a separate ext_jid attribute to save a JID that makes sense
    434    to export to BitlBee. This is mainly for groupchats right now. It's
    435    a bit of a hack, but I just think having the user nickname in the hostname
    436    part of the hostmask doesn't look nice on IRC. Normally you can convert
    437    a normal JID to ext_jid by swapping the part before and after the / and
    438    replacing the / with a =. But there should be some stripping (@s are
    439    allowed in Jabber nicks...). */
    440 struct jabber_buddy *jabber_buddy_by_ext_jid( struct im_connection *ic, char *jid_, get_buddy_flags_t flags )
    441 {
    442         struct jabber_buddy *bud;
    443         char *s, *jid;
    444        
    445         jid = jabber_normalize( jid_ );
    446        
    447         if( ( s = strchr( jid, '=' ) ) == NULL )
    448                 return NULL;
    449        
    450         for( bud = jabber_buddy_by_jid( ic, s + 1, GET_BUDDY_FIRST ); bud; bud = bud->next )
    451         {
    452                 /* Hmmm, could happen if not all people in the chat are anonymized? */
    453                 if( bud->ext_jid == NULL )
    454                         continue;
    455                
    456                 if( strcmp( bud->ext_jid, jid ) == 0 )
    457                         break;
    458         }
    459        
    460         g_free( jid );
    461        
    462         return bud;
    463 }
    464 
    465420/* Remove one specific full JID from our list. Use this when a buddy goes
    466421   off-line (because (s)he can still be online from a different location.
     
    486441                        g_hash_table_remove( jd->buddies, bud->bare_jid );
    487442                        g_free( bud->bare_jid );
    488                         g_free( bud->ext_jid );
    489443                        g_free( bud->full_jid );
    490444                        g_free( bud->away_message );
     
    519473                                        g_hash_table_replace( jd->buddies, bi->bare_jid, bi->next );
    520474                               
    521                                 g_free( bi->ext_jid );
    522475                                g_free( bi->full_jid );
    523476                                g_free( bi->away_message );
     
    542495   specified bare JID. Use this when removing someone from the contact
    543496   list, for example. */
    544 int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid )
     497int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid_ )
    545498{
    546499        struct jabber_data *jd = ic->proto_data;
    547500        struct jabber_buddy *bud, *next;
    548        
    549         if( strchr( bare_jid, '/' ) )
     501        char *bare_jid;
     502       
     503        if( strchr( bare_jid_, '/' ) )
    550504                return 0;
    551505       
    552         if( ( bud = jabber_buddy_by_jid( ic, bare_jid, GET_BUDDY_FIRST ) ) )
     506        bare_jid = jabber_normalize( bare_jid_ );
     507       
     508        if( ( bud = g_hash_table_lookup( jd->buddies, bare_jid ) ) )
    553509        {
    554510                /* Most important: Remove the hash reference. We don't know
    555511                   this buddy anymore. */
    556512                g_hash_table_remove( jd->buddies, bud->bare_jid );
    557                 g_free( bud->bare_jid );
    558513               
    559514                /* Deallocate the linked list of resources. */
    560515                while( bud )
    561516                {
    562                         /* ext_jid && anonymous means that this buddy is
    563                            specific to one groupchat (the one we're
    564                            currently cleaning up) so it can be deleted
    565                            completely. */
    566                         if( bud->ext_jid && bud->flags & JBFLAG_IS_ANONYMOUS )
    567                                 imcb_remove_buddy( ic, bud->ext_jid, NULL );
    568                        
    569517                        next = bud->next;
    570                         g_free( bud->ext_jid );
    571518                        g_free( bud->full_jid );
    572519                        g_free( bud->away_message );
     
    575522                }
    576523               
     524                g_free( bare_jid );
    577525                return 1;
    578526        }
    579527        else
    580528        {
     529                g_free( bare_jid );
    581530                return 0;
    582531        }
    583532}
    584 
    585 struct groupchat *jabber_chat_by_name( struct im_connection *ic, const char *name )
    586 {
    587         char *normalized = jabber_normalize( name );
    588         struct groupchat *ret;
    589         struct jabber_chat *jc;
    590        
    591         for( ret = ic->groupchats; ret; ret = ret->next )
    592         {
    593                 jc = ret->data;
    594                 if( strcmp( normalized, jc->name ) == 0 )
    595                         break;
    596         }
    597         g_free( normalized );
    598        
    599         return ret;
    600 }
    601 
    602 time_t jabber_get_timestamp( struct xt_node *xt )
    603 {
    604         struct tm tp, utc;
    605         struct xt_node *c;
    606         time_t res, tres;
    607         char *s = NULL;
    608        
    609         for( c = xt->children; ( c = xt_find_node( c, "x" ) ); c = c->next )
    610         {
    611                 if( ( s = xt_find_attr( c, "xmlns" ) ) && strcmp( s, XMLNS_DELAY ) == 0 )
    612                         break;
    613         }
    614        
    615         if( !c || !( s = xt_find_attr( c, "stamp" ) ) )
    616                 return 0;
    617        
    618         memset( &tp, 0, sizeof( tp ) );
    619         if( sscanf( s, "%4d%2d%2dT%2d:%2d:%2d", &tp.tm_year, &tp.tm_mon, &tp.tm_mday,
    620                                                 &tp.tm_hour, &tp.tm_min, &tp.tm_sec ) != 6 )
    621                 return 0;
    622        
    623         tp.tm_year -= 1900;
    624         tp.tm_mon --;
    625         tp.tm_isdst = -1; /* GRRRRRRRRRRR */
    626        
    627         res = mktime( &tp );
    628         /* Problem is, mktime() just gave us the GMT timestamp for the
    629            given local time... While the given time WAS NOT local. So
    630            we should fix this now.
    631        
    632            Now I could choose between messing with environment variables
    633            (kludgy) or using timegm() (not portable)... Or doing the
    634            following, which I actually prefer... */
    635         gmtime_r( &res, &utc );
    636         utc.tm_isdst = -1; /* Once more: GRRRRRRRRRRRRRRRRRR!!! */
    637         if( utc.tm_hour == tp.tm_hour && utc.tm_min == tp.tm_min )
    638                 /* Sweet! We're in UTC right now... */
    639                 return res;
    640        
    641         tres = mktime( &utc );
    642         res += res - tres;
    643        
    644         /* Yes, this is a hack. And it will go wrong around DST changes.
    645            BUT this is more likely to be threadsafe than messing with
    646            environment variables, and possibly more portable... */
    647        
    648         return res;
    649 }
    650 
    651 struct jabber_error *jabber_error_parse( struct xt_node *node, char *xmlns )
    652 {
    653         struct jabber_error *err = g_new0( struct jabber_error, 1 );
    654         struct xt_node *c;
    655         char *s;
    656        
    657         err->type = xt_find_attr( node, "type" );
    658        
    659         for( c = node->children; c; c = c->next )
    660         {
    661                 if( !( s = xt_find_attr( c, "xmlns" ) ) ||
    662                     strcmp( s, xmlns ) != 0 )
    663                         continue;
    664                
    665                 if( strcmp( c->name, "text" ) != 0 )
    666                 {
    667                         err->code = c->name;
    668                 }
    669                 /* Only use the text if it doesn't have an xml:lang attribute,
    670                    if it's empty or if it's set to something English. */
    671                 else if( !( s = xt_find_attr( c, "xml:lang" ) ) ||
    672                          !*s || strncmp( s, "en", 2 ) == 0 )
    673                 {
    674                         err->text = c->text;
    675                 }
    676         }
    677        
    678         return err;
    679 }
    680 
    681 void jabber_error_free( struct jabber_error *err )
    682 {
    683         g_free( err );
    684 }
  • protocols/jabber/message.c

    r256899f rcd428e4  
    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;
    3332        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 );
    3933       
    4034        if( type && strcmp( type, "error" ) == 0 )
     
    4236                /* Handle type=error packet. */
    4337        }
    44         else if( type && from && strcmp( type, "groupchat" ) == 0 )
     38        else if( type && strcmp( type, "groupchat" ) == 0 )
    4539        {
    46                 jabber_chat_pkt_message( ic, bud, node );
     40                /* TODO! */
    4741        }
    4842        else /* "chat", "normal", "headline", no-type or whatever. Should all be pretty similar. */
    4943        {
     44                struct jabber_buddy *bud = NULL;
    5045                GString *fullmsg = g_string_new( "" );
    5146               
    5247                if( ( s = strchr( from, '/' ) ) )
    5348                {
    54                         if( bud )
    55                         {
     49                        if( ( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT ) ) )
    5650                                bud->last_act = time( NULL );
    57                                 from = bud->ext_jid ? : bud->bare_jid;
    58                         }
    5951                        else
    6052                                *s = 0; /* We need to generate a bare JID now. */
     
    8476               
    8577                if( fullmsg->len > 0 )
    86                         imcb_buddy_msg( ic, from, fullmsg->str,
    87                                         0, jabber_get_timestamp( node ) );
     78                        imcb_buddy_msg( ic, bud ? bud->bare_jid : from, fullmsg->str, 0, 0 );
    8879               
    8980                g_string_free( fullmsg, TRUE );
    9081               
    9182                /* Handling of incoming typing notifications. */
    92                 if( bud == NULL )
    93                 {
    94                         /* Can't handle these for unknown buddies. */
    95                 }
    96                 else if( xt_find_node( node->children, "composing" ) )
     83                if( xt_find_node( node->children, "composing" ) )
    9784                {
    9885                        bud->flags |= JBFLAG_DOES_XEP85;
    99                         imcb_buddy_typing( ic, from, OPT_TYPING );
     86                        imcb_buddy_typing( ic, bud ? bud->bare_jid : from, OPT_TYPING );
    10087                }
    10188                /* No need to send a "stopped typing" signal when there's a message. */
     
    10390                {
    10491                        bud->flags |= JBFLAG_DOES_XEP85;
    105                         imcb_buddy_typing( ic, from, 0 );
     92                        imcb_buddy_typing( ic, bud ? bud->bare_jid : from, 0 );
    10693                }
    10794                else if( xt_find_node( node->children, "paused" ) )
    10895                {
    10996                        bud->flags |= JBFLAG_DOES_XEP85;
    110                         imcb_buddy_typing( ic, from, OPT_THINKING );
     97                        imcb_buddy_typing( ic, bud ? bud->bare_jid : from, OPT_THINKING );
    11198                }
    11299               
  • protocols/jabber/presence.c

    r256899f rcd428e4  
    3131        struct xt_node *c;
    3232        struct jabber_buddy *bud;
    33         int is_chat = 0, is_away = 0;
    3433        char *s;
    3534       
     
    3736                return XT_HANDLED;
    3837       
    39         if( ( s = strchr( from, '/' ) ) )
    40         {
    41                 *s = 0;
    42                 if( jabber_chat_by_name( ic, from ) )
    43                         is_chat = 1;
    44                 *s = '/';
    45         }
    46        
    4738        if( type == NULL )
    4839        {
     40                int is_away = 0;
     41               
    4942                if( !( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT | GET_BUDDY_CREAT ) ) )
    5043                {
     
    7972                        bud->priority = 0;
    8073               
    81                 if( is_chat )
    82                         jabber_chat_pkt_presence( ic, bud, node );
    83                 else if( bud == jabber_buddy_by_jid( ic, bud->bare_jid, 0 ) )
     74                if( bud == jabber_buddy_by_jid( ic, bud->bare_jid, 0 ) )
    8475                        imcb_buddy_status( ic, bud->bare_jid, OPT_LOGGED_IN | is_away,
    8576                                           ( is_away && bud->away_state ) ? bud->away_state->full_name : NULL,
     
    8879        else if( strcmp( type, "unavailable" ) == 0 )
    8980        {
    90                 if( ( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT ) ) == NULL )
     81                if( jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT ) == NULL )
    9182                {
    9283                        if( set_getbool( &ic->irc->set, "debug" ) )
     
    9586                }
    9687               
    97                 /* Handle this before we delete the JID. */
    98                 if( is_chat )
    99                 {
    100                         jabber_chat_pkt_presence( ic, bud, node );
    101                 }
    102                
    10388                jabber_buddy_remove( ic, from );
    10489               
    105                 if( is_chat )
    106                 {
    107                         /* Nothing else to do for now? */
    108                 }
    109                 else if( ( s = strchr( from, '/' ) ) )
     90                if( ( s = strchr( from, '/' ) ) )
    11091                {
    11192                        *s = 0;
    11293               
    113                         /* If another resource is still available, send its presence
    114                            information. */
    115                         if( ( bud = jabber_buddy_by_jid( ic, from, 0 ) ) )
    116                         {
    117                                 if( bud->away_state && ( *bud->away_state->code == 0 ||
    118                                     strcmp( bud->away_state->code, "chat" ) == 0 ) )
    119                                         is_away = OPT_AWAY;
    120                                
    121                                 imcb_buddy_status( ic, bud->bare_jid, OPT_LOGGED_IN | is_away,
    122                                                    ( is_away && bud->away_state ) ? bud->away_state->full_name : NULL,
    123                                                    bud->away_message );
    124                         }
    125                         else
    126                         {
    127                                 /* Otherwise, count him/her as offline now. */
     94                        /* Only count this as offline if there's no other resource
     95                           available anymore. */
     96                        if( jabber_buddy_by_jid( ic, from, 0 ) == NULL )
    12897                                imcb_buddy_status( ic, from, 0, NULL, NULL );
    129                         }
    13098                       
    13199                        *s = '/';
     
    158126        else if( strcmp( type, "error" ) == 0 )
    159127        {
    160                 struct jabber_error *err;
    161                
    162                 if( ( c = xt_find_node( node->children, "error" ) ) )
    163                 {
    164                         err = jabber_error_parse( c, XMLNS_STANZA_ERROR );
    165                         imcb_error( ic, "Stanza (%s) error: %s%s%s", node->name,
    166                                     err->code, err->text ? ": " : "",
    167                                     err->text ? err->text : "" );
    168                         jabber_error_free( err );
    169                 }
    170                 /* What else to do with it? */
     128                /* What to do with it? */
    171129        }
    172130       
     
    182140        char *show = jd->away_state->code;
    183141        char *status = jd->away_message;
    184         struct groupchat *c;
    185142        int st;
    186143       
     
    193150       
    194151        st = jabber_write_packet( ic, node );
    195        
    196         /* Have to send this update to all groupchats too, the server won't
    197            do this automatically. */
    198         for( c = ic->groupchats; c && st; c = c->next )
    199         {
    200                 struct jabber_chat *jc = c->data;
    201                
    202                 xt_add_attr( node, "to", jc->my_full_jid );
    203                 st = jabber_write_packet( ic, node );
    204         }
    205152       
    206153        xt_free_node( node );
  • protocols/jabber/sasl.c

    r256899f rcd428e4  
    332332        struct jabber_data *jd = ic->proto_data;
    333333       
    334         return ( jd->xt && jd->xt->root && xt_find_attr( jd->xt->root, "version" ) ) != 0;
    335 }
     334        return ( (void*) ( jd->xt && jd->xt->root && xt_find_attr( jd->xt->root, "version" ) ) ) != NULL;
     335}
  • protocols/jabber/xmltree.c

    r256899f rcd428e4  
    444444   list, not the node itself! The reason you have to do this by hand: So
    445445   that you can also use this function as a find-next. */
    446 struct xt_node *xt_find_node( struct xt_node *node, const char *name )
     446struct xt_node *xt_find_node( struct xt_node *node, char *name )
    447447{
    448448        while( node )
     
    457457}
    458458
    459 char *xt_find_attr( struct xt_node *node, const char *key )
     459char *xt_find_attr( struct xt_node *node, char *key )
    460460{
    461461        int i;
     
    526526}
    527527
    528 void xt_add_attr( struct xt_node *node, const char *key, const char *value )
     528void xt_add_attr( struct xt_node *node, char *key, char *value )
    529529{
    530530        int i;
     
    553553}
    554554
    555 int xt_remove_attr( struct xt_node *node, const char *key )
     555int xt_remove_attr( struct xt_node *node, char *key )
    556556{
    557557        int i, last;
  • protocols/jabber/xmltree.h

    r256899f rcd428e4  
    8787void xt_free_node( struct xt_node *node );
    8888void xt_free( struct xt_parser *xt );
    89 struct xt_node *xt_find_node( struct xt_node *node, const char *name );
    90 char *xt_find_attr( struct xt_node *node, const char *key );
     89struct xt_node *xt_find_node( struct xt_node *node, char *name );
     90char *xt_find_attr( struct xt_node *node, char *key );
    9191
    9292struct xt_node *xt_new_node( char *name, char *text, struct xt_node *children );
    9393void xt_add_child( struct xt_node *parent, struct xt_node *child );
    94 void xt_add_attr( struct xt_node *node, const char *key, const char *value );
    95 int xt_remove_attr( struct xt_node *node, const char *key );
     94void xt_add_attr( struct xt_node *node, char *key, char *value );
     95int xt_remove_attr( struct xt_node *node, char *key );
    9696
    9797#endif
  • protocols/msn/sb.c

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

    r256899f rcd428e4  
    9999}
    100100
     101 
    101102struct prpl *find_protocol(const char *name)
    102103{
     
    288289{
    289290        irc_t *irc = ic->irc;
    290         user_t *t, *u;
     291        user_t *t, *u = irc->users;
    291292        account_t *a;
    292293       
     
    305306        b_event_remove( ic->inpa );
    306307       
    307         u = irc->users;
    308308        while( u )
    309309        {
     
    428428{
    429429        user_t *u = user_findhandle( ic, handle );
     430        char *s, newnick[MAX_NICK_LENGTH+1];
    430431       
    431432        if( !u || !realname ) return;
     
    439440                if( ( ic->flags & OPT_LOGGED_IN ) && set_getbool( &ic->irc->set, "display_namechanges" ) )
    440441                        imcb_log( ic, "User `%s' changed name to `%s'", u->nick, u->realname );
    441         }
    442 }
    443 
    444 void imcb_remove_buddy( struct im_connection *ic, char *handle, char *group )
    445 {
    446         user_t *u;
    447        
    448         if( ( u = user_findhandle( ic, handle ) ) )
    449                 user_del( ic->irc, u->nick );
    450 }
    451 
    452 /* Mainly meant for ICQ (and now also for Jabber conferences) to allow IM
    453    modules to suggest a nickname for a handle. */
    454 void imcb_buddy_nick_hint( struct im_connection *ic, char *handle, char *nick )
    455 {
    456         user_t *u = user_findhandle( ic, handle );
    457         char newnick[MAX_NICK_LENGTH+1], *orig_nick;
    458        
    459         if( u && !u->online && !nick_saved( ic->acc, handle ) )
    460         {
    461                 /* Only do this if the person isn't online yet (which should
    462                    be the case if we just added it) and if the user hasn't
    463                    assigned a nickname to this buddy already. */
    464                
    465                 strncpy( newnick, nick, MAX_NICK_LENGTH );
    466                 newnick[MAX_NICK_LENGTH] = 0;
    467                
    468                 /* Some processing to make sure this string is a valid IRC nickname. */
    469                 nick_strip( newnick );
    470                 if( set_getbool( &ic->irc->set, "lcnicks" ) )
    471                         nick_lc( newnick );
    472                
    473                 if( strcmp( u->nick, newnick ) != 0 )
    474                 {
    475                         /* Only do this if newnick is different from the current one.
    476                            If rejoining a channel, maybe we got this nick already
    477                            (and dedupe would only add an underscore. */
    478                         nick_dedupe( ic->acc, handle, newnick );
     442               
     443                if( !u->online && !nick_saved( ic->acc, handle ) )
     444                {
     445                        /* Detect numeric handles: */
     446                        for( s = u->user; isdigit( *s ); s++ );
    479447                       
    480                         /* u->nick will be freed halfway the process, so it can't be
    481                            passed as an argument. */
    482                         orig_nick = g_strdup( u->nick );
    483                         user_rename( ic->irc, orig_nick, newnick );
    484                         g_free( orig_nick );
    485                 }
    486         }
    487 }
     448                        if( *s == 0 )
     449                        {
     450                                /* If we reached the end of the string, it only contained numbers.
     451                                   Seems to be an ICQ# then, so hopefully realname contains
     452                                   something more useful. */
     453                                strcpy( newnick, realname );
     454                               
     455                                /* Some processing to make sure this string is a valid IRC nickname. */
     456                                nick_strip( newnick );
     457                                if( set_getbool( &ic->irc->set, "lcnicks" ) )
     458                                        nick_lc( newnick );
     459                               
     460                                u->nick = g_strdup( newnick );
     461                        }
     462                }
     463        }
     464}
     465
    488466
    489467/* prpl.c */
     
    576554                u->online = 0;
    577555               
    578                 /* Remove him/her from the groupchats to prevent PART messages after he/she QUIT already */
    579                 for( c = ic->groupchats; c; c = c->next )
     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 )
    580558                        remove_chat_buddy_silent( c, handle );
    581559        }
     
    692670}
    693671
    694 void imcb_chat_free( struct groupchat *c )
     672void imcb_chat_removed( struct groupchat *c )
    695673{
    696674        struct im_connection *ic = c->ic;
    697         struct groupchat *l;
     675        struct groupchat *l = NULL;
    698676        GList *ir;
    699677       
     
    715693                }
    716694               
    717                 /* Find the previous chat in the linked list. */
    718                 for( l = ic->groupchats; l && l->next != c; l = l->next );
    719                
    720695                if( l )
    721696                        l->next = c->next;
    722697                else
    723                         ic->groupchats = c->next;
     698                        ic->conversations = c->next;
    724699               
    725700                for( ir = c->in_room; ir; ir = ir->next )
     
    760735}
    761736
    762 void imcb_chat_topic( struct groupchat *c, char *who, char *topic, time_t set_at )
    763 {
    764         struct im_connection *ic = c->ic;
    765         user_t *u = NULL;
    766        
    767         if( who == NULL)
    768                 u = user_find( ic->irc, ic->irc->mynick );
    769         else if( g_strcasecmp( who, ic->acc->user ) == 0 )
    770                 u = user_find( ic->irc, ic->irc->nick );
     737struct groupchat *imcb_chat_new( struct im_connection *ic, char *handle )
     738{
     739        struct groupchat *c;
     740       
     741        /* This one just creates the conversation structure, user won't see anything yet */
     742       
     743        if( ic->conversations )
     744        {
     745                for( c = ic->conversations; c->next; c = c->next );
     746                c = c->next = g_new0( struct groupchat, 1 );
     747        }
    771748        else
    772                 u = user_findhandle( ic, who );
    773        
    774         if( ( g_strcasecmp( set_getstr( &ic->irc->set, "strip_html" ), "always" ) == 0 ) ||
    775             ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) )
    776                 strip_html( topic );
    777        
    778         g_free( c->topic );
    779         c->topic = g_strdup( topic );
    780        
    781         if( c->joined && u )
    782                 irc_write( ic->irc, ":%s!%s@%s TOPIC %s :%s", u->nick, u->user, u->host, c->channel, topic );
    783 }
    784 
    785 struct groupchat *imcb_chat_new( struct im_connection *ic, char *handle )
    786 {
    787         struct groupchat *c;
    788        
    789         /* This one just creates the conversation structure, user won't see anything yet */
    790        
    791         if( ic->groupchats )
    792         {
    793                 for( c = ic->groupchats; c->next; c = c->next );
    794                 c = c->next = g_new0( struct groupchat, 1 );
    795         }
    796         else
    797                 ic->groupchats = c = g_new0( struct groupchat, 1 );
     749                ic->conversations = c = g_new0( struct groupchat, 1 );
    798750       
    799751        c->ic = ic;
    800752        c->title = g_strdup( handle );
    801753        c->channel = g_strdup_printf( "&chat_%03d", ic->irc->c_id++ );
    802         c->topic = g_strdup_printf( "%s :BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!", c->channel, c->title );
    803754       
    804755        if( set_getbool( &ic->irc->set, "debug" ) )
     
    845796}
    846797
    847 /* This function is one BIG hack... :-( EREWRITE */
    848798void imcb_chat_remove_buddy( struct groupchat *b, char *handle, char *reason )
    849799{
     
    857807        if( g_strcasecmp( handle, b->ic->acc->user ) == 0 )
    858808        {
    859                 if( b->joined == 0 )
    860                         return;
    861                
    862809                u = user_find( b->ic->irc, b->ic->irc->nick );
    863810                b->joined = 0;
     
    869816        }
    870817       
    871         if( me || ( remove_chat_buddy_silent( b, handle ) && b->joined && u ) )
    872                 irc_part( b->ic->irc, u, b->channel );
     818        if( remove_chat_buddy_silent( b, handle ) )
     819                if( ( b->joined || me ) && u )
     820                        irc_part( b->ic->irc, u, b->channel );
    873821}
    874822
     
    896844
    897845/* Misc. BitlBee stuff which shouldn't really be here */
     846
     847struct groupchat *chat_by_channel( char *channel )
     848{
     849        struct im_connection *ic;
     850        struct groupchat *c;
     851        GSList *l;
     852       
     853        /* This finds the connection which has a conversation which belongs to this channel */
     854        for( l = connections; l; l = l->next )
     855        {
     856                ic = l->data;
     857                for( c = ic->conversations; c && g_strcasecmp( c->channel, channel ) != 0; c = c->next );
     858                if( c )
     859                        return c;
     860        }
     861       
     862        return NULL;
     863}
    898864
    899865char *set_eval_away_devoice( set_t *set, char *value )
     
    11291095        ic->acc->prpl->rem_deny( ic, handle );
    11301096}
    1131 
    1132 void imcb_clean_handle( struct im_connection *ic, char *handle )
    1133 {
    1134         /* Accepts a handle and does whatever is necessary to make it
    1135            BitlBee-friendly. Currently this means removing everything
    1136            outside 33-127 (ASCII printable excl spaces), @ (only one
    1137            is allowed) and ! and : */
    1138         char out[strlen(handle)+1];
    1139         int s, d;
    1140        
    1141         s = d = 0;
    1142         while( handle[s] )
    1143         {
    1144                 if( handle[s] > ' ' && handle[s] != '!' && handle[s] != ':' &&
    1145                     ( handle[s] & 0x80 ) == 0 )
    1146                 {
    1147                         if( handle[s] == '@' )
    1148                         {
    1149                                 /* See if we got an @ already? */
    1150                                 out[d] = 0;
    1151                                 if( strchr( out, '@' ) )
    1152                                         continue;
    1153                         }
    1154                        
    1155                         out[d++] = handle[s];
    1156                 }
    1157                 s ++;
    1158         }
    1159         out[d] = handle[s];
    1160        
    1161         strcpy( handle, out );
    1162 }
  • protocols/nogaim.h

    r256899f rcd428e4  
    6161#define OPT_AWAY        0x00000004
    6262#define OPT_DOES_HTML   0x00000010
    63 #define OPT_LOCALBUDDY  0x00000020 /* For nicks local to one groupchat */
    6463#define OPT_TYPING      0x00000100 /* Some pieces of code make assumptions */
    6564#define OPT_THINKING    0x00000200 /* about these values... Stupid me! */
     
    9291        irc_t *irc;
    9392       
    94         struct groupchat *groupchats;
     93        struct groupchat *conversations;
    9594};
    9695
     
    105104        GList *ignored;
    106105       
     106        /* BitlBee */
    107107        struct groupchat *next;
    108108        char *channel;
     
    110110         * chat using imcb_chat_new(). */
    111111        char *title;
    112         /* Use imcb_chat_topic() to change this variable otherwise the user
    113          * won't notice the topic change. */
    114         char *topic;
    115112        char joined;
    116113        /* This is for you, you can add your own structure here to extend this
     
    215212        struct groupchat *
    216213             (* chat_join)      (struct im_connection *, char *room, char *nick, char *password);
    217         /* Change the topic, if supported. Note that BitlBee expects the IM
    218            server to confirm the topic change with a regular topic change
    219            event. If it doesn't do that, you have to fake it to make it
    220            visible to the user. */
    221         void (* chat_topic)     (struct groupchat *, char *topic);
    222214       
    223215        /* You can tell what away states your protocol supports, so that
     
    273265G_MODULE_EXPORT struct buddy *imcb_find_buddy( struct im_connection *ic, char *handle );
    274266G_MODULE_EXPORT void imcb_rename_buddy( struct im_connection *ic, char *handle, char *realname );
    275 G_MODULE_EXPORT void imcb_buddy_nick_hint( struct im_connection *ic, char *handle, char *nick );
    276267
    277268/* Buddy activity */
     
    285276G_MODULE_EXPORT void imcb_buddy_msg( struct im_connection *ic, char *handle, char *msg, u_int32_t flags, time_t sent_at );
    286277G_MODULE_EXPORT void imcb_buddy_typing( struct im_connection *ic, char *handle, u_int32_t flags );
    287 G_MODULE_EXPORT void imcb_clean_handle( struct im_connection *ic, char *handle );
    288278
    289279/* Groupchats */
     
    301291/* To tell BitlBee 'who' said 'msg' in 'c'. 'flags' and 'sent_at' can be 0. */
    302292G_MODULE_EXPORT void imcb_chat_msg( struct groupchat *c, char *who, char *msg, u_int32_t flags, time_t sent_at );
    303 /* To tell BitlBee 'who' changed the topic of 'c' to 'topic'. */
    304 G_MODULE_EXPORT void imcb_chat_topic( struct groupchat *c, char *who, char *topic, time_t set_at );
    305 G_MODULE_EXPORT void imcb_chat_free( struct groupchat *c );
     293G_MODULE_EXPORT void imcb_chat_removed( struct groupchat *c );
     294struct groupchat *chat_by_channel( char *channel );
    306295
    307296/* Actions, or whatever. */
  • protocols/oscar/oscar.c

    r256899f rcd428e4  
    20312031                                       
    20322032                                        if (realname) {
    2033                                                 imcb_buddy_nick_hint(ic, curitem->name, realname);
    20342033                                                imcb_rename_buddy(ic, curitem->name, realname);
    20352034                                                g_free(realname);
     
    25242523
    25252524        /* Notify the conversation window that we've left the chat */
    2526         imcb_chat_free(cc->cnv);
     2525        imcb_chat_removed(cc->cnv);
    25272526
    25282527        /* Destroy the chat_connection */
  • protocols/yahoo/yahoo.c

    r256899f rcd428e4  
    145145        GSList *l;
    146146       
    147         while( ic->groupchats )
    148                 imcb_chat_free( ic->groupchats );
     147        while( ic->conversations )
     148                imcb_chat_removed( ic->conversations );
    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_free( c );
     320        imcb_chat_removed( c );
    321321}
    322322
     
    798798{
    799799        yahoo_conference_decline( inv->yid, NULL, inv->members, inv->name, "User rejected groupchat" );
    800         imcb_chat_free( inv->c );
     800        imcb_chat_removed( inv->c );
    801801        g_free( inv->name );
    802802        g_free( inv );
     
    841841        struct groupchat *c;
    842842       
    843         for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
     843        for( c = ic->conversations; c && strcmp( c->title, room ) != 0; c = c->next );
    844844       
    845845        if( c )
     
    853853        struct groupchat *c;
    854854       
    855         for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
     855        for( c = ic->conversations; c && strcmp( c->title, room ) != 0; c = c->next );
    856856       
    857857        if( c )
     
    865865        struct groupchat *c;
    866866       
    867         for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next );
     867        for( c = ic->conversations; c && strcmp( c->title, room ) != 0; c = c->next );
    868868       
    869869        if( c )
  • root_commands.c

    r256899f rcd428e4  
    930930        if( cmd[3] )
    931931        {
    932                 if( cmd[3][0] != '#' && cmd[3][0] != '&' )
    933                         channel = g_strdup_printf( "&%s", cmd[3] );
    934                 else
    935                         channel = g_strdup( cmd[3] );
     932                channel = g_strdup( cmd[3] );
    936933        }
    937934        else
     
    939936                char *s;
    940937               
    941                 channel = g_strdup_printf( "&%s", chat );
     938                channel = g_strdup( chat );
    942939                if( ( s = strchr( channel, '@' ) ) )
    943940                        *s = 0;
     
    945942        if( cmd[3] && cmd[4] )
    946943                nick = cmd[4];
    947         else
    948                 nick = irc->nick;
    949944        if( cmd[3] && cmd[4] && cmd[5] )
    950945                password = cmd[5];
    951946       
    952         if( !nick_ok( channel + 1 ) )
    953         {
    954                 irc_usermsg( irc, "Invalid channel name: %s", channel );
    955                 g_free( channel );
    956                 return;
    957         }
    958         else if( g_strcasecmp( channel, irc->channel ) == 0 || irc_chat_by_channel( irc, channel ) )
    959         {
    960                 irc_usermsg( irc, "Channel already exists: %s", channel );
    961                 g_free( channel );
    962                 return;
    963         }
    964        
    965         if( ( c = a->prpl->chat_join( ic, chat, nick, password ) ) )
    966         {
    967                 g_free( c->channel );
    968                 c->channel = channel;
    969         }
    970         else
    971         {
    972                 irc_usermsg( irc, "Tried to join chat, not sure if this was successful" );
    973                 g_free( channel );
    974         }
     947        c = a->prpl->chat_join( ic, chat, nick, password );
     948       
     949        g_free( channel );
    975950}
    976951
  • user.c

    r256899f rcd428e4  
    161161}
    162162
    163 /* DO NOT PASS u->nick FOR oldnick !!! */
    164163void user_rename( irc_t *irc, char *oldnick, char *newnick )
    165164{
Note: See TracChangeset for help on using the changeset viewer.