Changeset b4f496e


Ignore:
Timestamp:
2016-11-19T07:32:48Z (5 years ago)
Author:
dequis <dx@…>
Branches:
master
Children:
a7baf40
Parents:
9f03c47
Message:

Improve handling of unknown protocols / missing plugins

Instead of failing to load the config, a fake prpl is created to load
the account, keep its settings, and refuse to log in with a helpful
error message.

Also added a new explain_unknown_protocol() function which returns text
which attempts to explain why a protocol is missing, handling several
typical cases, including the future removal of several dead libpurple
plugins.

That message is shown when logging in to a loaded account with a missing
protocol and when adding a new one with 'account add', with the
difference that the latter doesn't leave a placeholder fake account.

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • protocols/Makefile

    r9f03c47 rb4f496e  
    1313
    1414# [SH] Program variables
    15 objects = account.o bee.o bee_chat.o bee_ft.o bee_user.o nogaim.o
     15objects = account.o bee.o bee_chat.o bee_ft.o bee_user.o nogaim.o unknown.o
    1616
    1717
  • protocols/nogaim.c

    r9f03c47 rb4f496e  
    160160GList *protocols = NULL;
    161161GList *disabled_protocols = NULL;
     162static struct prpl *unknown_prpl;
    162163
    163164void register_protocol(struct prpl *p)
     
    191192}
    192193
     194struct prpl *make_unknown_protocol(const char *name)
     195{
     196        struct prpl *ret = g_memdup(unknown_prpl, sizeof(struct prpl));
     197        ret->name = g_strdup(name);
     198        register_protocol(ret);
     199        return ret;
     200}
     201
    193202gboolean is_protocol_disabled(const char *name)
    194203{
    195204        return g_list_find_custom(disabled_protocols, name, proto_name_cmp) != NULL;
     205}
     206
     207/* Returns heap allocated string with text attempting to explain why a protocol is missing
     208 * Free the return value with g_free() */
     209char *explain_unknown_protocol(const char *name)
     210{
     211        char *extramsg = NULL;
     212
     213        if (is_protocol_disabled(name)) {
     214                return g_strdup("Protocol disabled in the global config (bitlbee.conf)");
     215        }
     216
     217        if (strcmp(name, "yahoo") == 0) {
     218                return g_strdup("The old yahoo protocol is gone, try the funyahoo++ libpurple plugin instead.");
     219        }
     220
     221#ifdef WITH_PURPLE
     222        if ((strcmp(name, "msn") == 0) ||
     223            (strcmp(name, "loubserp-mxit") == 0) ||
     224            (strcmp(name, "myspace") == 0)) {
     225                return g_strdup("This protocol has been removed from your libpurple version.");
     226        }
     227
     228        if (strcmp(name, "hipchat") == 0) {
     229                return g_strdup("This account type isn't supported by libpurple's jabber.");
     230        }
     231
     232#else
     233        if (strcmp(name, "aim") == 0 || strcmp(name, "icq") == 0) {
     234                return g_strdup("This account uses libpurple specific aliases for oscar. "
     235                                "Re-add the account with `account add oscar ...'");
     236        }
     237
     238        extramsg = "If this is a libpurple plugin, you might need to install bitlbee-libpurple instead.";
     239#endif
     240        return g_strconcat("The protocol plugin is not installed or could not be loaded. "
     241                           "Use the `plugins' command to list available protocols. ",
     242                           extramsg, NULL);
    196243}
    197244
     
    204251        extern void twitter_initmodule();
    205252        extern void purple_initmodule();
     253        extern void unknown_prpl_initmodule();
     254
     255        unknown_prpl_initmodule(&unknown_prpl);
    206256
    207257#ifdef WITH_MSN
  • protocols/nogaim.h

    r9f03c47 rb4f496e  
    159159        /* The protocol is not suitable for OTR, see OPT_NOOTR */
    160160        PRPL_OPT_NOOTR = 1 << 12,
     161
     162        /* This prpl is a placeholder for a missing protocol */
     163        PRPL_OPT_UNKNOWN_PROTOCOL = 1 << 13,
    161164} prpl_options_t;
    162165
     
    321324G_MODULE_EXPORT struct prpl *find_protocol(const char *name);
    322325G_MODULE_EXPORT gboolean is_protocol_disabled(const char *name);
     326G_MODULE_EXPORT struct prpl *make_unknown_protocol(const char *name);
     327G_MODULE_EXPORT char *explain_unknown_protocol(const char *name);
    323328/* When registering a new protocol, you should allocate space for a new prpl
    324329 * struct, initialize it (set the function pointers to point to your
  • root_commands.c

    r9f03c47 rb4f496e  
    439439
    440440                if (prpl == NULL) {
    441                         if (is_protocol_disabled(cmd[2])) {
    442                                 irc_rootmsg(irc, "Protocol disabled in global config");
    443                         } else {
    444                                 irc_rootmsg(irc, "Unknown protocol");
    445                         }
     441                        char *msg = explain_unknown_protocol(cmd[2]);
     442                        irc_rootmsg(irc, "Unknown protocol");
     443                        irc_rootmsg(irc, msg);
     444                        g_free(msg);
    446445                        return;
    447446                }
  • storage_xml.c

    r9f03c47 rb4f496e  
    6060}
    6161
    62 static void handle_settings(struct xt_node *node, set_t **head)
     62static void handle_settings(struct xt_node *node, set_t **head, gboolean add_unknowns)
    6363{
    6464        struct xt_node *c;
     
    7070
    7171                if (!name) {
     72                        continue;
     73                }
     74
     75                if (add_unknowns && !set_find(head, name)) {
     76                        s = set_add(head, name, NULL, NULL, NULL);
     77                        s->flags |= ACC_SET_ONLINE_ONLY;
     78                        s->value = g_strdup(c->text);
    7279                        continue;
    7380                }
     
    99106        account_t *acc;
    100107        struct xt_node *c;
     108        gboolean is_unknown = FALSE;
    101109
    102110        handle = xt_find_attr(node, "handle");
     
    111119                prpl = find_protocol(protocol);
    112120                if (!prpl) {
    113                         irc_rootmsg(xd->irc, "Error loading user config: Protocol not found: `%s'", protocol);
    114                         return XT_ABORT;
    115                 }
     121                        irc_rootmsg(xd->irc, "Warning: Protocol not found: `%s'", protocol);
     122                        prpl = make_unknown_protocol(protocol);
     123                }
     124                is_unknown = (prpl->options & PRPL_OPT_UNKNOWN_PROTOCOL) != 0;
    116125                local = protocol_account_islocal(protocol);
    117126        }
     
    153162        g_free(password);
    154163
    155         handle_settings(node, &acc->set);
     164        handle_settings(node, &acc->set, is_unknown);
    156165
    157166        for (c = node->children; (c = xt_find_node(c, "buddy")); c = c->next) {
     
    192201        }
    193202
    194         handle_settings(node, &ic->set);
     203        handle_settings(node, &ic->set, FALSE);
    195204
    196205        return XT_HANDLED;
     
    270279        }
    271280
    272         handle_settings(node, &xd->irc->b->set);
     281        handle_settings(node, &xd->irc->b->set, FALSE);
    273282
    274283error:
Note: See TracChangeset for help on using the changeset viewer.