5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2006 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
22 #include "silcserver.h"
23 #include "server_internal.h"
25 /******************************* Heartbeat **********************************/
27 /* Send the heartbeat packet. */
29 SilcBool silc_server_send_heartbeat(SilcPacketStream stream)
31 return stream ? silc_packet_send(stream, SILC_PACKET_HEARTBEAT, 0,
36 /********************************* Error ************************************/
38 /* Sends error packet. */
40 SilcBool silc_server_send_error(SilcPacketStream stream, const char *fmt, ...)
42 unsigned char buf[2048];
48 memset(buf, 0, sizeof(buf));
50 vsilc_snprintf(buf, sizeof(buf) - 1, fmt, ap);
53 return silc_packet_send(stream, SILC_PACKET_ERROR, 0, buf, strlen(buf));
57 /********************************* New ID ***********************************/
59 /* Sends New ID packet. The packet is used to distribute information about
60 new registered clients, servers and channels. If the argument `broadcast'
61 is TRUE then the packet is sent as broadcast packet. */
63 SilcBool silc_server_send_new_id(SilcPacketStream stream,
65 void *id, SilcIdType id_type)
73 SILC_LOG_DEBUG(("Sending new ID (%s)", silc_id_render(id, id_type)));
75 idp = silc_id_payload_encode(id, id_type);
79 ret = silc_packet_send(stream, SILC_PACKET_NEW_ID,
80 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
81 idp->data, silc_buffer_len(idp));
83 silc_buffer_free(idp);
88 /****************************** Command packets *****************************/
90 /* Generic function to send any command. The arguments must be sent already
91 encoded into correct form in correct order, and they must as follows:
92 { argument type, argument data, argument length }. */
94 SilcBool silc_server_send_command(SilcServer server,
95 SilcPacketStream stream,
102 SilcBool ret = FALSE;
105 server->stat.commands_sent++;
109 packet = silc_command_payload_encode_vap(command, ident, argc, ap);
115 ret = silc_packet_send(stream, SILC_PACKET_COMMAND, 0,
116 packet->data, silc_buffer_len(packet));
118 silc_buffer_free(packet);
124 /* Generic function to send a command reply. The arguments must be sent
125 already encoded into correct form in correct order, and they must be
126 { argument type, argument data, argument length }. */
128 SilcBool silc_server_send_command_reply(SilcServer server,
129 SilcPacketStream stream,
134 SilcUInt32 argc, ...)
138 SilcBool ret = FALSE;
141 server->stat.commands_sent++;
145 packet = silc_command_reply_payload_encode_vap(command, status, error,
152 ret = silc_packet_send(stream, SILC_PACKET_COMMAND_REPLY, 0,
153 packet->data, silc_buffer_len(packet));
155 silc_buffer_free(packet);
162 /****************************** Notify packets ******************************/
164 /* Sends notify packet. Each variable argument format in the argument list
165 must be { argument data, argument length }. */
167 SilcBool silc_server_send_notify(SilcServer server,
168 SilcPacketStream stream,
171 SilcUInt32 argc, ...)
175 SilcBool ret = FALSE;
182 packet = silc_notify_payload_encode(type, argc, ap);
188 ret = silc_packet_send(stream, SILC_PACKET_NOTIFY,
189 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
190 packet->data, silc_buffer_len(packet));
193 /* Send to backup routers if this is being broadcasted to primary
194 router. The silc_server_backup_send checks further whether to
195 actually send it or not. */
196 if ((broadcast && stream == SILC_PRIMARY_ROUTE(server)) ||
197 (broadcast && !SILC_PRIMARY_ROUTE(server)))
198 silc_server_backup_send(server, NULL, SILC_PACKET_NOTIFY, 0,
199 packet->data, packet->len, FALSE, TRUE);
202 silc_buffer_free(packet);
208 /* Sends current motd to client in notify packet */
210 SilcBool silc_server_send_motd(SilcServer server, SilcPacketStream stream)
212 char *motd, *motd_file = NULL;
214 SilcBool ret = FALSE;
216 if (!stream || !server->params)
219 motd_file = server->params->server_info->motd_file;
223 motd = silc_file_readfile(motd_file, &motd_len);
228 ret = silc_server_send_notify(server, stream, FALSE,
229 SILC_NOTIFY_TYPE_MOTD, 1, motd, motd_len);
236 /* Sends notify packet and gets the arguments from the `args' Argument
239 SilcBool silc_server_send_notify_args(SilcPacketStream stream,
246 SilcBool ret = FALSE;
251 packet = silc_notify_payload_encode_args(type, argc, args);
255 ret = silc_packet_send(stream, SILC_PACKET_NOTIFY,
256 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
257 packet->data, silc_buffer_len(packet));
259 silc_buffer_free(packet);
263 /* Send CHANNEL_CHANGE notify type. This tells the receiver to replace the
264 `old_id' with the `new_id'. */
266 SilcBool silc_server_send_notify_channel_change(SilcServer server,
267 SilcPacketStream stream,
269 SilcChannelID *old_id,
270 SilcChannelID *new_id)
272 SilcBuffer idp1, idp2;
273 SilcBool ret = FALSE;
275 if (!server || !stream)
278 idp1 = silc_id_payload_encode((void *)old_id, SILC_ID_CHANNEL);
279 idp2 = silc_id_payload_encode((void *)new_id, SILC_ID_CHANNEL);
283 ret = silc_server_send_notify(server, stream, broadcast,
284 SILC_NOTIFY_TYPE_CHANNEL_CHANGE,
285 2, idp1->data, silc_buffer_len(idp1),
286 idp2->data, silc_buffer_len(idp2));
287 silc_buffer_free(idp1);
288 silc_buffer_free(idp2);