if (trie_findfirst(&f, &client->channels) == 1)
do {
struct channel *chan = f->n->value;
- channel_part(client, chan, "I fell for a classic prank");
+ channel_part(client, chan, "I fell for a classic prank", NULL);
} while(trie_findfirst(&f, &client->channels) == 1);
free(f);
return 0;
struct channel *chan = findChannel(channel);
if (!chan)
return err_nosuchchannel(client, args[0]), sendbuf(client), 0;
- channel_part(client, chan, args[1] ? args[1] : "");
+ channel_part(client, chan, args[1] ? args[1] : "", NULL);
} while (p);
} else if(strcmp(command, "TOPIC") == 0) {
if (!is_registered(client))
} else {
// TODO: membership check, maybe?
if (chan->dmode & DMODE_TOPICPROT && !trie_get(&chan->o, client->key))
- return 0; // error 482
+ return 0; // FIXME: error 482
free(chan->topic);
free(chan->topic_who);
if (!*args[1]) {
msg_invite(client, cl, chan);
sendbuf(cl);
sendbuf_chan_caps(chan, CAP_INVITENOTIFY, 0);
+ } else if(strcmp(command, "KICK") == 0) {
+ if (!is_registered(client))
+ return err_notregistered(client), sendbuf(client), 0;
+ if (argc < 2)
+ return err_needmoreparams(client, command), sendbuf(client), 0;
+ struct channel *chan = findChannel(args[0]);
+ if (!chan)
+ return err_nosuchchannel(client, args[0]), sendbuf(client), 0;
+ if (!trie_get(&chan->o, client->key)) {
+ copy_strf(&databuf, ":%s 482 %s :You're not channel operator\r\n", hostname, client->nick, chan->name);
+ return sendbuf(client), 0;
+ }
+ if (!trie_get(&chan->members, client->key))
+ return err_notonchannel(client, chan), sendbuf(client), 0;
+ char *p = args[1];
+ do {
+ char *nick = p;
+ if ((p = strchr(nick, ',')))
+ *p++ = '\0';
+ struct client_data *cl = findClient(nick);
+ if (!cl)
+ err_nosuchnick(client, nick), sendbuf(client);
+ else
+ channel_part(cl, chan, args[2], client);
+ } while (p);
} else if(strcmp(command, "PRIVMSG") == 0 || strcmp(command, "NOTICE") == 0) {
if (!is_registered(client))
return err_notregistered(client), sendbuf(client), 0;
// send names
channel_sendnames(client, chan);
}
-void channel_part(struct client_data *client, struct channel *chan, const char *reason)
+void channel_part(struct client_data *client, struct channel *chan, const char *reason, struct client_data *kicker)
{
if (!trie_get(&chan->members, client->key))
return;
- if (reason) {
+ if (kicker) {
+ msg_kick(kicker, client, chan, reason);
+ sendbuf_chan(chan);
+ } else if (reason) {
msg_part(client, chan, *reason ? reason : NULL);
sendbuf_chan(chan);
}
copy_strf(&databuf, ":%s!%s@%s INVITE %s %s\r\n",
src->nick, src->username, src->hostname, dst->nick, chan->name);
}
-#if 0
void msg_kick(struct client_data *src, struct client_data *who, struct channel *chan, const char *reason)
{
if (reason)
copy_strf(&databuf, ":%s!%s@%s KICK %s %s\r\n",
src->nick, src->username, src->hostname, chan->name, who->nick);
}
-#endif
void msg_privmsg(struct client_data *src, const char *dst, const char *msg)
{
copy_strf(&databuf, ":%s!%s@%s PRIVMSG %s :%s\r\n",