aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarius Halden <marius.h@lden.org>2016-04-12 00:22:39 +0200
committerMarius Halden <marius.h@lden.org>2016-05-07 14:31:03 +0200
commitecda1fce37c21bf6925f8bb67135f15cbf22f8aa (patch)
treee2a13685fb1e2a72390881d30a09a575fd633758
parent20152af8648494fa7cc73c56c3a09c22ff6e85fe (diff)
Better handling of set account
-rw-r--r--irc.h4
-rw-r--r--irc_channel.c49
-rw-r--r--protocols/account.c88
3 files changed, 102 insertions, 39 deletions
diff --git a/irc.h b/irc.h
index c96cdad3..42d3a721 100644
--- a/irc.h
+++ b/irc.h
@@ -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);
}