/*
* Created: Tue Nov 25 19:25:33 GMT+0200 1997
*/
-/*
- * $Id$
- * $Log$
- * Revision 1.1 2000/06/27 11:36:55 priikone
- * Initial revision
- *
- *
- */
+/* $Id$ */
#include "silcincludes.h"
#include "silcprotocol.h"
+/* Dynamically registered protocols */
+SilcProtocolObject *silc_protocol_list = NULL;
+
+/* Dynamically registers new protocol. The protocol is added into protocol
+ list and can be unregistered with silc_protocol_unregister. */
+
+void silc_protocol_register(SilcProtocolType type,
+ SilcProtocolCallback callback)
+{
+ SilcProtocolObject *new;
+
+ new = silc_calloc(1, sizeof(*new));
+ new->type = type;
+ new->callback = callback;
+
+ if (!silc_protocol_list)
+ silc_protocol_list = new;
+ else {
+ new->next = silc_protocol_list;
+ silc_protocol_list = new;
+ }
+}
+
+/* Unregisters protocol. The unregistering is done by both protocol type
+ and the protocol callback. */
+
+void silc_protocol_unregister(SilcProtocolType type,
+ SilcProtocolCallback callback)
+{
+ SilcProtocolObject *protocol, *prev;
+
+ protocol = silc_protocol_list;
+ prev = NULL;
+ while (protocol && (protocol->type != type &&
+ protocol->callback != callback)) {
+ prev = protocol;
+ protocol = protocol->next;
+ }
+
+ if (protocol) {
+ if (prev)
+ prev->next = protocol->next;
+ else
+ silc_protocol_list = protocol->next;
+
+ silc_free(protocol);
+ }
+}
+
/* Allocates a new protocol object. The new allocated and initialized
protocol is returned to the new_protocol argument. The argument context
is the context to be sent as argument for the protocol. The callback
void silc_protocol_alloc(SilcProtocolType type, SilcProtocol *new_protocol,
void *context, SilcProtocolFinalCallback callback)
{
- int i;
+ SilcProtocolObject *protocol;
SILC_LOG_DEBUG(("Allocating new protocol type %d", type));
- for (i = 0; silc_protocol_list[i].callback; i++)
- if (silc_protocol_list[i].type == type)
- break;
+ protocol = silc_protocol_list;
+ while (protocol && protocol->type != type)
+ protocol = protocol->next;
- if (!silc_protocol_list[i].callback) {
+ if (!protocol) {
SILC_LOG_ERROR(("Requested protocol does not exists"));
+ *new_protocol = NULL;
return;
}
*new_protocol = silc_calloc(1, sizeof(**new_protocol));
- if (*new_protocol == NULL) {
- SILC_LOG_ERROR(("Cannot allocate new protocol object"));
- return;
- }
-
- (*new_protocol)->protocol = (SilcProtocolObject *)&silc_protocol_list[i];
+ (*new_protocol)->protocol = protocol;
(*new_protocol)->state = SILC_PROTOCOL_STATE_UNKNOWN;
(*new_protocol)->context = context;
(*new_protocol)->execute = silc_protocol_execute;
protocol->final_callback(qptr, 0, context, fd);
}
+
+/* Cancels the execution of the next state of the protocol. */
+
+void silc_protocol_cancel(void *qptr, void *context)
+{
+ SilcProtocol protocol = (SilcProtocol)context;
+
+ SILC_LOG_DEBUG(("Start"));
+
+ silc_task_unregister_by_callback(qptr, protocol->protocol->callback);
+}