Statistics
| Revision:

root / src / main.c @ 537

History | View | Annotate | Download (22.3 kB)

1 1 hiro
/*
2 1 hiro
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 14 hiro
 * Copyright (C) 1999-2005 Hiroyuki Yamamoto
4 1 hiro
 *
5 1 hiro
 * This program is free software; you can redistribute it and/or modify
6 1 hiro
 * it under the terms of the GNU General Public License as published by
7 1 hiro
 * the Free Software Foundation; either version 2 of the License, or
8 1 hiro
 * (at your option) any later version.
9 1 hiro
 *
10 1 hiro
 * This program is distributed in the hope that it will be useful,
11 1 hiro
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 1 hiro
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 1 hiro
 * GNU General Public License for more details.
14 1 hiro
 *
15 1 hiro
 * You should have received a copy of the GNU General Public License
16 1 hiro
 * along with this program; if not, write to the Free Software
17 1 hiro
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 1 hiro
 */
19 1 hiro
20 1 hiro
#ifdef HAVE_CONFIG_H
21 1 hiro
#  include "config.h"
22 1 hiro
#endif
23 1 hiro
24 1 hiro
#include "defs.h"
25 1 hiro
26 1 hiro
#include <glib.h>
27 92 hiro
#include <glib/gi18n.h>
28 1 hiro
#include <gtk/gtkmain.h>
29 1 hiro
#include <gtk/gtkrc.h>
30 237 hiro
#include <gtk/gtkstock.h>
31 237 hiro
#include <gtk/gtkaccelmap.h>
32 1 hiro
33 1 hiro
#include <stdio.h>
34 1 hiro
#include <stdlib.h>
35 1 hiro
#include <string.h>
36 1 hiro
#include <ctype.h>
37 1 hiro
#include <unistd.h>
38 1 hiro
#include <time.h>
39 1 hiro
#include <sys/stat.h>
40 1 hiro
#include <sys/types.h>
41 467 hiro
#ifdef G_OS_UNIX
42 467 hiro
#  include <signal.h>
43 467 hiro
#endif
44 1 hiro
45 1 hiro
#if HAVE_LOCALE_H
46 1 hiro
#  include <locale.h>
47 1 hiro
#endif
48 1 hiro
49 1 hiro
#if USE_GPGME
50 1 hiro
#  include <gpgme.h>
51 1 hiro
#endif
52 1 hiro
53 1 hiro
#include "main.h"
54 1 hiro
#include "mainwindow.h"
55 1 hiro
#include "folderview.h"
56 1 hiro
#include "summaryview.h"
57 1 hiro
#include "prefs_common.h"
58 1 hiro
#include "prefs_account.h"
59 1 hiro
#include "prefs_actions.h"
60 1 hiro
#include "prefs_display_header.h"
61 1 hiro
#include "account.h"
62 537 hiro
#include "account_dialog.h"
63 1 hiro
#include "procmsg.h"
64 1 hiro
#include "filter.h"
65 1 hiro
#include "inc.h"
66 1 hiro
#include "import.h"
67 1 hiro
#include "manage_window.h"
68 1 hiro
#include "alertpanel.h"
69 1 hiro
#include "statusbar.h"
70 1 hiro
#include "addressbook.h"
71 14 hiro
#include "addrindex.h"
72 1 hiro
#include "compose.h"
73 1 hiro
#include "folder.h"
74 1 hiro
#include "setup.h"
75 1 hiro
#include "utils.h"
76 1 hiro
#include "gtkutils.h"
77 1 hiro
#include "socket.h"
78 424 hiro
#include "stock_pixmap.h"
79 1 hiro
80 1 hiro
#if USE_GPGME
81 1 hiro
#  include "rfc2015.h"
82 1 hiro
#endif
83 1 hiro
#if USE_SSL
84 1 hiro
#  include "ssl.h"
85 1 hiro
#endif
86 1 hiro
87 1 hiro
#include "version.h"
88 1 hiro
89 1 hiro
gchar *prog_version;
90 1 hiro
gchar *startup_dir;
91 1 hiro
92 1 hiro
static gint lock_socket = -1;
93 1 hiro
static gint lock_socket_tag = 0;
94 1 hiro
95 1 hiro
static struct RemoteCmd {
96 1 hiro
        gboolean receive;
97 1 hiro
        gboolean receive_all;
98 1 hiro
        gboolean compose;
99 1 hiro
        const gchar *compose_mailto;
100 1 hiro
        GPtrArray *attach_files;
101 1 hiro
        gboolean status;
102 1 hiro
        gboolean status_full;
103 1 hiro
        GPtrArray *status_folders;
104 1 hiro
        GPtrArray *status_full_folders;
105 1 hiro
        gboolean send;
106 1 hiro
} cmd;
107 1 hiro
108 525 hiro
static void parse_cmd_opt                (int                 argc,
109 525 hiro
                                         char                *argv[]);
110 1 hiro
111 525 hiro
static void app_init                        (void);
112 525 hiro
static void parse_gtkrc_files                (void);
113 525 hiro
static void setup_rc_dir                (void);
114 525 hiro
static void check_gpg                        (void);
115 1 hiro
116 525 hiro
static gchar *get_socket_name                (void);
117 1 hiro
static gint prohibit_duplicate_launch        (void);
118 1 hiro
static gint lock_socket_remove                (void);
119 1 hiro
static void lock_socket_input_cb        (gpointer           data,
120 1 hiro
                                         gint                   source,
121 1 hiro
                                         GdkInputCondition condition);
122 1 hiro
123 525 hiro
static void remote_command_exec                (void);
124 14 hiro
static void migrate_old_config                (void);
125 14 hiro
126 1 hiro
static void open_compose_new                (const gchar        *address,
127 1 hiro
                                         GPtrArray        *attach_files);
