Changes in / [5cb9461:1a2c1c0]
- Files:
-
- 8 added
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
Makefile
r5cb9461 r1a2c1c0 11 11 # Program variables 12 12 objects = bitlbee.o dcc.o help.o ipc.o irc.o irc_im.o irc_channel.o irc_commands.o irc_send.o irc_user.o irc_util.o nick.o $(OTR_BI) query.o root_commands.o set.o storage.o $(STORAGE_OBJS) 13 headers = bitlbee.h commands.h conf.h config.h help.h ipc.h irc.h log.h nick.h query.h set.h sock.h storage.h lib/events.h lib/ftutil.h lib/http_client.h lib/ini.h lib/ md5.h lib/misc.h lib/proxy.h lib/sha1.h lib/ssl_client.h lib/url.h protocols/account.h protocols/bee.h protocols/ft.h protocols/nogaim.h13 headers = bitlbee.h commands.h conf.h config.h help.h ipc.h irc.h log.h nick.h query.h set.h sock.h storage.h lib/events.h lib/ftutil.h lib/http_client.h lib/ini.h lib/json.h lib/json_util.h lib/md5.h lib/misc.h lib/proxy.h lib/sha1.h lib/ssl_client.h lib/url.h protocols/account.h protocols/bee.h protocols/ft.h protocols/nogaim.h 14 14 subdirs = lib protocols 15 15 -
configure
r5cb9461 r1a2c1c0 211 211 echo CFLAGS+=-I${srcdir} -I${srcdir}/lib -I${srcdir}/protocols -I. >> Makefile.settings 212 212 213 echo CFLAGS+=-DHAVE_CONFIG_H >> Makefile.settings213 echo CFLAGS+=-DHAVE_CONFIG_H -D_GNU_SOURCE >> Makefile.settings 214 214 215 215 if [ -n "$CC" ]; then -
lib/http_client.c
r5cb9461 r1a2c1c0 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * 4 * Copyright 2002-201 2Wilmer van der Gaast and others *4 * Copyright 2002-2013 Wilmer van der Gaast and others * 5 5 \********************************************************************/ 6 6 … … 69 69 req->request_length = strlen( request ); 70 70 req->redir_ttl = 3; 71 req->content_length = -1; 71 72 72 73 if( getenv( "BITLBEE_DEBUG" ) ) … … 96 97 request = g_strdup_printf( "GET %s HTTP/1.0\r\n" 97 98 "Host: %s\r\n" 98 "Connection: close\r\n"99 99 "User-Agent: BitlBee " BITLBEE_VERSION " " ARCH "/" CPU "\r\n" 100 100 "\r\n", url->file, url->host ); … … 193 193 } 194 194 195 typedef enum { 196 CR_OK, 197 CR_EOF, 198 CR_ERROR, 199 CR_ABORT, 200 } http_ret_t; 201 195 202 static gboolean http_handle_headers( struct http_request *req ); 203 static http_ret_t http_process_chunked_data( struct http_request *req, const char *buffer, int len ); 204 static http_ret_t http_process_data( struct http_request *req, const char *buffer, int len ); 196 205 197 206 static gboolean http_incoming_data( gpointer data, int source, b_input_condition cond ) … … 199 208 struct http_request *req = data; 200 209 char buffer[4096]; 201 char *s;202 size_t content_length;203 210 int st; 204 211 … … 244 251 } 245 252 246 if( st > 0 && !req->sbuf ) 247 { 248 req->reply_headers = g_realloc( req->reply_headers, req->bytes_read + st + 1 ); 249 memcpy( req->reply_headers + req->bytes_read, buffer, st ); 250 req->bytes_read += st; 251 252 st = 0; 253 } 254 255 if( st >= 0 && ( req->flags & HTTPC_STREAMING ) ) 256 { 257 if( !req->reply_body && 258 ( strstr( req->reply_headers, "\r\n\r\n" ) || 259 strstr( req->reply_headers, "\n\n" ) ) ) 260 { 261 size_t hlen; 262 263 /* We've now received all headers, so process them once 264 before we start feeding back data. */ 265 if( !http_handle_headers( req ) ) 266 return FALSE; 267 268 hlen = req->reply_body - req->reply_headers; 269 270 req->sblen = req->bytes_read - hlen; 271 req->sbuf = g_memdup( req->reply_body, req->sblen + 1 ); 272 req->reply_headers = g_realloc( req->reply_headers, hlen + 1 ); 273 274 req->reply_body = req->sbuf; 275 } 276 277 if( st > 0 ) 278 { 279 int pos = req->reply_body - req->sbuf; 280 req->sbuf = g_realloc( req->sbuf, req->sblen + st + 1 ); 281 memcpy( req->sbuf + req->sblen, buffer, st ); 282 req->bytes_read += st; 283 req->sblen += st; 284 req->sbuf[req->sblen] = '\0'; 285 req->reply_body = req->sbuf + pos; 286 req->body_size = req->sblen - pos; 287 } 288 289 if( req->reply_body ) 290 req->func( req ); 291 } 253 if( st > 0 ) 254 { 255 http_ret_t c; 256 257 if( req->flags & HTTPC_CHUNKED ) 258 c = http_process_chunked_data( req, buffer, st ); 259 else 260 c = http_process_data( req, buffer, st ); 261 262 if( c == CR_EOF ) 263 goto eof; 264 else if( c == CR_ERROR || c == CR_ABORT ) 265 return FALSE; 266 } 267 268 if( req->content_length != -1 && 269 req->body_size >= req->content_length ) 270 goto eof; 292 271 293 272 if( ssl_pending( req->ssl ) ) … … 311 290 goto cleanup; 312 291 } 313 314 if( !( req->flags & HTTPC_STREAMING ) )315 {316 /* Returns FALSE if we were redirected, in which case we should abort317 and not run any callback yet. */318 if( !http_handle_headers( req ) )319 return FALSE;320 }321 292 322 293 cleanup: … … 326 297 closesocket( req->fd ); 327 298 328 if( ( s = get_rfc822_header( req->reply_headers, "Content-Length", 0 ) ) && 329 sscanf( s, "%zd", &content_length ) == 1 ) 330 { 331 if( content_length < req->body_size ) 332 { 333 req->status_code = -1; 334 g_free( req->status_string ); 335 req->status_string = g_strdup( "Response truncated" ); 336 } 337 } 338 g_free( s ); 299 if( req->body_size < req->content_length ) 300 { 301 req->status_code = -1; 302 g_free( req->status_string ); 303 req->status_string = g_strdup( "Response truncated" ); 304 } 339 305 340 306 if( getenv( "BITLBEE_DEBUG" ) && req ) … … 347 313 } 348 314 315 static http_ret_t http_process_chunked_data( struct http_request *req, const char *buffer, int len ) 316 { 317 char *chunk, *eos, *s; 318 319 if( len < 0 ) 320 return TRUE; 321 322 if( len > 0 ) 323 { 324 req->cbuf = g_realloc( req->cbuf, req->cblen + len + 1 ); 325 memcpy( req->cbuf + req->cblen, buffer, len ); 326 req->cblen += len; 327 req->cbuf[req->cblen] = '\0'; 328 } 329 330 /* Turns out writing a proper chunked-encoding state machine is not 331 that simple. :-( I've tested this one feeding it byte by byte so 332 I hope it's solid now. */ 333 chunk = req->cbuf; 334 eos = req->cbuf + req->cblen; 335 while( TRUE ) 336 { 337 int clen = 0; 338 339 /* Might be a \r\n from the last chunk. */ 340 s = chunk; 341 while( isspace( *s ) ) 342 s ++; 343 /* Chunk length. Might be incomplete. */ 344 if( s < eos && sscanf( s, "%x", &clen ) != 1 ) 345 return CR_ERROR; 346 while( isxdigit( *s ) ) 347 s ++; 348 349 /* If we read anything here, it *must* be \r\n. */ 350 if( strncmp( s, "\r\n", MIN( 2, eos - s ) ) != 0 ) 351 return CR_ERROR; 352 s += 2; 353 354 if( s >= eos ) 355 break; 356 357 /* 0-length chunk means end of response. */ 358 if( clen == 0 ) 359 return CR_EOF; 360 361 /* Wait for the whole chunk to arrive. */ 362 if( s + clen > eos ) 363 break; 364 if( http_process_data( req, s, clen ) != CR_OK ) 365 return CR_ABORT; 366 367 chunk = s + clen; 368 } 369 370 if( chunk != req->cbuf ) 371 { 372 req->cblen = eos - chunk; 373 s = g_memdup( chunk, req->cblen + 1 ); 374 g_free( req->cbuf ); 375 req->cbuf = s; 376 } 377 378 return CR_OK; 379 } 380 381 static http_ret_t http_process_data( struct http_request *req, const char *buffer, int len ) 382 { 383 if( len <= 0 ) 384 return CR_OK; 385 386 if( !req->reply_body ) 387 { 388 req->reply_headers = g_realloc( req->reply_headers, req->bytes_read + len + 1 ); 389 memcpy( req->reply_headers + req->bytes_read, buffer, len ); 390 req->bytes_read += len; 391 req->reply_headers[req->bytes_read] = '\0'; 392 393 if( strstr( req->reply_headers, "\r\n\r\n" ) || 394 strstr( req->reply_headers, "\n\n" ) ) 395 { 396 /* We've now received all headers. Look for something 397 interesting. */ 398 if( !http_handle_headers( req ) ) 399 return CR_ABORT; 400 401 /* Start parsing the body as chunked if required. */ 402 if( req->flags & HTTPC_CHUNKED ) 403 return http_process_chunked_data( req, NULL, 0 ); 404 } 405 } 406 else 407 { 408 int pos = req->reply_body - req->sbuf; 409 req->sbuf = g_realloc( req->sbuf, req->sblen + len + 1 ); 410 memcpy( req->sbuf + req->sblen, buffer, len ); 411 req->bytes_read += len; 412 req->sblen += len; 413 req->sbuf[req->sblen] = '\0'; 414 req->reply_body = req->sbuf + pos; 415 req->body_size = req->sblen - pos; 416 } 417 418 if( ( req->flags & HTTPC_STREAMING ) && req->reply_body ) 419 req->func( req ); 420 421 return CR_OK; 422 } 423 349 424 /* Splits headers and body. Checks result code, in case of 300s it'll handle 350 425 redirects. If this returns FALSE, don't call any callbacks! */ 351 426 static gboolean http_handle_headers( struct http_request *req ) 352 427 { 353 char *end1, *end2 ;428 char *end1, *end2, *s; 354 429 int evil_server = 0; 355 430 … … 377 452 } 378 453 379 *end1 = 0;454 *end1 = '\0'; 380 455 381 456 if( getenv( "BITLBEE_DEBUG" ) ) … … 387 462 req->reply_body = end1 + 2; 388 463 389 req->body_size = req->reply_headers + req->bytes_read - req->reply_body; 464 /* Separately allocated space for headers and body. */ 465 req->sblen = req->body_size = req->reply_headers + req->bytes_read - req->reply_body; 466 req->sbuf = req->reply_body = g_memdup( req->reply_body, req->body_size + 1 ); 467 req->reply_headers = g_realloc( req->reply_headers, end1 - req->reply_headers + 1 ); 390 468 391 469 if( ( end1 = strchr( req->reply_headers, ' ' ) ) != NULL ) … … 452 530 don't need this yet anyway, I won't implement it. */ 453 531 454 req->status_string = g_strdup( "Can't handle re cursive redirects" );532 req->status_string = g_strdup( "Can't handle relative redirects" ); 455 533 456 534 return TRUE; … … 460 538 /* A whole URL */ 461 539 url_t *url; 462 char *s ;540 char *s, *version, *headers; 463 541 const char *new_method; 464 542 … … 488 566 return TRUE; 489 567 } 568 headers = s; 490 569 491 570 /* More or less HTTP/1.0 compliant, from my reading of RFC 2616. … … 507 586 new_method = "POST"; 508 587 588 if( ( version = strstr( req->request, " HTTP/" ) ) && 589 ( s = strstr( version, "\r\n" ) ) ) 590 { 591 version ++; 592 version = g_strndup( version, s - version ); 593 } 594 else 595 version = g_strdup( "HTTP/1.0" ); 596 509 597 /* Okay, this isn't fun! We have to rebuild the request... :-( */ 510 new_request = g_strdup_printf( "%s %s HTTP/1.0\r\nHost: %s%s", 511 new_method, url->file, url->host, s ); 598 new_request = g_strdup_printf( "%s %s %s\r\nHost: %s%s", 599 new_method, url->file, version, 600 url->host, headers ); 512 601 513 602 new_host = g_strdup( url->host ); … … 521 610 522 611 g_free( url ); 612 g_free( version ); 523 613 } 524 614 … … 557 647 g_free( req->request ); 558 648 g_free( req->reply_headers ); 649 g_free( req->sbuf ); 559 650 req->request = new_request; 560 651 req->request_length = strlen( new_request ); 561 652 req->bytes_read = req->bytes_written = req->inpa = 0; 562 653 req->reply_headers = req->reply_body = NULL; 654 req->sbuf = req->cbuf = NULL; 655 req->sblen = req->cblen = 0; 563 656 564 657 return FALSE; 658 } 659 660 if( ( s = get_rfc822_header( req->reply_headers, "Content-Length", 0 ) ) && 661 sscanf( s, "%d", &req->content_length ) != 1 ) 662 req->content_length = -1; 663 g_free( s ); 664 665 if( ( s = get_rfc822_header( req->reply_headers, "Transfer-Encoding", 0 ) ) ) 666 { 667 if( strcasestr( s, "chunked" ) ) 668 { 669 req->flags |= HTTPC_CHUNKED; 670 req->cbuf = req->sbuf; 671 req->cblen = req->sblen; 672 673 req->reply_body = req->sbuf = g_strdup( "" ); 674 req->body_size = req->sblen = 0; 675 } 676 g_free( s ); 565 677 } 566 678 … … 607 719 g_free( req->status_string ); 608 720 g_free( req->sbuf ); 721 g_free( req->cbuf ); 609 722 g_free( req ); 610 723 } -
lib/http_client.h
r5cb9461 r1a2c1c0 42 42 HTTPC_STREAMING = 1, 43 43 HTTPC_EOF = 2, 44 HTTPC_CHUNKED = 4, 44 45 45 46 /* Let's reserve 0x1000000+ for lib users. */ … … 77 78 int bytes_written; 78 79 int bytes_read; 80 int content_length; /* "Content-Length:" header or -1 */ 79 81 80 82 /* Used in streaming mode. Caller should read from reply_body. */ 81 83 char *sbuf; 82 84 size_t sblen; 85 86 /* Chunked encoding only. Raw chunked stream is decoded from here. */ 87 char *cbuf; 88 size_t cblen; 83 89 }; 84 90 -
lib/oauth.c
r5cb9461 r1a2c1c0 262 262 "Content-Type: application/x-www-form-urlencoded\r\n" 263 263 "Content-Length: %zd\r\n" 264 "Connection: close\r\n"265 264 "\r\n" 266 265 "%s", url_p.file, url_p.host, strlen( post ), post ); -
lib/oauth2.c
r5cb9461 r1a2c1c0 2 2 * * 3 3 * BitlBee - An IRC to IM gateway * 4 * Simple OAuth client (consumer) implementation.*4 * Simple OAuth2 client (consumer) implementation. * 5 5 * * 6 * Copyright 2010-201 2Wilmer van der Gaast <wilmer@gaast.net> *6 * Copyright 2010-2013 Wilmer van der Gaast <wilmer@gaast.net> * 7 7 * * 8 8 * This program is free software; you can redistribute it and/or modify * … … 22 22 \***************************************************************************/ 23 23 24 /* Out of protest, I should rename this file. OAuth2 is a pathetic joke, and 25 of all things, DEFINITELY NOT A STANDARD. The only thing various OAuth2 26 implementations have in common is that name, wrongfully stolen from 27 a pretty nice standard called OAuth 1.0a. That, and the fact that they 28 use JSON. Wait, no, Facebook's version doesn't use JSON. For some of its 29 responses. 30 31 Apparently too many people were too retarded to comprehend the elementary 32 bits of crypto in OAuth 1.0a (took me one afternoon to implement) so 33 the standard was replaced with what comes down to a complicated scheme 34 around what's really just application-specific passwords. 35 36 And then a bunch of mostly incompatible implementations. Great work, guys. 37 38 http://hueniverse.com/2012/07/oauth-2-0-and-the-road-to-hell/ */ 39 24 40 #include <glib.h> 25 41 #include "http_client.h" … … 27 43 #include "oauth.h" 28 44 #include "json.h" 45 #include "json_util.h" 29 46 #include "url.h" 30 47 … … 79 96 "Content-Type: application/x-www-form-urlencoded\r\n" 80 97 "Content-Length: %zd\r\n" 81 "Connection: close\r\n"82 98 "\r\n" 83 99 "%s", url_p.file, url_p.host, strlen( args_s ), args_s ); … … 99 115 } 100 116 117 static char* oauth2_parse_error( json_value *e ) 118 { 119 /* This does a reasonable job with some of the flavours of error 120 responses I've seen. Because apparently it's not standardised. */ 121 122 if( e->type == json_object ) 123 { 124 /* Facebook style */ 125 const char *msg = json_o_str( e, "message" ); 126 const char *type = json_o_str( e, "type" ); 127 json_value *code_o = json_o_get( e, "code" ); 128 int code = 0; 129 130 if( code_o && code_o->type == json_integer ) 131 code = code_o->u.integer; 132 133 return g_strdup_printf( "Error %d: %s", code, msg ? msg : type ? type : "Unknown error" ); 134 } 135 else if( e->type == json_string ) 136 { 137 return g_strdup( e->u.string.ptr ); 138 } 139 return NULL; 140 } 141 101 142 static void oauth2_access_token_done( struct http_request *req ) 102 143 { 103 144 struct oauth2_access_token_data *cb_data = req->data; 104 char *atoken = NULL, *rtoken = NULL ;145 char *atoken = NULL, *rtoken = NULL, *error = NULL; 105 146 char *content_type; 106 147 … … 110 151 content_type = get_rfc822_header( req->reply_headers, "Content-Type", 0 ); 111 152 112 if( req->status_code != 200 ) 113 { 114 } 115 else if( content_type && strstr( content_type, "application/json" ) ) 153 if( content_type && ( strstr( content_type, "application/json" ) || 154 strstr( content_type, "text/javascript" ) ) ) 116 155 { 117 156 json_value *js = json_parse( req->reply_body ); 118 157 if( js && js->type == json_object ) 119 158 { 120 int i; 121 122 for( i = 0; i < js->u.object.length; i ++ ) 159 JSON_O_FOREACH( js, k, v ) 123 160 { 124 if( js->u.object.values[i].value->type != json_string ) 161 if( strcmp( k, "error" ) == 0 ) 162 error = oauth2_parse_error( v ); 163 if( v->type != json_string ) 125 164 continue; 126 if( strcmp( js->u.object.values[i].name, "access_token" ) == 0 )127 atoken = g_strdup( js->u.object.values[i].value->u.string.ptr );128 if( strcmp( js->u.object.values[i].name, "refresh_token" ) == 0 )129 rtoken = g_strdup( js->u.object.values[i].value->u.string.ptr );165 if( strcmp( k, "access_token" ) == 0 ) 166 atoken = g_strdup( v->u.string.ptr ); 167 if( strcmp( k, "refresh_token" ) == 0 ) 168 rtoken = g_strdup( v->u.string.ptr ); 130 169 } 131 170 } … … 144 183 if( getenv( "BITLBEE_DEBUG" ) ) 145 184 printf( "Extracted atoken=%s rtoken=%s\n", atoken, rtoken ); 185 if( !atoken && !rtoken && !error ) 186 error = g_strdup( "Unusuable response" ); 146 187 147 cb_data->func( cb_data->data, atoken, rtoken );188 cb_data->func( cb_data->data, atoken, rtoken, error ); 148 189 g_free( content_type ); 149 190 g_free( atoken ); 150 191 g_free( rtoken ); 192 g_free( error ); 151 193 g_free( cb_data ); 152 194 } -
lib/oauth2.h
r5cb9461 r1a2c1c0 4 4 * Simple OAuth2 client (consumer) implementation. * 5 5 * * 6 * Copyright 2010-201 1Wilmer van der Gaast <wilmer@gaast.net> *6 * Copyright 2010-2013 Wilmer van der Gaast <wilmer@gaast.net> * 7 7 * * 8 8 * This program is free software; you can redistribute it and/or modify * … … 25 25 module, and from http://code.google.com/apis/accounts/docs/OAuth2.html . */ 26 26 27 typedef void (*oauth2_token_callback)( gpointer data, const char *atoken, const char *rtoken ); 27 typedef void (*oauth2_token_callback)( gpointer data, const char *atoken, 28 const char *rtoken, const char *error ); 28 29 29 30 struct oauth2_service -
lib/proxy.c
r5cb9461 r1a2c1c0 158 158 } 159 159 160 event_debug("proxy_connect_none( \"%s\", %d ) = %d\n", host, port , fd);160 event_debug("proxy_connect_none( \"%s\", %d ) = %d\n", host, port_, fd); 161 161 162 162 if (connect(fd, phb->gai_cur->ai_addr, phb->gai_cur->ai_addrlen) < 0 && !sockerr_again()) { -
lib/ssl_nss.c
r5cb9461 r1a2c1c0 152 152 conn->func = func; 153 153 conn->data = data; 154 conn->hostname = hostname;154 conn->hostname = g_strdup(hostname); 155 155 156 156 /* For now, SSL verification is globally enabled by setting the cafile … … 296 296 PR_Close(conn->prfd); 297 297 298 298 g_free(conn->hostname); 299 299 g_free(conn); 300 300 } -
nick.c
r5cb9461 r1a2c1c0 392 392 393 393 for( i = 0; nick[i]; i ++ ) 394 nick[i] = tab[(int)nick[i]]; 394 if( nick[i] < 0x7f ) 395 nick[i] = tab[(int)nick[i]]; 395 396 396 397 return nick_ok( irc, nick ); -
protocols/jabber/sasl.c
r5cb9461 r1a2c1c0 483 483 } 484 484 485 static void sasl_oauth2_got_token( gpointer data, const char *access_token, const char *refresh_token );485 static void sasl_oauth2_got_token( gpointer data, const char *access_token, const char *refresh_token, const char *error ); 486 486 487 487 int sasl_oauth2_get_refresh_token( struct im_connection *ic, const char *msg ) … … 514 514 } 515 515 516 static void sasl_oauth2_got_token( gpointer data, const char *access_token, const char *refresh_token )516 static void sasl_oauth2_got_token( gpointer data, const char *access_token, const char *refresh_token, const char *error ) 517 517 { 518 518 struct im_connection *ic = data; … … 527 527 if( access_token == NULL ) 528 528 { 529 imcb_error( ic, "OAuth failure ( missing access token)");529 imcb_error( ic, "OAuth failure (%s)", error ); 530 530 imc_logout( ic, TRUE ); 531 531 return; -
protocols/oscar/oscar.c
r5cb9461 r1a2c1c0 981 981 982 982 if (args->icbmflags & AIM_IMFLAGS_UNICODE) 983 src = "U NICODEBIG";983 src = "UCS-2BE"; 984 984 else 985 985 src = "ISO8859-1"; … … 1769 1769 args.flags |= AIM_IMFLAGS_ISO_8859_1; 1770 1770 len = ret; 1771 } else if ((ret = do_iconv("UTF-8", "U NICODEBIG", message, s, len, BUF_LONG)) >= 0) {1771 } else if ((ret = do_iconv("UTF-8", "UCS-2BE", message, s, len, BUF_LONG)) >= 0) { 1772 1772 args.flags |= AIM_IMFLAGS_UNICODE; 1773 1773 len = ret; … … 2406 2406 flags |= AIM_CHATFLAGS_ISO_8859_1; 2407 2407 len = ret; 2408 } else if ((ret = do_iconv("UTF-8", "U NICODEBIG", message, s, len, BUF_LONG)) >= 0) {2408 } else if ((ret = do_iconv("UTF-8", "UCS-2BE", message, s, len, BUF_LONG)) >= 0) { 2409 2409 flags |= AIM_CHATFLAGS_UNICODE; 2410 2410 len = ret; -
protocols/skype/README
r5cb9461 r1a2c1c0 58 58 connects to Skype, finally BitlBee can connect to `skyped`. 59 59 60 === Installing under Frugalware or Debian 61 62 - Install the necessary packages: 63 64 ---- 65 # pacman-g2 -S bitlbee-skype 66 ---- 67 68 or 60 === Installing 61 62 Either use your package manager to install the Skype plugin, using something 63 like: 69 64 70 65 ---- … … 72 67 ---- 73 68 74 (the later from the unstable repo) 75 76 and you don't have to compile anything manually. 77 78 === Installing under OS X 79 80 - Install the necessary packages from ports: 81 82 NOTE: You have to edit the Portfile manually to include the install-dev target, 83 just append install-dev after install-etc. 84 85 ---- 86 # port -v install bitlbee 87 ---- 88 89 and you have to install `bitlbee-skype` and `skype4py` from 90 source. 91 92 === Installing from source 93 94 NOTE: bitlbee-skype by default builds and installs skyped and the 95 plugin. In case you just want to install the plugin for a public server 96 or you want to use skyped with a public server (like 97 `bitlbee1.asnetinc.net`), you don't need both. 98 99 - You need the latest stable BitlBee release (unless you want to use a 100 public server): 101 102 ---- 103 $ wget http://get.bitlbee.org/src/bitlbee-@BITLBEE_VERSION@.tar.gz 104 $ tar xf bitlbee-@BITLBEE_VERSION@.tar.gz 105 $ cd bitlbee-@BITLBEE_VERSION@ 106 ---- 107 108 - Now compile and install it: 109 110 ---- 111 $ ./configure 112 $ make 113 # make install install-dev 114 ---- 115 116 - To install http://skype4py.sourceforge.net/[Skype4Py] from source 117 (unless you want to install the plugin for a public server): 118 119 ---- 120 $ tar -zxvf Skype4Py-x.x.x.x.tar.gz 121 $ cd Skype4Py-x.x.x.x 122 # python setup.py install 123 ---- 124 125 - Get the plugin code (in an empty dir, or whereever you want, it does 126 not matter): 127 128 ---- 129 $ wget http://vmiklos.hu/project/bitlbee-skype/bitlbee-skype-@VERSION@.tar.gz 130 $ tar xf bitlbee-skype-@VERSION@.tar.gz 131 $ cd bitlbee-skype-@VERSION@ 132 ---- 133 134 - Compile and install it: 135 136 ---- 137 $ ./configure 138 $ make 139 # make install 140 ---- 141 142 This will install the plugin to where BitlBee expects them, which is 143 `/usr/local/lib/bitlbee` if you installed BitlBee from source. 69 Or install http://sourceforge.net/projects/skype4py/[Skype4Py], and build 70 BitlBee with `--skype=1`. 144 71 145 72 === Configuring -
protocols/skype/skype.c
r5cb9461 r1a2c1c0 344 344 ptr++; 345 345 if (!strncmp(ptr, "ONLINESTATUS ", 13)) { 346 if (!strcmp(user, sd->username))347 348 346 if (!strlen(user) || !strcmp(user, sd->username)) 347 return; 348 if (!set_getbool(&ic->acc->set, "test_join") 349 349 && !strcmp(user, "echo123")) 350 350 return; 351 351 ptr = g_strdup_printf("%s@skype.com", user); 352 352 imcb_add_buddy(ic, ptr, skype_group_by_username(ic, user)); … … 1016 1016 } 1017 1017 } else if (!strncmp(info, "MEMBERS ", 8) || !strncmp(info, "ACTIVEMEMBERS ", 14) ) { 1018 info += 8; 1018 if (!strncmp(info, "MEMBERS ", 8)) 1019 info += 8; 1020 else 1021 info += 14; 1019 1022 gc = bee_chat_by_title(ic->bee, ic, id); 1020 1023 /* Hack! We set ->data to TRUE … … 1564 1567 1565 1568 s = set_add(&acc->set, "mood_text", NULL, skype_set_mood_text, acc); 1566 s->flags |= ACC_SET_NOSAVE | ACC_SET_ONLINE_ONLY;1569 s->flags |= SET_NOSAVE | ACC_SET_ONLINE_ONLY; 1567 1570 1568 1571 s = set_add(&acc->set, "call", NULL, skype_set_call, acc); -
protocols/skype/skyped.py
r5cb9461 r1a2c1c0 273 273 if options.log: 274 274 sock = open(options.log, "a") 275 sock.write( prefix + ": " + sanitized)275 sock.write("%s: %s\n" % (prefix, sanitized)) 276 276 sock.close() 277 277 -
protocols/skype/test.py
r5cb9461 r1a2c1c0 113 113 self.mock("groupchat-leave") 114 114 115 def testGroupchatMsg(self): 116 self.mock("groupchat-msg") 117 118 def testGroupchatTopic(self): 119 self.mock("groupchat-topic") 120 115 121 def testCalledYes(self): 116 122 self.mock("called-yes") … … 125 131 self.mock("group-read") 126 132 133 def testGroupAdd(self): 134 self.mock("group-add") 135 127 136 def testCtcpHelp(self): 128 137 self.mock("ctcp-help") … … 130 139 def testSetMoodText(self): 131 140 self.mock("set-mood-text") 141 142 def testAwaySet(self): 143 self.mock("away-set") 132 144 133 145 if __name__ == '__main__': -
protocols/twitter/twitter.c
r5cb9461 r1a2c1c0 158 158 { 159 159 struct twitter_data *td = ic->proto_data; 160 const char *url = set_getstr(&ic->acc->set, "base_url"); 160 161 161 162 imcb_log(ic, "Requesting OAuth request token"); 163 164 if (!strstr(url, "twitter.com") && !strstr(url, "identi.ca")) 165 imcb_log(ic, "Warning: OAuth only works with identi.ca and " 166 "Twitter."); 162 167 163 168 td->oauth_info = oauth_request_token(get_oauth_service(ic), twitter_oauth_callback, ic); … … 178 183 td = ic->proto_data; 179 184 if (info->stage == OAUTH_REQUEST_TOKEN) { 180 char name[strlen(ic->acc->user) + 9], *msg;185 char *name, *msg; 181 186 182 187 if (info->request_token == NULL) { … … 186 191 } 187 192 188 sprintf(name,"%s_%s", td->prefix, ic->acc->user);193 name = g_strdup_printf("%s_%s", td->prefix, ic->acc->user); 189 194 msg = g_strdup_printf("To finish OAuth authentication, please visit " 190 195 "%s and respond with the resulting PIN code.", 191 196 info->auth_url); 192 197 imcb_buddy_msg(ic, name, msg, 0, 0); 198 g_free(name); 193 199 g_free(msg); 194 200 } else if (info->stage == OAUTH_ACCESS_TOKEN) { … … 283 289 char *def_url; 284 290 char *def_tul; 291 char *def_mentions; 285 292 286 293 if (strcmp(acc->prpl->name, "twitter") == 0) { 287 294 def_url = TWITTER_API_URL; 288 295 def_tul = "20"; 296 def_mentions = "true"; 289 297 } else { /* if( strcmp( acc->prpl->name, "identica" ) == 0 ) */ 290 298 def_url = IDENTICA_API_URL; 291 299 def_tul = "0"; 300 def_mentions = "false"; 292 301 } 293 302 … … 302 311 s->flags |= ACC_SET_OFFLINE_ONLY; 303 312 304 s = set_add(&acc->set, "fetch_mentions", "true", set_eval_bool, acc);313 s = set_add(&acc->set, "fetch_mentions", def_mentions, set_eval_bool, acc); 305 314 306 315 s = set_add(&acc->set, "message_length", "140", set_eval_int, acc); -
protocols/twitter/twitter_http.c
r5cb9461 r1a2c1c0 78 78 79 79 // Make the request. 80 g_string_printf(request, "%s %s%s%s%s HTTP/1. 0\r\n"80 g_string_printf(request, "%s %s%s%s%s HTTP/1.1\r\n" 81 81 "Host: %s\r\n" 82 82 "User-Agent: BitlBee " BITLBEE_VERSION " " ARCH "/" CPU "\r\n", -
protocols/twitter/twitter_lib.h
r5cb9461 r1a2c1c0 29 29 #include "twitter_http.h" 30 30 31 #define TWITTER_API_URL "http ://api.twitter.com/1.1"31 #define TWITTER_API_URL "https://api.twitter.com/1.1" 32 32 #define IDENTICA_API_URL "https://identi.ca/api" 33 33 -
storage_xml.c
r5cb9461 r1a2c1c0 174 174 char *fn, buf[2048]; 175 175 int fd, st; 176 struct xt_parser *xp ;176 struct xt_parser *xp = NULL; 177 177 struct xt_node *node; 178 178 storage_status_t ret = STORAGE_OTHER_ERROR;
Note: See TracChangeset
for help on using the changeset viewer.