--- /dev/null
+
+@SYNTAX:stats@
+
+Shows various server and network statistics.
}
}
break;
- }
-
- if (!success)
+ } else if (!success) {
+ silc_say_error("WHOIS: %s", silc_get_status_message(status));
return;
-
+ }
+
client_entry = va_arg(vp, SilcClientEntry);
nickname = va_arg(vp, char *);
username = va_arg(vp, char *);
silc_say_error("%s: %s", tmp,
silc_get_status_message(status));
break;
- }
-
- if (!success)
+ } else if (!success) {
+ silc_say_error("WHOWAS: %s", silc_get_status_message(status));
return;
+ }
(void)va_arg(vp, SilcClientEntry);
nickname = va_arg(vp, char *);
"Bad version". Protocol or software version mismatch.
+ 54 SILC_STATUS_ERR_TIMEDOUT
+
+ "Operation timed out". Operation or service request timed
+ out, and thus was not processed.
+
.in 3
/* Initialize the scheduler */
client->schedule =
silc_schedule_init(client->internal->params->task_max ?
- client->internal->params->task_max : 200);
+ client->internal->params->task_max : 200, client);
if (!client->schedule)
return FALSE;
#define SILC_STATUS_ERR_BAD_SERVER_ID 51
#define SILC_STATUS_ERR_KEY_EXCHANGE_FAILED 52
#define SILC_STATUS_ERR_BAD_VERSION 53
+#define SILC_STATUS_ERR_TIMEDOUT 54
/***/
#define SILC_STATUS_IS_ERROR(status) (status >= SILC_STATUS_ERR_NO_SUCH_NICK)
the scheduler needs to be wakenup when tasks are added or removed from
the task queues. Returns context to the platform specific scheduler. */
-void *silc_schedule_internal_init(SilcSchedule schedule)
+void *silc_schedule_internal_init(SilcSchedule schedule, void *context)
{
#ifdef SILC_THREADS
return NULL;
SILC_TASK_TIMEOUT,
SILC_TASK_PRI_NORMAL);
else
- protocol->protocol->callback(schedule, 0, 0, (void *)protocol);
+ protocol->protocol->callback(schedule, silc_schedule_get_context(schedule),
+ 0, 0, (void *)protocol);
}
/* Executes the final callback of the protocol. */
void silc_protocol_execute_final(SilcProtocol protocol, SilcSchedule schedule)
{
- protocol->final_callback(schedule, 0, 0, (void *)protocol);
+ protocol->final_callback(schedule, silc_schedule_get_context(schedule),
+ 0, 0, (void *)protocol);
}
/* Cancels the execution of the next state of the protocol. */
the wakeup mechanism of the scheduler. In multi-threaded environment
the scheduler needs to be wakenup when tasks are added or removed from
the task queues. Returns context to the platform specific scheduler. */
-void *silc_schedule_internal_init(SilcSchedule schedule);
+void *silc_schedule_internal_init(SilcSchedule schedule, void *context);
/* Uninitializes the platform specific scheduler context. */
void silc_schedule_internal_uninit(void *context);
*/
struct SilcScheduleStruct {
+ void *app_context; /* Application specific context */
SilcTaskQueue fd_queue;
SilcTaskQueue timeout_queue;
SilcTaskQueue generic_queue;
/* Initializes the scheduler. This returns the scheduler context that
is given as arugment usually to all silc_schedule_* functions.
The `max_tasks' indicates the number of maximum tasks that the
- scheduler can handle. */
+ scheduler can handle. The `app_context' is application specific
+ context that is delivered to task callbacks. */
-SilcSchedule silc_schedule_init(int max_tasks)
+SilcSchedule silc_schedule_init(int max_tasks, void *app_context)
{
SilcSchedule schedule;
schedule->max_fd = max_tasks;
schedule->timeout = NULL;
schedule->valid = TRUE;
+ schedule->app_context = app_context;
/* Allocate scheduler lock */
silc_mutex_alloc(&schedule->lock);
/* Initialize the platform specific scheduler. */
- schedule->internal = silc_schedule_internal_init(schedule);
+ schedule->internal = silc_schedule_internal_init(schedule, app_context);
return schedule;
}
if (task->valid && schedule->fd_list[i].revents & SILC_TASK_READ) {
silc_mutex_unlock(schedule->fd_queue->lock);
SILC_SCHEDULE_UNLOCK(schedule);
- task->callback(schedule, SILC_TASK_READ, task->fd, task->context);
+ task->callback(schedule, schedule->app_context,
+ SILC_TASK_READ, task->fd, task->context);
SILC_SCHEDULE_LOCK(schedule);
silc_mutex_lock(schedule->fd_queue->lock);
}
if (task->valid && schedule->fd_list[i].revents & SILC_TASK_WRITE) {
silc_mutex_unlock(schedule->fd_queue->lock);
SILC_SCHEDULE_UNLOCK(schedule);
- task->callback(schedule, SILC_TASK_WRITE, task->fd, task->context);
+ task->callback(schedule, schedule->app_context,
+ SILC_TASK_WRITE, task->fd, task->context);
SILC_SCHEDULE_LOCK(schedule);
silc_mutex_lock(schedule->fd_queue->lock);
}
if (task->valid && schedule->fd_list[i].revents & SILC_TASK_READ) {
silc_mutex_unlock(schedule->generic_queue->lock);
SILC_SCHEDULE_UNLOCK(schedule);
- task->callback(schedule, SILC_TASK_READ, fd, task->context);
+ task->callback(schedule, schedule->app_context,
+ SILC_TASK_READ, fd, task->context);
SILC_SCHEDULE_LOCK(schedule);
silc_mutex_lock(schedule->generic_queue->lock);
}
if (task->valid && schedule->fd_list[i].revents & SILC_TASK_WRITE) {
silc_mutex_unlock(schedule->generic_queue->lock);
SILC_SCHEDULE_UNLOCK(schedule);
- task->callback(schedule, SILC_TASK_WRITE, fd, task->context);
+ task->callback(schedule, schedule->app_context,
+ SILC_TASK_WRITE, fd, task->context);
SILC_SCHEDULE_LOCK(schedule);
silc_mutex_lock(schedule->generic_queue->lock);
}
if (task->valid) {
silc_mutex_unlock(queue->lock);
SILC_SCHEDULE_UNLOCK(schedule);
- task->callback(schedule, SILC_TASK_EXPIRE, task->fd, task->context);
+ task->callback(schedule, schedule->app_context,
+ SILC_TASK_EXPIRE, task->fd, task->context);
SILC_SCHEDULE_LOCK(schedule);
silc_mutex_lock(queue->lock);
}
#endif
}
+/* Returns the application specific context that was saved into the
+ scheduler in silc_schedule_init function. The context is also
+ returned to application in task callback functions, but this function
+ may be used to get it as well if needed. */
+
+void *silc_schedule_get_context(SilcSchedule schedule)
+{
+ return schedule->app_context;
+}
+
/* Add new task to the scheduler */
SilcTask silc_schedule_task_add(SilcSchedule schedule, SilcUInt32 fd,
*
* SYNOPSIS
*
- * typedef void (*SilcTaskCallback)(SilcSchedule schedule,
- * SilcTaskEvent type, SilcUInt32 fd,
+ * typedef void (*SilcTaskCallback)(SilcSchedule schedule,
+ * void *app_context,
+ * SilcTaskEvent type, SilcUInt32 fd,
* void *context);
*
* DESCRIPTION
* The `schedule' is the scheduler context, the `type' is the indicated
* event, the `fd' is the file descriptor of the task and the `context'
* is a caller specified context. If multiple events occurred this
- * callback is called separately for all events.
+ * callback is called separately for all events. The `app_context'
+ * is application specific context that was given as argument to the
+ * silc_schedule_init function.
*
* To specify task callback function in the application using the
* SILC_TASK_CALLBACK and SILC_TASK_CALLBACK_GLOBAL macros is
* recommended.
*
***/
-typedef void (*SilcTaskCallback)(SilcSchedule schedule, SilcTaskEvent type,
- SilcUInt32 fd, void *context);
+typedef void (*SilcTaskCallback)(SilcSchedule schedule, void *app_context,
+ SilcTaskEvent type, SilcUInt32 fd,
+ void *context);
/* Macros */
* SOURCE
*/
#define SILC_TASK_CALLBACK(func) \
-static void func(SilcSchedule schedule, SilcTaskEvent type, \
+static void func(SilcSchedule schedule, void *app_context, \
+ SilcTaskEvent type, \
SilcUInt32 fd, void *context)
/***/
*
* SOURCE
*/
-#define SILC_TASK_CALLBACK_GLOBAL(func) \
-void func(SilcSchedule schedule, SilcTaskEvent type, \
+#define SILC_TASK_CALLBACK_GLOBAL(func) \
+void func(SilcSchedule schedule, void *app_context, SilcTaskEvent type, \
SilcUInt32 fd, void *context)
/***/
*
* SYNOPSIS
*
- * SilcSchedule silc_schedule_init(int max_tasks);
+ * SilcSchedule silc_schedule_init(int max_tasks, void *app_context);
*
* DESCRIPTION
*
* Initializes the scheduler. This returns the scheduler context that
* is given as argument usually to all silc_schedule_* functions.
* The `max_tasks' indicates the number of maximum tasks that the
- * scheduler can handle.
+ * scheduler can handle. The `app_context' is application specific
+ * context that is delivered to all task callbacks. The caller must
+ * free that context. The 'app_context' can be for example the
+ * application itself.
*
***/
-SilcSchedule silc_schedule_init(int max_tasks);
+SilcSchedule silc_schedule_init(int max_tasks, void *app_context);
/****f* silcutil/SilcScheduleAPI/silc_schedule_uninit
*
***/
void silc_schedule_wakeup(SilcSchedule schedule);
+/****f* silcutil/SilcScheduleAPI/silc_schedule_get_context
+ *
+ * SYNOPSIS
+ *
+ * void *silc_schedule_get_context(SilcSchedule schedule);
+ *
+ * DESCRIPTION
+ *
+ * Returns the application specific context that was saved into the
+ * scheduler in silc_schedule_init function. The context is also
+ * returned to application in task callback functions, but this function
+ * may be used to get it as well if needed.
+ *
+ ***/
+void *silc_schedule_get_context(SilcSchedule schedule);
+
/****f* silcutil/SilcScheduleAPI/silc_schedule_task_add
*
* SYNOPSIS
slen2 = strlen(string2);
/* See if they are same already */
- if (!strncmp(string1, string2, strlen(string2)))
+ if (!strncmp(string1, string2, slen2) && slen2 == slen1)
return TRUE;
if (slen2 < slen1)
{ STAT(BAD_SERVER_ID), "Server ID is not valid" },
{ STAT(KEY_EXCHANGE_FAILED), "Key exchange failed" },
{ STAT(BAD_VERSION), "Bad version" },
+ { STAT(TIMEDOUT), "Service timed out" },
{ 0, NULL }
};
/* Internal context. */
typedef struct {
+ void *app_context;
int wakeup_pipe[2];
SilcTask wakeup_task;
sigset_t signals;
the scheduler needs to be wakenup when tasks are added or removed from
the task queues. Returns context to the platform specific scheduler. */
-void *silc_schedule_internal_init(SilcSchedule schedule)
+void *silc_schedule_internal_init(SilcSchedule schedule,
+ void *app_context)
{
SilcUnixScheduler internal;
}
#endif
+ internal->app_context = app_context;
+
return (void *)internal;
}
for (i = 0; i < SIGNAL_COUNT; i++) {
if (internal->signal_call[i].call &&
internal->signal_call[i].callback) {
- internal->signal_call[i].callback(schedule, SILC_TASK_INTERRUPT,
+ internal->signal_call[i].callback(schedule, internal->app_context,
+ SILC_TASK_INTERRUPT,
internal->signal_call[i].signal,
internal->signal_call[i].context);
internal->signal_call[i].call = FALSE;
the scheduler needs to be wakenup when tasks are added or removed from
the task queues. Returns context to the platform specific scheduler. */
-void *silc_schedule_internal_init(SilcSchedule schedule)
+void *silc_schedule_internal_init(SilcSchedule schedule, void *app_context)
{
#ifdef SILC_THREADS
SilcWin32Wakeup wakeup;
#
# Author: Pekka Riikonen <priikone@silcnet.org>
#
-# Copyright (C) GNU GPL 2001 Pekka Riikonen
+# Copyright (C) GNU GPL 2001 - 2002 Pekka Riikonen
#
# SILC Toolkit Reference Manual documentation script. This will automatically
# generate documentation from the source tree. This will require the