Fixed the server to server (server to router actually) connections
[silc.git] / apps / silcd / command_reply.c
1 /*
2
3   command_reply.c
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 1997 - 2000 Pekka Riikonen
8
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.
13   
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.
18
19 */
20 /*
21  * $Id$
22  * $Log$
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.
27  *
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.
33  *
34  * Revision 1.3  2000/07/05 06:14:01  priikone
35  *      Global costemic changes.
36  *
37  * Revision 1.2  2000/07/03 05:52:22  priikone
38  *      Implemented LEAVE command.
39  *
40  * Revision 1.1.1.1  2000/06/27 11:36:56  priikone
41  *      Imported from internal CVS/Added Log headers.
42  *
43  *
44  */
45
46 #include "serverincludes.h"
47 #include "server_internal.h"
48 #include "command_reply.h"
49
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[] =
53 {
54   SILC_SERVER_CMD_REPLY(join, JOIN),
55   SILC_SERVER_CMD_REPLY(identify, IDENTIFY),
56
57   { NULL, 0 },
58 };
59
60 /* Process received command reply. */
61
62 void silc_server_command_reply_process(SilcServer server,
63                                        SilcSocketConnection sock,
64                                        SilcBuffer buffer)
65 {
66   SilcServerCommandReplyContext ctx;
67   SilcCommandPayload payload;
68
69   /* Get command reply payload from packet */
70   payload = silc_command_parse_payload(buffer);
71   if (!payload) {
72     /* Silently ignore bad reply packet */
73     SILC_LOG_DEBUG(("Bad command reply packet"));
74     return;
75   }
76   
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));
80   ctx->server = server;
81   ctx->sock = sock;
82   ctx->payload = payload;
83       
84   /* Check for pending commands and mark to be exeucted */
85   SILC_SERVER_COMMAND_CHECK_PENDING(ctx);
86   
87   /* Execute command reply */
88   SILC_SERVER_COMMAND_REPLY_EXEC(ctx);
89 }
90
91 /* Free command reply context and its internals. */
92
93 void silc_server_command_reply_free(SilcServerCommandReplyContext cmd)
94 {
95   if (cmd) {
96     silc_command_free_payload(cmd->payload);
97     silc_free(cmd);
98   }
99 }
100
101 /* Received reply for forwarded JOIN command. Router has created or joined
102    the client to the channel. We save some channel information locally
103    for future use. */
104
105 SILC_SERVER_CMD_REPLY_FUNC(join)
106 {
107   SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
108   SilcServer server = cmd->server;
109   SilcCommandStatus status;
110   SilcChannelID *id;
111   SilcChannelEntry entry;
112   unsigned char *id_string;
113   char *channel_name, *tmp;
114
115   SILC_LOG_DEBUG(("Start"));
116
117   tmp = silc_command_get_arg_type(cmd->payload, 1, NULL);
118   SILC_GET16_MSB(status, tmp);
119   if (status != SILC_STATUS_OK)
120     goto out;
121
122   /* Get channel name */
123   tmp = silc_command_get_arg_type(cmd->payload, 2, NULL);
124   if (!tmp)
125     goto out;
126
127   /* Get channel ID */
128   id_string = silc_command_get_arg_type(cmd->payload, 3, NULL);
129   if (!id_string)
130     goto out;
131
132   channel_name = strdup(tmp);
133
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);
139   if (!entry)
140     goto out;
141
142   entry->global_users = TRUE;
143
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);
147
148  out:
149   silc_server_command_reply_free(cmd);
150 }
151
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
155    after all. */
156
157 SILC_SERVER_CMD_REPLY_FUNC(identify)
158 {
159   SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
160   SilcServer server = cmd->server;
161   SilcCommandStatus status;
162   unsigned char *tmp;
163
164   SILC_LOG_DEBUG(("Start"));
165
166   tmp = silc_command_get_arg_type(cmd->payload, 1, NULL);
167   SILC_GET16_MSB(status, tmp);
168   if (status != SILC_STATUS_OK)
169     goto out;
170
171   /* Process one identify reply */
172   if (status == SILC_STATUS_OK) {
173     SilcClientID *client_id;
174     unsigned char *id_data;
175     char *nickname, *username;
176
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)
180       goto out;
181
182     username = silc_command_get_arg_type(cmd->payload, 4, NULL);
183
184     client_id = silc_id_str2id(id_data, SILC_ID_CLIENT);
185
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
188        in their cache. */
189     silc_idlist_add_client(server->global_list, strdup(nickname),
190                            username, NULL, client_id, NULL, NULL, NULL,
191                            NULL, NULL, NULL, NULL);
192   }
193
194   if (status == SILC_STATUS_LIST_START) {
195
196   }
197
198   if (status == SILC_STATUS_LIST_END) {
199
200   }
201
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);
205
206  out:
207   silc_server_command_reply_free(cmd);
208 }