diff options
Diffstat (limited to 'handle.c')
| -rw-r--r-- | handle.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/handle.c b/handle.c index ecbde08..d11b39a 100644 --- a/handle.c +++ b/handle.c @@ -76,8 +76,10 @@ join(struct Message *msg, struct Peer *peer) static int mode_channel(struct Message *msg, struct Peer *peer) { + const struct ChannelModeParam *parsed; enum ChannelPeerMode modes; struct Channel *channel; + char modebuf[2]; size_t i; for (i = 0; i < channels_c; ++i) @@ -96,6 +98,56 @@ mode_channel(struct Message *msg, struct Peer *peer) ensure(modes & CHANNEL_OPER || peer->modes & OPER, reply(peer, 482, channel->name), 0); + parsed = channel_modes_parse(msg); + for (; parsed->param || parsed->mode; ++parsed) switch (parsed->mode) + { + break; case 'o': + ensure(parsed->param, reply(peer, 461, msg->command), 0); + + for (i = 0; i < channel->peers_c; ++i) + if (!strcmp(channel->peers[i].p->nick, parsed->param)) + break; + ensure(i != channel->peers_c, reply(peer, 441, parsed->param, channel->name), 0); + + writechanf( + 0, + channel, + "%s!%s@%s MODE %s %co %s", + getnick(peer), + peer->user, + peer->host, + channel->name, + parsed->set ? '+' : '-', + parsed->param + ); + + if (parsed->set) + channel->peers[i].modes |= CHANNEL_OPER; + else + channel->peers[i].modes &= ~CHANNEL_OPER; + break; case 's': + /* TODO: implement +s. For now it's just a some mode with no param */ + writechanf( + 0, + channel, + "%s!%s@%s MODE %s %cs", + getnick(peer), + peer->user, + peer->host, + channel->name, + parsed->set ? '+' : '-' + ); + if (parsed->set) + channel->modes |= CHANNEL_SECRET; + else + channel->modes &= ~CHANNEL_SECRET; + break; default: + modebuf[0] = parsed->mode; + modebuf[1] = 0; + reply(peer, 472, modebuf, channel->name); + return 0; + } + return 0; } |