SILC_SERVER_CMD(quit, QUIT, SILC_CF_LAG | SILC_CF_REG),
SILC_SERVER_CMD(kill, KILL, SILC_CF_LAG_STRICT | SILC_CF_REG | SILC_CF_OPER),
SILC_SERVER_CMD(info, INFO, SILC_CF_LAG | SILC_CF_REG),
+ SILC_SERVER_CMD(stats, STATS, SILC_CF_LAG | SILC_CF_REG),
SILC_SERVER_CMD(ping, PING, SILC_CF_LAG | SILC_CF_REG),
SILC_SERVER_CMD(oper, OPER, SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER),
SILC_SERVER_CMD(join, JOIN, SILC_CF_LAG_STRICT | SILC_CF_REG),
SILC_LOG_DEBUG(("Sending command status %d", status));
buffer =
- silc_command_reply_payload_encode_va(command, status,
+ silc_command_reply_payload_encode_va(command, status, 0,
silc_command_get_ident(cmd->payload),
0);
silc_server_packet_send(cmd->server, cmd->sock,
SILC_LOG_DEBUG(("Sending command status %d", status));
buffer =
- silc_command_reply_payload_encode_va(command, status,
+ silc_command_reply_payload_encode_va(command, status, 0,
silc_command_get_ident(cmd->payload),
1, arg_type, arg, arg_len);
silc_server_packet_send(cmd->server, cmd->sock,
SilcServerCommandReplyContext cmdr,
SilcCommand command)
{
- SilcCommandStatus status;
-
if (!cmd->pending || !cmdr)
return FALSE;
- SILC_GET16_MSB(status, silc_argument_get_arg_type(cmdr->args, 1, NULL));
- if (status != SILC_STATUS_OK &&
- status != SILC_STATUS_LIST_START &&
- status != SILC_STATUS_LIST_ITEM &&
- status != SILC_STATUS_LIST_END) {
+ if (!silc_command_get_status(cmdr->payload, NULL, NULL)) {
SilcBuffer buffer;
/* Send the same command reply payload */
packet =
silc_command_reply_payload_encode_va(SILC_COMMAND_WHOIS,
- status, ident, 8,
+ status, 0, ident, 8,
2, idp->data, idp->len,
3, nh, strlen(nh),
4, uh, strlen(uh),
packet =
silc_command_reply_payload_encode_va(SILC_COMMAND_WHOWAS,
- status, ident, 4,
+ status, 0, ident, 4,
2, idp->data, idp->len,
3, nh, strlen(nh),
4, uh, strlen(uh),
if (!entry->username) {
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_IDENTIFY,
- status, ident, 2,
+ status, 0, ident, 2,
2, idp->data, idp->len,
3, nh, strlen(nh));
} else {
}
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_IDENTIFY,
- status, ident, 3,
+ status, 0, ident, 3,
2, idp->data, idp->len,
3, nh, strlen(nh),
4, uh, strlen(uh));
idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
packet =
silc_command_reply_payload_encode_va(SILC_COMMAND_IDENTIFY,
- status, ident, 2,
+ status, 0, ident, 2,
2, idp->data, idp->len,
3, entry->server_name,
entry->server_name ?
idp = silc_id_payload_encode(entry->id, SILC_ID_CHANNEL);
packet =
silc_command_reply_payload_encode_va(SILC_COMMAND_IDENTIFY,
- status, ident, 2,
+ status, 0, ident, 2,
2, idp->data, idp->len,
3, entry->channel_name,
entry->channel_name ?
send_reply:
/* Send the new Client ID as reply command back to client */
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_NICK,
- SILC_STATUS_OK, ident, 1,
+ SILC_STATUS_OK, 0, ident, 1,
2, nidp->data, nidp->len);
silc_server_packet_send(cmd->server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
0, packet->data, packet->len, FALSE);
/* Send the reply */
packet =
silc_command_reply_payload_encode_va(SILC_COMMAND_LIST,
- status, ident, 4,
+ status, 0, ident, 4,
2, idp->data, idp->len,
3, entry->channel_name,
strlen(entry->channel_name),
/* Send the reply */
packet =
silc_command_reply_payload_encode_va(SILC_COMMAND_LIST,
- status, ident, 4,
+ status, 0, ident, 4,
2, idp->data, idp->len,
3, entry->channel_name,
strlen(entry->channel_name),
/* Send the topic to client as reply packet */
idp = silc_id_payload_encode(channel_id, SILC_ID_CHANNEL);
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_TOPIC,
- SILC_STATUS_OK, ident, 2,
+ SILC_STATUS_OK, 0, ident, 2,
2, idp->data, idp->len,
3, channel->topic,
channel->topic ?
}
/* Get route to the client */
- dest_sock = silc_server_get_client_route(server, NULL, 0, dest_id, &idata);
+ dest_sock = silc_server_get_client_route(server, NULL, 0, dest_id,
+ &idata, NULL);
if (!dest_sock) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
SILC_STATUS_ERR_NO_SUCH_CLIENT_ID);
if (add || del)
packet =
silc_command_reply_payload_encode_va(SILC_COMMAND_INVITE,
- SILC_STATUS_OK, ident, 2,
+ SILC_STATUS_OK, 0, ident, 2,
2, tmp, len,
3, channel->invite_list,
channel->invite_list ?
else
packet =
silc_command_reply_payload_encode_va(SILC_COMMAND_INVITE,
- SILC_STATUS_OK, ident, 1,
+ SILC_STATUS_OK, 0, ident, 1,
2, tmp, len);
silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
packet->data, packet->len, FALSE);
/* Update statistics */
if (remote_client->connection)
server->stat.my_clients--;
- if (server->server_type == SILC_ROUTER)
+ if (server->stat.cell_clients)
server->stat.cell_clients--;
SILC_OPER_STATS_UPDATE(remote_client, server, SILC_UMODE_SERVER_OPERATOR);
SILC_OPER_STATS_UPDATE(remote_client, router, SILC_UMODE_ROUTER_OPERATOR);
/* Send the reply */
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_INFO,
- SILC_STATUS_OK, ident, 3,
+ SILC_STATUS_OK, 0, ident, 3,
2, idp->data, idp->len,
3, server_name,
strlen(server_name),
silc_server_command_free(cmd);
}
+/* Server side of command STATS. */
+
+SILC_SERVER_CMD_FUNC(stats)
+{
+ SilcServerCommandContext cmd = (SilcServerCommandContext)context;
+ SilcServer server = cmd->server;
+ SilcServerID *server_id;
+ unsigned char *tmp;
+ SilcUInt32 tmp_len;
+ SilcBuffer packet, stats;
+ SilcUInt16 ident = silc_command_get_ident(cmd->payload);
+ SilcUInt32 uptime;
+
+ SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_STATS, cmd, 1, 1);
+
+ /* Get Server ID */
+ tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
+ if (!tmp) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
+ SILC_STATUS_ERR_NO_SERVER_ID);
+ goto out;
+ }
+ server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
+ if (!server_id)
+ goto out;
+
+ /* The ID must be ours */
+ if (!SILC_ID_SERVER_COMPARE(server->id, server_id)) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
+ SILC_STATUS_ERR_NO_SUCH_SERVER);
+ silc_free(server_id);
+ goto out;
+ }
+ silc_free(server_id);
+
+ /* If we are router then just send everything we got. If we are normal
+ server then we'll send this to our router to get all the latest
+ statistical information. */
+ if (!cmd->pending && server->server_type != SILC_ROUTER &&
+ !server->standalone) {
+ /* Send request to our router */
+ SilcBuffer idp = silc_id_payload_encode(server->router->id,
+ SILC_ID_SERVER);
+ packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
+ ++server->cmd_ident, 1,
+ 1, idp->data, idp->len);
+ silc_server_packet_send(server, server->router->connection,
+ SILC_PACKET_COMMAND, 0, packet->data,
+ packet->len, FALSE);
+
+ /* Reprocess this packet after received reply from router */
+ silc_server_command_pending(server, SILC_COMMAND_STATS,
+ server->cmd_ident,
+ silc_server_command_stats,
+ silc_server_command_dup(cmd));
+ cmd->pending = TRUE;
+ silc_buffer_free(packet);
+ silc_buffer_free(idp);
+ goto out;
+ }
+
+ /* Send our reply to sender */
+ uptime = time(NULL) - server->starttime;
+
+ stats = silc_buffer_alloc_size(60);
+ silc_buffer_format(stats,
+ SILC_STR_UI_INT(server->starttime),
+ SILC_STR_UI_INT(uptime),
+ SILC_STR_UI_INT(server->stat.my_clients),
+ SILC_STR_UI_INT(server->stat.my_channels),
+ SILC_STR_UI_INT(server->stat.my_server_ops),
+ SILC_STR_UI_INT(server->stat.my_router_ops),
+ SILC_STR_UI_INT(server->stat.cell_clients),
+ SILC_STR_UI_INT(server->stat.cell_channels),
+ SILC_STR_UI_INT(server->stat.cell_servers),
+ SILC_STR_UI_INT(server->stat.clients),
+ SILC_STR_UI_INT(server->stat.channels),
+ SILC_STR_UI_INT(server->stat.servers),
+ SILC_STR_UI_INT(server->stat.routers),
+ SILC_STR_UI_INT(server->stat.server_ops),
+ SILC_STR_UI_INT(server->stat.router_ops),
+ SILC_STR_END);
+
+ packet = silc_command_reply_payload_encode_va(SILC_COMMAND_STATS,
+ SILC_STATUS_OK, 0, ident, 2,
+ 2, tmp, tmp_len,
+ 3, stats->data, stats->len);
+ silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
+ 0, packet->data, packet->len, FALSE);
+ silc_buffer_free(packet);
+ silc_buffer_free(stats);
+
+ out:
+ silc_server_command_free(cmd);
+}
+
/* Internal routine to join channel. The channel sent to this function
has been either created or resolved from ID lists. This joins the sent
client to the channel. */
reply =
silc_command_reply_payload_encode_va(SILC_COMMAND_JOIN,
- SILC_STATUS_OK, ident, 13,
+ SILC_STATUS_OK, 0, ident, 13,
2, channel->channel_name,
strlen(channel->channel_name),
3, chidp->data, chidp->len,
/* Check whether the channel was created by our router */
if (cmd->pending && context2) {
- SilcServerCommandReplyContext reply =
- (SilcServerCommandReplyContext)context2;
+ SilcServerCommandReplyContext reply = context2;
if (silc_command_get(reply->payload) == SILC_COMMAND_JOIN) {
tmp = silc_argument_get_arg_type(reply->args, 6, NULL);
motd[motd_len] = 0;
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD,
- SILC_STATUS_OK, ident, 2,
+ SILC_STATUS_OK, 0,
+ ident, 2,
2, idp, idp->len,
3, motd, motd_len);
} else {
/* No motd */
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD,
- SILC_STATUS_OK, ident, 1,
+ SILC_STATUS_OK, 0,
+ ident, 1,
2, idp, idp->len);
}
idp = silc_id_payload_encode(server->id_entry->id, SILC_ID_SERVER);
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD,
- SILC_STATUS_OK, ident, 2,
+ SILC_STATUS_OK, 0, ident, 2,
2, idp, idp->len,
3, entry->motd,
entry->motd ?
goto out;
}
+ /* Anonymous mode cannot be set by client */
+ if (mask & SILC_UMODE_ANONYMOUS) {
+ if (!(client->mode & SILC_UMODE_ANONYMOUS)) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
+ SILC_STATUS_ERR_PERM_DENIED);
+ goto out;
+ }
+ } else {
+ if (client->mode & SILC_UMODE_ANONYMOUS) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
+ SILC_STATUS_ERR_PERM_DENIED);
+ goto out;
+ }
+ }
+
/* Change the mode */
client->mode = mask;
/* Send command reply to sender */
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_UMODE,
- SILC_STATUS_OK, ident, 1,
+ SILC_STATUS_OK, 0, ident, 1,
2, tmp_mask, 4);
silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
packet->data, packet->len, FALSE);
/* Send command reply to sender */
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CMODE,
- SILC_STATUS_OK, ident, 2,
+ SILC_STATUS_OK, 0, ident, 2,
2, tmp_id, tmp_len2,
3, tmp_mask, 4);
silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
}
if (target_mask & SILC_CHANNEL_UMODE_CHANFO) {
+ if (target_client != client) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_NOT_YOU);
+ goto out;
+ }
+
if (!(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
/* The client tries to claim the founder rights. */
unsigned char *tmp_auth;
SilcUInt32 tmp_auth_len, auth_len;
void *auth;
- if (target_client != client) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NOT_YOU);
- goto out;
- }
-
if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
!channel->founder_key || !idata->public_key ||
!silc_pkcs_public_key_compare(channel->founder_key,
}
}
+ if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES) {
+ if (target_client != client) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_NOT_YOU);
+ goto out;
+ }
+
+ if (!(chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)) {
+ chl->mode |= SILC_CHANNEL_UMODE_BLOCK_MESSAGES;
+ notify = TRUE;
+ }
+ } else {
+ if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES) {
+ if (target_client != client) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_NOT_YOU);
+ goto out;
+ }
+
+ chl->mode &= ~SILC_CHANNEL_UMODE_BLOCK_MESSAGES;
+ notify = TRUE;
+ }
+ }
+
+
idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
tmp_id = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
/* Send command reply to sender */
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CUMODE,
- SILC_STATUS_OK, ident, 3,
+ SILC_STATUS_OK, 0, ident, 3,
2, tmp_mask, 4,
3, tmp_ch_id, tmp_ch_len,
4, tmp_id, tmp_len);
/* Send the reply back to the client */
packet =
silc_command_reply_payload_encode_va(SILC_COMMAND_BAN,
- SILC_STATUS_OK, ident, 2,
+ SILC_STATUS_OK, 0, ident, 2,
2, id, id_len,
3, channel->ban_list,
channel->ban_list ?
/* Send reply */
idp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_USERS,
- SILC_STATUS_OK, ident, 4,
+ SILC_STATUS_OK, 0, ident, 4,
2, idp->data, idp->len,
3, lc, 4,
4, client_id_list->data,
SilcSocketConnection dest_sock;
dest_sock = silc_server_get_client_route(server, NULL, 0,
- client_id, NULL);
+ client_id, NULL, NULL);
if (!dest_sock)
goto out;
tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_GETKEY,
- SILC_STATUS_OK, ident,
+ SILC_STATUS_OK, 0, ident,
pkdata ? 2 : 1,
2, tmp, tmp_len,
3, pkdata, pklen);