Changes in / [6a9d068:f924563]


Ignore:
Files:
2 added
20 edited

Legend:

Unmodified
Added
Removed
  • bitlbee.c

    r6a9d068 rf924563  
    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{
     
    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 #ifdef IPV6_V6ONLY             
    73                 if( res->ai_family == AF_INET6 )
    74                 {
    75                         i = 0;
    76                         setsockopt( global.listen_socket, IPPROTO_IPV6, IPV6_V6ONLY,
    77                                     (char *) &i, sizeof( i ) );
    78                 }
    79 #endif
    80 
    81                 /* TIME_WAIT (?) sucks.. */
    82                 i = 1;
    83                 setsockopt( global.listen_socket, SOL_SOCKET, SO_REUSEADDR, &i, sizeof( i ) );
    84 
    85                 i = bind( global.listen_socket, res->ai_addr, res->ai_addrlen );
    86                 if( i == -1 )
    87                 {
    88                         log_error( "bind" );
    89                         return( -1 );
    90                 }
    91                 break;
    92         }
    93 
     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       
    94114        freeaddrinfo( addrinfo_bind );
    95115
  • bitlbee.h

    r6a9d068 rf924563  
    3535
    3636#define PACKAGE "BitlBee"
    37 #define BITLBEE_VERSION "1.2.6"
     37#define BITLBEE_VERSION "1.2.6a"
    3838#define VERSION BITLBEE_VERSION
    3939#define BITLBEE_VER(a,b,c) (((a) << 16) + ((b) << 8) + (c))
  • debian/bitlbee.init

    r6a9d068 rf924563  
    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

    r6a9d068 rf924563  
     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

    r6a9d068 rf924563  
    9999                find usr -type f -exec md5sum {} \; > DEBIAN/md5sums
    100100
    101         dpkg-gencontrol -ldebian/changelog -isp -pbitlbee-dev -Pdebian/bitlbee-dev
     101        dpkg-gencontrol -ldebian/changelog -isp -pbitlbee-dev -Pdebian/bitlbee-dev -v1:$(BITLBEE_VERSION)-0
    102102
    103103        dpkg --build debian/bitlbee-dev ..
  • doc/CHANGES

    r6a9d068 rf924563  
    44http://bugs.bitlbee.org/bitlbee/timeline?daysback=90&changeset=on
    55
     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
    612Version 1.2.6:
    7 - Native (very basic) support for Twitter.
     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.
    816- Fixed format of status messages in /WHOIS to improve IRC client
    917  compatibility.
     
    1624  behaviour now is to write to wherever the last message came from, or to
    1725  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!)
    1829- The usual misc. bug fixes.
    1930
    20 Finished ...
     31Finished 19 Apr 2010
    2132
    2233Version 1.2.5:
  • doc/user-guide/commands.xml

    r6a9d068 rf924563  
    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>
     
    7373                                       
    7474                                        <para>
    75                                                 By default all your Twitter contacts will show up in your contact list and their tweets will show up as private messages or in &amp;bitlbee depending on your settings. If you want them in a separate channel, use the use_groupchat setting (see <emphasis>help set use_groupchat</emphasis>).
     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>).
    7676                                        </para>
    7777                                       
    7878                                        <para>
    79                                                 To send tweets yourself, send them to any of your Twitter contacts via /query (doesn't matter who), or just write in the groupchat channel if you enabled that option.
     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
     82                                        <para>
     83                                                Since Twitter now requires OAuth authentication, you should not enter your Twitter password into BitlBee. Just type a bogus password. The first time you log in, BitlBee will start OAuth authentication. (See <emphasis>help set oauth</emphasis>.)
    8084                                        </para>
    8185                                </description>
     
    659663        </bitlbee-setting>
    660664
     665        <bitlbee-setting name="mode" type="string" scope="account">
     666                <possible-values>one, many, chat</possible-values>
     667                <default>one</default>
     668
     669                <description>
     670                        <para>
     671                                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.
     672                        </para>
     673                       
     674                        <para>
     675                                If you prefer to have all your Twitter things in a separate channel, you can set this setting to "chat".
     676                        </para>
     677                       
     678                        <para>
     679                                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.
     680                        </para>
     681                </description>
     682
     683        </bitlbee-setting>
     684
    661685        <bitlbee-setting name="nick" type="string" scope="chat">
    662686
     
    683707        </bitlbee-setting>
    684708
     709        <bitlbee-setting name="oauth" type="boolean" scope="account">
     710                <default>true</default>
     711
     712                <description>
     713                        <para>
     714                                This enables OAuth authentication for Twitter accounts. From June 2010 this will be mandatory.
     715                        </para>
     716
     717                        <para>
     718                                With OAuth enabled, you shouldn't tell BitlBee your Twitter password. Just add your account with a bogus password and type <emphasis>account on</emphasis>. BitlBee will then give you a URL to authenticate with Twitter. If this succeeds, Twitter will return a PIN code which you can give back to BitlBee to finish the process.
     719                        </para>
     720
     721                        <para>
     722                                The resulting access token will be saved permanently, so you have to do this only once.
     723                        </para>
     724                </description>
     725
     726        </bitlbee-setting>
     727
    685728        <bitlbee-setting name="ops" type="string" scope="global">
    686729                <default>both</default>
     
    818861        </bitlbee-setting>
    819862
     863        <bitlbee-setting name="show_offline" type="boolean" scope="global">
     864                <default>false</default>
     865
     866                <description>
     867                        <para>
     868                                If enabled causes BitlBee to also show offline users in Channel. Online-users will get op, away-users voice and offline users none of both. This option takes effect as soon as you reconnect.
     869                        </para>
     870                </description>
     871        </bitlbee-setting>
     872
    820873        <bitlbee-setting name="simulate_netsplit" type="boolean" scope="global">
    821874                <default>true</default>
     
    863916                        <para>
    864917                                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.
     918                        </para>
     919                </description>
     920        </bitlbee-setting>
     921
     922        <bitlbee-setting name="switchboard_keepalives" type="boolean" scope="account">
     923                <default>false</default>
     924
     925                <description>
     926                        <para>
     927                                Turn on this flag if you have difficulties talking to offline/invisible contacts.
     928                        </para>
     929                       
     930                        <para>
     931                                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.
     932                        </para>
     933                       
     934                        <para>
     935                                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.
    865936                        </para>
    866937                </description>
     
    916987                        <para>
    917988                                Sends you a /notice when a user starts typing a message (if supported by the IM protocol and the user's client). To use this, you most likely want to use a script in your IRC client to show this information in a more sensible way.
    918                         </para>
    919                 </description>
    920         </bitlbee-setting>
    921 
    922         <bitlbee-setting name="use_groupchat" type="boolean" scope="account">
    923                 <default>false</default>
    924 
    925                 <description>
    926                         <para>
    927                                 By default the Twitter module shows all Twitter contacts and their Tweet in &amp;bitlbee and/or private messages. With this setting enabled the module will show all contacts and their Tweets in a separate channel.
    928989                        </para>
    929990                </description>
  • lib/Makefile

    r6a9d068 rf924563  
    1010
    1111# [SH] Program variables
    12 objects = arc.o base64.o $(EVENT_HANDLER) http_client.o ini.o md5.o misc.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o ftutil.o
     12objects = arc.o base64.o $(EVENT_HANDLER) ftutil.o http_client.o ini.o md5.o misc.o oauth.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o
    1313
    1414CFLAGS += -Wall
  • lib/misc.c

    r6a9d068 rf924563  
    306306        for( i = j = 0; t[i]; i ++, j ++ )
    307307        {
    308                 /* if( t[i] <= ' ' || ((unsigned char *)t)[i] >= 128 || t[i] == '%' ) */
    309                 if( !isalnum( t[i] ) )
     308                if( !isalnum( t[i] ) && !strchr( "._-~", t[i] ) )
    310309                {
    311310                        sprintf( s + j, "%%%02X", ((unsigned char*)t)[i] );
  • lib/url.c

    r6a9d068 rf924563  
    2727
    2828/* Convert an URL to a url_t structure */
    29 int url_set( url_t *url, char *set_url )
     29int url_set( url_t *url, const char *set_url )
    3030{
    3131        char s[MAX_STRING+1];
  • lib/url.h

    r6a9d068 rf924563  
    4242} url_t;
    4343
    44 int url_set( url_t *url, char *set_url );
     44int url_set( url_t *url, const char *set_url );
  • protocols/msn/msn.c

    r6a9d068 rf924563  
    3838        set_add( &acc->set, "local_display_name", "false", set_eval_bool, acc );
    3939        set_add( &acc->set, "mail_notifications", "false", set_eval_bool, acc );
     40        set_add( &acc->set, "switchboard_keepalives", "false", set_eval_bool, acc );
    4041}
    4142
  • protocols/msn/msn.h

    r6a9d068 rf924563  
    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;
     
    181187gboolean msn_sb_connected( gpointer data, gint source, b_input_condition cond );
    182188int 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 );
    183191
    184192/* invitation.c */
  • protocols/msn/ns.c

    r6a9d068 rf924563  
    422422        else if( strcmp( cmd[0], "FLN" ) == 0 )
    423423        {
    424                 if( cmd[1] )
    425                         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 );
    426430        }
    427431        else if( strcmp( cmd[0], "NLN" ) == 0 )
     
    449453                                   ( st != msn_away_state_list ? OPT_AWAY : 0 ),
    450454                                   st->name, NULL );
     455               
     456                msn_sb_stop_keepalives( msn_sb_by_handle( ic, cmd[2] ) );
    451457        }
    452458        else if( strcmp( cmd[0], "RNG" ) == 0 )
  • protocols/msn/sb.c

    r6a9d068 rf924563  
    175175                        i = g_snprintf( buf, i, MSN_TYPING_HEADERS, sb->ic->acc->user );
    176176                }
     177                else if( strcmp( text, SB_KEEPALIVE_MESSAGE ) == 0 )
     178                {
     179                        buf = g_strdup( SB_KEEPALIVE_HEADERS );
     180                        i = strlen( buf );
     181                }
    177182                else if( strncmp( text, MSN_INVITE_HEADERS, sizeof( MSN_INVITE_HEADERS ) - 1 ) == 0 )
    178183                {
     
    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 );
     
    752764        return( 1 );
    753765}
     766
     767static gboolean msn_sb_keepalive( gpointer data, gint source, b_input_condition cond )
     768{
     769        struct msn_switchboard *sb = data;
     770        return sb->ready && msn_sb_sendmessage( sb, SB_KEEPALIVE_MESSAGE );
     771}
     772
     773void msn_sb_start_keepalives( struct msn_switchboard *sb, gboolean initial )
     774{
     775        bee_user_t *bu;
     776       
     777        if( sb && sb->who && sb->keepalive == 0 &&
     778            ( bu = bee_user_by_handle( sb->ic->bee, sb->ic, sb->who ) ) &&
     779            !( bu->flags & BEE_USER_ONLINE ) &&
     780            set_getbool( &sb->ic->acc->set, "switchboard_keepalives" ) )
     781        {
     782                if( initial )
     783                        msn_sb_keepalive( sb, 0, 0 );
     784               
     785                sb->keepalive = b_timeout_add( 20000, msn_sb_keepalive, sb );
     786        }
     787}
     788
     789void msn_sb_stop_keepalives( struct msn_switchboard *sb )
     790{
     791        if( sb && sb->keepalive > 0 )
     792        {
     793                b_event_remove( sb->keepalive );
     794                sb->keepalive = 0;
     795        }
     796}
  • protocols/twitter/twitter.c

    r6a9d068 rf924563  
    2323
    2424#include "nogaim.h"
     25#include "oauth.h"
    2526#include "twitter.h"
    2627#include "twitter_http.h"
    2728#include "twitter_lib.h"
    2829
    29 
    3030/**
    3131 * Main loop function
     
    4141        // If the user uses multiple private message windows we need to get the
    4242        // users buddies.
    43         if (!set_getbool( &ic->acc->set, "use_groupchat" ))
     43        if (g_strcasecmp(set_getstr(&ic->acc->set, "mode"), "many") == 0)
    4444                twitter_get_statuses_friends(ic, -1);
    4545
     
    5151}
    5252
    53 
    54 static void twitter_init( account_t *acc )
    55 {
    56         set_t *s;
    57         s = set_add( &acc->set, "use_groupchat", "false", set_eval_bool, acc );
    58         s->flags |= ACC_SET_OFFLINE_ONLY;
    59 }
    60 
    61 /**
    62  * Login method. Since the twitter API works with seperate HTTP request we
    63  * only save the user and pass to the twitter_data object.
    64  */
    65 static void twitter_login( account_t *acc )
    66 {
    67         struct im_connection *ic = imcb_new( acc );
    68         struct twitter_data *td = g_new0( struct twitter_data, 1 );
    69 
    70         twitter_connections = g_slist_append( twitter_connections, ic );
    71 
    72         td->user = acc->user;
    73         td->pass = acc->pass;
    74         td->home_timeline_id = 0;
    75 
    76         ic->proto_data = td;
    77 
     53static void twitter_main_loop_start( struct im_connection *ic )
     54{
     55        struct twitter_data *td = ic->proto_data;
     56       
    7857        imcb_log( ic, "Connecting to Twitter" );
    7958
     
    8665}
    8766
     67
     68static const struct oauth_service twitter_oauth =
     69{
     70        "http://api.twitter.com/oauth/request_token",
     71        "http://api.twitter.com/oauth/access_token",
     72        "http://api.twitter.com/oauth/authorize",
     73        .consumer_key = "xsDNKJuNZYkZyMcu914uEA",
     74        .consumer_secret = "FCxqcr0pXKzsF9ajmP57S3VQ8V6Drk4o2QYtqMcOszo",
     75};
     76
     77static gboolean twitter_oauth_callback( struct oauth_info *info );
     78
     79static void twitter_oauth_start( struct im_connection *ic )
     80{
     81        struct twitter_data *td = ic->proto_data;
     82       
     83        imcb_log( ic, "Requesting OAuth request token" );
     84
     85        td->oauth_info = oauth_request_token( &twitter_oauth, twitter_oauth_callback, ic );
     86}
     87
     88static gboolean twitter_oauth_callback( struct oauth_info *info )
     89{
     90        struct im_connection *ic = info->data;
     91        struct twitter_data *td;
     92       
     93        if( !g_slist_find( twitter_connections, ic ) )
     94                return FALSE;
     95       
     96        td = ic->proto_data;
     97        if( info->stage == OAUTH_REQUEST_TOKEN )
     98        {
     99                char name[strlen(ic->acc->user)+9], *msg;
     100               
     101                if( info->request_token == NULL )
     102                {
     103                        imcb_error( ic, "OAuth error: %s", info->http->status_string );
     104                        imc_logout( ic, TRUE );
     105                        return FALSE;
     106                }
     107               
     108                sprintf( name, "twitter_%s", ic->acc->user );
     109                msg = g_strdup_printf( "To finish OAuth authentication, please visit "
     110                                       "%s and respond with the resulting PIN code.",
     111                                       info->auth_url );
     112                imcb_buddy_msg( ic, name, msg, 0, 0 );
     113                g_free( msg );
     114        }
     115        else if( info->stage == OAUTH_ACCESS_TOKEN )
     116        {
     117                if( info->token == NULL || info->token_secret == NULL )
     118                {
     119                        imcb_error( ic, "OAuth error: %s", info->http->status_string );
     120                        imc_logout( ic, TRUE );
     121                        return FALSE;
     122                }
     123               
     124                /* IM mods didn't do this so far and it's ugly but I should
     125                   be able to get away with it... */
     126                g_free( ic->acc->pass );
     127                ic->acc->pass = oauth_to_string( info );
     128               
     129                twitter_main_loop_start( ic );
     130        }
     131       
     132        return TRUE;
     133}
     134
     135
     136static char *set_eval_mode( set_t *set, char *value )
     137{
     138        if( g_strcasecmp( value, "one" ) == 0 ||
     139            g_strcasecmp( value, "many" ) == 0 ||
     140            g_strcasecmp( value, "chat" ) == 0 )
     141                return value;
     142        else
     143                return NULL;
     144}
     145
     146static void twitter_init( account_t *acc )
     147{
     148        set_t *s;
     149       
     150        s = set_add( &acc->set, "mode", "one", set_eval_mode, acc );
     151        s->flags |= ACC_SET_OFFLINE_ONLY;
     152       
     153        s = set_add( &acc->set, "oauth", "true", set_eval_bool, acc );
     154}
     155
     156/**
     157 * Login method. Since the twitter API works with seperate HTTP request we
     158 * only save the user and pass to the twitter_data object.
     159 */
     160static void twitter_login( account_t *acc )
     161{
     162        struct im_connection *ic = imcb_new( acc );
     163        struct twitter_data *td = g_new0( struct twitter_data, 1 );
     164        char name[strlen(acc->user)+9];
     165
     166        twitter_connections = g_slist_append( twitter_connections, ic );
     167        ic->proto_data = td;
     168        ic->flags |= OPT_DOES_HTML;
     169       
     170        td->user = acc->user;
     171        if( !set_getbool( &acc->set, "oauth" ) )
     172                td->pass = g_strdup( acc->pass );
     173        else if( strstr( acc->pass, "oauth_token=" ) )
     174                td->oauth_info = oauth_from_string( acc->pass, &twitter_oauth );
     175        td->home_timeline_id = 0;
     176       
     177        sprintf( name, "twitter_%s", acc->user );
     178        imcb_add_buddy( ic, name, NULL );
     179        imcb_buddy_status( ic, name, OPT_LOGGED_IN, NULL, NULL );
     180       
     181        if( td->pass || td->oauth_info )
     182                twitter_main_loop_start( ic );
     183        else
     184                twitter_oauth_start( ic );
     185}
     186
    88187/**
    89188 * Logout method. Just free the twitter_data.
     
    104203        if( td )
    105204        {
     205                oauth_info_free( td->oauth_info );
     206                g_free( td->pass );
    106207                g_free( td );
    107208        }
     
    115216static int twitter_buddy_msg( struct im_connection *ic, char *who, char *message, int away )
    116217{
    117         // Let's just update the status.
    118 //      if ( g_strcasecmp(who, ic->acc->user) == 0 )
    119                 twitter_post_status(ic, message);
    120 //      else
    121 //              twitter_direct_messages_new(ic, who, message);
     218        struct twitter_data *td = ic->proto_data;
     219       
     220        if (g_strncasecmp(who, "twitter_", 8) == 0 &&
     221            g_strcasecmp(who + 8, ic->acc->user) == 0)
     222        {
     223                if( set_getbool( &ic->acc->set, "oauth" ) &&
     224                    td->oauth_info && td->oauth_info->token == NULL )
     225                {
     226                        if( !oauth_access_token( message, td->oauth_info ) )
     227                        {
     228                                imcb_error( ic, "OAuth error: %s", "Failed to send access token request" );
     229                                imc_logout( ic, TRUE );
     230                                return FALSE;
     231                        }
     232                }
     233                else
     234                        twitter_post_status(ic, message);
     235        }
     236        else
     237        {
     238                twitter_direct_messages_new(ic, who, message);
     239        }
    122240        return( 0 );
    123241}
  • protocols/twitter/twitter.h

    r6a9d068 rf924563  
    3737        char* user;
    3838        char* pass;
     39        struct oauth_info *oauth_info;
    3940        guint64 home_timeline_id;
    4041        gint main_loop_id;
  • protocols/twitter/twitter_http.c

    r6a9d068 rf924563  
    2929****************************************************************************/
    3030
    31 #include "twitter_http.h"
    3231#include "twitter.h"
    3332#include "bitlbee.h"
     
    3534#include "misc.h"
    3635#include "base64.h"
     36#include "oauth.h"
    3737#include <ctype.h>
    3838#include <errno.h>
     39
     40#include "twitter_http.h"
    3941
    4042
     
    4547 * This is actually pretty generic function... Perhaps it should move to the lib/http_client.c
    4648 */
    47 void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, char* user, char* pass, char** arguments, int arguments_len)
     49void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, char* user, char* pass, struct oauth_info* oi, char** arguments, int arguments_len)
    4850{
    4951        url_t *url = g_new0( url_t, 1 );
     
    110112
    111113        // If a pass and user are given we append them to the request.
    112         if (userpass_base64)
     114        if (oi)
     115        {
     116                char *full_header;
     117               
     118                full_header = oauth_http_header(oi, is_post ? "POST" : "GET",
     119                                                url_string, url_arguments);
     120               
     121                tmp = g_strdup_printf("%sAuthorization: %s\r\n", request, full_header);
     122                g_free(request);
     123                g_free(full_header);
     124                request = tmp;
     125        }
     126        else if (userpass_base64)
    113127        {
    114128                tmp = g_strdup_printf("%sAuthorization: Basic %s\r\n", request, userpass_base64);
  • protocols/twitter/twitter_http.h

    r6a9d068 rf924563  
    2828#include "http_client.h"
    2929
     30struct oauth_info;
     31
    3032void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post,
    31                                         char* user, char* pass, char** arguments, int arguments_len);
     33                   char* user, char* pass, struct oauth_info *oi, char** arguments, int arguments_len);
    3234
    3335#endif //_TWITTER_HTTP_H
  • protocols/twitter/twitter_lib.c

    r6a9d068 rf924563  
    105105        if (!bee_user_by_handle( ic->bee, ic, name ))
    106106        {
     107                char *mode = set_getstr(&ic->acc->set, "mode");
     108               
    107109                // The buddy is not in the list, add the buddy and set the status to logged in.
    108110                imcb_add_buddy( ic, name, NULL );
    109111                imcb_rename_buddy( ic, name, fullname );
    110                 if (set_getbool( &ic->acc->set, "use_groupchat" ))
     112                if (g_strcasecmp(mode, "chat") == 0)
    111113                        imcb_chat_add_buddy( td->home_timeline_gc, name );
    112                 else
     114                else if (g_strcasecmp(mode, "many") == 0)
    113115                        imcb_buddy_status( ic, name, OPT_LOGGED_IN, NULL, NULL );
    114116        }
     
    128130        args[0] = "cursor";
    129131        args[1] = g_strdup_printf ("%d", next_cursor);
    130         twitter_http(TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, td->user, td->pass, args, 2);
     132        twitter_http(TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, td->user, td->pass, td->oauth_info, args, 2);
    131133
    132134        g_free(args[1]);
     
    394396        }
    395397
    396         twitter_http(TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, td->user, td->pass, args, td->home_timeline_id ? 4 : 2);
     398        twitter_http(TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, td->user, td->pass, td->oauth_info, args, td->home_timeline_id ? 4 : 2);
    397399
    398400        g_free(args[1]);
     
    452454        GSList *l = NULL;
    453455        struct twitter_xml_status *status;
    454 
     456        char from[MAX_STRING];
     457        gboolean mode_one;
     458       
     459        mode_one = g_strcasecmp( set_getstr( &ic->acc->set, "mode" ), "one" ) == 0;
     460
     461        if( mode_one )
     462        {
     463                g_snprintf( from, sizeof( from ) - 1, "twitter_%s", ic->acc->user );
     464                from[MAX_STRING-1] = '\0';
     465        }
     466       
    455467        for ( l = list; l ; l = g_slist_next(l) )
    456468        {
     469                char *text = NULL;
     470               
    457471                status = l->data;
    458                 imcb_buddy_msg( ic, status->user->screen_name, status->text, 0, status->created_at );
     472               
     473                if( mode_one )
     474                        text = g_strdup_printf( "\002<\002%s\002>\002 %s",
     475                                                status->user->screen_name, status->text );
     476                else
     477                        twitter_add_buddy(ic, status->user->screen_name, status->user->name);
     478               
     479                imcb_buddy_msg( ic,
     480                                mode_one ? from : status->user->screen_name,
     481                                mode_one ? text : status->text,
     482                                0, status->created_at );
     483               
    459484                // Update the home_timeline_id to hold the highest id, so that by the next request
    460485                // we won't pick up the updates allready in the list.
    461486                td->home_timeline_id = td->home_timeline_id < status->id ? status->id : td->home_timeline_id;
     487               
     488                g_free( text );
    462489        }
    463490}
     
    483510        {
    484511                td->http_fails = 0;
    485                 if (!ic->flags & OPT_LOGGED_IN)
     512                if (!(ic->flags & OPT_LOGGED_IN))
    486513                        imcb_connected(ic);
    487514        }
     
    512539
    513540        // See if the user wants to see the messages in a groupchat window or as private messages.
    514         if (set_getbool( &ic->acc->set, "use_groupchat" ))
     541        if (g_strcasecmp(set_getstr(&ic->acc->set, "mode"), "chat") == 0)
    515542                twitter_groupchat(ic, txl->list);
    516543        else
     
    593620        args[1] = g_strdup_printf ("%d", next_cursor);
    594621
    595         twitter_http(TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, td->user, td->pass, args, 2);
     622        twitter_http(TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, td->user, td->pass, td->oauth_info, args, 2);
    596623
    597624        g_free(args[1]);
     
    612639        if (req->status_code != 200) {
    613640                // It didn't go well, output the error and return.
    614                 imcb_error(ic, "Could not post tweet... HTTP STATUS: %d", req->status_code);
     641                imcb_error(ic, "Could not post message... HTTP STATUS: %d", req->status_code);
    615642                return;
    616643        }
     
    627654        args[0] = "status";
    628655        args[1] = msg;
    629         twitter_http(TWITTER_STATUS_UPDATE_URL, twitter_http_post_status, ic, 1, td->user, td->pass, args, 2);
     656        twitter_http(TWITTER_STATUS_UPDATE_URL, twitter_http_post_status, ic, 1, td->user, td->pass, td->oauth_info, args, 2);
    630657//      g_free(args[1]);
    631658}
     
    645672        args[3] = msg;
    646673        // Use the same callback as for twitter_post_status, since it does basically the same.
    647         twitter_http(TWITTER_DIRECT_MESSAGES_NEW_URL, twitter_http_post_status, ic, 1, td->user, td->pass, args, 4);
     674        twitter_http(TWITTER_DIRECT_MESSAGES_NEW_URL, twitter_http_post_status, ic, 1, td->user, td->pass, td->oauth_info, args, 4);
    648675//      g_free(args[1]);
    649676//      g_free(args[3]);
Note: See TracChangeset for help on using the changeset viewer.