+ client_entry2 = silc_client_get_client_by_id(client, conn,
+ &id.u.client_id);
+ if (!client_entry2 || !client_entry2->internal.valid) {
+ /** Resolve client */
+ silc_client_unref_client(client, conn, client_entry);
+ silc_client_unref_client(client, conn, client_entry2);
+ SILC_FSM_CALL(silc_client_get_client_by_id_resolve(
+ client, conn, &id.u.client_id, NULL,
+ silc_client_notify_resolved,
+ notify));
+ /* NOT REACHED */
+ }
+ entry = client_entry2;
+ } else if (id.type == SILC_ID_SERVER) {
+ /* Find Server entry */
+ server = silc_client_get_server_by_id(client, conn, &id.u.server_id);
+ if (!server) {
+ /** Resolve server */
+ SILC_FSM_CALL(silc_client_get_server_by_id_resolve(
+ client, conn, &id.u.server_id,
+ silc_client_notify_resolved,
+ notify));
+ /* NOT REACHED */
+ }
+ entry = server;
+ } else {
+ /* Find Channel entry */
+ channel_entry = silc_client_get_channel_by_id(client, conn,
+ &id.u.channel_id);
+ if (!channel_entry) {
+ /** Resolve channel */
+ SILC_FSM_CALL(silc_client_get_channel_by_id_resolve(
+ client, conn, &id.u.channel_id,
+ silc_client_notify_resolved,
+ notify));
+ /* NOT REACHED */
+ }
+ entry = channel_entry;
+ }
+
+ /* Notify application. */
+ NOTIFY(client, conn, type, client_entry, comment, id.type, entry);
+
+ /* Delete the killed client */
+ if (client_entry != conn->local_entry) {
+ silc_client_remove_from_channels(client, conn, client_entry);
+ client_entry->internal.valid = FALSE;
+ silc_client_del_client(client, conn, client_entry);
+ }
+
+ out:
+ silc_client_unref_client(client, conn, client_entry);
+ if (client_entry2)
+ silc_client_unref_client(client, conn, client_entry2);
+ if (server)
+ silc_client_unref_server(client, conn, server);
+ if (channel_entry)
+ silc_client_unref_channel(client, conn, channel_entry);
+
+ /** Notify processed */
+ silc_fsm_next(fsm, silc_client_notify_processed);
+ return SILC_FSM_CONTINUE;
+}
+
+/**************************** SERVER SIGNOFF ********************************/
+
+/* Some server quit SILC network. Remove its clients from channels. */
+
+SILC_FSM_STATE(silc_client_notify_server_signoff)
+{
+ SilcClientConnection conn = fsm_context;
+ SilcClient client = conn->client;
+ SilcClientNotify notify = state_context;
+ SilcNotifyPayload payload = notify->payload;
+ SilcNotifyType type = silc_notify_get_type(payload);
+ SilcArgumentPayload args = silc_notify_get_args(payload);
+ SilcClientEntry client_entry;
+ SilcServerEntry server_entry = NULL;
+ SilcDList clients;
+ SilcID id;
+ int i;
+
+ SILC_LOG_DEBUG(("Notify: SERVER_SIGNOFF"));