128 1 hiro
129 1 hiro
static void send_queue                        (void);
130 1 hiro
131 525 hiro
#define MAKE_DIR_IF_NOT_EXIST(dir)                                        \
132 525 hiro
{                                                                        \
133 525 hiro
        if (!is_dir_exist(dir)) {                                        \
134 525 hiro
                if (is_file_exist(dir)) {                                \
135 525 hiro
                        alertpanel_warning                                \
136 525 hiro
                                (_("File `%s' already exists.\n"        \
137 525 hiro
                                   "Can't create folder."),                \
138 525 hiro
                                 dir);                                        \
139 525 hiro
                        exit(1);                                        \
140 525 hiro
                }                                                        \
141 525 hiro
                if (make_dir(dir) < 0)                                        \
142 525 hiro
                        exit(1);                                        \
143 525 hiro
        }                                                                \
144 1 hiro
}
145 1 hiro
146 525 hiro
#define CHDIR_EXIT_IF_FAIL(dir, val)        \
147 525 hiro
{                                        \
148 525 hiro
        if (change_dir(dir) < 0)        \
149 525 hiro
                exit(val);                \
150 525 hiro
}
151 525 hiro
152 525 hiro
153 1 hiro
int main(int argc, char *argv[])
154 1 hiro
{
155 1 hiro
        MainWindow *mainwin;
156 1 hiro
        FolderView *folderview;
157 424 hiro
        GdkPixbuf *icon;
158 1 hiro
159 526 hiro
        app_init();
160 1 hiro
        parse_cmd_opt(argc, argv);
161 1 hiro
162 525 hiro
#ifdef G_OS_UNIX
163 1 hiro
        /* check and create unix domain socket for remote operation */
164 1 hiro
        lock_socket = prohibit_duplicate_launch();
165 1 hiro
        if (lock_socket < 0) return 0;
166 1 hiro
167 1 hiro
        if (cmd.status || cmd.status_full) {
168 1 hiro
                puts("0 Sylpheed not running.");
169 1 hiro
                lock_socket_remove();
170 1 hiro
                return 0;
171 1 hiro
        }
172 469 hiro
#endif
173 1 hiro
174 1 hiro
        gtk_set_locale();
175 1 hiro
        gtk_init(&argc, &argv);
176 1 hiro
177 1 hiro
        gdk_rgb_init();
178 1 hiro
        gtk_widget_set_default_colormap(gdk_rgb_get_cmap());
179 1 hiro
        gtk_widget_set_default_visual(gdk_rgb_get_visual());
180 1 hiro
181 1 hiro
#if USE_THREADS || USE_LDAP
182 1 hiro
        g_thread_init(NULL);
183 1 hiro
        if (!g_thread_supported())
184 1 hiro
                g_error(_("g_thread is not supported by glib.\n"));
185 1 hiro
#endif
186 1 hiro
187 525 hiro
        parse_gtkrc_files();
188 525 hiro
        setup_rc_dir();
189 1 hiro
190 484 hiro
        if (is_file_exist("sylpheed.log")) {
191 484 hiro
                if (rename_force("sylpheed.log", "sylpheed.log.bak") < 0)
192 1 hiro
                        FILE_OP_ERROR("sylpheed.log", "rename");
193 1 hiro
        }
194 484 hiro
        set_log_file("sylpheed.log");
195 1 hiro
196 525 hiro
        CHDIR_EXIT_IF_FAIL(get_home_dir(), 1);
197 484 hiro
198 1 hiro
        prefs_common_read_config();
199 525 hiro
        prefs_filter_read_config();
200 525 hiro
        prefs_actions_read_config();
201 525 hiro
        prefs_display_header_read_config();
202 1 hiro
203 534 hiro
        gtkut_stock_button_set_set_reverse(!prefs_common.comply_gnome_hig);
204 534 hiro
205 525 hiro
        check_gpg();
206 438 hiro
207 1 hiro
        sock_set_io_timeout(prefs_common.io_timeout_secs);
208 1 hiro
209 1 hiro
        gtkut_widget_init();
210 424 hiro
        stock_pixbuf_gdk(NULL, STOCK_PIXMAP_SYLPHEED, &icon);
211 424 hiro
        gtk_window_set_default_icon(icon);
212 1 hiro
213 1 hiro
        mainwin = main_window_create
214 1 hiro
                (prefs_common.sep_folder | prefs_common.sep_msg << 1);
215 1 hiro
        folderview = mainwin->folderview;
216 1 hiro
217 525 hiro
#ifdef G_OS_UNIX
218 1 hiro
        /* register the callback of unix domain socket input */
219 1 hiro
        lock_socket_tag = gdk_input_add(lock_socket,
220 1 hiro
                                        GDK_INPUT_READ | GDK_INPUT_EXCEPTION,
221 1 hiro
                                        lock_socket_input_cb,
222 1 hiro
                                        mainwin);
223 469 hiro
#endif
224 1 hiro
225 1 hiro
        account_read_config_all();
226 537 hiro
        account_set_menu();
227 537 hiro
        main_window_reflect_prefs_all();
228 1 hiro
229 1 hiro
        if (folder_read_list() < 0) {
230 1 hiro
                setup(mainwin);
231 1 hiro
                folder_write_list();
232 1 hiro
        }
233 1 hiro
        if (!account_get_list()) {
234 1 hiro
                account_edit_open();
235 1 hiro
                account_add();
236 1 hiro
        }
237 1 hiro
238 1 hiro
        account_set_missing_folder();
239 1 hiro
        folder_set_missing_folders();
240 1 hiro
        folderview_set(folderview);
241 1 hiro
242 1 hiro
        addressbook_read_file();
243 1 hiro
244 1 hiro
        inc_autocheck_timer_init(mainwin);
245 1 hiro
246 525 hiro
        remote_command_exec();
247 1 hiro
248 1 hiro
        gtk_main();
249 1 hiro
250 1 hiro
        return 0;
251 1 hiro
}
252 1 hiro
253 1 hiro
static void parse_cmd_opt(int argc, char *argv[])
254 1 hiro
{
255 1 hiro
        gint i;
256 1 hiro
257 1 hiro
        for (i = 1; i < argc; i++) {
258 1 hiro
                if (!strncmp(argv[i], "--debug", 7))
259 522 hiro
                        set_debug_mode(TRUE);
260 1 hiro
                else if (!strncmp(argv[i], "--receive-all", 13))
261 1 hiro
                        cmd.receive_all = TRUE;
262 1 hiro
                else if (!strncmp(argv[i], "--receive", 9))
263 1 hiro
                        cmd.receive = TRUE;
264 1 hiro
                else if (!strncmp(argv[i], "--compose", 9)) {
265 1 hiro
                        const gchar *p = argv[i + 1];
266 1 hiro
267 1 hiro
                        cmd.compose = TRUE;
268 1 hiro
                        cmd.compose_mailto = NULL;
269 1 hiro
                        if (p && *p != '\0' && *p != '-') {
270 1 hiro
                                if (!strncmp(p, "mailto:", 7))
271 1 hiro
                                        cmd.compose_mailto = p + 7;
272 1 hiro
                                else
273 1 hiro
                                        cmd.compose_mailto = p;
274 1 hiro
                                i++;
275 1 hiro
                        }
276 1 hiro
                } else if (!strncmp(argv[i], "--attach", 8)) {
277 1 hiro
                        const gchar *p = argv[i + 1];
278 1 hiro
                        gchar *file;
279 1 hiro
280 1 hiro
                        while (p && *p != '\0' && *p != '-') {
281 1 hiro
                                if (!cmd.attach_files)
282 1 hiro
                                        cmd.attach_files = g_ptr_array_new();
283 1 hiro
                                if (*p != G_DIR_SEPARATOR)
284 1 hiro
                                        file = g_strconcat(startup_dir,
285 1 hiro
                                                           G_DIR_SEPARATOR_S,
286 1 hiro
                                                           p, NULL);
287 1 hiro
                                else
288 1 hiro
                                        file = g_strdup(p);
289 1 hiro
                                g_ptr_array_add(cmd.attach_files, file);
290 1 hiro
                                i++;
291 1 hiro
                                p = argv[i + 1];
292 1 hiro
                        }
293 1 hiro
                } else if (!strncmp(argv[i], "--send", 6)) {
294 1 hiro
                        cmd.send = TRUE;
295 1 hiro
                } else if (!strncmp(argv[i], "--version", 9)) {
296 1 hiro
                        puts("Sylpheed version " VERSION);
297 1 hiro
                        exit(0);
298 1 hiro
                } else if (!strncmp(argv[i], "--status-full", 13)) {
299 1 hiro
                        const gchar *p = argv[i + 1];
300 1 hiro
301 1 hiro
                        cmd.status_full = TRUE;
302 1 hiro
                        while (p && *p != '\0' && *p != '-') {
303 1 hiro
                                if (!cmd.status_full_folders)
304 1 hiro
                                        cmd.status_full_folders =
305 1 hiro
                                                g_ptr_array_new();
306 1 hiro
                                g_ptr_array_add(cmd.status_full_folders,
307 1 hiro
                                                g_strdup(p));
308 1 hiro
                                i++;
309 1 hiro
                                p = argv[i + 1];
310 1 hiro
                        }
311 1 hiro
                } else if (!strncmp(argv[i], "--status", 8)) {
312 1 hiro
                        const gchar *p = argv[i + 1];
313 1 hiro
314 1 hiro
                        cmd.status = TRUE;
315 1 hiro
                        while (p && *p != '\0' && *p != '-') {
316 1 hiro
                                if (!cmd.status_folders)
317 1 hiro
                                        cmd.status_folders = g_ptr_array_new();
318 1 hiro
                                g_ptr_array_add(cmd.status_folders,
319 1 hiro
                                                g_strdup(p));
320 1 hiro
                                i++;
321 1 hiro
                                p = argv[i + 1];
322 1 hiro
                        }
323 1 hiro
                } else if (!strncmp(argv[i], "--help", 6)) {
324 1 hiro
                        g_print(_("Usage: %s [OPTION]...\n"),
325 1 hiro
                                g_basename(argv[0]));
326 1 hiro
327 74 hiro
                        g_print("%s\n", _("  --compose [address]    open composition window"));
328 74 hiro
                        g_print("%s\n", _("  --attach file1 [file2]...\n"
329 74 hiro
                                "                         open composition window with specified files\n"
330 74 hiro
                                "                         attached"));
331 74 hiro
                        g_print("%s\n", _("  --receive              receive new messages"));
332 74 hiro
                        g_print("%s\n", _("  --receive-all          receive new messages of all accounts"));
333 74 hiro
                        g_print("%s\n", _("  --send                 send all queued messages"));
334 74 hiro
                        g_print("%s\n", _("  --status [folder]...   show the total number of messages"));
335 74 hiro
                        g_print("%s\n", _("  --status-full [folder]...\n"
336 74 hiro
                                "                         show the status of each folder"));
337 74 hiro
                        g_print("%s\n", _("  --debug                debug mode"));
338 74 hiro
                        g_print("%s\n", _("  --help                 display this help and exit"));
339 74 hiro
                        g_print("%s\n", _("  --version              output version information and exit"));
340 1 hiro
341 1 hiro
                        exit(1);
342 1 hiro
                }
343 1 hiro
        }
344 1 hiro
345 1 hiro
        if (cmd.attach_files && cmd.compose == FALSE) {
346 1 hiro
                cmd.compose = TRUE;
347 1 hiro
                cmd.compose_mailto = NULL;
348 1 hiro
        }
349 1 hiro
}
350 1 hiro
351 1 hiro
static gint get_queued_message_num(void)
352 1 hiro
{
353 1 hiro
        FolderItem *queue;
354 1 hiro
355 1 hiro
        queue = folder_get_default_queue();
356 1 hiro
        if (!queue) return -1;
357 1 hiro
358 1 hiro
        folder_item_scan(queue);
359 1 hiro
        return queue->total;
360 1 hiro
}
361 1 hiro
362 525 hiro
static void app_init(void)
363 525 hiro
{
364 525 hiro
        setlocale(LC_ALL, "");
365 525 hiro
        bindtextdomain(PACKAGE, LOCALEDIR);
366 525 hiro
        bind_textdomain_codeset(PACKAGE, CS_UTF_8);
367 525 hiro
        textdomain(PACKAGE);
368 525 hiro
369 525 hiro
        prog_version = PROG_VERSION;
370 525 hiro
        startup_dir = g_get_current_dir();
371 525 hiro
372 525 hiro
        sock_init();
373 525 hiro
#if USE_SSL
374 525 hiro
        ssl_init();
375 525 hiro
#endif
376 525 hiro
377 525 hiro
#ifdef G_OS_UNIX
378 525 hiro
        /* ignore SIGPIPE signal for preventing sudden death of program */
379 525 hiro
        signal(SIGPIPE, SIG_IGN);
380 525 hiro
#endif
381 525 hiro
}
382 525 hiro
383 525 hiro
static void parse_gtkrc_files(void)
384 525 hiro
{
385 525 hiro
        gchar *userrc;
386 525 hiro
387 525 hiro
        /* parse gtkrc files */
388 525 hiro
        userrc = g_strconcat(get_home_dir(), G_DIR_SEPARATOR_S, ".gtkrc-2.0",
389 525 hiro
                             NULL);
390 525 hiro
        gtk_rc_parse(userrc);
391 525 hiro
        g_free(userrc);
392 525 hiro
        userrc = g_strconcat(get_home_dir(), G_DIR_SEPARATOR_S, ".gtk",
393 525 hiro
                             G_DIR_SEPARATOR_S, "gtkrc-2.0", NULL);
394 525 hiro
        gtk_rc_parse(userrc);
395 525 hiro
        g_free(userrc);
396 525 hiro
        userrc = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, "gtkrc", NULL);
