SilcBool silc_server_send_notify(SilcServer server, SilcPacketStream stream, SilcBool broadcast, SilcNotifyType type, SilcUInt32 argc, ...) { va_list ap; SilcBuffer packet; SilcBool ret = FALSE; if (!stream) return FALSE; va_start(ap, argc); packet = silc_notify_payload_encode(type, argc, ap); if (!packet) { va_end(ap); return ret; } ret = silc_packet_send(stream, SILC_PACKET_NOTIFY, broadcast ? SILC_PACKET_FLAG_BROADCAST : 0, packet->data, silc_buffer_len(packet)); #if 0 /* Send to backup routers if this is being broadcasted to primary router. The silc_server_backup_send checks further whether to actually send it or not. */ if ((broadcast && stream == SILC_PRIMARY_ROUTE(server)) || (broadcast && !SILC_PRIMARY_ROUTE(server))) silc_server_backup_send(server, NULL, SILC_PACKET_NOTIFY, 0, packet->data, packet->len, FALSE, TRUE); #endif /* 0 */ silc_buffer_free(packet); va_end(ap); return ret; }
static char silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd) { SilcServer server = cmd->server; SilcUInt32 len, id_len; unsigned char *id_data; char *name, *info; SilcClientID client_id; SilcServerID server_id; SilcChannelID channel_id; SilcClientEntry client; SilcServerEntry server_entry; SilcChannelEntry channel; char global = FALSE; char nick[128 + 1]; SilcIDPayload idp = NULL; SilcIdType id_type; id_data = silc_argument_get_arg_type(cmd->args, 2, &id_len); if (!id_data) return FALSE; idp = silc_id_payload_parse(id_data, id_len); if (!idp) return FALSE; name = silc_argument_get_arg_type(cmd->args, 3, &len); info = silc_argument_get_arg_type(cmd->args, 4, &len); id_type = silc_id_payload_get_type(idp); switch (id_type) { case SILC_ID_CLIENT: if (!silc_id_payload_get_id(idp, &client_id, sizeof(client_id))) goto error; SILC_LOG_DEBUG(("Received client information")); client = silc_idlist_find_client_by_id(server->local_list, &client_id, FALSE, NULL); if (!client) { client = silc_idlist_find_client_by_id(server->global_list, &client_id, FALSE, NULL); global = TRUE; } if (!client) { /* If router did not find such Client ID in its lists then this must be bogus client or some router in the net is buggy. */ if (server->server_type != SILC_SERVER) goto error; /* Take nickname */ if (name) silc_parse_userfqdn(name, nick, sizeof(nick), NULL, 0); /* We don't have that client anywhere, add it. The client is added to global list since server didn't have it in the lists so it must be global. */ client = silc_idlist_add_client(server->global_list, nick[0] ? strdup(nick) : NULL, info ? strdup(info) : NULL, NULL, silc_id_dup(&client_id, SILC_ID_CLIENT), silc_packet_get_context(cmd->sock), NULL); if (!client) { SILC_LOG_ERROR(("Could not add new client to the ID Cache")); goto error; } client->data.status |= SILC_IDLIST_STATUS_REGISTERED; client->data.status |= SILC_IDLIST_STATUS_RESOLVED; client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING; SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients, server->stat.clients + 1)); server->stat.clients++; } else { /* We have the client already, update the data */ SILC_LOG_DEBUG(("Updating client data")); /* Take nickname */ if (name) { silc_parse_userfqdn(name, nick, sizeof(nick), NULL, 0); /* Check nickname */ name = silc_identifier_check(nick, strlen(nick), SILC_STRING_UTF8, 128, NULL); if (!name) { SILC_LOG_ERROR(("Malformed nickname '%s' received in IDENTIFY " "reply ", nick)); return FALSE; } silc_free(client->nickname); client->nickname = strdup(nick); /* Update the context */ silc_idcache_update_by_context(global ? server->global_list->clients : server->local_list->clients, client, NULL, name, TRUE); } if (info) { silc_free(client->username); client->username = strdup(info); } client->data.status |= SILC_IDLIST_STATUS_RESOLVED; client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING; } break; case SILC_ID_SERVER: if (!name) goto error; if (!silc_id_payload_get_id(idp, &server_id, sizeof(server_id))) goto error; SILC_LOG_DEBUG(("Received server information")); server_entry = silc_idlist_find_server_by_id(server->local_list, &server_id, FALSE, NULL); if (!server_entry) server_entry = silc_idlist_find_server_by_id(server->global_list, &server_id, FALSE, NULL); if (!server_entry) { /* If router did not find such Server ID in its lists then this must be bogus server or some router in the net is buggy. */ if (server->server_type != SILC_SERVER) goto error; /* We don't have that server anywhere, add it. */ server_entry = silc_idlist_add_server(server->global_list, strdup(name), 0, silc_id_dup(&server_id, SILC_ID_SERVER), server->router, SILC_PRIMARY_ROUTE(server)); if (!server_entry) goto error; server_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED; server_entry->data.status |= SILC_IDLIST_STATUS_RESOLVED; server_entry->data.status &= ~SILC_IDLIST_STATUS_RESOLVING; } break; case SILC_ID_CHANNEL: if (!name) goto error; if (!silc_id_payload_get_id(idp, &channel_id, sizeof(channel_id))) goto error; SILC_LOG_DEBUG(("Received channel information")); /* Check channel name */ info = silc_channel_name_check(name, strlen(name), SILC_STRING_UTF8, 256, NULL); if (!info) goto error; channel = silc_idlist_find_channel_by_name(server->local_list, info, NULL); if (!channel) channel = silc_idlist_find_channel_by_name(server->global_list, info, NULL); if (!channel) { /* If router did not find such Channel ID in its lists then this must be bogus channel or some router in the net is buggy. */ if (server->server_type != SILC_SERVER) { silc_free(info); goto error; } /* We don't have that channel anywhere, add it. */ channel = silc_idlist_add_channel(server->global_list, strdup(name), SILC_CHANNEL_MODE_NONE, silc_id_dup(&channel_id, SILC_ID_CHANNEL), server->router, NULL, NULL, 0); if (!channel) { silc_free(info); goto error; } silc_free(info); } break; } silc_id_payload_free(idp); return TRUE; error: silc_id_payload_free(idp); return FALSE; }