Added SILC Thread Queue API
[runtime.git] / apps / irssi / src / core / core.c
1 /*
2  core.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
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "module.h"
22 #include <signal.h>
23
24 #include "args.h"
25 #include "pidwait.h"
26 #include "misc.h"
27
28 #include "net-disconnect.h"
29 #include "net-sendbuffer.h"
30 #include "signals.h"
31 #include "settings.h"
32 #include "session.h"
33
34 #include "chat-protocols.h"
35 #include "servers.h"
36 #include "chatnets.h"
37 #include "commands.h"
38 #include "expandos.h"
39 #include "write-buffer.h"
40 #include "log.h"
41 #include "rawlog.h"
42 #include "ignore.h"
43 #include "recode.h"
44
45 #include "channels.h"
46 #include "queries.h"
47 #include "nicklist.h"
48 #include "nickmatch-cache.h"
49
50 #ifdef HAVE_SYS_RESOURCE_H
51 #  include <sys/resource.h>
52    struct rlimit orig_core_rlimit;
53 #endif
54
55 void chat_commands_init(void);
56 void chat_commands_deinit(void);
57
58 void log_away_init(void);
59 void log_away_deinit(void);
60
61 int irssi_gui;
62 int irssi_init_finished;
63 int reload_config;
64 time_t client_start_time;
65
66 static char *irssi_dir, *irssi_config_file;
67 static GSList *dialog_type_queue, *dialog_text_queue;
68
69 const char *get_irssi_dir(void)
70 {
71         return irssi_dir;
72 }
73
74 /* return full path for ~/.irssi/config */
75 const char *get_irssi_config(void)
76 {
77         return irssi_config_file;
78 }
79
80 static void sig_reload_config(int signo)
81 {
82         reload_config = TRUE;
83 }
84
85 static void read_settings(void)
86 {
87 #ifndef WIN32
88         static int signals[] = {
89                 SIGINT, SIGQUIT, SIGTERM,
90                 SIGALRM, SIGUSR1, SIGUSR2
91         };
92         static char *signames[] = {
93                 "int", "quit", "term",
94                 "alrm", "usr1", "usr2"
95         };
96
97         const char *ignores;
98         struct sigaction act;
99         int n;
100
101         ignores = settings_get_str("ignore_signals");
102
103         sigemptyset (&act.sa_mask);
104         act.sa_flags = 0;
105
106         /* reload config on SIGHUP */
107         act.sa_handler = sig_reload_config;
108         sigaction(SIGHUP, &act, NULL);
109
110         for (n = 0; n < sizeof(signals)/sizeof(signals[0]); n++) {
111                 act.sa_handler = find_substr(ignores, signames[n]) ?
112                         SIG_IGN : SIG_DFL;
113                 sigaction(signals[n], &act, NULL);
114         }
115
116 #ifdef HAVE_SYS_RESOURCE_H
117         if (!settings_get_bool("override_coredump_limit"))
118                 setrlimit(RLIMIT_CORE, &orig_core_rlimit);
119         else {
120                 struct rlimit rlimit;
121
122                 rlimit.rlim_cur = RLIM_INFINITY;
123                 rlimit.rlim_max = RLIM_INFINITY;
124                 if (setrlimit(RLIMIT_CORE, &rlimit) == -1)
125                         settings_set_bool("override_coredump_limit", FALSE);
126         }
127 #endif
128 #endif
129 }
130
131 static void sig_gui_dialog(const char *type, const char *text)
132 {
133         dialog_type_queue = g_slist_append(dialog_type_queue, g_strdup(type));
134         dialog_text_queue = g_slist_append(dialog_text_queue, g_strdup(text));
135 }
136
137 static void sig_init_finished(void)
138 {
139         GSList *type, *text;
140
141         signal_remove("gui dialog", (SIGNAL_FUNC) sig_gui_dialog);
142         signal_remove("irssi init finished", (SIGNAL_FUNC) sig_init_finished);
143
144         /* send the dialog texts that were in queue before irssi
145            was initialized */
146         type = dialog_type_queue;
147         text = dialog_text_queue;
148         for (; text != NULL; text = text->next, type = type->next) {
149                 signal_emit("gui dialog", 2, type->data, text->data);
150                 g_free(type->data);
151                 g_free(text->data);
152         }
153         g_slist_free(dialog_type_queue);
154         g_slist_free(dialog_text_queue);
155 }
156
157 void core_init_paths(int argc, char *argv[])
158 {
159         static struct poptOption options[] = {
160                 { "config", 0, POPT_ARG_STRING, NULL, 0, "Configuration file location (~/.irssi/config)", "PATH" },
161                 { "home", 0, POPT_ARG_STRING, NULL, 0, "Irssi home dir location (~/.irssi)", "PATH" },
162                 { NULL, '\0', 0, NULL }
163         };
164         const char *home;
165         char *str;
166         int n, len;
167
168         for (n = 1; n < argc; n++) {
169                 if (strncmp(argv[n], "--home=", 7) == 0) {
170                         g_free_not_null(irssi_dir);
171                         irssi_dir = convert_home(argv[n]+7);
172                         len = strlen(irssi_dir);
173                         if (irssi_dir[len-1] == G_DIR_SEPARATOR)
174                                 irssi_dir[len-1] = '\0';
175                 } else if (strncmp(argv[n], "--config=", 9) == 0) {
176                         g_free_not_null(irssi_config_file);
177                         irssi_config_file = convert_home(argv[n]+9);
178                 }
179         }
180
181         if (irssi_dir != NULL && !g_path_is_absolute(irssi_dir)) {
182                 str = irssi_dir;
183                 irssi_dir = g_strdup_printf("%s/%s", g_get_current_dir(), str);
184                 g_free(str);
185         }
186
187         if (irssi_config_file != NULL &&
188             !g_path_is_absolute(irssi_config_file)) {
189                 str = irssi_config_file;
190                 irssi_config_file =
191                         g_strdup_printf("%s/%s", g_get_current_dir(), str);
192                 g_free(str);
193         }
194
195         args_register(options);
196
197         if (irssi_dir == NULL) {
198                 home = g_get_home_dir();
199                 if (home == NULL)
200                         home = ".";
201
202                 irssi_dir = g_strdup_printf(IRSSI_DIR_FULL, home);
203         }
204         if (irssi_config_file == NULL)
205                 irssi_config_file = g_strdup_printf("%s/"IRSSI_HOME_CONFIG, irssi_dir);
206
207         session_set_binary(argv[0]);
208 }
209
210 static void sig_irssi_init_finished(void)
211 {
212         irssi_init_finished = TRUE;
213 }
214
215 void core_init(int argc, char *argv[])
216 {
217         dialog_type_queue = NULL;
218         dialog_text_queue = NULL;
219         client_start_time = time(NULL);
220
221         modules_init();
222 #ifndef WIN32
223         pidwait_init();
224 #endif
225
226         net_disconnect_init();
227         net_sendbuffer_init();
228         signals_init();
229
230         signal_add_first("gui dialog", (SIGNAL_FUNC) sig_gui_dialog);
231         signal_add_first("irssi init finished", (SIGNAL_FUNC) sig_init_finished);
232
233         settings_init();
234         commands_init();
235         nickmatch_cache_init();
236         session_init();
237
238         chat_protocols_init();
239         chatnets_init();
240         expandos_init();
241         ignore_init();
242         servers_init();
243         write_buffer_init();
244         log_init();
245         log_away_init();
246         rawlog_init();
247         recode_init();
248
249         channels_init();
250         queries_init();
251         nicklist_init();
252
253         chat_commands_init();
254
255         settings_add_str("misc", "ignore_signals", "");
256         settings_add_bool("misc", "override_coredump_limit", FALSE);
257
258 #ifdef HAVE_SYS_RESOURCE_H
259         getrlimit(RLIMIT_CORE, &orig_core_rlimit);
260 #endif
261         read_settings();
262         signal_add("setup changed", (SIGNAL_FUNC) read_settings);
263         signal_add("irssi init finished", (SIGNAL_FUNC) sig_irssi_init_finished);
264
265         settings_check();
266
267         module_register("core", "core");
268 }
269
270 void core_deinit(void)
271 {
272         module_uniq_destroy("WINDOW ITEM TYPE");
273
274         signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
275         signal_remove("irssi init finished", (SIGNAL_FUNC) sig_irssi_init_finished);
276
277         chat_commands_deinit();
278
279         nicklist_deinit();
280         queries_deinit();
281         channels_deinit();
282
283         recode_deinit();
284         rawlog_deinit();
285         log_away_deinit();
286         log_deinit();
287         write_buffer_deinit();
288         servers_deinit();
289         ignore_deinit();
290         expandos_deinit();
291         chatnets_deinit();
292         chat_protocols_deinit();
293
294         session_deinit();
295         nickmatch_cache_deinit();
296         commands_deinit();
297         settings_deinit();
298         signals_deinit();
299         net_sendbuffer_deinit();
300         net_disconnect_deinit();
301
302 #ifndef WIN32
303         pidwait_deinit();
304 #endif
305         modules_deinit();
306
307         g_free(irssi_dir);
308         g_free(irssi_config_file);
309 }