Changeset 5ebff60 for protocols/nogaim.c
- Timestamp:
- 2015-02-20T22:50:54Z (9 years ago)
- Branches:
- master
- Children:
- 0b9daac, 3d45471, 7733b8c
- Parents:
- af359b4
- git-author:
- Indent <please@…> (19-02-15 05:47:20)
- git-committer:
- dequis <dx@…> (20-02-15 22:50:54)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/nogaim.c
raf359b4 r5ebff60 1 1 /********************************************************************\ 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * … … 43 43 { 44 44 void (*init_function) (void); 45 45 46 46 GModule *mod = g_module_open(path, G_MODULE_BIND_LAZY); 47 47 48 if (!mod) {48 if (!mod) { 49 49 log_message(LOGLVL_ERROR, "Can't find `%s', not loading (%s)\n", path, g_module_error()); 50 50 return FALSE; 51 51 } 52 52 53 if (!g_module_symbol(mod,"init_plugin",(gpointer *) &init_function)) {53 if (!g_module_symbol(mod, "init_plugin", (gpointer *) &init_function)) { 54 54 log_message(LOGLVL_WARNING, "Can't find function `init_plugin' in `%s'\n", path); 55 55 return FALSE; … … 74 74 while ((entry = g_dir_read_name(dir))) { 75 75 path = g_build_filename(global.conf->plugindir, entry, NULL); 76 if (!path) {76 if (!path) { 77 77 log_message(LOGLVL_WARNING, "Can't build path for %s\n", entry); 78 78 continue; … … 90 90 91 91 GList *protocols = NULL; 92 93 void register_protocol 92 93 void register_protocol(struct prpl *p) 94 94 { 95 95 int i; 96 96 gboolean refused = global.conf->protocols != NULL; 97 98 for (i = 0; global.conf->protocols && global.conf->protocols[i]; i++) 99 { 100 if (g_strcasecmp(p->name, global.conf->protocols[i]) == 0) 97 98 for (i = 0; global.conf->protocols && global.conf->protocols[i]; i++) { 99 if (g_strcasecmp(p->name, global.conf->protocols[i]) == 0) { 101 100 refused = FALSE; 102 } 103 104 if (refused) 101 } 102 } 103 104 if (refused) { 105 105 log_message(LOGLVL_WARNING, "Protocol %s disabled\n", p->name); 106 else106 } else { 107 107 protocols = g_list_append(protocols, p); 108 } 108 109 } 109 110 … … 111 112 { 112 113 GList *gl; 113 114 for( gl = protocols; gl; gl = gl->next ) 115 { 116 struct prpl *proto = gl->data; 117 118 if( g_strcasecmp( proto->name, name ) == 0 ) 114 115 for (gl = protocols; gl; gl = gl->next) { 116 struct prpl *proto = gl->data; 117 118 if (g_strcasecmp(proto->name, name) == 0) { 119 119 return proto; 120 } 121 122 return NULL; 120 } 121 } 122 123 return NULL; 123 124 } 124 125 … … 139 140 oscar_initmodule(); 140 141 #endif 141 142 142 143 #ifdef WITH_YAHOO 143 144 byahoo_initmodule(); 144 145 #endif 145 146 146 147 #ifdef WITH_JABBER 147 148 jabber_initmodule(); … … 161 162 } 162 163 163 GSList *get_connections() { return connections; } 164 165 struct im_connection *imcb_new( account_t *acc ) 164 GSList *get_connections() 165 { 166 return connections; 167 } 168 169 struct im_connection *imcb_new(account_t *acc) 166 170 { 167 171 struct im_connection *ic; 168 169 ic = g_new0( struct im_connection, 1);170 172 173 ic = g_new0(struct im_connection, 1); 174 171 175 ic->bee = acc->bee; 172 176 ic->acc = acc; 173 177 acc->ic = ic; 174 175 connections = g_slist_append( connections, ic);176 177 return( ic);178 } 179 180 void imc_free( struct im_connection *ic)178 179 connections = g_slist_append(connections, ic); 180 181 return(ic); 182 } 183 184 void imc_free(struct im_connection *ic) 181 185 { 182 186 account_t *a; 183 187 184 188 /* Destroy the pointer to this connection from the account list */ 185 for( a = ic->bee->accounts; a; a = a->next ) 186 if( a->ic == ic ) 187 { 189 for (a = ic->bee->accounts; a; a = a->next) { 190 if (a->ic == ic) { 188 191 a->ic = NULL; 189 192 break; 190 193 } 191 192 connections = g_slist_remove( connections, ic ); 193 g_free( ic ); 194 } 195 196 static void serv_got_crap( struct im_connection *ic, char *format, ... ) 194 } 195 196 connections = g_slist_remove(connections, ic); 197 g_free(ic); 198 } 199 200 static void serv_got_crap(struct im_connection *ic, char *format, ...) 197 201 { 198 202 va_list params; 199 203 char *text; 200 204 account_t *a; 201 202 va_start( params, format ); 203 text = g_strdup_vprintf( format, params ); 204 va_end( params ); 205 206 if( ( g_strcasecmp( set_getstr( &ic->bee->set, "strip_html" ), "always" ) == 0 ) || 207 ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->bee->set, "strip_html" ) ) ) 208 strip_html( text ); 209 205 206 va_start(params, format); 207 text = g_strdup_vprintf(format, params); 208 va_end(params); 209 210 if ((g_strcasecmp(set_getstr(&ic->bee->set, "strip_html"), "always") == 0) || 211 ((ic->flags & OPT_DOES_HTML) && set_getbool(&ic->bee->set, "strip_html"))) { 212 strip_html(text); 213 } 214 210 215 /* Try to find a different connection on the same protocol. */ 211 for ( a = ic->bee->accounts; a; a = a->next )212 if ( a->prpl == ic->acc->prpl && a->ic != ic )216 for (a = ic->bee->accounts; a; a = a->next) { 217 if (a->prpl == ic->acc->prpl && a->ic != ic) { 213 218 break; 214 219 } 220 } 221 215 222 /* If we found one, include the screenname in the message. */ 216 if ( a )223 if (a) { 217 224 /* FIXME(wilmer): ui_log callback or so */ 218 irc_rootmsg( ic->bee->ui_data, "%s - %s", ic->acc->tag, text ); 219 else 220 irc_rootmsg( ic->bee->ui_data, "%s - %s", ic->acc->prpl->name, text ); 221 222 g_free( text ); 223 } 224 225 void imcb_log( struct im_connection *ic, char *format, ... ) 225 irc_rootmsg(ic->bee->ui_data, "%s - %s", ic->acc->tag, text); 226 } else { 227 irc_rootmsg(ic->bee->ui_data, "%s - %s", ic->acc->prpl->name, text); 228 } 229 230 g_free(text); 231 } 232 233 void imcb_log(struct im_connection *ic, char *format, ...) 226 234 { 227 235 va_list params; 228 236 char *text; 229 230 va_start( params, format ); 231 text = g_strdup_vprintf( format, params ); 232 va_end( params ); 233 234 if( ic->flags & OPT_LOGGED_IN ) 235 serv_got_crap( ic, "%s", text ); 236 else 237 serv_got_crap( ic, "Logging in: %s", text ); 238 239 g_free( text ); 240 } 241 242 void imcb_error( struct im_connection *ic, char *format, ... ) 237 238 va_start(params, format); 239 text = g_strdup_vprintf(format, params); 240 va_end(params); 241 242 if (ic->flags & OPT_LOGGED_IN) { 243 serv_got_crap(ic, "%s", text); 244 } else { 245 serv_got_crap(ic, "Logging in: %s", text); 246 } 247 248 g_free(text); 249 } 250 251 void imcb_error(struct im_connection *ic, char *format, ...) 243 252 { 244 253 va_list params; 245 254 char *text; 246 247 va_start( params, format ); 248 text = g_strdup_vprintf( format, params ); 249 va_end( params ); 250 251 if( ic->flags & OPT_LOGGED_IN ) 252 serv_got_crap( ic, "Error: %s", text ); 253 else 254 serv_got_crap( ic, "Login error: %s", text ); 255 256 g_free( text ); 257 } 258 259 static gboolean send_keepalive( gpointer d, gint fd, b_input_condition cond ) 255 256 va_start(params, format); 257 text = g_strdup_vprintf(format, params); 258 va_end(params); 259 260 if (ic->flags & OPT_LOGGED_IN) { 261 serv_got_crap(ic, "Error: %s", text); 262 } else { 263 serv_got_crap(ic, "Login error: %s", text); 264 } 265 266 g_free(text); 267 } 268 269 static gboolean send_keepalive(gpointer d, gint fd, b_input_condition cond) 260 270 { 261 271 struct im_connection *ic = d; 262 263 if( ( ic->flags & OPT_PONGS ) && !( ic->flags & OPT_PONGED ) ) 264 { 272 273 if ((ic->flags & OPT_PONGS) && !(ic->flags & OPT_PONGED)) { 265 274 /* This protocol is expected to ack keepalives and hasn't 266 275 since the last time we were here. */ 267 imcb_error( ic, "Connection timeout");268 imc_logout( ic, TRUE);276 imcb_error(ic, "Connection timeout"); 277 imc_logout(ic, TRUE); 269 278 return FALSE; 270 279 } 271 280 ic->flags &= ~OPT_PONGED; 272 273 if( ic->acc->prpl->keepalive ) 274 ic->acc->prpl->keepalive( ic ); 275 281 282 if (ic->acc->prpl->keepalive) { 283 ic->acc->prpl->keepalive(ic); 284 } 285 276 286 return TRUE; 277 287 } 278 288 279 void start_keepalives( struct im_connection *ic, int interval)280 { 281 b_event_remove( ic->keepalive);282 ic->keepalive = b_timeout_add( interval, send_keepalive, ic);283 289 void start_keepalives(struct im_connection *ic, int interval) 290 { 291 b_event_remove(ic->keepalive); 292 ic->keepalive = b_timeout_add(interval, send_keepalive, ic); 293 284 294 /* Connecting successfully counts as a first successful pong. */ 285 if ( ic->flags & OPT_PONGS )295 if (ic->flags & OPT_PONGS) { 286 296 ic->flags |= OPT_PONGED; 287 } 288 289 void imcb_connected( struct im_connection *ic ) 297 } 298 } 299 300 void imcb_connected(struct im_connection *ic) 290 301 { 291 302 /* MSN servers sometimes redirect you to a different server and do 292 303 the whole login sequence again, so these "late" calls to this 293 304 function should be handled correctly. (IOW, ignored) */ 294 if ( ic->flags & OPT_LOGGED_IN )305 if (ic->flags & OPT_LOGGED_IN) { 295 306 return; 296 297 if( ic->acc->flags & ACC_FLAG_LOCAL ) 298 {307 } 308 309 if (ic->acc->flags & ACC_FLAG_LOCAL) { 299 310 GHashTableIter nicks; 300 311 gpointer k, v; 301 g_hash_table_iter_init( &nicks, ic->acc->nicks ); 302 while( g_hash_table_iter_next( &nicks, &k, &v ) ) 303 { 304 ic->acc->prpl->add_buddy( ic, (char*) k, NULL ); 305 } 306 } 307 308 imcb_log( ic, "Logged in" ); 309 312 g_hash_table_iter_init(&nicks, ic->acc->nicks); 313 while (g_hash_table_iter_next(&nicks, &k, &v)) { 314 ic->acc->prpl->add_buddy(ic, (char *) k, NULL); 315 } 316 } 317 318 imcb_log(ic, "Logged in"); 319 310 320 ic->flags |= OPT_LOGGED_IN; 311 start_keepalives( ic, 60000);312 321 start_keepalives(ic, 60000); 322 313 323 /* Necessary to send initial presence status, even if we're not away. */ 314 imc_away_send_update( ic);315 324 imc_away_send_update(ic); 325 316 326 /* Apparently we're connected successfully, so reset the 317 327 exponential backoff timer. */ 318 328 ic->acc->auto_reconnect_delay = 0; 319 320 if( ic->bee->ui->imc_connected ) 321 ic->bee->ui->imc_connected( ic ); 322 } 323 324 gboolean auto_reconnect( gpointer data, gint fd, b_input_condition cond ) 329 330 if (ic->bee->ui->imc_connected) { 331 ic->bee->ui->imc_connected(ic); 332 } 333 } 334 335 gboolean auto_reconnect(gpointer data, gint fd, b_input_condition cond) 325 336 { 326 337 account_t *a = data; 327 338 328 339 a->reconnect = 0; 329 account_on( a->bee, a);330 331 return( FALSE );/* Only have to run the timeout once */332 } 333 334 void cancel_auto_reconnect( account_t *a)335 { 336 b_event_remove( a->reconnect);340 account_on(a->bee, a); 341 342 return(FALSE); /* Only have to run the timeout once */ 343 } 344 345 void cancel_auto_reconnect(account_t *a) 346 { 347 b_event_remove(a->reconnect); 337 348 a->reconnect = 0; 338 349 } 339 350 340 void imc_logout( struct im_connection *ic, int allow_reconnect)351 void imc_logout(struct im_connection *ic, int allow_reconnect) 341 352 { 342 353 bee_t *bee = ic->bee; … … 344 355 GSList *l; 345 356 int delay; 346 357 347 358 /* Nested calls might happen sometimes, this is probably the best 348 359 place to catch them. */ 349 if ( ic->flags & OPT_LOGGING_OUT )360 if (ic->flags & OPT_LOGGING_OUT) { 350 361 return; 351 else362 } else { 352 363 ic->flags |= OPT_LOGGING_OUT; 353 354 if( ic->bee->ui->imc_disconnected ) 355 ic->bee->ui->imc_disconnected( ic ); 356 357 imcb_log( ic, "Signing off.." ); 358 364 } 365 366 if (ic->bee->ui->imc_disconnected) { 367 ic->bee->ui->imc_disconnected(ic); 368 } 369 370 imcb_log(ic, "Signing off.."); 371 359 372 /* TBH I don't remember anymore why I didn't just use ic->acc... */ 360 for ( a = bee->accounts; a; a = a->next )361 if ( a->ic == ic )373 for (a = bee->accounts; a; a = a->next) { 374 if (a->ic == ic) { 362 375 break; 363 364 if( a && !allow_reconnect && !( ic->flags & OPT_LOGGED_IN ) && 365 set_getbool( &a->set, "oauth" ) ) 366 { 376 } 377 } 378 379 if (a && !allow_reconnect && !(ic->flags & OPT_LOGGED_IN) && 380 set_getbool(&a->set, "oauth")) { 367 381 /* If this account supports OAuth, we're not logged in yet and 368 382 not allowed to retry, assume there were auth issues. Give a 369 383 helpful message on what might be necessary to fix this. */ 370 imcb_log( ic, "If you're having problems logging in, try re-requesting " 371 "an OAuth token: account %s set password \"\"", a->tag ); 372 } 373 374 for( l = bee->users; l; ) 375 { 384 imcb_log(ic, "If you're having problems logging in, try re-requesting " 385 "an OAuth token: account %s set password \"\"", a->tag); 386 } 387 388 for (l = bee->users; l; ) { 376 389 bee_user_t *bu = l->data; 377 390 GSList *next = l->next; 378 379 if( bu->ic == ic ) 380 bee_user_free( bee, bu ); 381 391 392 if (bu->ic == ic) { 393 bee_user_free(bee, bu); 394 } 395 382 396 l = next; 383 397 } 384 385 b_event_remove( ic->keepalive);398 399 b_event_remove(ic->keepalive); 386 400 ic->keepalive = 0; 387 ic->acc->prpl->logout( ic);388 b_event_remove( ic->inpa);389 390 g_free( ic->away);401 ic->acc->prpl->logout(ic); 402 b_event_remove(ic->inpa); 403 404 g_free(ic->away); 391 405 ic->away = NULL; 392 393 query_del_by_conn( (irc_t*) ic->bee->ui_data, ic ); 394 395 if( !a ) 396 { 406 407 query_del_by_conn((irc_t *) ic->bee->ui_data, ic); 408 409 if (!a) { 397 410 /* Uhm... This is very sick. */ 398 } 399 else if( allow_reconnect && set_getbool( &bee->set, "auto_reconnect" ) && 400 set_getbool( &a->set, "auto_reconnect" ) && 401 ( delay = account_reconnect_delay( a ) ) > 0 ) 402 { 403 imcb_log( ic, "Reconnecting in %d seconds..", delay ); 404 a->reconnect = b_timeout_add( delay * 1000, auto_reconnect, a ); 405 } 406 407 imc_free( ic ); 408 } 409 410 void imcb_ask( struct im_connection *ic, char *msg, void *data, 411 query_callback doit, query_callback dont ) 412 { 413 query_add( (irc_t *) ic->bee->ui_data, ic, msg, doit, dont, g_free, data ); 414 } 415 416 void imcb_ask_with_free( struct im_connection *ic, char *msg, void *data, 417 query_callback doit, query_callback dont, query_callback myfree ) 418 { 419 query_add( (irc_t *) ic->bee->ui_data, ic, msg, doit, dont, myfree, data ); 420 } 421 422 void imcb_add_buddy( struct im_connection *ic, const char *handle, const char *group ) 411 } else if (allow_reconnect && set_getbool(&bee->set, "auto_reconnect") && 412 set_getbool(&a->set, "auto_reconnect") && 413 (delay = account_reconnect_delay(a)) > 0) { 414 imcb_log(ic, "Reconnecting in %d seconds..", delay); 415 a->reconnect = b_timeout_add(delay * 1000, auto_reconnect, a); 416 } 417 418 imc_free(ic); 419 } 420 421 void imcb_ask(struct im_connection *ic, char *msg, void *data, 422 query_callback doit, query_callback dont) 423 { 424 query_add((irc_t *) ic->bee->ui_data, ic, msg, doit, dont, g_free, data); 425 } 426 427 void imcb_ask_with_free(struct im_connection *ic, char *msg, void *data, 428 query_callback doit, query_callback dont, query_callback myfree) 429 { 430 query_add((irc_t *) ic->bee->ui_data, ic, msg, doit, dont, myfree, data); 431 } 432 433 void imcb_add_buddy(struct im_connection *ic, const char *handle, const char *group) 423 434 { 424 435 bee_user_t *bu; 425 436 bee_t *bee = ic->bee; 426 437 bee_group_t *oldg; 427 428 if( !( bu = bee_user_by_handle( bee, ic, handle ) ) ) 429 bu = bee_user_new( bee, ic, handle, 0 ); 430 438 439 if (!(bu = bee_user_by_handle(bee, ic, handle))) { 440 bu = bee_user_new(bee, ic, handle, 0); 441 } 442 431 443 oldg = bu->group; 432 bu->group = bee_group_by_name( bee, group, TRUE ); 433 434 if( bee->ui->user_group && bu->group != oldg ) 435 bee->ui->user_group( bee, bu ); 436 } 437 438 void imcb_rename_buddy( struct im_connection *ic, const char *handle, const char *fullname ) 444 bu->group = bee_group_by_name(bee, group, TRUE); 445 446 if (bee->ui->user_group && bu->group != oldg) { 447 bee->ui->user_group(bee, bu); 448 } 449 } 450 451 void imcb_rename_buddy(struct im_connection *ic, const char *handle, const char *fullname) 439 452 { 440 453 bee_t *bee = ic->bee; 441 bee_user_t *bu = bee_user_by_handle( bee, ic, handle ); 442 443 if( !bu || !fullname ) return; 444 445 if( !bu->fullname || strcmp( bu->fullname, fullname ) != 0 ) 446 { 447 g_free( bu->fullname ); 448 bu->fullname = g_strdup( fullname ); 449 450 if( bee->ui->user_fullname ) 451 bee->ui->user_fullname( bee, bu ); 452 } 453 } 454 455 void imcb_remove_buddy( struct im_connection *ic, const char *handle, char *group ) 456 { 457 bee_user_free( ic->bee, bee_user_by_handle( ic->bee, ic, handle ) ); 454 bee_user_t *bu = bee_user_by_handle(bee, ic, handle); 455 456 if (!bu || !fullname) { 457 return; 458 } 459 460 if (!bu->fullname || strcmp(bu->fullname, fullname) != 0) { 461 g_free(bu->fullname); 462 bu->fullname = g_strdup(fullname); 463 464 if (bee->ui->user_fullname) { 465 bee->ui->user_fullname(bee, bu); 466 } 467 } 468 } 469 470 void imcb_remove_buddy(struct im_connection *ic, const char *handle, char *group) 471 { 472 bee_user_free(ic->bee, bee_user_by_handle(ic->bee, ic, handle)); 458 473 } 459 474 460 475 /* Mainly meant for ICQ (and now also for Jabber conferences) to allow IM 461 476 modules to suggest a nickname for a handle. */ 462 void imcb_buddy_nick_hint( struct im_connection *ic, const char *handle, const char *nick)477 void imcb_buddy_nick_hint(struct im_connection *ic, const char *handle, const char *nick) 463 478 { 464 479 bee_t *bee = ic->bee; 465 bee_user_t *bu = bee_user_by_handle( bee, ic, handle ); 466 467 if( !bu || !nick ) return; 468 469 g_free( bu->nick ); 470 bu->nick = g_strdup( nick ); 471 472 if( bee->ui->user_nick_hint ) 473 bee->ui->user_nick_hint( bee, bu, nick ); 474 } 475 476 477 struct imcb_ask_cb_data 478 { 480 bee_user_t *bu = bee_user_by_handle(bee, ic, handle); 481 482 if (!bu || !nick) { 483 return; 484 } 485 486 g_free(bu->nick); 487 bu->nick = g_strdup(nick); 488 489 if (bee->ui->user_nick_hint) { 490 bee->ui->user_nick_hint(bee, bu, nick); 491 } 492 } 493 494 495 struct imcb_ask_cb_data { 479 496 struct im_connection *ic; 480 497 char *handle; 481 498 }; 482 499 483 static void imcb_ask_auth_cb_no( void *data)500 static void imcb_ask_auth_cb_no(void *data) 484 501 { 485 502 struct imcb_ask_cb_data *cbd = data; 486 487 cbd->ic->acc->prpl->auth_deny( cbd->ic, cbd->handle);488 489 g_free( cbd->handle);490 g_free( cbd);491 } 492 493 static void imcb_ask_auth_cb_yes( void *data)503 504 cbd->ic->acc->prpl->auth_deny(cbd->ic, cbd->handle); 505 506 g_free(cbd->handle); 507 g_free(cbd); 508 } 509 510 static void imcb_ask_auth_cb_yes(void *data) 494 511 { 495 512 struct imcb_ask_cb_data *cbd = data; 496 497 cbd->ic->acc->prpl->auth_allow( cbd->ic, cbd->handle);498 499 g_free( cbd->handle);500 g_free( cbd);501 } 502 503 void imcb_ask_auth( struct im_connection *ic, const char *handle, const char *realname)504 { 505 struct imcb_ask_cb_data *data = g_new0( struct imcb_ask_cb_data, 1);513 514 cbd->ic->acc->prpl->auth_allow(cbd->ic, cbd->handle); 515 516 g_free(cbd->handle); 517 g_free(cbd); 518 } 519 520 void imcb_ask_auth(struct im_connection *ic, const char *handle, const char *realname) 521 { 522 struct imcb_ask_cb_data *data = g_new0(struct imcb_ask_cb_data, 1); 506 523 char *s, *realname_ = NULL; 507 508 if( realname != NULL ) 509 realname_ = g_strdup_printf( " (%s)", realname ); 510 511 s = g_strdup_printf( "The user %s%s wants to add you to his/her buddy list.", 512 handle, realname_ ? realname_ : "" ); 513 514 g_free( realname_ ); 515 524 525 if (realname != NULL) { 526 realname_ = g_strdup_printf(" (%s)", realname); 527 } 528 529 s = g_strdup_printf("The user %s%s wants to add you to his/her buddy list.", 530 handle, realname_ ? realname_ : ""); 531 532 g_free(realname_); 533 516 534 data->ic = ic; 517 data->handle = g_strdup( handle);518 query_add( 519 imcb_ask_auth_cb_yes, imcb_ask_auth_cb_no, g_free, data);520 } 521 522 523 static void imcb_ask_add_cb_no( void *data)524 { 525 g_free( ((struct imcb_ask_cb_data*)data)->handle);526 g_free( data);527 } 528 529 static void imcb_ask_add_cb_yes( void *data)535 data->handle = g_strdup(handle); 536 query_add((irc_t *) ic->bee->ui_data, ic, s, 537 imcb_ask_auth_cb_yes, imcb_ask_auth_cb_no, g_free, data); 538 } 539 540 541 static void imcb_ask_add_cb_no(void *data) 542 { 543 g_free(((struct imcb_ask_cb_data*) data)->handle); 544 g_free(data); 545 } 546 547 static void imcb_ask_add_cb_yes(void *data) 530 548 { 531 549 struct imcb_ask_cb_data *cbd = data; 532 533 cbd->ic->acc->prpl->add_buddy( cbd->ic, cbd->handle, NULL);534 535 imcb_ask_add_cb_no( data);536 } 537 538 void imcb_ask_add( struct im_connection *ic, const char *handle, const char *realname)539 { 540 struct imcb_ask_cb_data *data = g_new0( struct imcb_ask_cb_data, 1);550 551 cbd->ic->acc->prpl->add_buddy(cbd->ic, cbd->handle, NULL); 552 553 imcb_ask_add_cb_no(data); 554 } 555 556 void imcb_ask_add(struct im_connection *ic, const char *handle, const char *realname) 557 { 558 struct imcb_ask_cb_data *data = g_new0(struct imcb_ask_cb_data, 1); 541 559 char *s; 542 560 543 561 /* TODO: Make a setting for this! */ 544 if ( bee_user_by_handle( ic->bee, ic, handle ) != NULL )562 if (bee_user_by_handle(ic->bee, ic, handle) != NULL) { 545 563 return; 546 547 s = g_strdup_printf( "The user %s is not in your buddy list yet. Do you want to add him/her now?", handle ); 548 564 } 565 566 s = g_strdup_printf("The user %s is not in your buddy list yet. Do you want to add him/her now?", handle); 567 549 568 data->ic = ic; 550 data->handle = g_strdup( handle);551 query_add( 552 imcb_ask_add_cb_yes, imcb_ask_add_cb_no, g_free, data);553 } 554 555 struct bee_user *imcb_buddy_by_handle( struct im_connection *ic, const char *handle)556 { 557 return bee_user_by_handle( ic->bee, ic, handle);569 data->handle = g_strdup(handle); 570 query_add((irc_t *) ic->bee->ui_data, ic, s, 571 imcb_ask_add_cb_yes, imcb_ask_add_cb_no, g_free, data); 572 } 573 574 struct bee_user *imcb_buddy_by_handle(struct im_connection *ic, const char *handle) 575 { 576 return bee_user_by_handle(ic->bee, ic, handle); 558 577 } 559 578 … … 561 580 them all from some wrappers. We'll start to define some down here: */ 562 581 563 int imc_chat_msg( struct groupchat *c, char *msg, int flags)582 int imc_chat_msg(struct groupchat *c, char *msg, int flags) 564 583 { 565 584 char *buf = NULL; 566 567 if( ( c->ic->flags & OPT_DOES_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) ) 568 { 569 buf = escape_html( msg ); 585 586 if ((c->ic->flags & OPT_DOES_HTML) && (g_strncasecmp(msg, "<html>", 6) != 0)) { 587 buf = escape_html(msg); 570 588 msg = buf; 571 589 } 572 573 c->ic->acc->prpl->chat_msg( c, msg, flags);574 g_free( buf);575 590 591 c->ic->acc->prpl->chat_msg(c, msg, flags); 592 g_free(buf); 593 576 594 return 1; 577 595 } 578 596 579 static char *imc_away_state_find( GList *gcm, char *away, char **message);580 581 int imc_away_send_update( struct im_connection *ic)597 static char *imc_away_state_find(GList *gcm, char *away, char **message); 598 599 int imc_away_send_update(struct im_connection *ic) 582 600 { 583 601 char *away, *msg = NULL; 584 585 if (ic->acc->prpl->away_states == NULL ||586 ic->acc->prpl->set_away == NULL )602 603 if (ic->acc->prpl->away_states == NULL || 604 ic->acc->prpl->set_away == NULL) { 587 605 return 0; 588 589 away = set_getstr( &ic->acc->set, "away" ) ? 590 : set_getstr( &ic->bee->set, "away" );591 if( away && *away )592 {593 GList *m = ic->acc->prpl->away_states( ic);606 } 607 608 away = set_getstr(&ic->acc->set, "away") ? 609 : set_getstr(&ic->bee->set, "away"); 610 if (away && *away) { 611 GList *m = ic->acc->prpl->away_states(ic); 594 612 msg = ic->acc->flags & ACC_FLAG_AWAY_MESSAGE ? away : NULL; 595 away = imc_away_state_find( m, away, &msg ) ? : m->data; 596 } 597 else if( ic->acc->flags & ACC_FLAG_STATUS_MESSAGE ) 598 { 613 away = imc_away_state_find(m, away, &msg) ? : m->data; 614 } else if (ic->acc->flags & ACC_FLAG_STATUS_MESSAGE) { 599 615 away = NULL; 600 msg = set_getstr( &ic->acc->set, "status") ?601 : set_getstr( &ic->bee->set, "status");602 } 603 604 ic->acc->prpl->set_away( ic, away, msg);605 616 msg = set_getstr(&ic->acc->set, "status") ? 617 : set_getstr(&ic->bee->set, "status"); 618 } 619 620 ic->acc->prpl->set_away(ic, away, msg); 621 606 622 return 1; 607 623 } … … 619 635 }; 620 636 621 static char *imc_away_state_find( GList *gcm, char *away, char **message)637 static char *imc_away_state_find(GList *gcm, char *away, char **message) 622 638 { 623 639 GList *m; 624 640 int i, j; 625 626 for( m = gcm; m; m = m->next ) 627 if( g_strncasecmp( m->data, away, strlen( m->data ) ) == 0 ) 628 { 641 642 for (m = gcm; m; m = m->next) { 643 if (g_strncasecmp(m->data, away, strlen(m->data)) == 0) { 629 644 /* At least the Yahoo! module works better if message 630 645 contains no data unless it adds something to what 631 646 we have in state already. */ 632 if ( strlen( m->data ) == strlen( away ) )647 if (strlen(m->data) == strlen(away)) { 633 648 *message = NULL; 634 649 } 650 635 651 return m->data; 636 652 } 637 638 for( i = 0; *imc_away_alias_list[i]; i ++ ) 639 {653 } 654 655 for (i = 0; *imc_away_alias_list[i]; i++) { 640 656 int keep_message; 641 642 for( j = 0; imc_away_alias_list[i][j]; j ++ ) 643 if( g_strncasecmp( away, imc_away_alias_list[i][j], strlen( imc_away_alias_list[i][j] ) ) == 0 ) 644 { 645 keep_message = strlen( away ) != strlen( imc_away_alias_list[i][j] ); 657 658 for (j = 0; imc_away_alias_list[i][j]; j++) { 659 if (g_strncasecmp(away, imc_away_alias_list[i][j], strlen(imc_away_alias_list[i][j])) == 0) { 660 keep_message = strlen(away) != strlen(imc_away_alias_list[i][j]); 646 661 break; 647 662 } 648 649 if( !imc_away_alias_list[i][j] ) /* If we reach the end, this row */ 650 continue; /* is not what we want. Next! */ 651 663 } 664 665 if (!imc_away_alias_list[i][j]) { /* If we reach the end, this row */ 666 continue; /* is not what we want. Next! */ 667 668 } 652 669 /* Now find an entry in this row which exists in gcm */ 653 for( j = 0; imc_away_alias_list[i][j]; j ++ ) 654 { 655 for( m = gcm; m; m = m->next ) 656 if( g_strcasecmp( imc_away_alias_list[i][j], m->data ) == 0 ) 657 { 658 if( !keep_message ) 670 for (j = 0; imc_away_alias_list[i][j]; j++) { 671 for (m = gcm; m; m = m->next) { 672 if (g_strcasecmp(imc_away_alias_list[i][j], m->data) == 0) { 673 if (!keep_message) { 659 674 *message = NULL; 660 675 } 676 661 677 return imc_away_alias_list[i][j]; 662 678 } 663 } 664 679 } 680 } 681 665 682 /* No need to look further, apparently this state doesn't 666 683 have any good alias for this protocol. */ 667 684 break; 668 685 } 669 686 670 687 return NULL; 671 688 } 672 689 673 void imc_add_allow( struct im_connection *ic, char *handle ) 674 { 675 if( g_slist_find_custom( ic->permit, handle, (GCompareFunc) ic->acc->prpl->handle_cmp ) == NULL ) 676 { 677 ic->permit = g_slist_prepend( ic->permit, g_strdup( handle ) ); 678 } 679 680 ic->acc->prpl->add_permit( ic, handle ); 681 } 682 683 void imc_rem_allow( struct im_connection *ic, char *handle ) 690 void imc_add_allow(struct im_connection *ic, char *handle) 691 { 692 if (g_slist_find_custom(ic->permit, handle, (GCompareFunc) ic->acc->prpl->handle_cmp) == NULL) { 693 ic->permit = g_slist_prepend(ic->permit, g_strdup(handle)); 694 } 695 696 ic->acc->prpl->add_permit(ic, handle); 697 } 698 699 void imc_rem_allow(struct im_connection *ic, char *handle) 684 700 { 685 701 GSList *l; 686 687 if( ( l = g_slist_find_custom( ic->permit, handle, (GCompareFunc) ic->acc->prpl->handle_cmp ) ) ) 688 { 689 g_free( l->data ); 690 ic->permit = g_slist_delete_link( ic->permit, l ); 691 } 692 693 ic->acc->prpl->rem_permit( ic, handle ); 694 } 695 696 void imc_add_block( struct im_connection *ic, char *handle ) 697 { 698 if( g_slist_find_custom( ic->deny, handle, (GCompareFunc) ic->acc->prpl->handle_cmp ) == NULL ) 699 { 700 ic->deny = g_slist_prepend( ic->deny, g_strdup( handle ) ); 701 } 702 703 ic->acc->prpl->add_deny( ic, handle ); 704 } 705 706 void imc_rem_block( struct im_connection *ic, char *handle ) 702 703 if ((l = g_slist_find_custom(ic->permit, handle, (GCompareFunc) ic->acc->prpl->handle_cmp))) { 704 g_free(l->data); 705 ic->permit = g_slist_delete_link(ic->permit, l); 706 } 707 708 ic->acc->prpl->rem_permit(ic, handle); 709 } 710 711 void imc_add_block(struct im_connection *ic, char *handle) 712 { 713 if (g_slist_find_custom(ic->deny, handle, (GCompareFunc) ic->acc->prpl->handle_cmp) == NULL) { 714 ic->deny = g_slist_prepend(ic->deny, g_strdup(handle)); 715 } 716 717 ic->acc->prpl->add_deny(ic, handle); 718 } 719 720 void imc_rem_block(struct im_connection *ic, char *handle) 707 721 { 708 722 GSList *l; 709 710 if( ( l = g_slist_find_custom( ic->deny, handle, (GCompareFunc) ic->acc->prpl->handle_cmp ) ) ) 711 { 712 g_free( l->data ); 713 ic->deny = g_slist_delete_link( ic->deny, l ); 714 } 715 716 ic->acc->prpl->rem_deny( ic, handle ); 717 } 718 719 void imcb_clean_handle( struct im_connection *ic, char *handle ) 723 724 if ((l = g_slist_find_custom(ic->deny, handle, (GCompareFunc) ic->acc->prpl->handle_cmp))) { 725 g_free(l->data); 726 ic->deny = g_slist_delete_link(ic->deny, l); 727 } 728 729 ic->acc->prpl->rem_deny(ic, handle); 730 } 731 732 void imcb_clean_handle(struct im_connection *ic, char *handle) 720 733 { 721 734 /* Accepts a handle and does whatever is necessary to make it … … 723 736 outside 33-127 (ASCII printable excl spaces), @ (only one 724 737 is allowed) and ! and : */ 725 char out[strlen(handle) +1];738 char out[strlen(handle) + 1]; 726 739 int s, d; 727 740 728 741 s = d = 0; 729 while( handle[s] ) 730 { 731 if( handle[s] > ' ' && handle[s] != '!' && handle[s] != ':' && 732 ( handle[s] & 0x80 ) == 0 ) 733 { 734 if( handle[s] == '@' ) 735 { 742 while (handle[s]) { 743 if (handle[s] > ' ' && handle[s] != '!' && handle[s] != ':' && 744 (handle[s] & 0x80) == 0) { 745 if (handle[s] == '@') { 736 746 /* See if we got an @ already? */ 737 747 out[d] = 0; 738 if ( strchr( out, '@' ) )748 if (strchr(out, '@')) { 739 749 continue; 750 } 740 751 } 741 752 742 753 out[d++] = handle[s]; 743 754 } 744 s 755 s++; 745 756 } 746 757 out[d] = handle[s]; 747 748 strcpy( handle, out);749 } 758 759 strcpy(handle, out); 760 }
Note: See TracChangeset
for help on using the changeset viewer.