From db996c22cd51cd46dd9afee1085a8af04cc7b53b Mon Sep 17 00:00:00 2001 From: Nakidai Date: Tue, 10 Feb 2026 03:38:15 +0300 Subject: Add channel mode editing support Well, an oper should have some way to manage their channel :) --- channel.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'channel.c') diff --git a/channel.c b/channel.c index 21a777a..d04f3cc 100644 --- a/channel.c +++ b/channel.c @@ -79,6 +79,60 @@ channel_exit(struct Channel *channel, struct Peer *peer) return 0; } +const struct ChannelModeParam * +channel_modes_parse(const struct Message *msg) +{ + static struct ChannelModeParam modes[MESSAGE_MAX]; + size_t i, modes_c, queue_l, queue_r; + char *m, queue[PARAM_MAX]; + int set = 1; + + memset(modes, 0, sizeof(modes)); + for (modes_c = queue_l = queue_r = 0, i = 1; msg->params[i]; ++i, set = 1) switch (*msg->params[i]) + { + case '-': + set = 0; + case '+': + { + for (m = msg->params[i]+1; *m; ++m) switch (*m) + { + break; case 'o': + /* since all flags are ASCII (< 128) bit 7 + * can be and is abused for the set flag */ + if (queue_r == lengthof(queue)) + { + modes[modes_c].mode = *m; + return modes; + } + queue[queue_r++] = (set << 7) | *m; + break; case 's': + modes[modes_c].mode = *m; + modes[modes_c++].set = set; + break; default: + modes[modes_c].mode = *m; + modes[modes_c++].set = set; + return modes; + } + } break; + default: + { + modes[modes_c].param = msg->params[i]; + + if (queue_l == queue_r) + { + return modes; + } + else + { + modes[modes_c].set = !!(queue[queue_l] & (1 << 7)); + modes[modes_c++].mode = queue[queue_l++] & ~(1 << 7); + } + } break; + } + + return modes; +} + void channel_remove(size_t cid) { -- cgit 1.4.1