397 525 hiro
        gtk_rc_parse(userrc);
398 525 hiro
        g_free(userrc);
399 525 hiro
400 525 hiro
        userrc = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, MENU_RC, NULL);
401 525 hiro
        gtk_accel_map_load(userrc);
402 525 hiro
        g_free(userrc);
403 525 hiro
}
404 525 hiro
405 525 hiro
static void setup_rc_dir(void)
406 525 hiro
{
407 525 hiro
        CHDIR_EXIT_IF_FAIL(get_home_dir(), 1);
408 525 hiro
409 525 hiro
#ifndef G_OS_WIN32
410 525 hiro
        /* backup if old rc file exists */
411 525 hiro
        if (is_file_exist(RC_DIR)) {
412 525 hiro
                if (rename_force(RC_DIR, RC_DIR ".bak") < 0)
413 525 hiro
                        FILE_OP_ERROR(RC_DIR, "rename");
414 525 hiro
        }
415 525 hiro
416 525 hiro
        /* migration from ~/.sylpheed to ~/.sylpheed-2.0 */
417 525 hiro
        if (!is_dir_exist(RC_DIR)) {
418 525 hiro
                const gchar *envstr;
419 525 hiro
                AlertValue val;
420 525 hiro
421 525 hiro
                /* check for filename encoding */
422 525 hiro
                if (conv_get_locale_charset() != C_UTF_8) {
423 525 hiro
                        envstr = g_getenv("G_FILENAME_ENCODING");
424 525 hiro
                        if (!envstr)
425 525 hiro
                                envstr = g_getenv("G_BROKEN_FILENAMES");
426 525 hiro
                        if (!envstr) {
427 525 hiro
                                val = alertpanel(_("Filename encoding"),
428 525 hiro
                                                 _("The locale encoding is not UTF-8, but the environmental variable G_FILENAME_ENCODING is not set.\n"
429 525 hiro
                                                   "If the locale encoding is used for file name or directory name, it will not work correctly.\n"
430 525 hiro
                                                   "In that case, you must set the following environmental variable (see README for detail):\n"
431 525 hiro
                                                   "\n"
432 525 hiro
                                                   "\tG_FILENAME_ENCODING=@locale\n"
433 525 hiro
                                                   "\n"
434 525 hiro
                                                   "Continue?"),
435 525 hiro
                                                 GTK_STOCK_OK, GTK_STOCK_QUIT,
436 525 hiro
                                                 NULL);
437 525 hiro
                                if (G_ALERTDEFAULT != val)
438 525 hiro
                                        exit(1);
439 525 hiro
                        }
440 525 hiro
                }
441 525 hiro
442 525 hiro
                if (make_dir(RC_DIR) < 0)
443 525 hiro
                        exit(1);
444 525 hiro
                if (is_dir_exist(OLD_RC_DIR))
445 525 hiro
                        migrate_old_config();
446 525 hiro
        }
447 525 hiro
#else
448 525 hiro
        if (!is_dir_exist(get_rc_dir())) {
449 525 hiro
                if (make_dir_hier(get_rc_dir()) < 0)
450 525 hiro
                        exit(1);
451 525 hiro
        }
452 525 hiro
453 525 hiro
        MAKE_DIR_IF_NOT_EXIST(get_mail_base_dir());
454 525 hiro
#endif /* G_OS_WIN32 */
455 525 hiro
456 525 hiro
        CHDIR_EXIT_IF_FAIL(get_rc_dir(), 1);
457 525 hiro
458 525 hiro
        MAKE_DIR_IF_NOT_EXIST(get_imap_cache_dir());
459 525 hiro
        MAKE_DIR_IF_NOT_EXIST(get_news_cache_dir());
460 525 hiro
        MAKE_DIR_IF_NOT_EXIST(get_mime_tmp_dir());
461 525 hiro
        MAKE_DIR_IF_NOT_EXIST(get_tmp_dir());
462 525 hiro
        MAKE_DIR_IF_NOT_EXIST(UIDL_DIR);
463 525 hiro
464 525 hiro
        /* remove temporary files */
465 525 hiro
        remove_all_files(get_tmp_dir());
466 525 hiro
        remove_all_files(get_mime_tmp_dir());
467 525 hiro
}
468 525 hiro
469 1 hiro
void app_will_exit(GtkWidget *widget, gpointer data)
470 1 hiro
{
471 1 hiro
        MainWindow *mainwin = data;
472 1 hiro
        gchar *filename;
473 1 hiro
474 1 hiro
        if (compose_get_compose_list()) {
475 1 hiro
                if (alertpanel(_("Notice"),
476 1 hiro
                               _("Composing message exists. Really quit?"),
477 30 hiro
                               GTK_STOCK_OK, GTK_STOCK_CANCEL, NULL)
478 30 hiro
                    != G_ALERTDEFAULT)
479 1 hiro
                        return;
480 1 hiro
                manage_window_focus_in(mainwin->window, NULL, NULL);
481 1 hiro
        }
482 1 hiro
483 1 hiro
        if (prefs_common.warn_queued_on_exit && get_queued_message_num() > 0) {
484 1 hiro
                if (alertpanel(_("Queued messages"),
485 1 hiro
                               _("Some unsent messages are queued. Exit now?"),
486 30 hiro
                               GTK_STOCK_OK, GTK_STOCK_CANCEL, NULL)
487 30 hiro
                    != G_ALERTDEFAULT)
488 1 hiro
                        return;
489 1 hiro
                manage_window_focus_in(mainwin->window, NULL, NULL);
490 1 hiro
        }
491 1 hiro
492 1 hiro
        inc_autocheck_timer_remove();
493 1 hiro
494 1 hiro
        if (prefs_common.clean_on_exit)
495 1 hiro
                main_window_empty_trash(mainwin, prefs_common.ask_on_clean);
496 1 hiro
497 1 hiro
        /* save all state before exiting */
498 1 hiro
        folder_write_list();
499 1 hiro
        summary_write_cache(mainwin->summaryview);
500 1 hiro
501 1 hiro
        main_window_get_size(mainwin);
502 1 hiro
        main_window_get_position(mainwin);
503 1 hiro
        prefs_common_write_config();
504 1 hiro
        prefs_filter_write_config();
505 1 hiro
        account_write_config_all();
506 1 hiro
        addressbook_export_to_file();
507 1 hiro
508 1 hiro
        filename = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, MENU_RC, NULL);
