diff options
| author | Nakidai <nakidai@disroot.org> | 2026-02-10 03:38:15 +0300 |
|---|---|---|
| committer | Nakidai <nakidai@disroot.org> | 2026-02-10 03:38:15 +0300 |
| commit | db996c22cd51cd46dd9afee1085a8af04cc7b53b (patch) | |
| tree | 3fdc59fc9f7d42a1e8f96d9ca615e2d8b19a60da /channel.c | |
| parent | 15b0b805fe2e739c9d89b54e1bfb26beb79c3112 (diff) | |
| download | libreircd-db996c22cd51cd46dd9afee1085a8af04cc7b53b.tar.gz libreircd-db996c22cd51cd46dd9afee1085a8af04cc7b53b.zip | |
Add channel mode editing support
Well, an oper should have some way to manage their channel :)
Diffstat (limited to 'channel.c')
| -rw-r--r-- | channel.c | 54 |
1 files changed, 54 insertions, 0 deletions
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) { |