Major rewrite of ID Cache system. Support added for the new
[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.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.
28  *
29  * Revision 1.3  2000/07/05 06:14:01  priikone
30  *      Global costemic changes.
31  *
32  * Revision 1.2  2000/07/03 05:52:22  priikone
33  *      Implemented LEAVE command.
34  *
35  * Revision 1.1.1.1  2000/06/27 11:36:56  priikone
36  *      Imported from internal CVS/Added Log headers.
37  *
38  *
39  */
40
41 #include "serverincludes.h"
42 #include "server_internal.h"
43 #include "command_reply.h"
44
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[] =
48 {
49   SILC_SERVER_CMD_REPLY(join, JOIN),
50   SILC_SERVER_CMD_REPLY(identify, IDENTIFY),
51
52   { NULL, 0 },
53 };
54
55 /* Process received command reply. */
56
57 void silc_server_command_reply_process(SilcServer server,
58                                        SilcSocketConnection sock,
59                                        SilcBuffer buffer)
60 {
61   SilcServerCommandReplyContext ctx;
62   SilcCommandPayload payload;
63
64   /* Get command reply payload from packet */
65   payload = silc_command_parse_payload(buffer);
66   if (!payload) {
67     /* Silently ignore bad reply packet */
68     SILC_LOG_DEBUG(("Bad command reply packet"));
69     return;
70   }
71   
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));
75   ctx->server = server;
76   ctx->sock = sock;
77   ctx->payload = payload;
78       
79   /* Check for pending commands and mark to be exeucted */
80   SILC_SERVER_COMMAND_CHECK_PENDING(ctx);
81   
82   /* Execute command reply */
83   SILC_SERVER_COMMAND_REPLY_EXEC(ctx);
84 }
85
86 /* Free command reply context and its internals. */
87
88 void silc_server_command_reply_free(SilcServerCommandReplyContext cmd)
89 {
90   if (cmd) {
91     silc_command_free_payload(cmd->payload);
92     silc_free(cmd);
93   }
94 }
95
96 /* Received reply for forwarded JOIN command. Router has created or joined
97    the client to the channel. We save some channel information locally
98    for future use. */
99
100 SILC_SERVER_CMD_REPLY_FUNC(join)
101 {
102   SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
103   SilcServer server = cmd->server;
104   SilcCommandStatus status;
105   SilcChannelID *id;
106   SilcChannelEntry entry;
107   unsigned char *id_string;
108   char *channel_name, *tmp;
109
110   SILC_LOG_DEBUG(("Start"));
111
112   tmp = silc_command_get_arg_type(cmd->payload, 1, NULL);
113   SILC_GET16_MSB(status, tmp);
114   if (status != SILC_STATUS_OK)
115     goto out;
116
117   /* Get channel name */
118   tmp = silc_command_get_arg_type(cmd->payload, 2, NULL);
119   if (!tmp)
120     goto out;
121
122   /* Get channel ID */
123   id_string = silc_command_get_arg_type(cmd->payload, 3, NULL);
124   if (!id_string)
125     goto out;
126
127   channel_name = strdup(tmp);
128
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);
134   if (!entry)
135     goto out;
136
137   entry->global_users = TRUE;
138
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);
142
143  out:
144   silc_server_command_reply_free(cmd);
145 }
146
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
150    after all. */
151
152 SILC_SERVER_CMD_REPLY_FUNC(identify)
153 {
154   SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
155   SilcServer server = cmd->server;
156   SilcCommandStatus status;
157   unsigned char *tmp;
158
159   SILC_LOG_DEBUG(("Start"));
160
161   tmp = silc_command_get_arg_type(cmd->payload, 1, NULL);
162   SILC_GET16_MSB(status, tmp);
163   if (status != SILC_STATUS_OK)
164     goto out;
165
166   /* Process one identify reply */
167   if (status == SILC_STATUS_OK) {
168     unsigned char *id_data;
169     char *nickname;
170
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)
174       goto out;
175
176 #if 0
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);
181
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);
185 #endif
186   }
187
188   if (status == SILC_STATUS_LIST_START) {
189
190   }
191
192   if (status == SILC_STATUS_LIST_END) {
193
194   }
195
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);
199
200  out:
201   silc_server_command_reply_free(cmd);
202 }