+/* converts an utf-8 string to current locale */
+char * silc_convert_utf8_string(const char *str)
+{
+ int message_len = (str != NULL ? strlen(str) : 0);
+ char *message = silc_calloc(message_len + 1, sizeof(*message));
+
+ g_return_val_if_fail(message != NULL, NULL);
+
+ if (str == NULL) {
+ *message = 0;
+ return message;
+ }
+
+ if (!silc_term_utf8() && silc_utf8_valid(str, message_len))
+ silc_utf8_decode(str, message_len, SILC_STRING_LOCALE,
+ message, message_len);
+ else
+ strcpy(message, str);
+
+ return message;
+}
+
+/* print "nick appears as" message to every channel of a server */
+static void
+silc_print_nick_change_channel(SILC_SERVER_REC *server, const char *channel,
+ const char *newnick, const char *oldnick,
+ const char *address)
+{
+ if (ignore_check(SERVER(server), oldnick, address,
+ channel, newnick, MSGLEVEL_NICKS))
+ return;
+
+ printformat_module("fe-common/silc", server, channel, MSGLEVEL_NICKS,
+ SILCTXT_CHANNEL_APPEARS,
+ oldnick, newnick, channel, address);
+}
+
+static void
+silc_print_nick_change(SILC_SERVER_REC *server, const char *newnick,
+ const char *oldnick, const char *address)
+{
+ GSList *tmp, *windows;
+
+ /* Print to each channel/query where the nick is.
+ Don't print more than once to the same window. */
+ windows = NULL;
+
+ for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
+ CHANNEL_REC *channel = tmp->data;
+ WINDOW_REC *window = window_item_window((WI_ITEM_REC *) channel);
+
+ if (nicklist_find(channel, newnick) == NULL ||
+ g_slist_find(windows, window) != NULL)
+ continue;
+
+ windows = g_slist_append(windows, window);
+ silc_print_nick_change_channel(server, channel->visible_name,
+ newnick, oldnick, address);
+ }
+
+ g_slist_free(windows);
+}
+
+static void silc_parse_channel_public_keys(SILC_SERVER_REC *server,
+ SilcChannelEntry channel_entry,
+ SilcBuffer channel_pubkeys)
+{
+ SilcUInt16 argc;
+ SilcArgumentPayload chpks;
+ unsigned char *pk;
+ SilcUInt32 pk_len, type;
+ int c = 1;
+ char *fingerprint, *babbleprint;
+ SilcPublicKey pubkey;
+ SilcPublicKeyIdentifier ident;
+
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_CHANNEL_PK_LIST,
+ channel_entry->channel_name);
+
+ SILC_GET16_MSB(argc, channel_pubkeys->data);
+ chpks = silc_argument_payload_parse(channel_pubkeys->data + 2,
+ channel_pubkeys->len - 2, argc);
+ if (!chpks)
+ return;
+
+ pk = silc_argument_get_first_arg(chpks, &type, &pk_len);
+ while (pk) {
+ fingerprint = silc_hash_fingerprint(NULL, pk + 4, pk_len - 4);
+ babbleprint = silc_hash_babbleprint(NULL, pk + 4, pk_len - 4);
+ silc_pkcs_public_key_payload_decode(pk, pk_len, &pubkey);
+ ident = silc_pkcs_decode_identifier(pubkey->identifier);
+
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_CHANNEL_PK_LIST_ENTRY,
+ c++, channel_entry->channel_name,
+ type == 0x00 ? "Added" : "Removed",
+ ident->realname ? ident->realname : "",
+ fingerprint, babbleprint);
+
+ silc_free(fingerprint);
+ silc_free(babbleprint);
+ silc_pkcs_public_key_free(pubkey);
+ silc_pkcs_free_identifier(ident);
+ pk = silc_argument_get_next_arg(chpks, &type, &pk_len);
+ }
+
+ silc_argument_payload_free(chpks);
+}
+