+/**
+ * Announce a channel and its users in the network.
+ */
+static bool
+Announce_Channel(CLIENT *Client, CHANNEL *Chan)
+{
+ CL2CHAN *cl2chan;
+ CLIENT *cl;
+ char str[COMMAND_LEN], *ptr;
+ bool njoin, xop;
+
+ /* Check features of remote server */
+ njoin = Conn_Options(Client_Conn(Client)) & CONN_RFC1459 ? false : true;
+ xop = Client_HasFlag(Client, 'X') ? true : false;
+
+ /* Get all the members of this channel */
+ cl2chan = Channel_FirstMember(Chan);
+ snprintf(str, sizeof(str), "NJOIN %s :", Channel_Name(Chan));
+ while (cl2chan) {
+ cl = Channel_GetClient(cl2chan);
+ assert(cl != NULL);
+
+ if (njoin) {
+ /* RFC 2813: send NJOIN with nicknames and modes
+ * (if user is channel operator or has voice) */
+ if (str[strlen(str) - 1] != ':')
+ strlcat(str, ",", sizeof(str));
+
+ /* Prepare user prefix (ChanOp, voiced, ...) */
+ if (xop && Channel_UserHasMode(Chan, cl, 'q'))
+ strlcat(str, "~", sizeof(str));
+ if (xop && Channel_UserHasMode(Chan, cl, 'a'))
+ strlcat(str, "&", sizeof(str));
+ if (Channel_UserHasMode(Chan, cl, 'o'))
+ strlcat(str, "@", sizeof(str));
+ if (xop && Channel_UserHasMode(Chan, cl, 'h'))
+ strlcat(str, "%", sizeof(str));
+ if (Channel_UserHasMode(Chan, cl, 'v'))
+ strlcat(str, "+", sizeof(str));
+
+ strlcat(str, Client_ID(cl), sizeof(str));
+
+ /* Send the data if the buffer is "full" */
+ if (strlen(str) > (sizeof(str) - CLIENT_NICK_LEN - 8)) {
+ if (!IRC_WriteStrClient(Client, "%s", str))
+ return DISCONNECTED;
+ snprintf(str, sizeof(str), "NJOIN %s :",
+ Channel_Name(Chan));
+ }
+ } else {
+ /* RFC 1459: no NJOIN, send JOIN and MODE */
+ if (!IRC_WriteStrClientPrefix(Client, cl, "JOIN %s",
+ Channel_Name(Chan)))
+ return DISCONNECTED;
+ ptr = Channel_UserModes(Chan, cl);
+ while (*ptr) {
+ if (!IRC_WriteStrClientPrefix(Client, cl,
+ "MODE %s +%c %s",
+ Channel_Name(Chan), ptr[0],
+ Client_ID(cl)))
+ return DISCONNECTED;
+ ptr++;
+ }
+ }
+
+ cl2chan = Channel_NextMember(Chan, cl2chan);
+ }
+
+ /* Data left in the buffer? */
+ if (str[strlen(str) - 1] != ':') {
+ /* Yes, send it ... */
+ if (!IRC_WriteStrClient(Client, "%s", str))
+ return DISCONNECTED;
+ }
+
+ return CONNECTED;
+} /* Announce_Channel */
+