509 1 hiro
        gtk_accel_map_save(filename);
510 1 hiro
        g_free(filename);
511 1 hiro
512 438 hiro
        /* remove temporary files */
513 291 hiro
        remove_all_files(get_tmp_dir());
514 1 hiro
        remove_all_files(get_mime_tmp_dir());
515 1 hiro
516 1 hiro
        close_log_file();
517 1 hiro
        lock_socket_remove();
518 1 hiro
519 1 hiro
#if USE_SSL
520 1 hiro
        ssl_done();
521 1 hiro
#endif
522 1 hiro
523 469 hiro
        sock_cleanup();
524 469 hiro
525 1 hiro
        gtk_main_quit();
526 1 hiro
}
527 1 hiro
528 56 hiro
#if 0
529 1 hiro
#if USE_GPGME
530 1 hiro
static void idle_function_for_gpgme(void)
531 1 hiro
{
532 1 hiro
        while (gtk_events_pending())
533 1 hiro
                gtk_main_iteration();
534 1 hiro
}
535 1 hiro
#endif /* USE_GPGME */
536 56 hiro
#endif /* 0 */
537 1 hiro
538 525 hiro
static void check_gpg(void)
539 525 hiro
{
540 525 hiro
#if USE_GPGME
541 525 hiro
        if (gpgme_check_version("0.4.5")) {
542 525 hiro
                /* Also does some gpgme init */
543 525 hiro
                gpgme_engine_info_t engineInfo;
544 525 hiro
545 525 hiro
                rfc2015_disable_all();
546 525 hiro
547 525 hiro
                gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL));
