chanlog_time(chan->topic_when);
sendbuf_chan(chan);
}
+ } else if(strcmp(command, "INVITE") == 0) {
+ if (!is_registered(client))
+ return err_notregistered(client), sendbuf(client), 0;
+ if (!args[0]) {
+ // List pending invites
+ struct trie_find *f = NULL;
+ if (trie_findfirst(&f, &client->invites) == 1)
+ do {
+ struct channel *chan = f->n->value;
+ copy_strf(&databuf, ":%s 336 %s %s\n", hostname, client->nick, chan->name);
+ sendbuf(client);
+ } while(trie_findnext(&f) == 1);
+ copy_strf(&databuf, ":%s 337 %s :End of /INVITE list\n", hostname, client->nick);
+ sendbuf(client);
+ return 0;
+ }
+ if (!args[1])
+ return err_needmoreparams(client, command), sendbuf(client), 0;
+ struct channel *chan = findChannel(args[1]);
+ if (!chan)
+ return err_nosuchchannel(client, args[1]), sendbuf(client), 0;
+ if (chan->dmode & DMODE_INVITEONLY) {
+ 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;
+ }
+ } else {
+ if (!trie_get(&chan->members, client->key))
+ return err_notonchannel(client, chan), sendbuf(client), 0;
+ }
+ struct client_data *cl = findClient(args[0]);
+ if (!cl)
+ return err_nosuchnick(client, args[0]), sendbuf(client), 0;
+ if (trie_get(&chan->members, cl->key))
+ return err_useronchannel(client, cl->nick, chan), sendbuf(client), 0;
+ trie_set(&chan->invitees, cl->nick, cl, NULL);
+ trie_set(&cl->invites, chan->name, chan, NULL);
+ copy_strf(&databuf, ":%s 341 %s %s %s\r\n", hostname, client->nick, cl->nick, chan->name);
+ sendbuf(client);
+ msg_invite(client, cl, chan);
+ sendbuf(cl);
} else if(strcmp(command, "PRIVMSG") == 0 || strcmp(command, "NOTICE") == 0) {
if (!is_registered(client))
return err_notregistered(client), sendbuf(client), 0;
return err_cannotsendtochan(client, chan->name), sendbuf(client), 0;
if (match_list(client, &chan->listb) && !match_list(client, &chan->liste))
return err_cannotsendtochan(client, chan->name), sendbuf(client), 0;
- // TODO: actual invites
- if (chan->dmode & DMODE_INVITEONLY && !match_list(client, &chan->listI))
+ if (chan->dmode & DMODE_INVITEONLY
+ && !trie_get(&chan->invitees, client->key) && !match_list(client, &chan->listI))
return err_cannotsendtochan(client, chan->name), sendbuf(client), 0;
if (chan->dmode & DMODE_NOEXTERNAL && !trie_get(&chan->members, client->key))
return err_cannotsendtochan(client, chan->name), sendbuf(client), 0;
return err_channelisfull(client, chan), sendbuf(client);
if (match_list(client, &chan->listb) && !match_list(client, &chan->liste))
return err_bannedfromchan(client, chan), sendbuf(client);
- // TODO: actual invites
- if (chan->dmode & DMODE_INVITEONLY && !match_list(client, &chan->listI))
+ if (chan->dmode & DMODE_INVITEONLY
+ && !trie_get(&chan->invitees, client->key) && !match_list(client, &chan->listI))
return err_inviteonlychan(client, chan), sendbuf(client);
}
if (trie_set(&chan->members, client->key, client, NULL) == -1)
chan->member_count--;
if (!chan->member_count && !(chan->dmode & DMODE_PERSIST)) {
trie_set(&channel_map, chan->key, NULL, NULL);
+ struct trie_find *f = NULL;
+ if (trie_findfirst(&f, &chan->invitees) == 1)
+ do {
+ struct client_data *cl = f->n->value;
+ trie_set(&cl->invites, chan->key, NULL, NULL);
+ } while(trie_findnext(&f) == 1);
free(chan->key);
free(chan->name);
free(chan->topic);
trie_free(&chan->listq);
trie_free(&chan->listwo);
trie_free(&chan->listwv);
+ trie_free(&chan->invitees);
free(chan->chankey);
free(chan);
}
src->nick, src->username, src->hostname,
chan->name, chan->topic ? chan->topic : "");
}
-#if 0
void msg_invite(struct client_data *src, struct client_data *dst, struct channel *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 442 %s %s :You're not on that channel\r\n", hostname, client->nick, chan->name);
}
-#if 0
void err_useronchannel(struct client_data *client, const char *nick, struct channel *chan) // 443
{
copy_strf(&databuf, ":%s 443 %s %s %s :is already on channel\r\n", hostname, client->nick, nick, chan->name);
}
-#endif
void err_notregistered(struct client_data *client) // 451
{
(void)client;