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.
23 * Revision 1.4 2000/07/12 05:59:41 priikone
24 * Major rewrite of ID Cache system. Support added for the new
25 * ID cache system. Major rewrite of ID List stuff on server. All
26 * SilcXXXList's are now called SilcXXXEntry's and they are pointers
27 * by default. A lot rewritten ID list functions.
29 * Revision 1.3 2000/07/05 06:14:01 priikone
30 * Global costemic changes.
32 * Revision 1.2 2000/07/03 05:52:22 priikone
33 * Implemented LEAVE command.
35 * Revision 1.1.1.1 2000/06/27 11:36:56 priikone
36 * Imported from internal CVS/Added Log headers.
41 #include "serverincludes.h"
42 #include "server_internal.h"
43 #include "command_reply.h"
45 /* Server command reply list. Not all commands have reply function as
46 they are never sent by server. More maybe added later if need appears. */
47 SilcServerCommandReply silc_command_reply_list[] =
49 SILC_SERVER_CMD_REPLY(join, JOIN),
50 SILC_SERVER_CMD_REPLY(identify, IDENTIFY),
55 /* Process received command reply. */
57 void silc_server_command_reply_process(SilcServer server,
58 SilcSocketConnection sock,
61 SilcServerCommandReplyContext ctx;
62 SilcCommandPayload payload;
64 /* Get command reply payload from packet */
65 payload = silc_command_parse_payload(buffer);
67 /* Silently ignore bad reply packet */
68 SILC_LOG_DEBUG(("Bad command reply packet"));
72 /* Allocate command reply context. This must be free'd by the
73 command reply routine receiving it. */
74 ctx = silc_calloc(1, sizeof(*ctx));
77 ctx->payload = payload;
79 /* Check for pending commands and mark to be exeucted */
80 SILC_SERVER_COMMAND_CHECK_PENDING(ctx);
82 /* Execute command reply */
83 SILC_SERVER_COMMAND_REPLY_EXEC(ctx);
86 /* Free command reply context and its internals. */
88 void silc_server_command_reply_free(SilcServerCommandReplyContext cmd)
91 silc_command_free_payload(cmd->payload);
96 /* Received reply for forwarded JOIN command. Router has created or joined
97 the client to the channel. We save some channel information locally
100 SILC_SERVER_CMD_REPLY_FUNC(join)
102 SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
103 SilcServer server = cmd->server;
104 SilcCommandStatus status;
106 SilcChannelEntry entry;
107 unsigned char *id_string;
108 char *channel_name, *tmp;
110 SILC_LOG_DEBUG(("Start"));
112 tmp = silc_command_get_arg_type(cmd->payload, 1, NULL);
113 SILC_GET16_MSB(status, tmp);
114 if (status != SILC_STATUS_OK)
117 /* Get channel name */
118 tmp = silc_command_get_arg_type(cmd->payload, 2, NULL);
123 id_string = silc_command_get_arg_type(cmd->payload, 3, NULL);
127 channel_name = strdup(tmp);
129 /* Add the channel to our local list. */
130 id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
131 entry = silc_idlist_add_channel(server->local_list, channel_name,
132 SILC_CHANNEL_MODE_NONE, id,
133 server->id_entry->router, NULL);
137 entry->global_users = TRUE;
139 /* Execute pending JOIN command so that the client who originally
140 wanted to join the channel will be joined after all. */
141 SILC_SERVER_COMMAND_EXEC_PENDING(cmd, SILC_COMMAND_JOIN);
144 silc_server_command_reply_free(cmd);
147 /* Received reply for forwarded IDENTIFY command. We have received the
148 requested identify information now and we will cache it. After this we
149 will call the pending command so that the requestee gets the information
152 SILC_SERVER_CMD_REPLY_FUNC(identify)
154 SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
155 SilcServer server = cmd->server;
156 SilcCommandStatus status;
159 SILC_LOG_DEBUG(("Start"));
161 tmp = silc_command_get_arg_type(cmd->payload, 1, NULL);
162 SILC_GET16_MSB(status, tmp);
163 if (status != SILC_STATUS_OK)
166 /* Process one identify reply */
167 if (status == SILC_STATUS_OK) {
168 unsigned char *id_data;
171 id_data = silc_command_get_arg_type(cmd->payload, 2, NULL);
172 nickname = silc_command_get_arg_type(cmd->payload, 3, NULL);
173 if (!id_data || !nickname)
177 /* Allocate client entry */
178 client_entry = silc_calloc(1, sizeof(*client_entry));
179 client_entry->id = silc_id_str2id(id_data, SILC_ID_CLIENT);
180 client_entry->nickname = strdup(nickname);
182 /* Save received Client ID to ID cache */
183 silc_idcache_add(win->client_cache, client_entry->nickname,
184 SILC_ID_CLIENT, client_entry->id, client_entry, TRUE);
188 if (status == SILC_STATUS_LIST_START) {
192 if (status == SILC_STATUS_LIST_END) {
196 /* Execute pending IDENTIFY command so that the client who originally
197 requested the identify information will get it after all. */
198 SILC_SERVER_COMMAND_EXEC_PENDING(cmd, SILC_COMMAND_IDENTIFY);
201 silc_server_command_reply_free(cmd);