548 525 hiro
                gpgme_set_locale(NULL, LC_MESSAGES,
549 525 hiro
                                 setlocale(LC_MESSAGES, NULL));
550 525 hiro
551 525 hiro
                if (!gpgme_get_engine_info(&engineInfo)) {
552 525 hiro
                        while (engineInfo) {
553 525 hiro
                                debug_print("GpgME Protocol: %s\n      Version: %s\n",
554 525 hiro
                                            gpgme_get_protocol_name
555 525 hiro
                                                (engineInfo->protocol),
556 525 hiro
                                            engineInfo->version);
557 525 hiro
                                engineInfo = engineInfo->next;
558 525 hiro
                        }
559 525 hiro
                }
560 525 hiro
        } else {
561 525 hiro
                if (prefs_common.gpg_warning) {
562 525 hiro
                        AlertValue val;
563 525 hiro
564 525 hiro
                        val = alertpanel_message_with_disable
565 525 hiro
                                (_("Warning"),
566 525 hiro
                                 _("GnuPG is not installed properly, or its version is too old.\n"
567 525 hiro
                                   "OpenPGP support disabled."),
568 525 hiro
                                 ALERT_WARNING);
569 525 hiro
                        if (val & G_ALERTDISABLE)
570 525 hiro
                                prefs_common.gpg_warning = FALSE;
571 525 hiro
                }
572 525 hiro
        }
573 525 hiro
        /* FIXME: This function went away.  We can either block until gpgme
574 525 hiro
         * operations finish (currently implemented) or register callbacks
575 525 hiro
         * with the gtk main loop via the gpgme io callback interface instead.
576 525 hiro
         *
577 525 hiro
         * gpgme_register_idle(idle_function_for_gpgme);
578 525 hiro
         */
579 525 hiro
#endif
580 525 hiro
}
581 525 hiro
582 1 hiro
static gchar *get_socket_name(void)
583 1 hiro
{
584 1 hiro
        static gchar *filename = NULL;
585 1 hiro
586 1 hiro
        if (filename == NULL) {
587 1 hiro
                filename = g_strdup_printf("%s%csylpheed-%d",
588 1 hiro
                                           g_get_tmp_dir(), G_DIR_SEPARATOR,
589 469 hiro
#if HAVE_GETUID
590 1 hiro
                                           getuid());
591 469 hiro
#else
592 469 hiro
                                           0);
593 469 hiro
#endif
594 1 hiro
        }
