extern int ms_svsnick(struct Client*, struct Client*, int, char*[]);
extern int ms_svsnick_old(struct Client*, struct Client*, int, char*[]);
extern int ms_svsjoin(struct Client*, struct Client*, int, char*[]);
+extern int ms_svspart(struct Client*, struct Client*, int, char*[]);
extern int ms_topic(struct Client*, struct Client*, int, char*[]);
extern int ms_trace(struct Client*, struct Client*, int, char*[]);
extern int ms_uping(struct Client*, struct Client*, int, char*[]);
--- /dev/null
+/*
+ * IRC - Internet Relay Chat, ircd/m_svspart.c
+ * Written by Pierre Schweitzer.
+ */
+
+#include "config.h"
+
+#include "channel.h"
+#include "client.h"
+#include "handlers.h"
+#include "hash.h"
+#include "ircd.h"
+#include "ircd_chattr.h"
+#include "ircd_features.h"
+#include "ircd_reply.h"
+#include "ircd_string.h"
+#include "msg.h"
+#include "numeric.h"
+#include "numnicks.h"
+#include "s_debug.h"
+#include "s_user.h"
+#include "send.h"
+
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+/** SVSPART
+ * SVSPART is forwarded to the server where the user is connected to.
+ * This allows to send SVSPARTs from all servers in the network but additionally causes
+ * some overhead. Though, SVSPART is not often called and this overhead can be ignored.
+ */
+/* ms_svspart - server message handler
+ *
+ * parv[0] = sender prefix
+ * parv[1] = numeric of client
+ * parv[2] = channel, NO CHANLIST!
+ * parv[3] = comment (optional)
+ */
+signed int ms_svspart(struct Client* cptr, struct Client* sptr, signed int parc, char* parv[]) {
+ struct Client *acptr;
+ struct Channel *chptr;
+ struct JoinBuf part;
+ struct Membership *member;
+ unsigned int flags = 0;
+ int use_comment;
+
+ if(parc < 3) {
+ return protocol_violation(cptr, "Too few arguments for SVSPART");
+ }
+
+ /* Ignore if the user has already quitted. */
+ if(!(acptr = findNUser(parv[1]))) {
+ return 0;
+ }
+
+ /* Check channelname. */
+ if(!IsChannelName(parv[2]) || !strIsIrcCh(parv[2])) {
+ return 0;
+ }
+
+ /* Get the channel */
+ chptr = get_channel(acptr, parv[2], CGT_NO_CREATE);
+
+ /* Ensure the user is in channel */
+ if (!(member = find_member_link(chptr, acptr))) return 0;
+
+ /* Forward the message to the server where the user is connected to. */
+ if(!MyConnect(acptr)) {
+ if (parc > 3)
+ sendcmdto_one(sptr, CMD_SVSPART, acptr, "%s %s :%s", parv[1], chptr->chname, parv[3]);
+ else
+ sendcmdto_one(sptr, CMD_SVSPART, acptr, "%s %s", parv[1], chptr->chname);
+ return 0;
+ }
+
+ /* Check if we can put part message */
+ use_comment = (parc > 3 && !EmptyString(parv[3]) &&
+ member_can_send_to_channel(member, 0));
+
+ /* Use join buf to make him leave - use comment if provided */
+ joinbuf_init(&part, acptr, acptr, JOINBUF_TYPE_PART,
+ use_comment ? parv[3] : 0, 0);
+
+ if (!member_can_send_to_channel(member, 0))
+ flags |= CHFL_BANNED;
+
+ if (IsDelayedJoin(member))
+ flags |= CHFL_DELAYED;
+
+ /* Make the user leave */
+ joinbuf_join(&part, chptr, flags);
+
+ joinbuf_flush(&part);
+
+ return 0;
+}
+
\ No newline at end of file
/* UNREG, CLIENT, SERVER, OPER, SERVICE */
{ m_ignore, m_ignore, ms_svsjoin, m_svsjoin, m_ignore }
},
+ {
+ MSG_SVSPART,
+ TOK_SVSPART,
+ 0, MAXPARA, MFLG_SLOW, 0, NULL,
+ /* UNREG, CLIENT, SERVER, OPER, SERVICE */
+ { m_ignore, m_ignore, ms_svspart, m_svspart, m_ignore }
+ },
{
MSG_WEBIRC,
TOK_WEBIRC,