X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=ircd%2Fm_invite.c;h=2479753dd5f152f304cf6777d168b063c979ae68;hb=refs%2Fheads%2Fupstream;hp=1ee016cfb350dc10b45006ffbf0d3bcba8666c30;hpb=ae91ef6320f611af74e70a0db2620c338fbaa7d5;p=ircu2.10.12-pk.git diff --git a/ircd/m_invite.c b/ircd/m_invite.c index 1ee016c..2479753 100644 --- a/ircd/m_invite.c +++ b/ircd/m_invite.c @@ -79,18 +79,14 @@ * note: it is guaranteed that parv[0]..parv[parc-1] are all * non-NULL pointers. */ -#if 0 -/* - * No need to include handlers.h here the signatures must match - * and we don't need to force a rebuild of all the handlers everytime - * we add a new one to the list. --Bleep - */ -#include "handlers.h" -#endif /* 0 */ +#include "config.h" + #include "channel.h" #include "client.h" #include "hash.h" #include "ircd.h" +#include "ircd_features.h" +#include "ircd_log.h" #include "ircd_reply.h" #include "ircd_string.h" #include "list.h" @@ -101,7 +97,7 @@ #include "send.h" #include "struct.h" -#include +/* #include -- Now using assert in ircd_log.h */ /* * m_invite - generic message handler @@ -129,96 +125,76 @@ int m_invite(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) * list the channels you have an invite to. */ struct SLink *lp; - for (lp = sptr->user->invited; lp; lp = lp->next) - sendto_one(cptr, rpl_str(RPL_INVITELIST), me.name, cptr->name, - lp->value.chptr->chname); - sendto_one(cptr, rpl_str(RPL_ENDOFINVITELIST), me.name, cptr->name); + for (lp = cli_user(sptr)->invited; lp; lp = lp->next) + send_reply(cptr, RPL_INVITELIST, lp->value.chptr->chname); + send_reply(cptr, RPL_ENDOFINVITELIST); return 0; } - + if (parc < 3 || EmptyString(parv[2])) return need_more_params(sptr, "INVITE"); if (!(acptr = FindUser(parv[1]))) { - sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name, parv[0], parv[1]); + send_reply(sptr, ERR_NOSUCHNICK, parv[1]); return 0; } if (is_silenced(sptr, acptr)) return 0; - clean_channelname(parv[2]); - - if (!IsChannelPrefix(*parv[2])) - return 0; - - if (!(chptr = FindChannel(parv[2]))) { - if (IsModelessChannel(parv[2]) || IsLocalChannel(parv[2])) { - sendto_one(sptr, err_str(ERR_NOTONCHANNEL), me.name, parv[0], parv[2]); - return 0; - } - - /* Do not disallow to invite to non-existant #channels, otherwise they - would simply first be created, causing only MORE bandwidth usage. */ - - if (check_target_limit(sptr, acptr, acptr->name, 0)) - return 0; - - sendto_one(sptr, rpl_str(RPL_INVITING), me.name, parv[0], - acptr->name, parv[2]); - - if (acptr->user->away) - sendto_one(sptr, rpl_str(RPL_AWAY), me.name, parv[0], - acptr->name, acptr->user->away); - - if (MyUser(acptr)) - sendto_prefix_one(acptr, sptr, ":%s " MSG_INVITE " %s :%s", sptr->name, - acptr->name, parv[2]); - else - sendto_one(acptr, "%s%s " TOK_INVITE " %s :%s", NumNick(sptr), - acptr->name, parv[2]); - + if (!IsChannelName(parv[2]) + || !strIsIrcCh(parv[2]) + || !(chptr = FindChannel(parv[2]))) { + send_reply(sptr, ERR_NOSUCHCHANNEL, parv[2]); return 0; } if (!find_channel_member(sptr, chptr)) { - sendto_one(sptr, err_str(ERR_NOTONCHANNEL), me.name, parv[0], - chptr->chname); + send_reply(sptr, ERR_NOTONCHANNEL, chptr->chname); return 0; } if (find_channel_member(acptr, chptr)) { - sendto_one(sptr, err_str(ERR_USERONCHANNEL), - me.name, parv[0], acptr->name, chptr->chname); + send_reply(sptr, ERR_USERONCHANNEL, cli_name(acptr), chptr->chname); return 0; } if (!is_chan_op(sptr, chptr)) { - sendto_one(sptr, err_str(ERR_CHANOPRIVSNEEDED), - me.name, parv[0], chptr->chname); + send_reply(sptr, ERR_CHANOPRIVSNEEDED, chptr->chname); return 0; } /* If we get here, it was a VALID and meaningful INVITE */ - if (check_target_limit(sptr, acptr, acptr->name, 0)) + if (check_target_limit(sptr, acptr, cli_name(acptr), 0)) return 0; - sendto_one(sptr, rpl_str(RPL_INVITING), me.name, parv[0], - acptr->name, chptr->chname); + send_reply(sptr, RPL_INVITING, cli_name(acptr), chptr->chname); - if (acptr->user->away) - sendto_one(sptr, rpl_str(RPL_AWAY), me.name, parv[0], - acptr->name, acptr->user->away); + if (cli_user(acptr)->away) + send_reply(sptr, RPL_AWAY, cli_name(acptr), cli_user(acptr)->away); if (MyConnect(acptr)) { add_invite(acptr, chptr); - sendto_prefix_one(acptr, sptr, ":%s " MSG_INVITE " %s :%s", - sptr->name, acptr->name, chptr->chname); + sendcmdto_one(sptr, CMD_INVITE, acptr, "%s %H", cli_name(acptr), chptr); + } else if (!IsLocalChannel(chptr->chname)) { + sendcmdto_one(sptr, CMD_INVITE, acptr, "%s %H %Tu", cli_name(acptr), chptr, + chptr->creationtime); + } + + if (!IsLocalChannel(chptr->chname) || MyConnect(acptr)) { + if (feature_bool(FEAT_ANNOUNCE_INVITES)) { + /* Announce to channel operators. */ + sendcmdto_channel_butserv_butone(&his, get_error_numeric(RPL_ISSUEDINVITE)->str, + NULL, chptr, sptr, SKIP_NONOPS, + "%H %C %C :%C has been invited by %C", + chptr, acptr, sptr, acptr, sptr); + /* Announce to servers with channel operators. */ + sendcmdto_channel_servers_butone(sptr, NULL, TOK_INVITE, chptr, acptr, SKIP_NONOPS, + "%s %H %Tu", cli_name(acptr), + chptr, chptr->creationtime); + } } - else - sendto_one(acptr, "%s%s " TOK_INVITE " %s :%s", - NumNick(sptr), acptr->name, chptr->chname); return 0; } @@ -229,6 +205,7 @@ int m_invite(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) * parv[0] - sender prefix * parv[1] - user to invite * parv[2] - channel name + * parv[3] - (optional) channel timestamp * * - INVITE now is accepted only if who does it is chanop (this of course * implies that channel must exist and he must be on it). @@ -238,206 +215,89 @@ int m_invite(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) * * - Invite with no parameters now lists the channels you are invited to. * - Isomer 23 Oct 99 + * + * - Invite with too-late timestamp, or with no timestamp from a bursting + * server, is silently discarded. - Entrope 19 Jan 05 */ int ms_invite(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) { struct Client *acptr; struct Channel *chptr; + time_t invite_ts; if (IsServer(sptr)) { /* * this will blow up if we get an invite from a server * we look for channel membership in sptr below. */ - /* PROTOCOL WARNING */ - return 0; + return protocol_violation(sptr,"Server attempting to invite"); } if (parc < 3 || EmptyString(parv[2])) { /* * should have been handled upstream, ignore it. */ - /* PROTOCOL WARNING */ - return 0; + protocol_violation(sptr,"Too few arguments to invite"); + return need_more_params(sptr,"INVITE"); } - if ('#' != *parv[2]) { + if (!IsGlobalChannel(parv[2])) { /* * should not be sent */ - /* PROTOCOL WARNING */ - return 0; + return protocol_violation(sptr, "Invite to a non-standard channel %s",parv[2]); } if (!(acptr = FindUser(parv[1]))) { - sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name, parv[0], parv[1]); - return 0; - } - if (!MyUser(acptr)) { - /* - * just relay the message - */ - sendto_one(acptr, "%s%s " TOK_INVITE " %s :%s", - NumNick(sptr), acptr->name, parv[2]); + send_reply(sptr, ERR_NOSUCHNICK, parv[1]); return 0; } - if (is_silenced(sptr, acptr)) - return 0; - if (!(chptr = FindChannel(parv[2]))) { /* - * allow invites to non existant channels, bleah + * allow invites to non existent channels, bleah * avoid JOIN, INVITE, PART abuse */ - sendto_prefix_one(acptr, sptr, ":%s " MSG_INVITE " %s :%s", sptr->name, - acptr->name, parv[2]); + sendcmdto_one(sptr, CMD_INVITE, acptr, "%C :%s", acptr, parv[2]); return 0; } - if (!find_channel_member(sptr, chptr)) { - sendto_one(sptr, err_str(ERR_NOTONCHANNEL), me.name, parv[0], - chptr->chname); - return 0; - } - if (find_channel_member(acptr, chptr)) { - sendto_one(sptr, err_str(ERR_USERONCHANNEL), - me.name, parv[0], acptr->name, chptr->chname); + if (parc > 3) { + invite_ts = atoi(parv[3]); + if (invite_ts > chptr->creationtime) + return 0; + } else if (IsBurstOrBurstAck(cptr)) return 0; - } - add_invite(acptr, chptr); - sendto_prefix_one(acptr, sptr, ":%s " MSG_INVITE " %s :%s", sptr->name, - acptr->name, chptr->chname); - return 0; -} - -#if 0 -/* - * m_invite - * - * parv[0] - sender prefix - * parv[1] - user to invite - * parv[2] - channel name - * - * - INVITE now is accepted only if who does it is chanop (this of course - * implies that channel must exist and he must be on it). - * - * - On the other side it IS processed even if channel is NOT invite only - * leaving room for other enhancements like inviting banned ppl. -- Nemesi - * - * - Invite with no parameters now lists the channels you are invited to. - * - Isomer 23 Oct 99 - */ -int m_invite(struct Client* cptr, struct Client *sptr, int parc, char *parv[]) -{ - struct Client *acptr; - struct Channel *chptr; - - if (parc < 2 ) { - /* - * list the channels you have an invite to. - */ - struct SLink *lp; - for (lp = sptr->user->invited; lp; lp = lp->next) - sendto_one(cptr, rpl_str(RPL_INVITELIST), me.name, cptr->name, - lp->value.chptr->chname); - sendto_one(cptr, rpl_str(RPL_ENDOFINVITELIST), me.name, cptr->name); + if (!IsChannelService(sptr) && !find_channel_member(sptr, chptr)) { + send_reply(sptr, ERR_NOTONCHANNEL, chptr->chname); return 0; } - if (parc < 3 || *parv[2] == '\0') - return need_more_params(sptr, "INVITE"); - - if (!(acptr = FindUser(parv[1]))) - { - sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name, parv[0], parv[1]); + if (find_channel_member(acptr, chptr)) { + send_reply(sptr, ERR_USERONCHANNEL, cli_name(acptr), chptr->chname); return 0; } if (is_silenced(sptr, acptr)) return 0; - if (MyUser(sptr)) - clean_channelname(parv[2]); - else if (IsLocalChannel(parv[2])) - return 0; - - if (*parv[2] == '0' || !IsChannelName(parv[2])) - return 0; - - if (!(chptr = FindChannel(parv[2]))) - { - if (IsModelessChannel(parv[2]) || IsLocalChannel(parv[2])) - { - sendto_one(sptr, err_str(ERR_NOTONCHANNEL), me.name, parv[0], parv[2]); - return 0; - } - - /* Do not disallow to invite to non-existant #channels, otherwise they - would simply first be created, causing only MORE bandwidth usage. */ - if (MyConnect(sptr)) - { - if (check_target_limit(sptr, acptr, acptr->name, 0)) - return 0; - - sendto_one(sptr, rpl_str(RPL_INVITING), me.name, parv[0], - acptr->name, parv[2]); - - if (acptr->user->away) - sendto_one(sptr, rpl_str(RPL_AWAY), me.name, parv[0], - acptr->name, acptr->user->away); - } - - sendto_prefix_one(acptr, sptr, ":%s INVITE %s :%s", parv[0], - acptr->name, parv[2]); - - return 0; - } - - if (!find_channel_member(sptr, chptr)) - { - sendto_one(sptr, err_str(ERR_NOTONCHANNEL), me.name, parv[0], - chptr->chname); - return 0; - } - - if (find_channel_member(acptr, chptr)) - { - sendto_one(sptr, err_str(ERR_USERONCHANNEL), - me.name, parv[0], acptr->name, chptr->chname); - return 0; - } - - if (MyConnect(sptr)) - { - if (!is_chan_op(sptr, chptr)) - { - sendto_one(sptr, err_str(ERR_CHANOPRIVSNEEDED), - me.name, parv[0], chptr->chname); - return 0; - } - - /* If we get here, it was a VALID and meaningful INVITE */ - - if (check_target_limit(sptr, acptr, acptr->name, 0)) - return 0; - - sendto_one(sptr, rpl_str(RPL_INVITING), me.name, parv[0], - acptr->name, chptr->chname); - - if (acptr->user->away) - sendto_one(sptr, rpl_str(RPL_AWAY), me.name, parv[0], - acptr->name, acptr->user->away); - } - if (MyConnect(acptr)) { add_invite(acptr, chptr); - sendto_prefix_one(acptr, sptr, ":%s INVITE %s :%s", parv[0], - acptr->name, chptr->chname); + sendcmdto_one(sptr, CMD_INVITE, acptr, "%s %H", cli_name(acptr), chptr); + } else { + sendcmdto_one(sptr, CMD_INVITE, acptr, "%s %H %Tu", cli_name(acptr), chptr, + chptr->creationtime); + } + + if (feature_bool(FEAT_ANNOUNCE_INVITES)) { + /* Announce to channel operators. */ + sendcmdto_channel_butserv_butone(&his, get_error_numeric(RPL_ISSUEDINVITE)->str, + NULL, chptr, sptr, SKIP_NONOPS, + "%H %C %C :%C has been invited by %C", + chptr, acptr, sptr, acptr, sptr); + /* Announce to servers with channel operators. */ + sendcmdto_channel_servers_butone(sptr, NULL, TOK_INVITE, chptr, acptr, SKIP_NONOPS, + "%s %H %Tu", cli_name(acptr), chptr, + chptr->creationtime); } - else - sendto_highprot_butone(acptr, 10, "%s%s " TOK_INVITE " %s :%s", - NumNick(sptr), acptr->name, chptr->chname); return 0; } -#endif /* 0 */ -