+/* Sends the LIST command reply */
+
+static void
+silc_server_command_list_send_reply(SilcServerCommandContext cmd,
+ SilcChannelEntry *lch,
+ unsigned int lch_count,
+ SilcChannelEntry *gch,
+ unsigned int gch_count)
+{
+ int i;
+ SilcBuffer packet, idp;
+ SilcChannelEntry entry;
+ SilcCommandStatus status;
+ unsigned short ident = silc_command_get_ident(cmd->payload);
+ char *topic;
+ unsigned char usercount[4];
+ unsigned int users;
+
+ for (i = 0; i < lch_count; i++)
+ if (lch[i]->mode & SILC_CHANNEL_MODE_SECRET)
+ lch[i] = NULL;
+ for (i = 0; i < gch_count; i++)
+ if (gch[i]->mode & SILC_CHANNEL_MODE_SECRET)
+ gch[i] = NULL;
+
+ status = SILC_STATUS_OK;
+ if ((lch_count + gch_count) > 1)
+ status = SILC_STATUS_LIST_START;
+
+ /* Local list */
+ for (i = 0; i < lch_count; i++) {
+ entry = lch[i];
+
+ if (!entry)
+ continue;
+
+ if (i >= 1)
+ status = SILC_STATUS_LIST_ITEM;
+
+ if (i == lch_count - 1 && gch_count)
+ break;
+ if (lch_count > 1 && i == lch_count - 1)
+ status = SILC_STATUS_LIST_END;
+
+ idp = silc_id_payload_encode(entry->id, SILC_ID_CHANNEL);
+
+ if (entry->mode & SILC_CHANNEL_MODE_PRIVATE) {
+ topic = "*private*";
+ memset(usercount, 0, sizeof(usercount));
+ } else {
+ topic = entry->topic;
+ users = silc_list_count(entry->user_list);
+ SILC_PUT32_MSB(users, usercount);
+ }
+
+ /* Send the reply */
+ if (topic)
+ packet =
+ silc_command_reply_payload_encode_va(SILC_COMMAND_LIST,
+ status, ident, 4,
+ 2, idp->data, idp->len,
+ 3, entry->channel_name,
+ strlen(entry->channel_name),
+ 4, topic, strlen(topic),
+ 5, usercount, 4);
+ else
+ packet =
+ silc_command_reply_payload_encode_va(SILC_COMMAND_LIST,
+ status, ident, 3,
+ 2, idp->data, idp->len,
+ 3, entry->channel_name,
+ strlen(entry->channel_name),
+ 5, usercount, 4);
+ silc_server_packet_send(cmd->server, cmd->sock,
+ SILC_PACKET_COMMAND_REPLY, 0, packet->data,
+ packet->len, FALSE);
+ silc_buffer_free(packet);
+ silc_buffer_free(idp);
+ }
+
+ status = i ? SILC_STATUS_LIST_ITEM : SILC_STATUS_OK;
+
+ /* Global list */
+ for (i = 0; i < gch_count; i++) {
+ entry = gch[i];
+
+ if (!entry)
+ continue;
+
+ if (i >= 1)
+ status = SILC_STATUS_LIST_ITEM;
+
+ if (gch_count > 1 && i == lch_count - 1)
+ status = SILC_STATUS_LIST_END;
+
+ idp = silc_id_payload_encode(entry->id, SILC_ID_CHANNEL);
+
+ if (entry->mode & SILC_CHANNEL_MODE_PRIVATE) {
+ topic = "*private*";
+ memset(usercount, 0, sizeof(usercount));
+ } else {
+ topic = entry->topic;
+ users = silc_list_count(entry->user_list);
+ SILC_PUT32_MSB(users, usercount);
+ }
+
+ /* Send the reply */
+ if (topic)
+ packet =
+ silc_command_reply_payload_encode_va(SILC_COMMAND_LIST,
+ status, ident, 4,
+ 2, idp->data, idp->len,
+ 3, entry->channel_name,
+ strlen(entry->channel_name),
+ 4, topic, strlen(topic),
+ 5, usercount, 4);
+ else
+ packet =
+ silc_command_reply_payload_encode_va(SILC_COMMAND_LIST,
+ status, ident, 3,
+ 2, idp->data, idp->len,
+ 3, entry->channel_name,
+ strlen(entry->channel_name),
+ 5, usercount, 4);
+ silc_server_packet_send(cmd->server, cmd->sock,
+ SILC_PACKET_COMMAND_REPLY, 0, packet->data,
+ packet->len, FALSE);
+ silc_buffer_free(packet);
+ silc_buffer_free(idp);
+ }
+}
+
+/* Server side of LIST command. This lists the channel of the requested
+ server. Secret channels are not listed. */
+