diff options
Diffstat (limited to 'protocols/account.c')
-rw-r--r-- | protocols/account.c | 92 |
1 files changed, 91 insertions, 1 deletions
diff --git a/protocols/account.c b/protocols/account.c index b5ff4e88..80b1d020 100644 --- a/protocols/account.c +++ b/protocols/account.c @@ -77,6 +77,8 @@ account_t *account_add(bee_t *bee, struct prpl *prpl, char *user, char *pass) s = set_add(&a->set, "username", NULL, set_eval_account, a); s->flags |= SET_NOSAVE | ACC_SET_OFFLINE_ONLY | ACC_SET_LOCKABLE; set_setstr(&a->set, "username", user); + set_add(&a->set, "offline_user_quits", "true", set_eval_bool, a); + set_add(&a->set, "offline_is_away", "false", set_eval_bool, a); if (prpl == &protocol_missing) { s = set_add(&a->set, "server", NULL, set_eval_account, a); @@ -130,6 +132,36 @@ account_t *account_add(bee_t *bee, struct prpl *prpl, char *user, char *pass) return a; } +void account_update_channel_set(irc_channel_t *ic, char *old_tag, char *new_tag) +{ + gboolean found = FALSE; + char **account, **accounts; + char *saccount = set_getstr(&ic->set, "account"); + + if (saccount == NULL || *saccount == '\0') { + return; + } + + accounts = g_strsplit(saccount, ",", 0); + for (account = accounts; *account; account++) { + if (g_strcasecmp(*account, old_tag) == 0) { + found = TRUE; + break; + } + } + + if (found) { + g_free(*account); + *account = g_strdup(new_tag); + + saccount = g_strjoinv(",", accounts); + set_setstr(&ic->set, "account", saccount); + g_free(saccount); + } + + g_strfreev(accounts); +} + char *set_eval_account(set_t *set, char *value) { account_t *acc = set->data; @@ -171,14 +203,28 @@ char *set_eval_account(set_t *set, char *value) return NULL; /* password shouldn't be visible in plaintext! */ } else if (strcmp(set->key, "tag") == 0) { account_t *oa; + irc_t *irc; + GSList *l; + char *old; /* Enforce uniqueness. */ if ((oa = account_by_tag(acc->bee, value)) && oa != acc) { return SET_INVALID; } - g_free(acc->tag); + old = acc->tag; acc->tag = g_strdup(value); + + irc = acc->bee->ui_data; + for (l = irc->channels; l; l = l->next) { + irc_channel_t *ic = l->data; + + if (g_strcasecmp(set_getstr(&ic->set, "type"), "control") == 0) { + account_update_channel_set(ic, old, value); + } + } + + g_free(old); return value; } else if (strcmp(set->key, "auto_connect") == 0) { if (!is_bool(value)) { @@ -299,9 +345,43 @@ account_t *account_by_tag(bee_t *bee, const char *tag) return NULL; } +void account_remove_from_channel_set(irc_channel_t *ic, char *tag) +{ + gboolean found = FALSE; + char **account, **accounts; + char *saccount = set_getstr(&ic->set, "account"); + + if (saccount == NULL || *saccount == '\0') { + return; + } + + accounts = g_strsplit(saccount, ",", 0); + for (account = accounts; *account; account++) { + if (g_strcasecmp(*account, tag) == 0) { + found = TRUE; + break; + } + } + + if (found) { + g_free(*account); + + do { + *account = *(account + 1); + } while (*(++account) != NULL); + + saccount = g_strjoinv(",", accounts); + set_setstr(&ic->set, "account", saccount); + } + + g_strfreev(accounts); +} + void account_del(bee_t *bee, account_t *acc) { account_t *a, *l = NULL; + GSList *accl; + irc_t *irc; if (acc->ic) { /* Caller should have checked, accounts still in use can't be deleted. */ @@ -325,6 +405,16 @@ void account_del(bee_t *bee, account_t *acc) } */ + /* Remove from channel set account */ + irc = acc->bee->ui_data; + for (accl = irc->channels; accl; accl = accl->next) { + irc_channel_t *ic = accl->data; + + if (g_strcasecmp(set_getstr(&ic->set, "type"), "control") == 0) { + account_remove_from_channel_set(ic, acc->tag); + } + } + while (a->set) { set_del(&a->set, a->set->key); } |