1 /*
2 servers-setup.c : irssi
3
4 Copyright (C) 1999-2001 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 "signals.h"
23 #include "network.h"
24 #include "lib-config/iconfig.h"
25 #include "settings.h"
26
27 #include "chat-protocols.h"
28 #include "chatnets.h"
29 #include "servers.h"
30 #include "servers-setup.h"
31
32 GSList *setupservers;
33
34 static char *old_source_host;
35 int source_host_ok; /* Use source_host_ip .. */
36 IPADDR *source_host_ip4, *source_host_ip6; /* Resolved address */
37
save_ips(IPADDR * ip4,IPADDR * ip6,IPADDR ** save_ip4,IPADDR ** save_ip6)38 static void save_ips(IPADDR *ip4, IPADDR *ip6,
39 IPADDR **save_ip4, IPADDR **save_ip6)
40 {
41 if (ip4->family == 0)
42 g_free_and_null(*save_ip4);
43 else {
44 if (*save_ip4 == NULL)
45 *save_ip4 = g_new(IPADDR, 1);
46 memcpy(*save_ip4, ip4, sizeof(IPADDR));
47 }
48
49 if (ip6->family == 0)
50 g_free_and_null(*save_ip6);
51 else {
52 if (*save_ip6 == NULL)
53 *save_ip6 = g_new(IPADDR, 1);
54 memcpy(*save_ip6, ip6, sizeof(IPADDR));
55 }
56 }
57
get_source_host_ip(void)58 static void get_source_host_ip(void)
59 {
60 const char *hostname;
61 IPADDR ip4, ip6;
62
63 if (source_host_ok)
64 return;
65
66 /* FIXME: This will block! */
67 hostname = settings_get_str("hostname");
68 source_host_ok = *hostname != '\0' &&
69 net_gethostbyname(hostname, &ip4, &ip6) == 0;
70
71 if (source_host_ok)
72 save_ips(&ip4, &ip6, &source_host_ip4, &source_host_ip6);
73 else {
74 g_free_and_null(source_host_ip4);
75 g_free_and_null(source_host_ip6);
76 }
77 }
78
conn_set_ip(SERVER_CONNECT_REC * conn,const char * own_host,IPADDR ** own_ip4,IPADDR ** own_ip6)79 static void conn_set_ip(SERVER_CONNECT_REC *conn, const char *own_host,
80 IPADDR **own_ip4, IPADDR **own_ip6)
81 {
82 IPADDR ip4, ip6;
83
84 if (*own_ip4 == NULL && *own_ip6 == NULL) {
85 /* resolve the IP */
86 if (net_gethostbyname(own_host, &ip4, &ip6) == 0)
87 save_ips(&ip4, &ip6, own_ip4, own_ip6);
88 }
89
90 server_connect_own_ip_save(conn, *own_ip4, *own_ip6);
91 }
92
93 /* Fill information to connection from server setup record */
server_setup_fill_reconn(SERVER_CONNECT_REC * conn,SERVER_SETUP_REC * sserver)94 void server_setup_fill_reconn(SERVER_CONNECT_REC *conn,
95 SERVER_SETUP_REC *sserver)
96 {
97 g_return_if_fail(IS_SERVER_CONNECT(conn));
98 g_return_if_fail(IS_SERVER_SETUP(sserver));
99
100 if (sserver->own_host != NULL) {
101 conn_set_ip(conn, sserver->own_host,
102 &sserver->own_ip4, &sserver->own_ip6);
103 }
104
105 if (sserver->chatnet != NULL && conn->chatnet == NULL)
106 conn->chatnet = g_strdup(sserver->chatnet);
107
108 if (sserver->password != NULL && conn->password == NULL)
109 conn->password = g_strdup(sserver->password);
110
111 if (sserver->no_proxy)
112 g_free_and_null(conn->proxy);
113
114 if (sserver->family != 0 && conn->family == 0)
115 conn->family = sserver->family;
116 if (sserver->address && !conn->address)
117 conn->address = g_strdup(sserver->address);
118 if (sserver->port > 0 && conn->port <= 0)
119 conn->port = sserver->port;
120
121 conn->use_tls = sserver->use_tls;
122 if (conn->tls_cert == NULL && sserver->tls_cert != NULL && sserver->tls_cert[0] != '\0')
123 conn->tls_cert = g_strdup(sserver->tls_cert);
124 if (conn->tls_pkey == NULL && sserver->tls_pkey != NULL && sserver->tls_pkey[0] != '\0')
125 conn->tls_pkey = g_strdup(sserver->tls_pkey);
126 if (conn->tls_pass == NULL && sserver->tls_pass != NULL && sserver->tls_pass[0] != '\0')
127 conn->tls_pass = g_strdup(sserver->tls_pass);
128 conn->tls_verify = sserver->tls_verify;
129 if (conn->tls_cafile == NULL && sserver->tls_cafile != NULL && sserver->tls_cafile[0] != '\0')
130 conn->tls_cafile = g_strdup(sserver->tls_cafile);
131 if (conn->tls_capath == NULL && sserver->tls_capath != NULL && sserver->tls_capath[0] != '\0')
132 conn->tls_capath = g_strdup(sserver->tls_capath);
133 if (conn->tls_ciphers == NULL && sserver->tls_ciphers != NULL && sserver->tls_ciphers[0] != '\0')
134 conn->tls_ciphers = g_strdup(sserver->tls_ciphers);
135 if (conn->tls_pinned_cert == NULL && sserver->tls_pinned_cert != NULL && sserver->tls_pinned_cert[0] != '\0')
136 conn->tls_pinned_cert = g_strdup(sserver->tls_pinned_cert);
137 if (conn->tls_pinned_pubkey == NULL && sserver->tls_pinned_pubkey != NULL && sserver->tls_pinned_pubkey[0] != '\0')
138 conn->tls_pinned_pubkey = g_strdup(sserver->tls_pinned_pubkey);
139
140 signal_emit("server setup fill reconn", 2, conn, sserver);
141 }
142
server_setup_fill(SERVER_CONNECT_REC * conn,const char * address,int port)143 static void server_setup_fill(SERVER_CONNECT_REC *conn,
144 const char *address, int port)
145 {
146 g_return_if_fail(conn != NULL);
147 g_return_if_fail(address != NULL);
148
149 conn->type = module_get_uniq_id("SERVER CONNECT", 0);
150
151 conn->address = g_strdup(address);
152 if (port > 0) conn->port = port;
153
154 if (strchr(address, '/') != NULL)
155 conn->unix_socket = TRUE;
156
157 if (!conn->nick) conn->nick = g_strdup(settings_get_str("nick"));
158 conn->username = g_strdup(settings_get_str("user_name"));
159 conn->realname = g_strdup(settings_get_str("real_name"));
160
161 /* proxy settings */
162 if (settings_get_bool("use_proxy")) {
163 conn->proxy = g_strdup(settings_get_str("proxy_address"));
164 conn->proxy_port = settings_get_int("proxy_port");
165 conn->proxy_string = g_strdup(settings_get_str("proxy_string"));
166 conn->proxy_string_after = g_strdup(settings_get_str("proxy_string_after"));
167 conn->proxy_password = g_strdup(settings_get_str("proxy_password"));
168 }
169
170 /* source IP */
171 if (source_host_ip4 != NULL) {
172 conn->own_ip4 = g_new(IPADDR, 1);
173 memcpy(conn->own_ip4, source_host_ip4, sizeof(IPADDR));
174 }
175 if (source_host_ip6 != NULL) {
176 conn->own_ip6 = g_new(IPADDR, 1);
177 memcpy(conn->own_ip6, source_host_ip6, sizeof(IPADDR));
178 }
179
180 signal_emit("server setup fill connect", 1, conn);
181 }
182
server_setup_fill_server(SERVER_CONNECT_REC * conn,SERVER_SETUP_REC * sserver)183 static void server_setup_fill_server(SERVER_CONNECT_REC *conn,
184 SERVER_SETUP_REC *sserver)
185 {
186 g_return_if_fail(IS_SERVER_CONNECT(conn));
187 g_return_if_fail(IS_SERVER_SETUP(sserver));
188
189 sserver->last_connect = time(NULL);
190
191 server_setup_fill_reconn(conn, sserver);
192
193 signal_emit("server setup fill server", 2, conn, sserver);
194 }
195
server_setup_fill_chatnet(SERVER_CONNECT_REC * conn,CHATNET_REC * chatnet)196 static void server_setup_fill_chatnet(SERVER_CONNECT_REC *conn,
197 CHATNET_REC *chatnet)
198 {
199 g_return_if_fail(IS_SERVER_CONNECT(conn));
200 g_return_if_fail(IS_CHATNET(chatnet));
201
202 if (chatnet->nick != NULL) {
203 g_free(conn->nick);
204 conn->nick = g_strdup(chatnet->nick);;
205 }
206 if (chatnet->username != NULL) {
207 g_free(conn->username);
208 conn->username = g_strdup(chatnet->username);;
209 }
210 if (chatnet->realname != NULL) {
211 g_free(conn->realname);
212 conn->realname = g_strdup(chatnet->realname);;
213 }
214 if (chatnet->own_host != NULL) {
215 conn_set_ip(conn, chatnet->own_host,
216 &chatnet->own_ip4, &chatnet->own_ip6);
217 }
218
219 signal_emit("server setup fill chatnet", 2, conn, chatnet);
220 }
221
222 static SERVER_CONNECT_REC *
create_addr_conn(int chat_type,const char * address,int port,const char * chatnet,const char * password,const char * nick)223 create_addr_conn(int chat_type, const char *address, int port,
224 const char *chatnet, const char *password,
225 const char *nick)
226 {
227 CHAT_PROTOCOL_REC *proto;
228 SERVER_CONNECT_REC *conn;
229 SERVER_SETUP_REC *sserver;
230 CHATNET_REC *chatnetrec;
231
232 g_return_val_if_fail(address != NULL, NULL);
233
234 sserver = server_setup_find(address, port, chatnet);
235 if (sserver != NULL) {
236 if (chat_type < 0)
237 chat_type = sserver->chat_type;
238 else if (chat_type != sserver->chat_type)
239 sserver = NULL;
240 }
241
242 proto = chat_type >= 0 ? chat_protocol_find_id(chat_type) :
243 chat_protocol_get_default();
244
245 conn = proto->create_server_connect();
246 server_connect_ref(conn);
247
248 conn->chat_type = proto->id;
249 if (chatnet != NULL && *chatnet != '\0')
250 conn->chatnet = g_strdup(chatnet);
251
252 /* fill in the defaults */
253 server_setup_fill(conn, address, port);
254
255 /* fill the rest from chat network settings */
256 chatnetrec = chatnet != NULL ? chatnet_find(chatnet) :
257 (sserver == NULL || sserver->chatnet == NULL ? NULL :
258 chatnet_find(sserver->chatnet));
259 if (chatnetrec != NULL)
260 server_setup_fill_chatnet(conn, chatnetrec);
261
262 /* fill the information from setup */
263 if (sserver != NULL)
264 server_setup_fill_server(conn, sserver);
265
266 /* nick / password given in command line overrides all settings */
267 if (password && *password) {
268 g_free_not_null(conn->password);
269 conn->password = g_strdup(password);
270 }
271 if (nick && *nick) {
272 g_free_not_null(conn->nick);
273 conn->nick = g_strdup(nick);
274 }
275
276 return conn;
277 }
278
279 /* Connect to server where last connect succeeded (or we haven't tried to
280 connect yet). If there's no such server, connect to server where we
281 haven't connected for the longest time */
282 static SERVER_CONNECT_REC *
create_chatnet_conn(const char * dest,int port,const char * password,const char * nick)283 create_chatnet_conn(const char *dest, int port,
284 const char *password, const char *nick)
285 {
286 SERVER_SETUP_REC *bestrec;
287 GSList *tmp;
288 time_t now, besttime;
289
290 now = time(NULL);
291 bestrec = NULL; besttime = now;
292 for (tmp = setupservers; tmp != NULL; tmp = tmp->next) {
293 SERVER_SETUP_REC *rec = tmp->data;
294
295 if (rec->chatnet == NULL ||
296 g_ascii_strcasecmp(rec->chatnet, dest) != 0)
297 continue;
298
299 if (!rec->last_failed) {
300 bestrec = rec;
301 break;
302 }
303
304 if (bestrec == NULL || besttime > rec->last_connect) {
305 bestrec = rec;
306 besttime = rec->last_connect;
307 }
308 }
309
310 return bestrec == NULL ? NULL :
311 create_addr_conn(bestrec->chat_type, bestrec->address, 0,
312 dest, NULL, nick);
313 }
314
315 /* Create server connection record. `dest' is required, rest can be NULL.
316 `dest' is either a server address or chat network */
317 SERVER_CONNECT_REC *
server_create_conn(int chat_type,const char * dest,int port,const char * chatnet,const char * password,const char * nick)318 server_create_conn(int chat_type, const char *dest, int port,
319 const char *chatnet, const char *password,
320 const char *nick)
321 {
322 SERVER_CONNECT_REC *rec;
323 CHATNET_REC *chatrec;
324
325 g_return_val_if_fail(dest != NULL, NULL);
326
327 chatrec = chatnet_find(dest);
328 if (chatrec != NULL) {
329 rec = create_chatnet_conn(chatrec->name, port, password, nick);
330 /* If rec is NULL the chatnet has no url to connect to */
331 return rec;
332 }
333
334 chatrec = chatnet == NULL ? NULL : chatnet_find(chatnet);
335 if (chatrec != NULL)
336 chatnet = chatrec->name;
337
338 return create_addr_conn(chat_type, dest, port,
339 chatnet, password, nick);
340 }
341
342 /* Find matching server from setup. Try to find record with a same port,
343 but fallback to any server with the same address. */
server_setup_find(const char * address,int port,const char * chatnet)344 SERVER_SETUP_REC *server_setup_find(const char *address, int port,
345 const char *chatnet)
346 {
347 SERVER_SETUP_REC *server;
348 GSList *tmp;
349
350 g_return_val_if_fail(address != NULL, NULL);
351
352 server = NULL;
353 for (tmp = setupservers; tmp != NULL; tmp = tmp->next) {
354 SERVER_SETUP_REC *rec = tmp->data;
355
356 if (g_ascii_strcasecmp(rec->address, address) == 0 &&
357 (chatnet == NULL || rec->chatnet == NULL ||
358 g_ascii_strcasecmp(rec->chatnet, chatnet) == 0)) {
359 server = rec;
360 if (rec->port == port)
361 break;
362 }
363 }
364
365 return server;
366 }
367
server_setup_read(CONFIG_NODE * node)368 static SERVER_SETUP_REC *server_setup_read(CONFIG_NODE *node)
369 {
370 SERVER_SETUP_REC *rec;
371 CHATNET_REC *chatnetrec;
372 char *server, *chatnet, *family;
373 int port;
374 char *value = NULL;
375
376 g_return_val_if_fail(node != NULL, NULL);
377
378 server = config_node_get_str(node, "address", NULL);
379 if (server == NULL)
380 return NULL;
381
382 port = config_node_get_int(node, "port", 0);
383 chatnet = config_node_get_str(node, "chatnet", NULL);
384
385 if (server_setup_find(server, port, chatnet) != NULL) {
386 return NULL;
387 }
388
389 rec = NULL;
390
391 chatnetrec = chatnet == NULL ? NULL : chatnet_find(chatnet);
392 if (chatnetrec == NULL && chatnet != NULL) {
393 /* chat network not found, create it. */
394 chatnetrec = chat_protocol_get_default()->create_chatnet();
395 chatnetrec->chat_type = chat_protocol_get_default()->id;
396 chatnetrec->name = g_strdup(chatnet);
397 chatnet_create(chatnetrec);
398 }
399
400 family = config_node_get_str(node, "family", "");
401
402 rec = CHAT_PROTOCOL(chatnetrec)->create_server_setup();
403 rec->type = module_get_uniq_id("SERVER SETUP", 0);
404 rec->chat_type = CHAT_PROTOCOL(chatnetrec)->id;
405 rec->chatnet = chatnetrec == NULL ? NULL : g_strdup(chatnetrec->name);
406 rec->family = g_ascii_strcasecmp(family, "inet6") == 0 ? AF_INET6 :
407 (g_ascii_strcasecmp(family, "inet") == 0 ? AF_INET : 0);
408 rec->address = g_strdup(server);
409 rec->password = g_strdup(config_node_get_str(node, "password", NULL));
410
411 rec->use_tls = config_node_get_bool(node, "use_tls", FALSE) || config_node_get_bool(node, "use_ssl", FALSE);
412 rec->tls_verify = config_node_get_bool(node, "tls_verify", FALSE) || config_node_get_bool(node, "ssl_verify", FALSE);
413
414 value = config_node_get_str(node, "tls_cert", NULL);
415 if (value == NULL)
416 value = config_node_get_str(node, "ssl_cert", NULL);
417 rec->tls_cert = g_strdup(value);
418
419 value = config_node_get_str(node, "tls_pkey", NULL);
420 if (value == NULL)
421 value = config_node_get_str(node, "ssl_pkey", NULL);
422 rec->tls_pkey = g_strdup(value);
423
424 value = config_node_get_str(node, "tls_pass", NULL);
425 if (value == NULL)
426 value = config_node_get_str(node, "ssl_pass", NULL);
427 rec->tls_pass = g_strdup(value);
428
429 value = config_node_get_str(node, "tls_cafile", NULL);
430 if (value == NULL)
431 value = config_node_get_str(node, "ssl_cafile", NULL);
432 rec->tls_cafile = g_strdup(value);
433
434 value = config_node_get_str(node, "tls_capath", NULL);
435 if (value == NULL)
436 value = config_node_get_str(node, "ssl_capath", NULL);
437 rec->tls_capath = g_strdup(value);
438
439 value = config_node_get_str(node, "tls_ciphers", NULL);
440 if (value == NULL)
441 value = config_node_get_str(node, "ssl_ciphers", NULL);
442 rec->tls_ciphers = g_strdup(value);
443
444 value = config_node_get_str(node, "tls_pinned_cert", NULL);
445 if (value == NULL)
446 value = config_node_get_str(node, "ssl_pinned_cert", NULL);
447 rec->tls_pinned_cert = g_strdup(value);
448
449 value = config_node_get_str(node, "tls_pinned_pubkey", NULL);
450 if (value == NULL)
451 value = config_node_get_str(node, "ssl_pinned_pubkey", NULL);
452 rec->tls_pinned_pubkey = g_strdup(value);
453
454 if (rec->tls_cafile || rec->tls_capath)
455 rec->tls_verify = TRUE;
456 if (rec->tls_cert != NULL || rec->tls_verify)
457 rec->use_tls = TRUE;
458
459 rec->port = port;
460 rec->autoconnect = config_node_get_bool(node, "autoconnect", FALSE);
461 rec->no_proxy = config_node_get_bool(node, "no_proxy", FALSE);
462 rec->own_host = g_strdup(config_node_get_str(node, "own_host", NULL));
463
464 signal_emit("server setup read", 2, rec, node);
465
466 setupservers = g_slist_append(setupservers, rec);
467 return rec;
468 }
469
compare_server_setup(CONFIG_NODE * node,SERVER_SETUP_REC * server)470 static int compare_server_setup (CONFIG_NODE *node, SERVER_SETUP_REC *server)
471 {
472 char *address, *chatnet;
473 int port;
474
475 address = config_node_get_str(node, "address", NULL);
476 chatnet = config_node_get_str(node, "chatnet", NULL);
477 port = config_node_get_int(node, "port", 0);
478
479 if (address == NULL || chatnet == NULL) {
480 return 0;
481 }
482
483 if (g_ascii_strcasecmp(address, server->address) != 0 ||
484 g_ascii_strcasecmp(chatnet, server->chatnet) != 0 ||
485 port != server->port) {
486 return 1;
487 }
488
489 return 0;
490 }
491
server_setup_save(SERVER_SETUP_REC * rec)492 static void server_setup_save(SERVER_SETUP_REC *rec)
493 {
494 CONFIG_NODE *parent_node, *node;
495 GSList *config_node;
496
497 parent_node = iconfig_node_traverse("(servers", TRUE);
498
499 /* Try to find this channel in the configuration */
500 config_node = g_slist_find_custom(parent_node->value, rec,
501 (GCompareFunc)compare_server_setup);
502 if (config_node != NULL)
503 /* Let's update this server record */
504 node = config_node->data;
505 else
506 /* Create a brand-new server record */
507 node = iconfig_node_section(parent_node, NULL, NODE_TYPE_BLOCK);
508
509 iconfig_node_clear(node);
510 iconfig_node_set_str(node, "address", rec->address);
511 iconfig_node_set_str(node, "chatnet", rec->chatnet);
512
513 iconfig_node_set_int(node, "port", rec->port);
514 iconfig_node_set_str(node, "password", rec->password);
515
516 iconfig_node_set_bool(node, "use_tls", rec->use_tls);
517 iconfig_node_set_str(node, "tls_cert", rec->tls_cert);
518 iconfig_node_set_str(node, "tls_pkey", rec->tls_pkey);
519 iconfig_node_set_str(node, "tls_pass", rec->tls_pass);
520 iconfig_node_set_bool(node, "tls_verify", rec->tls_verify);
521 iconfig_node_set_str(node, "tls_cafile", rec->tls_cafile);
522 iconfig_node_set_str(node, "tls_capath", rec->tls_capath);
523 iconfig_node_set_str(node, "tls_ciphers", rec->tls_ciphers);
524 iconfig_node_set_str(node, "tls_pinned_cert", rec->tls_pinned_cert);
525 iconfig_node_set_str(node, "tls_pinned_pubkey", rec->tls_pinned_pubkey);
526
527 iconfig_node_set_str(node, "own_host", rec->own_host);
528
529 iconfig_node_set_str(node, "family",
530 rec->family == AF_INET6 ? "inet6" :
531 rec->family == AF_INET ? "inet" : NULL);
532
533 if (rec->autoconnect)
534 iconfig_node_set_bool(node, "autoconnect", TRUE);
535 if (rec->no_proxy)
536 iconfig_node_set_bool(node, "no_proxy", TRUE);
537
538 signal_emit("server setup saved", 2, rec, node);
539 }
540
server_setup_remove_config(SERVER_SETUP_REC * rec)541 static void server_setup_remove_config(SERVER_SETUP_REC *rec)
542 {
543 CONFIG_NODE *parent_node;
544 GSList *config_node;
545
546 parent_node = iconfig_node_traverse("servers", FALSE);
547
548 if (parent_node == NULL)
549 return;
550
551 /* Try to find this server in the configuration */
552 config_node = g_slist_find_custom(parent_node->value, rec,
553 (GCompareFunc)compare_server_setup);
554
555 if (config_node != NULL)
556 /* Delete the server from the configuration */
557 iconfig_node_remove(parent_node, config_node->data);
558 }
559
server_setup_destroy(SERVER_SETUP_REC * rec)560 static void server_setup_destroy(SERVER_SETUP_REC *rec)
561 {
562 setupservers = g_slist_remove(setupservers, rec);
563 signal_emit("server setup destroyed", 1, rec);
564
565 g_free_not_null(rec->own_host);
566 g_free_not_null(rec->own_ip4);
567 g_free_not_null(rec->own_ip6);
568 g_free_not_null(rec->chatnet);
569 g_free_not_null(rec->password);
570 g_free_not_null(rec->tls_cert);
571 g_free_not_null(rec->tls_pkey);
572 g_free_not_null(rec->tls_pass);
573 g_free_not_null(rec->tls_cafile);
574 g_free_not_null(rec->tls_capath);
575 g_free_not_null(rec->tls_ciphers);
576 g_free_not_null(rec->tls_pinned_cert);
577 g_free_not_null(rec->tls_pinned_pubkey);
578 g_free(rec->address);
579 g_free(rec);
580 }
581
server_setup_add(SERVER_SETUP_REC * rec)582 void server_setup_add(SERVER_SETUP_REC *rec)
583 {
584 rec->type = module_get_uniq_id("SERVER SETUP", 0);
585 if (g_slist_find(setupservers, rec) == NULL)
586 setupservers = g_slist_append(setupservers, rec);
587 server_setup_save(rec);
588
589 signal_emit("server setup updated", 1, rec);
590 }
591
server_setup_remove_chatnet(const char * chatnet)592 void server_setup_remove_chatnet(const char *chatnet)
593 {
594 GSList *tmp, *next;
595
596 g_return_if_fail(chatnet != NULL);
597
598 for (tmp = setupservers; tmp != NULL; tmp = next) {
599 SERVER_SETUP_REC *rec = tmp->data;
600
601 next = tmp->next;
602 if (g_ascii_strcasecmp(rec->chatnet, chatnet) == 0)
603 server_setup_remove(rec);
604 }
605 }
606
server_setup_remove(SERVER_SETUP_REC * rec)607 void server_setup_remove(SERVER_SETUP_REC *rec)
608 {
609 server_setup_remove_config(rec);
610 server_setup_destroy(rec);
611 }
612
read_servers(void)613 static void read_servers(void)
614 {
615 CONFIG_NODE *node;
616 GSList *tmp;
617
618 while (setupservers != NULL)
619 server_setup_destroy(setupservers->data);
620
621 /* Read servers */
622 node = iconfig_node_traverse("servers", FALSE);
623 if (node != NULL) {
624 tmp = config_node_first(node->value);
625 for (; tmp != NULL; tmp = config_node_next(tmp))
626 server_setup_read(tmp->data);
627 }
628 }
629
read_settings(void)630 static void read_settings(void)
631 {
632 if (old_source_host == NULL ||
633 g_strcmp0(old_source_host, settings_get_str("hostname")) != 0) {
634 g_free_not_null(old_source_host);
635 old_source_host = g_strdup(settings_get_str("hostname"));
636
637 source_host_ok = FALSE;
638 get_source_host_ip();
639 }
640 }
641
servers_setup_init(void)642 void servers_setup_init(void)
643 {
644 settings_add_str("server", "hostname", "");
645
646 settings_add_str("server", "nick", NULL);
647 settings_add_str("server", "user_name", NULL);
648 settings_add_str("server", "real_name", NULL);
649
650 settings_add_bool("proxy", "use_proxy", FALSE);
651 settings_add_str("proxy", "proxy_address", "");
652 settings_add_int("proxy", "proxy_port", 6667);
653 settings_add_str("proxy", "proxy_string", "CONNECT %s %d");
654 settings_add_str("proxy", "proxy_string_after", "");
655 settings_add_str("proxy", "proxy_password", "");
656
657 setupservers = NULL;
658 source_host_ip4 = source_host_ip6 = NULL;
659 old_source_host = NULL;
660 read_settings();
661
662 signal_add("setup changed", (SIGNAL_FUNC) read_settings);
663 signal_add("setup reread", (SIGNAL_FUNC) read_servers);
664 signal_add("irssi init read settings", (SIGNAL_FUNC) read_servers);
665 }
666
servers_setup_deinit(void)667 void servers_setup_deinit(void)
668 {
669 g_free_not_null(source_host_ip4);
670 g_free_not_null(source_host_ip6);
671 g_free_not_null(old_source_host);
672
673 while (setupservers != NULL)
674 server_setup_destroy(setupservers->data);
675
676 signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
677 signal_remove("setup reread", (SIGNAL_FUNC) read_servers);
678 signal_remove("irssi init read settings", (SIGNAL_FUNC) read_servers);
679
680 module_uniq_destroy("SERVER SETUP");
681 }
682