diff options
Diffstat (limited to 'irc_channel.c')
-rw-r--r-- | irc_channel.c | 103 |
1 files changed, 90 insertions, 13 deletions
diff --git a/irc_channel.c b/irc_channel.c index e2c77fc5..ee81a597 100644 --- a/irc_channel.c +++ b/irc_channel.c @@ -245,7 +245,8 @@ int irc_channel_add_user(irc_channel_t *ic, irc_user_t *iu) ic->users = g_slist_insert_sorted(ic->users, icu, irc_channel_user_cmp); if (iu == ic->irc->user || iu == ic->irc->root) { - irc_channel_update_ops(ic, set_getstr(&ic->irc->b->set, "ops")); + irc_channel_update_ops(ic, set_getstr(&ic->irc->b->set, "ops"), + set_getstr(&ic->irc->b->set, "ops_mode")); } if (iu == ic->irc->user || ic->flags & IRC_CHANNEL_JOINED) { @@ -441,7 +442,11 @@ void irc_channel_set_mode(irc_channel_t *ic, const char *s) char irc_channel_user_get_prefix(irc_channel_user_t *icu) { - if (icu->flags & IRC_CHANNEL_USER_OP) { + if (icu->flags & IRC_CHANNEL_USER_OWNER) { + return '~'; + } else if (icu->flags & IRC_CHANNEL_USER_ADMIN) { + return '&'; + } else if (icu->flags & IRC_CHANNEL_USER_OP) { return '@'; } else if (icu->flags & IRC_CHANNEL_USER_HALFOP) { return '%'; @@ -675,14 +680,33 @@ static gint irc_channel_user_cmp(gconstpointer a_, gconstpointer b_) return irc_user_cmp(a->iu, b->iu); } -void irc_channel_update_ops(irc_channel_t *ic, char *value) +static int irc_channel_prefix_to_mode(char *value) { + if (g_strcasecmp(value, "~") == 0) { + return IRC_CHANNEL_USER_OWNER; + } else if (g_strcasecmp(value, "&") == 0) { + return IRC_CHANNEL_USER_ADMIN; + } else if (g_strcasecmp(value, "@") == 0) { + return IRC_CHANNEL_USER_OP; + } else if (g_strcasecmp(value, "%") == 0) { + return IRC_CHANNEL_USER_HALFOP; + } else if (g_strcasecmp(value, "+") == 0) { + return IRC_CHANNEL_USER_VOICE; + } else { + return 0; + } +} + +void irc_channel_update_ops(irc_channel_t *ic, char *ops, char *ops_mode) +{ + int mode = irc_channel_prefix_to_mode(ops_mode); + irc_channel_user_set_mode(ic, ic->irc->root, - (strcmp(value, "both") == 0 || - strcmp(value, "root") == 0) ? IRC_CHANNEL_USER_OP : 0); + (strcmp(ops, "both") == 0 || + strcmp(ops, "root") == 0) ? mode : 0); irc_channel_user_set_mode(ic, ic->irc->user, - (strcmp(value, "both") == 0 || - strcmp(value, "user") == 0) ? IRC_CHANNEL_USER_OP : 0); + (strcmp(ops, "both") == 0 || + strcmp(ops, "user") == 0) ? mode : 0); } char *set_eval_irc_channel_ops(set_t *set, char *value) @@ -696,7 +720,27 @@ char *set_eval_irc_channel_ops(set_t *set, char *value) } for (l = irc->channels; l; l = l->next) { - irc_channel_update_ops(l->data, value); + irc_channel_update_ops(l->data, value, set_getstr(&irc->b->set, "ops_mode")); + } + + return value; +} + +char *set_eval_irc_channel_ops_mode(set_t *set, char *value) +{ + irc_t *irc = set->data; + GSList *l; + + if (g_strcasecmp(value, "~") != 0 && + g_strcasecmp(value, "&") != 0 && + g_strcasecmp(value, "@") != 0 && + g_strcasecmp(value, "%") != 0 && + g_strcasecmp(value, "+") != 0) { + return SET_INVALID; + } + + for (l = irc->channels; l; l = l->next) { + irc_channel_update_ops(l->data, set_getstr(&irc->b->set, "ops"), value); } return value; @@ -822,17 +866,38 @@ 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; + GSList *new_acc = NULL; + char **accounts, **account; - if (!(acc = account_get(ic->irc->b, value))) { - return SET_INVALID; + if (value == NULL) { + goto out; + } + + accounts = g_strsplit(value, ",", 0); + for (account = accounts; *account; account++) { + if (!(acc = account_get(ic->irc->b, *account))) { + goto fail; + } else { + new_acc = g_slist_append(new_acc, acc); + } } + g_strfreev(accounts); + +out: + g_slist_free(icc->account); + icc->account = new_acc; - icc->account = acc; if ((icc->type & IRC_CC_TYPE_MASK) == IRC_CC_TYPE_ACCOUNT) { bee_irc_channel_update(ic->irc, ic, NULL); } - return g_strdup(acc->tag); + return g_strdup(value); + +fail: + g_slist_free(new_acc); + g_strfreev(accounts); + + return SET_INVALID; } static char *set_eval_fill_by(set_t *set, char *value) @@ -920,6 +985,10 @@ static char *set_eval_show_users(set_t *set, char *value) modechar = IRC_CHANNEL_USER_HALFOP; } else if (last == '@') { modechar = IRC_CHANNEL_USER_OP; + } else if (last == '&') { + modechar = IRC_CHANNEL_USER_ADMIN; + } else if (last == '~') { + modechar = IRC_CHANNEL_USER_OWNER; } if (strncmp(*part, "offline", 7) == 0) { @@ -952,6 +1021,7 @@ fail: gboolean irc_channel_wants_user(irc_channel_t *ic, irc_user_t *iu) { struct irc_control_channel *icc = ic->data; + GSList *accl; gboolean ret = FALSE; if (iu->bu == NULL) { @@ -963,7 +1033,13 @@ 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: - ret = iu->bu->ic->acc == icc->account; + for (accl = icc->account; accl; accl = accl->next) { + account_t *acc = accl->data; + if (iu->bu->ic->acc == acc) { + ret = TRUE; + break; + } + } break; case IRC_CC_TYPE_PROTOCOL: ret = iu->bu->ic->acc->prpl == icc->protocol; @@ -991,6 +1067,7 @@ static gboolean control_channel_free(irc_channel_t *ic) set_del(&ic->set, "protocol"); set_del(&ic->set, "show_users"); + g_slist_free(icc->account); g_free(icc); ic->data = NULL; |