/src/irssi/src/core/channels-setup.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | channels-setup.c : irssi |
3 | | |
4 | | Copyright (C) 1999-2000 Timo Sirainen |
5 | | |
6 | | This program is free software; you can redistribute it and/or modify |
7 | | it under the terms of the GNU General Public License as published by |
8 | | the Free Software Foundation; either version 2 of the License, or |
9 | | (at your option) any later version. |
10 | | |
11 | | This program is distributed in the hope that it will be useful, |
12 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | GNU General Public License for more details. |
15 | | |
16 | | You should have received a copy of the GNU General Public License along |
17 | | with this program; if not, write to the Free Software Foundation, Inc., |
18 | | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
19 | | */ |
20 | | |
21 | | #include "module.h" |
22 | | #include <irssi/src/core/signals.h> |
23 | | #include <irssi/src/lib-config/iconfig.h> |
24 | | #include <irssi/src/core/settings.h> |
25 | | |
26 | | #include <irssi/src/core/chat-protocols.h> |
27 | | #include <irssi/src/core/chatnets.h> |
28 | | #include <irssi/src/core/servers-setup.h> |
29 | | #include <irssi/src/core/channels-setup.h> |
30 | | |
31 | | GSList *setupchannels; |
32 | | |
33 | | static int compare_channel_setup (CONFIG_NODE *node, CHANNEL_SETUP_REC *channel) |
34 | 0 | { |
35 | 0 | char *name, *chatnet; |
36 | | |
37 | | /* skip comment nodes */ |
38 | 0 | if (node->type == NODE_TYPE_COMMENT) |
39 | 0 | return -1; |
40 | | |
41 | 0 | name = config_node_get_str(node, "name", NULL); |
42 | 0 | chatnet = config_node_get_str(node, "chatnet", NULL); |
43 | |
|
44 | 0 | if (name == NULL || chatnet == NULL) { |
45 | 0 | return 0; |
46 | 0 | } |
47 | | |
48 | 0 | if (g_ascii_strcasecmp(name, channel->name) != 0 || |
49 | 0 | g_ascii_strcasecmp(chatnet, channel->chatnet) != 0) { |
50 | 0 | return 1; |
51 | 0 | } |
52 | | |
53 | 0 | return 0; |
54 | 0 | } |
55 | | |
56 | | static void channel_setup_save(CHANNEL_SETUP_REC *channel) |
57 | 0 | { |
58 | 0 | CONFIG_NODE *parent_node, *node; |
59 | 0 | GSList *config_node; |
60 | |
|
61 | 0 | parent_node = iconfig_node_traverse("(channels", TRUE); |
62 | | |
63 | | /* Try to find this channel in the configuration */ |
64 | 0 | config_node = g_slist_find_custom(parent_node->value, channel, |
65 | 0 | (GCompareFunc)compare_channel_setup); |
66 | 0 | if (config_node != NULL) |
67 | | /* Let's update this channel record */ |
68 | 0 | node = config_node->data; |
69 | 0 | else |
70 | | /* Create a brand-new channel record */ |
71 | 0 | node = iconfig_node_section(parent_node, NULL, NODE_TYPE_BLOCK); |
72 | |
|
73 | 0 | iconfig_node_clear(node); |
74 | 0 | iconfig_node_set_str(node, "name", channel->name); |
75 | 0 | iconfig_node_set_str(node, "chatnet", channel->chatnet); |
76 | 0 | if (channel->autojoin) |
77 | 0 | iconfig_node_set_bool(node, "autojoin", TRUE); |
78 | 0 | iconfig_node_set_str(node, "password", channel->password); |
79 | 0 | iconfig_node_set_str(node, "botmasks", channel->botmasks); |
80 | 0 | iconfig_node_set_str(node, "autosendcmd", channel->autosendcmd); |
81 | 0 | } |
82 | | |
83 | | void channel_setup_create(CHANNEL_SETUP_REC *channel) |
84 | 0 | { |
85 | 0 | channel->type = module_get_uniq_id("CHANNEL SETUP", 0); |
86 | |
|
87 | 0 | if (g_slist_find(setupchannels, channel) == NULL) |
88 | 0 | setupchannels = g_slist_append(setupchannels, channel); |
89 | 0 | channel_setup_save(channel); |
90 | |
|
91 | 0 | signal_emit("channel setup created", 1, channel); |
92 | 0 | } |
93 | | |
94 | | static void channel_config_remove(CHANNEL_SETUP_REC *channel) |
95 | 0 | { |
96 | 0 | CONFIG_NODE *parent_node; |
97 | 0 | GSList *config_node; |
98 | |
|
99 | 0 | parent_node = iconfig_node_traverse("channels", FALSE); |
100 | |
|
101 | 0 | if (parent_node == NULL) |
102 | 0 | return; |
103 | | |
104 | | /* Try to find this channel in the configuration */ |
105 | 0 | config_node = g_slist_find_custom(parent_node->value, channel, |
106 | 0 | (GCompareFunc)compare_channel_setup); |
107 | |
|
108 | 0 | if (config_node != NULL) |
109 | | /* Delete the channel from the configuration */ |
110 | 0 | iconfig_node_remove(parent_node, config_node->data); |
111 | 0 | } |
112 | | |
113 | | static void channel_setup_destroy(CHANNEL_SETUP_REC *channel) |
114 | 0 | { |
115 | 0 | g_return_if_fail(channel != NULL); |
116 | | |
117 | 0 | setupchannels = g_slist_remove(setupchannels, channel); |
118 | 0 | signal_emit("channel setup destroyed", 1, channel); |
119 | |
|
120 | 0 | g_free_not_null(channel->chatnet); |
121 | 0 | g_free_not_null(channel->password); |
122 | 0 | g_free_not_null(channel->botmasks); |
123 | 0 | g_free_not_null(channel->autosendcmd); |
124 | 0 | g_free(channel->name); |
125 | 0 | g_free(channel); |
126 | 0 | } |
127 | | |
128 | | void channel_setup_remove_chatnet(const char *chatnet) |
129 | 0 | { |
130 | 0 | GSList *tmp, *next; |
131 | |
|
132 | 0 | g_return_if_fail(chatnet != NULL); |
133 | | |
134 | 0 | for (tmp = setupchannels; tmp != NULL; tmp = next) { |
135 | 0 | CHANNEL_SETUP_REC *rec = tmp->data; |
136 | |
|
137 | 0 | next = tmp->next; |
138 | 0 | if (g_ascii_strcasecmp(rec->chatnet, chatnet) == 0) |
139 | 0 | channel_setup_remove(rec); |
140 | 0 | } |
141 | 0 | } |
142 | | |
143 | | void channel_setup_remove(CHANNEL_SETUP_REC *channel) |
144 | 0 | { |
145 | 0 | channel_config_remove(channel); |
146 | 0 | channel_setup_destroy(channel); |
147 | 0 | } |
148 | | |
149 | | CHANNEL_SETUP_REC *channel_setup_find(const char *channel, |
150 | | const char *chatnet) |
151 | 33.2k | { |
152 | 33.2k | GSList *tmp; |
153 | | |
154 | 33.2k | g_return_val_if_fail(channel != NULL, NULL); |
155 | | |
156 | 299k | for (tmp = setupchannels; tmp != NULL; tmp = tmp->next) { |
157 | 265k | CHANNEL_SETUP_REC *rec = tmp->data; |
158 | | |
159 | 265k | if (g_ascii_strcasecmp(rec->name, channel) == 0 && |
160 | 265k | channel_chatnet_match(rec->chatnet, chatnet)) |
161 | 0 | return rec; |
162 | 265k | } |
163 | | |
164 | 33.2k | return NULL; |
165 | 33.2k | } |
166 | | |
167 | | static CHANNEL_SETUP_REC *channel_setup_read(CONFIG_NODE *node) |
168 | 18 | { |
169 | 18 | CHANNEL_SETUP_REC *rec; |
170 | 18 | CHATNET_REC *chatnetrec; |
171 | 18 | char *channel, *chatnet; |
172 | | |
173 | 18 | g_return_val_if_fail(node != NULL, NULL); |
174 | | |
175 | 18 | channel = config_node_get_str(node, "name", NULL); |
176 | 18 | chatnet = config_node_get_str(node, "chatnet", NULL); |
177 | | |
178 | 18 | chatnetrec = chatnet == NULL ? NULL : chatnet_find(chatnet); |
179 | 18 | if (channel == NULL || chatnetrec == NULL) { |
180 | | /* missing information.. */ |
181 | 2 | return NULL; |
182 | 2 | } |
183 | | |
184 | 16 | rec = CHAT_PROTOCOL(chatnetrec)->create_channel_setup(); |
185 | 16 | rec->type = module_get_uniq_id("CHANNEL SETUP", 0); |
186 | 16 | rec->chat_type = CHAT_PROTOCOL(chatnetrec)->id; |
187 | 16 | rec->autojoin = config_node_get_bool(node, "autojoin", FALSE); |
188 | 16 | rec->name = g_strdup(channel); |
189 | 16 | rec->chatnet = g_strdup(chatnetrec != NULL ? chatnetrec->name : chatnet); |
190 | 16 | rec->password = g_strdup(config_node_get_str(node, "password", NULL)); |
191 | 16 | rec->botmasks = g_strdup(config_node_get_str(node, "botmasks", NULL)); |
192 | 16 | rec->autosendcmd = g_strdup(config_node_get_str(node, "autosendcmd", NULL)); |
193 | | |
194 | 16 | setupchannels = g_slist_append(setupchannels, rec); |
195 | 16 | signal_emit("channel setup created", 2, rec, node); |
196 | 16 | return rec; |
197 | 18 | } |
198 | | |
199 | | static void channels_read_config(void) |
200 | 2 | { |
201 | 2 | CONFIG_NODE *node; |
202 | 2 | GSList *tmp; |
203 | | |
204 | 2 | while (setupchannels != NULL) |
205 | 0 | channel_setup_destroy(setupchannels->data); |
206 | | |
207 | | /* Read channels */ |
208 | 2 | node = iconfig_node_traverse("channels", FALSE); |
209 | 2 | if (node != NULL) { |
210 | 2 | int i = 0; |
211 | 2 | tmp = config_node_first(node->value); |
212 | 20 | for (; tmp != NULL; tmp = config_node_next(tmp), i++) { |
213 | 18 | node = tmp->data; |
214 | 18 | if (node->type != NODE_TYPE_BLOCK) { |
215 | 0 | g_critical("Expected block node at `channels[%d]' was of %s type. " |
216 | 0 | "Corrupt config?", |
217 | 0 | i, node->type == NODE_TYPE_LIST ? "list" : "scalar"); |
218 | 18 | } else { |
219 | 18 | channel_setup_read(node); |
220 | 18 | } |
221 | 18 | } |
222 | 2 | } |
223 | 2 | } |
224 | | |
225 | | void channels_setup_init(void) |
226 | 8 | { |
227 | 8 | setupchannels = NULL; |
228 | 8 | source_host_ok = FALSE; |
229 | | |
230 | 8 | signal_add("setup reread channels", (SIGNAL_FUNC) channels_read_config); |
231 | 8 | } |
232 | | |
233 | | void channels_setup_deinit(void) |
234 | 0 | { |
235 | 0 | while (setupchannels != NULL) |
236 | 0 | channel_setup_destroy(setupchannels->data); |
237 | |
|
238 | 0 | signal_remove("setup reread channels", (SIGNAL_FUNC) channels_read_config); |
239 | 0 | } |