Ignore:
Timestamp:
2016-11-20T08:40:36Z (7 years ago)
Author:
dequis <dx@…>
Children:
3f44e43
Parents:
ba52ac5 (diff), 9f03c47 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge master up to commit '9f03c47' into parson

File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/purple/purple.c

    rba52ac5 r537d9b9  
    4343                                   const char *message, const char *who);
    4444
     45void purple_transfer_cancel_all(struct im_connection *ic);
     46
    4547/* purple_request_input specific stuff */
    4648typedef void (*ri_callback_t)(gpointer, const gchar *);
     
    5456};
    5557
     58struct purple_roomlist_data {
     59        GSList *chats;
     60        gint topic;
     61        gboolean initialized;
     62};
     63
     64
    5665struct im_connection *purple_ic_by_pa(PurpleAccount *pa)
    5766{
     
    94103}
    95104
     105static 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
    96116static void purple_init(account_t *acc)
    97117{
    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);
    99120        PurplePluginProtocolInfo *pi = prpl->info->extra_info;
    100121        PurpleAccount *pa;
     
    262283        /* Go through all away states to figure out if away/status messages
    263284           are possible. */
    264         pa = purple_account_new(acc->user, (char *) acc->prpl->data);
     285        pa = purple_account_new(acc->user, prpl_id);
    265286        for (st = purple_account_get_status_types(pa); st; st = st->next) {
    266287                PurpleStatusPrimitive prim = purple_status_type_get_primitive(st->data);
     
    345366
    346367        ic->proto_data = pd = g_new0(struct purple_data, 1);
    347         pd->account = purple_account_new(acc->user, (char *) acc->prpl->data);
     368        pd->account = purple_account_new(acc->user, purple_get_account_prpl_id(acc));
    348369        pd->input_requests = g_hash_table_new_full(g_direct_hash, g_direct_equal,
    349370                                                   NULL, g_free);
     
    371392        }
    372393
     394        if (pd->filetransfers) {
     395                purple_transfer_cancel_all(ic);
     396        }
     397
    373398        purple_account_set_enabled(pd->account, "BitlBee", FALSE);
    374399        purple_connections = g_slist_remove(purple_connections, ic);
    375400        purple_accounts_remove(pd->account);
     401        imcb_chat_list_free(ic);
     402        g_free(pd->chat_list_server);
    376403        g_hash_table_destroy(pd->input_requests);
    377404        g_free(pd);
     
    673700}
    674701
     702void purple_chat_set_topic(struct groupchat *gc, char *topic)
     703{
     704        PurpleConversation *pc = gc->data;
     705        PurpleConvChat *pcc = PURPLE_CONV_CHAT(pc);
     706        struct purple_data *pd = gc->ic->proto_data;
     707        PurplePlugin *prpl = purple_plugins_find_with_id(pd->account->protocol_id);
     708        PurplePluginProtocolInfo *pi = prpl->info->extra_info;
     709
     710        if (pi->set_chat_topic) {
     711                pi->set_chat_topic(purple_account_get_connection(pd->account),
     712                                   purple_conv_chat_get_id(pcc),
     713                                   topic);
     714        }
     715}
     716
    675717void purple_chat_kick(struct groupchat *gc, char *who, const char *message)
    676718{
     
    697739        GHashTable *chat_hash;
    698740        PurpleConversation *conv;
     741        struct groupchat *gc;
    699742        GList *info, *l;
    700743
     
    730773        g_list_free(info);
    731774
     775        /* do this before serv_join_chat to handle cases where prplcb_conv_new is called immediately (not async) */
     776        gc = imcb_chat_new(ic, room);
     777
    732778        serv_join_chat(purple_account_get_connection(pd->account), chat_hash);
    733779
    734780        g_hash_table_destroy(chat_hash);
    735781
    736         return imcb_chat_new(ic, room);
     782        return gc;
     783}
     784
     785void purple_chat_list(struct im_connection *ic, const char *server)
     786{
     787        PurpleRoomlist *list;
     788        struct purple_data *pd = ic->proto_data;
     789        PurplePlugin *prpl = purple_plugins_find_with_id(pd->account->protocol_id);
     790        PurplePluginProtocolInfo *pi = prpl->info->extra_info;
     791
     792        if (!pi || !pi->roomlist_get_list) {
     793                imcb_log(ic, "Room listing unsupported by this purple plugin");
     794                return;
     795        }
     796
     797        g_free(pd->chat_list_server);
     798        pd->chat_list_server = (server && *server) ? g_strdup(server) : NULL;
     799
     800        list = purple_roomlist_get_list(pd->account->gc);
     801
     802        if (list) {
     803                struct purple_roomlist_data *rld = list->ui_data;
     804                rld->initialized = TRUE;
     805
     806                purple_roomlist_ref(list);
     807        }
    737808}
    738809
     
    9701041
    9711042/* Generic handler for IM or chat messages, covers write_chat, write_im and write_conv */
    972 static void handle_conv_msg(PurpleConversation *conv, const char *who, const char *message, guint32 bee_flags, time_t mtime)
     1043static void handle_conv_msg(PurpleConversation *conv, const char *who, const char *message_, guint32 bee_flags, time_t mtime)
    9731044{
    9741045        struct im_connection *ic = purple_ic_by_pa(conv->account);
    9751046        struct groupchat *gc = conv->ui_data;
     1047        char *message = g_strdup(message_);
    9761048        PurpleBuddy *buddy;
    9771049
     
    9821054
    9831055        if (conv->type == PURPLE_CONV_TYPE_IM) {
    984                 imcb_buddy_msg(ic, (char *) who, (char *) message, bee_flags, mtime);
     1056                imcb_buddy_msg(ic, who, message, bee_flags, mtime);
    9851057        } else if (gc) {
    986                 imcb_chat_msg(gc, who, (char *) message, bee_flags, mtime);
    987         }
     1058                imcb_chat_msg(gc, who, message, bee_flags, mtime);
     1059        }
     1060
     1061        g_free(message);
    9881062}
    9891063
     
    11711245        struct im_connection *ic = purple_ic_by_pa(account);
    11721246        struct purple_data *pd = ic->proto_data;
    1173         struct request_input_data *ri = g_new0(struct request_input_data, 1);
    1174         guint id = pd->next_request_id++;
     1247        struct request_input_data *ri;
     1248        guint id;
     1249
     1250        /* hack so that jabber's chat list doesn't ask for conference server twice */
     1251        if (pd->chat_list_server && title && g_strcmp0(title, "Enter a Conference Server") == 0) {
     1252                ((ri_callback_t) ok_cb)(user_data, pd->chat_list_server);
     1253                g_free(pd->chat_list_server);
     1254                pd->chat_list_server = NULL;
     1255                return NULL;
     1256        }
     1257
     1258        id = pd->next_request_id++;
     1259        ri = g_new0(struct request_input_data, 1);
    11751260
    11761261        ri->id = id;
     
    11821267
    11831268        imcb_add_buddy(ic, ri->buddy, NULL);
    1184         imcb_buddy_msg(ic, ri->buddy, secondary, 0, 0);
     1269
     1270        if (title && *title) {
     1271                imcb_buddy_msg(ic, ri->buddy, title, 0, 0);
     1272        }
     1273
     1274        if (primary && *primary) {
     1275                imcb_buddy_msg(ic, ri->buddy, primary, 0, 0);
     1276        }
     1277
     1278        if (secondary && *secondary) {
     1279                imcb_buddy_msg(ic, ri->buddy, secondary, 0, 0);
     1280        }
    11851281
    11861282        return ri;
     
    12561352        prplcb_privacy_deny_added,         /* deny_added */
    12571353        prplcb_privacy_deny_removed,       /* deny_removed */
     1354};
     1355
     1356static void prplcb_roomlist_create(PurpleRoomlist *list)
     1357{
     1358        struct purple_roomlist_data *rld;
     1359
     1360        list->ui_data = rld = g_new0(struct purple_roomlist_data, 1);
     1361        rld->topic = -1;
     1362}
     1363
     1364static void prplcb_roomlist_set_fields(PurpleRoomlist *list, GList *fields)
     1365{
     1366        gint topic = -1;
     1367        GList *l;
     1368        guint i;
     1369        PurpleRoomlistField *field;
     1370        struct purple_roomlist_data *rld = list->ui_data;
     1371
     1372        for (i = 0, l = fields; l; i++, l = l->next) {
     1373                field = l->data;
     1374
     1375                /* Use the first visible string field as a fallback topic */
     1376                if (i != 0 && topic < 0 && !field->hidden &&
     1377                    field->type == PURPLE_ROOMLIST_FIELD_STRING) {
     1378                        topic = i;
     1379                }
     1380
     1381                if ((g_strcasecmp(field->name, "description") == 0) ||
     1382                    (g_strcasecmp(field->name, "topic") == 0)) {
     1383                        if (field->type == PURPLE_ROOMLIST_FIELD_STRING) {
     1384                                rld->topic = i;
     1385                        }
     1386                }
     1387        }
     1388
     1389        if (rld->topic < 0) {
     1390                rld->topic = topic;
     1391        }
     1392}
     1393
     1394static void prplcb_roomlist_add_room(PurpleRoomlist *list, PurpleRoomlistRoom *room)
     1395{
     1396        bee_chat_info_t *ci;
     1397        const char *title;
     1398        const char *topic;
     1399        GList *fields;
     1400        struct purple_roomlist_data *rld = list->ui_data;
     1401
     1402        fields = purple_roomlist_room_get_fields(room);
     1403        title = purple_roomlist_room_get_name(room);
     1404
     1405        if (rld->topic >= 0) {
     1406                topic = g_list_nth_data(fields, rld->topic);
     1407        } else {
     1408                topic = NULL;
     1409        }
     1410
     1411        ci = g_new(bee_chat_info_t, 1);
     1412        ci->title = g_strdup(title);
     1413        ci->topic = g_strdup(topic);
     1414        rld->chats = g_slist_prepend(rld->chats, ci);
     1415}
     1416
     1417static void prplcb_roomlist_in_progress(PurpleRoomlist *list, gboolean in_progress)
     1418{
     1419        struct im_connection *ic;
     1420        struct purple_data *pd;
     1421        struct purple_roomlist_data *rld = list->ui_data;
     1422
     1423        if (in_progress || !rld) {
     1424                return;
     1425        }
     1426
     1427        ic = purple_ic_by_pa(list->account);
     1428        imcb_chat_list_free(ic);
     1429
     1430        pd = ic->proto_data;
     1431        g_free(pd->chat_list_server);
     1432        pd->chat_list_server = NULL;
     1433
     1434        ic->chatlist = g_slist_reverse(rld->chats);
     1435        rld->chats = NULL;
     1436
     1437        imcb_chat_list_finish(ic);
     1438
     1439        if (rld->initialized) {
     1440                purple_roomlist_unref(list);
     1441        }
     1442}
     1443
     1444static void prplcb_roomlist_destroy(PurpleRoomlist *list)
     1445{
     1446        g_free(list->ui_data);
     1447        list->ui_data = NULL;
     1448}
     1449
     1450static PurpleRoomlistUiOps bee_roomlist_uiops =
     1451{
     1452        NULL,                         /* show_with_account */
     1453        prplcb_roomlist_create,       /* create */
     1454        prplcb_roomlist_set_fields,   /* set_fields */
     1455        prplcb_roomlist_add_room,     /* add_room */
     1456        prplcb_roomlist_in_progress,  /* in_progress */
     1457        prplcb_roomlist_destroy,      /* destroy */
    12581458};
    12591459
     
    14221622        purple_request_set_ui_ops(&bee_request_uiops);
    14231623        purple_privacy_set_ui_ops(&bee_privacy_uiops);
     1624        purple_roomlist_set_ui_ops(&bee_roomlist_uiops);
    14241625        purple_notify_set_ui_ops(&bee_notify_uiops);
    14251626        purple_accounts_set_ui_ops(&bee_account_uiops);
     
    14381639        char *dir;
    14391640
     1641        if (purple_get_core() != NULL) {
     1642                log_message(LOGLVL_ERROR, "libpurple already initialized. "
     1643                            "Please use inetd or ForkDaemon mode instead.");
     1644                return;
     1645        }
     1646
    14401647        g_assert((int) B_EV_IO_READ == (int) PURPLE_INPUT_READ);
    14411648        g_assert((int) B_EV_IO_WRITE == (int) PURPLE_INPUT_WRITE);
     
    14431650        dir = g_strdup_printf("%s/purple", global.conf->configdir);
    14441651        purple_util_set_user_dir(dir);
     1652        g_free(dir);
     1653
     1654        dir = g_strdup_printf("%s/purple", global.conf->plugindir);
     1655        purple_plugins_add_search_path(dir);
    14451656        g_free(dir);
    14461657
     
    15061717        funcs.chat_with = purple_chat_with;
    15071718        funcs.chat_invite = purple_chat_invite;
     1719        funcs.chat_topic = purple_chat_set_topic;
    15081720        funcs.chat_kick = purple_chat_kick;
    15091721        funcs.chat_leave = purple_chat_leave;
    15101722        funcs.chat_join = purple_chat_join;
     1723        funcs.chat_list = purple_chat_list;
    15111724        funcs.transfer_request = purple_transfer_request;
    15121725
     
    15171730        for (prots = purple_plugins_get_protocols(); prots; prots = prots->next) {
    15181731                PurplePlugin *prot = prots->data;
     1732                PurplePluginProtocolInfo *pi = prot->info->extra_info;
    15191733                struct prpl *ret;
    15201734
     
    15301744                        ret->name += 5;
    15311745                }
     1746
     1747                if (pi->options & OPT_PROTO_NO_PASSWORD) {
     1748                        ret->options |= PRPL_OPT_NO_PASSWORD;
     1749                }
     1750
     1751                if (pi->options & OPT_PROTO_PASSWORD_OPTIONAL) {
     1752                        ret->options |= PRPL_OPT_PASSWORD_OPTIONAL;
     1753                }
     1754
    15321755                register_protocol(ret);
    15331756
     
    15391762                        ret = g_memdup(&funcs, sizeof(funcs));
    15401763                        ret->name = "oscar";
    1541                         ret->data = prot->info->id;
     1764                        /* purple_get_account_prpl_id() determines the actual protocol ID (icq/aim) */
     1765                        ret->data = NULL;
    15421766                        register_protocol(ret);
    15431767                }
Note: See TracChangeset for help on using the changeset viewer.