5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2000 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; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
22 #include "serverincludes.h"
23 #include "server_internal.h"
24 #include "command_reply.h"
26 /* Server command reply list. Not all commands have reply function as
27 they are never sent by server. More maybe added later if need appears. */
28 SilcServerCommandReply silc_command_reply_list[] =
30 SILC_SERVER_CMD_REPLY(join, JOIN),
31 SILC_SERVER_CMD_REPLY(identify, IDENTIFY),
36 /* Process received command reply. */
38 void silc_server_command_reply_process(SilcServer server,
39 SilcSocketConnection sock,
42 SilcServerCommandReplyContext ctx;
43 SilcCommandPayload payload;
45 /* Get command reply payload from packet */
46 payload = silc_command_payload_parse(buffer);
48 /* Silently ignore bad reply packet */
49 SILC_LOG_DEBUG(("Bad command reply packet"));
53 /* Allocate command reply context. This must be free'd by the
54 command reply routine receiving it. */
55 ctx = silc_calloc(1, sizeof(*ctx));
58 ctx->payload = payload;
59 ctx->args = silc_command_get_args(ctx->payload);
61 /* Check for pending commands and mark to be exeucted */
62 SILC_SERVER_COMMAND_CHECK_PENDING(ctx);
64 /* Execute command reply */
65 SILC_SERVER_COMMAND_REPLY_EXEC(ctx);
68 /* Free command reply context and its internals. */
70 void silc_server_command_reply_free(SilcServerCommandReplyContext cmd)
73 silc_command_free_payload(cmd->payload);
78 /* Received reply for forwarded JOIN command. Router has created or joined
79 the client to the channel. We save some channel information locally
82 SILC_SERVER_CMD_REPLY_FUNC(join)
84 SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
85 SilcServer server = cmd->server;
86 SilcCommandStatus status;
88 SilcChannelEntry entry;
90 unsigned char *id_string;
91 char *channel_name, *tmp;
93 SILC_LOG_DEBUG(("Start"));
95 tmp = silc_argument_get_arg_type(cmd->args, 1, NULL);
96 SILC_GET16_MSB(status, tmp);
97 if (status != SILC_STATUS_OK)
100 /* Get channel name */
101 tmp = silc_argument_get_arg_type(cmd->args, 2, NULL);
106 id_string = silc_argument_get_arg_type(cmd->args, 3, &len);
110 channel_name = strdup(tmp);
112 /* Add the channel to our local list. */
113 id = silc_id_payload_parse_id(id_string, len);
114 entry = silc_idlist_add_channel(server->local_list, channel_name,
115 SILC_CHANNEL_MODE_NONE, id,
116 server->id_entry->router, NULL);
118 silc_free(channel_name);
123 entry->global_users = TRUE;
125 /* Execute pending JOIN command so that the client who originally
126 wanted to join the channel will be joined after all. */
127 SILC_SERVER_COMMAND_EXEC_PENDING(cmd, SILC_COMMAND_JOIN);
130 silc_server_command_reply_free(cmd);
133 /* Received reply for forwarded IDENTIFY command. We have received the
134 requested identify information now and we will cache it. After this we
135 will call the pending command so that the requestee gets the information
138 SILC_SERVER_CMD_REPLY_FUNC(identify)
140 SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
141 SilcServer server = cmd->server;
142 SilcCommandStatus status;
144 SILC_LOG_DEBUG(("Start"));
146 SILC_GET16_MSB(status, silc_argument_get_arg_type(cmd->args, 1, NULL));
147 if (status != SILC_STATUS_OK)
150 /* Process one identify reply */
151 if (status == SILC_STATUS_OK) {
152 SilcClientID *client_id;
154 unsigned char *id_data;
155 char *nickname, *username;
157 id_data = silc_argument_get_arg_type(cmd->args, 2, &len);
158 nickname = silc_argument_get_arg_type(cmd->args, 3, NULL);
159 if (!id_data || !nickname)
162 username = silc_argument_get_arg_type(cmd->args, 4, NULL);
163 client_id = silc_id_payload_parse_id(id_data, len);
165 /* Add the client always to our global list. If normal or router server
166 ever gets here it means they don't have this client's information
168 silc_idlist_add_client(server->global_list, strdup(nickname),
169 username, NULL, client_id, NULL, NULL, NULL,
170 NULL, NULL, NULL, NULL);
173 if (status == SILC_STATUS_LIST_START) {
177 if (status == SILC_STATUS_LIST_END) {
181 /* Execute pending IDENTIFY command so that the client who originally
182 requested the identify information will get it after all. */
183 SILC_SERVER_COMMAND_EXEC_PENDING(cmd, SILC_COMMAND_IDENTIFY);
186 silc_server_command_reply_free(cmd);