Changeset 5ebff60 for protocols/purple/purple.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/purple/purple.c
raf359b4 r5ebff60 37 37 static bee_t *local_bee; 38 38 39 static char *set_eval_display_name( set_t *set, char *value);40 41 struct im_connection *purple_ic_by_pa( PurpleAccount *pa)39 static char *set_eval_display_name(set_t *set, char *value); 40 41 struct im_connection *purple_ic_by_pa(PurpleAccount *pa) 42 42 { 43 43 GSList *i; 44 45 for ( i = purple_connections; i; i = i->next )46 if ( ((struct im_connection *)i->data)->proto_data == pa )44 45 for (i = purple_connections; i; i = i->next) { 46 if (((struct im_connection *) i->data)->proto_data == pa) { 47 47 return i->data; 48 48 } 49 } 50 49 51 return NULL; 50 52 } 51 53 52 static struct im_connection *purple_ic_by_gc( PurpleConnection *gc ) 53 { 54 return purple_ic_by_pa( purple_connection_get_account( gc ) ); 55 } 56 57 static gboolean purple_menu_cmp( const char *a, const char *b ) 58 { 59 while( *a && *b ) 60 { 61 while( *a == '_' ) a ++; 62 while( *b == '_' ) b ++; 63 if( g_ascii_tolower( *a ) != g_ascii_tolower( *b ) ) 54 static struct im_connection *purple_ic_by_gc(PurpleConnection *gc) 55 { 56 return purple_ic_by_pa(purple_connection_get_account(gc)); 57 } 58 59 static gboolean purple_menu_cmp(const char *a, const char *b) 60 { 61 while (*a && *b) { 62 while (*a == '_') { 63 a++; 64 } 65 while (*b == '_') { 66 b++; 67 } 68 if (g_ascii_tolower(*a) != g_ascii_tolower(*b)) { 64 69 return FALSE; 65 66 a ++; 67 b ++; 68 } 69 70 return ( *a == '\0' && *b == '\0' ); 71 } 72 73 static void purple_init( account_t *acc ) 74 { 75 PurplePlugin *prpl = purple_plugins_find_with_id( (char*) acc->prpl->data ); 70 } 71 72 a++; 73 b++; 74 } 75 76 return (*a == '\0' && *b == '\0'); 77 } 78 79 static void purple_init(account_t *acc) 80 { 81 PurplePlugin *prpl = purple_plugins_find_with_id((char *) acc->prpl->data); 76 82 PurplePluginProtocolInfo *pi = prpl->info->extra_info; 77 83 PurpleAccount *pa; … … 81 87 GString *help; 82 88 static gboolean dir_fixed = FALSE; 83 89 84 90 /* Layer violation coming up: Making an exception for libpurple here. 85 91 Dig in the IRC state a bit to get a username. Ideally we should 86 92 check if s/he identified but this info doesn't seem *that* important. 87 93 It's just that fecking libpurple can't *not* store this shit. 88 94 89 95 Remember that libpurple is not really meant to be used on public 90 96 servers anyway! */ 91 if( !dir_fixed ) 92 { 97 if (!dir_fixed) { 93 98 irc_t *irc = acc->bee->ui_data; 94 99 char *dir; 95 96 dir = g_strdup_printf( "%s/purple/%s", global.conf->configdir, irc->user->nick);97 purple_util_set_user_dir( dir);98 g_free( dir);99 100 101 dir = g_strdup_printf("%s/purple/%s", global.conf->configdir, irc->user->nick); 102 purple_util_set_user_dir(dir); 103 g_free(dir); 104 100 105 purple_blist_load(); 101 106 purple_prefs_load(); 102 107 dir_fixed = TRUE; 103 108 } 104 105 help = g_string_new( "" ); 106 g_string_printf( help, "BitlBee libpurple module %s (%s).\n\nSupported settings:", 107 (char*) acc->prpl->name, prpl->info->name ); 108 109 if( pi->user_splits ) 110 { 109 110 help = g_string_new(""); 111 g_string_printf(help, "BitlBee libpurple module %s (%s).\n\nSupported settings:", 112 (char *) acc->prpl->name, prpl->info->name); 113 114 if (pi->user_splits) { 111 115 GList *l; 112 g_string_append_printf( help, "\n* username: Username" ); 113 for( l = pi->user_splits; l; l = l->next ) 114 g_string_append_printf( help, "%c%s", 115 purple_account_user_split_get_separator( l->data ), 116 purple_account_user_split_get_text( l->data ) ); 117 } 118 116 g_string_append_printf(help, "\n* username: Username"); 117 for (l = pi->user_splits; l; l = l->next) { 118 g_string_append_printf(help, "%c%s", 119 purple_account_user_split_get_separator(l->data), 120 purple_account_user_split_get_text(l->data)); 121 } 122 } 123 119 124 /* Convert all protocol_options into per-account setting variables. */ 120 for( i = pi->protocol_options; i; i = i->next ) 121 { 125 for (i = pi->protocol_options; i; i = i->next) { 122 126 PurpleAccountOption *o = i->data; 123 127 const char *name; … … 127 131 GList *io = NULL; 128 132 GSList *opts = NULL; 129 130 name = purple_account_option_get_setting( o ); 131 132 switch( purple_account_option_get_type( o ) ) 133 { 133 134 name = purple_account_option_get_setting(o); 135 136 switch (purple_account_option_get_type(o)) { 134 137 case PURPLE_PREF_STRING: 135 def = g_strdup( purple_account_option_get_default_string( o ));136 137 g_string_append_printf( 138 name, purple_account_option_get_text( o),139 "string", def);140 141 break; 142 138 def = g_strdup(purple_account_option_get_default_string(o)); 139 140 g_string_append_printf(help, "\n* %s (%s), %s, default: %s", 141 name, purple_account_option_get_text(o), 142 "string", def); 143 144 break; 145 143 146 case PURPLE_PREF_INT: 144 def = g_strdup_printf( "%d", purple_account_option_get_default_int( o ));147 def = g_strdup_printf("%d", purple_account_option_get_default_int(o)); 145 148 eval = set_eval_int; 146 147 g_string_append_printf( 148 name, purple_account_option_get_text( o),149 "integer", def);150 151 break; 152 149 150 g_string_append_printf(help, "\n* %s (%s), %s, default: %s", 151 name, purple_account_option_get_text(o), 152 "integer", def); 153 154 break; 155 153 156 case PURPLE_PREF_BOOLEAN: 154 if( purple_account_option_get_default_bool( o ) ) 155 def = g_strdup( "true" ); 156 else 157 def = g_strdup( "false" ); 157 if (purple_account_option_get_default_bool(o)) { 158 def = g_strdup("true"); 159 } else { 160 def = g_strdup("false"); 161 } 158 162 eval = set_eval_bool; 159 160 g_string_append_printf( 161 name, purple_account_option_get_text( o),162 "boolean", def);163 164 break; 165 163 164 g_string_append_printf(help, "\n* %s (%s), %s, default: %s", 165 name, purple_account_option_get_text(o), 166 "boolean", def); 167 168 break; 169 166 170 case PURPLE_PREF_STRING_LIST: 167 def = g_strdup( purple_account_option_get_default_list_value( o ) ); 168 169 g_string_append_printf( help, "\n* %s (%s), %s, default: %s", 170 name, purple_account_option_get_text( o ), 171 "list", def ); 172 g_string_append( help, "\n Possible values: " ); 173 174 for( io = purple_account_option_get_list( o ); io; io = io->next ) 175 { 171 def = g_strdup(purple_account_option_get_default_list_value(o)); 172 173 g_string_append_printf(help, "\n* %s (%s), %s, default: %s", 174 name, purple_account_option_get_text(o), 175 "list", def); 176 g_string_append(help, "\n Possible values: "); 177 178 for (io = purple_account_option_get_list(o); io; io = io->next) { 176 179 PurpleKeyValuePair *kv = io->data; 177 opts = g_slist_append( opts, kv->value);180 opts = g_slist_append(opts, kv->value); 178 181 /* TODO: kv->value is not a char*, WTF? */ 179 if( strcmp( kv->value, kv->key ) != 0 ) 180 g_string_append_printf( help, "%s (%s), ", (char*) kv->value, kv->key ); 181 else 182 g_string_append_printf( help, "%s, ", (char*) kv->value ); 182 if (strcmp(kv->value, kv->key) != 0) { 183 g_string_append_printf(help, "%s (%s), ", (char *) kv->value, kv->key); 184 } else { 185 g_string_append_printf(help, "%s, ", (char *) kv->value); 186 } 183 187 } 184 g_string_truncate( help, help->len - 2);188 g_string_truncate(help, help->len - 2); 185 189 eval = set_eval_list; 186 190 eval_data = opts; 187 188 break; 189 191 192 break; 193 190 194 default: 191 195 /** No way to talk to the user right now, invent one when … … 194 198 name, purple_account_option_get_type( o ) ); 195 199 */ 196 g_string_append_printf( 197 name, purple_account_option_get_type( o ));200 g_string_append_printf(help, "\n* [%s] UNSUPPORTED (type %d)", 201 name, purple_account_option_get_type(o)); 198 202 name = NULL; 199 203 } 200 201 if( name != NULL ) 202 { 203 s = set_add( &acc->set, name, def, eval, acc ); 204 205 if (name != NULL) { 206 s = set_add(&acc->set, name, def, eval, acc); 204 207 s->flags |= ACC_SET_OFFLINE_ONLY; 205 208 s->eval_data = eval_data; 206 g_free( def);207 } 208 } 209 210 g_snprintf( help_title, sizeof( help_title ), "purple %s", (char*) acc->prpl->name);211 help_add_mem( &global.help, help_title, help->str);212 g_string_free( help, TRUE);213 214 s = set_add( &acc->set, "display_name", NULL, set_eval_display_name, acc);209 g_free(def); 210 } 211 } 212 213 g_snprintf(help_title, sizeof(help_title), "purple %s", (char *) acc->prpl->name); 214 help_add_mem(&global.help, help_title, help->str); 215 g_string_free(help, TRUE); 216 217 s = set_add(&acc->set, "display_name", NULL, set_eval_display_name, acc); 215 218 s->flags |= ACC_SET_ONLINE_ONLY; 216 217 if( pi->options & OPT_PROTO_MAIL_CHECK ) 218 { 219 s = set_add( &acc->set, "mail_notifications", "false", set_eval_bool, acc ); 219 220 if (pi->options & OPT_PROTO_MAIL_CHECK) { 221 s = set_add(&acc->set, "mail_notifications", "false", set_eval_bool, acc); 220 222 s->flags |= ACC_SET_OFFLINE_ONLY; 221 223 } 222 223 if( strcmp( prpl->info->name, "Gadu-Gadu" ) == 0 ) 224 s = set_add( &acc->set, "gg_sync_contacts", "true", set_eval_bool, acc ); 225 224 225 if (strcmp(prpl->info->name, "Gadu-Gadu") == 0) { 226 s = set_add(&acc->set, "gg_sync_contacts", "true", set_eval_bool, acc); 227 } 228 226 229 /* Go through all away states to figure out if away/status messages 227 230 are possible. */ 228 pa = purple_account_new( acc->user, (char*) acc->prpl->data ); 229 for( st = purple_account_get_status_types( pa ); st; st = st->next ) 230 { 231 PurpleStatusPrimitive prim = purple_status_type_get_primitive( st->data ); 232 233 if( prim == PURPLE_STATUS_AVAILABLE ) 234 { 235 if( purple_status_type_get_attr( st->data, "message" ) ) 231 pa = purple_account_new(acc->user, (char *) acc->prpl->data); 232 for (st = purple_account_get_status_types(pa); st; st = st->next) { 233 PurpleStatusPrimitive prim = purple_status_type_get_primitive(st->data); 234 235 if (prim == PURPLE_STATUS_AVAILABLE) { 236 if (purple_status_type_get_attr(st->data, "message")) { 236 237 acc->flags |= ACC_FLAG_STATUS_MESSAGE; 237 } 238 else if( prim != PURPLE_STATUS_OFFLINE ) 239 { 240 if( purple_status_type_get_attr( st->data, "message" ) ) 238 } 239 } else if (prim != PURPLE_STATUS_OFFLINE) { 240 if (purple_status_type_get_attr(st->data, "message")) { 241 241 acc->flags |= ACC_FLAG_AWAY_MESSAGE; 242 } 243 } 244 purple_accounts_remove( pa ); 245 } 246 247 static void purple_sync_settings( account_t *acc, PurpleAccount *pa ) 248 { 249 PurplePlugin *prpl = purple_plugins_find_with_id( pa->protocol_id ); 242 } 243 } 244 } 245 purple_accounts_remove(pa); 246 } 247 248 static void purple_sync_settings(account_t *acc, PurpleAccount *pa) 249 { 250 PurplePlugin *prpl = purple_plugins_find_with_id(pa->protocol_id); 250 251 PurplePluginProtocolInfo *pi = prpl->info->extra_info; 251 252 GList *i; 252 253 for( i = pi->protocol_options; i; i = i->next ) 254 { 253 254 for (i = pi->protocol_options; i; i = i->next) { 255 255 PurpleAccountOption *o = i->data; 256 256 const char *name; 257 257 set_t *s; 258 259 name = purple_account_option_get_setting( o);260 s = set_find( &acc->set, name);261 if ( s->value == NULL )258 259 name = purple_account_option_get_setting(o); 260 s = set_find(&acc->set, name); 261 if (s->value == NULL) { 262 262 continue; 263 264 switch( purple_account_option_get_type( o ) ) 265 {263 } 264 265 switch (purple_account_option_get_type(o)) { 266 266 case PURPLE_PREF_STRING: 267 267 case PURPLE_PREF_STRING_LIST: 268 purple_account_set_string( pa, name, set_getstr( &acc->set, name ));269 break; 270 268 purple_account_set_string(pa, name, set_getstr(&acc->set, name)); 269 break; 270 271 271 case PURPLE_PREF_INT: 272 purple_account_set_int( pa, name, set_getint( &acc->set, name ));273 break; 274 272 purple_account_set_int(pa, name, set_getint(&acc->set, name)); 273 break; 274 275 275 case PURPLE_PREF_BOOLEAN: 276 purple_account_set_bool( pa, name, set_getbool( &acc->set, name ));277 break; 278 276 purple_account_set_bool(pa, name, set_getbool(&acc->set, name)); 277 break; 278 279 279 default: 280 280 break; 281 281 } 282 282 } 283 284 if( pi->options & OPT_PROTO_MAIL_CHECK ) 285 purple_account_set_check_mail( pa, set_getbool( &acc->set, "mail_notifications" ) ); 286 } 287 288 static void purple_login( account_t *acc ) 289 { 290 struct im_connection *ic = imcb_new( acc ); 283 284 if (pi->options & OPT_PROTO_MAIL_CHECK) { 285 purple_account_set_check_mail(pa, set_getbool(&acc->set, "mail_notifications")); 286 } 287 } 288 289 static void purple_login(account_t *acc) 290 { 291 struct im_connection *ic = imcb_new(acc); 291 292 PurpleAccount *pa; 292 293 if( ( local_bee != NULL && local_bee != acc->bee ) || 294 ( global.conf->runmode == RUNMODE_DAEMON && !getenv( "BITLBEE_DEBUG" ) ) ) 295 { 296 imcb_error( ic, "Daemon mode detected. Do *not* try to use libpurple in daemon mode! " 297 "Please use inetd or ForkDaemon mode instead." ); 298 imc_logout( ic, FALSE ); 293 294 if ((local_bee != NULL && local_bee != acc->bee) || 295 (global.conf->runmode == RUNMODE_DAEMON && !getenv("BITLBEE_DEBUG"))) { 296 imcb_error(ic, "Daemon mode detected. Do *not* try to use libpurple in daemon mode! " 297 "Please use inetd or ForkDaemon mode instead."); 298 imc_logout(ic, FALSE); 299 299 return; 300 300 } 301 301 local_bee = acc->bee; 302 302 303 303 /* For now this is needed in the _connected() handlers if using 304 304 GLib event handling, to make sure we're not handling events 305 305 on dead connections. */ 306 purple_connections = g_slist_prepend( purple_connections, ic);307 308 ic->proto_data = pa = purple_account_new( acc->user, (char*) acc->prpl->data);309 purple_account_set_password( pa, acc->pass);310 purple_sync_settings( acc, pa);311 312 purple_account_set_enabled( pa, "BitlBee", TRUE);313 } 314 315 static void purple_logout( struct im_connection *ic)306 purple_connections = g_slist_prepend(purple_connections, ic); 307 308 ic->proto_data = pa = purple_account_new(acc->user, (char *) acc->prpl->data); 309 purple_account_set_password(pa, acc->pass); 310 purple_sync_settings(acc, pa); 311 312 purple_account_set_enabled(pa, "BitlBee", TRUE); 313 } 314 315 static void purple_logout(struct im_connection *ic) 316 316 { 317 317 PurpleAccount *pa = ic->proto_data; 318 319 purple_account_set_enabled( pa, "BitlBee", FALSE);320 purple_connections = g_slist_remove( purple_connections, ic);321 purple_accounts_remove( pa);322 } 323 324 static int purple_buddy_msg( struct im_connection *ic, char *who, char *message, int flags)318 319 purple_account_set_enabled(pa, "BitlBee", FALSE); 320 purple_connections = g_slist_remove(purple_connections, ic); 321 purple_accounts_remove(pa); 322 } 323 324 static int purple_buddy_msg(struct im_connection *ic, char *who, char *message, int flags) 325 325 { 326 326 PurpleConversation *conv; 327 328 if( ( conv = purple_find_conversation_with_account( PURPLE_CONV_TYPE_IM, 329 who, ic->proto_data ) ) == NULL ) 330 { 331 conv = purple_conversation_new( PURPLE_CONV_TYPE_IM, 332 ic->proto_data, who ); 333 } 334 335 purple_conv_im_send( purple_conversation_get_im_data( conv ), message ); 336 327 328 if ((conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, 329 who, ic->proto_data)) == NULL) { 330 conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, 331 ic->proto_data, who); 332 } 333 334 purple_conv_im_send(purple_conversation_get_im_data(conv), message); 335 337 336 return 1; 338 337 } 339 338 340 static GList *purple_away_states( struct im_connection *ic)339 static GList *purple_away_states(struct im_connection *ic) 341 340 { 342 341 PurpleAccount *pa = ic->proto_data; 343 342 GList *st, *ret = NULL; 344 345 for ( st = purple_account_get_status_types( pa ); st; st = st->next )346 {347 PurpleStatusPrimitive prim = purple_status_type_get_primitive( st->data );348 if( prim != PURPLE_STATUS_AVAILABLE && prim != PURPLE_STATUS_OFFLINE )349 ret = g_list_append( ret, (void*) purple_status_type_get_name( st->data ) );350 } 351 343 344 for (st = purple_account_get_status_types(pa); st; st = st->next) { 345 PurpleStatusPrimitive prim = purple_status_type_get_primitive(st->data); 346 if (prim != PURPLE_STATUS_AVAILABLE && prim != PURPLE_STATUS_OFFLINE) { 347 ret = g_list_append(ret, (void *) purple_status_type_get_name(st->data)); 348 } 349 } 350 352 351 return ret; 353 352 } 354 353 355 static void purple_set_away( struct im_connection *ic, char *state_txt, char *message)354 static void purple_set_away(struct im_connection *ic, char *state_txt, char *message) 356 355 { 357 356 PurpleAccount *pa = ic->proto_data; 358 GList *status_types = purple_account_get_status_types( pa), *st;357 GList *status_types = purple_account_get_status_types(pa), *st; 359 358 PurpleStatusType *pst = NULL; 360 359 GList *args = NULL; 361 362 for( st = status_types; st; st = st->next ) 363 { 360 361 for (st = status_types; st; st = st->next) { 364 362 pst = st->data; 365 366 if( state_txt == NULL && 367 purple_status_type_get_primitive( pst ) == PURPLE_STATUS_AVAILABLE ) 368 break; 369 370 if( state_txt != NULL && 371 g_strcasecmp( state_txt, purple_status_type_get_name( pst ) ) == 0 ) 372 break; 373 } 374 375 if( message && purple_status_type_get_attr( pst, "message" ) ) 376 { 377 args = g_list_append( args, "message" ); 378 args = g_list_append( args, message ); 379 } 380 381 purple_account_set_status_list( pa, st ? purple_status_type_get_id( pst ) : "away", 382 TRUE, args ); 383 384 g_list_free( args ); 385 } 386 387 static char *set_eval_display_name( set_t *set, char *value ) 363 364 if (state_txt == NULL && 365 purple_status_type_get_primitive(pst) == PURPLE_STATUS_AVAILABLE) { 366 break; 367 } 368 369 if (state_txt != NULL && 370 g_strcasecmp(state_txt, purple_status_type_get_name(pst)) == 0) { 371 break; 372 } 373 } 374 375 if (message && purple_status_type_get_attr(pst, "message")) { 376 args = g_list_append(args, "message"); 377 args = g_list_append(args, message); 378 } 379 380 purple_account_set_status_list(pa, st ? purple_status_type_get_id(pst) : "away", 381 TRUE, args); 382 383 g_list_free(args); 384 } 385 386 static char *set_eval_display_name(set_t *set, char *value) 388 387 { 389 388 account_t *acc = set->data; 390 389 struct im_connection *ic = acc->ic; 391 392 if( ic ) 393 imcb_log( ic, "Changing display_name not currently supported with libpurple!" ); 394 390 391 if (ic) { 392 imcb_log(ic, "Changing display_name not currently supported with libpurple!"); 393 } 394 395 395 return NULL; 396 396 } 397 397 398 398 /* Bad bad gadu-gadu, not saving buddy list by itself */ 399 static void purple_gg_buddylist_export( PurpleConnection *gc ) 400 { 401 struct im_connection *ic = purple_ic_by_gc( gc ); 402 403 if( set_getstr( &ic->acc->set, "gg_sync_contacts" ) ) 404 { 405 GList *actions = gc->prpl->info->actions( gc->prpl, gc ); 399 static void purple_gg_buddylist_export(PurpleConnection *gc) 400 { 401 struct im_connection *ic = purple_ic_by_gc(gc); 402 403 if (set_getstr(&ic->acc->set, "gg_sync_contacts")) { 404 GList *actions = gc->prpl->info->actions(gc->prpl, gc); 406 405 GList *p; 407 for( p = g_list_first(actions); p; p = p->next ) 408 { 409 if( ((PurplePluginAction*)p->data) && 410 purple_menu_cmp( ((PurplePluginAction*)p->data)->label, "Upload buddylist to Server" ) == 0) 411 { 406 for (p = g_list_first(actions); p; p = p->next) { 407 if (((PurplePluginAction *) p->data) && 408 purple_menu_cmp(((PurplePluginAction *) p->data)->label, 409 "Upload buddylist to Server") == 0) { 412 410 PurplePluginAction action; 413 411 action.plugin = gc->prpl; 414 412 action.context = gc; 415 413 action.user_data = NULL; 416 ((PurplePluginAction *)p->data)->callback(&action);414 ((PurplePluginAction *) p->data)->callback(&action); 417 415 break; 418 416 } 419 417 } 420 g_list_free( actions ); 421 } 422 } 423 424 static void purple_gg_buddylist_import( PurpleConnection *gc ) 425 { 426 struct im_connection *ic = purple_ic_by_gc( gc ); 427 428 if( set_getstr( &ic->acc->set, "gg_sync_contacts" ) ) 429 { 430 GList *actions = gc->prpl->info->actions( gc->prpl, gc ); 418 g_list_free(actions); 419 } 420 } 421 422 static void purple_gg_buddylist_import(PurpleConnection *gc) 423 { 424 struct im_connection *ic = purple_ic_by_gc(gc); 425 426 if (set_getstr(&ic->acc->set, "gg_sync_contacts")) { 427 GList *actions = gc->prpl->info->actions(gc->prpl, gc); 431 428 GList *p; 432 for( p = g_list_first(actions); p; p = p->next ) 433 { 434 if( ((PurplePluginAction*)p->data) && 435 purple_menu_cmp( ((PurplePluginAction*)p->data)->label, "Download buddylist from Server" ) == 0 ) 436 { 429 for (p = g_list_first(actions); p; p = p->next) { 430 if (((PurplePluginAction *) p->data) && 431 purple_menu_cmp(((PurplePluginAction *) p->data)->label, 432 "Download buddylist from Server") == 0) { 437 433 PurplePluginAction action; 438 434 action.plugin = gc->prpl; 439 435 action.context = gc; 440 436 action.user_data = NULL; 441 ((PurplePluginAction *)p->data)->callback(&action);437 ((PurplePluginAction *) p->data)->callback(&action); 442 438 break; 443 439 } 444 440 } 445 g_list_free( actions);446 } 447 } 448 449 static void purple_add_buddy( struct im_connection *ic, char *who, char *group)441 g_list_free(actions); 442 } 443 } 444 445 static void purple_add_buddy(struct im_connection *ic, char *who, char *group) 450 446 { 451 447 PurpleBuddy *pb; 452 448 PurpleGroup *pg = NULL; 453 454 if( group && !( pg = purple_find_group( group ) ) ) 455 { 456 pg = purple_group_new( group ); 457 purple_blist_add_group( pg, NULL ); 458 } 459 460 pb = purple_buddy_new( (PurpleAccount*) ic->proto_data, who, NULL ); 461 purple_blist_add_buddy( pb, NULL, pg, NULL ); 462 purple_account_add_buddy( (PurpleAccount*) ic->proto_data, pb ); 463 464 purple_gg_buddylist_export( ((PurpleAccount*)ic->proto_data)->gc ); 465 } 466 467 static void purple_remove_buddy( struct im_connection *ic, char *who, char *group ) 449 450 if (group && !(pg = purple_find_group(group))) { 451 pg = purple_group_new(group); 452 purple_blist_add_group(pg, NULL); 453 } 454 455 pb = purple_buddy_new((PurpleAccount *) ic->proto_data, who, NULL); 456 purple_blist_add_buddy(pb, NULL, pg, NULL); 457 purple_account_add_buddy((PurpleAccount *) ic->proto_data, pb); 458 459 purple_gg_buddylist_export(((PurpleAccount *) ic->proto_data)->gc); 460 } 461 462 static void purple_remove_buddy(struct im_connection *ic, char *who, char *group) 468 463 { 469 464 PurpleBuddy *pb; 470 471 pb = purple_find_buddy( (PurpleAccount*) ic->proto_data, who ); 472 if( pb != NULL ) 473 { 465 466 pb = purple_find_buddy((PurpleAccount *) ic->proto_data, who); 467 if (pb != NULL) { 474 468 PurpleGroup *group; 475 476 group = purple_buddy_get_group( pb);477 purple_account_remove_buddy( (PurpleAccount*) ic->proto_data, pb, group);478 479 purple_blist_remove_buddy( pb);480 } 481 482 purple_gg_buddylist_export( ((PurpleAccount*)ic->proto_data)->gc);483 } 484 485 static void purple_add_permit( struct im_connection *ic, char *who)469 470 group = purple_buddy_get_group(pb); 471 purple_account_remove_buddy((PurpleAccount *) ic->proto_data, pb, group); 472 473 purple_blist_remove_buddy(pb); 474 } 475 476 purple_gg_buddylist_export(((PurpleAccount *) ic->proto_data)->gc); 477 } 478 479 static void purple_add_permit(struct im_connection *ic, char *who) 486 480 { 487 481 PurpleAccount *pa = ic->proto_data; 488 489 purple_privacy_permit_add( pa, who, FALSE);490 } 491 492 static void purple_add_deny( struct im_connection *ic, char *who)482 483 purple_privacy_permit_add(pa, who, FALSE); 484 } 485 486 static void purple_add_deny(struct im_connection *ic, char *who) 493 487 { 494 488 PurpleAccount *pa = ic->proto_data; 495 496 purple_privacy_deny_add( pa, who, FALSE);497 } 498 499 static void purple_rem_permit( struct im_connection *ic, char *who)489 490 purple_privacy_deny_add(pa, who, FALSE); 491 } 492 493 static void purple_rem_permit(struct im_connection *ic, char *who) 500 494 { 501 495 PurpleAccount *pa = ic->proto_data; 502 503 purple_privacy_permit_remove( pa, who, FALSE);504 } 505 506 static void purple_rem_deny( struct im_connection *ic, char *who)496 497 purple_privacy_permit_remove(pa, who, FALSE); 498 } 499 500 static void purple_rem_deny(struct im_connection *ic, char *who) 507 501 { 508 502 PurpleAccount *pa = ic->proto_data; 509 510 purple_privacy_deny_remove( pa, who, FALSE);511 } 512 513 static void purple_get_info( struct im_connection *ic, char *who)514 { 515 serv_get_info( purple_account_get_connection( ic->proto_data ), who);516 } 517 518 static void purple_keepalive( struct im_connection *ic)519 { 520 } 521 522 static int purple_send_typing( struct im_connection *ic, char *who, int flags)503 504 purple_privacy_deny_remove(pa, who, FALSE); 505 } 506 507 static void purple_get_info(struct im_connection *ic, char *who) 508 { 509 serv_get_info(purple_account_get_connection(ic->proto_data), who); 510 } 511 512 static void purple_keepalive(struct im_connection *ic) 513 { 514 } 515 516 static int purple_send_typing(struct im_connection *ic, char *who, int flags) 523 517 { 524 518 PurpleTypingState state = PURPLE_NOT_TYPING; 525 519 PurpleAccount *pa = ic->proto_data; 526 527 if ( flags & OPT_TYPING )520 521 if (flags & OPT_TYPING) { 528 522 state = PURPLE_TYPING; 529 else if( flags & OPT_THINKING )523 } else if (flags & OPT_THINKING) { 530 524 state = PURPLE_TYPED; 531 532 serv_send_typing( purple_account_get_connection( pa ), who, state ); 533 525 } 526 527 serv_send_typing(purple_account_get_connection(pa), who, state); 528 534 529 return 1; 535 530 } 536 531 537 static void purple_chat_msg( struct groupchat *gc, char *message, int flags)532 static void purple_chat_msg(struct groupchat *gc, char *message, int flags) 538 533 { 539 534 PurpleConversation *pc = gc->data; 540 541 purple_conv_chat_send( purple_conversation_get_chat_data( pc ), message);542 } 543 544 struct groupchat *purple_chat_with( struct im_connection *ic, char *who)535 536 purple_conv_chat_send(purple_conversation_get_chat_data(pc), message); 537 } 538 539 struct groupchat *purple_chat_with(struct im_connection *ic, char *who) 545 540 { 546 541 /* No, "of course" this won't work this way. Or in fact, it almost … … 551 546 PurpleConvChat *pcc; 552 547 struct groupchat *gc; 553 548 554 549 gc = imcb_chat_new( ic, "BitlBee-libpurple groupchat" ); 555 550 gc->data = pc = purple_conversation_new( PURPLE_CONV_TYPE_CHAT, pa, "BitlBee-libpurple groupchat" ); 556 551 pc->ui_data = gc; 557 552 558 553 pcc = PURPLE_CONV_CHAT( pc ); 559 554 purple_conv_chat_add_user( pcc, ic->acc->user, "", 0, TRUE ); … … 561 556 //purple_conv_chat_add_user( pcc, who, "", 0, TRUE ); 562 557 */ 563 558 564 559 /* There went my nice afternoon. :-( */ 565 560 566 561 PurpleAccount *pa = ic->proto_data; 567 PurplePlugin *prpl = purple_plugins_find_with_id( pa->protocol_id);562 PurplePlugin *prpl = purple_plugins_find_with_id(pa->protocol_id); 568 563 PurplePluginProtocolInfo *pi = prpl->info->extra_info; 569 PurpleBuddy *pb = purple_find_buddy( (PurpleAccount*) ic->proto_data, who);564 PurpleBuddy *pb = purple_find_buddy((PurpleAccount *) ic->proto_data, who); 570 565 PurpleMenuAction *mi; 571 566 GList *menu; 567 572 568 void (*callback)(PurpleBlistNode *, gpointer); /* FFFFFFFFFFFFFUUUUUUUUUUUUUU */ 573 574 if ( !pb || !pi || !pi->blist_node_menu )569 570 if (!pb || !pi || !pi->blist_node_menu) { 575 571 return NULL; 576 577 menu = pi->blist_node_menu( &pb->node ); 578 while( menu )579 {572 } 573 574 menu = pi->blist_node_menu(&pb->node); 575 while (menu) { 580 576 mi = menu->data; 581 if( purple_menu_cmp( mi->label, "initiate chat" ) || 582 purple_menu_cmp( mi->label, "initiate conference" ) ) 583 break; 577 if (purple_menu_cmp(mi->label, "initiate chat") || 578 purple_menu_cmp(mi->label, "initiate conference")) { 579 break; 580 } 584 581 menu = menu->next; 585 582 } 586 587 if ( menu == NULL )583 584 if (menu == NULL) { 588 585 return NULL; 589 586 } 587 590 588 /* Call the fucker. */ 591 callback = (void *) mi->callback;592 callback( &pb->node, menu->data);593 589 callback = (void *) mi->callback; 590 callback(&pb->node, menu->data); 591 594 592 return NULL; 595 593 } 596 594 597 void purple_chat_invite( struct groupchat *gc, char *who, char *message)595 void purple_chat_invite(struct groupchat *gc, char *who, char *message) 598 596 { 599 597 PurpleConversation *pc = gc->data; 600 PurpleConvChat *pcc = PURPLE_CONV_CHAT( pc);601 602 serv_chat_invite( purple_account_get_connection( gc->ic->proto_data),603 purple_conv_chat_get_id( pcc ),604 605 who);606 } 607 608 void purple_chat_kick( struct groupchat *gc, char *who, const char *message)598 PurpleConvChat *pcc = PURPLE_CONV_CHAT(pc); 599 600 serv_chat_invite(purple_account_get_connection(gc->ic->proto_data), 601 purple_conv_chat_get_id(pcc), 602 message && *message ? message : "Please join my chat", 603 who); 604 } 605 606 void purple_chat_kick(struct groupchat *gc, char *who, const char *message) 609 607 { 610 608 PurpleConversation *pc = gc->data; 611 char *str = g_strdup_printf( "kick %s %s", who, message ); 612 purple_conversation_do_command( pc, str, NULL, NULL ); 613 g_free( str ); 614 } 615 616 void purple_chat_leave( struct groupchat *gc ) 609 char *str = g_strdup_printf("kick %s %s", who, message); 610 611 purple_conversation_do_command(pc, str, NULL, NULL); 612 g_free(str); 613 } 614 615 void purple_chat_leave(struct groupchat *gc) 617 616 { 618 617 PurpleConversation *pc = gc->data; 619 620 purple_conversation_destroy( pc ); 621 } 622 623 struct groupchat *purple_chat_join( struct im_connection *ic, const char *room, const char *nick, const char *password, set_t **sets ) 618 619 purple_conversation_destroy(pc); 620 } 621 622 struct groupchat *purple_chat_join(struct im_connection *ic, const char *room, const char *nick, const char *password, 623 set_t **sets) 624 624 { 625 625 PurpleAccount *pa = ic->proto_data; 626 PurplePlugin *prpl = purple_plugins_find_with_id( pa->protocol_id);626 PurplePlugin *prpl = purple_plugins_find_with_id(pa->protocol_id); 627 627 PurplePluginProtocolInfo *pi = prpl->info->extra_info; 628 628 GHashTable *chat_hash; 629 629 PurpleConversation *conv; 630 630 GList *info, *l; 631 632 if( !pi->chat_info || !pi->chat_info_defaults || 633 !( info = pi->chat_info( purple_account_get_connection( pa ) ) ) ) 634 { 635 imcb_error( ic, "Joining chatrooms not supported by this protocol" ); 631 632 if (!pi->chat_info || !pi->chat_info_defaults || 633 !(info = pi->chat_info(purple_account_get_connection(pa)))) { 634 imcb_error(ic, "Joining chatrooms not supported by this protocol"); 636 635 return NULL; 637 636 } 638 639 if ( ( conv = purple_find_conversation_with_account( PURPLE_CONV_TYPE_CHAT, room, pa ) ) )640 purple_conversation_destroy( conv);641 642 chat_hash = pi->chat_info_defaults( purple_account_get_connection( pa ), room ); 643 644 for( l = info; l; l = l->next ) 645 {637 638 if ((conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, room, pa))) { 639 purple_conversation_destroy(conv); 640 } 641 642 chat_hash = pi->chat_info_defaults(purple_account_get_connection(pa), room); 643 644 for (l = info; l; l = l->next) { 646 645 struct proto_chat_entry *pce = l->data; 647 648 if( strcmp( pce->identifier, "handle" ) == 0 ) 649 g_hash_table_replace( chat_hash, "handle", g_strdup( nick ) ); 650 else if( strcmp( pce->identifier, "password" ) == 0 ) 651 g_hash_table_replace( chat_hash, "password", g_strdup( password ) ); 652 else if( strcmp( pce->identifier, "passwd" ) == 0 ) 653 g_hash_table_replace( chat_hash, "passwd", g_strdup( password ) ); 654 } 655 656 serv_join_chat( purple_account_get_connection( pa ), chat_hash ); 657 646 647 if (strcmp(pce->identifier, "handle") == 0) { 648 g_hash_table_replace(chat_hash, "handle", g_strdup(nick)); 649 } else if (strcmp(pce->identifier, "password") == 0) { 650 g_hash_table_replace(chat_hash, "password", g_strdup(password)); 651 } else if (strcmp(pce->identifier, "passwd") == 0) { 652 g_hash_table_replace(chat_hash, "passwd", g_strdup(password)); 653 } 654 } 655 656 serv_join_chat(purple_account_get_connection(pa), chat_hash); 657 658 658 return NULL; 659 659 } 660 660 661 void purple_transfer_request( struct im_connection *ic, file_transfer_t *ft, char *handle);661 void purple_transfer_request(struct im_connection *ic, file_transfer_t *ft, char *handle); 662 662 663 663 static void purple_ui_init(); … … 666 666 { 667 667 static GHashTable *ret; 668 669 if( ret == NULL ) 670 { 668 669 if (ret == NULL) { 671 670 ret = g_hash_table_new(g_str_hash, g_str_equal); 672 g_hash_table_insert( ret, "name", "BitlBee");673 g_hash_table_insert( ret, "version", BITLBEE_VERSION);674 } 675 671 g_hash_table_insert(ret, "name", "BitlBee"); 672 g_hash_table_insert(ret, "version", BITLBEE_VERSION); 673 } 674 676 675 return ret; 677 676 } 678 677 679 static PurpleCoreUiOps bee_core_uiops = 678 static PurpleCoreUiOps bee_core_uiops = 680 679 { 681 680 NULL, … … 686 685 }; 687 686 688 static void prplcb_conn_progress( PurpleConnection *gc, const char *text, size_t step, size_t step_count)689 { 690 struct im_connection *ic = purple_ic_by_gc( gc);691 692 imcb_log( ic, "%s", text);693 } 694 695 static void prplcb_conn_connected( PurpleConnection *gc)696 { 697 struct im_connection *ic = purple_ic_by_gc( gc);687 static void prplcb_conn_progress(PurpleConnection *gc, const char *text, size_t step, size_t step_count) 688 { 689 struct im_connection *ic = purple_ic_by_gc(gc); 690 691 imcb_log(ic, "%s", text); 692 } 693 694 static void prplcb_conn_connected(PurpleConnection *gc) 695 { 696 struct im_connection *ic = purple_ic_by_gc(gc); 698 697 const char *dn; 699 698 set_t *s; 700 701 imcb_connected( ic ); 702 703 if( ( dn = purple_connection_get_display_name( gc ) ) && 704 ( s = set_find( &ic->acc->set, "display_name" ) ) ) 705 { 706 g_free( s->value ); 707 s->value = g_strdup( dn ); 699 700 imcb_connected(ic); 701 702 if ((dn = purple_connection_get_display_name(gc)) && 703 (s = set_find(&ic->acc->set, "display_name"))) { 704 g_free(s->value); 705 s->value = g_strdup(dn); 708 706 } 709 707 710 708 // user list needs to be requested for Gadu-Gadu 711 purple_gg_buddylist_import( gc);712 713 if ( gc->flags & PURPLE_CONNECTION_HTML )709 purple_gg_buddylist_import(gc); 710 711 if (gc->flags & PURPLE_CONNECTION_HTML) { 714 712 ic->flags |= OPT_DOES_HTML; 715 } 716 717 static void prplcb_conn_disconnected( PurpleConnection *gc ) 718 { 719 struct im_connection *ic = purple_ic_by_gc( gc ); 720 721 if( ic != NULL ) 722 { 723 imc_logout( ic, !gc->wants_to_die ); 724 } 725 } 726 727 static void prplcb_conn_notice( PurpleConnection *gc, const char *text ) 728 { 729 struct im_connection *ic = purple_ic_by_gc( gc ); 730 731 if( ic != NULL ) 732 imcb_log( ic, "%s", text ); 733 } 734 735 static void prplcb_conn_report_disconnect_reason( PurpleConnection *gc, PurpleConnectionError reason, const char *text ) 736 { 737 struct im_connection *ic = purple_ic_by_gc( gc ); 738 713 } 714 } 715 716 static void prplcb_conn_disconnected(PurpleConnection *gc) 717 { 718 struct im_connection *ic = purple_ic_by_gc(gc); 719 720 if (ic != NULL) { 721 imc_logout(ic, !gc->wants_to_die); 722 } 723 } 724 725 static void prplcb_conn_notice(PurpleConnection *gc, const char *text) 726 { 727 struct im_connection *ic = purple_ic_by_gc(gc); 728 729 if (ic != NULL) { 730 imcb_log(ic, "%s", text); 731 } 732 } 733 734 static void prplcb_conn_report_disconnect_reason(PurpleConnection *gc, PurpleConnectionError reason, const char *text) 735 { 736 struct im_connection *ic = purple_ic_by_gc(gc); 737 739 738 /* PURPLE_CONNECTION_ERROR_NAME_IN_USE means concurrent login, 740 739 should probably handle that. */ 741 if( ic != NULL ) 742 imcb_error( ic, "%s", text ); 740 if (ic != NULL) { 741 imcb_error(ic, "%s", text); 742 } 743 743 } 744 744 … … 755 755 }; 756 756 757 static void prplcb_blist_update( PurpleBuddyList *list, PurpleBlistNode *node ) 758 { 759 if( node->type == PURPLE_BLIST_BUDDY_NODE ) 760 { 761 PurpleBuddy *bud = (PurpleBuddy*) node; 762 PurpleGroup *group = purple_buddy_get_group( bud ); 763 struct im_connection *ic = purple_ic_by_pa( bud->account ); 757 static void prplcb_blist_update(PurpleBuddyList *list, PurpleBlistNode *node) 758 { 759 if (node->type == PURPLE_BLIST_BUDDY_NODE) { 760 PurpleBuddy *bud = (PurpleBuddy *) node; 761 PurpleGroup *group = purple_buddy_get_group(bud); 762 struct im_connection *ic = purple_ic_by_pa(bud->account); 764 763 PurpleStatus *as; 765 764 int flags = 0; 766 767 if ( ic == NULL )765 766 if (ic == NULL) { 768 767 return; 769 770 if( bud->server_alias ) 771 imcb_rename_buddy( ic, bud->name, bud->server_alias ); 772 else if( bud->alias ) 773 imcb_rename_buddy( ic, bud->name, bud->alias ); 774 775 if( group ) 776 imcb_add_buddy( ic, bud->name, purple_group_get_name( group ) ); 777 778 flags |= purple_presence_is_online( bud->presence ) ? OPT_LOGGED_IN : 0; 779 flags |= purple_presence_is_available( bud->presence ) ? 0 : OPT_AWAY; 780 781 as = purple_presence_get_active_status( bud->presence ); 782 783 imcb_buddy_status( ic, bud->name, flags, purple_status_get_name( as ), 784 purple_status_get_attr_string( as, "message" ) ); 785 786 imcb_buddy_times( ic, bud->name, 787 purple_presence_get_login_time( bud->presence ), 788 purple_presence_get_idle_time( bud->presence ) ); 789 } 790 } 791 792 static void prplcb_blist_new( PurpleBlistNode *node ) 793 { 794 if( node->type == PURPLE_BLIST_BUDDY_NODE ) 795 { 796 PurpleBuddy *bud = (PurpleBuddy*) node; 797 struct im_connection *ic = purple_ic_by_pa( bud->account ); 798 799 if( ic == NULL ) 768 } 769 770 if (bud->server_alias) { 771 imcb_rename_buddy(ic, bud->name, bud->server_alias); 772 } else if (bud->alias) { 773 imcb_rename_buddy(ic, bud->name, bud->alias); 774 } 775 776 if (group) { 777 imcb_add_buddy(ic, bud->name, purple_group_get_name(group)); 778 } 779 780 flags |= purple_presence_is_online(bud->presence) ? OPT_LOGGED_IN : 0; 781 flags |= purple_presence_is_available(bud->presence) ? 0 : OPT_AWAY; 782 783 as = purple_presence_get_active_status(bud->presence); 784 785 imcb_buddy_status(ic, bud->name, flags, purple_status_get_name(as), 786 purple_status_get_attr_string(as, "message")); 787 788 imcb_buddy_times(ic, bud->name, 789 purple_presence_get_login_time(bud->presence), 790 purple_presence_get_idle_time(bud->presence)); 791 } 792 } 793 794 static void prplcb_blist_new(PurpleBlistNode *node) 795 { 796 if (node->type == PURPLE_BLIST_BUDDY_NODE) { 797 PurpleBuddy *bud = (PurpleBuddy *) node; 798 struct im_connection *ic = purple_ic_by_pa(bud->account); 799 800 if (ic == NULL) { 800 801 return; 801 802 imcb_add_buddy( ic, bud->name, NULL ); 803 804 prplcb_blist_update( NULL, node ); 805 } 806 } 807 808 static void prplcb_blist_remove( PurpleBuddyList *list, PurpleBlistNode *node ) 802 } 803 804 imcb_add_buddy(ic, bud->name, NULL); 805 806 prplcb_blist_update(NULL, node); 807 } 808 } 809 810 static void prplcb_blist_remove(PurpleBuddyList *list, PurpleBlistNode *node) 809 811 { 810 812 /* 811 812 813 814 815 816 817 818 819 820 821 813 PurpleBuddy *bud = (PurpleBuddy*) node; 814 815 if( node->type == PURPLE_BLIST_BUDDY_NODE ) 816 { 817 struct im_connection *ic = purple_ic_by_pa( bud->account ); 818 819 if( ic == NULL ) 820 return; 821 822 imcb_remove_buddy( ic, bud->name, NULL ); 823 } 822 824 */ 823 825 } … … 832 834 }; 833 835 834 void prplcb_conv_new( PurpleConversation *conv ) 835 { 836 if( conv->type == PURPLE_CONV_TYPE_CHAT ) 837 { 838 struct im_connection *ic = purple_ic_by_pa( conv->account ); 836 void prplcb_conv_new(PurpleConversation *conv) 837 { 838 if (conv->type == PURPLE_CONV_TYPE_CHAT) { 839 struct im_connection *ic = purple_ic_by_pa(conv->account); 839 840 struct groupchat *gc; 840 841 gc = imcb_chat_new( ic, conv->name ); 842 if( conv->title != NULL ) 843 { 844 imcb_chat_name_hint( gc, conv->title ); 845 imcb_chat_topic( gc, NULL, conv->title, 0 ); 841 842 gc = imcb_chat_new(ic, conv->name); 843 if (conv->title != NULL) { 844 imcb_chat_name_hint(gc, conv->title); 845 imcb_chat_topic(gc, NULL, conv->title, 0); 846 846 } 847 847 848 848 conv->ui_data = gc; 849 849 gc->data = conv; 850 850 851 851 /* libpurple brokenness: Whatever. Show that we join right away, 852 852 there's no clear "This is you!" signaling in _add_users so 853 853 don't even try. */ 854 imcb_chat_add_buddy( gc, gc->ic->acc->user);855 } 856 } 857 858 void prplcb_conv_free( PurpleConversation *conv)854 imcb_chat_add_buddy(gc, gc->ic->acc->user); 855 } 856 } 857 858 void prplcb_conv_free(PurpleConversation *conv) 859 859 { 860 860 struct groupchat *gc = conv->ui_data; 861 862 imcb_chat_free( gc);863 } 864 865 void prplcb_conv_add_users( PurpleConversation *conv, GList *cbuddies, gboolean new_arrivals)861 862 imcb_chat_free(gc); 863 } 864 865 void prplcb_conv_add_users(PurpleConversation *conv, GList *cbuddies, gboolean new_arrivals) 866 866 { 867 867 struct groupchat *gc = conv->ui_data; 868 868 GList *b; 869 870 for( b = cbuddies; b; b = b->next ) 871 { 869 870 for (b = cbuddies; b; b = b->next) { 872 871 PurpleConvChatBuddy *pcb = b->data; 873 874 imcb_chat_add_buddy( gc, pcb->name);875 } 876 } 877 878 void prplcb_conv_del_users( PurpleConversation *conv, GList *cbuddies)872 873 imcb_chat_add_buddy(gc, pcb->name); 874 } 875 } 876 877 void prplcb_conv_del_users(PurpleConversation *conv, GList *cbuddies) 879 878 { 880 879 struct groupchat *gc = conv->ui_data; 881 880 GList *b; 882 883 for( b = cbuddies; b; b = b->next ) 884 imcb_chat_remove_buddy( gc, b->data, "" ); 885 } 886 887 void prplcb_conv_chat_msg( PurpleConversation *conv, const char *who, const char *message, PurpleMessageFlags flags, time_t mtime ) 881 882 for (b = cbuddies; b; b = b->next) { 883 imcb_chat_remove_buddy(gc, b->data, ""); 884 } 885 } 886 887 void prplcb_conv_chat_msg(PurpleConversation *conv, const char *who, const char *message, PurpleMessageFlags flags, 888 time_t mtime) 888 889 { 889 890 struct groupchat *gc = conv->ui_data; 890 891 PurpleBuddy *buddy; 891 892 892 893 /* ..._SEND means it's an outgoing message, no need to echo those. */ 893 if ( flags & PURPLE_MESSAGE_SEND )894 if (flags & PURPLE_MESSAGE_SEND) { 894 895 return; 895 896 buddy = purple_find_buddy( conv->account, who ); 897 if( buddy != NULL ) 898 who = purple_buddy_get_name( buddy ); 899 900 imcb_chat_msg( gc, who, (char*) message, 0, mtime ); 901 } 902 903 static void prplcb_conv_im( PurpleConversation *conv, const char *who, const char *message, PurpleMessageFlags flags, time_t mtime ) 904 { 905 struct im_connection *ic = purple_ic_by_pa( conv->account ); 896 } 897 898 buddy = purple_find_buddy(conv->account, who); 899 if (buddy != NULL) { 900 who = purple_buddy_get_name(buddy); 901 } 902 903 imcb_chat_msg(gc, who, (char *) message, 0, mtime); 904 } 905 906 static void prplcb_conv_im(PurpleConversation *conv, const char *who, const char *message, PurpleMessageFlags flags, 907 time_t mtime) 908 { 909 struct im_connection *ic = purple_ic_by_pa(conv->account); 906 910 PurpleBuddy *buddy; 907 911 908 912 /* ..._SEND means it's an outgoing message, no need to echo those. */ 909 if ( flags & PURPLE_MESSAGE_SEND )913 if (flags & PURPLE_MESSAGE_SEND) { 910 914 return; 911 912 buddy = purple_find_buddy( conv->account, who ); 913 if( buddy != NULL ) 914 who = purple_buddy_get_name( buddy ); 915 916 imcb_buddy_msg( ic, (char*) who, (char*) message, 0, mtime ); 915 } 916 917 buddy = purple_find_buddy(conv->account, who); 918 if (buddy != NULL) { 919 who = purple_buddy_get_name(buddy); 920 } 921 922 imcb_buddy_msg(ic, (char *) who, (char *) message, 0, mtime); 917 923 } 918 924 919 925 /* No, this is not a ui_op but a signal. */ 920 static void prplcb_buddy_typing( PurpleAccount *account, const char *who, gpointer null)926 static void prplcb_buddy_typing(PurpleAccount *account, const char *who, gpointer null) 921 927 { 922 928 PurpleConversation *conv; 923 929 PurpleConvIm *im; 924 930 int state; 925 926 if ( ( conv = purple_find_conversation_with_account( PURPLE_CONV_TYPE_IM, who, account ) ) == NULL )931 932 if ((conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, account)) == NULL) { 927 933 return; 928 934 } 935 929 936 im = PURPLE_CONV_IM(conv); 930 switch( purple_conv_im_get_typing_state( im ) ) 931 { 937 switch (purple_conv_im_get_typing_state(im)) { 932 938 case PURPLE_TYPING: 933 939 state = OPT_TYPING; … … 939 945 state = 0; 940 946 } 941 942 imcb_buddy_typing( purple_ic_by_pa( account ), who, state);943 } 944 945 static PurpleConversationUiOps bee_conv_uiops = 947 948 imcb_buddy_typing(purple_ic_by_pa(account), who, state); 949 } 950 951 static PurpleConversationUiOps bee_conv_uiops = 946 952 { 947 953 prplcb_conv_new, /* create_conversation */ … … 962 968 }; 963 969 964 struct prplcb_request_action_data 965 { 970 struct prplcb_request_action_data { 966 971 void *user_data, *bee_data; 967 972 PurpleRequestActionCb yes, no; … … 969 974 }; 970 975 971 static void prplcb_request_action_yes( void *data)976 static void prplcb_request_action_yes(void *data) 972 977 { 973 978 struct prplcb_request_action_data *pqad = data; 974 975 if( pqad->yes ) 976 pqad->yes( pqad->user_data, pqad->yes_i ); 977 g_free( pqad ); 978 } 979 980 static void prplcb_request_action_no( void *data ) 979 980 if (pqad->yes) { 981 pqad->yes(pqad->user_data, pqad->yes_i); 982 } 983 g_free(pqad); 984 } 985 986 static void prplcb_request_action_no(void *data) 981 987 { 982 988 struct prplcb_request_action_data *pqad = data; 983 984 if( pqad->no ) 985 pqad->no( pqad->user_data, pqad->no_i ); 986 g_free( pqad ); 987 } 988 989 static void *prplcb_request_action( const char *title, const char *primary, const char *secondary, 990 int default_action, PurpleAccount *account, const char *who, 991 PurpleConversation *conv, void *user_data, size_t action_count, 992 va_list actions ) 993 { 994 struct prplcb_request_action_data *pqad; 989 990 if (pqad->no) { 991 pqad->no(pqad->user_data, pqad->no_i); 992 } 993 g_free(pqad); 994 } 995 996 static void *prplcb_request_action(const char *title, const char *primary, const char *secondary, 997 int default_action, PurpleAccount *account, const char *who, 998 PurpleConversation *conv, void *user_data, size_t action_count, 999 va_list actions) 1000 { 1001 struct prplcb_request_action_data *pqad; 995 1002 int i; 996 1003 char *q; 997 998 pqad = g_new0( struct prplcb_request_action_data, 1 ); 999 1000 for( i = 0; i < action_count; i ++ ) 1001 { 1004 1005 pqad = g_new0(struct prplcb_request_action_data, 1); 1006 1007 for (i = 0; i < action_count; i++) { 1002 1008 char *caption; 1003 1009 void *fn; 1004 1005 caption = va_arg( actions, char* ); 1006 fn = va_arg( actions, void* ); 1007 1008 if( strstr( caption, "Accept" ) || strstr( caption, "OK" ) ) 1009 { 1010 1011 caption = va_arg(actions, char*); 1012 fn = va_arg(actions, void*); 1013 1014 if (strstr(caption, "Accept") || strstr(caption, "OK")) { 1010 1015 pqad->yes = fn; 1011 1016 pqad->yes_i = i; 1012 } 1013 else if( strstr( caption, "Reject" ) || strstr( caption, "Cancel" ) ) 1014 { 1017 } else if (strstr(caption, "Reject") || strstr(caption, "Cancel")) { 1015 1018 pqad->no = fn; 1016 1019 pqad->no_i = i; 1017 1020 } 1018 1021 } 1019 1022 1020 1023 pqad->user_data = user_data; 1021 1024 1022 1025 /* TODO: IRC stuff here :-( */ 1023 q = g_strdup_printf( "Request: %s\n\n%s\n\n%s", title, primary, secondary);1024 pqad->bee_data = query_add( local_bee->ui_data, purple_ic_by_pa( account), q,1025 prplcb_request_action_yes, prplcb_request_action_no, g_free, pqad);1026 1027 g_free( q);1028 1026 q = g_strdup_printf("Request: %s\n\n%s\n\n%s", title, primary, secondary); 1027 pqad->bee_data = query_add(local_bee->ui_data, purple_ic_by_pa(account), q, 1028 prplcb_request_action_yes, prplcb_request_action_no, g_free, pqad); 1029 1030 g_free(q); 1031 1029 1032 return pqad; 1030 1033 } … … 1033 1036 static void prplcb_request_test() 1034 1037 { 1035 1038 fprintf( stderr, "bla\n" ); 1036 1039 } 1037 1040 */ … … 1048 1051 }; 1049 1052 1050 static void prplcb_privacy_permit_added( PurpleAccount *account, const char *name ) 1051 { 1052 struct im_connection *ic = purple_ic_by_pa( account ); 1053 1054 if( !g_slist_find_custom( ic->permit, name, (GCompareFunc) ic->acc->prpl->handle_cmp ) ) 1055 ic->permit = g_slist_prepend( ic->permit, g_strdup( name ) ); 1056 } 1057 1058 static void prplcb_privacy_permit_removed( PurpleAccount *account, const char *name ) 1059 { 1060 struct im_connection *ic = purple_ic_by_pa( account ); 1053 static void prplcb_privacy_permit_added(PurpleAccount *account, const char *name) 1054 { 1055 struct im_connection *ic = purple_ic_by_pa(account); 1056 1057 if (!g_slist_find_custom(ic->permit, name, (GCompareFunc) ic->acc->prpl->handle_cmp)) { 1058 ic->permit = g_slist_prepend(ic->permit, g_strdup(name)); 1059 } 1060 } 1061 1062 static void prplcb_privacy_permit_removed(PurpleAccount *account, const char *name) 1063 { 1064 struct im_connection *ic = purple_ic_by_pa(account); 1061 1065 void *n; 1062 1063 n = g_slist_find_custom( ic->permit, name, (GCompareFunc) ic->acc->prpl->handle_cmp ); 1064 ic->permit = g_slist_remove( ic->permit, n ); 1065 } 1066 1067 static void prplcb_privacy_deny_added( PurpleAccount *account, const char *name ) 1068 { 1069 struct im_connection *ic = purple_ic_by_pa( account ); 1070 1071 if( !g_slist_find_custom( ic->deny, name, (GCompareFunc) ic->acc->prpl->handle_cmp ) ) 1072 ic->deny = g_slist_prepend( ic->deny, g_strdup( name ) ); 1073 } 1074 1075 static void prplcb_privacy_deny_removed( PurpleAccount *account, const char *name ) 1076 { 1077 struct im_connection *ic = purple_ic_by_pa( account ); 1066 1067 n = g_slist_find_custom(ic->permit, name, (GCompareFunc) ic->acc->prpl->handle_cmp); 1068 ic->permit = g_slist_remove(ic->permit, n); 1069 } 1070 1071 static void prplcb_privacy_deny_added(PurpleAccount *account, const char *name) 1072 { 1073 struct im_connection *ic = purple_ic_by_pa(account); 1074 1075 if (!g_slist_find_custom(ic->deny, name, (GCompareFunc) ic->acc->prpl->handle_cmp)) { 1076 ic->deny = g_slist_prepend(ic->deny, g_strdup(name)); 1077 } 1078 } 1079 1080 static void prplcb_privacy_deny_removed(PurpleAccount *account, const char *name) 1081 { 1082 struct im_connection *ic = purple_ic_by_pa(account); 1078 1083 void *n; 1079 1080 n = g_slist_find_custom( ic->deny, name, (GCompareFunc) ic->acc->prpl->handle_cmp);1081 ic->deny = g_slist_remove( ic->deny, n);1084 1085 n = g_slist_find_custom(ic->deny, name, (GCompareFunc) ic->acc->prpl->handle_cmp); 1086 ic->deny = g_slist_remove(ic->deny, n); 1082 1087 } 1083 1088 … … 1090 1095 }; 1091 1096 1092 static void prplcb_debug_print( PurpleDebugLevel level, const char *category, const char *arg_s)1093 { 1094 fprintf( stderr, "DEBUG %s: %s", category, arg_s);1097 static void prplcb_debug_print(PurpleDebugLevel level, const char *category, const char *arg_s) 1098 { 1099 fprintf(stderr, "DEBUG %s: %s", category, arg_s); 1095 1100 } 1096 1101 … … 1100 1105 }; 1101 1106 1102 static guint prplcb_ev_timeout_add( guint interval, GSourceFunc func, gpointer udata)1103 { 1104 return b_timeout_add( interval, (b_event_handler) func, udata);1105 } 1106 1107 static guint prplcb_ev_input_add( int fd, PurpleInputCondition cond, PurpleInputFunction func, gpointer udata)1108 { 1109 return b_input_add( fd, cond | B_EV_FLAG_FORCE_REPEAT, (b_event_handler) func, udata);1110 } 1111 1112 static gboolean prplcb_ev_remove( guint id)1113 { 1114 b_event_remove( (gint) id);1107 static guint prplcb_ev_timeout_add(guint interval, GSourceFunc func, gpointer udata) 1108 { 1109 return b_timeout_add(interval, (b_event_handler) func, udata); 1110 } 1111 1112 static guint prplcb_ev_input_add(int fd, PurpleInputCondition cond, PurpleInputFunction func, gpointer udata) 1113 { 1114 return b_input_add(fd, cond | B_EV_FLAG_FORCE_REPEAT, (b_event_handler) func, udata); 1115 } 1116 1117 static gboolean prplcb_ev_remove(guint id) 1118 { 1119 b_event_remove((gint) id); 1115 1120 return TRUE; 1116 1121 } 1117 1122 1118 static PurpleEventLoopUiOps glib_eventloops = 1123 static PurpleEventLoopUiOps glib_eventloops = 1119 1124 { 1120 1125 prplcb_ev_timeout_add, … … 1124 1129 }; 1125 1130 1126 static void *prplcb_notify_email( 1127 const char *to, const char *url)1128 { 1129 struct im_connection *ic = purple_ic_by_gc( gc);1130 1131 imcb_log( ic, "Received e-mail from %s for %s: %s <%s>", from, to, subject, url);1132 1131 static void *prplcb_notify_email(PurpleConnection *gc, const char *subject, const char *from, 1132 const char *to, const char *url) 1133 { 1134 struct im_connection *ic = purple_ic_by_gc(gc); 1135 1136 imcb_log(ic, "Received e-mail from %s for %s: %s <%s>", from, to, subject, url); 1137 1133 1138 return NULL; 1134 1139 } 1135 1140 1136 static void *prplcb_notify_userinfo( PurpleConnection *gc, const char *who, PurpleNotifyUserInfo *user_info)1137 { 1138 struct im_connection *ic = purple_ic_by_gc( gc);1139 GString *info = g_string_new( "");1140 GList *l = purple_notify_user_info_get_entries( user_info);1141 static void *prplcb_notify_userinfo(PurpleConnection *gc, const char *who, PurpleNotifyUserInfo *user_info) 1142 { 1143 struct im_connection *ic = purple_ic_by_gc(gc); 1144 GString *info = g_string_new(""); 1145 GList *l = purple_notify_user_info_get_entries(user_info); 1141 1146 char *key; 1142 1147 const char *value; 1143 1148 int n; 1144 1145 while( l ) 1146 { 1149 1150 while (l) { 1147 1151 PurpleNotifyUserInfoEntry *e = l->data; 1148 1149 switch( purple_notify_user_info_entry_get_type( e ) ) 1150 { 1152 1153 switch (purple_notify_user_info_entry_get_type(e)) { 1151 1154 case PURPLE_NOTIFY_USER_INFO_ENTRY_PAIR: 1152 1155 case PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER: 1153 key = g_strdup( purple_notify_user_info_entry_get_label( e ) ); 1154 value = purple_notify_user_info_entry_get_value( e ); 1155 1156 if( key ) 1157 { 1158 strip_html( key ); 1159 g_string_append_printf( info, "%s: ", key ); 1160 1161 if( value ) 1162 { 1163 n = strlen( value ) - 1; 1164 while( g_ascii_isspace( value[n] ) ) 1165 n --; 1166 g_string_append_len( info, value, n + 1 ); 1156 key = g_strdup(purple_notify_user_info_entry_get_label(e)); 1157 value = purple_notify_user_info_entry_get_value(e); 1158 1159 if (key) { 1160 strip_html(key); 1161 g_string_append_printf(info, "%s: ", key); 1162 1163 if (value) { 1164 n = strlen(value) - 1; 1165 while (g_ascii_isspace(value[n])) { 1166 n--; 1167 } 1168 g_string_append_len(info, value, n + 1); 1167 1169 } 1168 g_string_append_c( info, '\n');1169 g_free( key);1170 g_string_append_c(info, '\n'); 1171 g_free(key); 1170 1172 } 1171 1173 1172 1174 break; 1173 1175 case PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK: 1174 g_string_append( info, "------------------------\n");1175 break; 1176 } 1177 1176 g_string_append(info, "------------------------\n"); 1177 break; 1178 } 1179 1178 1180 l = l->next; 1179 1181 } 1180 1181 imcb_log( ic, "User %s info:\n%s", who, info->str);1182 g_string_free( info, TRUE);1183 1182 1183 imcb_log(ic, "User %s info:\n%s", who, info->str); 1184 g_string_free(info, TRUE); 1185 1184 1186 return NULL; 1185 1187 } … … 1187 1189 static PurpleNotifyUiOps bee_notify_uiops = 1188 1190 { 1189 1190 1191 1192 1193 1194 1195 1191 NULL, 1192 prplcb_notify_email, 1193 NULL, 1194 NULL, 1195 NULL, 1196 NULL, 1197 prplcb_notify_userinfo, 1196 1198 }; 1197 1199 1198 static void *prplcb_account_request_authorize( PurpleAccount *account, const char *remote_user, 1199 const char *id, const char *alias, const char *message, gboolean on_list, 1200 PurpleAccountRequestAuthorizationCb authorize_cb, PurpleAccountRequestAuthorizationCb deny_cb, void *user_data ) 1201 { 1202 struct im_connection *ic = purple_ic_by_pa( account ); 1200 static void *prplcb_account_request_authorize(PurpleAccount *account, const char *remote_user, 1201 const char *id, const char *alias, const char *message, gboolean on_list, 1202 PurpleAccountRequestAuthorizationCb authorize_cb, 1203 PurpleAccountRequestAuthorizationCb deny_cb, void *user_data) 1204 { 1205 struct im_connection *ic = purple_ic_by_pa(account); 1203 1206 char *q; 1204 1205 if( alias ) 1206 q = g_strdup_printf( "%s (%s) wants to add you to his/her contact " 1207 "list. (%s)", alias, remote_user, message ); 1208 else 1209 q = g_strdup_printf( "%s wants to add you to his/her contact " 1210 "list. (%s)", remote_user, message ); 1211 1212 imcb_ask_with_free( ic, q, user_data, authorize_cb, deny_cb, NULL ); 1213 g_free( q ); 1214 1207 1208 if (alias) { 1209 q = g_strdup_printf("%s (%s) wants to add you to his/her contact " 1210 "list. (%s)", alias, remote_user, message); 1211 } else { 1212 q = g_strdup_printf("%s wants to add you to his/her contact " 1213 "list. (%s)", remote_user, message); 1214 } 1215 1216 imcb_ask_with_free(ic, q, user_data, authorize_cb, deny_cb, NULL); 1217 g_free(q); 1218 1215 1219 return NULL; 1216 1220 } … … 1229 1233 static void purple_ui_init() 1230 1234 { 1231 purple_connections_set_ui_ops( &bee_conn_uiops ); 1232 purple_blist_set_ui_ops( &bee_blist_uiops ); 1233 purple_conversations_set_ui_ops( &bee_conv_uiops ); 1234 purple_request_set_ui_ops( &bee_request_uiops ); 1235 purple_privacy_set_ui_ops( &bee_privacy_uiops ); 1236 purple_notify_set_ui_ops( &bee_notify_uiops ); 1237 purple_accounts_set_ui_ops( &bee_account_uiops ); 1238 purple_xfers_set_ui_ops( &bee_xfer_uiops ); 1239 1240 if( getenv( "BITLBEE_DEBUG" ) ) 1241 purple_debug_set_ui_ops( &bee_debug_uiops ); 1235 purple_connections_set_ui_ops(&bee_conn_uiops); 1236 purple_blist_set_ui_ops(&bee_blist_uiops); 1237 purple_conversations_set_ui_ops(&bee_conv_uiops); 1238 purple_request_set_ui_ops(&bee_request_uiops); 1239 purple_privacy_set_ui_ops(&bee_privacy_uiops); 1240 purple_notify_set_ui_ops(&bee_notify_uiops); 1241 purple_accounts_set_ui_ops(&bee_account_uiops); 1242 purple_xfers_set_ui_ops(&bee_xfer_uiops); 1243 1244 if (getenv("BITLBEE_DEBUG")) { 1245 purple_debug_set_ui_ops(&bee_debug_uiops); 1246 } 1242 1247 } 1243 1248 … … 1248 1253 GString *help; 1249 1254 char *dir; 1250 1251 if( B_EV_IO_READ != PURPLE_INPUT_READ || 1252 B_EV_IO_WRITE != PURPLE_INPUT_WRITE ) 1253 { 1255 1256 if (B_EV_IO_READ != PURPLE_INPUT_READ || 1257 B_EV_IO_WRITE != PURPLE_INPUT_WRITE) { 1254 1258 /* FIXME FIXME FIXME FIXME FIXME :-) */ 1255 exit( 1 ); 1256 } 1257 1258 dir = g_strdup_printf( "%s/purple", global.conf->configdir ); 1259 purple_util_set_user_dir( dir ); 1260 g_free( dir ); 1261 1262 purple_debug_set_enabled( FALSE ); 1263 purple_core_set_ui_ops( &bee_core_uiops ); 1264 purple_eventloop_set_ui_ops( &glib_eventloops ); 1265 if( !purple_core_init( "BitlBee") ) 1266 { 1259 exit(1); 1260 } 1261 1262 dir = g_strdup_printf("%s/purple", global.conf->configdir); 1263 purple_util_set_user_dir(dir); 1264 g_free(dir); 1265 1266 purple_debug_set_enabled(FALSE); 1267 purple_core_set_ui_ops(&bee_core_uiops); 1268 purple_eventloop_set_ui_ops(&glib_eventloops); 1269 if (!purple_core_init("BitlBee")) { 1267 1270 /* Initializing the core failed. Terminate. */ 1268 fprintf( stderr, "libpurple initialization failed.\n");1271 fprintf(stderr, "libpurple initialization failed.\n"); 1269 1272 abort(); 1270 1273 } 1271 1272 if( proxytype != PROXY_NONE ) 1273 { 1274 1275 if (proxytype != PROXY_NONE) { 1274 1276 PurpleProxyInfo *pi = purple_global_proxy_get_info(); 1275 switch( proxytype ) 1276 { 1277 switch (proxytype) { 1277 1278 case PROXY_SOCKS4: 1278 purple_proxy_info_set_type( pi, PURPLE_PROXY_SOCKS4);1279 purple_proxy_info_set_type(pi, PURPLE_PROXY_SOCKS4); 1279 1280 break; 1280 1281 case PROXY_SOCKS5: 1281 purple_proxy_info_set_type( pi, PURPLE_PROXY_SOCKS5);1282 purple_proxy_info_set_type(pi, PURPLE_PROXY_SOCKS5); 1282 1283 break; 1283 1284 case PROXY_HTTP: 1284 purple_proxy_info_set_type( pi, PURPLE_PROXY_HTTP);1285 break; 1286 } 1287 purple_proxy_info_set_host( pi, proxyhost);1288 purple_proxy_info_set_port( pi, proxyport);1289 purple_proxy_info_set_username( pi, proxyuser);1290 purple_proxy_info_set_password( pi, proxypass);1291 } 1292 1293 purple_set_blist( purple_blist_new());1294 1285 purple_proxy_info_set_type(pi, PURPLE_PROXY_HTTP); 1286 break; 1287 } 1288 purple_proxy_info_set_host(pi, proxyhost); 1289 purple_proxy_info_set_port(pi, proxyport); 1290 purple_proxy_info_set_username(pi, proxyuser); 1291 purple_proxy_info_set_password(pi, proxypass); 1292 } 1293 1294 purple_set_blist(purple_blist_new()); 1295 1295 1296 /* No, really. So far there were ui_ops for everything, but now suddenly 1296 1297 one needs to use signals for typing notification stuff. :-( */ 1297 purple_signal_connect( 1298 &funcs, PURPLE_CALLBACK(prplcb_buddy_typing), NULL);1299 purple_signal_connect( 1300 &funcs, PURPLE_CALLBACK(prplcb_buddy_typing), NULL);1301 purple_signal_connect( 1302 &funcs, PURPLE_CALLBACK(prplcb_buddy_typing), NULL);1303 1304 memset( &funcs, 0, sizeof( funcs ));1298 purple_signal_connect(purple_conversations_get_handle(), "buddy-typing", 1299 &funcs, PURPLE_CALLBACK(prplcb_buddy_typing), NULL); 1300 purple_signal_connect(purple_conversations_get_handle(), "buddy-typed", 1301 &funcs, PURPLE_CALLBACK(prplcb_buddy_typing), NULL); 1302 purple_signal_connect(purple_conversations_get_handle(), "buddy-typing-stopped", 1303 &funcs, PURPLE_CALLBACK(prplcb_buddy_typing), NULL); 1304 1305 memset(&funcs, 0, sizeof(funcs)); 1305 1306 funcs.login = purple_login; 1306 1307 funcs.init = purple_init; … … 1327 1328 funcs.chat_join = purple_chat_join; 1328 1329 funcs.transfer_request = purple_transfer_request; 1329 1330 help = g_string_new( "BitlBee libpurple module supports the following IM protocols:\n");1331 1330 1331 help = g_string_new("BitlBee libpurple module supports the following IM protocols:\n"); 1332 1332 1333 /* Add a protocol entry to BitlBee's structures for every protocol 1333 supported by this libpurple instance. */ 1334 for( prots = purple_plugins_get_protocols(); prots; prots = prots->next ) 1335 { 1334 supported by this libpurple instance. */ 1335 for (prots = purple_plugins_get_protocols(); prots; prots = prots->next) { 1336 1336 PurplePlugin *prot = prots->data; 1337 1337 struct prpl *ret; 1338 1338 1339 1339 /* If we already have this one (as a native module), don't 1340 1340 add a libpurple duplicate. */ 1341 if ( find_protocol( prot->info->id ) )1341 if (find_protocol(prot->info->id)) { 1342 1342 continue; 1343 1344 ret = g_memdup( &funcs, sizeof( funcs ) ); 1343 } 1344 1345 ret = g_memdup(&funcs, sizeof(funcs)); 1345 1346 ret->name = ret->data = prot->info->id; 1346 if ( strncmp( ret->name, "prpl-", 5 ) == 0 )1347 if (strncmp(ret->name, "prpl-", 5) == 0) { 1347 1348 ret->name += 5; 1348 register_protocol( ret ); 1349 1350 g_string_append_printf( help, "\n* %s (%s)", ret->name, prot->info->name ); 1351 1349 } 1350 register_protocol(ret); 1351 1352 g_string_append_printf(help, "\n* %s (%s)", ret->name, prot->info->name); 1353 1352 1354 /* libpurple doesn't define a protocol called OSCAR, but we 1353 1355 need it to be compatible with normal BitlBee. */ 1354 if( g_strcasecmp( prot->info->id, "prpl-aim" ) == 0 ) 1355 { 1356 ret = g_memdup( &funcs, sizeof( funcs ) ); 1356 if (g_strcasecmp(prot->info->id, "prpl-aim") == 0) { 1357 ret = g_memdup(&funcs, sizeof(funcs)); 1357 1358 ret->name = "oscar"; 1358 1359 ret->data = prot->info->id; 1359 register_protocol( ret);1360 } 1361 } 1362 1363 g_string_append( 1364 1365 "(create an account using that protocol first!)");1366 1360 register_protocol(ret); 1361 } 1362 } 1363 1364 g_string_append(help, "\n\nFor used protocols, more information about available " 1365 "settings can be found using \x02help purple <protocol name>\x02 " 1366 "(create an account using that protocol first!)"); 1367 1367 1368 /* Add a simple dynamically-generated help item listing all 1368 1369 the supported protocols. */ 1369 help_add_mem( &global.help, "purple", help->str);1370 g_string_free( help, TRUE);1371 } 1370 help_add_mem(&global.help, "purple", help->str); 1371 g_string_free(help, TRUE); 1372 }
Note: See TracChangeset
for help on using the changeset viewer.