Changes in / [7d53efb:ba3233c]


Ignore:
Files:
23 edited

Legend:

Unmodified
Added
Removed
  • bitlbee.h

    r7d53efb rba3233c  
    3535
    3636#define PACKAGE "BitlBee"
    37 #define BITLBEE_VERSION "1.2.6a"
     37#define BITLBEE_VERSION "1.2.7"
    3838#define VERSION BITLBEE_VERSION
    3939#define BITLBEE_VER(a,b,c) (((a) << 16) + ((b) << 8) + (c))
    40 #define BITLBEE_VERSION_CODE BITLBEE_VER(1, 2, 6)
     40#define BITLBEE_VERSION_CODE BITLBEE_VER(1, 2, 7)
    4141
    4242#define MAX_STRING 511
  • debian/changelog

    r7d53efb rba3233c  
     1bitlbee (1.2.7-1) unstable; urgency=high
     2
     3  * New upstream version.
     4  * Fixes MSN Messenger login issues, so uploading at high priority.
     5
     6 -- Wilmer van der Gaast <wilmer@gaast.net>  Sat, 15 May 2010 16:15:57 +0100
     7
    18bitlbee (1.2.6a-1) unstable; urgency=low
    29
  • debian/control

    r7d53efb rba3233c  
    1515Description: An IRC to other chat networks gateway
    1616 This program can be used as an IRC server which forwards everything you
    17  say to people on other chat networks: Jabber, ICQ, AIM, MSN and Yahoo.
     17 say to people on other chat networks: Jabber, ICQ, AIM, MSN, Yahoo! and
     18 Twitter.
    1819
    1920Package: bitlbee-dev
     
    2223Description: An IRC to other chat networks gateway
    2324 This program can be used as an IRC server which forwards everything you
    24  say to people on other chat networks: Jabber, ICQ, AIM, MSN and Yahoo.
     25 say to people on other chat networks: Jabber, ICQ, AIM, MSN, Yahoo! and
     26 Twitter.
    2527 .
    2628 This package holds development stuff for compiling plug-ins.
  • debian/rules

    r7d53efb rba3233c  
    9999                find usr -type f -exec md5sum {} \; > DEBIAN/md5sums
    100100
     101ifdef BITLBEE_FORCE_VERSION
    101102        dpkg-gencontrol -ldebian/changelog -isp -pbitlbee-dev -Pdebian/bitlbee-dev -v1:$(BITLBEE_VERSION)-0
     103else
     104        dpkg-gencontrol -ldebian/changelog -isp -pbitlbee-dev -Pdebian/bitlbee-dev
     105endif
    102106
    103107        dpkg --build debian/bitlbee-dev ..
  • doc/CHANGES

    r7d53efb rba3233c  
    33
    44http://bugs.bitlbee.org/bitlbee/timeline?daysback=90&changeset=on
     5
     6Version 1.2.7:
     7- Fixed problems with MSN Messenger authentication. ("Could not parse
     8  Passport server response")
     9- Fixed broken typing notifications when talking to GTalk contacts.
     10- Fixed an issue with non-anonymous Jabber chatrooms polluting the nick
     11  namespace, sometimes generating odd warning messages.
     12- Restored ability to start groupchats on ICQ.
     13- Added show_offline setting that will also show offline contacts in the
     14  control channel.
     15- OAuth support for Twitter: This means the module will keep working after
     16  June (this also changes "via API" under your tweets into "via BitlBee").
     17
     18Finished 15 May 2010
    519
    620Version 1.2.6a:
  • doc/bitlbee.8

    r7d53efb rba3233c  
    3939networks and acts as a gateway. Users can connect to the server
    4040with any normal IRC client and see their 'buddy list' in
    41 &bitlbee. BitlBee's protocol support is based on the gaim
    42 protocol plugins. BitlBee currently supports Oscar (aim and icq),
    43 MSN, Jabber and Yahoo.
     41&bitlbee. It currently supports Oscar (AIM and ICQ),
     42MSN, Jabber, Yahoo! and Twitter.
    4443
    4544\fBbitlbee\fP should be called by
  • doc/user-guide/commands.xml

    r7d53efb rba3233c  
    620620
    621621        <bitlbee-setting name="ignore_auth_requests" type="boolean" scope="account">
    622                 <default>true</default>
     622                <default>false</default>
    623623
    624624                <description>
  • doc/user-guide/quickstart.xml

    r7d53efb rba3233c  
    33
    44<para>
    5 Welcome to BitlBee, your IRC gateway to ICQ, MSN, AOL, Jabber and Yahoo Instant Messaging Systems.
     5Welcome to BitlBee, your IRC gateway to ICQ, MSN, AOL, Jabber, Yahoo! and Twitter.
    66</para>
    77
     
    4343
    4444<para>
    45 Other available IM protocols are msn, oscar, and yahoo. OSCAR is the protocol used by ICQ and AOL. For more information about the <emphasis>account add</emphasis> command, see <emphasis>help account add</emphasis>.
     45Other available IM protocols are msn, oscar, yahoo and twitter. OSCAR is the protocol used by ICQ and AOL. For more information about the <emphasis>account add</emphasis> command, see <emphasis>help account add</emphasis>.
    4646</para>
    4747
  • irc_commands.c

    r7d53efb rba3233c  
    7373static void irc_cmd_nick( irc_t *irc, char **cmd )
    7474{
    75         if( irc->nick )
    76         {
    77                 irc_reply( irc, 438, ":The hand of the deity is upon thee, thy nick may not change" );
     75        if( irc->status & USTATUS_IDENTIFIED && irc->nick )
     76        {
     77                irc_reply( irc, 438, "%s %s :You can only change your nick if you're not "
     78                           "logged in (i.e. pre-identify)", irc->nick, cmd[1] );
    7879        }
    7980        /* This is not clean, but for now it'll have to be like this... */
    80         else if( ( nick_cmp( cmd[1], irc->mynick ) == 0 ) || ( nick_cmp( cmd[1], NS_NICK ) == 0 ) )
    81         {
    82                 irc_reply( irc, 433, ":This nick is already in use" );
     81        else if( ( nick_cmp( cmd[1], irc->mynick ) == 0 ) || ( nick_cmp( cmd[1], NS_NICK ) == 0 ) || ( user_find( irc, cmd[1] ) != NULL ) )
     82        {
     83                irc_reply( irc, 433, "%s :This nick is already in use", cmd[1] );
    8384        }
    8485        else if( !nick_ok( cmd[1] ) )
    8586        {
    8687                /* [SH] Invalid characters. */
    87                 irc_reply( irc, 432, ":This nick contains invalid characters" );
     88                irc_reply( irc, 432, "%s :This nick contains invalid characters", cmd[1] );
     89        }
     90        else if(irc->nick)
     91        {
     92                if( user_find( irc, irc->nick ) )
     93                        user_rename(irc, irc->nick, cmd[1]);
     94
     95                irc_write( irc, ":%s!%s@%s NICK %s", irc->nick, irc->user, irc->host, cmd[1] );
     96                g_free(irc->nick);
     97                irc->nick = g_strdup( cmd[1] );
    8898        }
    8999        else
  • lib/misc.c

    r7d53efb rba3233c  
    154154{
    155155        char *start = in;
    156         char *out = g_malloc( strlen( in ) + 1 );
     156        char out[strlen(in)+1];
    157157        char *s = out, *cs;
    158158        int i, matched;
    159159       
    160         memset( out, 0, strlen( in ) + 1 );
     160        memset( out, 0, sizeof( out ) );
    161161       
    162162        while( *in )
     
    220220       
    221221        strcpy( start, out );
    222         g_free( out );
    223222}
    224223
  • lib/xmltree.c

    r7d53efb rba3233c  
    449449        while( node )
    450450        {
    451                 if( g_strcasecmp( node->name, name ) == 0 )
     451                char *colon;
     452               
     453                if( g_strcasecmp( node->name, name ) == 0 ||
     454                    ( ( colon = strchr( node->name, ':' ) ) &&
     455                      g_strcasecmp( colon + 1, name ) == 0 ) )
    452456                        break;
    453457               
     
    461465{
    462466        int i;
     467        char *colon;
    463468       
    464469        if( !node )
     
    468473                if( g_strcasecmp( node->attr[i].key, key ) == 0 )
    469474                        break;
     475       
     476        /* This is an awful hack that only takes care of namespace prefixes
     477           inside a tag. Since IMHO excessive namespace usage in XMPP is
     478           massive overkill anyway (this code exists for almost four years
     479           now and never really missed it): Meh. */
     480        if( !node->attr[i].key && strcmp( key, "xmlns" ) == 0 &&
     481            ( colon = strchr( node->name, ':' ) ) )
     482        {
     483                *colon = '\0';
     484                for( i = 0; node->attr[i].key; i ++ )
     485                        if( strncmp( node->attr[i].key, "xmlns:", 6 ) == 0 &&
     486                            strcmp( node->attr[i].key + 6, node->name ) == 0 )
     487                                break;
     488                *colon = ':';
     489        }
    470490       
    471491        return node->attr[i].value;
  • protocols/jabber/conference.c

    r7d53efb rba3233c  
    272272                }
    273273               
    274                 if( bud != jc->me )
    275                 {
     274                if( bud != jc->me && bud->flags & JBFLAG_IS_ANONYMOUS )
     275                {
     276                        /* If JIDs are anonymized, add them to the local
     277                           list for the duration of this chat. */
    276278                        imcb_add_buddy( ic, bud->ext_jid, NULL );
    277279                        imcb_buddy_nick_hint( ic, bud->ext_jid, bud->resource );
  • protocols/jabber/iq.c

    r7d53efb rba3233c  
    127127                    !( s = xt_find_attr( c, "xmlns" ) ) )
    128128                {
    129                         imcb_log( ic, "Warning: Received incomplete IQ-%s packet", type );
    130129                        return XT_HANDLED;
    131130                }
  • protocols/msn/passport.c

    r7d53efb rba3233c  
    145145        char *s;
    146146       
    147         if( ( s = xt_find_attr( node, "Id" ) ) && strcmp( s, "PPToken1" ) == 0 )
     147        if( ( s = xt_find_attr( node, "Id" ) ) &&
     148            ( strncmp( s, "Compact", 7 ) == 0 ||
     149              strncmp( s, "PPToken", 7 ) == 0 ) )
    148150                mad->token = g_memdup( node->text, node->text_len + 1 );
    149151       
  • protocols/msn/sb.c

    r7d53efb rba3233c  
    328328        struct msn_data *md = ic->proto_data;
    329329       
    330         if( msn_handler( sb->handler ) == -1 )
     330        if( msn_handler( sb->handler ) != -1 )
     331                return TRUE;
     332       
     333        if( sb->msgq != NULL )
    331334        {
    332335                time_t now = time( NULL );
     336                char buf[1024];
    333337               
    334338                if( now - md->first_sb_failure > 600 )
     
    347351                                      "There might be problems delivering your messages." );
    348352               
    349                 if( sb->msgq != NULL )
    350                 {
    351                         char buf[1024];
    352                        
    353                         if( md->msgq == NULL )
    354                         {
    355                                 md->msgq = sb->msgq;
    356                         }
    357                         else
    358                         {
    359                                 GSList *l;
    360                                
    361                                 for( l = md->msgq; l->next; l = l->next );
    362                                 l->next = sb->msgq;
    363                         }
    364                         sb->msgq = NULL;
    365                        
    366                         debug( "Moved queued messages back to the main queue, creating a new switchboard to retry." );
    367                         g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId );
    368                         if( !msn_write( ic, buf, strlen( buf ) ) )
    369                                 return FALSE;
    370                 }
    371                
    372                 msn_sb_destroy( sb );
    373                
    374                 return FALSE;
    375         }
    376         else
    377         {
    378                 return TRUE;
    379         }
     353                if( md->msgq == NULL )
     354                {
     355                        md->msgq = sb->msgq;
     356                }
     357                else
     358                {
     359                        GSList *l;
     360                       
     361                        for( l = md->msgq; l->next; l = l->next );
     362                        l->next = sb->msgq;
     363                }
     364                sb->msgq = NULL;
     365               
     366                debug( "Moved queued messages back to the main queue, "
     367                       "creating a new switchboard to retry." );
     368                g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId );
     369                if( !msn_write( ic, buf, strlen( buf ) ) )
     370                        return FALSE;
     371        }
     372       
     373        msn_sb_destroy( sb );
     374        return FALSE;
    380375}
    381376
  • protocols/oscar/oscar.c

    r7d53efb rba3233c  
    205205static int gaim_icbm_param_info  (aim_session_t *, aim_frame_t *, ...);
    206206static int gaim_parse_genericerr (aim_session_t *, aim_frame_t *, ...);
    207 static int gaim_memrequest       (aim_session_t *, aim_frame_t *, ...);
    208207static int gaim_selfinfo         (aim_session_t *, aim_frame_t *, ...);
    209208static int gaim_offlinemsg       (aim_session_t *, aim_frame_t *, ...);
     
    570569        aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_ERROR, gaim_parse_genericerr, 0);
    571570        aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BOS, AIM_CB_BOS_ERROR, gaim_parse_genericerr, 0);
    572         aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, 0x1f, gaim_memrequest, 0);
    573571        aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_SELFINFO, gaim_selfinfo, 0);
    574572        aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSG, gaim_offlinemsg, 0);
     
    604602}
    605603
    606 struct pieceofcrap {
    607         struct im_connection *ic;
    608         unsigned long offset;
    609         unsigned long len;
    610         char *modname;
    611         int fd;
    612         aim_conn_t *conn;
    613         unsigned int inpa;
    614 };
    615 
    616 static gboolean damn_you(gpointer data, gint source, b_input_condition c)
    617 {
    618         struct pieceofcrap *pos = data;
    619         struct oscar_data *od = pos->ic->proto_data;
    620         char in = '\0';
    621         int x = 0;
    622         unsigned char m[17];
    623 
    624         while (read(pos->fd, &in, 1) == 1) {
    625                 if (in == '\n')
    626                         x++;
    627                 else if (in != '\r')
    628                         x = 0;
    629                 if (x == 2)
    630                         break;
    631                 in = '\0';
    632         }
    633         if (in != '\n') {
    634                 imcb_error(pos->ic, "Gaim was unable to get a valid hash for logging into AIM."
    635                                 " You may be disconnected shortly.");
    636                 b_event_remove(pos->inpa);
    637                 closesocket(pos->fd);
    638                 g_free(pos);
    639                 return FALSE;
    640         }
    641         /* [WvG] Wheeeee! Who needs error checking anyway? ;-) */
    642         read(pos->fd, m, 16);
    643         m[16] = '\0';
    644         b_event_remove(pos->inpa);
    645         closesocket(pos->fd);
    646         aim_sendmemblock(od->sess, pos->conn, 0, 16, m, AIM_SENDMEMBLOCK_FLAG_ISHASH);
    647         g_free(pos);
    648        
    649         return FALSE;
    650 }
    651 
    652 static gboolean straight_to_hell(gpointer data, gint source, b_input_condition cond) {
    653         struct pieceofcrap *pos = data;
    654         char buf[BUF_LONG];
    655 
    656         if (source < 0) {
    657                 imcb_error(pos->ic, "Gaim was unable to get a valid hash for logging into AIM."
    658                                 " You may be disconnected shortly.");
    659                 if (pos->modname)
    660                         g_free(pos->modname);
    661                 g_free(pos);
    662                 return FALSE;
    663         }
    664 
    665         g_snprintf(buf, sizeof(buf), "GET " AIMHASHDATA
    666                         "?offset=%ld&len=%ld&modname=%s HTTP/1.0\n\n",
    667                         pos->offset, pos->len, pos->modname ? pos->modname : "");
    668         write(pos->fd, buf, strlen(buf));
    669         if (pos->modname)
    670                 g_free(pos->modname);
    671         pos->inpa = b_input_add(pos->fd, GAIM_INPUT_READ, damn_you, pos);
    672         return FALSE;
    673 }
    674 
    675604/* size of icbmui.ocm, the largest module in AIM 3.5 */
    676605#define AIM_MAX_FILE_SIZE 98304
    677 
    678 int gaim_memrequest(aim_session_t *sess, aim_frame_t *fr, ...) {
    679         va_list ap;
    680         struct pieceofcrap *pos;
    681         guint32 offset, len;
    682         char *modname;
    683         int fd;
    684 
    685         va_start(ap, fr);
    686         offset = (guint32)va_arg(ap, unsigned long);
    687         len = (guint32)va_arg(ap, unsigned long);
    688         modname = va_arg(ap, char *);
    689         va_end(ap);
    690 
    691         if (len == 0) {
    692                 aim_sendmemblock(sess, fr->conn, offset, len, NULL,
    693                                 AIM_SENDMEMBLOCK_FLAG_ISREQUEST);
    694                 return 1;
    695         }
    696         /* uncomment this when you're convinced it's right. remember, it's been wrong before.
    697         if (offset > AIM_MAX_FILE_SIZE || len > AIM_MAX_FILE_SIZE) {
    698                 char *buf;
    699                 int i = 8;
    700                 if (modname)
    701                         i += strlen(modname);
    702                 buf = g_malloc(i);
    703                 i = 0;
    704                 if (modname) {
    705                         memcpy(buf, modname, strlen(modname));
    706                         i += strlen(modname);
    707                 }
    708                 buf[i++] = offset & 0xff;
    709                 buf[i++] = (offset >> 8) & 0xff;
    710                 buf[i++] = (offset >> 16) & 0xff;
    711                 buf[i++] = (offset >> 24) & 0xff;
    712                 buf[i++] = len & 0xff;
    713                 buf[i++] = (len >> 8) & 0xff;
    714                 buf[i++] = (len >> 16) & 0xff;
    715                 buf[i++] = (len >> 24) & 0xff;
    716                 aim_sendmemblock(sess, command->conn, offset, i, buf, AIM_SENDMEMBLOCK_FLAG_ISREQUEST);
    717                 g_free(buf);
    718                 return 1;
    719         }
    720         */
    721 
    722         pos = g_new0(struct pieceofcrap, 1);
    723         pos->ic = sess->aux_data;
    724         pos->conn = fr->conn;
    725 
    726         pos->offset = offset;
    727         pos->len = len;
    728         pos->modname = modname ? g_strdup(modname) : NULL;
    729 
    730         fd = proxy_connect("gaim.sourceforge.net", 80, straight_to_hell, pos);
    731         if (fd < 0) {
    732                 if (pos->modname)
    733                         g_free(pos->modname);
    734                 g_free(pos);
    735                 imcb_error(sess->aux_data, "Gaim was unable to get a valid hash for logging into AIM."
    736                                 " You may be disconnected shortly.");
    737         }
    738         pos->fd = fd;
    739 
    740         return 1;
    741 }
    742606
    743607static int gaim_parse_login(aim_session_t *sess, aim_frame_t *fr, ...) {
     
    11661030                m = g_list_append(m, exch);
    11671031
    1168                 g_snprintf( txt, 1024, "Got an invitation to chatroom %s from %s: %s", name, userinfo->sn, args->msg );
     1032                g_snprintf(txt, 1024, "Got an invitation to chatroom %s from %s: %s", name, userinfo->sn, args->msg);
    11691033
    11701034                inv->ic = ic;
     
    11721036                inv->name = g_strdup(name);
    11731037               
    1174                 imcb_ask( ic, txt, inv, oscar_accept_chat, oscar_reject_chat);
     1038                imcb_ask(ic, txt, inv, oscar_accept_chat, oscar_reject_chat);
    11751039       
    11761040                if (name)
    11771041                        g_free(name);
     1042        } else if (args->reqclass & AIM_CAPS_ICQRTF) {
     1043                // TODO: constify
     1044                char text[strlen(args->info.rtfmsg.rtfmsg)+1];
     1045                strncpy(text, args->info.rtfmsg.rtfmsg, sizeof(text));
     1046                imcb_buddy_msg(ic, normalize(userinfo->sn), text, 0, 0);
    11781047        }
    11791048
     
    26512520        char * chatname;
    26522521       
    2653         chatname = g_strdup_printf("%s%d", ic->acc->user, chat_id++);
     2522        chatname = g_strdup_printf("%s%s_%d", isdigit(*ic->acc->user) ? "icq_" : "",
     2523                                   ic->acc->user, chat_id++);
    26542524 
    26552525        ret = oscar_chat_join(ic, chatname, NULL, NULL);
  • protocols/twitter/twitter.c

    r7d53efb rba3233c  
    2727#include "twitter_http.h"
    2828#include "twitter_lib.h"
     29#include "url.h"
    2930
    3031/**
     
    7071        "http://api.twitter.com/oauth/request_token",
    7172        "http://api.twitter.com/oauth/access_token",
    72         "http://api.twitter.com/oauth/authorize",
     73        "https://api.twitter.com/oauth/authorize",
    7374        .consumer_key = "xsDNKJuNZYkZyMcu914uEA",
    7475        .consumer_secret = "FCxqcr0pXKzsF9ajmP57S3VQ8V6Drk4o2QYtqMcOszo",
     
    160161        set_t *s;
    161162       
     163        s = set_add( &acc->set, "base_url", TWITTER_API_URL, NULL, acc );
     164        s->flags |= ACC_SET_OFFLINE_ONLY;
     165       
    162166        s = set_add( &acc->set, "message_length", "140", set_eval_int, acc );
    163167       
     
    175179{
    176180        struct im_connection *ic = imcb_new( acc );
    177         struct twitter_data *td = g_new0( struct twitter_data, 1 );
     181        struct twitter_data *td;
    178182        char name[strlen(acc->user)+9];
    179 
     183        url_t url;
     184
     185        if( !url_set( &url, set_getstr( &ic->acc->set, "base_url" ) ) ||
     186            ( url.proto != PROTO_HTTP && url.proto != PROTO_HTTPS ) )
     187        {
     188                imcb_error( ic, "Incorrect API base URL: %s", set_getstr( &ic->acc->set, "base_url" ) );
     189                imc_logout( ic, FALSE );
     190                return;
     191        }
     192       
    180193        twitter_connections = g_slist_append( twitter_connections, ic );
     194        td = g_new0( struct twitter_data, 1 );
    181195        ic->proto_data = td;
    182         ic->flags |= OPT_DOES_HTML;
     196       
     197        td->url_ssl = url.proto == PROTO_HTTPS;
     198        td->url_port = url.port;
     199        td->url_host = g_strdup( url.host );
     200        if( strcmp( url.file, "/" ) != 0 )
     201                td->url_path = g_strdup( url.file );
     202        else
     203                td->url_path = g_strdup( "" );
    183204       
    184205        td->user = acc->user;
    185         if( !set_getbool( &acc->set, "oauth" ) )
    186                 td->pass = g_strdup( acc->pass );
    187         else if( strstr( acc->pass, "oauth_token=" ) )
     206        if( strstr( acc->pass, "oauth_token=" ) )
    188207                td->oauth_info = oauth_from_string( acc->pass, &twitter_oauth );
    189         td->home_timeline_id = 0;
    190208       
    191209        sprintf( name, "twitter_%s", acc->user );
     
    193211        imcb_buddy_status( ic, name, OPT_LOGGED_IN, NULL, NULL );
    194212       
    195         if( td->pass || td->oauth_info )
     213        if( td->oauth_info || !set_getbool( &acc->set, "oauth" ) )
    196214                twitter_main_loop_start( ic );
    197215        else
  • protocols/twitter/twitter.h

    r7d53efb rba3233c  
    4242        struct groupchat *home_timeline_gc;
    4343        gint http_fails;
     44       
     45        gboolean url_ssl;
     46        int url_port;
     47        char *url_host;
     48        char *url_path;
    4449};
    4550
  • protocols/twitter/twitter_http.c

    r7d53efb rba3233c  
    4141
    4242
    43 char *twitter_url_append(char *url, char *key, char* value);
     43static char *twitter_url_append(char *url, char *key, char* value);
    4444
    4545/**
     
    4747 * This is actually pretty generic function... Perhaps it should move to the lib/http_client.c
    4848 */
    49 void *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)
     49void *twitter_http(struct im_connection *ic, char *url_string, http_input_function func, gpointer data, int is_post, char** arguments, int arguments_len)
    5050{
    51         url_t *url = g_new0( url_t, 1 );
     51        struct twitter_data *td = ic->proto_data;
    5252        char *tmp;
    53         char *request;
     53        GString *request = g_string_new("");
    5454        void *ret;
    55         char *userpass = NULL;
    56         char *userpass_base64;
    5755        char *url_arguments;
    5856
    59         // Fill the url structure.
    60         if( !url_set( url, url_string ) )
    61         {
    62                 g_free( url );
    63                 return NULL;
    64         }
    65 
    66         if( url->proto != PROTO_HTTP && url->proto != PROTO_HTTPS )
    67         {
    68                 g_free( url );
    69                 return NULL;
    70         }
    71 
    72         // Concatenate user and pass
    73         if (user && pass) {
    74                 userpass = g_strdup_printf("%s:%s", user, pass);
    75                 userpass_base64 = base64_encode((unsigned char*)userpass, strlen(userpass));
    76         } else {
    77                 userpass_base64 = NULL;
    78         }
    79 
    80         url_arguments = g_malloc(1);
    81         url_arguments[0] = '\0';
     57        url_arguments = g_strdup("");
    8258
    8359        // Construct the url arguments.
     
    9369        }
    9470
    95         // Do GET stuff...
    96         if (!is_post)
    97         {
    98                 // Find the char-pointer of the end of the string.
    99                 tmp = url->file + strlen(url->file);
    100                 tmp[0] = '?';
    101                 // append the url_arguments to the end of the url->file.
    102                 // TODO GM: Check the length?
    103                 g_stpcpy (tmp+1, url_arguments);
    104         }
    105 
    106 
    10771        // Make the request.
    108         request = g_strdup_printf(  "%s %s HTTP/1.0\r\n"
    109                                     "Host: %s\r\n"
    110                                     "User-Agent: BitlBee " BITLBEE_VERSION " " ARCH "/" CPU "\r\n",
    111                                     is_post ? "POST" : "GET", url->file, url->host );
     72        g_string_printf(request, "%s %s%s%s%s HTTP/1.0\r\n"
     73                                 "Host: %s\r\n"
     74                                 "User-Agent: BitlBee " BITLBEE_VERSION " " ARCH "/" CPU "\r\n",
     75                                 is_post ? "POST" : "GET",
     76                                 td->url_path, url_string,
     77                                 is_post ? "" : "?", is_post ? "" : url_arguments,
     78                                 td->url_host);
    11279
    11380        // If a pass and user are given we append them to the request.
    114         if (oi)
     81        if (td->oauth_info)
    11582        {
    11683                char *full_header;
     84                char *full_url;
    11785               
    118                 full_header = oauth_http_header(oi, is_post ? "POST" : "GET",
    119                                                 url_string, url_arguments);
     86                full_url = g_strconcat(set_getstr(&ic->acc->set, "base_url" ), url_string, NULL);
     87                full_header = oauth_http_header(td->oauth_info, is_post ? "POST" : "GET",
     88                                                full_url, url_arguments);
    12089               
    121                 tmp = g_strdup_printf("%sAuthorization: %s\r\n", request, full_header);
    122                 g_free(request);
     90                g_string_append_printf(request, "Authorization: %s\r\n", full_header);
    12391                g_free(full_header);
    124                 request = tmp;
     92                g_free(full_url);
    12593        }
    126         else if (userpass_base64)
     94        else
    12795        {
    128                 tmp = g_strdup_printf("%sAuthorization: Basic %s\r\n", request, userpass_base64);
    129                 g_free(request);
    130                 request = tmp;
     96                char userpass[strlen(ic->acc->user)+2+strlen(ic->acc->pass)];
     97                char *userpass_base64;
     98               
     99                g_snprintf(userpass, sizeof(userpass), "%s:%s", ic->acc->user, ic->acc->pass);
     100                userpass_base64 = base64_encode((unsigned char*)userpass, strlen(userpass));
     101                g_string_append_printf(request, "Authorization: Basic %s\r\n", userpass_base64);
     102                g_free( userpass_base64 );
    131103        }
    132104
     
    135107        {
    136108                // Append the Content-Type and url-encoded arguments.
    137                 tmp = g_strdup_printf("%sContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %zd\r\n\r\n%s",
    138                                                                 request, strlen(url_arguments), url_arguments);
    139                 g_free(request);
    140                 request = tmp;
     109                g_string_append_printf(request,
     110                                       "Content-Type: application/x-www-form-urlencoded\r\n"
     111                                       "Content-Length: %zd\r\n\r\n%s",
     112                                       strlen(url_arguments), url_arguments);
    141113        } else {
    142114                // Append an extra \r\n to end the request...
    143                 tmp = g_strdup_printf("%s\r\n", request);
    144                 g_free(request);
    145                 request = tmp;
     115                g_string_append(request, "\r\n");
    146116        }
    147117
    148         ret = http_dorequest( url->host, url->port,     url->proto == PROTO_HTTPS, request, func, data );
     118        ret = http_dorequest(td->url_host, td->url_port, td->url_ssl, request->str, func, data);
    149119
    150         g_free( url );
    151         g_free( userpass );
    152         g_free( userpass_base64 );
    153120        g_free( url_arguments );
    154         g_free( request );
     121        g_string_free( request, TRUE );
    155122        return ret;
    156123}
    157124
    158 char *twitter_url_append(char *url, char *key, char* value)
     125static char *twitter_url_append(char *url, char *key, char* value)
    159126{
    160127        char *key_encoded = g_strndup(key, 3 * strlen(key));
  • protocols/twitter/twitter_http.h

    r7d53efb rba3233c  
    3030struct oauth_info;
    3131
    32 void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post,
    33                    char* user, char* pass, struct oauth_info *oi, char** arguments, int arguments_len);
     32void *twitter_http(struct im_connection *ic, char *url_string, http_input_function func,
     33                   gpointer data, int is_post, char** arguments, int arguments_len);
    3434
    3535#endif //_TWITTER_HTTP_H
  • protocols/twitter/twitter_lib.c

    r7d53efb rba3233c  
    117117}
    118118
     119/* Warning: May return a malloc()ed value, which will be free()d on the next
     120   call. Only for short-term use. */
     121static char *twitter_parse_error(struct http_request *req)
     122{
     123        static char *ret = NULL;
     124        struct xt_parser *xp = NULL;
     125        struct xt_node *node;
     126       
     127        g_free(ret);
     128        ret = NULL;
     129       
     130        if (req->body_size > 0)
     131        {
     132                xp = xt_new(NULL, NULL);
     133                xt_feed(xp, req->reply_body, req->body_size);
     134               
     135                if ((node = xt_find_node(xp->root, "hash")) &&
     136                    (node = xt_find_node(node->children, "error")) &&
     137                    node->text_len > 0)
     138                {
     139                        ret = g_strdup_printf("%s (%s)", req->status_string, node->text);
     140                        xt_free(xp);
     141                        return ret;
     142                }
     143               
     144                xt_free(xp);
     145        }
     146       
     147        return req->status_string;
     148}
     149
    119150static void twitter_http_get_friends_ids(struct http_request *req);
    120151
     
    124155void twitter_get_friends_ids(struct im_connection *ic, int next_cursor)
    125156{
    126         struct twitter_data *td = ic->proto_data;
    127 
    128157        // Primitive, but hey! It works...     
    129158        char* args[2];
    130159        args[0] = "cursor";
    131160        args[1] = g_strdup_printf ("%d", next_cursor);
    132         twitter_http(TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, td->user, td->pass, td->oauth_info, args, 2);
     161        twitter_http(ic, TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, args, 2);
    133162
    134163        g_free(args[1]);
     
    196225                // It didn't go well, output the error and return.
    197226                if (++td->http_fails >= 5)
    198                         imcb_error(ic, "Could not retrieve friends. HTTP STATUS: %d", req->status_code);
     227                        imcb_error(ic, "Could not retrieve friends: %s", twitter_parse_error(req));
    199228               
    200229                return;
     
    396425        }
    397426
    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);
     427        twitter_http(ic, TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, args, td->home_timeline_id ? 4 : 2);
    399428
    400429        g_free(args[1]);
     
    434463                twitter_add_buddy(ic, status->user->screen_name, status->user->name);
    435464               
     465                strip_html(status->text);
     466               
    436467                // Say it!
    437468                if (g_strcasecmp(td->user, status->user->screen_name) == 0)
     
    471502                status = l->data;
    472503               
     504                strip_html( status->text );
    473505                if( mode_one )
    474506                        text = g_strdup_printf( "\002<\002%s\002>\002 %s",
     
    523555                // It didn't go well, output the error and return.
    524556                if (++td->http_fails >= 5)
    525                         imcb_error(ic, "Could not retrieve " TWITTER_HOME_TIMELINE_URL ". HTTP STATUS: %d", req->status_code);
     557                        imcb_error(ic, "Could not retrieve " TWITTER_HOME_TIMELINE_URL ": %s", twitter_parse_error(req));
    526558               
    527559                return;
     
    575607                // It didn't go well, output the error and return.
    576608                if (++td->http_fails >= 5)
    577                         imcb_error(ic, "Could not retrieve " TWITTER_SHOW_FRIENDS_URL " HTTP STATUS: %d", req->status_code);
     609                        imcb_error(ic, "Could not retrieve " TWITTER_SHOW_FRIENDS_URL ": %s", twitter_parse_error(req));
    578610               
    579611                return;
     
    614646void twitter_get_statuses_friends(struct im_connection *ic, int next_cursor)
    615647{
    616         struct twitter_data *td = ic->proto_data;
    617 
    618648        char* args[2];
    619649        args[0] = "cursor";
    620650        args[1] = g_strdup_printf ("%d", next_cursor);
    621651
    622         twitter_http(TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, td->user, td->pass, td->oauth_info, args, 2);
     652        twitter_http(ic, TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, args, 2);
    623653
    624654        g_free(args[1]);
     
    639669        if (req->status_code != 200) {
    640670                // It didn't go well, output the error and return.
    641                 imcb_error(ic, "HTTP Error... STATUS: %d", req->status_code);
     671                imcb_error(ic, "HTTP error: %s", twitter_parse_error(req));
    642672                return;
    643673        }
     
    649679void twitter_post_status(struct im_connection *ic, char* msg)
    650680{
    651         struct twitter_data *td = ic->proto_data;
    652 
    653681        char* args[2];
    654682        args[0] = "status";
    655683        args[1] = msg;
    656         twitter_http(TWITTER_STATUS_UPDATE_URL, twitter_http_post, ic, 1, td->user, td->pass, td->oauth_info, args, 2);
     684        twitter_http(ic, TWITTER_STATUS_UPDATE_URL, twitter_http_post, ic, 1, args, 2);
    657685//      g_free(args[1]);
    658686}
     
    664692void twitter_direct_messages_new(struct im_connection *ic, char *who, char *msg)
    665693{
    666         struct twitter_data *td = ic->proto_data;
    667 
    668694        char* args[4];
    669695        args[0] = "screen_name";
     
    672698        args[3] = msg;
    673699        // Use the same callback as for twitter_post_status, since it does basically the same.
    674         twitter_http(TWITTER_DIRECT_MESSAGES_NEW_URL, twitter_http_post, ic, 1, td->user, td->pass, td->oauth_info, args, 4);
     700        twitter_http(ic, TWITTER_DIRECT_MESSAGES_NEW_URL, twitter_http_post, ic, 1, args, 4);
    675701//      g_free(args[1]);
    676702//      g_free(args[3]);
     
    679705void twitter_friendships_create_destroy(struct im_connection *ic, char *who, int create)
    680706{
    681         struct twitter_data *td = ic->proto_data;
    682 
    683707        char* args[2];
    684708        args[0] = "screen_name";
    685709        args[1] = who;
    686         twitter_http(create ? TWITTER_FRIENDSHIPS_CREATE_URL : TWITTER_FRIENDSHIPS_DESTROY_URL, twitter_http_post, ic, 1, td->user, td->pass, td->oauth_info, args, 2);
    687 }
    688 
    689 
    690 
     710        twitter_http(ic, create ? TWITTER_FRIENDSHIPS_CREATE_URL : TWITTER_FRIENDSHIPS_DESTROY_URL, twitter_http_post, ic, 1, args, 2);
     711}
  • protocols/twitter/twitter_lib.h

    r7d53efb rba3233c  
    3232
    3333/* Status URLs */
    34 #define TWITTER_STATUS_UPDATE_URL TWITTER_API_URL "/statuses/update.xml"
    35 #define TWITTER_STATUS_SHOW_URL TWITTER_API_URL "/statuses/show/"
    36 #define TWITTER_STATUS_DESTROY_URL TWITTER_API_URL "/statuses/destroy/"
     34#define TWITTER_STATUS_UPDATE_URL "/statuses/update.xml"
     35#define TWITTER_STATUS_SHOW_URL "/statuses/show/"
     36#define TWITTER_STATUS_DESTROY_URL "/statuses/destroy/"
    3737
    3838/* Timeline URLs */
    39 #define TWITTER_PUBLIC_TIMELINE_URL TWITTER_API_URL "/statuses/public_timeline.xml"
    40 #define TWITTER_FEATURED_USERS_URL TWITTER_API_URL "/statuses/featured.xml"
    41 #define TWITTER_FRIENDS_TIMELINE_URL TWITTER_API_URL "/statuses/friends_timeline.xml"
    42 #define TWITTER_HOME_TIMELINE_URL TWITTER_API_URL "/statuses/home_timeline.xml"
    43 #define TWITTER_MENTIONS_URL TWITTER_API_URL "/statuses/mentions.xml"
    44 #define TWITTER_USER_TIMELINE_URL TWITTER_API_URL "/statuses/user_timeline.xml"
     39#define TWITTER_PUBLIC_TIMELINE_URL "/statuses/public_timeline.xml"
     40#define TWITTER_FEATURED_USERS_URL "/statuses/featured.xml"
     41#define TWITTER_FRIENDS_TIMELINE_URL "/statuses/friends_timeline.xml"
     42#define TWITTER_HOME_TIMELINE_URL "/statuses/home_timeline.xml"
     43#define TWITTER_MENTIONS_URL "/statuses/mentions.xml"
     44#define TWITTER_USER_TIMELINE_URL "/statuses/user_timeline.xml"
    4545
    4646/* Users URLs */
    47 #define TWITTER_SHOW_USERS_URL TWITTER_API_URL "/users/show.xml"
    48 #define TWITTER_SHOW_FRIENDS_URL TWITTER_API_URL "/statuses/friends.xml"
    49 #define TWITTER_SHOW_FOLLOWERS_URL TWITTER_API_URL "/statuses/followers.xml"
     47#define TWITTER_SHOW_USERS_URL "/users/show.xml"
     48#define TWITTER_SHOW_FRIENDS_URL "/statuses/friends.xml"
     49#define TWITTER_SHOW_FOLLOWERS_URL "/statuses/followers.xml"
    5050
    5151/* Direct messages URLs */
    52 #define TWITTER_DIRECT_MESSAGES_URL TWITTER_API_URL "/direct_messages.xml"
    53 #define TWITTER_DIRECT_MESSAGES_NEW_URL TWITTER_API_URL "/direct_messages/new.xml"
    54 #define TWITTER_DIRECT_MESSAGES_SENT_URL TWITTER_API_URL "/direct_messages/sent.xml"
    55 #define TWITTER_DIRECT_MESSAGES_DESTROY_URL TWITTER_API_URL "/direct_messages/destroy/"
     52#define TWITTER_DIRECT_MESSAGES_URL "/direct_messages.xml"
     53#define TWITTER_DIRECT_MESSAGES_NEW_URL "/direct_messages/new.xml"
     54#define TWITTER_DIRECT_MESSAGES_SENT_URL "/direct_messages/sent.xml"
     55#define TWITTER_DIRECT_MESSAGES_DESTROY_URL "/direct_messages/destroy/"
    5656
    5757/* Friendships URLs */
    58 #define TWITTER_FRIENDSHIPS_CREATE_URL TWITTER_API_URL "/friendships/create.xml"
    59 #define TWITTER_FRIENDSHIPS_DESTROY_URL TWITTER_API_URL "/friendships/destroy.xml"
    60 #define TWITTER_FRIENDSHIPS_SHOW_URL TWITTER_API_URL "/friendships/show.xml"
     58#define TWITTER_FRIENDSHIPS_CREATE_URL "/friendships/create.xml"
     59#define TWITTER_FRIENDSHIPS_DESTROY_URL "/friendships/destroy.xml"
     60#define TWITTER_FRIENDSHIPS_SHOW_URL "/friendships/show.xml"
    6161
    6262/* Social graphs URLs */
    63 #define TWITTER_FRIENDS_IDS_URL TWITTER_API_URL "/friends/ids.xml"
    64 #define TWITTER_FOLLOWERS_IDS_URL TWITTER_API_URL "/followers/ids.xml"
     63#define TWITTER_FRIENDS_IDS_URL "/friends/ids.xml"
     64#define TWITTER_FOLLOWERS_IDS_URL "/followers/ids.xml"
    6565
    6666/* Account URLs */
    67 #define TWITTER_ACCOUNT_RATE_LIMIT_URL TWITTER_API_URL "/account/rate_limit_status.xml"
     67#define TWITTER_ACCOUNT_RATE_LIMIT_URL "/account/rate_limit_status.xml"
    6868
    6969/* Favorites URLs */
    70 #define TWITTER_FAVORITES_GET_URL TWITTER_API_URL "/favorites.xml"
    71 #define TWITTER_FAVORITE_CREATE_URL TWITTER_API_URL "/favorites/create/"
    72 #define TWITTER_FAVORITE_DESTROY_URL TWITTER_API_URL "/favorites/destroy/"
     70#define TWITTER_FAVORITES_GET_URL "/favorites.xml"
     71#define TWITTER_FAVORITE_CREATE_URL "/favorites/create/"
     72#define TWITTER_FAVORITE_DESTROY_URL "/favorites/destroy/"
    7373
    7474/* Block URLs */
    75 #define TWITTER_BLOCKS_CREATE_URL TWITTER_API_URL "/blocks/create/"
    76 #define TWITTER_BLOCKS_DESTROY_URL TWITTER_API_URL "/blocks/destroy/"
     75#define TWITTER_BLOCKS_CREATE_URL "/blocks/create/"
     76#define TWITTER_BLOCKS_DESTROY_URL "/blocks/destroy/"
    7777
    7878void twitter_get_friends_ids(struct im_connection *ic, int next_cursor);
  • protocols/yahoo/yahoo.c

    r7d53efb rba3233c  
    138138        struct im_connection *ic = imcb_new( acc );
    139139        struct byahoo_data *yd = ic->proto_data = g_new0( struct byahoo_data, 1 );
     140        char *s;
    140141       
    141142        yd->logged_in = FALSE;
    142143        yd->current_status = YAHOO_STATUS_AVAILABLE;
     144       
     145        if( ( s = strchr( acc->user, '@' ) ) && g_strcasecmp( s, "@yahoo.com" ) == 0 )
     146                imcb_error( ic, "Your Yahoo! username should just be a username. "
     147                                "Do not include any @domain part." );
    143148       
    144149        imcb_log( ic, "Connecting" );
     
    828833        YList *m;
    829834       
     835        if( g_strcasecmp( who, ic->acc->user ) == 0 )
     836                /* WTF, Yahoo! seems to echo these now? */
     837                return;
     838       
    830839        inv = g_malloc( sizeof( struct byahoo_conf_invitation ) );
    831840        memset( inv, 0, sizeof( struct byahoo_conf_invitation ) );
Note: See TracChangeset for help on using the changeset viewer.