#include "fe-common/silc/module-formats.h"
#include "core.h"
+#include "blob.h"
static void
silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
SilcSKEPKType pk_type,
SilcVerifyPublicKey completion, void *context);
+static void silc_get_umode_string(SilcUInt32 mode, char *buf,
+ SilcUInt32 buf_size)
+{
+ if ((mode & SILC_UMODE_SERVER_OPERATOR) ||
+ (mode & SILC_UMODE_ROUTER_OPERATOR)) {
+ strcat(buf, (mode & SILC_UMODE_SERVER_OPERATOR) ?
+ "[server operator]" :
+ (mode & SILC_UMODE_ROUTER_OPERATOR) ?
+ "[SILC operator]" : "[unknown mode]");
+ }
+ if (mode & SILC_UMODE_GONE)
+ strcat(buf, " [away]");
+ if (mode & SILC_UMODE_INDISPOSED)
+ strcat(buf, " [indisposed]");
+ if (mode & SILC_UMODE_BUSY)
+ strcat(buf, " [busy]");
+ if (mode & SILC_UMODE_PAGE)
+ strcat(buf, " [page to reach]");
+ if (mode & SILC_UMODE_HYPER)
+ strcat(buf, " [hyper active]");
+ if (mode & SILC_UMODE_ROBOT)
+ strcat(buf, " [robot]");
+ if (mode & SILC_UMODE_ANONYMOUS)
+ strcat(buf, " [anonymous]");
+ if (mode & SILC_UMODE_BLOCK_PRIVMSG)
+ strcat(buf, " [blocks private messages]");
+ if (mode & SILC_UMODE_DETACHED)
+ strcat(buf, " [detached]");
+ if (mode & SILC_UMODE_REJECT_WATCHING)
+ strcat(buf, " [rejects watching]");
+ if (mode & SILC_UMODE_BLOCK_INVITE)
+ strcat(buf, " [blocks invites]");
+}
+
void silc_say(SilcClient client, SilcClientConnection conn,
SilcClientMessageType type, char *msg, ...)
{
va_end(va);
}
+void silc_emit_mime_sig(SILC_SERVER_REC *server, SILC_CHANNEL_REC *channel,
+ const char *data, SilcUInt32 data_len,
+ const char *encoding, const char *type,
+ const char *nick)
+{
+ BLOB_REC blob;
+
+ blob_fill(&blob);
+ blob.octets = data_len;
+ blob.data = (char *)data;
+
+ signal_emit("mime", 6, server, channel, &blob, encoding, type, nick);
+}
+
/* Message for a channel. The `sender' is the nickname of the sender
received in the packet. The `channel_name' is the name of the channel. */
nick = silc_nicklist_insert(chanrec, chu, FALSE);
}
+ if (flags & SILC_MESSAGE_FLAG_DATA) {
+ /* MIME object received, try to display it as well as we can */
+ char type[128], enc[128];
+ unsigned char *data;
+ SilcUInt32 data_len;
+
+ memset(type, 0, sizeof(type));
+ memset(enc, 0, sizeof(enc));
+ if (!silc_mime_parse(message, message_len, NULL, 0, type, sizeof(type) - 1,
+ enc, sizeof(enc) - 1, &data, &data_len))
+ return;
+
+ /* Then figure out what we can display */
+ if (strstr(type, "text/") && !strstr(type, "text/t140") &&
+ !strstr(type, "text/vnd")) {
+ /* It is something textual, display it */
+ message = (const unsigned char *)data;
+ } else {
+ silc_emit_mime_sig(server, chanrec, data, data_len,
+ enc, type, nick->nick);
+ message = NULL;
+ }
+ }
+
+ if (!message)
+ return;
+
if (flags & SILC_MESSAGE_FLAG_ACTION)
printformat_module("fe-common/silc", server, channel->channel_name,
MSGLEVEL_ACTIONS, SILCTXT_CHANNEL_ACTION,
printformat_module("fe-common/silc", server, channel->channel_name,
MSGLEVEL_NOTICES, SILCTXT_CHANNEL_NOTICE,
nick == NULL ? "[<unknown>]" : nick->nick, message);
- else
+ else {
+ if (flags & SILC_MESSAGE_FLAG_UTF8 && !silc_term_utf8()) {
+ char tmp[256], *cp, *dm = NULL;
+
+ memset(tmp, 0, sizeof(tmp));
+ cp = tmp;
+ if (message_len > sizeof(tmp) - 1) {
+ dm = silc_calloc(message_len + 1, sizeof(*dm));
+ cp = dm;
+ }
+
+ silc_utf8_decode(message, message_len, SILC_STRING_LANGUAGE,
+ cp, message_len);
+ signal_emit("message public", 6, server, cp,
+ nick == NULL ? "[<unknown>]" : nick->nick,
+ nick == NULL ? "" : nick->host == NULL ? "" : nick->host,
+ chanrec->name, nick);
+ silc_free(dm);
+ return;
+ }
+
signal_emit("message public", 6, server, message,
nick == NULL ? "[<unknown>]" : nick->nick,
nick == NULL ? "" : nick->host == NULL ? "" : nick->host,
chanrec->name, nick);
+ }
}
/* Private message to the client. The `sender' is the nickname of the
if (sender->username)
snprintf(userhost, sizeof(userhost) - 1, "%s@%s",
sender->username, sender->hostname);
+
+ if (flags & SILC_MESSAGE_FLAG_DATA) {
+ /* MIME object received, try to display it as well as we can */
+ char type[128], enc[128];
+ unsigned char *data;
+ SilcUInt32 data_len;
+
+ memset(type, 0, sizeof(type));
+ memset(enc, 0, sizeof(enc));
+ if (!silc_mime_parse(message, message_len, NULL, 0, type, sizeof(type) - 1,
+ enc, sizeof(enc) - 1, &data, &data_len))
+ return;
+
+ /* Then figure out what we can display */
+ if (strstr(type, "text/") && !strstr(type, "text/t140") &&
+ !strstr(type, "text/vnd")) {
+ /* It is something textual, display it */
+ message = (const unsigned char *)data;
+ } else {
+ silc_emit_mime_sig(server, NULL, data, data_len,
+ enc, type, sender->nickname);
+ message = NULL;
+ }
+ }
+
+ if (!message)
+ return;
+
+ if (flags & SILC_MESSAGE_FLAG_UTF8 && !silc_term_utf8()) {
+ char tmp[256], *cp, *dm = NULL;
+
+ memset(tmp, 0, sizeof(tmp));
+ cp = tmp;
+ if (message_len > sizeof(tmp) - 1) {
+ dm = silc_calloc(message_len + 1, sizeof(*dm));
+ cp = dm;
+ }
+
+ silc_utf8_decode(message, message_len, SILC_STRING_LANGUAGE,
+ cp, message_len);
+ signal_emit("message private", 4, server, cp,
+ sender->nickname ? sender->nickname : "[<unknown>]",
+ sender->username ? userhost : NULL);
+ silc_free(dm);
+ return;
+ }
+
signal_emit("message private", 4, server, message,
sender->nickname ? sender->nickname : "[<unknown>]",
sender->username ? userhost : NULL);
SilcIdType idtype;
void *entry;
SilcUInt32 mode;
- char userhost[512];
+ char buf[512];
char *name, *tmp;
GSList *list1, *list_tmp;
name = va_arg(va, char *);
client_entry = va_arg(va, SilcClientEntry);
- memset(userhost, 0, sizeof(userhost));
- snprintf(userhost, sizeof(userhost) - 1, "%s@%s",
+ memset(buf, 0, sizeof(buf));
+ snprintf(buf, sizeof(buf) - 1, "%s@%s",
client_entry->username, client_entry->hostname);
signal_emit("message invite", 4, server, channel ? channel->channel_name :
- name, client_entry->nickname, userhost);
+ name, client_entry->nickname, buf);
break;
case SILC_NOTIFY_TYPE_JOIN:
}
}
- memset(userhost, 0, sizeof(userhost));
+ memset(buf, 0, sizeof(buf));
if (client_entry->username)
- snprintf(userhost, sizeof(userhost) - 1, "%s@%s",
+ snprintf(buf, sizeof(buf) - 1, "%s@%s",
client_entry->username, client_entry->hostname);
signal_emit("message join", 4, server, channel->channel_name,
client_entry->nickname,
- client_entry->username == NULL ? "" : userhost);
+ client_entry->username == NULL ? "" : buf);
break;
case SILC_NOTIFY_TYPE_LEAVE:
client_entry = va_arg(va, SilcClientEntry);
channel = va_arg(va, SilcChannelEntry);
- memset(userhost, 0, sizeof(userhost));
+ memset(buf, 0, sizeof(buf));
if (client_entry->username)
- snprintf(userhost, sizeof(userhost) - 1, "%s@%s",
+ snprintf(buf, sizeof(buf) - 1, "%s@%s",
client_entry->username, client_entry->hostname);
signal_emit("message part", 5, server, channel->channel_name,
client_entry->nickname, client_entry->username ?
- userhost : "", client_entry->nickname);
+ buf : "", client_entry->nickname);
chanrec = silc_channel_find_entry(server, channel);
if (chanrec != NULL) {
silc_server_free_ftp(server, client_entry);
- memset(userhost, 0, sizeof(userhost));
+ memset(buf, 0, sizeof(buf));
if (client_entry->username)
- snprintf(userhost, sizeof(userhost) - 1, "%s@%s",
+ snprintf(buf, sizeof(buf) - 1, "%s@%s",
client_entry->username, client_entry->hostname);
signal_emit("message quit", 4, server, client_entry->nickname,
- client_entry->username ? userhost : "",
+ client_entry->username ? buf : "",
tmp ? tmp : "");
list1 = nicklist_get_same_unique(SERVER(server), client_entry);
if (idtype == SILC_ID_CLIENT) {
client_entry = (SilcClientEntry)entry;
- memset(userhost, 0, sizeof(userhost));
- snprintf(userhost, sizeof(userhost) - 1, "%s@%s",
+ memset(buf, 0, sizeof(buf));
+ snprintf(buf, sizeof(buf) - 1, "%s@%s",
client_entry->username, client_entry->hostname);
signal_emit("message topic", 5, server, channel->channel_name,
- tmp, client_entry->nickname, userhost);
+ tmp, client_entry->nickname, buf);
} else if (idtype == SILC_ID_SERVER) {
server_entry = (SilcServerEntry)entry;
signal_emit("message topic", 5, server, channel->channel_name,
tmp, server_entry->server_name,
server_entry->server_name);
- } else {
+ } else if (idtype == SILC_ID_CHANNEL) {
channel = (SilcChannelEntry)entry;
signal_emit("message topic", 5, server, channel->channel_name,
tmp, channel->channel_name, channel->channel_name);
client_entry = va_arg(va, SilcClientEntry);
client_entry2 = va_arg(va, SilcClientEntry);
+
+ if (!strcmp(client_entry->nickname, client_entry2->nickname))
+ break;
- memset(userhost, 0, sizeof(userhost));
- snprintf(userhost, sizeof(userhost) - 1, "%s@%s",
+ memset(buf, 0, sizeof(buf));
+ snprintf(buf, sizeof(buf) - 1, "%s@%s",
client_entry2->username, client_entry2->hostname);
nicklist_rename_unique(SERVER(server),
client_entry, client_entry->nickname,
client_entry2, client_entry2->nickname);
signal_emit("message nick", 4, server, client_entry2->nickname,
- client_entry->nickname, userhost);
+ client_entry->nickname, buf);
break;
case SILC_NOTIFY_TYPE_CMODE_CHANGE:
MSGLEVEL_MODES, SILCTXT_CHANNEL_CMODE,
channel->channel_name, tmp ? tmp : "removed all",
server_entry->server_name);
- } else {
+ } else if (idtype == SILC_ID_CHANNEL) {
channel2 = (SilcChannelEntry)entry;
printformat_module("fe-common/silc", server, channel->channel_name,
MSGLEVEL_MODES, SILCTXT_CHANNEL_CMODE,
channel->channel_name, client_entry2->nickname,
tmp ? tmp : "removed all",
server_entry->server_name);
- } else {
+ } else if (idtype == SILC_ID_CHANNEL) {
channel2 = (SilcChannelEntry)entry;
printformat_module("fe-common/silc", server, channel->channel_name,
MSGLEVEL_MODES, SILCTXT_CHANNEL_CUMODE,
SILCTXT_CHANNEL_FOUNDER,
channel->channel_name, client_entry2->nickname);
+ if (mode & SILC_CHANNEL_UMODE_QUIET && conn->local_entry == client_entry2)
+ printformat_module("fe-common/silc",
+ server, channel->channel_name, MSGLEVEL_CRAP,
+ SILCTXT_CHANNEL_QUIETED, channel->channel_name);
+
silc_free(tmp);
break;
client_entry = va_arg(va, SilcClientEntry);
tmp = va_arg(va, char *);
- client_entry2 = va_arg(va, SilcClientEntry);
+ idtype = va_arg(va, int);
+ entry = va_arg(va, SilcClientEntry);
if (client_entry == conn->local_entry) {
- printformat_module("fe-common/silc", server, NULL,
- MSGLEVEL_CRAP, SILCTXT_CHANNEL_KILLED_YOU,
- client_entry2 ? client_entry2->nickname : "",
- tmp ? tmp : "");
+ if (idtype == SILC_ID_CLIENT) {
+ client_entry2 = (SilcClientEntry)entry;
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_CHANNEL_KILLED_YOU,
+ client_entry2 ? client_entry2->nickname : "",
+ tmp ? tmp : "");
+ } else if (idtype == SILC_ID_SERVER) {
+ server_entry = (SilcServerEntry)entry;
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_CHANNEL_KILLED_YOU,
+ server_entry->server_name, tmp ? tmp : "");
+ } else if (idtype == SILC_ID_CHANNEL) {
+ channel = (SilcChannelEntry)entry;
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_CHANNEL_KILLED_YOU,
+ channel->channel_name, tmp ? tmp : "");
+ }
} else {
list1 = nicklist_get_same_unique(SERVER(server), client_entry);
for (list_tmp = list1; list_tmp != NULL; list_tmp =
nicklist_remove(channel, nickrec);
}
- printformat_module("fe-common/silc", server, NULL,
- MSGLEVEL_CRAP, SILCTXT_CHANNEL_KILLED,
- client_entry->nickname,
- client_entry2 ? client_entry2->nickname : "",
- tmp ? tmp : "");
+ if (idtype == SILC_ID_CLIENT) {
+ client_entry2 = (SilcClientEntry)entry;
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_CHANNEL_KILLED,
+ client_entry->nickname,
+ client_entry2 ? client_entry2->nickname : "",
+ tmp ? tmp : "");
+ } else if (idtype == SILC_ID_SERVER) {
+ server_entry = (SilcServerEntry)entry;
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_CHANNEL_KILLED,
+ client_entry->nickname,
+ server_entry->server_name, tmp ? tmp : "");
+ } else if (idtype == SILC_ID_CHANNEL) {
+ channel = (SilcChannelEntry)entry;
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_CHANNEL_KILLED,
+ client_entry->nickname,
+ channel->channel_name, tmp ? tmp : "");
+ }
}
break;
clients_count = va_arg(va, SilcUInt32);
for (i = 0; i < clients_count; i++) {
- memset(userhost, 0, sizeof(userhost));
+ memset(buf, 0, sizeof(buf));
if (clients[i]->username)
- snprintf(userhost, sizeof(userhost) - 1, "%s@%s",
+ snprintf(buf, sizeof(buf) - 1, "%s@%s",
clients[i]->username, clients[i]->hostname);
signal_emit("message quit", 4, server, clients[i]->nickname,
- clients[i]->username ? userhost : "",
+ clients[i]->username ? buf : "",
"server signoff");
silc_server_free_ftp(server, clients[i]);
}
break;
+ case SILC_NOTIFY_TYPE_ERROR:
+ {
+ SilcStatus error = va_arg(va, int);
+
+ silc_say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
+ "%s", silc_get_status_message(error));
+ }
+ break;
+
+ case SILC_NOTIFY_TYPE_WATCH:
+ {
+ SilcNotifyType notify;
+
+ client_entry = va_arg(va, SilcClientEntry);
+ name = va_arg(va, char *); /* Maybe NULL */
+ mode = va_arg(va, SilcUInt32);
+ notify = va_arg(va, int);
+
+ if (notify == SILC_NOTIFY_TYPE_NICK_CHANGE) {
+ if (name)
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_WATCH_NICK_CHANGE,
+ client_entry->nickname, name);
+ else
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_WATCH_PRESENT,
+ client_entry->nickname);
+ } else if (notify == SILC_NOTIFY_TYPE_UMODE_CHANGE) {
+ /* See if client was away and is now present */
+ if (!(mode & (SILC_UMODE_GONE | SILC_UMODE_INDISPOSED |
+ SILC_UMODE_BUSY | SILC_UMODE_PAGE |
+ SILC_UMODE_DETACHED)) &&
+ (client_entry->mode & SILC_UMODE_GONE ||
+ client_entry->mode & SILC_UMODE_INDISPOSED ||
+ client_entry->mode & SILC_UMODE_BUSY ||
+ client_entry->mode & SILC_UMODE_PAGE ||
+ client_entry->mode & SILC_UMODE_DETACHED)) {
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_WATCH_PRESENT,
+ client_entry->nickname);
+ }
+
+ if (mode) {
+ memset(buf, 0, sizeof(buf));
+ silc_get_umode_string(mode, buf, sizeof(buf) - 1);
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_WATCH_UMODE_CHANGE,
+ client_entry->nickname, buf);
+ }
+ } else if (notify == SILC_NOTIFY_TYPE_KILLED) {
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_WATCH_KILLED,
+ client_entry->nickname);
+ } else if (notify == SILC_NOTIFY_TYPE_SIGNOFF ||
+ notify == SILC_NOTIFY_TYPE_SERVER_SIGNOFF) {
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_WATCH_SIGNOFF,
+ client_entry->nickname);
+ } else if (notify == SILC_NOTIFY_TYPE_NONE) {
+ /* Client logged in to the network */
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_WATCH_PRESENT,
+ client_entry->nickname);
+ }
+ }
+ break;
+
default:
/* Unknown notify */
printformat_module("fe-common/silc", server, NULL,
or connecting failed. This is also the first time application receives
the SilcClientConnection object which it should save somewhere. */
-void silc_connect(SilcClient client, SilcClientConnection conn, int success)
+void silc_connect(SilcClient client, SilcClientConnection conn,
+ SilcClientConnectionStatus status)
{
SILC_SERVER_REC *server = conn->context;
- if (!server && !success) {
+ if (!server || server->disconnected) {
silc_client_close_connection(client, conn);
return;
}
- if (success) {
+ switch (status) {
+ case SILC_CLIENT_CONN_SUCCESS:
+ /* We have successfully connected to server */
server->connected = TRUE;
signal_emit("event connected", 1, server);
- } else {
+ break;
+
+ case SILC_CLIENT_CONN_SUCCESS_RESUME:
+ /* We have successfully resumed old detached session */
+ server->connected = TRUE;
+ signal_emit("event connected", 1, server);
+
+ /* If we resumed old session check whether we need to update
+ our nickname */
+ if (strcmp(server->nick, conn->local_entry->nickname)) {
+ char *old;
+ old = g_strdup(server->nick);
+ server_change_nick(SERVER(server), conn->local_entry->nickname);
+ nicklist_rename_unique(SERVER(server),
+ conn->local_entry, server->nick,
+ conn->local_entry, conn->local_entry->nickname);
+ signal_emit("message own_nick", 4, server, server->nick, old, "");
+ g_free(old);
+ }
+ break;
+
+ default:
server->connection_lost = TRUE;
if (server->conn)
server->conn->context = NULL;
server_disconnect(SERVER(server));
+ break;
}
}
/* Called to indicate that connection was disconnected to the server. */
-void silc_disconnect(SilcClient client, SilcClientConnection conn)
+void silc_disconnect(SilcClient client, SilcClientConnection conn,
+ SilcStatus status, const char *message)
{
SILC_SERVER_REC *server = conn->context;
silc_change_nick(server, silc_client->username);
}
+ if (message)
+ silc_say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
+ "Server closed connection: %s (%d) %s",
+ silc_get_status_message(status), status,
+ message ? message : "");
+
server->conn->context = NULL;
server->conn = NULL;
server->connection_lost = TRUE;
that the command really was processed. */
void silc_command(SilcClient client, SilcClientConnection conn,
- SilcClientCommandContext cmd_context, int success,
- SilcCommand command)
+ SilcClientCommandContext cmd_context, bool success,
+ SilcCommand command, SilcStatus status)
{
SILC_SERVER_REC *server = conn->context;
SILC_LOG_DEBUG(("Start"));
- if (!success)
+ if (!success) {
+ silc_say_error("%s", silc_get_status_message(status));
return;
+ }
- switch(command) {
+ switch (command) {
case SILC_COMMAND_INVITE:
printformat_module("fe-common/silc", server, NULL,
MSGLEVEL_CRAP, SILCTXT_CHANNEL_INVITING,
SilcClientEntry founder = NULL;
NICK_REC *ownnick;
+ SILC_LOG_DEBUG(("Start, channel %s, %d users", channel->channel_name,
+ silc_hash_table_count(channel->user_list)));
+
if (!clients)
return;
ownnick = NICK(silc_nicklist_find(chanrec, conn->local_entry));
nicklist_set_own(CHANNEL(chanrec), ownnick);
signal_emit("channel joined", 1, chanrec);
+ chanrec->entry = channel;
if (chanrec->topic)
printformat_module("fe-common/silc", server, channel->channel_name,
void
silc_command_reply(SilcClient client, SilcClientConnection conn,
- SilcCommandPayload cmd_payload, int success,
- SilcCommand command, SilcCommandStatus status, ...)
+ SilcCommandPayload cmd_payload, bool success,
+ SilcCommand command, SilcStatus status, ...)
{
SILC_SERVER_REC *server = conn->context;
char buf[1024], *nickname, *username, *realname, *nick;
unsigned char *fingerprint;
SilcUInt32 idle, mode;
- SilcBuffer channels;
+ SilcBuffer channels, user_modes;
SilcClientEntry client_entry;
if (status == SILC_STATUS_ERR_NO_SUCH_NICK) {
3, NULL);
if (tmp)
silc_say_error("%s: %s", tmp,
- silc_client_command_status_message(status));
+ silc_get_status_message(status));
break;
} else if (status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
/* Try to find the entry for the unknown client ID, since we
client_id);
if (client_entry && client_entry->nickname)
silc_say_error("%s: %s", client_entry->nickname,
- silc_client_command_status_message(status));
+ silc_get_status_message(status));
silc_free(client_id);
}
}
mode = va_arg(vp, SilcUInt32);
idle = va_arg(vp, SilcUInt32);
fingerprint = va_arg(vp, unsigned char *);
+ user_modes = va_arg(vp, SilcBuffer);
silc_parse_userfqdn(nickname, &nick, NULL);
printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
SILCTXT_WHOIS_REALNAME, realname);
silc_free(nick);
- if (channels) {
+ if (channels && user_modes) {
+ SilcUInt32 *umodes;
SilcDList list = silc_channel_payload_parse_list(channels->data,
channels->len);
- if (list) {
+ if (list && silc_get_mode_list(user_modes, silc_dlist_count(list),
+ &umodes)) {
SilcChannelPayload entry;
+ int i = 0;
+
memset(buf, 0, sizeof(buf));
silc_dlist_start(list);
while ((entry = silc_dlist_get(list)) != SILC_LIST_END) {
- char *m = silc_client_chumode_char(silc_channel_get_mode(entry));
SilcUInt32 name_len;
+ char *m = silc_client_chumode_char(umodes[i++]);
char *name = silc_channel_get_name(entry, &name_len);
if (m)
printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
SILCTXT_WHOIS_CHANNELS, buf);
silc_channel_payload_list_free(list);
+ silc_free(umodes);
}
}
if (mode) {
memset(buf, 0, sizeof(buf));
-
- if ((mode & SILC_UMODE_SERVER_OPERATOR) ||
- (mode & SILC_UMODE_ROUTER_OPERATOR)) {
- strcat(buf, (mode & SILC_UMODE_SERVER_OPERATOR) ?
- "Server Operator" :
- (mode & SILC_UMODE_ROUTER_OPERATOR) ?
- "SILC Operator" : "[Unknown mode]");
- }
- if (mode & SILC_UMODE_GONE)
- strcat(buf, " away");
- if (mode & SILC_UMODE_INDISPOSED)
- strcat(buf, " indisposed");
- if (mode & SILC_UMODE_BUSY)
- strcat(buf, " busy");
- if (mode & SILC_UMODE_PAGE)
- strcat(buf, " page to reach");
- if (mode & SILC_UMODE_HYPER)
- strcat(buf, " hyper active");
- if (mode & SILC_UMODE_ROBOT)
- strcat(buf, " robot");
- if (mode & SILC_UMODE_ANONYMOUS)
- strcat(buf, " anonymous");
- if (mode & SILC_UMODE_BLOCK_PRIVMSG)
- strcat(buf, " blocks private messages");
-
+ silc_get_umode_string(mode, buf, sizeof(buf - 1));
printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
SILCTXT_WHOIS_MODES, buf);
}
3, NULL);
if (tmp)
silc_say_error("%s: %s", tmp,
- silc_client_command_status_message(status));
+ silc_get_status_message(status));
break;
} else if (status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
/* Try to find the entry for the unknown client ID, since we
client_id);
if (client_entry && client_entry->nickname)
silc_say_error("%s: %s", client_entry->nickname,
- silc_client_command_status_message(status));
+ silc_get_status_message(status));
silc_free(client_id);
}
}
3, NULL);
if (tmp)
silc_say_error("%s: %s", tmp,
- silc_client_command_status_message(status));
+ silc_get_status_message(status));
break;
}
case SILC_COMMAND_NICK:
{
- SilcClientEntry client = va_arg(vp, SilcClientEntry);
char *old;
+ SilcClientEntry client = va_arg(vp, SilcClientEntry);
if (!success)
return;
}
break;
+ case SILC_COMMAND_WATCH:
+ break;
+
+ case SILC_COMMAND_STATS:
+ {
+ SilcUInt32 starttime, uptime, my_clients, my_channels, my_server_ops,
+ my_router_ops, cell_clients, cell_channels, cell_servers,
+ clients, channels, servers, routers, server_ops, router_ops;
+ SilcUInt32 buf_len;
+ SilcBufferStruct buf;
+ unsigned char *tmp_buf;
+ char tmp[40];
+ const char *tmptime;
+ int days, hours, mins, secs;
+
+ if (!success)
+ return;
+
+ tmp_buf = va_arg(vp, unsigned char *);
+ buf_len = va_arg(vp, SilcUInt32);
+
+ if (!tmp_buf || !buf_len) {
+ printtext(server, NULL, MSGLEVEL_CRAP, "No statistics available");
+ return;
+ }
+
+ /* Get statistics structure */
+ silc_buffer_set(&buf, tmp_buf, buf_len);
+ silc_buffer_unformat(&buf,
+ SILC_STR_UI_INT(&starttime),
+ SILC_STR_UI_INT(&uptime),
+ SILC_STR_UI_INT(&my_clients),
+ SILC_STR_UI_INT(&my_channels),
+ SILC_STR_UI_INT(&my_server_ops),
+ SILC_STR_UI_INT(&my_router_ops),
+ SILC_STR_UI_INT(&cell_clients),
+ SILC_STR_UI_INT(&cell_channels),
+ SILC_STR_UI_INT(&cell_servers),
+ SILC_STR_UI_INT(&clients),
+ SILC_STR_UI_INT(&channels),
+ SILC_STR_UI_INT(&servers),
+ SILC_STR_UI_INT(&routers),
+ SILC_STR_UI_INT(&server_ops),
+ SILC_STR_UI_INT(&router_ops),
+ SILC_STR_END);
+
+ tmptime = silc_get_time(starttime);
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_STATS,
+ "Local server start time", tmptime);
+
+ days = uptime / (24 * 60 * 60);
+ uptime -= days * (24 * 60 * 60);
+ hours = uptime / (60 * 60);
+ uptime -= hours * (60 * 60);
+ mins = uptime / 60;
+ uptime -= mins * 60;
+ secs = uptime;
+ snprintf(tmp, sizeof(tmp) - 1, "%d days %d hours %d mins %d secs",
+ days, hours, mins, secs);
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_STATS,
+ "Local server uptime", tmp);
+
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)my_clients);
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_STATS,
+ "Local server clients", tmp);
+
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)my_channels);
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_STATS,
+ "Local server channels", tmp);
+
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)my_server_ops);
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_STATS,
+ "Local server operators", tmp);
+
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)my_router_ops);
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_STATS,
+ "Local router operators", tmp);
+
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)cell_clients);
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_STATS,
+ "Local cell clients", tmp);
+
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)cell_channels);
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_STATS,
+ "Local cell channels", tmp);
+
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)cell_servers);
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_STATS,
+ "Local cell servers", tmp);
+
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)clients);
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_STATS,
+ "Total clients", tmp);
+
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)channels);
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_STATS,
+ "Total channels", tmp);
+
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)servers);
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_STATS,
+ "Total servers", tmp);
+
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)routers);
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_STATS,
+ "Total routers", tmp);
+
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)server_ops);
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_STATS,
+ "Total server operators", tmp);
+
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)router_ops);
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_STATS,
+ "Total router operators", tmp);
+ }
+ break;
+
}
va_end(vp);
void ask_passphrase_completion(const char *passphrase, void *context)
{
AskPassphrase p = (AskPassphrase)context;
+ if (passphrase && passphrase[0] == '\0')
+ passphrase = NULL;
p->completion((unsigned char *)passphrase,
passphrase ? strlen(passphrase) : 0, p->context);
silc_free(p);
silc_detach(SilcClient client, SilcClientConnection conn,
const unsigned char *detach_data, SilcUInt32 detach_data_len)
{
+ char file[256];
+ /* Save the detachment data to file. */
+
+ memset(file, 0, sizeof(file));
+ snprintf(file, sizeof(file) - 1, "%s/session", get_irssi_dir());
+ silc_file_writefile(file, detach_data, detach_data_len);
}