Changeset ae3dc99 for protocols


Ignore:
Timestamp:
2010-04-24T17:02:07Z (15 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
c521362
Parents:
b5b40ff (diff), f1b7711 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merging stuff from mainline (1.2.6).

Location:
protocols
Files:
7 added
9 edited

Legend:

Unmodified
Added
Removed
  • protocols/jabber/jabber_util.c

    rb5b40ff rae3dc99  
    671671time_t jabber_get_timestamp( struct xt_node *xt )
    672672{
    673         struct tm tp, utc;
    674673        struct xt_node *c;
    675         time_t res, tres;
    676674        char *s = NULL;
     675        struct tm tp;
    677676       
    678677        for( c = xt->children; ( c = xt_find_node( c, "x" ) ); c = c->next )
     
    692691        tp.tm_year -= 1900;
    693692        tp.tm_mon --;
    694         tp.tm_isdst = -1; /* GRRRRRRRRRRR */
    695        
    696         res = mktime( &tp );
    697         /* Problem is, mktime() just gave us the GMT timestamp for the
    698            given local time... While the given time WAS NOT local. So
    699            we should fix this now.
    700        
    701            Now I could choose between messing with environment variables
    702            (kludgy) or using timegm() (not portable)... Or doing the
    703            following, which I actually prefer... */
    704         gmtime_r( &res, &utc );
    705         utc.tm_isdst = -1; /* Once more: GRRRRRRRRRRRRRRRRRR!!! */
    706         if( utc.tm_hour == tp.tm_hour && utc.tm_min == tp.tm_min )
    707                 /* Sweet! We're in UTC right now... */
    708                 return res;
    709        
    710         tres = mktime( &utc );
    711         res += res - tres;
    712        
    713         /* Yes, this is a hack. And it will go wrong around DST changes.
    714            BUT this is more likely to be threadsafe than messing with
    715            environment variables, and possibly more portable... */
    716        
    717         return res;
     693       
     694        return mktime_utc( &tp );
    718695}
    719696
  • protocols/jabber/message.c

    rb5b40ff rae3dc99  
    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/msn/msn.c

    rb5b40ff rae3dc99  
    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
     
    171169static void msn_set_my_name( struct im_connection *ic, char *info )
    172170{
    173         msn_set_display_name( set_find( &ic->acc->set, "display_name" ), info );
     171        msn_set_display_name( ic, info );
    174172}
    175173
     
    287285}
    288286
    289 static char *msn_set_display_name( set_t *set, char *value )
     287static char *set_eval_display_name( set_t *set, char *value )
    290288{
    291289        account_t *acc = set->data;
    292290        struct im_connection *ic = acc->ic;
    293         struct msn_data *md;
    294         char buf[1024], *fn;
    295        
    296         /* Double-check. */
     291       
     292        /* Allow any name if we're offline. */
    297293        if( ic == NULL )
    298                 return NULL;
    299        
    300         md = ic->proto_data;
     294                return value;
    301295       
    302296        if( strlen( value ) > 129 )
     
    305299                return NULL;
    306300        }
    307        
    308         fn = msn_http_encode( value );
    309        
    310         g_snprintf( buf, sizeof( buf ), "REA %d %s %s\r\n", ++md->trId, ic->acc->user, fn );
    311         msn_write( ic, buf, strlen( buf ) );
    312         g_free( fn );
    313301       
    314302        /* Returning NULL would be better, because the server still has to
    315303           confirm the name change. However, it looks a bit confusing to the
    316304           user. */
    317         return value;
     305        return msn_set_display_name( ic, value ) ? value : NULL;
    318306}
    319307
  • protocols/msn/msn.h

    rb5b40ff rae3dc99  
    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/"
     
    8489        gint inp;
    8590        struct msn_handler_data *handler;
     91        gint keepalive;
    8692       
    8793        int trId;
     
    162168char *msn_http_encode( const char *input );
    163169void msn_msgq_purge( struct im_connection *ic, GSList **list );
     170gboolean msn_set_display_name( struct im_connection *ic, const char *rawname );
    164171
    165172/* tables.c */
     
    180187gboolean msn_sb_connected( gpointer data, gint source, b_input_condition cond );
    181188int msn_sb_write_msg( struct im_connection *ic, struct msn_message *m );
     189void msn_sb_start_keepalives( struct msn_switchboard *sb, gboolean initial );
     190void msn_sb_stop_keepalives( struct msn_switchboard *sb );
    182191
    183192/* invitation.c */
  • protocols/msn/msn_util.c

    rb5b40ff rae3dc99  
    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

    rb5b40ff rae3dc99  
    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" );
     
    436422        else if( strcmp( cmd[0], "FLN" ) == 0 )
    437423        {
    438                 if( cmd[1] )
    439                         imcb_buddy_status( ic, cmd[1], 0, NULL, NULL );
     424                if( cmd[1] == NULL )
     425                        return 1;
     426               
     427                imcb_buddy_status( ic, cmd[1], 0, NULL, NULL );
     428               
     429                msn_sb_start_keepalives( msn_sb_by_handle( ic, cmd[1] ), TRUE );
    440430        }
    441431        else if( strcmp( cmd[0], "NLN" ) == 0 )
     
    463453                                   ( st != msn_away_state_list ? OPT_AWAY : 0 ),
    464454                                   st->name, NULL );
     455               
     456                msn_sb_stop_keepalives( msn_sb_by_handle( ic, cmd[2] ) );
    465457        }
    466458        else if( strcmp( cmd[0], "RNG" ) == 0 )
     
    567559                return( 0 );
    568560        }
     561#if 0
     562        /* Discard this one completely for now since I don't care about the ack
     563           and since MSN servers can apparently screw up the formatting. */
    569564        else if( strcmp( cmd[0], "REA" ) == 0 )
    570565        {
     
    597592                }
    598593        }
     594#endif
    599595        else if( strcmp( cmd[0], "IPG" ) == 0 )
    600596        {
     
    746742        }
    747743}
     744
     745static gboolean msn_ns_got_display_name( struct im_connection *ic, char *name )
     746{
     747        set_t *s;
     748       
     749        if( ( s = set_find( &ic->acc->set, "display_name" ) ) == NULL )
     750                return FALSE; /* Shouldn't happen.. */
     751       
     752        http_decode( name );
     753       
     754        if( s->value && strcmp( s->value, name ) == 0 )
     755        {
     756                return TRUE;
     757                /* The names match, nothing to worry about. */
     758        }
     759        else if( s->value != NULL &&
     760                 ( strcmp( name, ic->acc->user ) == 0 ||
     761                   set_getbool( &ic->acc->set, "local_display_name" ) ) )
     762        {
     763                /* The server thinks our display name is our e-mail address
     764                   which is probably wrong, or the user *wants* us to do this:
     765                   Always use the locally set display_name. */
     766                return msn_set_display_name( ic, s->value );
     767        }
     768        else
     769        {
     770                if( s->value && *s->value )
     771                        imcb_log( ic, "BitlBee thinks your display name is `%s' but "
     772                                      "the MSN server says it's `%s'. Using the MSN "
     773                                      "server's name. Set local_display_name to true "
     774                                      "to use the local name.", s->value, name );
     775               
     776                if( g_utf8_validate( name, -1, NULL ) )
     777                {
     778                        g_free( s->value );
     779                        s->value = g_strdup( name );
     780                }
     781                else
     782                {
     783                        imcb_log( ic, "Warning: Friendly name in server response was corrupted" );
     784                }
     785               
     786                return TRUE;
     787        }
     788}
  • protocols/msn/sb.c

    rb5b40ff rae3dc99  
    180180                        i = strlen( buf );
    181181                }
     182                else if( strcmp( text, SB_KEEPALIVE_MESSAGE ) == 0 )
     183                {
     184                        buf = g_strdup( SB_KEEPALIVE_HEADERS );
     185                        i = strlen( buf );
     186                }
    182187                else
    183188                {
     
    256261       
    257262        msn_msgq_purge( ic, &sb->msgq );
     263        msn_sb_stop_keepalives( sb );
    258264       
    259265        if( sb->key ) g_free( sb->key );
     
    477483               
    478484                sb->ready = 1;
     485               
     486                msn_sb_start_keepalives( sb, FALSE );
    479487        }
    480488        else if( strcmp( cmd[0], "CAL" ) == 0 )
     
    526534                        }
    527535                       
     536                        msn_sb_start_keepalives( sb, FALSE );
     537                       
    528538                        return( st );
    529539                }
     
    587597                if( sb->who )
    588598                {
     599                        msn_sb_stop_keepalives( sb );
     600                       
    589601                        /* This is a single-person chat, and the other person is leaving. */
    590602                        g_free( sb->who );
     
    749761        return( 1 );
    750762}
     763
     764static gboolean msn_sb_keepalive( gpointer data, gint source, b_input_condition cond )
     765{
     766        struct msn_switchboard *sb = data;
     767        return sb->ready && msn_sb_sendmessage( sb, SB_KEEPALIVE_MESSAGE );
     768}
     769
     770void msn_sb_start_keepalives( struct msn_switchboard *sb, gboolean initial )
     771{
     772        struct buddy *b;
     773       
     774        if( sb && sb->who && sb->keepalive == 0 &&
     775            ( b = imcb_find_buddy( sb->ic, sb->who ) ) && !b->present &&
     776            set_getbool( &sb->ic->acc->set, "switchboard_keepalives" ) )
     777        {
     778                if( initial )
     779                        msn_sb_keepalive( sb, 0, 0 );
     780               
     781                sb->keepalive = b_timeout_add( 20000, msn_sb_keepalive, sb );
     782        }
     783}
     784
     785void msn_sb_stop_keepalives( struct msn_switchboard *sb )
     786{
     787        if( sb && sb->keepalive > 0 )
     788        {
     789                b_event_remove( sb->keepalive );
     790                sb->keepalive = 0;
     791        }
     792}
  • protocols/nogaim.c

    rb5b40ff rae3dc99  
    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;
     
    135136        extern void byahoo_initmodule();
    136137        extern void jabber_initmodule();
     138        extern void twitter_initmodule();
    137139        extern void purple_initmodule();
    138140
     
    151153#ifdef WITH_JABBER
    152154        jabber_initmodule();
     155#endif
     156
     157#ifdef WITH_TWITTER
     158        twitter_initmodule();
    153159#endif
    154160       
     
    726732{
    727733        irc_t *irc = ic->irc;
    728         char *wrapped;
     734        char *wrapped, *ts = NULL;
    729735        user_t *u;
    730736       
     
    768774            ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) )
    769775                strip_html( msg );
    770 
     776       
     777        if( set_getbool( &ic->irc->set, "display_timestamps" ) &&
     778            ( ts = format_timestamp( irc, sent_at ) ) )
     779        {
     780                char *new = g_strconcat( ts, msg, NULL );
     781                g_free( ts );
     782                ts = msg = new;
     783        }
     784       
    771785        wrapped = word_wrap( msg, 425 );
    772786        irc_msgfrom( irc, u->nick, wrapped );
    773787        g_free( wrapped );
     788        g_free( ts );
    774789}
    775790
     
    813828       
    814829        return c;
     830}
     831
     832void imcb_chat_name_hint( struct groupchat *c, const char *name )
     833{
     834        if( !c->joined )
     835        {
     836                struct im_connection *ic = c->ic;
     837                char stripped[MAX_NICK_LENGTH+1], *full_name;
     838               
     839                strncpy( stripped, name, MAX_NICK_LENGTH );
     840                stripped[MAX_NICK_LENGTH] = '\0';
     841                nick_strip( stripped );
     842                if( set_getbool( &ic->irc->set, "lcnicks" ) )
     843                        nick_lc( stripped );
     844               
     845                full_name = g_strdup_printf( "&%s", stripped );
     846               
     847                if( stripped[0] &&
     848                    nick_cmp( stripped, ic->irc->channel + 1 ) != 0 &&
     849                    irc_chat_by_channel( ic->irc, full_name ) == NULL )
     850                {
     851                        g_free( c->channel );
     852                        c->channel = full_name;
     853                }
     854                else
     855                {
     856                        g_free( full_name );
     857                }
     858        }
    815859}
    816860
     
    875919        if( c && u )
    876920        {
    877                 irc_privmsg( ic->irc, u, "PRIVMSG", c->channel, "", wrapped );
     921                char *ts = NULL;
     922                if( set_getbool( &ic->irc->set, "display_timestamps" ) )
     923                        ts = format_timestamp( ic->irc, sent_at );
     924                irc_privmsg( ic->irc, u, "PRIVMSG", c->channel, ts ? : "", wrapped );
     925                g_free( ts );
    878926        }
    879927        else
     
    10691117}
    10701118
    1071 
    1072 
     1119char *set_eval_timezone( set_t *set, char *value )
     1120{
     1121        char *s;
     1122       
     1123        if( strcmp( value, "local" ) == 0 ||
     1124            strcmp( value, "gmt" ) == 0 || strcmp( value, "utc" ) == 0 )
     1125                return value;
     1126       
     1127        /* Otherwise: +/- at the beginning optional, then one or more numbers,
     1128           possibly followed by a colon and more numbers. Don't bother bound-
     1129           checking them since users are free to shoot themselves in the foot. */
     1130        s = value;
     1131        if( *s == '+' || *s == '-' )
     1132                s ++;
     1133       
     1134        /* \d+ */
     1135        if( !isdigit( *s ) )
     1136                return SET_INVALID;
     1137        while( *s && isdigit( *s ) ) s ++;
     1138       
     1139        /* EOS? */
     1140        if( *s == '\0' )
     1141                return value;
     1142       
     1143        /* Otherwise, colon */
     1144        if( *s != ':' )
     1145                return SET_INVALID;
     1146        s ++;
     1147       
     1148        /* \d+ */
     1149        if( !isdigit( *s ) )
     1150                return SET_INVALID;
     1151        while( *s && isdigit( *s ) ) s ++;
     1152       
     1153        /* EOS */
     1154        return *s == '\0' ? value : SET_INVALID;
     1155}
     1156
     1157static char *format_timestamp( irc_t *irc, time_t msg_ts )
     1158{
     1159        time_t now_ts = time( NULL );
     1160        struct tm now, msg;
     1161        char *set;
     1162       
     1163        /* If the timestamp is <= 0 or less than a minute ago, discard it as
     1164           it doesn't seem to add to much useful info and/or might be noise. */
     1165        if( msg_ts <= 0 || msg_ts > now_ts - 60 )
     1166                return NULL;
     1167       
     1168        set = set_getstr( &irc->set, "timezone" );
     1169        if( strcmp( set, "local" ) == 0 )
     1170        {
     1171                localtime_r( &now_ts, &now );
     1172                localtime_r( &msg_ts, &msg );
     1173        }
     1174        else
     1175        {
     1176                int hr, min = 0, sign = 60;
     1177               
     1178                if( set[0] == '-' )
     1179                {
     1180                        sign *= -1;
     1181                        set ++;
     1182                }
     1183                else if( set[0] == '+' )
     1184                {
     1185                        set ++;
     1186                }
     1187               
     1188                if( sscanf( set, "%d:%d", &hr, &min ) >= 1 )
     1189                {
     1190                        msg_ts += sign * ( hr * 60 + min );
     1191                        now_ts += sign * ( hr * 60 + min );
     1192                }
     1193               
     1194                gmtime_r( &now_ts, &now );
     1195                gmtime_r( &msg_ts, &msg );
     1196        }
     1197       
     1198        if( msg.tm_year == now.tm_year && msg.tm_yday == now.tm_yday )
     1199                return g_strdup_printf( "\x02[\x02\x02\x02%02d:%02d:%02d\x02]\x02 ",
     1200                                        msg.tm_hour, msg.tm_min, msg.tm_sec );
     1201        else
     1202                return g_strdup_printf( "\x02[\x02\x02\x02%04d-%02d-%02d "
     1203                                        "%02d:%02d:%02d\x02]\x02 ",
     1204                                        msg.tm_year + 1900, msg.tm_mon, msg.tm_mday,
     1205                                        msg.tm_hour, msg.tm_min, msg.tm_sec );
     1206}
    10731207
    10741208/* The plan is to not allow straight calls to prpl functions anymore, but do
     
    11131247{
    11141248        char *away, *msg = NULL;
     1249       
     1250        if( ic->acc->prpl->away_states == NULL ||
     1251            ic->acc->prpl->set_away == NULL )
     1252                return 0;
    11151253       
    11161254        away = set_getstr( &ic->acc->set, "away" ) ?
  • protocols/nogaim.h

    rb5b40ff rae3dc99  
    308308 *   user, too. */
    309309G_MODULE_EXPORT struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle );
     310G_MODULE_EXPORT void imcb_chat_name_hint( struct groupchat *c, const char *name );
    310311G_MODULE_EXPORT void imcb_chat_add_buddy( struct groupchat *b, const char *handle );
    311312/* To remove a handle from a group chat. Reason can be NULL. */
     
    330331
    331332/* Misc. stuff */
     333char *set_eval_timezone( set_t *set, char *value );
    332334char *set_eval_away_devoice( set_t *set, char *value );
    333335gboolean auto_reconnect( gpointer data, gint fd, b_input_condition cond );
Note: See TracChangeset for help on using the changeset viewer.