aboutsummaryrefslogtreecommitdiffstats
path: root/irc_channel.c
diff options
context:
space:
mode:
Diffstat (limited to 'irc_channel.c')
-rw-r--r--irc_channel.c103
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;