X-Git-Url: https://jfr.im/git/solanum.git/blobdiff_plain/03dba44854f964bdd0a7b2d059e81083051de710..9d6b870d7bdc20a7e698c18299c0516d30d7d24b:/modules/m_invite.c diff --git a/modules/m_invite.c b/modules/m_invite.c index 35e392ff..bd9aeefb 100644 --- a/modules/m_invite.c +++ b/modules/m_invite.c @@ -20,17 +20,13 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA - * - * $Id: m_invite.c 3438 2007-05-06 14:46:45Z jilles $ */ #include "stdinc.h" -#include "tools.h" -#include "common.h" #include "channel.h" #include "client.h" #include "hash.h" -#include "irc_string.h" +#include "match.h" #include "ircd.h" #include "numeric.h" #include "send.h" @@ -40,25 +36,35 @@ #include "parse.h" #include "modules.h" #include "packet.h" +#include "tgchange.h" + +static const char invite_desc[] = "Provides facilities for invite and related notifications"; -static int m_invite(struct Client *, struct Client *, int, const char **); +static void m_invite(struct MsgBuf *, struct Client *, struct Client *, int, const char **); +static unsigned int CAP_INVITE_NOTIFY = 0; struct Message invite_msgtab = { - "INVITE", 0, 0, 0, MFLG_SLOW, + "INVITE", 0, 0, 0, 0, {mg_unreg, {m_invite, 3}, {m_invite, 3}, mg_ignore, mg_ignore, {m_invite, 3}} }; + mapi_clist_av1 invite_clist[] = { &invite_msgtab, NULL }; -DECLARE_MODULE_AV1(invite, NULL, NULL, invite_clist, NULL, NULL, "$Revision: 3438 $"); + +mapi_cap_list_av2 invite_cap_list[] = { + { MAPI_CAP_CLIENT, "invite-notify", NULL, &CAP_INVITE_NOTIFY }, + { 0, NULL, NULL, NULL } +}; + +DECLARE_MODULE_AV2(invite, NULL, NULL, invite_clist, NULL, NULL, invite_cap_list, NULL, invite_desc); static void add_invite(struct Channel *, struct Client *); /* m_invite() - * parv[0] - sender prefix * parv[1] - user to invite * parv[2] - channel name */ -static int -m_invite(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) +static void +m_invite(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct Client *target_p; struct Channel *chptr; @@ -75,14 +81,14 @@ m_invite(struct Client *client_p, struct Client *source_p, int parc, const char if(target_p == NULL) { if(!MyClient(source_p) && IsDigit(parv[1][0])) - sendto_one_numeric(source_p, ERR_NOSUCHNICK, - "* :Target left IRC. Failed to invite to %s", + sendto_one_numeric(source_p, ERR_NOSUCHNICK, + "* :Target left IRC. Failed to invite to %s", parv[2]); else - sendto_one_numeric(source_p, ERR_NOSUCHNICK, - form_str(ERR_NOSUCHNICK), + sendto_one_numeric(source_p, ERR_NOSUCHNICK, + form_str(ERR_NOSUCHNICK), parv[1]); - return 0; + return; } if(check_channel_name(parv[2]) == 0) @@ -90,32 +96,34 @@ m_invite(struct Client *client_p, struct Client *source_p, int parc, const char sendto_one_numeric(source_p, ERR_BADCHANNAME, form_str(ERR_BADCHANNAME), parv[2]); - return 0; - } - - if(!IsChannelName(parv[2])) - { - if(MyClient(source_p)) - sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, - form_str(ERR_NOSUCHCHANNEL), parv[2]); - return 0; + return; } /* Do not send local channel invites to users if they are not on the - * same server as the person sending the INVITE message. + * same server as the person sending the INVITE message. */ if(parv[2][0] == '&' && !MyConnect(target_p)) { sendto_one(source_p, form_str(ERR_USERNOTONSERV), me.name, source_p->name, target_p->name); - return 0; + return; + } + + if(((MyConnect(source_p) && !IsExemptResv(source_p)) || + (MyConnect(target_p) && !IsExemptResv(target_p))) && + hash_find_resv(parv[2])) + { + sendto_one_numeric(source_p, ERR_BADCHANNAME, + form_str(ERR_BADCHANNAME), + parv[2]); + return; } if((chptr = find_channel(parv[2])) == NULL) { sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL), parv[2]); - return 0; + return; } msptr = find_channel_membership(chptr, source_p); @@ -123,7 +131,7 @@ m_invite(struct Client *client_p, struct Client *source_p, int parc, const char { sendto_one_numeric(source_p, ERR_NOTONCHANNEL, form_str(ERR_NOTONCHANNEL), parv[2]); - return 0; + return; } if(IsMember(target_p, chptr)) @@ -131,7 +139,7 @@ m_invite(struct Client *client_p, struct Client *source_p, int parc, const char sendto_one_numeric(source_p, ERR_USERONCHANNEL, form_str(ERR_USERONCHANNEL), target_p->name, parv[2]); - return 0; + return; } /* unconditionally require ops, unless the channel is +g */ @@ -141,7 +149,7 @@ m_invite(struct Client *client_p, struct Client *source_p, int parc, const char { sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED), me.name, source_p->name, parv[2]); - return 0; + return; } /* store invites when they could affect the ability to join @@ -154,7 +162,15 @@ m_invite(struct Client *client_p, struct Client *source_p, int parc, const char if(MyConnect(source_p)) { - sendto_one(source_p, form_str(RPL_INVITING), + if (ConfigFileEntry.target_change && !IsOper(source_p) && + !find_allowing_channel(source_p, target_p) && + !add_target(source_p, target_p)) + { + sendto_one(source_p, form_str(ERR_TARGCHANGE), + me.name, source_p->name, target_p->name); + return; + } + sendto_one(source_p, form_str(RPL_INVITING), me.name, source_p->name, target_p->name, parv[2]); if(target_p->user->away) @@ -166,25 +182,59 @@ m_invite(struct Client *client_p, struct Client *source_p, int parc, const char { /* this should never be less than */ if(atol(parv[3]) > chptr->channelts) - return 0; + return; } if(MyConnect(target_p)) { - sendto_one(target_p, ":%s!%s@%s INVITE %s :%s", - source_p->name, source_p->username, source_p->host, + if(!IsOper(source_p) && (IsSetCallerId(target_p) || + (IsSetRegOnlyMsg(target_p) && !source_p->user->suser[0])) && + !accept_message(source_p, target_p)) + { + if (IsSetRegOnlyMsg(target_p) && !source_p->user->suser[0]) + { + sendto_one_numeric(source_p, ERR_NONONREG, + form_str(ERR_NONONREG), + target_p->name); + return; + } + else + { + /* instead of sending RPL_UMODEGMSG, + * just let the invite through + */ + if((target_p->localClient->last_caller_id_time + + ConfigFileEntry.caller_id_wait) >= rb_current_time()) + { + sendto_one_numeric(source_p, ERR_TARGUMODEG, + form_str(ERR_TARGUMODEG), + target_p->name); + return; + } + target_p->localClient->last_caller_id_time = rb_current_time(); + } + } + add_reply_target(target_p, source_p); + sendto_one(target_p, ":%s!%s@%s INVITE %s :%s", + source_p->name, source_p->username, source_p->host, target_p->name, chptr->chname); if(store_invite) + { add_invite(chptr, target_p); - } - else if(target_p->from != client_p) - { - sendto_one_prefix(target_p, source_p, "INVITE", "%s %lu", - chptr->chname, (unsigned long) chptr->channelts); + + sendto_channel_local_with_capability(CHFL_CHANOP, 0, CAP_INVITE_NOTIFY, chptr, + ":%s NOTICE %s :%s is inviting %s to %s.", + me.name, chptr->chname, source_p->name, target_p->name, chptr->chname); + sendto_channel_local_with_capability(CHFL_CHANOP, CAP_INVITE_NOTIFY, 0, chptr, + ":%s!%s@%s INVITE %s %s", source_p->name, source_p->username, + source_p->host, target_p->name, chptr->chname); + } } - return 0; + sendto_server(source_p, chptr, CAP_TS6, 0, ":%s INVITE %s %s %lu", + use_id(source_p), use_id(target_p), + chptr->chname, (unsigned long) chptr->channelts); } /* add_invite() @@ -206,7 +256,7 @@ add_invite(struct Channel *chptr, struct Client *who) } /* ok, if their invite list is too long, remove the tail */ - if((int)rb_dlink_list_length(&who->user->invited) >= + if((int)rb_dlink_list_length(&who->user->invited) >= ConfigChannel.max_chans_per_user) { ptr = who->user->invited.tail; @@ -219,5 +269,3 @@ add_invite(struct Channel *chptr, struct Client *who) /* add channel to user invite list */ rb_dlinkAddAlloc(chptr, &who->user->invited); } - -