Changes in / [cbaac62:8c4afbfa]


Ignore:
Files:
1 added
23 edited

Legend:

Unmodified
Added
Removed
  • bitlbee.c

    rcbaac62 r8c4afbfa  
    7070#ifdef IPV6
    7171        memset( &listen_addr6, 0, sizeof( listen_addr6 ) );
     72        memset( &listen_addr, 0, sizeof( listen_addr ) );
    7273        listen_addr6.sin6_family = AF_INET6;
    7374        listen_addr6.sin6_port = htons( global.conf->port );
     
    7778                use_ipv6 = 0;
    7879#endif
    79                 memset( &listen_addr, 0, sizeof( listen_addr ) );
    8080                listen_addr.sin_family = AF_INET;
    8181                listen_addr.sin_port = htons( global.conf->port );
     
    125125                        exit( 0 );
    126126               
    127                 chdir( "/" );
     127//              chdir( "/" );
    128128               
    129129                /* Sometimes std* are already closed (for example when we're in a RESTARTed
  • irc.c

    rcbaac62 r8c4afbfa  
    658658                }
    659659        }
    660         else if( ( c = chat_by_channel( channel ) ) )
     660        else if( ( c = irc_chat_by_channel( irc, channel ) ) )
    661661        {
    662662                GList *l;
     
    811811        else
    812812        {
    813                 struct groupchat *c = chat_by_channel( channel );
     813                struct groupchat *c = irc_chat_by_channel( irc, channel );
    814814               
    815815                if( c )
     
    949949        if( *nick == '#' || *nick == '&' )
    950950        {
    951                 if( !( c = chat_by_channel( nick ) ) )
     951                if( !( c = irc_chat_by_channel( irc, nick ) ) )
    952952                {
    953953                        irc_reply( irc, 403, "%s :Channel does not exist", nick );
     
    12151215        return TRUE;
    12161216}
     1217
     1218struct groupchat *irc_chat_by_channel( irc_t *irc, char *channel )
     1219{
     1220        struct groupchat *c;
     1221        account_t *a;
     1222       
     1223        /* This finds the connection which has a conversation which belongs to this channel */
     1224        for( a = irc->accounts; a; a = a->next )
     1225        {
     1226                if( a->ic == NULL )
     1227                        continue;
     1228               
     1229                c = a->ic->groupchats;
     1230                while( c )
     1231                {
     1232                        if( c->channel && g_strcasecmp( c->channel, channel ) == 0 )
     1233                                return c;
     1234                       
     1235                        c = c->next;
     1236                }
     1237        }
     1238       
     1239        return NULL;
     1240}
  • irc.h

    rcbaac62 r8c4afbfa  
    140140
    141141void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags );
     142struct groupchat *irc_chat_by_channel( irc_t *irc, char *channel );
    142143
    143144#endif
  • irc_commands.c

    rcbaac62 r8c4afbfa  
    144144                irc_join( irc, u, irc->channel );
    145145        }
    146         else if( ( c = chat_by_channel( cmd[1] ) ) )
     146        else if( ( c = irc_chat_by_channel( irc, 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 = chat_by_channel( channel );
     203        struct groupchat *c = irc_chat_by_channel( irc, channel );
    204204        user_t *u = user_find( irc, nick );
    205205       
     
    287287                        u = u->next;
    288288                }
    289         else if( ( c = chat_by_channel( channel ) ) )
     289        else if( ( c = irc_chat_by_channel( irc, channel ) ) )
    290290                for( l = c->in_room; l; l = l->next )
    291291                {
  • nick.c

    rcbaac62 r8c4afbfa  
    5757        static char nick[MAX_NICK_LENGTH+1];
    5858        char *store_handle, *found_nick;
    59         int inf_protection = 256;
    6059       
    6160        memset( nick, 0, MAX_NICK_LENGTH + 1 );
     
    8281        }
    8382        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
     91void nick_dedupe( account_t *acc, const char *handle, char nick[MAX_NICK_LENGTH+1] )
     92{
     93        int inf_protection = 256;
    8494       
    8595        /* Now, find out if the nick is already in use at the moment, and make
     
    120130                }
    121131        }
    122        
    123         return nick;
    124132}
    125133
  • nick.h

    rcbaac62 r8c4afbfa  
    2626void nick_set( account_t *acc, const char *handle, const char *nick );
    2727char *nick_get( account_t *acc, const char *handle );
     28void nick_dedupe( account_t *acc, const char *handle, char nick[MAX_NICK_LENGTH+1] );
    2829int nick_saved( account_t *acc, const char *handle );
    2930void nick_del( account_t *acc, const char *handle );
  • protocols/jabber/Makefile

    rcbaac62 r8c4afbfa  
    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/io.c

    rcbaac62 r8c4afbfa  
    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        }
    4655       
    4756        if( jd->tx_len == 0 )
     
    484493}
    485494
     495static xt_status jabber_xmlconsole( struct xt_node *node, gpointer data )
     496{
     497        struct im_connection *ic = data;
     498        struct jabber_data *jd = ic->proto_data;
     499       
     500        if( jd->flags & JFLAG_XMLCONSOLE )
     501        {
     502                char *msg, *pkt;
     503               
     504                pkt = xt_to_string( node );
     505                msg = g_strdup_printf( "RX: %s", pkt );
     506                imcb_buddy_msg( ic, JABBER_XMLCONSOLE_HANDLE, msg, 0, 0 );
     507                g_free( msg );
     508                g_free( pkt );
     509        }
     510       
     511        return XT_NEXT;
     512}
     513
    486514static const struct xt_handler_entry jabber_handlers[] = {
     515        { NULL,                 "stream:stream",        jabber_xmlconsole },
    487516        { "stream:stream",      "<root>",               jabber_end_of_stream },
    488517        { "message",            "stream:stream",        jabber_pkt_message },
  • protocols/jabber/iq.c

    rcbaac62 r8c4afbfa  
    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                       
    101108                        c = xt_new_node( "identity", NULL, NULL );
    102109                        xt_add_attr( c, "category", "client" );
     
    105112                        xt_add_child( reply, c );
    106113                       
    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. */
     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                        }
    121120                }
    122121                else
     
    373372                                                                   group->text : NULL );
    374373                               
    375                                 imcb_rename_buddy( ic, jid, name );
     374                                if( 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. */
    381379                                jabber_buddy_remove_bare( ic, jid );
    382                                 imcb_buddy_status( ic, jid, 0, NULL, NULL );
    383                                 /* FIXME! */
     380                                imcb_remove_buddy( ic, jid, NULL );
    384381                        }
    385382                }
  • protocols/jabber/jabber.c

    rcbaac62 r8c4afbfa  
    197197        jabber_end_stream( ic );
    198198       
     199        while( ic->groupchats )
     200                jabber_chat_free( ic->groupchats );
     201       
    199202        if( jd->r_inpa >= 0 )
    200203                b_event_remove( jd->r_inpa );
     
    224227        struct jabber_buddy *bud;
    225228        struct xt_node *node;
     229        char *s;
    226230        int st;
    227231       
    228         bud = jabber_buddy_by_jid( ic, who, 0 );
     232        if( g_strcasecmp( who, JABBER_XMLCONSOLE_HANDLE ) == 0 )
     233                return jabber_write( ic, message, strlen( message ) );
     234       
     235        if( ( s = strchr( who, '=' ) ) && jabber_chat_by_name( ic, s + 1 ) )
     236                bud = jabber_buddy_by_ext_jid( ic, who, 0 );
     237        else
     238                bud = jabber_buddy_by_jid( ic, who, 0 );
    229239       
    230240        node = xt_new_node( "body", message, NULL );
     
    311321static void jabber_add_buddy( struct im_connection *ic, char *who, char *group )
    312322{
     323        struct jabber_data *jd = ic->proto_data;
     324       
     325        if( g_strcasecmp( who, JABBER_XMLCONSOLE_HANDLE ) == 0 )
     326        {
     327                jd->flags |= JFLAG_XMLCONSOLE;
     328                imcb_add_buddy( ic, JABBER_XMLCONSOLE_HANDLE, NULL );
     329                return;
     330        }
     331       
    313332        if( jabber_add_to_roster( ic, who, NULL ) )
    314333                presence_send_request( ic, who, "subscribe" );
     
    317336static void jabber_remove_buddy( struct im_connection *ic, char *who, char *group )
    318337{
     338        struct jabber_data *jd = ic->proto_data;
     339       
     340        if( g_strcasecmp( who, JABBER_XMLCONSOLE_HANDLE ) == 0 )
     341        {
     342                jd->flags &= ~JFLAG_XMLCONSOLE;
     343                /* Not necessary for now. And for now the code isn't too
     344                   happy if the buddy is completely gone right after calling
     345                   this function already.
     346                imcb_remove_buddy( ic, JABBER_XMLCONSOLE_HANDLE, NULL );
     347                */
     348                return;
     349        }
     350       
    319351        /* We should always do this part. Clean up our administration a little bit. */
    320352        jabber_buddy_remove_bare( ic, who );
     
    322354        if( jabber_remove_from_roster( ic, who ) )
    323355                presence_send_request( ic, who, "unsubscribe" );
     356}
     357
     358static struct groupchat *jabber_chat_join_( struct im_connection *ic, char *room, char *nick, char *password )
     359{
     360        if( strchr( room, '@' ) == NULL )
     361                imcb_error( ic, "Invalid room name: %s", room );
     362        else if( jabber_chat_by_name( ic, room ) )
     363                imcb_error( ic, "Already present in chat `%s'", room );
     364        else
     365                return jabber_chat_join( ic, room, nick, password );
     366       
     367        return NULL;
     368}
     369
     370static void jabber_chat_msg_( struct groupchat *c, char *message, int flags )
     371{
     372        if( c && message )
     373                jabber_chat_msg( c, message, flags );
     374}
     375
     376static void jabber_chat_leave_( struct groupchat *c )
     377{
     378        if( c )
     379                jabber_chat_leave( c, NULL );
    324380}
    325381
     
    388444        ret->buddy_msg = jabber_buddy_msg;
    389445        ret->away_states = jabber_away_states;
    390 //      ret->get_status_string = jabber_get_status_string;
    391446        ret->set_away = jabber_set_away;
    392447//      ret->set_info = jabber_set_info;
     
    394449        ret->add_buddy = jabber_add_buddy;
    395450        ret->remove_buddy = jabber_remove_buddy;
    396 //      ret->chat_msg = jabber_chat_msg;
     451        ret->chat_msg = jabber_chat_msg_;
    397452//      ret->chat_invite = jabber_chat_invite;
    398 //      ret->chat_leave = jabber_chat_leave;
    399 //      ret->chat_open = jabber_chat_open;
     453        ret->chat_leave = jabber_chat_leave_;
     454        ret->chat_join = jabber_chat_join_;
    400455        ret->keepalive = jabber_keepalive;
    401456        ret->send_typing = jabber_send_typing;
  • protocols/jabber/jabber.h

    rcbaac62 r8c4afbfa  
    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. */
    4445} jabber_flags_t;
    4546
     
    5051        JBFLAG_DOES_XEP85 = 2,          /* Set this when the resource seems to support
    5152                                           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. */
    5257} jabber_buddy_flags_t;
    53 
    54 #define JABBER_PORT_DEFAULT "5222"
    55 #define JABBER_PORT_MIN 5220
    56 #define JABBER_PORT_MAX 5229
    5758
    5859struct jabber_data
     
    101102        char *resource;
    102103       
     104        char *ext_jid; /* The JID to use in BitlBee. The real JID if possible, */
     105                       /* otherwise something similar to the conference JID. */
     106       
    103107        int priority;
    104108        struct jabber_away_state *away_state;
     
    110114        struct jabber_buddy *next;
    111115};
     116
     117struct 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
    112130
    113131/* Prefixes to use for packet IDs (mainly for IQ packets ATM). Usually the
     
    132150#define XMLNS_TIME         "jabber:iq:time"                     /* XEP-0090 */
    133151#define XMLNS_VCARD        "vcard-temp"                         /* XEP-0054 */
     152#define XMLNS_DELAY        "jabber:x:delay"                     /* XEP-0091 */
    134153#define XMLNS_CHATSTATES   "http://jabber.org/protocol/chatstates"  /* 0085 */
    135154#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 */
    136157
    137158/* iq.c */
     
    164185const struct jabber_away_state *jabber_away_state_by_name( char *name );
    165186void jabber_buddy_ask( struct im_connection *ic, char *handle );
    166 char *jabber_normalize( char *orig );
     187char *jabber_normalize( const char *orig );
    167188
    168189typedef enum
    169190{
    170191        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). */
     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. */
    172194} get_buddy_flags_t;
    173195
    174196struct jabber_buddy *jabber_buddy_add( struct im_connection *ic, char *full_jid );
    175197struct jabber_buddy *jabber_buddy_by_jid( struct im_connection *ic, char *jid, get_buddy_flags_t flags );
     198struct jabber_buddy *jabber_buddy_by_ext_jid( struct im_connection *ic, char *jid, get_buddy_flags_t flags );
    176199int jabber_buddy_remove( struct im_connection *ic, char *full_jid );
    177200int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid );
     201struct groupchat *jabber_chat_by_name( struct im_connection *ic, const char *name );
     202time_t jabber_get_timestamp( struct xt_node *xt );
    178203
    179204extern const struct jabber_away_state jabber_away_state_list[];
     
    193218gboolean sasl_supported( struct im_connection *ic );
    194219
     220/* conference.c */
     221struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char *nick, char *password );
     222void jabber_chat_free( struct groupchat *c );
     223int jabber_chat_msg( struct groupchat *ic, char *message, int flags );
     224int jabber_chat_leave( struct groupchat *c, const char *reason );
     225void jabber_chat_pkt_presence( struct im_connection *ic, struct jabber_buddy *bud, struct xt_node *node );
     226void jabber_chat_pkt_message( struct im_connection *ic, struct jabber_buddy *bud, struct xt_node *node );
     227
    195228#endif
  • protocols/jabber/jabber_util.c

    rcbaac62 r8c4afbfa  
    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;
     
    320320        else
    321321        {
     322                /* Keep in mind that full_jid currently isn't really
     323                   a full JID... */
    322324                new->bare_jid = g_strdup( full_jid );
    323325                g_hash_table_insert( jd->buddies, new->bare_jid, new );
     
    333335        {
    334336                /* Let's waste some more bytes of RAM instead of to make
    335                    memory management a total disaster here.. */
     337                   memory management a total disaster here. And it saves
     338                   me one g_free() call in this function. :-P */
    336339                new->full_jid = full_jid;
    337340        }
     
    353356        if( ( s = strchr( jid, '/' ) ) )
    354357        {
     358                int none_found = 0;
     359               
    355360                *s = 0;
    356361                if( ( bud = g_hash_table_lookup( jd->buddies, jid ) ) )
     
    370375                        }
    371376                }
    372                
    373                 if( bud == NULL && ( flags & GET_BUDDY_CREAT ) && imcb_find_buddy( ic, jid ) )
     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 ) )
    374387                {
    375388                        *s = '/';
     
    418431}
    419432
     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...). */
     440struct 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
    420465/* Remove one specific full JID from our list. Use this when a buddy goes
    421466   off-line (because (s)he can still be online from a different location.
     
    441486                        g_hash_table_remove( jd->buddies, bud->bare_jid );
    442487                        g_free( bud->bare_jid );
     488                        g_free( bud->ext_jid );
    443489                        g_free( bud->full_jid );
    444490                        g_free( bud->away_message );
     
    473519                                        g_hash_table_replace( jd->buddies, bi->bare_jid, bi->next );
    474520                               
     521                                g_free( bi->ext_jid );
    475522                                g_free( bi->full_jid );
    476523                                g_free( bi->away_message );
     
    495542   specified bare JID. Use this when removing someone from the contact
    496543   list, for example. */
    497 int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid_ )
     544int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid )
    498545{
    499546        struct jabber_data *jd = ic->proto_data;
    500547        struct jabber_buddy *bud, *next;
    501         char *bare_jid;
    502        
    503         if( strchr( bare_jid_, '/' ) )
     548       
     549        if( strchr( bare_jid, '/' ) )
    504550                return 0;
    505551       
    506         bare_jid = jabber_normalize( bare_jid_ );
    507        
    508         if( ( bud = g_hash_table_lookup( jd->buddies, bare_jid ) ) )
     552        if( ( bud = jabber_buddy_by_jid( ic, bare_jid, GET_BUDDY_FIRST ) ) )
    509553        {
    510554                /* Most important: Remove the hash reference. We don't know
    511555                   this buddy anymore. */
    512556                g_hash_table_remove( jd->buddies, bud->bare_jid );
     557                g_free( bud->bare_jid );
    513558               
    514559                /* Deallocate the linked list of resources. */
    515560                while( bud )
    516561                {
     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                       
    517569                        next = bud->next;
     570                        g_free( bud->ext_jid );
    518571                        g_free( bud->full_jid );
    519572                        g_free( bud->away_message );
     
    522575                }
    523576               
    524                 g_free( bare_jid );
    525577                return 1;
    526578        }
    527579        else
    528580        {
    529                 g_free( bare_jid );
    530581                return 0;
    531582        }
    532583}
     584
     585struct 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
     602time_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}
  • protocols/jabber/message.c

    rcbaac62 r8c4afbfa  
    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 )
     55                        {
    5056                                bud->last_act = time( NULL );
     57                                from = bud->ext_jid ? : bud->bare_jid;
     58                        }
    5159                        else
    5260                                *s = 0; /* We need to generate a bare JID now. */
     
    7684               
    7785                if( fullmsg->len > 0 )
    78                         imcb_buddy_msg( ic, bud ? bud->bare_jid : from, fullmsg->str, 0, 0 );
     86                        imcb_buddy_msg( ic, from, fullmsg->str,
     87                                        0, jabber_get_timestamp( node ) );
    7988               
    8089                g_string_free( fullmsg, TRUE );
     
    8493                {
    8594                        bud->flags |= JBFLAG_DOES_XEP85;
    86                         imcb_buddy_typing( ic, bud ? bud->bare_jid : from, OPT_TYPING );
     95                        imcb_buddy_typing( ic, from, OPT_TYPING );
    8796                }
    8897                /* No need to send a "stopped typing" signal when there's a message. */
     
    9099                {
    91100                        bud->flags |= JBFLAG_DOES_XEP85;
    92                         imcb_buddy_typing( ic, bud ? bud->bare_jid : from, 0 );
     101                        imcb_buddy_typing( ic, from, 0 );
    93102                }
    94103                else if( xt_find_node( node->children, "paused" ) )
    95104                {
    96105                        bud->flags |= JBFLAG_DOES_XEP85;
    97                         imcb_buddy_typing( ic, bud ? bud->bare_jid : from, OPT_THINKING );
     106                        imcb_buddy_typing( ic, from, OPT_THINKING );
    98107                }
    99108               
  • protocols/jabber/presence.c

    rcbaac62 r8c4afbfa  
    3131        struct xt_node *c;
    3232        struct jabber_buddy *bud;
     33        int is_chat = 0, is_away = 0;
    3334        char *s;
    3435       
     
    3637                return XT_HANDLED;
    3738       
     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       
    3847        if( type == NULL )
    3948        {
    40                 int is_away = 0;
    41                
    4249                if( !( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT | GET_BUDDY_CREAT ) ) )
    4350                {
     
    7279                        bud->priority = 0;
    7380               
    74                 if( bud == jabber_buddy_by_jid( ic, bud->bare_jid, 0 ) )
     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 ) )
    7584                        imcb_buddy_status( ic, bud->bare_jid, OPT_LOGGED_IN | is_away,
    7685                                           ( is_away && bud->away_state ) ? bud->away_state->full_name : NULL,
     
    7988        else if( strcmp( type, "unavailable" ) == 0 )
    8089        {
    81                 if( jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT ) == NULL )
     90                if( ( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT ) ) == NULL )
    8291                {
    8392                        if( set_getbool( &ic->irc->set, "debug" ) )
     
    8695                }
    8796               
     97                /* Handle this before we delete the JID. */
     98                if( is_chat )
     99                {
     100                        jabber_chat_pkt_presence( ic, bud, node );
     101                }
     102               
    88103                jabber_buddy_remove( ic, from );
    89104               
    90                 if( ( s = strchr( from, '/' ) ) )
     105                if( is_chat )
     106                {
     107                        /* Nothing else to do for now? */
     108                }
     109                else if( ( s = strchr( from, '/' ) ) )
    91110                {
    92111                        *s = 0;
    93112               
    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 )
     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. */
    97128                                imcb_buddy_status( ic, from, 0, NULL, NULL );
     129                        }
    98130                       
    99131                        *s = '/';
     
    145177        char *show = jd->away_state->code;
    146178        char *status = jd->away_message;
     179        struct groupchat *c;
    147180        int st;
    148181       
     
    156189        st = jabber_write_packet( ic, node );
    157190       
     191        /* Have to send this update to all groupchats too, the server won't
     192           do this automatically. */
     193        for( c = ic->groupchats; c && st; c = c->next )
     194        {
     195                struct jabber_chat *jc = c->data;
     196               
     197                xt_add_attr( node, "to", jc->my_full_jid );
     198                st = jabber_write_packet( ic, node );
     199        }
     200       
    158201        xt_free_node( node );
    159202        return st;
  • protocols/jabber/xmltree.c

    rcbaac62 r8c4afbfa  
    442442   list, not the node itself! The reason you have to do this by hand: So
    443443   that you can also use this function as a find-next. */
    444 struct xt_node *xt_find_node( struct xt_node *node, char *name )
     444struct xt_node *xt_find_node( struct xt_node *node, const char *name )
    445445{
    446446        while( node )
     
    455455}
    456456
    457 char *xt_find_attr( struct xt_node *node, char *key )
     457char *xt_find_attr( struct xt_node *node, const char *key )
    458458{
    459459        int i;
     
    524524}
    525525
    526 void xt_add_attr( struct xt_node *node, char *key, char *value )
     526void xt_add_attr( struct xt_node *node, const char *key, const char *value )
    527527{
    528528        int i;
     
    551551}
    552552
    553 int xt_remove_attr( struct xt_node *node, char *key )
     553int xt_remove_attr( struct xt_node *node, const char *key )
    554554{
    555555        int i, last;
  • protocols/jabber/xmltree.h

    rcbaac62 r8c4afbfa  
    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, char *name );
    90 char *xt_find_attr( struct xt_node *node, char *key );
     89struct xt_node *xt_find_node( struct xt_node *node, const char *name );
     90char *xt_find_attr( struct xt_node *node, const 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, char *key, char *value );
    95 int xt_remove_attr( struct xt_node *node, char *key );
     94void xt_add_attr( struct xt_node *node, const char *key, const char *value );
     95int xt_remove_attr( struct xt_node *node, const char *key );
    9696
    9797#endif
  • protocols/msn/sb.c

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

    rcbaac62 r8c4afbfa  
    289289{
    290290        irc_t *irc = ic->irc;
    291         user_t *t, *u = irc->users;
     291        user_t *t, *u;
    292292        account_t *a;
    293293       
     
    306306        b_event_remove( ic->inpa );
    307307       
     308        u = irc->users;
    308309        while( u )
    309310        {
     
    428429{
    429430        user_t *u = user_findhandle( ic, handle );
    430         char *s, newnick[MAX_NICK_LENGTH+1];
    431431       
    432432        if( !u || !realname ) return;
     
    440440                if( ( ic->flags & OPT_LOGGED_IN ) && set_getbool( &ic->irc->set, "display_namechanges" ) )
    441441                        imcb_log( ic, "User `%s' changed name to `%s'", u->nick, u->realname );
    442                
    443                 if( !u->online && !nick_saved( ic->acc, handle ) )
    444                 {
    445                         /* Detect numeric handles: */
    446                         for( s = u->user; isdigit( *s ); s++ );
     442        }
     443}
     444
     445void imcb_remove_buddy( struct im_connection *ic, char *handle, char *group )
     446{
     447        user_t *u;
     448       
     449        if( ( u = user_findhandle( ic, handle ) ) )
     450                user_del( ic->irc, u->nick );
     451}
     452
     453/* Mainly meant for ICQ (and now also for Jabber conferences) to allow IM
     454   modules to suggest a nickname for a handle. */
     455void imcb_buddy_nick_hint( struct im_connection *ic, char *handle, char *nick )
     456{
     457        user_t *u = user_findhandle( ic, handle );
     458        char newnick[MAX_NICK_LENGTH+1], *orig_nick;
     459       
     460        if( u && !u->online && !nick_saved( ic->acc, handle ) )
     461        {
     462                /* Only do this if the person isn't online yet (which should
     463                   be the case if we just added it) and if the user hasn't
     464                   assigned a nickname to this buddy already. */
     465               
     466                strncpy( newnick, nick, MAX_NICK_LENGTH );
     467                newnick[MAX_NICK_LENGTH] = 0;
     468               
     469                /* Some processing to make sure this string is a valid IRC nickname. */
     470                nick_strip( newnick );
     471                if( set_getbool( &ic->irc->set, "lcnicks" ) )
     472                        nick_lc( newnick );
     473               
     474                if( strcmp( u->nick, newnick ) != 0 )
     475                {
     476                        /* Only do this if newnick is different from the current one.
     477                           If rejoining a channel, maybe we got this nick already
     478                           (and dedupe would only add an underscore. */
     479                        nick_dedupe( ic->acc, handle, newnick );
    447480                       
    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 
     481                        /* u->nick will be freed halfway the process, so it can't be
     482                           passed as an argument. */
     483                        orig_nick = g_strdup( u->nick );
     484                        user_rename( ic->irc, orig_nick, newnick );
     485                        g_free( orig_nick );
     486                }
     487        }
     488}
    466489
    467490/* prpl.c */
     
    554577                u->online = 0;
    555578               
    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 )
     579                /* Remove him/her from the groupchats to prevent PART messages after he/she QUIT already */
     580                for( c = ic->groupchats; c; c = c->next )
    558581                        remove_chat_buddy_silent( c, (char*) handle );
    559582        }
     
    685708}
    686709
    687 void imcb_chat_removed( struct groupchat *c )
     710void imcb_chat_free( struct groupchat *c )
    688711{
    689712        struct im_connection *ic = c->ic;
    690         struct groupchat *l = NULL;
     713        struct groupchat *l;
    691714        GList *ir;
    692715       
     
    708731                }
    709732               
     733                /* Find the previous chat in the linked list. */
     734                for( l = ic->groupchats; l && l->next != c; l = l->next );
     735               
    710736                if( l )
    711737                        l->next = c->next;
    712738                else
    713                         ic->conversations = c->next;
     739                        ic->groupchats = c->next;
    714740               
    715741                for( ir = c->in_room; ir; ir = ir->next )
     
    749775        /* This one just creates the conversation structure, user won't see anything yet */
    750776       
    751         if( ic->conversations )
    752         {
    753                 for( c = ic->conversations; c->next; c = c->next );
     777        if( ic->groupchats )
     778        {
     779                for( c = ic->groupchats; c->next; c = c->next );
    754780                c = c->next = g_new0( struct groupchat, 1 );
    755781        }
    756782        else
    757                 ic->conversations = c = g_new0( struct groupchat, 1 );
     783                ic->groupchats = c = g_new0( struct groupchat, 1 );
    758784       
    759785        c->ic = ic;
     
    804830}
    805831
     832/* This function is one BIG hack... :-( EREWRITE */
    806833void imcb_chat_remove_buddy( struct groupchat *b, char *handle, char *reason )
    807834{
     
    815842        if( g_strcasecmp( handle, b->ic->acc->user ) == 0 )
    816843        {
     844                if( b->joined == 0 )
     845                        return;
     846               
    817847                u = user_find( b->ic->irc, b->ic->irc->nick );
    818848                b->joined = 0;
     
    824854        }
    825855       
    826         if( remove_chat_buddy_silent( b, handle ) )
    827                 if( ( b->joined || me ) && u )
    828                         irc_part( b->ic->irc, u, b->channel );
     856        if( me || ( remove_chat_buddy_silent( b, handle ) && b->joined && u ) )
     857                irc_part( b->ic->irc, u, b->channel );
    829858}
    830859
     
    852881
    853882/* Misc. BitlBee stuff which shouldn't really be here */
    854 
    855 struct groupchat *chat_by_channel( char *channel )
    856 {
    857         struct im_connection *ic;
    858         struct groupchat *c;
    859         GSList *l;
    860        
    861         /* This finds the connection which has a conversation which belongs to this channel */
    862         for( l = connections; l; l = l->next )
    863         {
    864                 ic = l->data;
    865                 for( c = ic->conversations; c && g_strcasecmp( c->channel, channel ) != 0; c = c->next );
    866                 if( c )
    867                         return c;
    868         }
    869        
    870         return NULL;
    871 }
    872883
    873884char *set_eval_away_devoice( set_t *set, char *value )
  • protocols/nogaim.h

    rcbaac62 r8c4afbfa  
    6161#define OPT_AWAY        0x00000004
    6262#define OPT_DOES_HTML   0x00000010
     63#define OPT_LOCALBUDDY  0x00000020 /* For nicks local to one groupchat */
    6364#define OPT_TYPING      0x00000100 /* Some pieces of code make assumptions */
    6465#define OPT_THINKING    0x00000200 /* about these values... Stupid me! */
     
    9192        irc_t *irc;
    9293       
    93         struct groupchat *conversations;
     94        struct groupchat *groupchats;
    9495};
    9596
     
    9798        struct im_connection *ic;
    9899
    99         /* stuff used just for chat */
    100100        GList *in_room;
    101101        GList *ignored;
    102102       
    103         /* BitlBee */
    104103        struct groupchat *next;
    105104        char *channel;
     
    195194G_MODULE_EXPORT struct buddy *imcb_find_buddy( struct im_connection *ic, char *handle );
    196195G_MODULE_EXPORT void imcb_rename_buddy( struct im_connection *ic, char *handle, char *realname );
     196G_MODULE_EXPORT void imcb_buddy_nick_hint( struct im_connection *ic, char *handle, char *nick );
    197197
    198198/* Buddy activity */
     
    208208G_MODULE_EXPORT void imcb_chat_remove_buddy( struct groupchat *b, char *handle, char *reason );
    209209G_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 );
    211 struct groupchat *chat_by_channel( char *channel );
     210G_MODULE_EXPORT void imcb_chat_free( struct groupchat *c );
    212211
    213212/* Actions, or whatever. */
  • protocols/oscar/oscar.c

    rcbaac62 r8c4afbfa  
    20222022                                       
    20232023                                        if (realname) {
     2024                                                imcb_buddy_nick_hint(ic, curitem->name, realname);
    20242025                                                imcb_rename_buddy(ic, curitem->name, realname);
    20252026                                                g_free(realname);
     
    25142515
    25152516        /* Notify the conversation window that we've left the chat */
    2516         imcb_chat_removed(cc->cnv);
     2517        imcb_chat_free(cc->cnv);
    25172518
    25182519        /* Destroy the chat_connection */
  • protocols/yahoo/yahoo.c

    rcbaac62 r8c4afbfa  
    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

    rcbaac62 r8c4afbfa  
    912912        if( cmd[3] )
    913913        {
    914                 channel = g_strdup( cmd[3] );
     914                if( cmd[3][0] != '#' && cmd[3][0] != '&' )
     915                        channel = g_strdup_printf( "&%s", cmd[3] );
     916                else
     917                        channel = g_strdup( cmd[3] );
    915918        }
    916919        else
     
    918921                char *s;
    919922               
    920                 channel = g_strdup( chat );
     923                channel = g_strdup_printf( "&%s", chat );
    921924                if( ( s = strchr( channel, '@' ) ) )
    922925                        *s = 0;
     
    924927        if( cmd[3] && cmd[4] )
    925928                nick = cmd[4];
     929        else
     930                nick = irc->nick;
    926931        if( cmd[3] && cmd[4] && cmd[5] )
    927932                password = cmd[5];
    928933       
    929         c = a->prpl->chat_join( ic, chat, nick, password );
    930        
    931         g_free( channel );
     934        if( !nick_ok( channel + 1 ) )
     935        {
     936                irc_usermsg( irc, "Invalid channel name: %s", channel );
     937                g_free( channel );
     938                return;
     939        }
     940        else if( g_strcasecmp( channel, irc->channel ) == 0 || irc_chat_by_channel( irc, channel ) )
     941        {
     942                irc_usermsg( irc, "Channel already exists: %s", channel );
     943                g_free( channel );
     944                return;
     945        }
     946       
     947        if( ( c = a->prpl->chat_join( ic, chat, nick, password ) ) )
     948        {
     949                g_free( c->channel );
     950                c->channel = channel;
     951        }
     952        else
     953        {
     954                irc_usermsg( irc, "Tried to join chat, not sure if this was successful" );
     955                g_free( channel );
     956        }
    932957}
    933958
  • user.c

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