diff options
Diffstat (limited to 'channel.c')
| -rw-r--r-- | channel.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/channel.c b/channel.c new file mode 100644 index 0000000..0cf0b30 --- /dev/null +++ b/channel.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2026 Nakidai Perumenei <nakidai at disroot dot org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "ircd.h" + +#include <stddef.h> +#include <string.h> + +#include <err.h> + + +struct Channel channels[CHANNELS_MAX]; +size_t channels_c; + +int +channel_join(struct Channel *channel, struct Peer *peer) +{ + if (channel->users_c == lengthof(channel->users) + || peer->channels_c == lengthof(peer->channels)) + return 1; + + peer->channels[peer->channels_c++] = channel; + channel->users[channel->users_c++] = peer; + writechanf( + 0, + channel, + ":%s!%s@%s JOIN %s", + getnick(peer), + peer->user, + peer->host, + channel->name + ); + return 0; +} + +int +channel_exit(struct Channel *channel, struct Peer *peer) +{ + size_t i; + + for (i = 0; i < channel->users_c; ++i) + if (channel->users[i]->fd == peer->fd) + break; + ensure(i != channel->users_c, (void)0, 1); + channel->users[i] = channel->users[--channel->users_c]; + + for (i = 0; i < peer->channels_c; ++i) + if (!strcmp(peer->channels[i]->name, channel->name)) + break; + ensure(i != peer->channels_c, warnx( + "channel_exit(): channel had user, but user hadn't channel" + ), 1) + peer->channels[i] = peer->channels[--peer->channels_c]; + + if (!channel->users_c) + { + for (i = 0; i < channels_c; ++i) + if (!strcmp(channels[i].name, channel->name)) + break; + ensure(i != channels_c, warnx( + "channel_exit(): couldn't find empty channel" + ), 1); + channels[i] = channels[--channels_c]; + } + + return 0; +} |