SILC_CLIENT_CMD(list, LIST, "LIST", SILC_CF_LAG | SILC_CF_REG, 2),
SILC_CLIENT_CMD(topic, TOPIC, "TOPIC", SILC_CF_LAG | SILC_CF_REG, 3),
SILC_CLIENT_CMD(invite, INVITE, "INVITE", SILC_CF_LAG | SILC_CF_REG, 3),
- SILC_CLIENT_CMD(quit, QUIT, "QUIT", SILC_CF_LAG | SILC_CF_REG, 1),
+ SILC_CLIENT_CMD(quit, QUIT, "QUIT", SILC_CF_LAG | SILC_CF_REG, 2),
SILC_CLIENT_CMD(kill, KILL, "KILL",
SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER, 2),
SILC_CLIENT_CMD(info, INFO, "INFO", SILC_CF_LAG | SILC_CF_REG, 2),
silc_client_command_destructor,
silc_client_command_invite,
silc_client_command_dup(cmd));
- goto out;
+ cmd->pending = 1;
+ return;
}
/* Find channel entry */
silc_client_command_free(cmd);
}
+typedef struct {
+ SilcClient client;
+ SilcClientConnection conn;
+} *QuitInternal;
+
+SILC_TASK_CALLBACK(silc_client_command_quit_cb)
+{
+ QuitInternal q = (QuitInternal)context;
+
+ /* Close connection */
+ q->client->ops->disconnect(q->client, q->conn);
+ silc_client_close_connection(q->client, q->conn->sock);
+
+ silc_free(q);
+}
+
/* Command QUIT. Closes connection with current server. */
SILC_CLIENT_CMD_FUNC(quit)
{
SilcClientCommandContext cmd = (SilcClientCommandContext)context;
SilcBuffer buffer;
+ QuitInternal q;
if (!cmd->conn) {
SILC_NOT_CONNECTED(cmd->client, cmd->conn);
goto out;
}
- buffer = silc_command_payload_encode(SILC_COMMAND_QUIT, cmd->argc - 1,
- ++cmd->argv, ++cmd->argv_lens,
- ++cmd->argv_types, 0);
+ if (cmd->argc > 1)
+ buffer = silc_command_payload_encode(SILC_COMMAND_QUIT, cmd->argc - 1,
+ &cmd->argv[1], &cmd->argv_lens[1],
+ &cmd->argv_types[1], 0);
+ else
+ buffer = silc_command_payload_encode(SILC_COMMAND_QUIT, 0,
+ NULL, NULL, NULL, 0);
silc_client_packet_send(cmd->client, cmd->conn->sock, SILC_PACKET_COMMAND,
NULL, 0, NULL, NULL,
buffer->data, buffer->len, TRUE);
silc_buffer_free(buffer);
- cmd->argv--;
- cmd->argv_lens--;
- cmd->argv_types--;
- /* Close connection */
- cmd->client->ops->disconnect(cmd->client, cmd->conn);
- silc_client_close_connection(cmd->client, cmd->conn->sock);
+ q = silc_calloc(1, sizeof(*q));
+ q->client = cmd->client;
+ q->conn = cmd->conn;
+
+ /* We quit the connection with little timeout */
+ silc_task_register(cmd->client->timeout_queue, cmd->conn->sock->sock,
+ silc_client_command_quit_cb, (void *)q,
+ 1, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
/* Notify application */
COMMAND;
silc_client_command_destructor,
silc_client_command_cumode,
silc_client_command_dup(cmd));
- goto out;
+ cmd->pending = 1;
+ return;
}
while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
SilcIDCacheEntry id_cache = NULL;
SilcChannelEntry channel;
SilcBuffer buffer, idp;
- char *name;
+ char *name, *line = NULL;
+ unsigned int line_len = 0;
if (!cmd->conn) {
SILC_NOT_CONNECTED(cmd->client, cmd->conn);
silc_client_command_users,
silc_client_command_dup(cmd));
cmd->pending = TRUE;
- goto out;
+ return;
}
if (cmd->pending) {
cmd->client->ops->say(cmd->client, conn, "Users on %s",
channel->channel_name);
+ line = silc_calloc(4096, sizeof(*line));
+ line_len = 4096;
silc_list_start(channel->clients);
while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
SilcClientEntry e = chu->client;
- char *m, tmp[80], line[80], len1;
+ char *m, tmp[80], len1;
+
+ memset(line, 0, sizeof(line_len));
+
+ if (strlen(e->nickname) + strlen(e->server) + 100 > line_len) {
+ silc_free(line);
+ line_len += strlen(e->nickname) + strlen(e->server) + 100;
+ line = silc_calloc(line_len, sizeof(*line));
+ }
- memset(line, 0, sizeof(line));
memset(tmp, 0, sizeof(tmp));
m = silc_client_chumode_char(chu->mode);
- strcat(line, " ");
- strcat(line, e->nickname);
- strcat(line, e->server ? "@" : "");
+ strncat(line, " ", 1);
+ strncat(line, e->nickname, strlen(e->nickname));
+ strncat(line, e->server ? "@" : "", 1);
len1 = 0;
if (e->server)
strcat(line, " ");
}
- strcat(line, " H");
+ strncat(line, " H", 3);
strcat(tmp, m ? m : "");
- strcat(line, tmp);
+ strncat(line, tmp, strlen(tmp));
if (strlen(tmp) < 5)
for (i = 0; i < 5 - strlen(tmp); i++)
}
}
+ if (line)
+ silc_free(line);
+
/* Notify application */
COMMAND;