Changeset 814aa52 for protocols


Ignore:
Timestamp:
2010-06-03T11:00:45Z (14 years ago)
Author:
Sven Moritz Hallberg <pesco@…>
Branches:
master
Children:
a6b2f13
Parents:
5f8ab6a9 (diff), f4bcc22 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

merge in bitlbee 1.2.6

Location:
protocols
Files:
7 added
13 edited

Legend:

Unmodified
Added
Removed
  • protocols/jabber/jabber.c

    r5f8ab6a9 r814aa52  
    5757        set_t *s;
    5858        char str[16];
     59       
     60        s = set_add( &acc->set, "activity_timeout", "600", set_eval_int, acc );
    5961       
    6062        g_snprintf( str, sizeof( str ), "%d", jabber_port_list[0] );
     
    307309                bud = jabber_buddy_by_ext_jid( ic, who, 0 );
    308310        else
    309                 bud = jabber_buddy_by_jid( ic, who, 0 );
     311                bud = jabber_buddy_by_jid( ic, who, GET_BUDDY_BARE_OK );
    310312       
    311313        node = xt_new_node( "body", message, NULL );
     
    352354static void jabber_get_info( struct im_connection *ic, char *who )
    353355{
    354         struct jabber_data *jd = ic->proto_data;
    355356        struct jabber_buddy *bud;
    356357       
    357         if( strchr( who, '/' ) )
    358                 bud = jabber_buddy_by_jid( ic, who, 0 );
    359         else
    360         {
    361                 char *s = jabber_normalize( who );
    362                 bud = g_hash_table_lookup( jd->buddies, s );
    363                 g_free( s );
    364         }
     358        bud = jabber_buddy_by_jid( ic, who, GET_BUDDY_FIRST );
    365359       
    366360        while( bud )
  • protocols/jabber/jabber.h

    r5f8ab6a9 r814aa52  
    108108};
    109109
     110/* Somewhat messy data structure: We have a hash table with the bare JID as
     111   the key and the head of a struct jabber_buddy list as the value. The head
     112   is always a bare JID. If the JID has other resources (often the case,
     113   except for some transports that don't support multiple resources), those
     114   follow. In that case, the bare JID at the beginning doesn't actually
     115   refer to a real session and should only be used for operations that
     116   support incomplete JIDs. */
    110117struct jabber_buddy
    111118{
     
    121128        char *away_message;
    122129       
    123         time_t last_act;
     130        time_t last_msg;
    124131        jabber_buddy_flags_t flags;
    125132       
     
    209216        GET_BUDDY_EXACT = 2,    /* Get an exact match (only makes sense with bare JIDs). */
    210217        GET_BUDDY_FIRST = 4,    /* No selection, simply get the first resource for this JID. */
     218        GET_BUDDY_BARE = 8,     /* Get the bare version of the JID (possibly inexistent). */
     219        GET_BUDDY_BARE_OK = 16, /* Allow returning a bare JID if that seems better. */
    211220} get_buddy_flags_t;
    212221
  • protocols/jabber/jabber_util.c

    r5f8ab6a9 r814aa52  
    44*  Jabber module - Misc. stuff                                              *
    55*                                                                           *
    6 *  Copyright 2006 Wilmer van der Gaast <wilmer@gaast.net>                   *
     6*  Copyright 2006-2010 Wilmer van der Gaast <wilmer@gaast.net>             
    77*                                                                           *
    88*  This program is free software; you can redistribute it and/or modify     *
     
    345345        if( ( bud = g_hash_table_lookup( jd->buddies, full_jid ) ) )
    346346        {
     347                /* The first entry is always a bare JID. If there are more, we
     348                   should ignore the first one here. */
     349                if( bud->next )
     350                        bud = bud->next;
     351               
    347352                /* If this is a transport buddy or whatever, it can't have more
    348353                   than one instance, so this is always wrong: */
     
    379384        else
    380385        {
    381                 /* Keep in mind that full_jid currently isn't really
    382                    a full JID... */
    383                 new->bare_jid = g_strdup( full_jid );
     386                new->full_jid = new->bare_jid = g_strdup( full_jid );
    384387                g_hash_table_insert( jd->buddies, new->bare_jid, new );
     388               
     389                if( s )
     390                {
     391                        new->next = g_new0( struct jabber_buddy, 1 );
     392                        new->next->bare_jid = new->bare_jid;
     393                        new = new->next;
     394                }
    385395        }
    386396       
     
    408418{
    409419        struct jabber_data *jd = ic->proto_data;
    410         struct jabber_buddy *bud;
     420        struct jabber_buddy *bud, *head;
    411421        char *s, *jid;
    412422       
     
    420430                if( ( bud = g_hash_table_lookup( jd->buddies, jid ) ) )
    421431                {
     432                        bare_exists = 1;
     433                       
     434                        if( bud->next )
     435                                bud = bud->next;
     436                       
    422437                        /* Just return the first one for this bare JID. */
    423438                        if( flags & GET_BUDDY_FIRST )
     
    441456                                        break;
    442457                }
    443                 else
    444                 {
    445                         /* This variable tells the if down here that the bare
    446                            JID already exists and we should feel free to add
    447                            more resources, if the caller asked for that. */
    448                         bare_exists = 1;
    449                 }
    450458               
    451459                if( bud == NULL && ( flags & GET_BUDDY_CREAT ) &&
    452                     ( !bare_exists || imcb_find_buddy( ic, jid ) ) )
     460                    ( bare_exists || imcb_find_buddy( ic, jid ) ) )
    453461                {
    454462                        *s = '/';
     
    464472                char *set;
    465473               
    466                 bud = g_hash_table_lookup( jd->buddies, jid );
     474                head = g_hash_table_lookup( jd->buddies, jid );
     475                bud = ( head && head->next ) ? head->next : head;
    467476               
    468477                g_free( jid );
     
    481490                        /* Looks like the caller doesn't care about details. */
    482491                        return bud;
     492                else if( flags & GET_BUDDY_BARE )
     493                        return head;
    483494               
    484495                best_prio = best_time = bud;
     
    487498                        if( bud->priority > best_prio->priority )
    488499                                best_prio = bud;
    489                         if( bud->last_act > best_time->last_act )
     500                        if( bud->last_msg > best_time->last_msg )
    490501                                best_time = bud;
    491502                }
     
    493504                if( ( set = set_getstr( &ic->acc->set, "resource_select" ) ) == NULL )
    494505                        return NULL;
    495                 else if( strcmp( set, "activity" ) == 0 )
     506                else if( strcmp( set, "priority" ) == 0 )
     507                        return best_prio;
     508                else if( flags & GET_BUDDY_BARE_OK ) /* && strcmp( set, "activity" ) == 0 */
     509                {
     510                        if( best_time->last_msg + set_getint( &ic->acc->set, "activity_timeout" ) >= time( NULL ) )
     511                                return best_time;
     512                        else
     513                                return head;
     514                }
     515                else
    496516                        return best_time;
    497                 else /* if( strcmp( set, "priority" ) == 0 ) */
    498                         return best_prio;
    499517        }
    500518}
     
    538556{
    539557        struct jabber_data *jd = ic->proto_data;
    540         struct jabber_buddy *bud, *prev, *bi;
     558        struct jabber_buddy *bud, *prev = NULL, *bi;
    541559        char *s, *full_jid;
    542560       
     
    548566        if( ( bud = g_hash_table_lookup( jd->buddies, full_jid ) ) )
    549567        {
     568                if( bud->next )
     569                        bud = (prev=bud)->next;
     570               
    550571                /* If there's only one item in the list (and if the resource
    551572                   matches), removing it is simple. (And the hash reference
     
    555576                      ( bud->resource && s && strcmp( bud->resource, s + 1 ) == 0 ) ) )
    556577                {
    557                         g_hash_table_remove( jd->buddies, bud->bare_jid );
    558                         g_free( bud->bare_jid );
    559                         g_free( bud->ext_jid );
    560                         g_free( bud->full_jid );
    561                         g_free( bud->away_message );
    562                         g_free( bud );
    563                        
    564                         g_free( full_jid );
    565                        
    566                         return 1;
     578                        return jabber_buddy_remove_bare( ic, full_jid );
    567579                }
    568580                else if( s == NULL || bud->resource == NULL )
     
    575587                else
    576588                {
    577                         for( bi = bud, prev = NULL; bi; bi = (prev=bi)->next )
     589                        for( bi = bud; bi; bi = (prev=bi)->next )
    578590                                if( strcmp( bi->resource, s + 1 ) == 0 )
    579591                                        break;
     
    586598                                        prev->next = bi->next;
    587599                                else
    588                                         /* The hash table should point at the second
    589                                            item, because we're removing the first. */
     600                                        /* Don't think this should ever happen anymore. */
    590601                                        g_hash_table_replace( jd->buddies, bi->bare_jid, bi->next );
    591602                               
     
    656667time_t jabber_get_timestamp( struct xt_node *xt )
    657668{
    658         struct tm tp, utc;
    659669        struct xt_node *c;
    660         time_t res, tres;
    661670        char *s = NULL;
     671        struct tm tp;
    662672       
    663673        for( c = xt->children; ( c = xt_find_node( c, "x" ) ); c = c->next )
     
    677687        tp.tm_year -= 1900;
    678688        tp.tm_mon --;
    679         tp.tm_isdst = -1; /* GRRRRRRRRRRR */
    680        
    681         res = mktime( &tp );
    682         /* Problem is, mktime() just gave us the GMT timestamp for the
    683            given local time... While the given time WAS NOT local. So
    684            we should fix this now.
    685        
    686            Now I could choose between messing with environment variables
    687            (kludgy) or using timegm() (not portable)... Or doing the
    688            following, which I actually prefer... */
    689         gmtime_r( &res, &utc );
    690         utc.tm_isdst = -1; /* Once more: GRRRRRRRRRRRRRRRRRR!!! */
    691         if( utc.tm_hour == tp.tm_hour && utc.tm_min == tp.tm_min )
    692                 /* Sweet! We're in UTC right now... */
    693                 return res;
    694        
    695         tres = mktime( &utc );
    696         res += res - tres;
    697        
    698         /* Yes, this is a hack. And it will go wrong around DST changes.
    699            BUT this is more likely to be threadsafe than messing with
    700            environment variables, and possibly more portable... */
    701        
    702         return res;
     689       
     690        return mktime_utc( &tp );
    703691}
    704692
  • protocols/jabber/message.c

    r5f8ab6a9 r814aa52  
    7171                        if( bud )
    7272                        {
    73                                 bud->last_act = time( NULL );
     73                                bud->last_msg = time( NULL );
    7474                                from = bud->ext_jid ? : bud->bare_jid;
    7575                        }
     
    8080                if( type && strcmp( type, "headline" ) == 0 )
    8181                {
    82                         c = xt_find_node( node->children, "subject" );
    83                         g_string_append_printf( fullmsg, "Headline: %s\n", c && c->text_len > 0 ? c->text : "" );
     82                        if( ( c = xt_find_node( node->children, "subject" ) ) && c->text_len > 0 )
     83                                g_string_append_printf( fullmsg, "Headline: %s\n", c->text );
    8484                       
    8585                        /* <x xmlns="jabber:x:oob"><url>http://....</url></x> can contain a URL, it seems. */
  • protocols/jabber/presence.c

    r5f8ab6a9 r814aa52  
    6868                {
    6969                        bud->away_state = NULL;
    70                         /* Let's only set last_act if there's *no* away state,
    71                            since it could be some auto-away thingy. */
    72                         bud->last_act = time( NULL );
    7370                }
    7471               
  • protocols/msn/msn.c

    r5f8ab6a9 r814aa52  
    3131GSList *msn_switchboards;
    3232
    33 static char *msn_set_display_name( set_t *set, char *value );
     33static char *set_eval_display_name( set_t *set, char *value );
    3434
    3535static void msn_init( account_t *acc )
    3636{
    37         set_t *s;
    38        
    39         s = set_add( &acc->set, "display_name", NULL, msn_set_display_name, acc );
    40         s->flags |= ACC_SET_NOSAVE | ACC_SET_ONLINE_ONLY;
    41 
    42         s = set_add( &acc->set, "mail_notifications", "false", set_eval_bool, acc );
     37        set_add( &acc->set, "display_name", NULL, set_eval_display_name, acc );
     38        set_add( &acc->set, "local_display_name", "false", set_eval_bool, acc );
     39        set_add( &acc->set, "mail_notifications", "false", set_eval_bool, acc );
     40        set_add( &acc->set, "switchboard_keepalives", "false", set_eval_bool, acc );
    4341}
    4442
     
    167165static void msn_set_my_name( struct im_connection *ic, char *info )
    168166{
    169         msn_set_display_name( set_find( &ic->acc->set, "display_name" ), info );
     167        msn_set_display_name( ic, info );
    170168}
    171169
     
    283281}
    284282
    285 static char *msn_set_display_name( set_t *set, char *value )
     283static char *set_eval_display_name( set_t *set, char *value )
    286284{
    287285        account_t *acc = set->data;
    288286        struct im_connection *ic = acc->ic;
    289         struct msn_data *md;
    290         char buf[1024], *fn;
    291        
    292         /* Double-check. */
     287       
     288        /* Allow any name if we're offline. */
    293289        if( ic == NULL )
    294                 return NULL;
    295        
    296         md = ic->proto_data;
     290                return value;
    297291       
    298292        if( strlen( value ) > 129 )
     
    301295                return NULL;
    302296        }
    303        
    304         fn = msn_http_encode( value );
    305        
    306         g_snprintf( buf, sizeof( buf ), "REA %d %s %s\r\n", ++md->trId, ic->acc->user, fn );
    307         msn_write( ic, buf, strlen( buf ) );
    308         g_free( fn );
    309297       
    310298        /* Returning NULL would be better, because the server still has to
    311299           confirm the name change. However, it looks a bit confusing to the
    312300           user. */
    313         return value;
     301        return msn_set_display_name( ic, value ) ? value : NULL;
    314302}
    315303
  • protocols/msn/msn.h

    r5f8ab6a9 r814aa52  
    3131#define TYPING_NOTIFICATION_MESSAGE "\r\r\rBEWARE, ME R TYPINK MESSAGE!!!!\r\r\r"
    3232#define GROUPCHAT_SWITCHBOARD_MESSAGE "\r\r\rME WANT TALK TO MANY PEOPLE\r\r\r"
     33#define SB_KEEPALIVE_MESSAGE "\r\r\rDONT HANG UP ON ME!\r\r\r"
    3334
    3435#ifdef DEBUG_MSN
     
    5354                           "TypingUser: %s\r\n" \
    5455                           "\r\n\r\n"
     56
     57#define SB_KEEPALIVE_HEADERS "MIME-Version: 1.0\r\n" \
     58                             "Content-Type: text/x-ping\r\n" \
     59                             "\r\n\r\n"
    5560
    5661#define PROFILE_URL "http://members.msn.com/"
     
    8388        gint inp;
    8489        struct msn_handler_data *handler;
     90        gint keepalive;
    8591       
    8692        int trId;
     
    161167char *msn_http_encode( const char *input );
    162168void msn_msgq_purge( struct im_connection *ic, GSList **list );
     169gboolean msn_set_display_name( struct im_connection *ic, const char *rawname );
    163170
    164171/* tables.c */
     
    179186gboolean msn_sb_connected( gpointer data, gint source, b_input_condition cond );
    180187int msn_sb_write_msg( struct im_connection *ic, struct msn_message *m );
     188void msn_sb_start_keepalives( struct msn_switchboard *sb, gboolean initial );
     189void msn_sb_stop_keepalives( struct msn_switchboard *sb );
    181190
    182191#endif //_MSN_H
  • protocols/msn/msn_util.c

    r5f8ab6a9 r814aa52  
    3838                imcb_error( ic, "Short write() to main server" );
    3939                imc_logout( ic, TRUE );
    40                 return( 0 );
    41         }
    42        
    43         return( 1 );
     40                return 0;
     41        }
     42       
     43        return 1;
    4444}
    4545
     
    377377        g_string_free( ret, TRUE );
    378378}
     379
     380gboolean msn_set_display_name( struct im_connection *ic, const char *rawname )
     381{
     382        char *fn = msn_http_encode( rawname );
     383        struct msn_data *md = ic->proto_data;
     384        char buf[1024];
     385       
     386        g_snprintf( buf, sizeof( buf ), "REA %d %s %s\r\n", ++md->trId, ic->acc->user, fn );
     387        g_free( fn );
     388       
     389        return msn_write( ic, buf, strlen( buf ) ) != 0;
     390}
  • protocols/msn/ns.c

    r5f8ab6a9 r814aa52  
    3535
    3636static void msn_auth_got_passport_token( struct msn_auth_data *mad );
     37static gboolean msn_ns_got_display_name( struct im_connection *ic, char *name );
    3738
    3839gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond )
     
    231232                else if( num_parts >= 7 && strcmp( cmd[2], "OK" ) == 0 )
    232233                {
    233                         set_t *s;
    234                        
    235234                        if( num_parts == 7 )
    236                         {
    237                                 http_decode( cmd[4] );
    238                                
    239                                 strncpy( ic->displayname, cmd[4], sizeof( ic->displayname ) );
    240                                 ic->displayname[sizeof(ic->displayname)-1] = 0;
    241                                
    242                                 if( ( s = set_find( &ic->acc->set, "display_name" ) ) )
    243                                 {
    244                                         g_free( s->value );
    245                                         s->value = g_strdup( cmd[4] );
    246                                 }
    247                         }
     235                                msn_ns_got_display_name( ic, cmd[4] );
    248236                        else
    249                         {
    250237                                imcb_log( ic, "Warning: Friendly name in server response was corrupted" );
    251                         }
    252238                       
    253239                        imcb_log( ic, "Authenticated, getting buddy list" );
     
    422408        else if( strcmp( cmd[0], "FLN" ) == 0 )
    423409        {
    424                 if( cmd[1] )
    425                         imcb_buddy_status( ic, cmd[1], 0, NULL, NULL );
     410                if( cmd[1] == NULL )
     411                        return 1;
     412               
     413                imcb_buddy_status( ic, cmd[1], 0, NULL, NULL );
     414               
     415                msn_sb_start_keepalives( msn_sb_by_handle( ic, cmd[1] ), TRUE );
    426416        }
    427417        else if( strcmp( cmd[0], "NLN" ) == 0 )
     
    449439                                   ( st != msn_away_state_list ? OPT_AWAY : 0 ),
    450440                                   st->name, NULL );
     441               
     442                msn_sb_stop_keepalives( msn_sb_by_handle( ic, cmd[2] ) );
    451443        }
    452444        else if( strcmp( cmd[0], "RNG" ) == 0 )
     
    553545                return( 0 );
    554546        }
     547#if 0
     548        /* Discard this one completely for now since I don't care about the ack
     549           and since MSN servers can apparently screw up the formatting. */
    555550        else if( strcmp( cmd[0], "REA" ) == 0 )
    556551        {
     
    583578                }
    584579        }
     580#endif
    585581        else if( strcmp( cmd[0], "IPG" ) == 0 )
    586582        {
     
    732728        }
    733729}
     730
     731static gboolean msn_ns_got_display_name( struct im_connection *ic, char *name )
     732{
     733        set_t *s;
     734       
     735        if( ( s = set_find( &ic->acc->set, "display_name" ) ) == NULL )
     736                return FALSE; /* Shouldn't happen.. */
     737       
     738        http_decode( name );
     739       
     740        if( s->value && strcmp( s->value, name ) == 0 )
     741        {
     742                return TRUE;
     743                /* The names match, nothing to worry about. */
     744        }
     745        else if( s->value != NULL &&
     746                 ( strcmp( name, ic->acc->user ) == 0 ||
     747                   set_getbool( &ic->acc->set, "local_display_name" ) ) )
     748        {
     749                /* The server thinks our display name is our e-mail address
     750                   which is probably wrong, or the user *wants* us to do this:
     751                   Always use the locally set display_name. */
     752                return msn_set_display_name( ic, s->value );
     753        }
     754        else
     755        {
     756                if( s->value && *s->value )
     757                        imcb_log( ic, "BitlBee thinks your display name is `%s' but "
     758                                      "the MSN server says it's `%s'. Using the MSN "
     759                                      "server's name. Set local_display_name to true "
     760                                      "to use the local name.", s->value, name );
     761               
     762                if( g_utf8_validate( name, -1, NULL ) )
     763                {
     764                        g_free( s->value );
     765                        s->value = g_strdup( name );
     766                }
     767                else
     768                {
     769                        imcb_log( ic, "Warning: Friendly name in server response was corrupted" );
     770                }
     771               
     772                return TRUE;
     773        }
     774}
  • protocols/msn/sb.c

    r5f8ab6a9 r814aa52  
    168168               
    169169                /* Build the message. Convert LF to CR-LF for normal messages. */
    170                 if( strcmp( text, TYPING_NOTIFICATION_MESSAGE ) != 0 )
     170                if( strcmp( text, TYPING_NOTIFICATION_MESSAGE ) == 0 )
     171                {
     172                        i = strlen( MSN_TYPING_HEADERS ) + strlen( sb->ic->acc->user );
     173                        buf = g_new0( char, i );
     174                        i = g_snprintf( buf, i, MSN_TYPING_HEADERS, sb->ic->acc->user );
     175                }
     176                else if( strcmp( text, SB_KEEPALIVE_MESSAGE ) == 0 )
     177                {
     178                        buf = g_strdup( SB_KEEPALIVE_HEADERS );
     179                        i = strlen( buf );
     180                }
     181                else
    171182                {
    172183                        buf = g_new0( char, sizeof( MSN_MESSAGE_HEADERS ) + strlen( text ) * 2 + 1 );
     
    182193                        }
    183194                }
    184                 else
    185                 {
    186                         i = strlen( MSN_TYPING_HEADERS ) + strlen( sb->ic->acc->user );
    187                         buf = g_new0( char, i );
    188                         i = g_snprintf( buf, i, MSN_TYPING_HEADERS, sb->ic->acc->user );
    189                 }
    190195               
    191196                /* Build the final packet (MSG command + the message). */
     
    250255       
    251256        msn_msgq_purge( ic, &sb->msgq );
     257        msn_sb_stop_keepalives( sb );
    252258       
    253259        if( sb->key ) g_free( sb->key );
     
    471477               
    472478                sb->ready = 1;
     479               
     480                msn_sb_start_keepalives( sb, FALSE );
    473481        }
    474482        else if( strcmp( cmd[0], "CAL" ) == 0 )
     
    520528                        }
    521529                       
     530                        msn_sb_start_keepalives( sb, FALSE );
     531                       
    522532                        return( st );
    523533                }
     
    581591                if( sb->who )
    582592                {
     593                        msn_sb_stop_keepalives( sb );
     594                       
    583595                        /* This is a single-person chat, and the other person is leaving. */
    584596                        g_free( sb->who );
     
    764776        return( 1 );
    765777}
     778
     779static gboolean msn_sb_keepalive( gpointer data, gint source, b_input_condition cond )
     780{
     781        struct msn_switchboard *sb = data;
     782        return sb->ready && msn_sb_sendmessage( sb, SB_KEEPALIVE_MESSAGE );
     783}
     784
     785void msn_sb_start_keepalives( struct msn_switchboard *sb, gboolean initial )
     786{
     787        struct buddy *b;
     788       
     789        if( sb && sb->who && sb->keepalive == 0 &&
     790            ( b = imcb_find_buddy( sb->ic, sb->who ) ) && !b->present &&
     791            set_getbool( &sb->ic->acc->set, "switchboard_keepalives" ) )
     792        {
     793                if( initial )
     794                        msn_sb_keepalive( sb, 0, 0 );
     795               
     796                sb->keepalive = b_timeout_add( 20000, msn_sb_keepalive, sb );
     797        }
     798}
     799
     800void msn_sb_stop_keepalives( struct msn_switchboard *sb )
     801{
     802        if( sb && sb->keepalive > 0 )
     803        {
     804                b_event_remove( sb->keepalive );
     805                sb->keepalive = 0;
     806        }
     807}
  • protocols/nogaim.c

    r5f8ab6a9 r814aa52  
    3939
    4040static int remove_chat_buddy_silent( struct groupchat *b, const char *handle );
     41static char *format_timestamp( irc_t *irc, time_t msg_ts );
    4142
    4243GSList *connections;
     
    132133        extern void byahoo_initmodule();
    133134        extern void jabber_initmodule();
     135        extern void twitter_initmodule();
    134136
    135137#ifdef WITH_MSN
     
    147149#ifdef WITH_JABBER
    148150        jabber_initmodule();
     151#endif
     152
     153#ifdef WITH_TWITTER
     154        twitter_initmodule();
    149155#endif
    150156
     
    727733{
    728734        irc_t *irc = ic->irc;
    729         char *wrapped;
     735        char *wrapped, *ts = NULL;
    730736        user_t *u;
    731737
     
    776782            ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) )
    777783                strip_html( msg );
    778 
     784       
     785        if( set_getbool( &ic->irc->set, "display_timestamps" ) &&
     786            ( ts = format_timestamp( irc, sent_at ) ) )
     787        {
     788                char *new = g_strconcat( ts, msg, NULL );
     789                g_free( ts );
     790                ts = msg = new;
     791        }
     792       
    779793        wrapped = word_wrap( msg, 425 );
    780794        irc_msgfrom( irc, u->nick, wrapped );
    781795        g_free( wrapped );
    782796        g_free( msg );
     797        g_free( ts );
    783798}
    784799
     
    822837       
    823838        return c;
     839}
     840
     841void imcb_chat_name_hint( struct groupchat *c, const char *name )
     842{
     843        if( !c->joined )
     844        {
     845                struct im_connection *ic = c->ic;
     846                char stripped[MAX_NICK_LENGTH+1], *full_name;
     847               
     848                strncpy( stripped, name, MAX_NICK_LENGTH );
     849                stripped[MAX_NICK_LENGTH] = '\0';
     850                nick_strip( stripped );
     851                if( set_getbool( &ic->irc->set, "lcnicks" ) )
     852                        nick_lc( stripped );
     853               
     854                full_name = g_strdup_printf( "&%s", stripped );
     855               
     856                if( stripped[0] &&
     857                    nick_cmp( stripped, ic->irc->channel + 1 ) != 0 &&
     858                    irc_chat_by_channel( ic->irc, full_name ) == NULL )
     859                {
     860                        g_free( c->channel );
     861                        c->channel = full_name;
     862                }
     863                else
     864                {
     865                        g_free( full_name );
     866                }
     867        }
    824868}
    825869
     
    884928        if( c && u )
    885929        {
    886                 irc_privmsg( ic->irc, u, "PRIVMSG", c->channel, "", wrapped );
     930                char *ts = NULL;
     931                if( set_getbool( &ic->irc->set, "display_timestamps" ) )
     932                        ts = format_timestamp( ic->irc, sent_at );
     933                irc_privmsg( ic->irc, u, "PRIVMSG", c->channel, ts ? : "", wrapped );
     934                g_free( ts );
    887935        }
    888936        else
     
    10211069
    10221070
     1071/* Misc. BitlBee stuff which shouldn't really be here */
     1072
     1073char *set_eval_timezone( set_t *set, char *value )
     1074{
     1075        char *s;
     1076       
     1077        if( strcmp( value, "local" ) == 0 ||
     1078            strcmp( value, "gmt" ) == 0 || strcmp( value, "utc" ) == 0 )
     1079                return value;
     1080       
     1081        /* Otherwise: +/- at the beginning optional, then one or more numbers,
     1082           possibly followed by a colon and more numbers. Don't bother bound-
     1083           checking them since users are free to shoot themselves in the foot. */
     1084        s = value;
     1085        if( *s == '+' || *s == '-' )
     1086                s ++;
     1087       
     1088        /* \d+ */
     1089        if( !isdigit( *s ) )
     1090                return SET_INVALID;
     1091        while( *s && isdigit( *s ) ) s ++;
     1092       
     1093        /* EOS? */
     1094        if( *s == '\0' )
     1095                return value;
     1096       
     1097        /* Otherwise, colon */
     1098        if( *s != ':' )
     1099                return SET_INVALID;
     1100        s ++;
     1101       
     1102        /* \d+ */
     1103        if( !isdigit( *s ) )
     1104                return SET_INVALID;
     1105        while( *s && isdigit( *s ) ) s ++;
     1106       
     1107        /* EOS */
     1108        return *s == '\0' ? value : SET_INVALID;
     1109}
     1110
     1111static char *format_timestamp( irc_t *irc, time_t msg_ts )
     1112{
     1113        time_t now_ts = time( NULL );
     1114        struct tm now, msg;
     1115        char *set;
     1116       
     1117        /* If the timestamp is <= 0 or less than a minute ago, discard it as
     1118           it doesn't seem to add to much useful info and/or might be noise. */
     1119        if( msg_ts <= 0 || msg_ts > now_ts - 60 )
     1120                return NULL;
     1121       
     1122        set = set_getstr( &irc->set, "timezone" );
     1123        if( strcmp( set, "local" ) == 0 )
     1124        {
     1125                localtime_r( &now_ts, &now );
     1126                localtime_r( &msg_ts, &msg );
     1127        }
     1128        else
     1129        {
     1130                int hr, min = 0, sign = 60;
     1131               
     1132                if( set[0] == '-' )
     1133                {
     1134                        sign *= -1;
     1135                        set ++;
     1136                }
     1137                else if( set[0] == '+' )
     1138                {
     1139                        set ++;
     1140                }
     1141               
     1142                if( sscanf( set, "%d:%d", &hr, &min ) >= 1 )
     1143                {
     1144                        msg_ts += sign * ( hr * 60 + min );
     1145                        now_ts += sign * ( hr * 60 + min );
     1146                }
     1147               
     1148                gmtime_r( &now_ts, &now );
     1149                gmtime_r( &msg_ts, &msg );
     1150        }
     1151       
     1152        if( msg.tm_year == now.tm_year && msg.tm_yday == now.tm_yday )
     1153                return g_strdup_printf( "\x02[\x02\x02\x02%02d:%02d:%02d\x02]\x02 ",
     1154                                        msg.tm_hour, msg.tm_min, msg.tm_sec );
     1155        else
     1156                return g_strdup_printf( "\x02[\x02\x02\x02%04d-%02d-%02d "
     1157                                        "%02d:%02d:%02d\x02]\x02 ",
     1158                                        msg.tm_year + 1900, msg.tm_mon, msg.tm_mday,
     1159                                        msg.tm_hour, msg.tm_min, msg.tm_sec );
     1160}
     1161
    10231162/* The plan is to not allow straight calls to prpl functions anymore, but do
    10241163   them all from some wrappers. We'll start to define some down here: */
     
    10631202{
    10641203        char *away, *msg = NULL;
     1204       
     1205        if( ic->acc->prpl->away_states == NULL ||
     1206            ic->acc->prpl->set_away == NULL )
     1207                return 0;
    10651208       
    10661209        away = set_getstr( &ic->acc->set, "away" ) ?
  • protocols/nogaim.h

    r5f8ab6a9 r814aa52  
    306306 *   user, too. */
    307307G_MODULE_EXPORT struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle );
     308G_MODULE_EXPORT void imcb_chat_name_hint( struct groupchat *c, const char *name );
    308309G_MODULE_EXPORT void imcb_chat_add_buddy( struct groupchat *b, const char *handle );
    309310/* To remove a handle from a group chat. Reason can be NULL. */
     
    328329
    329330/* Misc. stuff */
     331char *set_eval_timezone( set_t *set, char *value );
    330332gboolean auto_reconnect( gpointer data, gint fd, b_input_condition cond );
    331333void cancel_auto_reconnect( struct account *a );
  • protocols/oscar/oscar.c

    r5f8ab6a9 r814aa52  
    373373        set_t *s;
    374374       
    375         s = set_add( &acc->set, "server", AIM_DEFAULT_LOGIN_SERVER, set_eval_account, acc );
     375        if (isdigit(acc->user[0])) {
     376                set_add(&acc->set, "ignore_auth_requests", "false", set_eval_bool, acc);
     377        }
     378       
     379        s = set_add(&acc->set, "server", AIM_DEFAULT_LOGIN_SERVER, set_eval_account, acc);
    376380        s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY;
    377381       
    378         if (isdigit(acc->user[0])) {
    379                 s = set_add( &acc->set, "web_aware", "false", set_eval_bool, acc );
     382        if(isdigit(acc->user[0])) {
     383                s = set_add(&acc->set, "web_aware", "false", set_eval_bool, acc);
    380384                s->flags |= ACC_SET_OFFLINE_ONLY;
    381385        }
     
    12121216 */
    12131217static void gaim_icq_authask(struct im_connection *ic, guint32 uin, char *msg) {
    1214         struct icq_auth *data = g_new(struct icq_auth, 1);
     1218        struct icq_auth *data;
    12151219        char *reason = NULL;
    12161220        char *dialog_msg;
    1217        
     1221
     1222        if (set_getbool(&ic->acc->set, "ignore_auth_requests"))
     1223                return;
     1224       
     1225        data = g_new(struct icq_auth, 1);
     1226
    12181227        if (strlen(msg) > 6)
    12191228                reason = msg + 6;
Note: See TracChangeset for help on using the changeset viewer.