Changeset 5a8afc3


Ignore:
Timestamp:
2016-11-21T06:58:47Z (2 years ago)
Author:
dequis <dx@…>
Branches:
master
Children:
3f44e43, f8c9347
Parents:
11d4123
git-author:
dequis <dx@…> (21-11-16 06:40:54)
git-committer:
dequis <dx@…> (21-11-16 06:58:47)
Message:

Manual merge with wilmer's approach to handling missing protocols

Turns out he already implemented pretty much the same thing in the
parson branch... last year.

The differences between the two approaches are subtle (there aren't too
many ways to do this, some lines are the exact same thing) but I decided
I like his version better, so this mostly reverts a handful of my
changes while keeping others. The main advantage of his approach is that
no fake protocols are registered, no actual prpl functions are called,
and the missing prpl is a singleton constant.

New things compared to the implementation in the other branch:

  • The explain_unknown_protocol() function.
  • Fixed named chatrooms throwing a warning and losing the "account" setting when saving. See changes in irc_im.c
  • Fixed the "server" setting dropping when saving. See account.c

Differences with my previous implementation:

  • Accounts with missing protocols don't autoconnect
  • 'account list' marks them as "(missing!)"
Files:
1 deleted
9 edited

Legend:

Unmodified
Added
Removed
  • irc_im.c

    r11d4123 r5a8afc3  
    10141014        if (!(acc = account_get(ic->irc->b, value))) {
    10151015                return SET_INVALID;
    1016         } else if (!acc->prpl->chat_join) {
     1016        } else if (!acc->prpl->chat_join && acc->prpl != &protocol_missing) {
    10171017                irc_rootmsg(ic->irc, "Named chatrooms not supported on that account.");
    10181018                return SET_INVALID;
  • protocols/Makefile

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

    r11d4123 r5a8afc3  
    7575        s->flags |= SET_NOSAVE | ACC_SET_OFFLINE_ONLY | ACC_SET_LOCKABLE;
    7676        set_setstr(&a->set, "username", user);
     77
     78        if (prpl == &protocol_missing) {
     79                s = set_add(&a->set, "server", NULL, set_eval_account, a);
     80                s->flags |= SET_NOSAVE | SET_HIDDEN | ACC_SET_OFFLINE_ONLY | ACC_SET_ONLINE_ONLY;
     81        }
    7782
    7883        /* Hardcode some more clever tag guesses. */
  • protocols/nogaim.c

    r11d4123 r5a8afc3  
    160160GList *protocols = NULL;
    161161GList *disabled_protocols = NULL;
    162 static struct prpl *unknown_prpl;
    163162
    164163void register_protocol(struct prpl *p)
     
    190189        GList *gl = g_list_find_custom(protocols, name, proto_name_cmp);
    191190        return gl ? gl->data: NULL;
    192 }
    193 
    194 struct 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;
    200191}
    201192
     
    250241        extern void twitter_initmodule();
    251242        extern void purple_initmodule();
    252         extern void unknown_prpl_initmodule();
    253 
    254         unknown_prpl_initmodule(&unknown_prpl);
    255243
    256244#ifdef WITH_MSN
  • protocols/nogaim.h

    r11d4123 r5a8afc3  
    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,
    164161} prpl_options_t;
    165162
     
    324321G_MODULE_EXPORT struct prpl *find_protocol(const char *name);
    325322G_MODULE_EXPORT gboolean is_protocol_disabled(const char *name);
    326 G_MODULE_EXPORT struct prpl *make_unknown_protocol(const char *name);
    327323G_MODULE_EXPORT char *explain_unknown_protocol(const char *name);
    328324/* When registering a new protocol, you should allocate space for a new prpl
  • root_commands.c

    r11d4123 r5a8afc3  
    498498
    499499                for (a = irc->b->accounts; a; a = a->next) {
    500                         char *con;
     500                        char *con = NULL, *protocol = NULL;
    501501
    502502                        if (a->ic && (a->ic->flags & OPT_LOGGED_IN)) {
     
    510510                        }
    511511
    512                         irc_rootmsg(irc, "%2d (%s): %s, %s%s", i, a->tag, a->prpl->name, a->user, con);
     512                        if (a->prpl == &protocol_missing) {
     513                                protocol = g_strdup_printf("%s (missing!)", set_getstr(&a->set, "_protocol_name"));
     514                        } else {
     515                                protocol = g_strdup(a->prpl->name);
     516                        }
     517
     518                        irc_rootmsg(irc, "%2d (%s): %s, %s%s", i, a->tag, protocol, a->user, con);
     519                        g_free(protocol);
    513520
    514521                        i++;
     
    524531
    525532                        for (a = irc->b->accounts; a; a = a->next) {
    526                                 if (!a->ic && a->auto_connect) {
     533                                if (!a->ic && a->auto_connect && a->prpl != &protocol_missing) {
    527534                                        if (strcmp(a->pass, PASSWORD_PENDING) == 0) {
    528535                                                irc_rootmsg(irc, "Enter password for account %s "
     
    584591                        irc_rootmsg(irc, "Enter password for account %s "
    585592                                    "first (use /OPER)", a->tag);
     593                } else if (a->prpl == &protocol_missing) {
     594                        char *proto = set_getstr(&a->set, "_protocol_name");
     595                        char *msg = explain_unknown_protocol(proto);
     596                        irc_rootmsg(irc, "Unknown protocol `%s'", proto);
     597                        irc_rootmsg(irc, msg);
     598                        g_free(msg);
    586599                } else {
    587600                        account_on(irc->b, a);
  • storage.c

    r11d4123 r5a8afc3  
    3232
    3333static GList *storage_backends = NULL;
     34
     35const struct prpl protocol_missing = {
     36        .name = "_unknown",
     37};
    3438
    3539void register_storage_backend(storage_t *backend)
  • storage.h

    r11d4123 r5a8afc3  
    6363G_GNUC_MALLOC GList *storage_init(const char *primary, char **migrate);
    6464
     65extern const struct prpl protocol_missing;
     66
    6567#endif /* __STORAGE_H__ */
  • storage_xml.c

    r11d4123 r5a8afc3  
    6060}
    6161
    62 static void handle_settings(struct xt_node *node, set_t **head, gboolean add_unknowns)
     62static void handle_settings(struct xt_node *node, set_t **head)
    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);
    7972                        continue;
    8073                }
     
    9386                        }
    9487                }
     88        }
     89}
     90
     91/* Use for unsupported/not-found protocols. Save settings as-is but don't allow changes. */
     92static void handle_settings_raw(struct xt_node *node, set_t **head)
     93{
     94        struct xt_node *c;
     95
     96        for (c = node->children; (c = xt_find_node(c, "setting")); c = c->next) {
     97                char *name = xt_find_attr(c, "name");
     98
     99                if (!name) {
     100                        continue;
     101                }
     102
     103                set_t *s = set_add(head, name, NULL, NULL, NULL);
     104                set_setstr(head, name, c->text);
     105                s->flags |= SET_HIDDEN |
     106                            ACC_SET_OFFLINE_ONLY | ACC_SET_ONLINE_ONLY;
    95107        }
    96108}
     
    106118        account_t *acc;
    107119        struct xt_node *c;
    108         gboolean is_unknown = FALSE;
    109120
    110121        handle = xt_find_attr(node, "handle");
     
    120131                if (!prpl) {
    121132                        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;
     133                        prpl = (struct prpl*) &protocol_missing;
     134                }
    125135                local = protocol_account_islocal(protocol);
    126136        }
     
    158168                acc->flags |= ACC_FLAG_LOCKED;
    159169        }
     170        if (prpl == &protocol_missing) {
     171                set_t *s = set_add(&acc->set, "_protocol_name", protocol, NULL, NULL);
     172                s->flags |= SET_HIDDEN | SET_NOSAVE |
     173                            ACC_SET_OFFLINE_ONLY | ACC_SET_ONLINE_ONLY;
     174        }
    160175
    161176        g_free(pass_cr);
    162177        g_free(password);
    163178
    164         handle_settings(node, &acc->set, is_unknown);
     179        if (prpl == &protocol_missing) {
     180                handle_settings_raw(node, &acc->set);
     181        } else {
     182                handle_settings(node, &acc->set);
     183        }
    165184
    166185        for (c = node->children; (c = xt_find_node(c, "buddy")); c = c->next) {
     
    201220        }
    202221
    203         handle_settings(node, &ic->set, FALSE);
     222        handle_settings(node, &ic->set);
    204223
    205224        return XT_HANDLED;
     
    279298        }
    280299
    281         handle_settings(node, &xd->irc->b->set, FALSE);
     300        handle_settings(node, &xd->irc->b->set);
    282301
    283302error:
     
    351370
    352371                cur = xt_new_node("account", NULL, NULL);
    353                 xt_add_attr(cur, "protocol", acc->prpl->name);
     372                if (acc->prpl == &protocol_missing) {
     373                        xt_add_attr(cur, "protocol", set_getstr(&acc->set, "_protocol_name"));
     374                } else {
     375                        xt_add_attr(cur, "protocol", acc->prpl->name);
     376                }
    354377                xt_add_attr(cur, "handle", acc->user);
    355378                xt_add_attr(cur, "password", pass_b64);
Note: See TracChangeset for help on using the changeset viewer.