X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcclient%2Fcommand.h;h=0b8949e15132da54cb230e7e20face8ce73f0354;hb=a818c5b5411bbc4436d1c5f011236985c96bb787;hp=edb714505f12fec5e244134fa14487939455a3c7;hpb=318d79b391bf6288e3e28c840217a7097f3d0392;p=silc.git diff --git a/lib/silcclient/command.h b/lib/silcclient/command.h index edb71450..0b8949e1 100644 --- a/lib/silcclient/command.h +++ b/lib/silcclient/command.h @@ -1,16 +1,15 @@ /* - command.h + command.h - Author: Pekka Riikonen + Author: Pekka Riikonen - Copyright (C) 1997 - 2000 Pekka Riikonen + Copyright (C) 1997 - 2001 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - + the Free Software Foundation; version 2 of the License. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -21,118 +20,103 @@ #ifndef COMMAND_H #define COMMAND_H -/* - Structure holding one command and pointer to its function. - - SilcCommandCb cb - - Callback function called when this command is executed. - - SilcCommand cmd - - The actual command. These are defined in silccore/silccommand.h - - char *name +#include "command_reply.h" - Logical name of the command. This is the visible command name - that user uses when calling command. Eg. NICK. +/* Structure holding one command and pointer to its function. This + structure is allocate into the commands list, and is returned + for example by silc_client_command_find function. - SilcCommandFlag flags - - Flags for the command. These set how command behaves on different - situations. Server sets these flags as well, but to be sure - that our client never sends wrong commands we preserve the - flags on client side as well. - - XXX: We preserve these so that we define them but currently we - don't check the flags at all. + To call a command: command->command(cmd, NULL); + To call a command reply: command->reply(cmd, NULL); */ -typedef struct { - SilcCommandCb cb; - SilcCommand cmd; - char *name; - SilcCommandFlag flags; - unsigned int max_args; -} SilcClientCommand; - -/* All client commands */ -extern SilcClientCommand silc_command_list[]; - -/* Client command callback function. This included into Command Context, - and if it is defined it will be executed when executing the command. */ -typedef void (*SilcClientCommandCallback)(void *context); - -/* Context sent as argument to all commands */ -typedef struct { +struct SilcClientCommandStruct { + SilcCommand cmd; /* Command type */ + SilcCommandCb command; /* Command function */ + SilcCommandCb reply; /* Command reply callback */ + char *name; /* Name of the command (optional) */ + SilcUInt8 max_args; /* Maximum arguments (optional) */ + SilcUInt16 ident; /* Identifier for command (optional) */ + struct SilcClientCommandStruct *next; +}; + +/* Context sent as argument to all commands. This is used by the library + and application should use this as well. However, application may + choose to use some own context for its own local command. All library + commands, however, must use this context. */ +struct SilcClientCommandContextStruct { SilcClient client; SilcClientConnection conn; - SilcClientCommand *command; - unsigned int argc; + SilcClientCommand command; + SilcUInt32 argc; unsigned char **argv; - unsigned int *argv_lens; - unsigned int *argv_types; -} *SilcClientCommandContext; + SilcUInt32 *argv_lens; + SilcUInt32 *argv_types; + int pending; /* Command is being re-processed when TRUE */ + int users; /* Reference counter */ +}; /* Structure holding pending commands. If command is pending it will be executed after command reply has been executed. */ -/* XXX This support may added for commands as well and not just command - replies, if needed later. */ typedef struct SilcClientCommandPendingStruct { SilcCommand reply_cmd; + SilcCommandCb callback; void *context; - SilcClientCommandCallback callback; - + SilcUInt16 ident; struct SilcClientCommandPendingStruct *next; } SilcClientCommandPending; /* List of pending commands */ extern SilcClientCommandPending *silc_command_pending; + /* Macros */ -/* Macro used for command declaration in command list structure */ -#define SILC_CLIENT_CMD(func, cmd, name, flags, args) \ -{ silc_client_command_##func, SILC_COMMAND_##cmd, name, flags, args } +/* Macro used for command registering and unregistering */ +#define SILC_CLIENT_CMD(func, cmd, name, args) \ +silc_client_command_register(client, SILC_COMMAND_##cmd, name, \ + silc_client_command_##func, \ + silc_client_command_reply_##func, args, 0) +#define SILC_CLIENT_CMDU(func, cmd, name) \ +silc_client_command_unregister(client, SILC_COMMAND_##cmd, \ + silc_client_command_##func, \ + silc_client_command_reply_##func, 0) /* Macro used to declare command functions */ -#define SILC_CLIENT_CMD_FUNC(func) \ -void silc_client_command_##func(void *context) - -/* Checks for pending commands */ -#define SILC_CLIENT_COMMAND_CHECK_PENDING(ctx) \ -do { \ - if (silc_command_pending) { \ - SilcClientCommandPending *r; \ - SilcCommand cmd; \ - \ - cmd = silc_command_get(payload); \ - for (r = silc_command_pending; r; r = r->next) { \ - if (r->reply_cmd == cmd) { \ - ctx->context = r->context; \ - ctx->callback = r->callback; \ - break; \ - } \ - } \ - } \ +#define SILC_CLIENT_CMD_FUNC(func) \ +void silc_client_command_##func(void *context, void *context2) + +/* Executed pending command callback */ +#define SILC_CLIENT_PENDING_EXEC(ctx, cmd) \ +do { \ + if ((ctx)->callback) \ + (*ctx->callback)(ctx->context, ctx); \ + silc_client_command_pending_del((ctx)->sock->user_data, (cmd), \ + (ctx)->ident); \ } while(0) -/* Executed pending command */ -#define SILC_CLIENT_COMMAND_EXEC_PENDING(ctx, cmd) \ -do { \ - if (ctx->callback) { \ - (*ctx->callback)(ctx->context); \ - silc_client_command_pending_del((cmd)); \ - } \ -} while(0) +bool silc_client_command_register(SilcClient client, + SilcCommand command, + const char *name, + SilcCommandCb command_function, + SilcCommandCb command_reply_function, + SilcUInt8 max_args, + SilcUInt16 ident); +bool silc_client_command_unregister(SilcClient client, + SilcCommand command, + SilcCommandCb command_function, + SilcCommandCb command_reply_function, + SilcUInt16 ident); +void silc_client_commands_register(SilcClient client); +void silc_client_commands_unregister(SilcClient client); +void silc_client_command_pending_del(SilcClientConnection conn, + SilcCommand reply_cmd, + SilcUInt16 ident); +int silc_client_command_pending_check(SilcClientConnection conn, + SilcClientCommandReplyContext ctx, + SilcCommand command, + SilcUInt16 ident); -/* Prototypes */ -void silc_client_command_free(SilcClientCommandContext cmd); -SilcClientCommand *silc_client_command_find(const char *name); -void silc_client_command_pending(SilcCommand reply_cmd, - SilcClientCommandCallback callback, - void *context); -void silc_client_command_pending_del(SilcCommand reply_cmd); SILC_CLIENT_CMD_FUNC(whois); SILC_CLIENT_CMD_FUNC(whowas); SILC_CLIENT_CMD_FUNC(identify); @@ -150,12 +134,14 @@ SILC_CLIENT_CMD_FUNC(join); SILC_CLIENT_CMD_FUNC(motd); SILC_CLIENT_CMD_FUNC(umode); SILC_CLIENT_CMD_FUNC(cmode); +SILC_CLIENT_CMD_FUNC(cumode); SILC_CLIENT_CMD_FUNC(kick); -SILC_CLIENT_CMD_FUNC(restart); +SILC_CLIENT_CMD_FUNC(ban); SILC_CLIENT_CMD_FUNC(close); -SILC_CLIENT_CMD_FUNC(die); +SILC_CLIENT_CMD_FUNC(shutdown); SILC_CLIENT_CMD_FUNC(silcoper); SILC_CLIENT_CMD_FUNC(leave); -SILC_CLIENT_CMD_FUNC(names); +SILC_CLIENT_CMD_FUNC(users); +SILC_CLIENT_CMD_FUNC(getkey); #endif