X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcclient%2Fcommand.h;h=6b8bd6266eefacb18e5a1ca54688dcee5c57b431;hb=6394d86063413bc1c473723f3ef971840195bcd3;hp=7e7db0e9a32b2b8ef90dc8e7078fffbde90ccf7d;hpb=b6d96e1d0ddddd62dd022c7acfa93c7052ee5b88;p=silc.git diff --git a/lib/silcclient/command.h b/lib/silcclient/command.h index 7e7db0e9..6b8bd626 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,120 +20,116 @@ #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 +/* Forward declarations */ +typedef struct SilcClientCommandStruct *SilcClientCommand; +typedef struct SilcClientCommandContextStruct *SilcClientCommandContext; - char *name +#include "silcapi.h" +#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) */ + uint8 max_args; /* Maximum arguments (optional) */ + uint16 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; + uint32 argc; unsigned char **argv; - unsigned int *argv_lens; - unsigned int *argv_types; -} *SilcClientCommandContext; + uint32 *argv_lens; + uint32 *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; + SilcClientPendingDestructor destructor; void *context; - SilcClientCommandCallback callback; - + uint16 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); \ } 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)); \ - } \ +/* Execute destructor for pending command */ +#define SILC_CLIENT_PENDING_DESTRUCTOR(ctx, cmd) \ +do { \ + silc_client_command_pending_del((ctx)->sock->user_data, (cmd), \ + (ctx)->ident); \ + if (ctx->destructor) \ + (*ctx->destructor)(ctx->context); \ } while(0) -/* Prototypes */ -void silc_client_command_free(SilcClientCommandContext cmd); -void silc_client_send_command(SilcClient client, SilcClientConnection conn, - SilcCommand command, unsigned int argc, ...); -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); +bool silc_client_command_register(SilcClient client, + SilcCommand command, + const char *name, + SilcCommandCb command_function, + SilcCommandCb command_reply_function, + uint8 max_args, + uint16 ident); +bool silc_client_command_unregister(SilcClient client, + SilcCommand command, + SilcCommandCb command_function, + SilcCommandCb command_reply_function, + uint16 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, + uint16 ident); +int silc_client_command_pending_check(SilcClientConnection conn, + SilcClientCommandReplyContext ctx, + SilcCommand command, + uint16 ident); + SILC_CLIENT_CMD_FUNC(whois); SILC_CLIENT_CMD_FUNC(whowas); SILC_CLIENT_CMD_FUNC(identify); @@ -154,11 +149,12 @@ 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(users); +SILC_CLIENT_CMD_FUNC(getkey); #endif