1 /*
2 * LibSylph -- E-Mail client library
3 * Copyright (C) 1999-2010 Hiroyuki Yamamoto
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #ifdef HAVE_CONFIG_H
21 # include "config.h"
22 #endif
23
24 #include "defs.h"
25
26 #include <glib.h>
27 #include <glib/gi18n.h>
28
29 #ifdef G_OS_UNIX
30 # include <signal.h>
31 #endif
32
33 #if HAVE_LOCALE_H
34 # include <locale.h>
35 #endif
36
37 #include "sylmain.h"
38 #include "syl-marshal.h"
39 #include "prefs_common.h"
40 #include "account.h"
41 #include "filter.h"
42 #include "folder.h"
43 #include "socket.h"
44 #include "codeconv.h"
45 #include "utils.h"
46
47 #if USE_SSL
48 # include "ssl.h"
49 #endif
50
51 #ifndef PACKAGE
52 # define PACKAGE GETTEXT_PACKAGE
53 #endif
54
55 G_DEFINE_TYPE(SylApp, syl_app, G_TYPE_OBJECT);
56
57 enum {
58 INIT_DONE,
59 APP_EXIT,
60 APP_FORCE_EXIT,
61 ADD_MSG,
62 REMOVE_MSG,
63 REMOVE_ALL_MSG,
64 REMOVE_FOLDER,
65 MOVE_FOLDER,
66 FOLDERLIST_UPDATED,
67 ACCOUNT_UPDATED,
68 LAST_SIGNAL
69 };
70
71 static guint app_signals[LAST_SIGNAL] = { 0 };
72
73 static GObject *app = NULL;
74
75
syl_app_init(SylApp * self)76 static void syl_app_init(SylApp *self)
77 {
78 }
79
syl_app_class_init(SylAppClass * klass)80 static void syl_app_class_init(SylAppClass *klass)
81 {
82 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
83
84 app_signals[INIT_DONE] =
85 g_signal_new("init-done",
86 G_TYPE_FROM_CLASS(gobject_class),
87 G_SIGNAL_RUN_FIRST,
88 0,
89 NULL, NULL,
90 syl_marshal_VOID__VOID,
91 G_TYPE_NONE,
92 0);
93 app_signals[APP_EXIT] =
94 g_signal_new("app-exit",
95 G_TYPE_FROM_CLASS(gobject_class),
96 G_SIGNAL_RUN_FIRST,
97 0,
98 NULL, NULL,
99 syl_marshal_VOID__VOID,
100 G_TYPE_NONE,
101 0);
102 app_signals[APP_FORCE_EXIT] =
103 g_signal_new("app-force-exit",
104 G_TYPE_FROM_CLASS(gobject_class),
105 G_SIGNAL_RUN_FIRST,
106 0,
107 NULL, NULL,
108 syl_marshal_VOID__VOID,
109 G_TYPE_NONE,
110 0);
111 app_signals[ADD_MSG] =
112 g_signal_new("add-msg",
113 G_TYPE_FROM_CLASS(gobject_class),
114 G_SIGNAL_RUN_FIRST,
115 0,
116 NULL, NULL,
117 syl_marshal_VOID__POINTER_STRING_UINT,
118 G_TYPE_NONE,
119 3,
120 G_TYPE_POINTER,
121 G_TYPE_STRING,
122 G_TYPE_UINT);
123 app_signals[REMOVE_MSG] =
124 g_signal_new("remove-msg",
125 G_TYPE_FROM_CLASS(gobject_class),
126 G_SIGNAL_RUN_FIRST,
127 0,
128 NULL, NULL,
129 syl_marshal_VOID__POINTER_STRING_UINT,
130 G_TYPE_NONE,
131 3,
132 G_TYPE_POINTER,
133 G_TYPE_STRING,
134 G_TYPE_UINT);
135 app_signals[REMOVE_ALL_MSG] =
136 g_signal_new("remove-all-msg",
137 G_TYPE_FROM_CLASS(gobject_class),
138 G_SIGNAL_RUN_FIRST,
139 0,
140 NULL, NULL,
141 syl_marshal_VOID__POINTER,
142 G_TYPE_NONE,
143 1,
144 G_TYPE_POINTER);
145 app_signals[REMOVE_FOLDER] =
146 g_signal_new("remove-folder",
147 G_TYPE_FROM_CLASS(gobject_class),
148 G_SIGNAL_RUN_FIRST,
149 0,
150 NULL, NULL,
151 syl_marshal_VOID__POINTER,
152 G_TYPE_NONE,
153 1,
154 G_TYPE_POINTER);
155 app_signals[MOVE_FOLDER] =
156 g_signal_new("move-folder",
157 G_TYPE_FROM_CLASS(gobject_class),
158 G_SIGNAL_RUN_FIRST,
159 0,
160 NULL, NULL,
161 syl_marshal_VOID__POINTER_STRING_STRING,
162 G_TYPE_NONE,
163 3,
164 G_TYPE_POINTER,
165 G_TYPE_STRING,
166 G_TYPE_STRING);
167 app_signals[FOLDERLIST_UPDATED] =
168 g_signal_new("folderlist-updated",
169 G_TYPE_FROM_CLASS(gobject_class),
170 G_SIGNAL_RUN_FIRST,
171 0,
172 NULL, NULL,
173 syl_marshal_VOID__VOID,
174 G_TYPE_NONE,
175 0);
176 app_signals[ACCOUNT_UPDATED] =
177 g_signal_new("account-updated",
178 G_TYPE_FROM_CLASS(gobject_class),
179 G_SIGNAL_RUN_FIRST,
180 0,
181 NULL, NULL,
182 syl_marshal_VOID__VOID,
183 G_TYPE_NONE,
184 0);
185 }
186
syl_app_create(void)187 GObject *syl_app_create(void)
188 {
189 if (!app)
190 app = g_object_new(SYL_TYPE_APP, NULL);
191 return app;
192 }
193
syl_app_get(void)194 GObject *syl_app_get(void)
195 {
196 return app;
197 }
198
syl_init(void)199 void syl_init(void)
200 {
201 #ifdef G_OS_WIN32
202 gchar *newpath;
203 const gchar *lang_env;
204
205 /* disable locale variable such as "LANG=1041" */
206
207 #define DISABLE_DIGIT_LOCALE(envstr) \
208 { \
209 lang_env = g_getenv(envstr); \
210 if (lang_env && g_ascii_isdigit(lang_env[0])) \
211 g_unsetenv(envstr); \
212 }
213
214 DISABLE_DIGIT_LOCALE("LC_ALL");
215 DISABLE_DIGIT_LOCALE("LANG");
216 DISABLE_DIGIT_LOCALE("LC_CTYPE");
217 DISABLE_DIGIT_LOCALE("LC_MESSAGES");
218
219 #undef DISABLE_DIGIT_LOCALE
220
221 g_unsetenv("LANGUAGE");
222 #endif /* G_OS_WIN32 */
223
224 #ifdef HAVE_LOCALE_H
225 setlocale(LC_ALL, "");
226 #endif
227
228 set_startup_dir();
229
230 #ifdef G_OS_WIN32
231 /* include startup directory into %PATH% for GSpawn */
232 newpath = g_strconcat(get_startup_dir(), ";", g_getenv("PATH"), NULL);
233 g_setenv("PATH", newpath, TRUE);
234 g_free(newpath);
235 #endif
236
237 #ifdef ENABLE_NLS
238 syl_init_gettext(PACKAGE, LOCALEDIR);
239 textdomain(PACKAGE);
240 #endif
241
242 sock_init();
243
244 #ifdef G_OS_UNIX
245 /* ignore SIGPIPE signal for preventing sudden death of program */
246 signal(SIGPIPE, SIG_IGN);
247 #endif
248 }
249
250 #define MAKE_DIR_IF_NOT_EXIST(dir) \
251 { \
252 if (!is_dir_exist(dir)) { \
253 if (is_file_exist(dir)) { \
254 g_warning("File '%s' already exists. " \
255 "Can't create folder.", dir); \
256 return -1; \
257 } \
258 if (make_dir(dir) < 0) \
259 return -1; \
260 } \
261 }
262
syl_init_gettext(const gchar * package,const gchar * dirname)263 void syl_init_gettext(const gchar *package, const gchar *dirname)
264 {
265 #ifdef ENABLE_NLS
266 if (g_path_is_absolute(dirname))
267 bindtextdomain(package, dirname);
268 else {
269 gchar *locale_dir;
270
271 locale_dir = g_strconcat(get_startup_dir(), G_DIR_SEPARATOR_S,
272 dirname, NULL);
273 #ifdef G_OS_WIN32
274 {
275 gchar *locale_dir_;
276
277 locale_dir_ = g_locale_from_utf8(locale_dir, -1,
278 NULL, NULL, NULL);
279 if (locale_dir_) {
280 g_free(locale_dir);
281 locale_dir = locale_dir_;
282 }
283 }
284 #endif /* G_OS_WIN32 */
285 bindtextdomain(package, locale_dir);
286 g_free(locale_dir);
287 }
288
289 bind_textdomain_codeset(package, CS_UTF_8);
290 #endif /* ENABLE_NLS */
291 }
292
syl_setup_rc_dir(void)293 gint syl_setup_rc_dir(void)
294 {
295 if (!is_dir_exist(get_rc_dir())) {
296 if (make_dir_hier(get_rc_dir()) < 0)
297 return -1;
298 }
299
300 MAKE_DIR_IF_NOT_EXIST(get_mail_base_dir());
301
302 CHDIR_RETURN_VAL_IF_FAIL(get_rc_dir(), -1);
303
304 MAKE_DIR_IF_NOT_EXIST(get_imap_cache_dir());
305 MAKE_DIR_IF_NOT_EXIST(get_news_cache_dir());
306 MAKE_DIR_IF_NOT_EXIST(get_mime_tmp_dir());
307 MAKE_DIR_IF_NOT_EXIST(get_tmp_dir());
308 MAKE_DIR_IF_NOT_EXIST(UIDL_DIR);
309 MAKE_DIR_IF_NOT_EXIST(PLUGIN_DIR);
310
311 /* remove temporary files */
312 remove_all_files(get_tmp_dir());
313 remove_all_files(get_mime_tmp_dir());
314
315 return 0;
316 }
317
syl_save_all_state(void)318 void syl_save_all_state(void)
319 {
320 folder_write_list();
321 prefs_common_write_config();
322 filter_write_config();
323 account_write_config_all();
324 }
325
syl_cleanup(void)326 void syl_cleanup(void)
327 {
328 /* remove temporary files */
329 remove_all_files(get_tmp_dir());
330 remove_all_files(get_mime_tmp_dir());
331 #if GLIB_CHECK_VERSION(2, 6, 0)
332 g_log_set_default_handler(g_log_default_handler, NULL);
333 #endif
334 close_log_file();
335
336 sock_cleanup();
337
338 if (app) {
339 g_object_unref(app);
340 app = NULL;
341 }
342 }
343