Changeset ae3dc99


Ignore:
Timestamp:
2010-04-24T17:02:07Z (9 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).

Files:
7 added
26 edited

Legend:

Unmodified
Added
Removed
  • Makefile

    rb5b40ff rae3dc99  
    126126ctags:
    127127        ctags `find . -name "*.c"` `find . -name "*.h"`
     128
     129# Using this as a bogus Make target to test if a GNU-compatible version of
     130# make is available.
     131helloworld:
     132        @echo Hello World
  • bitlbee.c

    rb5b40ff rae3dc99  
    3636static gboolean bitlbee_io_new_client( gpointer data, gint fd, b_input_condition condition );
    3737
     38static gboolean try_listen( struct addrinfo *res )
     39{
     40        int i;
     41       
     42        global.listen_socket = socket( res->ai_family, res->ai_socktype, res->ai_protocol );
     43        if( global.listen_socket < 0 )
     44        {
     45                log_error( "socket" );
     46                return FALSE;
     47        }
     48
     49#ifdef IPV6_V6ONLY             
     50        if( res->ai_family == AF_INET6 )
     51        {
     52                i = 0;
     53                setsockopt( global.listen_socket, IPPROTO_IPV6, IPV6_V6ONLY,
     54                            (char *) &i, sizeof( i ) );
     55        }
     56#endif
     57
     58        /* TIME_WAIT (?) sucks.. */
     59        i = 1;
     60        setsockopt( global.listen_socket, SOL_SOCKET, SO_REUSEADDR, &i, sizeof( i ) );
     61
     62        i = bind( global.listen_socket, res->ai_addr, res->ai_addrlen );
     63        if( i == -1 )
     64        {
     65                closesocket( global.listen_socket );
     66                global.listen_socket = -1;
     67               
     68                log_error( "bind" );
     69                return FALSE;
     70        }
     71       
     72        return TRUE;
     73}
     74
    3875int bitlbee_daemon_init()
    3976{
     
    4279        FILE *fp;
    4380       
    44         log_link( LOGLVL_ERROR, LOGOUTPUT_SYSLOG );
    45         log_link( LOGLVL_WARNING, LOGOUTPUT_SYSLOG );
     81        log_link( LOGLVL_ERROR, LOGOUTPUT_CONSOLE );
     82        log_link( LOGLVL_WARNING, LOGOUTPUT_CONSOLE );
    4683       
    4784        memset( &hints, 0, sizeof( hints ) );
     
    63100
    64101        global.listen_socket = -1;
    65 
     102       
     103        /* Try IPv6 first (which will become an IPv6+IPv4 socket). */
    66104        for( res = addrinfo_bind; res; res = res->ai_next )
    67         {
    68                 global.listen_socket = socket( res->ai_family, res->ai_socktype, res->ai_protocol );
    69                 if( global.listen_socket < 0 )
    70                         continue;
    71 
    72                 /* TIME_WAIT (?) sucks.. */
    73                 i = 1;
    74                 setsockopt( global.listen_socket, SOL_SOCKET, SO_REUSEADDR, &i, sizeof( i ) );
    75 
    76                 i = bind( global.listen_socket, res->ai_addr, res->ai_addrlen );
    77                 if( i == -1 )
    78                 {
    79                         log_error( "bind" );
    80                         return( -1 );
    81                 }
    82 
    83                 break;
    84         }
    85 
     105                if( res->ai_family == AF_INET6 && try_listen( res ) )
     106                        break;
     107       
     108        /* The rest (so IPv4, I guess). */
     109        if( res == NULL )
     110                for( res = addrinfo_bind; res; res = res->ai_next )
     111                        if( res->ai_family != AF_INET6 && try_listen( res ) )
     112                                break;
     113       
    86114        freeaddrinfo( addrinfo_bind );
    87115
     
    107135                        exit( 0 );
    108136               
     137                setsid();
    109138                chdir( "/" );
    110139               
     
    137166#endif
    138167       
     168        if( !global.conf->nofork )
     169        {
     170                log_link( LOGLVL_ERROR, LOGOUTPUT_SYSLOG );
     171                log_link( LOGLVL_WARNING, LOGOUTPUT_SYSLOG );
     172        }
     173       
    139174        return( 0 );
    140175}
  • bitlbee.h

    rb5b40ff rae3dc99  
    3535
    3636#define PACKAGE "BitlBee"
    37 #define BITLBEE_VERSION "1.2.5"
     37#define BITLBEE_VERSION "1.2.6a"
    3838#define VERSION BITLBEE_VERSION
     39#define BITLBEE_VER(a,b,c) (((a) << 16) + ((b) << 8) + (c))
     40#define BITLBEE_VERSION_CODE BITLBEE_VER(1, 2, 6)
    3941
    4042#define MAX_STRING 511
  • conf.c

    rb5b40ff rae3dc99  
    8282        }
    8383       
    84         while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hR:u:" ) ) >= 0 )
     84        while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hR:u:V" ) ) >= 0 )
    8585        /*     ^^^^ Just to make sure we skip this step from the REHASH handler. */
    8686        {
     
    148148                                "  -d  Specify alternative user configuration directory\n"
    149149                                "  -x  Command-line interface to password encryption/hashing\n"
    150                                 "  -h  Show this help page.\n" );
     150                                "  -h  Show this help page.\n"
     151                                "  -V  Show version info.\n" );
     152                        return NULL;
     153                }
     154                else if( opt == 'V' )
     155                {
     156                        printf( "BitlBee %s\nAPI version %06x\n",
     157                                BITLBEE_VERSION, BITLBEE_VERSION_CODE );
    151158                        return NULL;
    152159                }
  • configure

    rb5b40ff rae3dc99  
    2626oscar=1
    2727yahoo=1
     28twitter=1
    2829purple=0
    2930
     
    6768--oscar=0/1     Disable/enable Oscar part (ICQ, AIM)    $oscar
    6869--yahoo=0/1     Disable/enable Yahoo part               $yahoo
     70--twitter=0/1 Disable/enable Twitter part               $twitter
    6971
    7072--purple=0/1    Disable/enable libpurple support        $purple
     
    270272detect_ldap()
    271273{
    272         TMPFILE=$(mktemp)
     274        TMPFILE=$(mktemp /tmp/bitlbee-configure.XXXXXX)
    273275        if $CC -o $TMPFILE -shared -lldap 2>/dev/null >/dev/null; then
    274276                cat<<EOF>>Makefile.settings
     
    298300detect_resolv_dynamic()
    299301{
    300         TMPFILE=$(mktemp)
     302        TMPFILE=$(mktemp /tmp/bitlbee-configure.XXXXXX)
    301303        ret=1
    302304        echo "$RESOLV_TESTCODE" | $CC -o $TMPFILE -x c - -lresolv >/dev/null 2>/dev/null
     
    312314detect_resolv_static()
    313315{
    314         TMPFILE=$(mktemp)
     316        TMPFILE=$(mktemp /tmp/bitlbee-configure.XXXXXX)
    315317        ret=1
    316318        for i in $systemlibdirs; do
     
    479481fi
    480482
     483if ! make helloworld > /dev/null 2>&1; then
     484        echo "WARNING: Your version of make (BSD make?) does not support BitlBee's makefiles."
     485        echo "BitlBee needs GNU make to build properly. On most systems GNU make is available"
     486        echo "under the name 'gmake'."
     487        echo
     488        if gmake helloworld > /dev/null 2>&1; then
     489                echo "gmake seems to be available on your machine, great."
     490                echo
     491        else
     492                echo "gmake is not installed (or not working). Please try to install it."
     493                echo
     494        fi
     495fi
     496
    481497cat <<EOF>bitlbee.pc
    482498prefix=$prefix
     
    551567fi
    552568
     569if [ "$twitter" = 0 ]; then
     570        echo '#undef WITH_TWITTER' >> config.h
     571else
     572        echo '#define WITH_TWITTER' >> config.h
     573        protocols=$protocols'twitter '
     574        protoobjs=$protoobjs'twitter_mod.o '
     575fi
     576
    553577if [ "$protocols" = "PROTOCOLS = " ]; then
    554578        echo "Warning: You haven't selected any communication protocol to compile!"
  • debian/bitlbee.init

    rb5b40ff rae3dc99  
    3838d_start() {
    3939        # Make sure BitlBee can actually write its PID...
    40         touch /var/run/bitlbee.pid
    41         chown bitlbee: /var/run/bitlbee.pid
     40        touch $PIDFILE
     41        chown bitlbee: $PIDFILE
    4242       
    4343        start-stop-daemon --start --quiet --pidfile $PIDFILE \
  • debian/changelog

    rb5b40ff rae3dc99  
     1bitlbee (1.2.6a-1) unstable; urgency=low
     2
     3  * New upstream version.
     4  * Native support for Twitter.
     5  * Fixed /WHOIS response format. (Closes: #576120)
     6  * Problems with bitlbee-skype are solved by now. (Closes: #575572)
     7
     8 -- Wilmer van der Gaast <wilmer@peer.gaast.net>  Tue, 20 Apr 2010 00:34:51 +0200
     9
    110bitlbee (1.2.5-1) unstable; urgency=low
    211
  • debian/rules

    rb5b40ff rae3dc99  
    100100                find usr -type f -exec md5sum {} \; > DEBIAN/md5sums
    101101
    102         dpkg-gencontrol -ldebian/changelog -isp -pbitlbee-dev -Pdebian/bitlbee-dev
     102        dpkg-gencontrol -ldebian/changelog -isp -pbitlbee-dev -Pdebian/bitlbee-dev -v1:$(BITLBEE_VERSION)-0
    103103
    104104        dpkg --build debian/bitlbee-dev ..
  • doc/CHANGES

    rb5b40ff rae3dc99  
    33
    44http://bugs.bitlbee.org/bitlbee/timeline?daysback=90&changeset=on
     5
     6Version 1.2.6a:
     7- Fixed a typo that renders the Twitter groupchat mode unusable. A last-
     8  minute change that came a few minutes late.
     9
     10Finished 19 Apr 2010
     11
     12Version 1.2.6:
     13- Native (very basic) support for Twitter, implemented by Geert Mulders.
     14  Currently supported are posting tweets, reading the ones of people you
     15  follow, and sending (not yet receiving!) direct messages.
     16- Fixed format of status messages in /WHOIS to improve IRC client
     17  compatibility.
     18- Show timestamps of offline messages/channel backlogs.
     19- Allow saving MSN display names locally since sometimes this stuff breaks
     20  server-side. (Use the local_display_name per-account setting.)
     21- Suppress empty "Headline:" messages for certain new XMPP broadcast
     22  messages.
     23- Better handling of XMPP contacts with multiple resources on-line. Default
     24  behaviour now is to write to wherever the last message came from, or to
     25  the bare JID (usually becomes a broadcast) if there wasn't any recent msg.
     26- Added a switchboard_keepalives setting which should solve some issues with
     27  talking to offline MSN contacts. (Although full support for offline
     28  messages is not ready yet!)
     29- The usual misc. bug fixes.
     30
     31Finished 19 Apr 2010
    532
    633Version 1.2.5:
     
    2350  the main client).
    2451
    25 Fixed 17 Mar 2010
     52Finished 17 Mar 2010
    2653
    2754Version 1.2.4:
  • doc/user-guide/commands.xml

    rb5b40ff rae3dc99  
    2121                        <description>
    2222                                <para>
    23                                         Adds an account on the given server with the specified protocol, username and password to the account list. Supported protocols right now are: Jabber, MSN, OSCAR (AIM/ICQ) and Yahoo. For more information about adding an account, see <emphasis>help account add &lt;protocol&gt;</emphasis>.
     23                                        Adds an account on the given server with the specified protocol, username and password to the account list. Supported protocols right now are: Jabber, MSN, OSCAR (AIM/ICQ), Yahoo and Twitter. For more information about adding an account, see <emphasis>help account add &lt;protocol&gt;</emphasis>.
    2424                                </para>
    2525                        </description>
     
    6363                                </ircexample>
    6464                        </bitlbee-command>
     65                       
     66                        <bitlbee-command name="twitter">
     67                                <syntax>account add twitter &lt;handle&gt; &lt;password&gt;</syntax>
     68
     69                                <description>
     70                                        <para>
     71                                                This module gives you simple access to Twitter. Although it uses the Twitter API, only Twitter itself is supported at the moment.
     72                                        </para>
     73                                       
     74                                        <para>
     75                                                By default all your Twitter contacts will come from a contact called twitter_(yourusername). You can change this behaviour using the <emphasis>mode</emphasis> setting (see <emphasis>help set mode</emphasis>).
     76                                        </para>
     77                                       
     78                                        <para>
     79                                                To send tweets yourself, send them to the twitter_(yourusername) contact, or just write in the groupchat channel if you enabled that option.
     80                                        </para>
     81                                </description>
     82                        </bitlbee-command>
    6583
    6684                        <bitlbee-command name="yahoo">
     
    401419
    402420        <bitlbee-setting name="auto_reconnect" type="boolean" scope="both">
    403                 <default>false</default>
     421                <default>true</default>
    404422
    405423                <description>
     
    556574                        <para>
    557575                                With this option enabled, root will inform you when someone in your buddy list changes his/her "friendly name".
     576                        </para>
     577                </description>
     578        </bitlbee-setting>
     579
     580        <bitlbee-setting name="display_timestamps" type="boolean" scope="global">
     581                <default>true</default>
     582
     583                <description>
     584                        <para>
     585                                When incoming messages are old (i.e. offline messages and channel backlogs), BitlBee will prepend them with a timestamp. If you find them ugly or useless, you can use this setting to hide them.
    558586                        </para>
    559587                </description>
     
    609637        </bitlbee-setting>
    610638
     639        <bitlbee-setting name="local_display_name" type="boolean" scope="account">
     640                <default>false</default>
     641
     642                <description>
     643                        <para>
     644                                Mostly meant to work around a bug in MSN servers (forgetting the display name set by the user), this setting tells BitlBee to store your display name locally and set this name on the MSN servers when connecting.
     645                        </para>
     646                </description>
     647
     648        </bitlbee-setting>
     649
    611650        <bitlbee-setting name="mail_notifications" type="boolean" scope="account">
    612651                <default>false</default>
     
    615654                        <para>
    616655                                Some protocols (MSN, Yahoo!) can notify via IM about new e-mail. Since most people use their Hotmail/Yahoo! addresses as a spam-box, this is disabled default. If you want these notifications, you can enable this setting.
     656                        </para>
     657                </description>
     658
     659        </bitlbee-setting>
     660
     661        <bitlbee-setting name="mode" type="string" scope="account">
     662                <possible-values>one, many, chat</possible-values>
     663                <default>one</default>
     664
     665                <description>
     666                        <para>
     667                                By default, everything from the Twitter module will come from one nick, twitter_(yourusername). If you prefer to have individual nicks for everyone, you can set this setting to "many" instead.
     668                        </para>
     669                       
     670                        <para>
     671                                If you prefer to have all your Twitter things in a separate channel, you can set this setting to "chat".
     672                        </para>
     673                       
     674                        <para>
     675                                In the last two modes, you can send direct messages by /msg'ing your contacts directly. Note, however, that incoming DMs are not fetched yet.
    617676                        </para>
    618677                </description>
     
    824883                        <para>
    825884                                If BitlBee fails to detect this sometimes (most likely in AIM messages over an ICQ connection), you can set this setting to <emphasis>always</emphasis>, but this might sometimes accidentally strip non-HTML things too.
     885                        </para>
     886                </description>
     887        </bitlbee-setting>
     888
     889        <bitlbee-setting name="switchboard_keepalives" type="boolean" scope="account">
     890                <default>false</default>
     891
     892                <description>
     893                        <para>
     894                                Turn on this flag if you have difficulties talking to offline/invisible contacts.
     895                        </para>
     896                       
     897                        <para>
     898                                With this setting enabled, BitlBee will send keepalives to MSN switchboards with offline/invisible contacts every twenty seconds. This should keep the server and client on the other side from shutting it down.
     899                        </para>
     900                       
     901                        <para>
     902                                This is useful because BitlBee doesn't support MSN offline messages yet and the MSN servers won't let the user reopen switchboards to offline users. Once offline messaging is supported, this flag might be removed.
     903                        </para>
     904                </description>
     905        </bitlbee-setting>
     906
     907        <bitlbee-setting name="timezone" type="string" scope="global">
     908                <default>local</default>
     909                <possible-values>local, utc, gmt, timezone-spec</possible-values>
     910
     911                <description>
     912                        <para>
     913                                If message timestamps are available for offline messages or chatroom backlogs, BitlBee will display them as part of the message. By default it will use the local timezone. If you're not in the same timezone as the BitlBee server, you can adjust the timestamps using this setting.
     914                        </para>
     915
     916                        <para>
     917                                Values local/utc/gmt should be self-explanatory. timezone-spec is a time offset in hours:minutes, for example: -8 for Pacific Standard Time, +2 for Central European Summer Time, +5:30 for Indian Standard Time.
    826918                        </para>
    827919                </description>
  • irc.c

    rb5b40ff rae3dc99  
    5353{
    5454        irc_t *irc = set->data;
     55        char *test;
     56        gsize test_bytes = 0;
    5557        GIConv ic, oc;
    5658
     
    5860                value = g_strdup( "utf-8" );
    5961
     62        if( ( oc = g_iconv_open( value, "utf-8" ) ) == (GIConv) -1 )
     63        {
     64                return NULL;
     65        }
     66       
     67        /* Do a test iconv to see if the user picked an IRC-compatible
     68           charset (for example utf-16 goes *horribly* wrong). */
     69        if( ( test = g_convert_with_iconv( " ", 1, oc, NULL, &test_bytes, NULL ) ) == NULL ||
     70            test_bytes > 1 )
     71        {
     72                g_free( test );
     73                g_iconv_close( oc );
     74                irc_usermsg( irc, "Unsupported character set: The IRC protocol "
     75                                  "only supports 8-bit character sets." );
     76                return NULL;
     77        }
     78        g_free( test );
     79       
    6080        if( ( ic = g_iconv_open( "utf-8", value ) ) == (GIConv) -1 )
    6181        {
    62                 return NULL;
    63         }
    64         if( ( oc = g_iconv_open( value, "utf-8" ) ) == (GIConv) -1 )
    65         {
    66                 g_iconv_close( ic );
     82                g_iconv_close( oc );
    6783                return NULL;
    6884        }
     
    176192        s = set_add( &irc->set, "default_target", "root", NULL, irc );
    177193        s = set_add( &irc->set, "display_namechanges", "false", set_eval_bool, irc );
     194        s = set_add( &irc->set, "display_timestamps", "true", set_eval_bool, irc );
    178195        s = set_add( &irc->set, "handle_unknown", "root", NULL, irc );
    179196        s = set_add( &irc->set, "lcnicks", "true", set_eval_bool, irc );
     
    189206        s->flags |= SET_NULL_OK;
    190207        s = set_add( &irc->set, "strip_html", "true", NULL, irc );
     208        s = set_add( &irc->set, "timezone", "local", set_eval_timezone, irc );
    191209        s = set_add( &irc->set, "to_char", ": ", set_eval_to_char, irc );
    192210        s = set_add( &irc->set, "typing_notice", "false", set_eval_bool, irc );
  • irc_commands.c

    rb5b40ff rae3dc99  
    498498                        irc_reply( irc, 301, "%s :%s", u->nick, u->away );
    499499                if( u->status_msg )
    500                         irc_reply( irc, 333, "%s :Status: %s", u->nick, u->status_msg );
     500                        irc_reply( irc, 320, "%s :%s", u->nick, u->status_msg );
    501501               
    502502                irc_reply( irc, 318, "%s :End of /WHOIS list", nick );
  • lib/misc.c

    rb5b40ff rae3dc99  
    7777       
    7878        return mktime(&tm);
     79}
     80
     81time_t mktime_utc( struct tm *tp )
     82{
     83        struct tm utc;
     84        time_t res, tres;
     85       
     86        tp->tm_isdst = -1;
     87        res = mktime( tp );
     88        /* Problem is, mktime() just gave us the GMT timestamp for the
     89           given local time... While the given time WAS NOT local. So
     90           we should fix this now.
     91           
     92           Now I could choose between messing with environment variables
     93           (kludgy) or using timegm() (not portable)... Or doing the
     94           following, which I actually prefer...
     95           
     96           tzset() may also work but in other places I actually want to
     97           use local time.
     98           
     99           FFFFFFFFFFFFFFFFFFFFFUUUUUUUUUUUUUUUUUUUU!! */
     100        gmtime_r( &res, &utc );
     101        utc.tm_isdst = -1;
     102        if( utc.tm_hour == tp->tm_hour && utc.tm_min == tp->tm_min )
     103                /* Sweet! We're in UTC right now... */
     104                return res;
     105       
     106        tres = mktime( &utc );
     107        res += res - tres;
     108       
     109        /* Yes, this is a hack. And it will go wrong around DST changes.
     110           BUT this is more likely to be threadsafe than messing with
     111           environment variables, and possibly more portable... */
     112       
     113        return res;
    79114}
    80115
  • lib/misc.h

    rb5b40ff rae3dc99  
    4343
    4444G_MODULE_EXPORT time_t get_time( int year, int month, int day, int hour, int min, int sec );
     45G_MODULE_EXPORT time_t mktime_utc( struct tm *tp );
    4546double gettime( void );
    4647
  • log.c

    rb5b40ff rae3dc99  
    172172                fprintf(stdout, "Debug: %s\n", message);
    173173#endif
     174        /* Always log stuff in syslogs too. */
     175        log_syslog(level, message);
    174176        return;
    175177}
  • 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 );
  • storage_xml.c

    rb5b40ff rae3dc99  
    496496                goto write_error;
    497497       
     498        fsync( fd );
    498499        close( fd );
    499500       
  • unix.c

    rb5b40ff rae3dc99  
    8383       
    8484                i = bitlbee_inetd_init();
    85                 log_message( LOGLVL_INFO, "Bitlbee %s starting in inetd mode.", BITLBEE_VERSION );
     85                log_message( LOGLVL_INFO, "BitlBee %s starting in inetd mode.", BITLBEE_VERSION );
    8686
    8787        }
    8888        else if( global.conf->runmode == RUNMODE_DAEMON )
    8989        {
    90                 log_link( LOGLVL_ERROR, LOGOUTPUT_SYSLOG );
    91                 log_link( LOGLVL_WARNING, LOGOUTPUT_SYSLOG );
     90                log_link( LOGLVL_ERROR, LOGOUTPUT_CONSOLE );
     91                log_link( LOGLVL_WARNING, LOGOUTPUT_CONSOLE );
    9292
    9393                i = bitlbee_daemon_init();
    94                 log_message( LOGLVL_INFO, "Bitlbee %s starting in daemon mode.", BITLBEE_VERSION );
     94                log_message( LOGLVL_INFO, "BitlBee %s starting in daemon mode.", BITLBEE_VERSION );
    9595        }
    9696        else if( global.conf->runmode == RUNMODE_FORKDAEMON )
    9797        {
     98                log_link( LOGLVL_ERROR, LOGOUTPUT_CONSOLE );
     99                log_link( LOGLVL_WARNING, LOGOUTPUT_CONSOLE );
     100
    98101                /* In case the operator requests a restart, we need this. */
    99102                old_cwd = g_malloc( 256 );
     
    106109               
    107110                i = bitlbee_daemon_init();
    108                 log_message( LOGLVL_INFO, "Bitlbee %s starting in forking daemon mode.", BITLBEE_VERSION );
     111                log_message( LOGLVL_INFO, "BitlBee %s starting in forking daemon mode.", BITLBEE_VERSION );
    109112        }
    110113        if( i != 0 )
Note: See TracChangeset for help on using the changeset viewer.