595 1 hiro
596 1 hiro
        return filename;
597 1 hiro
}
598 1 hiro
599 1 hiro
static gint prohibit_duplicate_launch(void)
600 1 hiro
{
601 1 hiro
        gint uxsock;
602 1 hiro
        gchar *path;
603 1 hiro
604 1 hiro
        path = get_socket_name();
605 1 hiro
        uxsock = fd_connect_unix(path);
606 1 hiro
        if (uxsock < 0) {
607 478 hiro
                g_unlink(path);
608 1 hiro
                return fd_open_unix(path);
609 1 hiro
        }
610 1 hiro
611 1 hiro
        /* remote command mode */
612 1 hiro
613 1 hiro
        debug_print(_("another Sylpheed is already running.\n"));
614 1 hiro
615 1 hiro
        if (cmd.receive_all)
616 1 hiro
                fd_write_all(uxsock, "receive_all\n", 12);
617 1 hiro
        else if (cmd.receive)
618 1 hiro
                fd_write_all(uxsock, "receive\n", 8);
619 1 hiro
        else if (cmd.compose && cmd.attach_files) {
620 1 hiro
                gchar *str, *compose_str;
621 1 hiro
                gint i;
622 1 hiro
623 1 hiro
                if (cmd.compose_mailto)
624 1 hiro
                        compose_str = g_strdup_printf("compose_attach %s\n",
625 1 hiro
                                                      cmd.compose_mailto);
626 1 hiro
                else
627 1 hiro
                        compose_str = g_strdup("compose_attach\n");
628 1 hiro
629 1 hiro
                fd_write_all(uxsock, compose_str, strlen(compose_str));
630 1 hiro
                g_free(compose_str);
631 1 hiro
632 1 hiro
                for (i = 0; i < cmd.attach_files->len; i++) {
633 1 hiro
                        str = g_ptr_array_index(cmd.attach_files, i);
634 1 hiro
                        fd_write_all(uxsock, str, strlen(str));
635 1 hiro
                        fd_write_all(uxsock, "\n", 1);
636 1 hiro
                }
637 1 hiro
638 1 hiro
                fd_write_all(uxsock, ".\n", 2);
639 1 hiro
        } else if (cmd.compose) {
640 1 hiro
                gchar *compose_str;
641 1 hiro
642 1 hiro
                if (cmd.compose_mailto)
643 1 hiro
                        compose_str = g_strdup_printf
644 1 hiro
                                ("compose %s\n", cmd.compose_mailto);
645 1 hiro
                else
646 1 hiro
                        compose_str = g_strdup("compose\n");
647 1 hiro
648 1 hiro
                fd_write_all(uxsock, compose_str, strlen(compose_str));
649 1 hiro
                g_free(compose_str);
650 1 hiro
        } else if (cmd.send) {
651 1 hiro
                fd_write_all(uxsock, "send\n", 5);
652 1 hiro
        } else if (cmd.status || cmd.status_full) {
653 1 hiro
                gchar buf[BUFFSIZE];
654 1 hiro
                gint i;
655 1 hiro
                const gchar *command;
656 1 hiro
                GPtrArray *folders;
657 1 hiro
                gchar *folder;
658 1 hiro
659 1 hiro
                command = cmd.status_full ? "status-full\n" : "status\n";
660 1 hiro
                folders = cmd.status_full ? cmd.status_full_folders :
661 1 hiro
                        cmd.status_folders;
662 1 hiro
663 1 hiro
                fd_write_all(uxsock, command, strlen(command));
664 1 hiro
                for (i = 0; folders && i < folders->len; ++i) {
665 1 hiro
                        folder = g_ptr_array_index(folders, i);
666 1 hiro
                        fd_write_all(uxsock, folder, strlen(folder));
667 1 hiro
                        fd_write_all(uxsock, "\n", 1);
668 1 hiro
                }
669 1 hiro
                fd_write_all(uxsock, ".\n", 2);
670 1 hiro
                for (;;) {
671 1 hiro
                        fd_gets(uxsock, buf, sizeof(buf));
672 1 hiro
                        if (!strncmp(buf, ".\n", 2)) break;
673 1 hiro
                        fputs(buf, stdout);
674 1 hiro
                }
675 1 hiro
        } else
676 1 hiro
                fd_write_all(uxsock, "popup\n", 6);
677 1 hiro
678 1 hiro
        fd_close(uxsock);
679 1 hiro
        return -1;
680 1 hiro
}
681 1 hiro
682 1 hiro
static gint lock_socket_remove(void)
683 1 hiro
{
684 469 hiro
#ifdef G_OS_UNIX
685 1 hiro
        gchar *filename;
686 1 hiro
687 1 hiro
        if (lock_socket < 0) return -1;
688 1 hiro
689 1 hiro
        if (lock_socket_tag > 0)
690 1 hiro
                gdk_input_remove(lock_socket_tag);
691 1 hiro
        fd_close(lock_socket);
692 1 hiro
        filename = get_socket_name();
693 478 hiro
        g_unlink(filename);
694 469 hiro
#endif
695 1 hiro
696 1 hiro
        return 0;
697 1 hiro
}
698 1 hiro
699 1 hiro
static GPtrArray *get_folder_item_list(gint sock)
700 1 hiro
{
701 1 hiro
        gchar buf[BUFFSIZE];
702 1 hiro
        FolderItem *item;
703 1 hiro
        GPtrArray *folders = NULL;
704 1 hiro
705 1 hiro
        for (;;) {
706 1 hiro
                fd_gets(sock, buf, sizeof(buf));
707 1 hiro
                if (!strncmp(buf, ".\n", 2)) break;
708 1 hiro
                strretchomp(buf);
709 1 hiro
                if (!folders) folders = g_ptr_array_new();
710 1 hiro
                item = folder_find_item_from_identifier(buf);
711 1 hiro
                if (item)
712 1 hiro
                        g_ptr_array_add(folders, item);
713 1 hiro
                else
714 1 hiro
                        g_warning("no such folder: %s\n", buf);
715 1 hiro
        }
716 1 hiro
717 1 hiro
        return folders;
718 1 hiro
}
719 1 hiro
720 1 hiro
static void lock_socket_input_cb(gpointer data,
721 1 hiro
                                 gint source,
722 1 hiro
                                 GdkInputCondition condition)
