#include "module.h" #include "silc-cmdqueue.h" #include GHashTable *cmd_queues; void silc_queue_init(void) { cmd_queues = g_hash_table_new(NULL, NULL); } static void cmd_list_remove_cb(char *cmd) { g_free(cmd); } static int cmd_queue_remove_cb(void *key, GSList *list) { if ((list != NULL) && (list->next != NULL)) { g_slist_foreach(list, (GFunc) cmd_list_remove_cb, NULL); g_slist_free(list); } return TRUE; } void silc_queue_deinit(void) { g_hash_table_foreach_remove(cmd_queues, (GHRFunc) cmd_queue_remove_cb, NULL); g_hash_table_destroy(cmd_queues); } void silc_queue_flush(SilcClientConnection conn) { GSList *list = g_hash_table_lookup(cmd_queues, conn); if (list != NULL) { GSList *tmp; for (tmp = g_slist_next(list); tmp != NULL; tmp = g_slist_next(tmp)) silc_client_command_call(silc_client, conn, tmp->data); g_slist_foreach(list, (GFunc) cmd_list_remove_cb, NULL); /* free all but the first element ... */ g_slist_free(g_slist_remove_link(list, list)); } } void silc_queue_enable(SilcClientConnection conn) { GSList *list = g_hash_table_lookup(cmd_queues, conn); if (list == NULL) g_hash_table_insert(cmd_queues, conn, g_slist_alloc()); } void silc_queue_disable(SilcClientConnection conn) { GSList *list = g_hash_table_lookup(cmd_queues, conn); if (list != NULL) { silc_queue_flush(conn); g_slist_free(list); g_hash_table_remove(cmd_queues, conn); } } bool silc_queue_command_call(SilcClient client, SilcClientConnection conn, const char *command_line, ...) { va_list ap; char *cmd = (char *) command_line; GSList *list = g_hash_table_lookup(cmd_queues, conn); bool need_free = FALSE; va_start(ap, command_line); if (command_line == NULL) { char *tmp = va_arg(ap, char *); need_free = TRUE; if (tmp == NULL) { va_end(ap); return FALSE; } cmd = g_strdup(tmp); for (tmp = va_arg(ap, char *); tmp != NULL; tmp = va_arg(ap, char *)) { char *old = cmd; cmd = g_strconcat(cmd, " ", tmp, NULL); g_free(old); } } va_end(ap); if (!silc_term_utf8()) { int len = silc_utf8_encoded_len(cmd, strlen(cmd), SILC_STRING_LOCALE); char *message = silc_calloc(len + 1, sizeof(*cmd)); if (message == NULL) { if (need_free) g_free(cmd); g_error("file %s: line %d: assertion `message != NULL' failed.", __FILE__, __LINE__); return FALSE; } silc_utf8_encode(cmd, strlen(cmd), SILC_STRING_LOCALE, message, len); if (need_free) g_free(cmd); need_free = TRUE; cmd = g_strdup(message); silc_free(message); } /* queueing disabled -> immediate execution */ if (list == NULL) { bool result = silc_client_command_call(client, conn, cmd); if (need_free) g_free(cmd); return result; } g_hash_table_remove(cmd_queues, conn); g_hash_table_insert(cmd_queues, conn, g_slist_append(list, g_strdup(cmd))); if (need_free) g_free(cmd); return TRUE; } bool silc_queue_get_state(SilcClientConnection conn) { return g_hash_table_lookup(cmd_queues, conn) != NULL; }