+ SilcClientInternal app = (SilcClientInternal)client->application;
+ va_list vp;
+ char message[4096];
+ SilcClientEntry client_entry, client_entry2;
+ SilcChannelEntry channel_entry;
+ char *tmp = NULL;
+ SilcUInt32 tmp_int;
+
+ va_start(vp, type);
+
+ memset(message, 0, sizeof(message));
+
+ /* Get arguments (defined by protocol in silc-pp-01 -draft) */
+ switch(type) {
+ case SILC_NOTIFY_TYPE_NONE:
+ tmp = va_arg(vp, char *);
+ if (!tmp)
+ return;
+ strcpy(message, tmp);
+ break;
+
+ case SILC_NOTIFY_TYPE_INVITE:
+ (void)va_arg(vp, SilcChannelEntry);
+ tmp = va_arg(vp, char *);
+ client_entry = va_arg(vp, SilcClientEntry);
+ snprintf(message, sizeof(message), "%s invites you to channel %s",
+ client_entry->nickname, tmp);
+ break;
+
+ case SILC_NOTIFY_TYPE_JOIN:
+ client_entry = va_arg(vp, SilcClientEntry);
+ channel_entry = va_arg(vp, SilcChannelEntry);
+ snprintf(message, sizeof(message), "%s (%s) has joined channel %s",
+ client_entry->nickname, client_entry->username,
+ channel_entry->channel_name);
+ if (client_entry == conn->local_entry) {
+ SilcChannelUser chu;
+
+ silc_list_start(channel_entry->clients);
+ while ((chu = silc_list_get(channel_entry->clients)) != SILC_LIST_END) {
+ if (chu->client == client_entry) {
+ if (app->screen->bottom_line->mode)
+ silc_free(app->screen->bottom_line->mode);
+ app->screen->bottom_line->mode = silc_client_chumode_char(chu->mode);
+ silc_screen_print_bottom_line(app->screen, 0);
+ break;
+ }
+ }
+ }
+ break;
+
+ case SILC_NOTIFY_TYPE_LEAVE:
+ client_entry = va_arg(vp, SilcClientEntry);
+ channel_entry = va_arg(vp, SilcChannelEntry);
+ if (client_entry->server)
+ snprintf(message, sizeof(message), "%s@%s has left channel %s",
+ client_entry->nickname, client_entry->server,
+ channel_entry->channel_name);
+ else
+ snprintf(message, sizeof(message), "%s has left channel %s",
+ client_entry->nickname, channel_entry->channel_name);
+ break;
+
+ case SILC_NOTIFY_TYPE_SIGNOFF:
+ client_entry = va_arg(vp, SilcClientEntry);
+ tmp = va_arg(vp, char *);
+ if (client_entry->server)
+ snprintf(message, sizeof(message), "Signoff: %s@%s %s%s%s",
+ client_entry->nickname, client_entry->server,
+ tmp ? "(" : "", tmp ? tmp : "", tmp ? ")" : "");
+ else
+ snprintf(message, sizeof(message), "Signoff: %s %s%s%s",
+ client_entry->nickname,
+ tmp ? "(" : "", tmp ? tmp : "", tmp ? ")" : "");
+ break;
+
+ case SILC_NOTIFY_TYPE_TOPIC_SET:
+ client_entry = va_arg(vp, SilcClientEntry);
+ tmp = va_arg(vp, char *);
+ channel_entry = va_arg(vp, SilcChannelEntry);
+ if (client_entry->server)
+ snprintf(message, sizeof(message), "%s@%s set topic on %s: %s",
+ client_entry->nickname, client_entry->server,
+ channel_entry->channel_name, tmp);
+ else
+ snprintf(message, sizeof(message), "%s set topic on %s: %s",
+ client_entry->nickname, channel_entry->channel_name, tmp);
+ break;
+
+ case SILC_NOTIFY_TYPE_NICK_CHANGE:
+ client_entry = va_arg(vp, SilcClientEntry);
+ client_entry2 = va_arg(vp, SilcClientEntry);
+ if (client_entry->server && client_entry2->server)
+ snprintf(message, sizeof(message), "%s@%s is known as %s@%s",
+ client_entry->nickname, client_entry->server,
+ client_entry2->nickname, client_entry2->server);
+ else
+ snprintf(message, sizeof(message), "%s is known as %s",
+ client_entry->nickname, client_entry2->nickname);
+ break;
+
+ case SILC_NOTIFY_TYPE_CMODE_CHANGE:
+ client_entry = va_arg(vp, SilcClientEntry);
+ tmp_int = va_arg(vp, SilcUInt32);
+ (void)va_arg(vp, char *);
+ (void)va_arg(vp, char *);
+ channel_entry = va_arg(vp, SilcChannelEntry);
+
+ tmp = silc_client_chmode(tmp_int,
+ channel_entry->channel_key->cipher->name,
+ channel_entry->hmac->hmac->name);
+
+ if (tmp) {
+ if (client_entry) {
+ snprintf(message, sizeof(message), "%s changed channel mode to +%s",
+ client_entry->nickname, tmp);
+ } else {
+ snprintf(message, sizeof(message),
+ "channel mode was changed to +%s (forced by router)",
+ tmp);
+ }
+ } else {
+ if (client_entry) {
+ snprintf(message, sizeof(message), "%s removed all channel modes",
+ client_entry->nickname);
+ } else {
+ snprintf(message, sizeof(message),
+ "Removed all channel modes (forced by router)");
+ }
+ }
+
+ if (app->screen->bottom_line->channel_mode)
+ silc_free(app->screen->bottom_line->channel_mode);
+ app->screen->bottom_line->channel_mode = tmp;
+ silc_screen_print_bottom_line(app->screen, 0);
+ break;
+
+ case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
+ client_entry = va_arg(vp, SilcClientEntry);
+ tmp_int = va_arg(vp, SilcUInt32);
+ tmp = silc_client_chumode(tmp_int);
+ client_entry2 = va_arg(vp, SilcClientEntry);
+ channel_entry = va_arg(vp, SilcChannelEntry);
+ if (tmp)
+ snprintf(message, sizeof(message), "%s changed %s's mode to +%s",
+ client_entry->nickname, client_entry2->nickname, tmp);
+ else
+ snprintf(message, sizeof(message), "%s removed %s's modes",
+ client_entry->nickname, client_entry2->nickname);
+ if (client_entry2 == conn->local_entry) {
+ if (app->screen->bottom_line->mode)
+ silc_free(app->screen->bottom_line->mode);
+ app->screen->bottom_line->mode = silc_client_chumode_char(tmp_int);
+ silc_screen_print_bottom_line(app->screen, 0);
+ }
+ silc_free(tmp);
+ break;
+
+ case SILC_NOTIFY_TYPE_MOTD:
+ {
+ char line[256];
+ int i;
+ tmp = va_arg(vp, unsigned char *);
+
+ i = 0;
+ while(tmp[i] != 0) {
+ if (tmp[i++] == '\n') {
+ memset(line, 0, sizeof(line));
+ strncat(line, tmp, i - 1);
+ tmp += i;
+
+ silc_say(client, conn, "%s", line);
+
+ if (!strlen(tmp))
+ break;
+ i = 0;
+ }
+ }
+ }
+ return;
+
+ case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
+ return;
+ break;
+
+ case SILC_NOTIFY_TYPE_KICKED:
+ client_entry = va_arg(vp, SilcClientEntry);
+ tmp = va_arg(vp, char *);
+ channel_entry = va_arg(vp, SilcChannelEntry);
+
+ if (client_entry == conn->local_entry) {
+ snprintf(message, sizeof(message),
+ "You have been kicked off channel %s %s%s%s",
+ conn->current_channel->channel_name,
+ tmp ? "(" : "", tmp ? tmp : "", tmp ? ")" : "");
+ } else {
+ snprintf(message, sizeof(message),
+ "%s%s%s has been kicked off channel %s %s%s%s",
+ client_entry->nickname,
+ client_entry->server ? "@" : "",
+ client_entry->server ? client_entry->server : "",
+ conn->current_channel->channel_name,
+ tmp ? "(" : "", tmp ? tmp : "", tmp ? ")" : "");
+ }
+ break;
+
+ case SILC_NOTIFY_TYPE_KILLED:
+ client_entry = va_arg(vp, SilcClientEntry);
+ tmp = va_arg(vp, char *);
+ channel_entry = va_arg(vp, SilcChannelEntry);
+
+ if (client_entry == conn->local_entry) {
+ snprintf(message, sizeof(message),
+ "You have been killed from the SILC Network %s%s%s",
+ tmp ? "(" : "", tmp ? tmp : "", tmp ? ")" : "");
+ } else {
+ snprintf(message, sizeof(message),
+ "%s%s%s has been killed from the SILC Network %s%s%s",
+ client_entry->nickname,
+ client_entry->server ? "@" : "",
+ client_entry->server ? client_entry->server : "",
+ tmp ? "(" : "", tmp ? tmp : "", tmp ? ")" : "");
+ }
+ break;
+
+ case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
+ {
+ SilcClientEntry *clients;
+ SilcUInt32 clients_count;
+ int i;
+
+ (void)va_arg(vp, void *);
+ clients = va_arg(vp, SilcClientEntry *);
+ clients_count = va_arg(vp, SilcUInt32);
+
+ for (i = 0; i < clients_count; i++) {
+ if (clients[i]->server)
+ snprintf(message, sizeof(message), "Server signoff: %s@%s %s%s%s",
+ clients[i]->nickname, clients[i]->server,
+ tmp ? "(" : "", tmp ? tmp : "", tmp ? ")" : "");
+ else
+ snprintf(message, sizeof(message), "Server signoff: %s %s%s%s",
+ clients[i]->nickname,
+ tmp ? "(" : "", tmp ? tmp : "", tmp ? ")" : "");
+ silc_print(client, "*** %s", message);
+ memset(message, 0, sizeof(message));
+ }
+ return;
+ }
+
+ default:
+ break;
+ }
+
+ silc_print(client, "*** %s", message);