diff options
author | dequis <dx@dxzone.com.ar> | 2016-11-21 03:40:54 -0300 |
---|---|---|
committer | dequis <dx@dxzone.com.ar> | 2016-11-21 03:58:47 -0300 |
commit | 5a8afc3f24a5308799d3960cab5726228345022d (patch) | |
tree | dc4569f0190238e20b3ae2c7ddb7feb2db27380d /storage_xml.c | |
parent | 11d4123fe9a4d88d475bee6c623fb80af8fdbb0b (diff) |
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!)"
Diffstat (limited to 'storage_xml.c')
-rw-r--r-- | storage_xml.c | 53 |
1 files changed, 38 insertions, 15 deletions
diff --git a/storage_xml.c b/storage_xml.c index 07cdaf0f..a921524f 100644 --- a/storage_xml.c +++ b/storage_xml.c @@ -59,7 +59,7 @@ static void xml_init(void) } } -static void handle_settings(struct xt_node *node, set_t **head, gboolean add_unknowns) +static void handle_settings(struct xt_node *node, set_t **head) { struct xt_node *c; struct set *s; @@ -72,13 +72,6 @@ static void handle_settings(struct xt_node *node, set_t **head, gboolean add_unk continue; } - if (add_unknowns && !set_find(head, name)) { - s = set_add(head, name, NULL, NULL, NULL); - s->flags |= ACC_SET_ONLINE_ONLY; - s->value = g_strdup(c->text); - continue; - } - if (strcmp(node->name, "account") == 0) { set_t *s = set_find(head, name); if (s && (s->flags & ACC_SET_ONLINE_ONLY)) { @@ -95,6 +88,25 @@ static void handle_settings(struct xt_node *node, set_t **head, gboolean add_unk } } +/* Use for unsupported/not-found protocols. Save settings as-is but don't allow changes. */ +static void handle_settings_raw(struct xt_node *node, set_t **head) +{ + struct xt_node *c; + + for (c = node->children; (c = xt_find_node(c, "setting")); c = c->next) { + char *name = xt_find_attr(c, "name"); + + if (!name) { + continue; + } + + set_t *s = set_add(head, name, NULL, NULL, NULL); + set_setstr(head, name, c->text); + s->flags |= SET_HIDDEN | + ACC_SET_OFFLINE_ONLY | ACC_SET_ONLINE_ONLY; + } +} + static xt_status handle_account(struct xt_node *node, gpointer data) { struct xml_parsedata *xd = data; @@ -105,7 +117,6 @@ static xt_status handle_account(struct xt_node *node, gpointer data) struct prpl *prpl = NULL; account_t *acc; struct xt_node *c; - gboolean is_unknown = FALSE; handle = xt_find_attr(node, "handle"); pass_b64 = xt_find_attr(node, "password"); @@ -119,9 +130,8 @@ static xt_status handle_account(struct xt_node *node, gpointer data) prpl = find_protocol(protocol); if (!prpl) { irc_rootmsg(xd->irc, "Warning: Protocol not found: `%s'", protocol); - prpl = make_unknown_protocol(protocol); + prpl = (struct prpl*) &protocol_missing; } - is_unknown = (prpl->options & PRPL_OPT_UNKNOWN_PROTOCOL) != 0; local = protocol_account_islocal(protocol); } @@ -157,11 +167,20 @@ static xt_status handle_account(struct xt_node *node, gpointer data) if (locked && !g_strcasecmp(locked, "true")) { acc->flags |= ACC_FLAG_LOCKED; } + if (prpl == &protocol_missing) { + set_t *s = set_add(&acc->set, "_protocol_name", protocol, NULL, NULL); + s->flags |= SET_HIDDEN | SET_NOSAVE | + ACC_SET_OFFLINE_ONLY | ACC_SET_ONLINE_ONLY; + } g_free(pass_cr); g_free(password); - handle_settings(node, &acc->set, is_unknown); + if (prpl == &protocol_missing) { + handle_settings_raw(node, &acc->set); + } else { + handle_settings(node, &acc->set); + } for (c = node->children; (c = xt_find_node(c, "buddy")); c = c->next) { char *handle, *nick; @@ -200,7 +219,7 @@ static xt_status handle_channel(struct xt_node *node, gpointer data) set_setstr(&ic->set, "type", type); } - handle_settings(node, &ic->set, FALSE); + handle_settings(node, &ic->set); return XT_HANDLED; } @@ -278,7 +297,7 @@ static storage_status_t xml_load_real(irc_t *irc, const char *my_nick, const cha ret = STORAGE_OK; } - handle_settings(node, &xd->irc->b->set, FALSE); + handle_settings(node, &xd->irc->b->set); error: xt_free(xp); @@ -350,7 +369,11 @@ struct xt_node *xml_generate(irc_t *irc) } cur = xt_new_node("account", NULL, NULL); - xt_add_attr(cur, "protocol", acc->prpl->name); + if (acc->prpl == &protocol_missing) { + xt_add_attr(cur, "protocol", set_getstr(&acc->set, "_protocol_name")); + } else { + xt_add_attr(cur, "protocol", acc->prpl->name); + } xt_add_attr(cur, "handle", acc->user); xt_add_attr(cur, "password", pass_b64); xt_add_attr(cur, "autoconnect", acc->auto_connect ? "true" : "false"); |