#include "client.h"
#include "ircd.h"
#include "ircd_features.h"
+#include "ircd_log.h"
#include "ircd_snprintf.h"
#include "ircd_string.h"
#include "list.h"
#include "struct.h"
#include "sys.h"
-#include <assert.h>
+/* #include <assert.h> -- Now using assert in ircd_log.h */
#include <stdio.h>
#include <string.h>
msgq_clean(mb);
}
+/**
+ * Send a (prefixed) command to all servers matching or not matching a
+ * flag but one.
+ * @param[in] from Client sending the command.
+ * @param[in] cmd Long name of command (ignored).
+ * @param[in] tok Short name of command.
+ * @param[in] one Client direction to skip (or NULL).
+ * @param[in] require Only send to servers with this Flag bit set.
+ * @param[in] forbid Do not send to servers with this Flag bit set.
+ * @param[in] pattern Format string for command arguments.
+ */
+void sendcmdto_flag_serv_butone(struct Client *from, const char *cmd,
+ const char *tok, struct Client *one,
+ int require, int forbid,
+ const char *pattern, ...)
+{
+ struct VarData vd;
+ struct MsgBuf *mb;
+ struct DLink *lp;
+
+ vd.vd_format = pattern; /* set up the struct VarData for %v */
+ va_start(vd.vd_args, pattern);
+
+ /* use token */
+ mb = msgq_make(&me, "%C %s %v", from, tok, &vd);
+ va_end(vd.vd_args);
+
+ /* send it to our downlinks */
+ for (lp = cli_serv(&me)->down; lp; lp = lp->next) {
+ if (one && lp->value.cptr == cli_from(one))
+ continue;
+ if ((require < FLAG_LAST_FLAG) && !HasFlag(lp->value.cptr, require))
+ continue;
+ if ((forbid < FLAG_LAST_FLAG) && HasFlag(lp->value.cptr, forbid))
+ continue;
+ send_buffer(lp->value.cptr, mb, 0);
+ }
+
+ msgq_clean(mb);
+}
+
/**
* Send a (prefixed) command to all servers but one.
* @param[in] from Client sending the command.
}
/** Send a (prefixed) command to all servers with users on \a to.
+ * Skip \a from and \a one plus those indicated in \a skip.
* @param[in] from Client originating the command.
* @param[in] cmd Long name of command (ignored).
* @param[in] tok Short name of command.
* @param[in] to Destination channel.
* @param[in] one Client direction to skip (or NULL).
- * @param[in] skip Ignored field.
+ * @param[in] skip Bitmask of SKIP_NONOPS and SKIP_NONVOICES indicating which clients to skip.
* @param[in] pattern Format string for command arguments.
*/
void sendcmdto_channel_servers_butone(struct Client *from, const char *cmd,
/* send the buffer to each server */
bump_sentalong(one);
- sentalong_marker++;
+ cli_sentalong(from) = sentalong_marker;
for (member = to->members; member; member = member->next_member) {
if (MyConnect(member->user)
|| IsZombie(member)
|| cli_fd(cli_from(member->user)) < 0
- || cli_sentalong(member->user) == sentalong_marker)
+ || cli_sentalong(member->user) == sentalong_marker
+ || (skip & SKIP_NONOPS && !IsChanOp(member))
+ || (skip & SKIP_NONVOICES && !IsChanOp(member) && !HasVoice(member)))
continue;
cli_sentalong(member->user) = sentalong_marker;
send_buffer(member->user, serv_mb, 0);
/** Send a (prefixed) command to all users on this channel, except for
* \a one and those matching \a skip.
+ * @warning \a pattern must not contain %v.
* @param[in] from Client originating the command.
* @param[in] cmd Long name of command.
* @param[in] tok Short name of command.
}
/** Send a (prefixed) WALL of type \a type to all users except \a one.
+ * @warning \a pattern must not contain %v.
* @param[in] from Source of the command.
* @param[in] type One of WALL_DESYNCH, WALL_WALLOPS or WALL_WALLUSERS.
* @param[in] one Client direction to skip (or NULL).
}
/** Send a (prefixed) command to all users matching \a to as \a who.
+ * @warning \a pattern must not contain %v.
* @param[in] from Source of the command.
* @param[in] cmd Long name of command.
* @param[in] tok Short name of command.