X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcclient%2Fcommand.c;fp=lib%2Fsilcclient%2Fcommand.c;h=1e829efa368a0ae4b9b700d873ef7d936f854856;hb=31b9c6e9ceffe13a84659d337e35f7a5960ac6d9;hp=f04e4510aaff84f3c8d490c76b0bb5cbe4bf70df;hpb=2d0cb701c5d5b26c424fb067a71201eafa042b34;p=silc.git diff --git a/lib/silcclient/command.c b/lib/silcclient/command.c index f04e4510..1e829efa 100644 --- a/lib/silcclient/command.c +++ b/lib/silcclient/command.c @@ -86,10 +86,13 @@ void silc_client_command_call(SilcClientCommand command, } /* Add new pending command to be executed when reply to a command has been - received. The `reply_cmd' is the command that will call the `callback' - with `context' when reply has been received. If `ident is non-zero - the `callback' will be executed when received reply with command - identifier `ident'. */ + received. The `reply_cmd' is the command that will call the `callback' + with `context' when reply has been received. It can be SILC_COMMAND_NONE + to match any command with the `ident'. If `ident' is non-zero + the `callback' will be executed when received reply with command + identifier `ident'. If there already exists pending command for the + specified command, ident, callback and context this function has no + effect. */ void silc_client_command_pending(SilcClientConnection conn, SilcCommand reply_cmd, @@ -99,6 +102,16 @@ void silc_client_command_pending(SilcClientConnection conn, { SilcClientCommandPending *reply; + /* Check whether identical pending already exists for same command, + ident, callback and callback context. If it does then it would be + error to register it again. */ + silc_dlist_start(conn->pending_commands); + while ((reply = silc_dlist_get(conn->pending_commands)) != SILC_LIST_END) { + if (reply->reply_cmd == reply_cmd && reply->ident == ident && + reply->callback == callback && reply->context == context) + return; + } + reply = silc_calloc(1, sizeof(*reply)); reply->reply_cmd = reply_cmd; reply->ident = ident; @@ -125,26 +138,33 @@ void silc_client_command_pending_del(SilcClientConnection conn, } /* Checks for pending commands and marks callbacks to be called from - the command reply function. Returns TRUE if there were pending command. */ - -int silc_client_command_pending_check(SilcClientConnection conn, - SilcClientCommandReplyContext ctx, - SilcCommand command, - SilcUInt16 ident) + the command reply function. */ + +SilcClientCommandPendingCallbacks +silc_client_command_pending_check(SilcClientConnection conn, + SilcClientCommandReplyContext ctx, + SilcCommand command, + SilcUInt16 ident, + SilcUInt32 *callbacks_count) { SilcClientCommandPending *r; + SilcClientCommandPendingCallbacks callbacks = NULL; + int i = 0; silc_dlist_start(conn->pending_commands); while ((r = silc_dlist_get(conn->pending_commands)) != SILC_LIST_END) { - if (r->reply_cmd == command && r->ident == ident) { - ctx->context = r->context; - ctx->callback = r->callback; + if ((r->reply_cmd == command || r->reply_cmd == SILC_COMMAND_NONE) + && r->ident == ident) { + callbacks = silc_realloc(callbacks, sizeof(*callbacks) * (i + 1)); + callbacks[i].context = r->context; + callbacks[i].callback = r->callback; ctx->ident = ident; - return TRUE; + i++; } } - return FALSE; + *callbacks_count = i; + return callbacks; } /* Allocate Command Context */