723 1 hiro
{
724 1 hiro
        MainWindow *mainwin = (MainWindow *)data;
725 1 hiro
        gint sock;
726 1 hiro
        gchar buf[BUFFSIZE];
727 1 hiro
728 1 hiro
        sock = fd_accept(source);
729 1 hiro
        fd_gets(sock, buf, sizeof(buf));
730 1 hiro
731 1 hiro
        if (!strncmp(buf, "popup", 5)) {
732 1 hiro
                main_window_popup(mainwin);
733 1 hiro
        } else if (!strncmp(buf, "receive_all", 11)) {
734 1 hiro
                main_window_popup(mainwin);
735 1 hiro
                inc_all_account_mail(mainwin, FALSE);
736 1 hiro
        } else if (!strncmp(buf, "receive", 7)) {
737 1 hiro
                main_window_popup(mainwin);
738 1 hiro
                inc_mail(mainwin);
739 1 hiro
        } else if (!strncmp(buf, "compose_attach", 14)) {
740 1 hiro
                GPtrArray *files;
741 1 hiro
                gchar *mailto;
742 1 hiro
743 1 hiro
                mailto = g_strdup(buf + strlen("compose_attach") + 1);
744 1 hiro
                files = g_ptr_array_new();
745 1 hiro
                while (fd_gets(sock, buf, sizeof(buf)) > 0) {
746 1 hiro
                        if (buf[0] == '.' && buf[1] == '\n') break;
747 1 hiro
                        strretchomp(buf);
748 1 hiro
                        g_ptr_array_add(files, g_strdup(buf));
749 1 hiro
                }
750 1 hiro
                open_compose_new(mailto, files);
751 1 hiro
                ptr_array_free_strings(files);
752 1 hiro
                g_ptr_array_free(files, TRUE);
753 1 hiro
                g_free(mailto);
754 1 hiro
        } else if (!strncmp(buf, "compose", 7)) {
755 1 hiro
                open_compose_new(buf + strlen("compose") + 1, NULL);
756 1 hiro
        } else if (!strncmp(buf, "send", 4)) {
757 1 hiro
                send_queue();
758 1 hiro
        } else if (!strncmp(buf, "status-full", 11) ||
759 1 hiro
                   !strncmp(buf, "status", 6)) {
760 1 hiro
                gchar *status;
761 1 hiro
                GPtrArray *folders;
762 1 hiro
763 1 hiro
                folders = get_folder_item_list(sock);
764 1 hiro
                status = folder_get_status
765 1 hiro
                        (folders, !strncmp(buf, "status-full", 11));
766 1 hiro
                fd_write_all(sock, status, strlen(status));
767 1 hiro
                fd_write_all(sock, ".\n", 2);
768 1 hiro
                g_free(status);
769 1 hiro
                if (folders) g_ptr_array_free(folders, TRUE);
770 1 hiro
        }
771 1 hiro
772 1 hiro
        fd_close(sock);
773 1 hiro
}
774 1 hiro
775 525 hiro
static void remote_command_exec(void)
776 525 hiro
{
777 525 hiro
        MainWindow *mainwin;
778 525 hiro
779 525 hiro
        mainwin = main_window_get();
780 525 hiro
781 525 hiro
        if (cmd.receive_all)
782 525 hiro
                inc_all_account_mail(mainwin, FALSE);
783 525 hiro
        else if (prefs_common.chk_on_startup)
784 525 hiro
                inc_all_account_mail(mainwin, TRUE);
785 525 hiro
        else if (cmd.receive)
786 525 hiro
                inc_mail(mainwin);
787 525 hiro
788 525 hiro
        if (cmd.compose)
789 525 hiro
                open_compose_new(cmd.compose_mailto, cmd.attach_files);
790 525 hiro
        if (cmd.attach_files) {
791 525 hiro
                ptr_array_free_strings(cmd.attach_files);
792 525 hiro
                g_ptr_array_free(cmd.attach_files, TRUE);
793 525 hiro
                cmd.attach_files = NULL;
794 525 hiro
        }
795 525 hiro
        if (cmd.send)
796 525 hiro
                send_queue();
797 525 hiro
        if (cmd.status_folders) {
798 525 hiro
                g_ptr_array_free(cmd.status_folders, TRUE);
799 525 hiro
                cmd.status_folders = NULL;
800 525 hiro
        }
801 525 hiro
        if (cmd.status_full_folders) {
802 525 hiro
                g_ptr_array_free(cmd.status_full_folders, TRUE);
803 525 hiro
                cmd.status_full_folders = NULL;
804 525 hiro
        }
805 525 hiro
}
806 525 hiro
807 14 hiro
static void migrate_old_config(void)
808 14 hiro
{
809 479 hiro
        GDir *dir;
810 479 hiro
        const gchar *dir_name;
811 14 hiro
        GPatternSpec *pspec;
812 14 hiro
813 14 hiro
        if (alertpanel(_("Migration of configuration"),
814 14 hiro
                       _("The previous version of configuration found.\n"
815 14 hiro
                         "Do you want to migrate it?"),
816 30 hiro
                       GTK_STOCK_YES, GTK_STOCK_NO, NULL) != G_ALERTDEFAULT)
817 14 hiro
                return;
818 14 hiro
819 14 hiro
        debug_print("Migrating old configuration...\n");
820 14 hiro
821 37 hiro
#define COPY_FILE(rcfile)                                                \
822 37 hiro
        if (is_file_exist(OLD_RC_DIR G_DIR_SEPARATOR_S rcfile)) {        \
823 37 hiro
                conv_copy_file(OLD_RC_DIR G_DIR_SEPARATOR_S rcfile,        \
824 37 hiro
                               RC_DIR G_DIR_SEPARATOR_S rcfile,                \
825 37 hiro
                               conv_get_locale_charset_str());                \
826 37 hiro
        }
827 14 hiro
828 14 hiro
        COPY_FILE(ACCOUNT_RC);
829 14 hiro
        COPY_FILE(ACTIONS_RC);
830 37 hiro
        COPY_FILE(COMMON_RC);
831 14 hiro
        COPY_FILE(CUSTOM_HEADER_RC);
832 14 hiro
        COPY_FILE(DISPLAY_HEADER_RC);
833 14 hiro
        COPY_FILE(FILTER_HEADER_RC);
834 14 hiro
        COPY_FILE(COMMAND_HISTORY);
835 14 hiro
836 14 hiro
#undef COPY_FILE
837 14 hiro
838 37 hiro
        if (is_file_exist(OLD_RC_DIR G_DIR_SEPARATOR_S FILTER_LIST))
839 37 hiro
                copy_file(OLD_RC_DIR G_DIR_SEPARATOR_S FILTER_LIST,
840 37 hiro
                          RC_DIR G_DIR_SEPARATOR_S FILTER_LIST, FALSE);
841 37 hiro
        if (is_file_exist(OLD_RC_DIR G_DIR_SEPARATOR_S FOLDER_LIST))
842 37 hiro
                copy_file(OLD_RC_DIR G_DIR_SEPARATOR_S FOLDER_LIST,
843 37 hiro
                          RC_DIR G_DIR_SEPARATOR_S FOLDER_LIST, FALSE);
844 156 hiro
        if (is_file_exist(OLD_RC_DIR G_DIR_SEPARATOR_S "mime.types"))
845 156 hiro
                copy_file(OLD_RC_DIR G_DIR_SEPARATOR_S "mime.types",
846 156 hiro
                          RC_DIR G_DIR_SEPARATOR_S "mime.types", FALSE);
847 14 hiro
848 37 hiro
        if (is_dir_exist(OLD_RC_DIR G_DIR_SEPARATOR_S TEMPLATE_DIR))
849 37 hiro
                conv_copy_dir(OLD_RC_DIR G_DIR_SEPARATOR_S TEMPLATE_DIR,
850 37 hiro
                              RC_DIR G_DIR_SEPARATOR_S TEMPLATE_DIR,
851 37 hiro
                              conv_get_locale_charset_str());
852 37 hiro
        if (is_dir_exist(OLD_RC_DIR G_DIR_SEPARATOR_S UIDL_DIR))
853 37 hiro
                copy_dir(OLD_RC_DIR G_DIR_SEPARATOR_S UIDL_DIR,
854 37 hiro
                         RC_DIR G_DIR_SEPARATOR_S UIDL_DIR);
855 14 hiro
856 14 hiro
        if (!is_file_exist(OLD_RC_DIR G_DIR_SEPARATOR_S ADDRESSBOOK_INDEX_FILE))
857 14 hiro
                return;
858 14 hiro
859 479 hiro
        if ((dir = g_dir_open(OLD_RC_DIR, 0, NULL)) == NULL) {
860 479 hiro
                g_warning("failed to open directory: %s\n", OLD_RC_DIR);
861 14 hiro
                return;
862 14 hiro
        }
863 14 hiro
864 14 hiro
        pspec = g_pattern_spec_new("addrbook-*.xml");
865 14 hiro
866 479 hiro
        while ((dir_name = g_dir_read_name(dir)) != NULL) {
867 479 hiro
                if (g_pattern_match_string(pspec, dir_name)) {
868 14 hiro
                        gchar *old_file;
869 14 hiro
                        gchar *new_file;
870 14 hiro
871 14 hiro
                        old_file = g_strconcat(OLD_RC_DIR G_DIR_SEPARATOR_S,
872 479 hiro
                                               dir_name, NULL);
873 14 hiro
                        new_file = g_strconcat(RC_DIR G_DIR_SEPARATOR_S,
874 479 hiro
                                               dir_name, NULL);
875 14 hiro
                        copy_file(old_file, new_file, FALSE);
876 14 hiro
                        g_free(new_file);
877 14 hiro
                        g_free(old_file);
878 14 hiro
                }
879 14 hiro
        }
880 14 hiro
881 14 hiro
        g_pattern_spec_free(pspec);
882 479 hiro
        g_dir_close(dir);
883 14 hiro
}
884 14 hiro
885 1 hiro
static void open_compose_new(const gchar *address, GPtrArray *attach_files)
886 1 hiro
{
887 1 hiro
        gchar *addr = NULL;
888 1 hiro
889 1 hiro
        if (address) {
890 1 hiro
                Xstrdup_a(addr, address, return);
891 1 hiro
                g_strstrip(addr);
892 1 hiro
        }
893 1 hiro
894 1 hiro
        compose_new(NULL, NULL, addr, attach_files);
895 1 hiro
}
896 1 hiro
897 1 hiro
static void send_queue(void)
898 1 hiro
{
899 1 hiro
        GList *list;
900 1 hiro
901 1 hiro
        if (!main_window_toggle_online_if_offline(main_window_get()))
902 1 hiro
                return;
903 1 hiro
904 1 hiro
        for (list = folder_get_list(); list != NULL; list = list->next) {
905 1 hiro
                Folder *folder = list->data;
906 1 hiro
907 1 hiro
                if (folder->queue) {
908 1 hiro
                        gint ret;
909 1 hiro
910 1 hiro
                        ret = procmsg_send_queue(folder->queue,
911 317 hiro
                                                 prefs_common.savemsg,
912 317 hiro
                                                 prefs_common.filter_sent);
913 1 hiro
                        statusbar_pop_all();
914 1 hiro
                        if (ret > 0)
915 1 hiro
                                folder_item_scan(folder->queue);
916 1 hiro
                }
917 1 hiro
        }
918 1 hiro
919 1 hiro
        folderview_update_all_updated(TRUE);
920 1 hiro
}