#include "modules.h"
#include "s_conf.h"
#include "packet.h"
-#include "irc_string.h"
+#include "inline/stringops.h"
+#include "hook.h"
static int m_part(struct Client *, struct Client *, int, const char **);
static void part_one_client(struct Client *client_p,
struct Client *source_p, char *name, char *reason);
+static int can_send_part(struct Client *source_p, struct Channel *chptr, struct membership *msptr);
+static int do_message_hook(struct Client *source_p, struct Channel *chptr, char **reason);
/*
** m_part
-** parv[0] = sender prefix
** parv[1] = channel
** parv[2] = reason
*/
if(MyClient(source_p) && !IsFloodDone(source_p))
flood_endgrace(source_p);
- strip_colour(reason);
-
while(name)
{
part_one_client(client_p, source_p, name, reason);
* Remove user from the old channel (if any)
* only allow /part reasons in -m chans
*/
- if(reason[0] && (is_chanop(msptr) || !MyConnect(source_p) ||
- ((can_send(chptr, source_p, msptr) > 0 &&
- (source_p->localClient->firsttime +
- ConfigFileEntry.anti_spam_exit_message_time) < rb_current_time()))))
+ if(!EmptyString(reason) &&
+ (!MyConnect(source_p) ||
+ (can_send_part(source_p, chptr, msptr) && do_message_hook(source_p, chptr, &reason))
+ )
+ )
{
+
sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
":%s PART %s :%s", use_id(source_p), chptr->chname, reason);
- sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
- ":%s PART %s :%s", source_p->name, chptr->chname, reason);
sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s :%s",
source_p->name, source_p->username,
source_p->host, chptr->chname, reason);
{
sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
":%s PART %s", use_id(source_p), chptr->chname);
- sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
- ":%s PART %s", source_p->name, chptr->chname);
sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s",
source_p->name, source_p->username,
source_p->host, chptr->chname);
}
remove_user_from_channel(msptr);
}
+
+/*
+ * can_send_part - whether a part message can be sent.
+ *
+ * inputs:
+ * - client parting
+ * - channel being parted
+ * - membership pointer
+ * outputs:
+ * - 1 if message allowed
+ * - 0 if message denied
+ * side effects:
+ * - none.
+ */
+static int
+can_send_part(struct Client *source_p, struct Channel *chptr, struct membership *msptr)
+{
+ if (!can_send(chptr, source_p, msptr))
+ return 0;
+ /* Allow chanops to bypass anti_spam_exit_message_time for part messages. */
+ if (is_chanop(msptr))
+ return 1;
+ return (source_p->localClient->firsttime + ConfigFileEntry.anti_spam_exit_message_time) < rb_current_time();
+}
+
+/*
+ * do_message_hook - execute the message hook on a part message reason.
+ *
+ * inputs:
+ * - client parting
+ * - channel being parted
+ * - pointer to reason
+ * outputs:
+ * - 1 if message is allowed
+ * - 0 if message is denied or message is now empty
+ * side effects:
+ * - reason may be modified.
+ */
+static int
+do_message_hook(struct Client *source_p, struct Channel *chptr, char **reason)
+{
+ hook_data_privmsg_channel hdata;
+
+ hdata.msgtype = MESSAGE_TYPE_PART;
+ hdata.source_p = source_p;
+ hdata.chptr = chptr;
+ hdata.text = *reason;
+ hdata.approved = 0;
+
+ call_hook(h_privmsg_channel, &hdata);
+
+ /* The reason may have been changed by a hook... */
+ *reason = hdata.text;
+
+ return (hdata.approved == 0 && !EmptyString(*reason));
+}