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;
89 unsigned char *id_string;
90 char *channel_name, *tmp;
92 SILC_LOG_DEBUG(("Start"));
94 tmp = silc_argument_get_arg_type(cmd->args, 1, NULL);
95 SILC_GET16_MSB(status, tmp);
96 if (status != SILC_STATUS_OK)
99 /* Get channel name */
100 tmp = silc_argument_get_arg_type(cmd->args, 2, NULL);
105 id_string = silc_argument_get_arg_type(cmd->args, 3, NULL);
109 channel_name = strdup(tmp);
111 /* Add the channel to our local list. */
112 id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
113 entry = silc_idlist_add_channel(server->local_list, channel_name,
114 SILC_CHANNEL_MODE_NONE, id,
115 server->id_entry->router, NULL);
119 entry->global_users = TRUE;
121 /* Execute pending JOIN command so that the client who originally
122 wanted to join the channel will be joined after all. */
123 SILC_SERVER_COMMAND_EXEC_PENDING(cmd, SILC_COMMAND_JOIN);
126 silc_server_command_reply_free(cmd);
129 /* Received reply for forwarded IDENTIFY command. We have received the
130 requested identify information now and we will cache it. After this we
131 will call the pending command so that the requestee gets the information
134 SILC_SERVER_CMD_REPLY_FUNC(identify)
136 SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
137 SilcServer server = cmd->server;
138 SilcCommandStatus status;
141 SILC_LOG_DEBUG(("Start"));
143 tmp = silc_argument_get_arg_type(cmd->args, 1, NULL);
144 SILC_GET16_MSB(status, tmp);
145 if (status != SILC_STATUS_OK)
148 /* Process one identify reply */
149 if (status == SILC_STATUS_OK) {
150 SilcClientID *client_id;
151 unsigned char *id_data;
152 char *nickname, *username;
154 id_data = silc_argument_get_arg_type(cmd->args, 2, NULL);
155 nickname = silc_argument_get_arg_type(cmd->args, 3, NULL);
156 if (!id_data || !nickname)
159 username = silc_argument_get_arg_type(cmd->args, 4, NULL);
161 client_id = silc_id_str2id(id_data, SILC_ID_CLIENT);
163 /* Add the client always to our global list. If normal or router server
164 ever gets here it means they don't have this client's information
166 silc_idlist_add_client(server->global_list, strdup(nickname),
167 username, NULL, client_id, NULL, NULL, NULL,
168 NULL, NULL, NULL, NULL);
171 if (status == SILC_STATUS_LIST_START) {
175 if (status == SILC_STATUS_LIST_END) {
179 /* Execute pending IDENTIFY command so that the client who originally
180 requested the identify information will get it after all. */
181 SILC_SERVER_COMMAND_EXEC_PENDING(cmd, SILC_COMMAND_IDENTIFY);
184 silc_server_command_reply_free(cmd);