if (is_silenced(sptr, acptr))
return 0;
- clean_channelname(parv[2]);
-
- if (!IsChannelPrefix(*parv[2]))
- return 0;
-
- if (!(chptr = FindChannel(parv[2]))) {
- send_reply(sptr, ERR_NOTONCHANNEL, parv[2]);
+ if (!IsChannelName(parv[2])
+ || !strIsIrcCh(parv[2])
+ || !(chptr = FindChannel(parv[2]))) {
+ send_reply(sptr, ERR_NOSUCHCHANNEL, parv[2]);
return 0;
}
if (cli_user(acptr)->away)
send_reply(sptr, RPL_AWAY, cli_name(acptr), cli_user(acptr)->away);
- if (MyConnect(acptr))
+ if (MyConnect(acptr)) {
add_invite(acptr, chptr);
+ 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(&me, get_error_numeric(RPL_ISSUEDINVITE)->str,
- NULL, chptr, sptr, SKIP_NONOPS,
+ 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, but skip acptr,
- * since they will be notified below. */
+ /* Announce to servers with channel operators. */
sendcmdto_channel_servers_butone(sptr, NULL, TOK_INVITE, chptr, acptr, SKIP_NONOPS,
- "%s :%H", cli_name(acptr), chptr);
+ "%s %H %Tu", cli_name(acptr),
+ chptr, chptr->creationtime);
}
- sendcmdto_one(sptr, CMD_INVITE, acptr, "%s :%H", cli_name(acptr), chptr);
}
return 0;
* 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).
*
* - 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)) {
/*
if (!(chptr = FindChannel(parv[2]))) {
/*
- * allow invites to non existant channels, bleah
+ * allow invites to non existent channels, bleah
* avoid JOIN, INVITE, PART abuse
*/
sendcmdto_one(sptr, CMD_INVITE, acptr, "%C :%s", acptr, parv[2]);
return 0;
}
+ if (parc > 3) {
+ invite_ts = atoi(parv[3]);
+ if (invite_ts > chptr->creationtime)
+ return 0;
+ } else if (IsBurstOrBurstAck(cptr))
+ return 0;
+
if (!IsChannelService(sptr) && !find_channel_member(sptr, chptr)) {
send_reply(sptr, ERR_NOTONCHANNEL, chptr->chname);
return 0;
if (is_silenced(sptr, acptr))
return 0;
- if (MyConnect(acptr))
- add_invite(acptr, chptr);
+ if (MyConnect(acptr)) {
+ add_invite(acptr, chptr);
+ 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(&me, get_error_numeric(RPL_ISSUEDINVITE)->str,
+ 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, but skip acptr,
- * since they will be notified below. */
+ /* Announce to servers with channel operators. */
sendcmdto_channel_servers_butone(sptr, NULL, TOK_INVITE, chptr, acptr, SKIP_NONOPS,
- "%s :%H", cli_name(acptr), chptr);
+ "%s %H %Tu", cli_name(acptr), chptr,
+ chptr->creationtime);
}
- sendcmdto_one(sptr, CMD_INVITE, acptr, "%s :%H", cli_name(acptr), chptr);
return 0;
}
-
-