Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/purple/purple.c

    r9f03c47 ra9e0de2  
    114114}
    115115
     116static gboolean purple_account_should_set_nick(account_t *acc)
     117{
     118        /* whitelist of protocols that tend to have numeric or meaningless usernames, and should
     119         * always offer the 'alias' as a nick.  this is just so that users don't have to do
     120         * 'account whatever set nick_format %full_name'
     121         */
     122        char *whitelist[] = {
     123                "prpl-hangouts",
     124                "prpl-eionrobb-funyahoo-plusplus",
     125                "prpl-icq",
     126                "prpl-line",
     127                NULL,
     128        };
     129        char **p;
     130
     131        for (p = whitelist; *p; p++) {
     132                if (g_strcmp0(acc->prpl->data, *p) == 0) {
     133                        return TRUE;
     134                }
     135        }
     136
     137        return FALSE;
     138}
     139
    116140static void purple_init(account_t *acc)
    117141{
     
    281305        }
    282306
     307        if (g_strcmp0(prpl->info->id, "prpl-line") == 0) {
     308                s = set_add(&acc->set, "line-auth-token", NULL, NULL, acc);
     309                s->flags |= SET_HIDDEN;
     310        }
     311
    283312        /* Go through all away states to figure out if away/status messages
    284313           are possible. */
     
    339368                purple_account_set_check_mail(pa, set_getbool(&acc->set, "mail_notifications"));
    340369        }
     370
     371        if (g_strcmp0(prpl->info->id, "prpl-line") == 0) {
     372                const char *name = "line-auth-token";
     373                purple_account_set_string(pa, name, set_getstr(&acc->set, name));
     374        }
    341375}
    342376
     
    367401        purple_account_set_password(pd->account, acc->pass);
    368402        purple_sync_settings(acc, pd->account);
     403
     404        if (purple_account_should_set_nick(acc)) {
     405                pd->flags = PURPLE_OPT_SHOULD_SET_NICK;
     406        }
    369407
    370408        purple_account_set_enabled(pd->account, "BitlBee", TRUE);
     
    736774        struct groupchat *gc;
    737775        GList *info, *l;
     776        GString *missing_settings = NULL;
    738777
    739778        if (!pi->chat_info || !pi->chat_info_defaults ||
     
    761800                } else if (strcmp(pce->identifier, "passwd") == 0) {
    762801                        g_hash_table_replace(chat_hash, "passwd", g_strdup(password));
     802                } else {
     803                        char *key, *value;
     804
     805                        key = g_strdup_printf("purple_%s", pce->identifier);
     806                        str_reject_chars(key, " -", '_');
     807
     808                        if ((value = set_getstr(sets, key))) {
     809                                /* sync from bitlbee to the prpl */
     810                                g_hash_table_replace(chat_hash, (char *) pce->identifier, g_strdup(value));
     811                        } else if ((value = g_hash_table_lookup(chat_hash, pce->identifier))) {
     812                                /* if the bitlbee one was empty, sync from prpl to bitlbee */
     813                                set_setstr(sets, key, value);
     814                        }
     815
     816                        g_free(key);
     817                }
     818
     819                if (pce->required && !g_hash_table_lookup(chat_hash, pce->identifier)) {
     820                        if (!missing_settings) {
     821                                missing_settings = g_string_sized_new(32);
     822                        }
     823                        g_string_append_printf(missing_settings, "%s, ", pce->identifier);
    763824                }
    764825
     
    767828
    768829        g_list_free(info);
     830
     831        if (missing_settings) {
     832                /* remove the ", " from the end */
     833                g_string_truncate(missing_settings, missing_settings->len - 2);
     834
     835                imcb_error(ic, "Can't join %s. The following settings are required: %s", room, missing_settings->str);
     836
     837                g_string_free(missing_settings, TRUE);
     838                g_hash_table_destroy(chat_hash);
     839                return NULL;
     840        }
    769841
    770842        /* do this before serv_join_chat to handle cases where prplcb_conv_new is called immediately (not async) */
     
    801873                purple_roomlist_ref(list);
    802874        }
     875}
     876
     877/* handles either prpl->chat_(add|free)_settings depending on the value of 'add' */
     878static void purple_chat_update_settings(account_t *acc, set_t **head, gboolean add)
     879{
     880        PurplePlugin *prpl = purple_plugins_find_with_id((char *) acc->prpl->data);
     881        PurplePluginProtocolInfo *pi = prpl->info->extra_info;
     882        GList *info, *l;
     883
     884        if (!pi->chat_info || !pi->chat_info_defaults) {
     885                return;
     886        }
     887
     888        /* hack / leap of faith: pass a NULL here because we don't have a connection yet.
     889         * i reviewed all the built-in prpls and a bunch of third-party ones and none
     890         * of them seem to need this parameter at all, so... i hope it never crashes */
     891        info = pi->chat_info(NULL);
     892
     893        for (l = info; l; l = l->next) {
     894                struct proto_chat_entry *pce = l->data;
     895                char *key;
     896
     897                if (strcmp(pce->identifier, "handle") == 0 ||
     898                    strcmp(pce->identifier, "password") == 0 ||
     899                    strcmp(pce->identifier, "passwd") == 0) {
     900                        /* skip these, they are handled above */
     901                        g_free(pce);
     902                        continue;
     903                }
     904
     905                key = g_strdup_printf("purple_%s", pce->identifier);
     906                str_reject_chars(key, " -", '_');
     907
     908                if (add) {
     909                        set_add(head, key, NULL, NULL, NULL);
     910                } else {
     911                        set_del(head, key);
     912                }
     913
     914                g_free(key);
     915                g_free(pce);
     916        }
     917
     918        g_list_free(NULL);
     919        g_list_free(info);
     920}
     921
     922static void purple_chat_add_settings(account_t *acc, set_t **head)
     923{
     924        purple_chat_update_settings(acc, head, TRUE);
     925}
     926
     927static void purple_chat_free_settings(account_t *acc, set_t **head)
     928{
     929        purple_chat_update_settings(acc, head, FALSE);
    803930}
    804931
     
    839966{
    840967        struct im_connection *ic = purple_ic_by_gc(gc);
    841         const char *dn;
     968        struct purple_data *pd = ic->proto_data;
     969        const char *dn, *token;
    842970        set_t *s;
    843971
     
    852980        // user list needs to be requested for Gadu-Gadu
    853981        purple_gg_buddylist_import(gc);
     982
     983        /* more awful hacks, because clearly we didn't have enough of those */
     984        if ((s = set_find(&ic->acc->set, "line-auth-token")) &&
     985            (token = purple_account_get_string(pd->account, "line-auth-token", NULL))) {
     986                g_free(s->value);
     987                s->value = g_strdup(token);
     988        }
    854989
    855990        ic->flags |= OPT_DOES_HTML;
     
    9031038                PurpleGroup *group = purple_buddy_get_group(bud);
    9041039                struct im_connection *ic = purple_ic_by_pa(bud->account);
     1040                struct purple_data *pd = ic->proto_data;
    9051041                PurpleStatus *as;
    9061042                int flags = 0;
     1043                char *alias = NULL;
    9071044
    9081045                if (ic == NULL) {
     
    9101047                }
    9111048
    912                 if (bud->server_alias) {
    913                         imcb_rename_buddy(ic, bud->name, bud->server_alias);
    914                 } else if (bud->alias) {
    915                         imcb_rename_buddy(ic, bud->name, bud->alias);
     1049                alias = bud->server_alias ? : bud->alias;
     1050
     1051                if (alias) {
     1052                        imcb_rename_buddy(ic, bud->name, alias);
     1053                        if (pd->flags & PURPLE_OPT_SHOULD_SET_NICK) {
     1054                                imcb_buddy_nick_change(ic, bud->name, alias);
     1055                        }
    9161056                }
    9171057
     
    10571197}
    10581198
    1059 /* Handles write_im and write_chat. Removes echoes of locally sent messages */
     1199/* Handles write_im and write_chat. Removes echoes of locally sent messages.
     1200 *
     1201 * PURPLE_MESSAGE_DELAYED is used for chat backlogs - if a message has both
     1202 * that flag and _SEND, it's a self-message from before joining the channel.
     1203 * Those are safe to display. The rest (with just _SEND) may be echoes. */
    10601204static void prplcb_conv_msg(PurpleConversation *conv, const char *who, const char *message, PurpleMessageFlags flags, time_t mtime)
    10611205{
    1062         if (!(flags & PURPLE_MESSAGE_SEND)) {
    1063                 handle_conv_msg(conv, who, message, 0, mtime);
     1206        if ((!(flags & PURPLE_MESSAGE_SEND)) || (flags & PURPLE_MESSAGE_DELAYED)) {
     1207                handle_conv_msg(conv, who, message, (flags & PURPLE_MESSAGE_SEND) ? OPT_SELFMESSAGE : 0, mtime);
    10641208        }
    10651209}
     
    13871531}
    13881532
     1533static char *prplcb_roomlist_get_room_name(PurpleRoomlist *list, PurpleRoomlistRoom *room)
     1534{
     1535        struct im_connection *ic = purple_ic_by_pa(list->account);
     1536        struct purple_data *pd = ic->proto_data;
     1537        PurplePlugin *prpl = purple_plugins_find_with_id(pd->account->protocol_id);
     1538        PurplePluginProtocolInfo *pi = prpl->info->extra_info;
     1539
     1540        if (pi && pi->roomlist_room_serialize) {
     1541                return pi->roomlist_room_serialize(room);
     1542        } else {
     1543                return g_strdup(purple_roomlist_room_get_name(room));
     1544        }
     1545}
     1546
    13891547static void prplcb_roomlist_add_room(PurpleRoomlist *list, PurpleRoomlistRoom *room)
    13901548{
    13911549        bee_chat_info_t *ci;
    1392         const char *title;
     1550        char *title;
    13931551        const char *topic;
    13941552        GList *fields;
     
    13961554
    13971555        fields = purple_roomlist_room_get_fields(room);
    1398         title = purple_roomlist_room_get_name(room);
     1556        title = prplcb_roomlist_get_room_name(list, room);
    13991557
    14001558        if (rld->topic >= 0) {
     
    14051563
    14061564        ci = g_new(bee_chat_info_t, 1);
    1407         ci->title = g_strdup(title);
     1565        ci->title = title;
    14081566        ci->topic = g_strdup(topic);
    14091567        rld->chats = g_slist_prepend(rld->chats, ci);
     
    16271785}
    16281786
     1787/* borrowing this semi-private function
     1788 * TODO: figure out a better interface later (famous last words) */
     1789gboolean plugin_info_add(struct plugin_info *info);
     1790
    16291791void purple_initmodule()
    16301792{
     
    16331795        GString *help;
    16341796        char *dir;
     1797        gboolean debug_enabled = !!getenv("BITLBEE_DEBUG");
    16351798
    16361799        if (purple_get_core() != NULL) {
     
    16401803        }
    16411804
    1642         g_assert((int) B_EV_IO_READ == (int) PURPLE_INPUT_READ);
    1643         g_assert((int) B_EV_IO_WRITE == (int) PURPLE_INPUT_WRITE);
     1805        g_return_if_fail((int) B_EV_IO_READ == (int) PURPLE_INPUT_READ);
     1806        g_return_if_fail((int) B_EV_IO_WRITE == (int) PURPLE_INPUT_WRITE);
    16441807
    16451808        dir = g_strdup_printf("%s/purple", global.conf->configdir);
     
    16511814        g_free(dir);
    16521815
    1653         purple_debug_set_enabled(FALSE);
     1816        purple_debug_set_enabled(debug_enabled);
    16541817        purple_core_set_ui_ops(&bee_core_uiops);
    16551818        purple_eventloop_set_ui_ops(&glib_eventloops);
     
    16591822                abort();
    16601823        }
     1824        purple_debug_set_enabled(FALSE);
    16611825
    16621826        if (proxytype != PROXY_NONE) {
     
    17171881        funcs.chat_join = purple_chat_join;
    17181882        funcs.chat_list = purple_chat_list;
     1883        funcs.chat_add_settings = purple_chat_add_settings;
     1884        funcs.chat_free_settings = purple_chat_free_settings;
    17191885        funcs.transfer_request = purple_transfer_request;
    17201886
     
    17271893                PurplePluginProtocolInfo *pi = prot->info->extra_info;
    17281894                struct prpl *ret;
     1895                struct plugin_info *info;
    17291896
    17301897                /* If we already have this one (as a native module), don't
     
    17611928                        register_protocol(ret);
    17621929                }
     1930
     1931                info = g_new0(struct plugin_info, 1);
     1932                info->abiver = BITLBEE_ABI_VERSION_CODE;
     1933                info->name = ret->name;
     1934                info->version = prot->info->version;
     1935                info->description = prot->info->description;
     1936                info->author = prot->info->author;
     1937                info->url = prot->info->homepage;
     1938
     1939                plugin_info_add(info);
    17631940        }
    17641941
Note: See TracChangeset for help on using the changeset viewer.