diff options
-rw-r--r-- | irc.h | 4 | ||||
-rw-r--r-- | irc_channel.c | 49 | ||||
-rw-r--r-- | protocols/account.c | 88 |
3 files changed, 102 insertions, 39 deletions
@@ -228,6 +228,8 @@ typedef struct irc_channel_user { int flags; } irc_channel_user_t; +struct account; + typedef enum { IRC_CC_TYPE_DEFAULT = 0x00001, IRC_CC_TYPE_REST = 0x00002, /* Still not implemented. */ @@ -241,7 +243,7 @@ typedef enum { struct irc_control_channel { irc_control_channel_type_t type; struct bee_group *group; - struct account *account; + GSList *account; struct prpl *protocol; char modes[5]; }; diff --git a/irc_channel.c b/irc_channel.c index 583b6d20..739360de 100644 --- a/irc_channel.c +++ b/irc_channel.c @@ -871,9 +871,9 @@ static char *set_eval_by_account(set_t *set, char *value) struct irc_channel *ic = set->data; struct irc_control_channel *icc = ic->data; account_t *acc; - struct acclist *accl, *tmp, *new_acc = NULL; - + GSList *accl, *new_acc = NULL; char **accounts, **account; + accounts = g_strsplit(value, ",", 0); if (accounts == NULL) { goto fail; @@ -883,25 +883,14 @@ static char *set_eval_by_account(set_t *set, char *value) if (!(acc = account_get(ic->irc->b, *account))) { goto fail; } else { - tmp = g_malloc(sizeof(struct account)); - if (tmp == NULL) { - goto fail; - } else { - tmp->acc = acc; - tmp->next = new_acc; - new_acc = tmp; - } + new_acc = g_slist_append(new_acc, account); } } - accl = (struct acclist *)icc->account; - while (accl) { - tmp = accl->next; - g_free(accl); - accl = tmp; - } + accl = icc->account; + g_slist_free(accl); - icc->account = (struct account *)new_acc; + icc->account = new_acc; if ((icc->type & IRC_CC_TYPE_MASK) == IRC_CC_TYPE_ACCOUNT) { bee_irc_channel_update(ic->irc, ic, NULL); } @@ -911,13 +900,7 @@ static char *set_eval_by_account(set_t *set, char *value) return g_strdup(value); fail: - accl = new_acc; - while (accl) { - tmp = accl->next; - g_free(accl); - accl = tmp; - } - + g_slist_free(new_acc); g_strfreev(accounts); return SET_INVALID; @@ -1044,7 +1027,7 @@ fail: gboolean irc_channel_wants_user(irc_channel_t *ic, irc_user_t *iu) { struct irc_control_channel *icc = ic->data; - struct acclist *accl; + GSList *accl; gboolean ret = FALSE; if (iu->bu == NULL) { @@ -1056,13 +1039,12 @@ gboolean irc_channel_wants_user(irc_channel_t *ic, irc_user_t *iu) ret = iu->bu->group == icc->group; break; case IRC_CC_TYPE_ACCOUNT: - accl = (struct acclist *)icc->account; - while (accl) { - if (iu->bu->ic->acc == accl->acc) { + for (accl = icc->account; accl; accl = accl->next) { + account_t *acc = accl->data; + if (iu->bu->ic->acc == acc) { ret = TRUE; break; } - accl = accl->next; } break; case IRC_CC_TYPE_PROTOCOL: @@ -1084,7 +1066,6 @@ gboolean irc_channel_wants_user(irc_channel_t *ic, irc_user_t *iu) static gboolean control_channel_free(irc_channel_t *ic) { struct irc_control_channel *icc = ic->data; - struct acclist *accl, *tmp; set_del(&ic->set, "account"); set_del(&ic->set, "fill_by"); @@ -1092,13 +1073,7 @@ static gboolean control_channel_free(irc_channel_t *ic) set_del(&ic->set, "protocol"); set_del(&ic->set, "show_users"); - accl = (struct acclist *)icc->account; - while (accl) { - tmp = accl->next; - g_free(accl); - accl = tmp; - } - + g_slist_free(icc->account); g_free(icc); ic->data = NULL; diff --git a/protocols/account.c b/protocols/account.c index e25e40c7..6f6ad339 100644 --- a/protocols/account.c +++ b/protocols/account.c @@ -163,14 +163,55 @@ 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) { + gboolean found = FALSE; + char **account, **accounts; + char *saccount = set_getstr(&ic->set, "account"); + + if (saccount == NULL || *saccount == '\0') { + continue; + } + + accounts = g_strsplit(saccount, ",", 0); + for (account = accounts; *account; account++) { + if (g_strcasecmp(*account, old) == 0) { + fprintf(stderr, "Found\n"); + found = TRUE; + g_free(*account); + *account = g_strdup(value); + break; + } + } + + if (found) { + saccount = g_strjoinv(",", accounts); + g_strfreev(accounts); + + fprintf(stderr, "%s\n", saccount); + set_setstr(&ic->set, "account", saccount); + + g_free(saccount); + } + } + } + + g_free(old); return value; } else if (strcmp(set->key, "auto_connect") == 0) { if (!is_bool(value)) { @@ -294,6 +335,8 @@ account_t *account_by_tag(bee_t *bee, const char *tag) 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. */ @@ -317,6 +360,49 @@ void account_del(bee_t *bee, account_t *acc) } */ + 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) { + gboolean found = FALSE; + char **account, **accounts; + char *saccount = set_getstr(&ic->set, "account"); + + if (saccount == NULL || *saccount == '\0') { + continue; + } + + accounts = g_strsplit(saccount, ",", 0); + for (account = accounts; *account; account++) { + if (g_strcasecmp(*account, acc->tag) == 0) { + found = TRUE; + break; + } + } + + if (found) { + g_free(*account); + + for (;;) { + *account = *(account + 1); + + account++; + if (*account == NULL) { + break; + } + } + + saccount = g_strjoinv(",", accounts); + g_strfreev(accounts); + + set_setstr(&ic->set, "account", saccount); + + g_free(saccount); + } + } + } + while (a->set) { set_del(&a->set, a->set->key); } |