Global costemic changes.
[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.3  2000/07/05 06:14:01  priikone
24  *      Global costemic changes.
25  *
26  * Revision 1.2  2000/07/03 05:52:22  priikone
27  *      Implemented LEAVE command.
28  *
29  * Revision 1.1.1.1  2000/06/27 11:36:56  priikone
30  *      Imported from internal CVS/Added Log headers.
31  *
32  *
33  */
34
35 #include "serverincludes.h"
36 #include "server_internal.h"
37 #include "command_reply.h"
38
39 /* Server command reply list. Not all commands have reply function as
40    they are never sent by server. More maybe added later if need appears. */
41 SilcServerCommandReply silc_command_reply_list[] =
42 {
43   SILC_SERVER_CMD_REPLY(join, JOIN),
44
45   { NULL, 0 },
46 };
47
48 /* Process received command reply. */
49
50 void silc_server_command_reply_process(SilcServer server,
51                                        SilcSocketConnection sock,
52                                        SilcBuffer buffer)
53 {
54   SilcServerCommandReplyContext ctx;
55   SilcCommandPayload payload;
56
57   /* Get command reply payload from packet */
58   payload = silc_command_parse_payload(buffer);
59   if (!payload) {
60     /* Silently ignore bad reply packet */
61     SILC_LOG_DEBUG(("Bad command reply packet"));
62     return;
63   }
64   
65   /* Allocate command reply context. This must be free'd by the
66      command reply routine receiving it. */
67   ctx = silc_calloc(1, sizeof(*ctx));
68   ctx->server = server;
69   ctx->sock = sock;
70   ctx->payload = payload;
71       
72   /* Check for pending commands and mark to be exeucted */
73   SILC_SERVER_COMMAND_CHECK_PENDING(ctx);
74   
75   /* Execute command reply */
76   SILC_SERVER_COMMAND_REPLY_EXEC(ctx);
77 }
78
79 /* Free command reply context and its internals. */
80
81 void silc_server_command_reply_free(SilcServerCommandReplyContext cmd)
82 {
83   if (cmd) {
84     silc_command_free_payload(cmd->payload);
85     silc_free(cmd);
86   }
87 }
88
89 /* Received reply for forwarded JOIN command. Router has created or joined
90    the client to the channel. We save some channel information locally
91    for future use. */
92
93 SILC_SERVER_CMD_REPLY_FUNC(join)
94 {
95   SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
96   SilcServer server = cmd->server;
97   SilcCommandStatus status;
98   SilcChannelID *id;
99   SilcChannelList *entry;
100   unsigned char *id_string;
101   char *channel_name, *tmp;
102
103 #define LCC(x) server->local_list->channel_cache[(x) - 32]
104 #define LCCC(x) server->local_list->channel_cache_count[(x) - 32]
105
106   SILC_LOG_DEBUG(("Start"));
107
108   tmp = silc_command_get_arg_type(cmd->payload, 1, NULL);
109   SILC_GET16_MSB(status, tmp);
110   if (status != SILC_STATUS_OK)
111     goto out;
112
113   /* Get channel name */
114   tmp = silc_command_get_arg_type(cmd->payload, 2, NULL);
115   if (!tmp)
116     goto out;
117
118   /* Get channel ID */
119   id_string = silc_command_get_arg_type(cmd->payload, 3, NULL);
120   if (!id_string)
121     goto out;
122
123   channel_name = strdup(tmp);
124
125   /* Add the channel to our local list. */
126   id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
127   silc_idlist_add_channel(&server->local_list->channels, channel_name, 
128                           SILC_CHANNEL_MODE_NONE, id, 
129                           server->id_entry->router, NULL, &entry);
130   LCCC(channel_name[0]) = silc_idcache_add(&LCC(channel_name[0]), 
131                                            LCCC(channel_name[0]),
132                                            channel_name, SILC_ID_CHANNEL, 
133                                            (void *)id, (void *)entry);
134   entry->global_users = TRUE;
135
136   /* Execute pending JOIN command so that the client who originally
137      wanted to join the channel will be joined after all. */
138   SILC_SERVER_COMMAND_EXEC_PENDING(cmd, SILC_COMMAND_JOIN);
139
140  out:
141   silc_server_command_reply_free(cmd);
142 #undef LCC
143 #undef LCCC
144 }