diff --git a/common/parse.c b/common/parse.c index 58340d10..8f321f34 100644 --- a/common/parse.c +++ b/common/parse.c @@ -50,6 +50,7 @@ struct Message msgtab[] = { { "TRACE", 0, MPAR, { _m(m_trace), _m(m_trace), _m(m_trace), _m(m_trace), _m(m_unreg) } }, { "TOPIC", 1, MPAR, { _m(m_nop), _m(m_topic), _m(m_topic), _m(m_nop), _m(m_unreg) } }, { "INVITE", 2, MPAR, { _m(m_nop), _m(m_invite), _m(m_invite), _m(m_nop), _m(m_unreg) } }, +{ "INVITED", 3, MPAR, { _m(m_invited), _m(m_nop), _m(m_nop), _m(m_nop), _m(m_unreg) } }, { "WALLOPS", 1, MPAR, { _m(m_wallops), _m(m_nop), _m(m_nop), _m(m_nop), _m(m_unreg) } }, { "PING", 1, MPAR, { _m(m_ping), _m(m_ping), _m(m_ping), _m(m_ping), _m(m_unreg) } }, { "PONG", 1, MPAR, { _m(m_pong), _m(m_pong), _m(m_pong), _m(m_pong), _m(m_unreg) } }, diff --git a/common/struct_def.h b/common/struct_def.h index 41d7c41e..0aaf3947 100644 --- a/common/struct_def.h +++ b/common/struct_def.h @@ -1014,6 +1014,7 @@ typedef enum ServerChannels { #define CAP_IRCNET_EXTENDED_JOIN 0x0002 #define CAP_MULTI_PREFIX 0x0004 #define CAP_SASL 0x0008 +#define CAP_INVITE_NOTIFY 0x0010 /* WHO parameter flags */ #define WHO_FLAG_OPERS_ONLY 0x0001 diff --git a/ircd/channel.c b/ircd/channel.c index 8375ceb8..6954c4c5 100644 --- a/ircd/channel.c +++ b/ircd/channel.c @@ -3255,6 +3255,34 @@ int m_topic(aClient *cptr, aClient *sptr, int parc, char *parv[]) return penalty; } +void invite_notify(aChannel *chptr, aClient *inviter, aClient *target) +{ + Link *lp; + + if (!chptr || !inviter || !target) + { + return; + } + + for (lp = chptr->members; lp; lp = lp->next) + { + aClient *chan_op = lp->value.cptr; + + if (chan_op == inviter) + { + continue; + } + + if (MyConnect(chan_op) && (lp->flags & CHFL_CHANOP) && + HasCap(chan_op, CAP_INVITE_NOTIFY)) + { + sendto_prefix_one(chan_op, inviter, ":%s!%s@%s INVITE %s %s", + inviter->name, inviter->user->username, + inviter->user->host, target->name, chptr->chname); + } + } +} + /* ** m_invite ** parv[0] - sender prefix @@ -3265,6 +3293,7 @@ int m_invite(aClient *cptr, aClient *sptr, int parc, char *parv[]) { aClient *acptr; aChannel *chptr; + int chan_op; if (!(acptr = find_person(parv[1], (aClient *)NULL))) { @@ -3320,7 +3349,8 @@ int m_invite(aClient *cptr, aClient *sptr, int parc, char *parv[]) return 1; } - if ((chptr->mode.mode & MODE_INVITEONLY) && !is_chan_op(sptr, chptr)) + chan_op = is_chan_op(sptr, chptr); + if ((chptr->mode.mode & MODE_INVITEONLY) && !chan_op) { sendto_one(sptr, replies[ERR_CHANOPRIVSNEEDED], ME, BadTo(parv[0]), chptr->chname); @@ -3340,11 +3370,48 @@ int m_invite(aClient *cptr, aClient *sptr, int parc, char *parv[]) sptr->user && is_chan_op(sptr, chptr)) add_invite(sptr, acptr, chptr); + if (MyConnect(sptr) && chan_op) + { + invite_notify(chptr, sptr, acptr); + sendto_match_servs(chptr, acptr, "ENCAP * PARSE %s INVITED %s %s %s", + me.serv->sid, sptr->uid, acptr->uid, chptr->chname); + } + sendto_prefix_one(acptr, sptr, ":%s INVITE %s :%s",parv[0], acptr->name, ((chptr) ? (chptr->chname) : parv[2])); return 2; } +/* +** m_invited +** parv[0] - server which send the command over ENCAP +** parv[1] - UID of the inviter +** parv[2] - UID of the invited person +** parv[3] - channel name +*/ +int m_invited(aClient *cptr, aClient *sptr, int parc, char *parv[]) +{ + aChannel *chptr; + aClient *inviter, *target; + + if (!(inviter = find_uid(parv[1], (aClient *)NULL))) + { + return 0; + } + + if (!(target = find_uid(parv[2], (aClient *)NULL))) + { + return 0; + } + + if (!(chptr = find_channel(parv[3], NullChn))) + { + return 0; + } + + invite_notify(chptr, inviter, target); + return 0; +} /* ** m_list diff --git a/ircd/channel_ext.h b/ircd/channel_ext.h index 446edb18..792433c4 100644 --- a/ircd/channel_ext.h +++ b/ircd/channel_ext.h @@ -62,8 +62,8 @@ EXTERN int m_njoin (Reg aClient *cptr, Reg aClient *sptr, int parc, EXTERN int m_part (aClient *cptr, aClient *sptr, int parc, char *parv[]); EXTERN int m_kick (aClient *cptr, aClient *sptr, int parc, char *parv[]); EXTERN int m_topic (aClient *cptr, aClient *sptr, int parc, char *parv[]); -EXTERN int m_invite (aClient *cptr, aClient *sptr, int parc, - char *parv[]); +EXTERN int m_invite (aClient *cptr, aClient *sptr, int parc,char *parv[]); +EXTERN int m_invited (aClient *cptr, aClient *sptr, int parc,char *parv[]); EXTERN int m_list (aClient *cptr, aClient *sptr, int parc, char *parv[]); EXTERN int m_names (aClient *cptr, aClient *sptr, int parc, char *parv[]); EXTERN time_t collect_channel_garbage (time_t now); diff --git a/ircd/s_cap.c b/ircd/s_cap.c index 95fb8983..76368245 100644 --- a/ircd/s_cap.c +++ b/ircd/s_cap.c @@ -32,6 +32,7 @@ struct Cap {"ircnet.com/extended-join", CAP_IRCNET_EXTENDED_JOIN}, {"multi-prefix", CAP_MULTI_PREFIX}, {"sasl", CAP_SASL}, + {"invite-notify", CAP_INVITE_NOTIFY}, {NULL, 0} }; diff --git a/ircd/s_serv.c b/ircd/s_serv.c index e1ddb885..823c79ea 100644 --- a/ircd/s_serv.c +++ b/ircd/s_serv.c @@ -3805,6 +3805,7 @@ static char *encap_whitelisted(char *cmd) char *whitelist[] = { "SASL", "TKLINE", "UNTKLINE", + "INVITED", NULL }; int i; @@ -3867,13 +3868,15 @@ int m_encap(aClient *cptr, aClient *sptr, int parc, char *parv[]) return 1; } - /* Resulting format: ":SID ENCAP *.mask sender!u@h COMMAND ..." */ + /* Resulting format: + * ": ENCAP PARSE [..]" + */ len = sprintf(buf, ":%s ENCAP %s PARSE", me.serv->sid, mask); toparse = buf + len; len += sprintf(buf + len, " %s %s", sptr->name, whitelisted); for (i = 3; i < parc; i++) len += sprintf(buf + len, " %s%s", i+1 == parc?":":"", parv[i]); - Debug((DEBUG_SEND,"m_encap(cli->serv): %s", buf)); + Debug((DEBUG_SEND,"m_encap(service->server): %s", buf)); if(strcmp(mask, me.name) && strcmp(mask, me.serv->sid)) { sendto_serv_v(cptr, SV_UID, "%s", buf); } @@ -3892,17 +3895,19 @@ int m_encap(aClient *cptr, aClient *sptr, int parc, char *parv[]) p = strchr(toparse, ' '); if(p == NULL) - return 2; + { + return 0; + } - if (p[1] == ':') p[1] = ' '; + if (p[1] == ':') + { + p[1] = ' '; + } - /* toparse now contains: :sendername COMMAND ... :lastarg. - * invariant: parse() ignores :sendername if cptr is client - */ Debug((DEBUG_DEBUG,"m_encap(PARSE): %s", toparse)); - parse(cptr, toparse, toparse + strlen(toparse)); /* Inception .. */ + parse(cptr, toparse, toparse + strlen(toparse)); } - return 5; + return 0; } /* announces server DIE */