Merged silc_1_0_branch to trunk.
[silc.git] / apps / irssi / src / silc / core / silc-cmdqueue.c
1 #include "module.h"
2 #include "silc-cmdqueue.h"
3
4 #include <stdarg.h>
5
6 GHashTable *cmd_queues;
7
8 void silc_queue_init(void)
9 {
10   cmd_queues = g_hash_table_new(NULL, NULL);
11 }
12
13 static void cmd_list_remove_cb(char *cmd)
14 {
15   g_free(cmd);
16 }
17
18 static int cmd_queue_remove_cb(void *key, GSList *list)
19 {
20   if ((list != NULL) && (list->next != NULL)) {
21     g_slist_foreach(list, (GFunc) cmd_list_remove_cb, NULL);
22     g_slist_free(list);
23   }
24
25   return TRUE;
26 }
27
28 void silc_queue_deinit(void)
29 {
30   g_hash_table_foreach_remove(cmd_queues, (GHRFunc) cmd_queue_remove_cb, NULL);
31   g_hash_table_destroy(cmd_queues);
32 }
33
34 void silc_queue_flush(SilcClientConnection conn)
35 {
36   GSList *list = g_hash_table_lookup(cmd_queues, conn);
37
38   if (list != NULL) {
39     GSList *tmp;
40
41     for (tmp = g_slist_next(list); tmp != NULL; tmp = g_slist_next(tmp))
42       silc_client_command_call(silc_client, conn, tmp->data);
43
44     g_slist_foreach(list, (GFunc) cmd_list_remove_cb, NULL);
45     /* free all but the first element ... */
46     g_slist_free(g_slist_remove_link(list, list));
47   }
48 }
49
50 void silc_queue_enable(SilcClientConnection conn)
51 {
52   GSList *list = g_hash_table_lookup(cmd_queues, conn);
53
54   if (list == NULL)
55     g_hash_table_insert(cmd_queues, conn, g_slist_alloc());
56 }
57
58 void silc_queue_disable(SilcClientConnection conn)
59 {
60   GSList *list = g_hash_table_lookup(cmd_queues, conn);
61
62    if (list != NULL) {
63      silc_queue_flush(conn);
64      g_slist_free(list);
65      g_hash_table_remove(cmd_queues, conn);
66    }
67 }
68
69 bool silc_queue_command_call(SilcClient client,
70                         SilcClientConnection conn,
71                         const char *command_line, ...)
72 {
73   va_list ap;
74   char *cmd = (char *) command_line;
75   GSList *list = g_hash_table_lookup(cmd_queues, conn);
76   bool need_free = FALSE;
77
78   va_start(ap, command_line);
79
80   if (command_line == NULL) {
81     char *tmp = va_arg(ap, char *);
82
83     need_free = TRUE;
84
85     if (tmp == NULL) {
86       va_end(ap);
87       return FALSE;
88     }
89
90     cmd = g_strdup(tmp);
91
92     for (tmp = va_arg(ap, char *); tmp != NULL; tmp = va_arg(ap, char *)) {
93       char *old = cmd;
94
95       cmd = g_strconcat(cmd, " ", tmp, NULL);
96       g_free(old);
97     }
98
99   }
100
101   va_end(ap);
102
103   if (!silc_term_utf8()) {
104     int len = silc_utf8_encoded_len(cmd, strlen(cmd), SILC_STRING_LOCALE);
105     char *message = silc_calloc(len + 1, sizeof(*cmd));
106     if (message == NULL) {
107
108       if (need_free)
109         g_free(cmd);
110
111       g_error("file %s: line %d: assertion `message != NULL' failed.",
112                  __FILE__, __LINE__);
113
114       return FALSE;
115     }
116     silc_utf8_encode(cmd, strlen(cmd), SILC_STRING_LOCALE, message, len);
117
118     if (need_free)
119       g_free(cmd);
120
121     need_free = TRUE;
122     cmd = g_strdup(message);
123
124     silc_free(message);
125   }
126
127   /* queueing disabled -> immediate execution */
128   if (list == NULL) {
129     bool result = silc_client_command_call(client, conn, cmd);
130
131     if (need_free)
132       g_free(cmd);
133
134     return result;
135   }
136
137   g_hash_table_remove(cmd_queues, conn);
138   g_hash_table_insert(cmd_queues, conn, g_slist_append(list, g_strdup(cmd)));
139
140   if (need_free)
141     g_free(cmd);
142
143   return TRUE;
144 }
145
146 bool silc_queue_get_state(SilcClientConnection conn) {
147   return g_hash_table_lookup(cmd_queues, conn) != NULL;
148 }