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.5 2000/07/26 07:05:11 priikone
24 * Fixed the server to server (server to router actually) connections
25 * and made the private message work inside a cell. Added functin
26 * silc_server_replace_id.
28 * Revision 1.4 2000/07/12 05:59:41 priikone
29 * Major rewrite of ID Cache system. Support added for the new
30 * ID cache system. Major rewrite of ID List stuff on server. All
31 * SilcXXXList's are now called SilcXXXEntry's and they are pointers
32 * by default. A lot rewritten ID list functions.
34 * Revision 1.3 2000/07/05 06:14:01 priikone
35 * Global costemic changes.
37 * Revision 1.2 2000/07/03 05:52:22 priikone
38 * Implemented LEAVE command.
40 * Revision 1.1.1.1 2000/06/27 11:36:56 priikone
41 * Imported from internal CVS/Added Log headers.
46 #include "serverincludes.h"
47 #include "server_internal.h"
48 #include "command_reply.h"
50 /* Server command reply list. Not all commands have reply function as
51 they are never sent by server. More maybe added later if need appears. */
52 SilcServerCommandReply silc_command_reply_list[] =
54 SILC_SERVER_CMD_REPLY(join, JOIN),
55 SILC_SERVER_CMD_REPLY(identify, IDENTIFY),
60 /* Process received command reply. */
62 void silc_server_command_reply_process(SilcServer server,
63 SilcSocketConnection sock,
66 SilcServerCommandReplyContext ctx;
67 SilcCommandPayload payload;
69 /* Get command reply payload from packet */
70 payload = silc_command_parse_payload(buffer);
72 /* Silently ignore bad reply packet */
73 SILC_LOG_DEBUG(("Bad command reply packet"));
77 /* Allocate command reply context. This must be free'd by the
78 command reply routine receiving it. */
79 ctx = silc_calloc(1, sizeof(*ctx));
82 ctx->payload = payload;
84 /* Check for pending commands and mark to be exeucted */
85 SILC_SERVER_COMMAND_CHECK_PENDING(ctx);
87 /* Execute command reply */
88 SILC_SERVER_COMMAND_REPLY_EXEC(ctx);
91 /* Free command reply context and its internals. */
93 void silc_server_command_reply_free(SilcServerCommandReplyContext cmd)
96 silc_command_free_payload(cmd->payload);
101 /* Received reply for forwarded JOIN command. Router has created or joined
102 the client to the channel. We save some channel information locally
105 SILC_SERVER_CMD_REPLY_FUNC(join)
107 SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
108 SilcServer server = cmd->server;
109 SilcCommandStatus status;
111 SilcChannelEntry entry;
112 unsigned char *id_string;
113 char *channel_name, *tmp;
115 SILC_LOG_DEBUG(("Start"));
117 tmp = silc_command_get_arg_type(cmd->payload, 1, NULL);
118 SILC_GET16_MSB(status, tmp);
119 if (status != SILC_STATUS_OK)
122 /* Get channel name */
123 tmp = silc_command_get_arg_type(cmd->payload, 2, NULL);
128 id_string = silc_command_get_arg_type(cmd->payload, 3, NULL);
132 channel_name = strdup(tmp);
134 /* Add the channel to our local list. */
135 id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
136 entry = silc_idlist_add_channel(server->local_list, channel_name,
137 SILC_CHANNEL_MODE_NONE, id,
138 server->id_entry->router, NULL);
142 entry->global_users = TRUE;
144 /* Execute pending JOIN command so that the client who originally
145 wanted to join the channel will be joined after all. */
146 SILC_SERVER_COMMAND_EXEC_PENDING(cmd, SILC_COMMAND_JOIN);
149 silc_server_command_reply_free(cmd);
152 /* Received reply for forwarded IDENTIFY command. We have received the
153 requested identify information now and we will cache it. After this we
154 will call the pending command so that the requestee gets the information
157 SILC_SERVER_CMD_REPLY_FUNC(identify)
159 SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
160 SilcServer server = cmd->server;
161 SilcCommandStatus status;
164 SILC_LOG_DEBUG(("Start"));
166 tmp = silc_command_get_arg_type(cmd->payload, 1, NULL);
167 SILC_GET16_MSB(status, tmp);
168 if (status != SILC_STATUS_OK)
171 /* Process one identify reply */
172 if (status == SILC_STATUS_OK) {
173 SilcClientID *client_id;
174 unsigned char *id_data;
175 char *nickname, *username;
177 id_data = silc_command_get_arg_type(cmd->payload, 2, NULL);
178 nickname = silc_command_get_arg_type(cmd->payload, 3, NULL);
179 if (!id_data || !nickname)
182 username = silc_command_get_arg_type(cmd->payload, 4, NULL);
184 client_id = silc_id_str2id(id_data, SILC_ID_CLIENT);
186 /* Add the client always to our global list. If normal or router server
187 ever gets here it means they don't have this client's information
189 silc_idlist_add_client(server->global_list, strdup(nickname),
190 username, NULL, client_id, NULL, NULL, NULL,
191 NULL, NULL, NULL, NULL);
194 if (status == SILC_STATUS_LIST_START) {
198 if (status == SILC_STATUS_LIST_END) {
202 /* Execute pending IDENTIFY command so that the client who originally
203 requested the identify information will get it after all. */
204 SILC_SERVER_COMMAND_EXEC_PENDING(cmd, SILC_COMMAND_IDENTIFY);
207 silc_server_command_reply_free(cmd);