5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2005 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; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
23 #include "command_reply.h"
25 /* Structure holding one command and pointer to its function. This
26 structure is allocate into the commands list, and is returned
27 for example by silc_client_command_find function.
29 To call a command: command->command(cmd, NULL);
30 To call a command reply: command->reply(cmd, NULL);
33 struct SilcClientCommandStruct {
34 SilcCommand cmd; /* Command type */
35 SilcCommandCb command; /* Command function */
36 SilcCommandCb reply; /* Command reply callback */
37 char *name; /* Name of the command (optional) */
38 SilcUInt8 max_args; /* Maximum arguments (optional) */
39 SilcUInt16 ident; /* Identifier for command (optional) */
40 struct SilcClientCommandStruct *next;
43 /* Context sent as argument to all commands. This is used by the library
44 and application should use this as well. However, application may
45 choose to use some own context for its own local command. All library
46 commands, however, must use this context. */
47 struct SilcClientCommandContextStruct {
49 SilcClientConnection conn;
50 SilcClientCommand command;
53 SilcUInt32 *argv_lens;
54 SilcUInt32 *argv_types;
55 int pending; /* Command is being re-processed when TRUE */
56 int users; /* Reference counter */
59 /* Structure holding pending commands. If command is pending it will be
60 executed after command reply has been executed. */
61 typedef struct SilcClientCommandPendingStruct {
62 SilcCommand reply_cmd;
64 unsigned int reply_check : 8;
65 SilcCommandCb callback;
67 struct SilcClientCommandPendingStruct *next;
68 } SilcClientCommandPending;
70 /* List of pending commands */
71 extern SilcClientCommandPending *silc_command_pending;
76 /* Macro used for command registering and unregistering */
77 #define SILC_CLIENT_CMD(func, cmd, name, args) \
78 silc_client_command_register(client, SILC_COMMAND_##cmd, name, \
79 silc_client_command_##func, \
80 silc_client_command_reply_##func, args, 0)
81 #define SILC_CLIENT_CMDU(func, cmd, name) \
82 silc_client_command_unregister(client, SILC_COMMAND_##cmd, \
83 silc_client_command_##func, \
84 silc_client_command_reply_##func, 0)
86 /* Macro used to declare command functions */
87 #define SILC_CLIENT_CMD_FUNC(func) \
88 void silc_client_command_##func(void *context, void *context2)
90 /* Executed pending command callback */
91 #define SILC_CLIENT_PENDING_EXEC(ctx, cmd) \
94 for (_i = 0; _i < ctx->callbacks_count; _i++) \
95 if (ctx->callbacks[_i].callback) \
96 (*ctx->callbacks[_i].callback)(ctx->callbacks[_i].context, ctx); \
97 silc_client_command_pending_del(ctx->sock->user_data, cmd, ctx->ident); \
100 SilcClientCommandContext silc_client_command_alloc(void);
101 void silc_client_command_free(SilcClientCommandContext ctx);
102 SilcClientCommandContext silc_client_command_dup(SilcClientCommandContext ctx);
103 SilcClientCommand silc_client_command_find(SilcClient client,
105 bool silc_client_command_register(SilcClient client,
108 SilcCommandCb command_function,
109 SilcCommandCb command_reply_function,
112 bool silc_client_command_unregister(SilcClient client,
114 SilcCommandCb command_function,
115 SilcCommandCb command_reply_function,
117 void silc_client_commands_register(SilcClient client);
118 void silc_client_commands_unregister(SilcClient client);
119 void silc_client_command_pending_del(SilcClientConnection conn,
120 SilcCommand reply_cmd,
122 SilcClientCommandPendingCallbacks
123 silc_client_command_pending_check(SilcClientConnection conn,
124 SilcClientCommandReplyContext ctx,
127 SilcUInt32 *callbacks_count);
128 void silc_client_command_process(SilcClient client,
129 SilcSocketConnection sock,
130 SilcPacketContext *packet);
131 SILC_CLIENT_CMD_FUNC(whois);
132 SILC_CLIENT_CMD_FUNC(whowas);
133 SILC_CLIENT_CMD_FUNC(identify);
134 SILC_CLIENT_CMD_FUNC(nick);
135 SILC_CLIENT_CMD_FUNC(list);
136 SILC_CLIENT_CMD_FUNC(topic);
137 SILC_CLIENT_CMD_FUNC(invite);
138 SILC_CLIENT_CMD_FUNC(quit);
139 SILC_CLIENT_CMD_FUNC(kill);
140 SILC_CLIENT_CMD_FUNC(info);
141 SILC_CLIENT_CMD_FUNC(ping);
142 SILC_CLIENT_CMD_FUNC(oper);
143 SILC_CLIENT_CMD_FUNC(join);
144 SILC_CLIENT_CMD_FUNC(motd);
145 SILC_CLIENT_CMD_FUNC(umode);
146 SILC_CLIENT_CMD_FUNC(cmode);
147 SILC_CLIENT_CMD_FUNC(cumode);
148 SILC_CLIENT_CMD_FUNC(kick);
149 SILC_CLIENT_CMD_FUNC(ban);
150 SILC_CLIENT_CMD_FUNC(detach);
151 SILC_CLIENT_CMD_FUNC(watch);
152 SILC_CLIENT_CMD_FUNC(silcoper);
153 SILC_CLIENT_CMD_FUNC(leave);
154 SILC_CLIENT_CMD_FUNC(users);
155 SILC_CLIENT_CMD_FUNC(getkey);
156 SILC_CLIENT_CMD_FUNC(service);
158 SILC_CLIENT_CMD_FUNC(shutdown);
159 SILC_CLIENT_CMD_FUNC(close);
160 SILC_CLIENT_CMD_FUNC(connect);