if (flags & SILC_MESSAGE_FLAG_DATA) {
/* MIME object received, try to display it as well as we can */
- char type[128];
+ 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,
- NULL, 0, &data, NULL))
+ enc, sizeof(enc) - 1, &data, &data_len))
return;
/* Then figure out what we can display */
!strstr(type, "text/vnd")) {
/* It is something textual, display it */
message = (const unsigned char *)data;
- } else {
- printformat_module("fe-common/silc", server, channel->channel_name,
- MSGLEVEL_CRAP, SILCTXT_MESSAGE_DATA,
- nick == NULL ? "[<unknown>]" : nick->nick, type);
- message = NULL;
}
}
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 (flags & SILC_MESSAGE_FLAG_DATA) {
/* MIME object received, try to display it as well as we can */
- char type[128];
+ 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,
- NULL, 0, &data, NULL))
+ enc, sizeof(enc) - 1, &data, &data_len))
return;
/* Then figure out what we can display */
!strstr(type, "text/vnd")) {
/* It is something textual, display it */
message = (const unsigned char *)data;
- } else {
- printformat_module("fe-common/silc", server, NULL,
- MSGLEVEL_CRAP, SILCTXT_MESSAGE_DATA,
- sender->nickname ? sender->nickname : "[<unknown>]",
- type);
- 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);
tmp = silc_client_chmode(mode,
channel->channel_key ?
- channel->channel_key->cipher->name : "",
+ silc_cipher_get_name(channel->channel_key) : "",
channel->hmac ?
silc_hmac_get_name(channel->hmac) : "");
{
SILC_SERVER_REC *server = conn->context;
- if (!server) {
+ if (!server || server->disconnected) {
silc_client_close_connection(client, conn);
return;
}
/* 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;
}
switch (command) {
+
case SILC_COMMAND_INVITE:
printformat_module("fe-common/silc", server, NULL,
MSGLEVEL_CRAP, SILCTXT_CHANNEL_INVITING,
(char *)conn->current_channel->channel_name :
(char *)cmd_context->argv[1]));
break;
+
+ case SILC_COMMAND_DETACH:
+ server->no_reconnect = TRUE;
+ break;
+
default:
break;
}
MSGLEVEL_CRAP, SILCTXT_CHANNEL_TOPIC,
channel->channel_name, chanrec->topic);
- fe_channels_nicklist(CHANNEL(chanrec), CHANNEL_NICKLIST_FLAG_ALL);
-
if (founder) {
if (founder == conn->local_entry)
printformat_module("fe-common/silc",
if (success) {
printformat_module("fe-common/silc", NULL, NULL,
- MSGLEVEL_CRAP, SILCTXT_GETKEY_VERIFIED, entity, name);
+ MSGLEVEL_CRAP, SILCTXT_PUBKEY_VERIFIED, entity, name);
} else {
printformat_module("fe-common/silc", NULL, NULL,
- MSGLEVEL_CRAP, SILCTXT_GETKEY_DISCARD, entity, name);
+ MSGLEVEL_CRAP, SILCTXT_PUBKEY_NOTVERIFIED,
+ entity, name);
}
silc_free(getkey->fingerprint);
SilcUInt32 idle, mode;
SilcBuffer channels, user_modes;
SilcClientEntry client_entry;
+ SilcDList attrs;
if (status == SILC_STATUS_ERR_NO_SUCH_NICK) {
/* Print the unknown nick for user */
}
}
break;
- }
-
- if (!success)
+ } else if (!success) {
+ silc_say_error("WHOIS: %s", silc_get_status_message(status));
return;
-
+ }
+
client_entry = va_arg(vp, SilcClientEntry);
nickname = va_arg(vp, char *);
username = va_arg(vp, char *);
idle = va_arg(vp, SilcUInt32);
fingerprint = va_arg(vp, unsigned char *);
user_modes = va_arg(vp, SilcBuffer);
+ attrs = va_arg(vp, SilcDList);
silc_parse_userfqdn(nickname, &nick, NULL);
printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
SILCTXT_WHOIS_FINGERPRINT, fingerprint);
silc_free(fingerprint);
}
+
+ if (attrs)
+ silc_query_attributes_print(server, silc_client, conn, attrs,
+ client_entry);
}
break;
silc_say_error("%s: %s", tmp,
silc_get_status_message(status));
break;
- }
-
- if (!success)
+ } else if (!success) {
+ silc_say_error("WHOWAS: %s", silc_get_status_message(status));
return;
+ }
(void)va_arg(vp, SilcClientEntry);
nickname = va_arg(vp, char *);
chanrec = silc_channel_find(server, channel);
if (!chanrec)
- chanrec = silc_channel_create(server, channel, TRUE);
+ chanrec = silc_channel_create(server, channel, channel, TRUE);
if (topic) {
g_free_not_null(chanrec->topic);
mode = silc_client_chmode(modei,
channel_entry->channel_key ?
- channel_entry->channel_key->cipher->name : "",
+ silc_cipher_get_name(channel_entry->
+ channel_key) : "",
channel_entry->hmac ?
silc_hmac_get_name(channel_entry->hmac) : "");
g_free_not_null(chanrec->mode);
silc_free(pk);
} else {
printformat_module("fe-common/silc", server, NULL,
- MSGLEVEL_CRAP, SILCTXT_GETKEY_NOKEY);
+ MSGLEVEL_CRAP, SILCTXT_PUBKEY_NOKEY);
}
}
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);
(*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context);
break;
case SILC_AUTH_PASSWORD:
- /* Do not ask the passphrase from user, the library will ask it if
- we do not provide it here. */
- (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context);
+ {
+ /* Check whether we find the password for this server in our
+ configuration. If not, then don't provide so library will ask
+ it from the user. */
+ SERVER_SETUP_REC *setup = server_setup_find_port(conn->remote_host,
+ conn->remote_port);
+ if (!setup || !setup->password) {
+ (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context);
+ break;
+ }
+
+ (*internal->completion)(TRUE, auth_meth, setup->password,
+ strlen(setup->password), internal->context);
+ }
break;
case SILC_AUTH_PUBLIC_KEY:
/* Do not get the authentication data now, the library will generate
SILC_LOG_DEBUG(("Start"));
- /* XXX must resolve from configuration whether this connection has
- any specific authentication data */
-
/* If we do not have this connection configured by the user in a
configuration file then resolve the authentication method from the
server for this session. */
desired (application may start it later by calling the function
silc_client_perform_key_agreement). */
-int silc_key_agreement(SilcClient client, SilcClientConnection conn,
- SilcClientEntry client_entry, const char *hostname,
- SilcUInt16 port, SilcKeyAgreementCallback *completion,
- void **context)
+bool silc_key_agreement(SilcClient client, SilcClientConnection conn,
+ SilcClientEntry client_entry, const char *hostname,
+ SilcUInt16 port, SilcKeyAgreementCallback *completion,
+ void **context)
{
char portstr[12];