+/**
+ * Forward JOIN command to all servers
+ *
+ * This function calls cb_join_forward(), which differentiates between
+ * protocol implementations (e.g. RFC 2812, RFC 1459).
+ *
+ * @param Client Client used to prefix the genrated commands
+ * @param target Forward JOIN (and MODE) command to this peer server
+ * @param chan Channel structure
+ * @param channame Channel name
+ */
+static void
+join_forward(CLIENT *Client, CLIENT *target, CHANNEL *chan,
+ const char *channame)
+{
+ char modes[CHANNEL_MODE_LEN], str[COMMAND_LEN];
+
+ /* RFC 2813, 4.2.1: channel modes are separated from the channel
+ * name with ASCII 7, if any, and not spaces: */
+ strlcpy(&modes[1], Channel_UserModes(chan, target), sizeof(modes) - 1);
+ if (modes[1])
+ modes[0] = 0x7;
+ else
+ modes[0] = '\0';
+
+ /* forward to other servers (if it is not a local channel) */
+ if (!Channel_IsLocal(chan)) {
+ snprintf(str, sizeof(str), "%s%s", channame, modes);
+ IRC_WriteStrServersPrefixFlag_CB(Client, target, '\0',
+ cb_join_forward, str);
+ }
+
+ /* tell users in this channel about the new client */
+ IRC_WriteStrChannelPrefix(Client, chan, target, false,
+ "JOIN :%s", channame);
+
+ /* synchronize channel modes */
+ if (modes[1]) {
+ IRC_WriteStrChannelPrefix(Client, chan, target, false,
+ "MODE %s +%s %s", channame,
+ &modes[1], Client_ID(target));
+ }
+} /* join_forward */