Initial revision
[silc.git] / apps / silcd / command.h
1 /*
2
3   servercommand.h
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 #ifndef COMMAND_H
22 #define COMMAND_H
23
24 /* 
25    Structure holding one command and pointer to its function. 
26
27    SilcCommandCb cb
28
29        Callback function called when this command is executed.
30
31    SilcCommand cmd
32
33        The actual command. Defined in silccore/silccommand.h
34
35    SilcCommandFlag flags
36
37        Flags for the command. These set how command behaves on different
38        situations. 
39
40 */
41 typedef struct {
42   SilcCommandCb cb;
43   SilcCommand cmd;
44   SilcCommandFlag flags;
45 } SilcServerCommand;
46
47 /* All server commands */
48 extern SilcServerCommand silc_command_list[];
49
50 /* Context sent as argument to all commands */
51 typedef struct {
52   SilcServer server;
53   SilcSocketConnection sock;
54   SilcCommandPayload payload;
55   SilcPacketContext *packet;
56   int pending;
57 } *SilcServerCommandContext;
58
59 /* Structure holding pending commands. If command is pending it will be
60    executed after command reply has been received and executed. 
61    Pending commands are used in cases where the original command request
62    had to be forwarded to router. After router replies the pending
63    command is re-executed. */
64 typedef struct SilcServerCommandPendingStruct {
65   SilcCommand reply_cmd;
66   void *context;
67   SilcCommandCb callback;
68
69   struct SilcServerCommandPendingStruct *next;
70 } SilcServerCommandPending;
71
72 /* List of pending commands */
73 extern SilcServerCommandPending *silc_command_pending;
74
75 /* Macros */
76
77 /* Macro used for command declaration in command list structure */
78 #define SILC_SERVER_CMD(func, cmd, flags) \
79 { silc_server_command_##func, SILC_COMMAND_##cmd, flags }
80
81 /* Macro used to declare command functions */
82 #define SILC_SERVER_CMD_FUNC(func) \
83 void silc_server_command_##func(void *context)
84
85 /* Macro used to execute commands */
86 #define SILC_SERVER_COMMAND_EXEC(ctx)                           \
87 do {                                                            \
88   SilcServerCommand *cmd;                                       \
89                                                                 \
90   for (cmd = silc_command_list; cmd->cb; cmd++)                 \
91     if (cmd->cmd == silc_command_get(ctx->payload)) {           \
92       cmd->cb(ctx);                                             \
93       break;                                                    \
94     }                                                           \
95                                                                 \
96   if (cmd == NULL) {                                            \
97     SILC_LOG_ERROR(("Unknown command, packet dropped"));        \
98     silc_free(ctx);                                             \
99     return;                                                     \
100   }                                                             \
101 } while(0)
102
103 /* Checks for pending commands */
104 #define SILC_SERVER_COMMAND_CHECK_PENDING(ctx)          \
105 do {                                                    \
106   if (silc_command_pending) {                           \
107     SilcServerCommandPending *r;                        \
108     SilcCommand cmd;                                    \
109                                                         \
110     cmd = silc_command_get(payload);                    \
111     for (r = silc_command_pending; r; r = r->next) {    \
112       if (r->reply_cmd == cmd) {                        \
113         ctx->context = r->context;                      \
114         ctx->callback = r->callback;                    \
115         break;                                          \
116       }                                                 \
117     }                                                   \
118   }                                                     \
119 } while(0)
120
121 /* Executed pending command */
122 #define SILC_SERVER_COMMAND_EXEC_PENDING(ctx, cmd)      \
123 do {                                                    \
124   if (ctx->callback) {                                  \
125     (*ctx->callback)(ctx->context);                     \
126     silc_server_command_pending_del(cmd);               \
127   }                                                     \
128 } while(0)
129
130 /* Prototypes */
131 void silc_server_command_pending(SilcCommand reply_cmd,
132                                  SilcCommandCb callback,
133                                  void *context);
134 void silc_server_command_pending_del(SilcCommand reply_cmd);
135 SILC_SERVER_CMD_FUNC(whois);
136 SILC_SERVER_CMD_FUNC(whowas);
137 SILC_SERVER_CMD_FUNC(identify);
138 SILC_SERVER_CMD_FUNC(newuser);
139 SILC_SERVER_CMD_FUNC(nick);
140 SILC_SERVER_CMD_FUNC(list);
141 SILC_SERVER_CMD_FUNC(topic);
142 SILC_SERVER_CMD_FUNC(invite);
143 SILC_SERVER_CMD_FUNC(quit);
144 SILC_SERVER_CMD_FUNC(kill);
145 SILC_SERVER_CMD_FUNC(info);
146 SILC_SERVER_CMD_FUNC(connect);
147 SILC_SERVER_CMD_FUNC(ping);
148 SILC_SERVER_CMD_FUNC(oper);
149 SILC_SERVER_CMD_FUNC(pass);
150 SILC_SERVER_CMD_FUNC(admin);
151 SILC_SERVER_CMD_FUNC(join);
152 SILC_SERVER_CMD_FUNC(motd);
153 SILC_SERVER_CMD_FUNC(umode);
154 SILC_SERVER_CMD_FUNC(cmode);
155 SILC_SERVER_CMD_FUNC(kick);
156 SILC_SERVER_CMD_FUNC(ignore);
157 SILC_SERVER_CMD_FUNC(restart);
158 SILC_SERVER_CMD_FUNC(close);
159 SILC_SERVER_CMD_FUNC(die);
160 SILC_SERVER_CMD_FUNC(silcoper);
161 SILC_SERVER_CMD_FUNC(leave);
162 SILC_SERVER_CMD_FUNC(names);
163
164 #endif