static void
silc_server_command_send_status_reply(SilcServerCommandContext cmd,
SilcCommand command,
- SilcCommandStatus status);
+ SilcStatus status);
static void
silc_server_command_send_status_data(SilcServerCommandContext cmd,
SilcCommand command,
- SilcCommandStatus status,
+ SilcStatus status,
SilcUInt32 arg_type,
const unsigned char *arg,
SilcUInt32 arg_len);
static void
silc_server_command_send_status_reply(SilcServerCommandContext cmd,
SilcCommand command,
- SilcCommandStatus status)
+ SilcStatus status)
{
SilcBuffer buffer;
static void
silc_server_command_send_status_data(SilcServerCommandContext cmd,
SilcCommand command,
- SilcCommandStatus status,
+ SilcStatus status,
SilcUInt32 arg_type,
const unsigned char *arg,
SilcUInt32 arg_len)
/* Get the max count of reply messages allowed */
tmp = silc_argument_get_arg_type(cmd->args, 2, NULL);
- if (tmp)
- *count = atoi(tmp);
- else
+ if (tmp) {
+ SILC_GET32_MSB(*count, tmp);
+ } else {
*count = 0;
+ }
return TRUE;
}
SilcServer server = cmd->server;
char *tmp;
int i, k, len, valid_count;
- SilcBuffer packet, idp, channels;
+ SilcBuffer packet, idp, channels, umode_list = NULL;
SilcClientEntry entry;
- SilcCommandStatus status;
+ SilcStatus status;
SilcUInt16 ident = silc_command_get_ident(cmd->payload);
char nh[256], uh[256];
unsigned char idle[4], mode[4];
strncat(uh, hsock->hostname, len);
}
- channels = silc_server_get_client_channel_list(server, entry);
+ if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT)
+ channels = silc_server_get_client_channel_list(server, entry, FALSE,
+ FALSE, &umode_list);
+ else
+ channels = silc_server_get_client_channel_list(server, entry, TRUE,
+ TRUE, &umode_list);
if (entry->data.fingerprint[0] != 0 && entry->data.fingerprint[1] != 0)
fingerprint = entry->data.fingerprint;
packet =
silc_command_reply_payload_encode_va(SILC_COMMAND_WHOIS,
- status, 0, ident, 8,
+ status, 0, ident, 9,
2, idp->data, idp->len,
3, nh, strlen(nh),
4, uh, strlen(uh),
7, mode, 4,
8, idle, 4,
9, fingerprint,
- fingerprint ? 20 : 0);
+ fingerprint ? 20 : 0,
+ 10, umode_list ? umode_list->data :
+ NULL, umode_list ? umode_list->len :
+ 0);
silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
0, packet->data, packet->len, FALSE);
silc_buffer_free(idp);
if (channels)
silc_buffer_free(channels);
+ if (umode_list) {
+ silc_buffer_free(umode_list);
+ umode_list = NULL;
+ }
k++;
}
/* Get the max count of reply messages allowed */
tmp = silc_argument_get_arg_type(cmd->args, 2, NULL);
- if (tmp)
- *count = atoi(tmp);
- else
+ if (tmp) {
+ SILC_GET32_MSB(*count, tmp);
+ } else {
*count = 0;
+ }
return TRUE;
}
int i, k, count = 0, len;
SilcBuffer packet, idp;
SilcClientEntry entry = NULL;
- SilcCommandStatus status;
+ SilcStatus status;
SilcUInt16 ident = silc_command_get_ident(cmd->payload);
char nh[256], uh[256];
int valid_count;
/* Get the max count of reply messages allowed */
tmp = silc_argument_get_arg_type(cmd->args, 4, NULL);
- if (tmp)
- *count = atoi(tmp);
- else
+ if (tmp) {
+ SILC_GET32_MSB(*count, tmp);
+ } else {
*count = 0;
+ }
return 1;
}
SilcServer server = cmd->server;
int i, k, len, valid_count;
SilcBuffer packet, idp;
- SilcCommandStatus status;
+ SilcStatus status;
SilcUInt16 ident = silc_command_get_ident(cmd->payload);
char nh[256], uh[256];
SilcSocketConnection hsock;
int i, k;
SilcBuffer packet, idp;
SilcChannelEntry entry;
- SilcCommandStatus status;
+ SilcStatus status;
SilcUInt16 ident = silc_command_get_ident(cmd->payload);
char *topic;
unsigned char usercount[4];
}
/* Get the client entry */
- dest = silc_server_get_client_resolve(server, dest_id, &resolve);
+ dest = silc_server_get_client_resolve(server, dest_id, FALSE, &resolve);
if (!dest) {
if (server->server_type != SILC_SERVER || !resolve) {
silc_server_command_send_status_reply(
if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
client = (SilcClientEntry)sock->user_data;
} else {
- client = silc_server_get_client_resolve(server, client_id, &resolve);
+ client = silc_server_get_client_resolve(server, client_id, FALSE,
+ &resolve);
if (!client) {
if (cmd->pending)
goto out;
silc_free(q);
}
+SILC_TASK_CALLBACK(silc_server_command_detach_timeout)
+{
+ QuitInternal q = (QuitInternal)context;
+ SilcClientEntry client = (SilcClientEntry)q->sock;
+
+ SILC_LOG_DEBUG(("Start"));
+
+ if (client->mode & SILC_UMODE_DETACHED)
+ silc_server_free_client_data(q->server, NULL, client, TRUE,
+ "Detach timeout");
+ silc_free(q);
+}
+
/* Server side of DETACH command. Detached the client from the network
by closing the connection but preserving the session. */
SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
QuitInternal q;
+ if (server->config->detach_disabled) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_DETACH,
+ SILC_STATUS_ERR_UNKNOWN_COMMAND);
+ goto out;
+ }
+
if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
goto out;
silc_schedule_task_add(server->schedule, 0, silc_server_command_detach_cb,
q, 0, 200000, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
+ if (server->config->detach_timeout) {
+ q = silc_calloc(1, sizeof(*q));
+ q->server = server;
+ q->sock = (void *)client;
+ silc_schedule_task_add(server->schedule, 0,
+ silc_server_command_detach_timeout,
+ q, server->config->detach_timeout * 60,
+ 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
+ }
+
/* Send reply to the sender */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_DETACH,
SILC_STATUS_OK);
channel = silc_idlist_find_channel_by_name(server->local_list,
channel_name, NULL);
- if (!channel || channel->disabled) {
+ if (!channel || channel->disabled || !channel->users_resolved) {
if (server->server_type != SILC_ROUTER && !server->standalone &&
!cmd->pending) {
SilcBuffer tmpbuf;
}
/* If the channel is private or secret do not send anything, unless the
- user requesting this command is on the channel. */
+ user requesting this command is on the channel or is server */
if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
if (channel->mode & (SILC_CHANNEL_MODE_PRIVATE | SILC_CHANNEL_MODE_SECRET)
&& !silc_server_client_on_channel(cmd->sock->user_data, channel,
NULL)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
- SILC_STATUS_ERR_NO_SUCH_CHANNEL);
- goto out;
- }
- } else {
- if (channel->mode &
- (SILC_CHANNEL_MODE_PRIVATE | SILC_CHANNEL_MODE_SECRET)) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
- SILC_STATUS_ERR_NO_SUCH_CHANNEL);
+ SILC_STATUS_ERR_NOT_ON_CHANNEL);
goto out;
}
}
client_id, TRUE, NULL);
if ((!client && !cmd->pending && !server->standalone) ||
- (client && !client->connection && !cmd->pending) ||
+ (client && !client->connection && !cmd->pending &&
+ !(client->mode & SILC_UMODE_DETACHED)) ||
(client && !client->data.public_key && !cmd->pending)) {
SilcBuffer tmpbuf;
SilcUInt16 old_ident;