Changes in protocols/purple/purple.c [ba7618d:9f03c47]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/purple/purple.c
rba7618d r9f03c47 43 43 const char *message, const char *who); 44 44 45 void purple_transfer_cancel_all(struct im_connection *ic); 46 45 47 /* purple_request_input specific stuff */ 46 48 typedef void (*ri_callback_t)(gpointer, const gchar *); … … 54 56 }; 55 57 58 struct purple_roomlist_data { 59 GSList *chats; 60 gint topic; 61 gboolean initialized; 62 }; 63 64 56 65 struct im_connection *purple_ic_by_pa(PurpleAccount *pa) 57 66 { … … 94 103 } 95 104 105 static char *purple_get_account_prpl_id(account_t *acc) 106 { 107 /* "oscar" is how non-purple bitlbee calls it, 108 * and it might be icq or aim, depending on the username */ 109 if (g_strcmp0(acc->prpl->name, "oscar") == 0) { 110 return (g_ascii_isdigit(acc->user[0])) ? "prpl-icq" : "prpl-aim"; 111 } 112 113 return acc->prpl->data; 114 } 115 96 116 static void purple_init(account_t *acc) 97 117 { 98 PurplePlugin *prpl = purple_plugins_find_with_id((char *) acc->prpl->data); 118 char *prpl_id = purple_get_account_prpl_id(acc); 119 PurplePlugin *prpl = purple_plugins_find_with_id(prpl_id); 99 120 PurplePluginProtocolInfo *pi = prpl->info->extra_info; 100 121 PurpleAccount *pa; … … 262 283 /* Go through all away states to figure out if away/status messages 263 284 are possible. */ 264 pa = purple_account_new(acc->user, (char *) acc->prpl->data);285 pa = purple_account_new(acc->user, prpl_id); 265 286 for (st = purple_account_get_status_types(pa); st; st = st->next) { 266 287 PurpleStatusPrimitive prim = purple_status_type_get_primitive(st->data); … … 340 361 341 362 ic->proto_data = pd = g_new0(struct purple_data, 1); 342 pd->account = purple_account_new(acc->user, (char *) acc->prpl->data);363 pd->account = purple_account_new(acc->user, purple_get_account_prpl_id(acc)); 343 364 pd->input_requests = g_hash_table_new_full(g_direct_hash, g_direct_equal, 344 365 NULL, g_free); … … 366 387 } 367 388 389 if (pd->filetransfers) { 390 purple_transfer_cancel_all(ic); 391 } 392 368 393 purple_account_set_enabled(pd->account, "BitlBee", FALSE); 369 394 purple_connections = g_slist_remove(purple_connections, ic); 370 395 purple_accounts_remove(pd->account); 396 imcb_chat_list_free(ic); 397 g_free(pd->chat_list_server); 371 398 g_hash_table_destroy(pd->input_requests); 372 399 g_free(pd); … … 668 695 } 669 696 697 void purple_chat_set_topic(struct groupchat *gc, char *topic) 698 { 699 PurpleConversation *pc = gc->data; 700 PurpleConvChat *pcc = PURPLE_CONV_CHAT(pc); 701 struct purple_data *pd = gc->ic->proto_data; 702 PurplePlugin *prpl = purple_plugins_find_with_id(pd->account->protocol_id); 703 PurplePluginProtocolInfo *pi = prpl->info->extra_info; 704 705 if (pi->set_chat_topic) { 706 pi->set_chat_topic(purple_account_get_connection(pd->account), 707 purple_conv_chat_get_id(pcc), 708 topic); 709 } 710 } 711 670 712 void purple_chat_kick(struct groupchat *gc, char *who, const char *message) 671 713 { … … 692 734 GHashTable *chat_hash; 693 735 PurpleConversation *conv; 736 struct groupchat *gc; 694 737 GList *info, *l; 695 738 … … 725 768 g_list_free(info); 726 769 770 /* do this before serv_join_chat to handle cases where prplcb_conv_new is called immediately (not async) */ 771 gc = imcb_chat_new(ic, room); 772 727 773 serv_join_chat(purple_account_get_connection(pd->account), chat_hash); 728 774 729 775 g_hash_table_destroy(chat_hash); 730 776 731 return imcb_chat_new(ic, room); 777 return gc; 778 } 779 780 void purple_chat_list(struct im_connection *ic, const char *server) 781 { 782 PurpleRoomlist *list; 783 struct purple_data *pd = ic->proto_data; 784 PurplePlugin *prpl = purple_plugins_find_with_id(pd->account->protocol_id); 785 PurplePluginProtocolInfo *pi = prpl->info->extra_info; 786 787 if (!pi || !pi->roomlist_get_list) { 788 imcb_log(ic, "Room listing unsupported by this purple plugin"); 789 return; 790 } 791 792 g_free(pd->chat_list_server); 793 pd->chat_list_server = (server && *server) ? g_strdup(server) : NULL; 794 795 list = purple_roomlist_get_list(pd->account->gc); 796 797 if (list) { 798 struct purple_roomlist_data *rld = list->ui_data; 799 rld->initialized = TRUE; 800 801 purple_roomlist_ref(list); 802 } 732 803 } 733 804 … … 965 1036 966 1037 /* Generic handler for IM or chat messages, covers write_chat, write_im and write_conv */ 967 static void handle_conv_msg(PurpleConversation *conv, const char *who, const char *message , guint32 bee_flags, time_t mtime)1038 static void handle_conv_msg(PurpleConversation *conv, const char *who, const char *message_, guint32 bee_flags, time_t mtime) 968 1039 { 969 1040 struct im_connection *ic = purple_ic_by_pa(conv->account); 970 1041 struct groupchat *gc = conv->ui_data; 1042 char *message = g_strdup(message_); 971 1043 PurpleBuddy *buddy; 972 1044 … … 977 1049 978 1050 if (conv->type == PURPLE_CONV_TYPE_IM) { 979 imcb_buddy_msg(ic, (char *) who, (char *)message, bee_flags, mtime);1051 imcb_buddy_msg(ic, who, message, bee_flags, mtime); 980 1052 } else if (gc) { 981 imcb_chat_msg(gc, who, (char *) message, bee_flags, mtime); 982 } 1053 imcb_chat_msg(gc, who, message, bee_flags, mtime); 1054 } 1055 1056 g_free(message); 983 1057 } 984 1058 … … 1166 1240 struct im_connection *ic = purple_ic_by_pa(account); 1167 1241 struct purple_data *pd = ic->proto_data; 1168 struct request_input_data *ri = g_new0(struct request_input_data, 1); 1169 guint id = pd->next_request_id++; 1242 struct request_input_data *ri; 1243 guint id; 1244 1245 /* hack so that jabber's chat list doesn't ask for conference server twice */ 1246 if (pd->chat_list_server && title && g_strcmp0(title, "Enter a Conference Server") == 0) { 1247 ((ri_callback_t) ok_cb)(user_data, pd->chat_list_server); 1248 g_free(pd->chat_list_server); 1249 pd->chat_list_server = NULL; 1250 return NULL; 1251 } 1252 1253 id = pd->next_request_id++; 1254 ri = g_new0(struct request_input_data, 1); 1170 1255 1171 1256 ri->id = id; … … 1177 1262 1178 1263 imcb_add_buddy(ic, ri->buddy, NULL); 1179 imcb_buddy_msg(ic, ri->buddy, secondary, 0, 0); 1264 1265 if (title && *title) { 1266 imcb_buddy_msg(ic, ri->buddy, title, 0, 0); 1267 } 1268 1269 if (primary && *primary) { 1270 imcb_buddy_msg(ic, ri->buddy, primary, 0, 0); 1271 } 1272 1273 if (secondary && *secondary) { 1274 imcb_buddy_msg(ic, ri->buddy, secondary, 0, 0); 1275 } 1180 1276 1181 1277 return ri; … … 1251 1347 prplcb_privacy_deny_added, /* deny_added */ 1252 1348 prplcb_privacy_deny_removed, /* deny_removed */ 1349 }; 1350 1351 static void prplcb_roomlist_create(PurpleRoomlist *list) 1352 { 1353 struct purple_roomlist_data *rld; 1354 1355 list->ui_data = rld = g_new0(struct purple_roomlist_data, 1); 1356 rld->topic = -1; 1357 } 1358 1359 static void prplcb_roomlist_set_fields(PurpleRoomlist *list, GList *fields) 1360 { 1361 gint topic = -1; 1362 GList *l; 1363 guint i; 1364 PurpleRoomlistField *field; 1365 struct purple_roomlist_data *rld = list->ui_data; 1366 1367 for (i = 0, l = fields; l; i++, l = l->next) { 1368 field = l->data; 1369 1370 /* Use the first visible string field as a fallback topic */ 1371 if (i != 0 && topic < 0 && !field->hidden && 1372 field->type == PURPLE_ROOMLIST_FIELD_STRING) { 1373 topic = i; 1374 } 1375 1376 if ((g_strcasecmp(field->name, "description") == 0) || 1377 (g_strcasecmp(field->name, "topic") == 0)) { 1378 if (field->type == PURPLE_ROOMLIST_FIELD_STRING) { 1379 rld->topic = i; 1380 } 1381 } 1382 } 1383 1384 if (rld->topic < 0) { 1385 rld->topic = topic; 1386 } 1387 } 1388 1389 static void prplcb_roomlist_add_room(PurpleRoomlist *list, PurpleRoomlistRoom *room) 1390 { 1391 bee_chat_info_t *ci; 1392 const char *title; 1393 const char *topic; 1394 GList *fields; 1395 struct purple_roomlist_data *rld = list->ui_data; 1396 1397 fields = purple_roomlist_room_get_fields(room); 1398 title = purple_roomlist_room_get_name(room); 1399 1400 if (rld->topic >= 0) { 1401 topic = g_list_nth_data(fields, rld->topic); 1402 } else { 1403 topic = NULL; 1404 } 1405 1406 ci = g_new(bee_chat_info_t, 1); 1407 ci->title = g_strdup(title); 1408 ci->topic = g_strdup(topic); 1409 rld->chats = g_slist_prepend(rld->chats, ci); 1410 } 1411 1412 static void prplcb_roomlist_in_progress(PurpleRoomlist *list, gboolean in_progress) 1413 { 1414 struct im_connection *ic; 1415 struct purple_data *pd; 1416 struct purple_roomlist_data *rld = list->ui_data; 1417 1418 if (in_progress || !rld) { 1419 return; 1420 } 1421 1422 ic = purple_ic_by_pa(list->account); 1423 imcb_chat_list_free(ic); 1424 1425 pd = ic->proto_data; 1426 g_free(pd->chat_list_server); 1427 pd->chat_list_server = NULL; 1428 1429 ic->chatlist = g_slist_reverse(rld->chats); 1430 rld->chats = NULL; 1431 1432 imcb_chat_list_finish(ic); 1433 1434 if (rld->initialized) { 1435 purple_roomlist_unref(list); 1436 } 1437 } 1438 1439 static void prplcb_roomlist_destroy(PurpleRoomlist *list) 1440 { 1441 g_free(list->ui_data); 1442 list->ui_data = NULL; 1443 } 1444 1445 static PurpleRoomlistUiOps bee_roomlist_uiops = 1446 { 1447 NULL, /* show_with_account */ 1448 prplcb_roomlist_create, /* create */ 1449 prplcb_roomlist_set_fields, /* set_fields */ 1450 prplcb_roomlist_add_room, /* add_room */ 1451 prplcb_roomlist_in_progress, /* in_progress */ 1452 prplcb_roomlist_destroy, /* destroy */ 1253 1453 }; 1254 1454 … … 1417 1617 purple_request_set_ui_ops(&bee_request_uiops); 1418 1618 purple_privacy_set_ui_ops(&bee_privacy_uiops); 1619 purple_roomlist_set_ui_ops(&bee_roomlist_uiops); 1419 1620 purple_notify_set_ui_ops(&bee_notify_uiops); 1420 1621 purple_accounts_set_ui_ops(&bee_account_uiops); … … 1433 1634 char *dir; 1434 1635 1636 if (purple_get_core() != NULL) { 1637 log_message(LOGLVL_ERROR, "libpurple already initialized. " 1638 "Please use inetd or ForkDaemon mode instead."); 1639 return; 1640 } 1641 1435 1642 g_assert((int) B_EV_IO_READ == (int) PURPLE_INPUT_READ); 1436 1643 g_assert((int) B_EV_IO_WRITE == (int) PURPLE_INPUT_WRITE); … … 1438 1645 dir = g_strdup_printf("%s/purple", global.conf->configdir); 1439 1646 purple_util_set_user_dir(dir); 1647 g_free(dir); 1648 1649 dir = g_strdup_printf("%s/purple", global.conf->plugindir); 1650 purple_plugins_add_search_path(dir); 1440 1651 g_free(dir); 1441 1652 … … 1501 1712 funcs.chat_with = purple_chat_with; 1502 1713 funcs.chat_invite = purple_chat_invite; 1714 funcs.chat_topic = purple_chat_set_topic; 1503 1715 funcs.chat_kick = purple_chat_kick; 1504 1716 funcs.chat_leave = purple_chat_leave; 1505 1717 funcs.chat_join = purple_chat_join; 1718 funcs.chat_list = purple_chat_list; 1506 1719 funcs.transfer_request = purple_transfer_request; 1507 1720 … … 1512 1725 for (prots = purple_plugins_get_protocols(); prots; prots = prots->next) { 1513 1726 PurplePlugin *prot = prots->data; 1727 PurplePluginProtocolInfo *pi = prot->info->extra_info; 1514 1728 struct prpl *ret; 1515 1729 … … 1525 1739 ret->name += 5; 1526 1740 } 1741 1742 if (pi->options & OPT_PROTO_NO_PASSWORD) { 1743 ret->options |= PRPL_OPT_NO_PASSWORD; 1744 } 1745 1746 if (pi->options & OPT_PROTO_PASSWORD_OPTIONAL) { 1747 ret->options |= PRPL_OPT_PASSWORD_OPTIONAL; 1748 } 1749 1527 1750 register_protocol(ret); 1528 1751 … … 1534 1757 ret = g_memdup(&funcs, sizeof(funcs)); 1535 1758 ret->name = "oscar"; 1536 ret->data = prot->info->id; 1759 /* purple_get_account_prpl_id() determines the actual protocol ID (icq/aim) */ 1760 ret->data = NULL; 1537 1761 register_protocol(ret); 1538 1762 }
Note: See TracChangeset
for help on using the changeset viewer.