Statistics
| Revision:

root / src / main.c @ 1910

History | View | Annotate | Download (35.6 kB)

1
/*
2
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3
 * Copyright (C) 1999-2007 Hiroyuki Yamamoto
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program 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
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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
#include <gtk/gtkmain.h>
29
#include <gtk/gtkrc.h>
30
#include <gtk/gtkstock.h>
31
#include <gtk/gtkaccelmap.h>
32
33
#include <stdio.h>
34
#include <stdlib.h>
35
#include <string.h>
36
#include <ctype.h>
37
#include <unistd.h>
38
#include <time.h>
39
#include <sys/stat.h>
40
#include <sys/types.h>
41
#ifdef G_OS_UNIX
42
#  include <signal.h>
43
#endif
44
45
#if HAVE_LOCALE_H
46
#  include <locale.h>
47
#endif
48
49
#if USE_GPGME
50
#  include <gpgme.h>
51
#endif
52
53
#include "main.h"
54
#include "mainwindow.h"
55
#include "folderview.h"
56
#include "summaryview.h"
57
#include "prefs_common.h"
58
#include "prefs_account.h"
59
#include "prefs_actions.h"
60
#include "prefs_display_header.h"
61
#include "account.h"
62
#include "account_dialog.h"
63
#include "procmsg.h"
64
#include "filter.h"
65
#include "send_message.h"
66
#include "inc.h"
67
#include "import.h"
68
#include "manage_window.h"
69
#include "alertpanel.h"
70
#include "inputdialog.h"
71
#include "statusbar.h"
72
#include "addressbook.h"
73
#include "addrindex.h"
74
#include "compose.h"
75
#include "logwindow.h"
76
#include "folder.h"
77
#include "setup.h"
78
#include "utils.h"
79
#include "gtkutils.h"
80
#include "socket.h"
81
#include "stock_pixmap.h"
82
#include "trayicon.h"
83
84
#if USE_GPGME
85
#  include "rfc2015.h"
86
#endif
87
#if USE_SSL
88
#  include "ssl.h"
89
#  include "sslmanager.h"
90
#endif
91
92
#ifdef G_OS_WIN32
93
#  include <windows.h>
94
#  include <pbt.h>
95
#  include <fcntl.h>
96
#endif
97
98
#include "version.h"
99
100
gchar *prog_version;
101
102
static gint lock_socket = -1;
103
static gint lock_socket_tag = 0;
104
static GIOChannel *lock_ch = NULL;
105
106
static struct RemoteCmd {
107
        gboolean receive;
108
        gboolean receive_all;
109
        gboolean compose;
110
        const gchar *compose_mailto;
111
        GPtrArray *attach_files;
112
        gboolean send;
113
        gboolean status;
114
        gboolean status_full;
115
        GPtrArray *status_folders;
116
        GPtrArray *status_full_folders;
117
        gchar *open_msg;
118
        gboolean configdir;
119
        gboolean exit;
120
#ifdef G_OS_WIN32
121
        gushort ipcport;
122
#endif
123
} cmd;
124
125
static void parse_cmd_opt                (int                 argc,
126
                                         char                *argv[]);
127
128
static void app_init                        (void);
129
static void parse_gtkrc_files                (void);
130
static void setup_rc_dir                (void);
131
static void check_gpg                        (void);
132
static void set_log_handlers                (gboolean         enable);
133
#ifdef G_OS_WIN32
134
static void process_win32_message        (void);
135
#endif
136
137
static gchar *get_socket_name                (void);
138
static gint prohibit_duplicate_launch        (void);
139
static gint lock_socket_remove                (void);
140
static gboolean lock_socket_input_cb        (GIOChannel        *source,
141
                                         GIOCondition         condition,
142
                                         gpointer         data);
143
144
static void remote_command_exec                (void);
145
static void migrate_old_config                (void);
146
147
static void open_compose_new                (const gchar        *address,
148
                                         GPtrArray        *attach_files);
149
static void open_message                (const gchar        *path);
150
151
static void send_queue                        (void);
152
153
#define MAKE_DIR_IF_NOT_EXIST(dir)                                        \
154
{                                                                        \
155
        if (!is_dir_exist(dir)) {                                        \
156
                if (is_file_exist(dir)) {                                \
157
                        alertpanel_warning                                \
158
                                (_("File `%s' already exists.\n"        \
159
                                   "Can't create folder."),                \
160
                                 dir);                                        \
161
                        exit(1);                                        \
162
                }                                                        \
163
                if (make_dir(dir) < 0)                                        \
164
                        exit(1);                                        \
165
        }                                                                \
166
}
167
168
#define CHDIR_EXIT_IF_FAIL(dir, val)        \
169
{                                        \
170
        if (change_dir(dir) < 0)        \
171
                exit(val);                \
172
}
173
174
175
int main(int argc, char *argv[])
176
{
177
        MainWindow *mainwin;
178
        FolderView *folderview;
179
        GdkPixbuf *icon;
180
#ifdef G_OS_WIN32
181
        GList *iconlist = NULL;
182
#endif
183
184
        app_init();
185
        parse_cmd_opt(argc, argv);
186
187
        sock_init();
188
#if USE_SSL
189
        ssl_init();
190
#endif
191
192
        /* check and create (unix domain) socket for remote operation */
193
        lock_socket = prohibit_duplicate_launch();
194
        if (lock_socket < 0) return 0;
195
196
        if (cmd.status || cmd.status_full) {
197
                puts("0 Sylpheed not running.");
198
                lock_socket_remove();
199
                return 0;
200
        }
201
202
        gtk_set_locale();
203
        gtk_init(&argc, &argv);
204
205
        gdk_rgb_init();
206
        gtk_widget_set_default_colormap(gdk_rgb_get_cmap());
207
        gtk_widget_set_default_visual(gdk_rgb_get_visual());
208
209
#if USE_THREADS || USE_LDAP
210
        if (!g_thread_supported())
211
                g_thread_init(NULL);
212
        if (!g_thread_supported())
213
                g_error(_("g_thread is not supported by glib.\n"));
214
#endif
215
216
        parse_gtkrc_files();
217
        setup_rc_dir();
218
219
        if (is_file_exist("sylpheed.log")) {
220
                if (rename_force("sylpheed.log", "sylpheed.log.bak") < 0)
221
                        FILE_OP_ERROR("sylpheed.log", "rename");
222
        }
223
        set_log_file("sylpheed.log");
224
225
        set_ui_update_func(gtkut_events_flush);
226
        set_progress_func(main_window_progress_show);
227
        set_input_query_password_func(input_dialog_query_password);
228
#if USE_SSL
229
        ssl_set_verify_func(ssl_manager_verify_cert);
230
#endif
231
232
        CHDIR_EXIT_IF_FAIL(get_home_dir(), 1);
233
234
        prefs_common_read_config();
235
        filter_read_config();
236
        prefs_actions_read_config();
237
        prefs_display_header_read_config();
238
239
#ifdef G_OS_WIN32
240
        {
241
                gchar *path;
242
                path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, COMMON_RC,
243
                                   NULL);
244
                if (!is_file_exist(path) && conv_is_ja_locale()) {
245
                        const gchar *str;
246
247
                        debug_print("fixing prefs_common.textfont setting\n");
248
                        str = "MS Gothic 12";
249
                        if (!gtkut_font_can_load(str)) {
250
                                debug_print("font '%s' load failed\n", str);
251
                                str = "\xef\xbc\xad\xef\xbc\xb3 \xe3\x82\xb4\xe3\x82\xb7\xe3\x83\x83\xe3\x82\xaf 12";
252
                                if (!gtkut_font_can_load(str)) {
253
                                        debug_print("font '%s' load failed\n", str);
254
                                        str = NULL;
255
                                }
256
                        }
257
                        if (str) {
258
                                debug_print("font '%s' load ok\n", str);
259
                                g_free(prefs_common.textfont);
260
                                prefs_common.textfont = g_strdup(str);
261
                        }
262
                }
263
                g_free(path);
264
        }
265
#endif
266
267
        gtkut_stock_button_set_set_reverse(!prefs_common.comply_gnome_hig);
268
269
        check_gpg();
270
271
        sock_set_io_timeout(prefs_common.io_timeout_secs);
272
273
        gtkut_widget_init();
274
275
#ifdef G_OS_WIN32
276
        stock_pixbuf_gdk(NULL, STOCK_PIXMAP_SYLPHEED_32, &icon);
277
        iconlist = g_list_append(iconlist, icon);
278
        stock_pixbuf_gdk(NULL, STOCK_PIXMAP_SYLPHEED_SMALL, &icon);
279
        iconlist = g_list_append(iconlist, icon);
280
        gtk_window_set_default_icon_list(iconlist);
281
        g_list_free(iconlist);
282
#else
283
        stock_pixbuf_gdk(NULL, STOCK_PIXMAP_SYLPHEED, &icon);
284
        gtk_window_set_default_icon(icon);
285
#endif
286
287
        mainwin = main_window_create
288
                (prefs_common.sep_folder | prefs_common.sep_msg << 1);
289
        folderview = mainwin->folderview;
290
291
        /* register the callback of socket input */
292
        if (lock_socket > 0) {
293
                lock_ch = g_io_channel_unix_new(lock_socket);
294
                lock_socket_tag = g_io_add_watch(lock_ch,
295
                                                 G_IO_IN|G_IO_PRI|G_IO_ERR,
296
                                                 lock_socket_input_cb, mainwin);
297
        }
298
299
        set_log_handlers(TRUE);
300
301
#ifdef G_OS_WIN32
302
        process_win32_message();
303
#endif
304
305
        account_read_config_all();
306
        account_set_menu();
307
        main_window_reflect_prefs_all();
308
309
        if (folder_read_list() < 0) {
310
                setup(mainwin);
311
                folder_write_list();
312
        }
313
        if (!account_get_list()) {
314
                account_edit_open();
315
                account_add();
316
        }
317
318
        account_set_missing_folder();
319
        folder_set_missing_folders();
320
        folderview_set(folderview);
321
322
        addressbook_read_file();
323
324
        inc_autocheck_timer_init(mainwin);
325
326
        remote_command_exec();
327
328
        gtk_main();
329
330
        return 0;
331
}
332
333
static void init_console(void)
334
{
335
#ifdef G_OS_WIN32
336
        gint fd;
337
        FILE *fp;
338
        static gboolean init_console_done = FALSE;
339
340
        if (init_console_done)
341
                return;
342
343
        if (!AllocConsole()) {
344
                g_warning("AllocConsole() failed\n");
345
                return;
346
        }
347
348
        fd = _open_osfhandle((glong)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT);
349
        _dup2(fd, 1);
350
        fp = _fdopen(fd, "w");
351
        *stdout = *fp;
352
        setvbuf(stdout, NULL, _IONBF, 0);
353
        fd = _open_osfhandle((glong)GetStdHandle(STD_ERROR_HANDLE), _O_TEXT);
354
        _dup2(fd, 2);
355
        fp = _fdopen(fd, "w");
356
        *stderr = *fp;
357
        setvbuf(stderr, NULL, _IONBF, 0);
358
359
        init_console_done = TRUE;
360
#endif
361
}
362
363
static void cleanup_console(void)
364
{
365
#ifdef G_OS_WIN32
366
        FreeConsole();
367
#endif
368
}
369
370
#ifdef G_OS_WIN32
371
static void read_ini_file(void)
372
{
373
        static gushort ipcport = REMOTE_CMD_PORT;
374
        static gchar *confdir = NULL;
375
376
        static PrefParam param[] = {
377
                {"ipcport", "50215", &ipcport, P_USHORT},
378
                {"configdir", NULL, &confdir, P_STRING},
379
380
                {NULL, NULL, NULL, P_OTHER}
381
        };
382
383
        gchar *file;
384
385
        file = g_strconcat(get_startup_dir(), G_DIR_SEPARATOR_S, "sylpheed.ini",
386
                           NULL);
387
        if (!is_file_exist(file)) {
388
                g_free(file);
389
                return;
390
        }
391
392
        prefs_read_config(param, "Sylpheed", file,
393
                          conv_get_locale_charset_str());
394
        g_free(file);
395
396
        cmd.ipcport = ipcport;
397
        if (confdir) {
398
                set_rc_dir(confdir);
399
                g_free(confdir);
400
                confdir = NULL;
401
                cmd.configdir = TRUE;
402
        }
403
}
404
#endif
405
406
static void parse_cmd_opt(int argc, char *argv[])
407
{
408
        gint i;
409
410
        for (i = 1; i < argc; i++) {
411
                if (!strncmp(argv[i], "--debug", 7)) {
412
                        init_console();
413
                        set_debug_mode(TRUE);
414
                } else if (!strncmp(argv[i], "--receive-all", 13))
415
                        cmd.receive_all = TRUE;
416
                else if (!strncmp(argv[i], "--receive", 9))
417
                        cmd.receive = TRUE;
418
                else if (!strncmp(argv[i], "--compose", 9)) {
419
                        const gchar *p = argv[i + 1];
420
421
                        cmd.compose = TRUE;
422
                        cmd.compose_mailto = NULL;
423
                        if (p && *p != '\0' && *p != '-') {
424
                                if (!strncmp(p, "mailto:", 7))
425
                                        cmd.compose_mailto = p + 7;
426
                                else
427
                                        cmd.compose_mailto = p;
428
                                i++;
429
                        }
430
                } else if (!strncmp(argv[i], "--attach", 8)) {
431
                        const gchar *p = argv[i + 1];
432
                        gchar *file;
433
434
                        while (p && *p != '\0' && *p != '-') {
435
                                if (!cmd.attach_files)
436
                                        cmd.attach_files = g_ptr_array_new();
437
                                if (*p != G_DIR_SEPARATOR)
438
                                        file = g_strconcat(get_startup_dir(),
439
                                                           G_DIR_SEPARATOR_S,
440
                                                           p, NULL);
441
                                else
442
                                        file = g_strdup(p);
443
                                g_ptr_array_add(cmd.attach_files, file);
444
                                i++;
445
                                p = argv[i + 1];
446
                        }
447
                } else if (!strncmp(argv[i], "--send", 6)) {
448
                        cmd.send = TRUE;
449
                } else if (!strncmp(argv[i], "--version", 9)) {
450
                        puts("Sylpheed version " VERSION);
451
                        exit(0);
452
                } else if (!strncmp(argv[i], "--status-full", 13)) {
453
                        const gchar *p = argv[i + 1];
454
455
                        cmd.status_full = TRUE;
456
                        while (p && *p != '\0' && *p != '-') {
457
                                if (!cmd.status_full_folders)
458
                                        cmd.status_full_folders =
459
                                                g_ptr_array_new();
460
                                g_ptr_array_add(cmd.status_full_folders,
461
                                                g_strdup(p));
462
                                i++;
463
                                p = argv[i + 1];
464
                        }
465
                } else if (!strncmp(argv[i], "--status", 8)) {
466
                        const gchar *p = argv[i + 1];
467
468
                        cmd.status = TRUE;
469
                        while (p && *p != '\0' && *p != '-') {
470
                                if (!cmd.status_folders)
471
                                        cmd.status_folders = g_ptr_array_new();
472
                                g_ptr_array_add(cmd.status_folders,
473
                                                g_strdup(p));
474
                                i++;
475
                                p = argv[i + 1];
476
                        }
477
                } else if (!strncmp(argv[i], "--open", 6)) {
478
                        const gchar *p = argv[i + 1];
479
480
                        if (p && *p != '\0' && *p != '-') {
481
                                cmd.open_msg = g_locale_to_utf8
482
                                        (p, -1, NULL, NULL, NULL);
483
                                i++;
484
                        }
485
                } else if (!strncmp(argv[i], "--configdir", 11)) {
486
                        const gchar *p = argv[i + 1];
487
488
                        if (p && *p != '\0' && *p != '-') {
489
                                /* this must only be done at startup */
490
#ifdef G_OS_WIN32
491
                                gchar *utf8dir;
492
493
                                utf8dir = g_locale_to_utf8
494
                                        (p, -1, NULL, NULL, NULL);
495
                                if (utf8dir) {
496
                                        set_rc_dir(utf8dir);
497
                                        g_free(utf8dir);
498
                                } else
499
                                        set_rc_dir(p);
500
#else
501
                                set_rc_dir(p);
502
#endif
503
                                cmd.configdir = TRUE;
504
                                i++;
505
                        }
506
#ifdef G_OS_WIN32
507
                } else if (!strncmp(argv[i], "--ipcport", 9)) {
508
                        if (argv[i + 1]) {
509
                                cmd.ipcport = atoi(argv[i + 1]);
510
                                i++;
511
                        }
512
#endif
513
                } else if (!strncmp(argv[i], "--exit", 6)) {
514
                        cmd.exit = TRUE;
515
                } else if (!strncmp(argv[i], "--help", 6)) {
516
                        init_console();
517
518
                        g_print(_("Usage: %s [OPTION]...\n"),
519
                                g_basename(argv[0]));
520
521
                        g_print("%s\n", _("  --compose [address]    open composition window"));
522
                        g_print("%s\n", _("  --attach file1 [file2]...\n"
523
                                "                         open composition window with specified files\n"
524
                                "                         attached"));
525
                        g_print("%s\n", _("  --receive              receive new messages"));
526
                        g_print("%s\n", _("  --receive-all          receive new messages of all accounts"));
527
                        g_print("%s\n", _("  --send                 send all queued messages"));
528
                        g_print("%s\n", _("  --status [folder]...   show the total number of messages"));
529
                        g_print("%s\n", _("  --status-full [folder]...\n"
530
                                "                         show the status of each folder"));
531
                        g_print("%s\n", _("  --open folderid/msgnum open message in new window"));
532
                        g_print("%s\n", _("  --configdir dirname    specify directory which stores configuration files"));
533
#ifdef G_OS_WIN32
534
                        g_print("%s\n", _("  --ipcport portnum      specify port for IPC remote commands"));
535
#endif
536
                        g_print("%s\n", _("  --exit                 exit Sylpheed"));
537
                        g_print("%s\n", _("  --debug                debug mode"));
538
                        g_print("%s\n", _("  --help                 display this help and exit"));
539
                        g_print("%s\n", _("  --version              output version information and exit"));
540
541
#ifdef G_OS_WIN32
542
                        g_print("\n");
543
                        g_print(_("Press any key..."));
544
                        _getch();
545
#endif
546
547
                        cleanup_console();
548
                        exit(1);
549
                }
550
        }
551
552
        if (cmd.attach_files && cmd.compose == FALSE) {
553
                cmd.compose = TRUE;
554
                cmd.compose_mailto = NULL;
555
        }
556
}
557
558
static gint get_queued_message_num(void)
559
{
560
        FolderItem *queue;
561
562
        queue = folder_get_default_queue();
563
        if (!queue) return -1;
564
565
        folder_item_scan(queue);
566
        return queue->total;
567
}
568
569
static void app_init(void)
570
{
571
#ifdef G_OS_WIN32
572
        gchar *newpath;
573
        const gchar *lang_env;
574
575
        /* disable locale variable such as "LANG=1041" */
576
577
#define DISABLE_DIGIT_LOCALE(envstr)                        \
578
{                                                        \
579
        lang_env = g_getenv(envstr);                        \
580
        if (lang_env && g_ascii_isdigit(lang_env[0]))        \
581
                g_unsetenv(envstr);                        \
582
}
583
584
        DISABLE_DIGIT_LOCALE("LC_ALL");
585
        DISABLE_DIGIT_LOCALE("LANG");
586
        DISABLE_DIGIT_LOCALE("LC_CTYPE");
587
        DISABLE_DIGIT_LOCALE("LC_MESSAGES");
588
589
#undef DISABLE_DIGIT_LOCALE
590
591
        g_unsetenv("LANGUAGE");
592
#endif
593
594
        setlocale(LC_ALL, "");
595
596
        prog_version = PROG_VERSION;
597
        set_startup_dir();
598
599
#ifdef G_OS_WIN32
600
        /* include startup directory into %PATH% for GSpawn */
601
        newpath = g_strconcat(get_startup_dir(), ";", g_getenv("PATH"), NULL);
602
        g_setenv("PATH", newpath, TRUE);
603
        g_free(newpath);
604
#endif
605
606
        if (g_path_is_absolute(LOCALEDIR))
607
                bindtextdomain(PACKAGE, LOCALEDIR);
608
        else {
609
                gchar *locale_dir;
610
611
                locale_dir = g_strconcat(get_startup_dir(), G_DIR_SEPARATOR_S,
612
                                         LOCALEDIR, NULL);
613
#ifdef G_OS_WIN32
614
                {
615
                        gchar *locale_dir_;
616
617
                        locale_dir_ = g_locale_from_utf8(locale_dir, -1,
618
                                                         NULL, NULL, NULL);
619
                        if (locale_dir_) {
620
                                g_free(locale_dir);
621
                                locale_dir = locale_dir_;
622
                        }
623
                }
624
#endif
625
                bindtextdomain(PACKAGE, locale_dir);
626
                g_free(locale_dir);
627
        }
628
629
        bind_textdomain_codeset(PACKAGE, CS_UTF_8);
630
        textdomain(PACKAGE);
631
632
#ifdef G_OS_UNIX
633
        /* ignore SIGPIPE signal for preventing sudden death of program */
634
        signal(SIGPIPE, SIG_IGN);
635
#endif
636
637
#ifdef G_OS_WIN32
638
        read_ini_file();
639
#endif
640
}
641
642
static void parse_gtkrc_files(void)
643
{
644
        gchar *userrc;
645
646
        /* parse gtkrc files */
647
        userrc = g_strconcat(get_home_dir(), G_DIR_SEPARATOR_S, ".gtkrc-2.0",
648
                             NULL);
649
        gtk_rc_parse(userrc);
650
        g_free(userrc);
651
        userrc = g_strconcat(get_home_dir(), G_DIR_SEPARATOR_S, ".gtk",
652
                             G_DIR_SEPARATOR_S, "gtkrc-2.0", NULL);
653
        gtk_rc_parse(userrc);
654
        g_free(userrc);
655
        userrc = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, "gtkrc", NULL);
656
        gtk_rc_parse(userrc);
657
        g_free(userrc);
658
659
        userrc = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, MENU_RC, NULL);
660
        gtk_accel_map_load(userrc);
661
        g_free(userrc);
662
}
663
664
static void setup_rc_dir(void)
665
{
666
#ifndef G_OS_WIN32
667
        CHDIR_EXIT_IF_FAIL(get_home_dir(), 1);
668
669
        /* backup if old rc file exists */
670
        if (!cmd.configdir && is_file_exist(RC_DIR)) {
671
                if (rename_force(RC_DIR, RC_DIR ".bak") < 0)
672
                        FILE_OP_ERROR(RC_DIR, "rename");
673
        }
674
675
        /* migration from ~/.sylpheed to ~/.sylpheed-2.0 */
676
        if (!cmd.configdir && !is_dir_exist(RC_DIR)) {
677
                const gchar *envstr;
678
                AlertValue val;
679
680
                /* check for filename encoding */
681
                if (conv_get_locale_charset() != C_UTF_8) {
682
                        envstr = g_getenv("G_FILENAME_ENCODING");
683
                        if (!envstr)
684
                                envstr = g_getenv("G_BROKEN_FILENAMES");
685
                        if (!envstr) {
686
                                val = alertpanel(_("Filename encoding"),
687
                                                 _("The locale encoding is not UTF-8, but the environmental variable G_FILENAME_ENCODING is not set.\n"
688
                                                   "If the locale encoding is used for file name or directory name, it will not work correctly.\n"
689
                                                   "In that case, you must set the following environmental variable (see README for detail):\n"
690
                                                   "\n"
691
                                                   "\tG_FILENAME_ENCODING=@locale\n"
692
                                                   "\n"
693
                                                   "Continue?"),
694
                                                 GTK_STOCK_OK, GTK_STOCK_QUIT,
695
                                                 NULL);
696
                                if (G_ALERTDEFAULT != val)
697
                                        exit(1);
698
                        }
699
                }
700
701
                if (make_dir(RC_DIR) < 0)
702
                        exit(1);
703
                if (is_dir_exist(OLD_RC_DIR))
704
                        migrate_old_config();
705
        }
706
#endif /* !G_OS_WIN32 */
707
708
        if (!is_dir_exist(get_rc_dir())) {
709
                if (make_dir_hier(get_rc_dir()) < 0)
710
                        exit(1);
711
        }
712
713
        MAKE_DIR_IF_NOT_EXIST(get_mail_base_dir());
714
715
        CHDIR_EXIT_IF_FAIL(get_rc_dir(), 1);
716
717
        MAKE_DIR_IF_NOT_EXIST(get_imap_cache_dir());
718
        MAKE_DIR_IF_NOT_EXIST(get_news_cache_dir());
719
        MAKE_DIR_IF_NOT_EXIST(get_mime_tmp_dir());
720
        MAKE_DIR_IF_NOT_EXIST(get_tmp_dir());
721
        MAKE_DIR_IF_NOT_EXIST(UIDL_DIR);
722
723
        /* remove temporary files */
724
        remove_all_files(get_tmp_dir());
725
        remove_all_files(get_mime_tmp_dir());
726
}
727
728
void app_will_exit(gboolean force)
729
{
730
        MainWindow *mainwin;
731
        gchar *filename;
732
        static gboolean on_exit = FALSE;
733
        GList *cur;
734
735
        if (on_exit)
736
                return;
737
        on_exit = TRUE;
738
739
        mainwin = main_window_get();
740
741
        if (!force && compose_get_compose_list()) {
742
                if (alertpanel(_("Notice"),
743
                               _("Composing message exists. Really quit?"),
744
                               GTK_STOCK_OK, GTK_STOCK_CANCEL, NULL)
745
                    != G_ALERTDEFAULT) {
746
                        on_exit = FALSE;
747
                        return;
748
                }
749
                manage_window_focus_in(mainwin->window, NULL, NULL);
750
        }
751
752
        if (!force &&
753
            prefs_common.warn_queued_on_exit && get_queued_message_num() > 0) {
754
                if (alertpanel(_("Queued messages"),
755
                               _("Some unsent messages are queued. Exit now?"),
756
                               GTK_STOCK_OK, GTK_STOCK_CANCEL, NULL)
757
                    != G_ALERTDEFAULT) {
758
                        on_exit = FALSE;
759
                        return;
760
                }
761
                manage_window_focus_in(mainwin->window, NULL, NULL);
762
        }
763
764
        inc_autocheck_timer_remove();
765
766
        if (prefs_common.clean_on_exit)
767
                main_window_empty_trash(mainwin,
768
                                        !force && prefs_common.ask_on_clean);
769
770
        for (cur = account_get_list(); cur != NULL; cur = cur->next) {
771
                PrefsAccount *ac = (PrefsAccount *)cur->data;
772
                if (ac->protocol == A_IMAP4 && ac->imap_clear_cache_on_exit &&
773
                    ac->folder)
774
                        procmsg_remove_all_cached_messages(FOLDER(ac->folder));
775
        }
776
777
        trayicon_destroy(mainwin->tray_icon);
778
779
        /* save all state before exiting */
780
        folder_write_list();
781
        summary_write_cache(mainwin->summaryview);
782
783
        main_window_get_size(mainwin);
784
        main_window_get_position(mainwin);
785
        prefs_common_write_config();
786
        filter_write_config();
787
        account_write_config_all();
788
        addressbook_export_to_file();
789
790
        filename = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, MENU_RC, NULL);
791
        gtk_accel_map_save(filename);
792
        g_free(filename);
793
794
        /* remove temporary files */
795
        remove_all_files(get_tmp_dir());
796
        remove_all_files(get_mime_tmp_dir());
797
798
        set_log_handlers(FALSE);
799
        close_log_file();
800
        lock_socket_remove();
801
802
#if USE_SSL
803
        ssl_done();
804
#endif
805
        cleanup_console();
806
        sock_cleanup();
807
808
        if (gtk_main_level() > 0)
809
                gtk_main_quit();
810
811
        exit(0);
812
}
813
814
#if 0
815
#if USE_GPGME
816
static void idle_function_for_gpgme(void)
817
{
818
        while (gtk_events_pending())
819
                gtk_main_iteration();
820
}
821
#endif /* USE_GPGME */
822
#endif /* 0 */
823
824
static void check_gpg(void)
825
{
826
#if USE_GPGME
827
        if (gpgme_check_version("0.4.5") &&
828
            !gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP)) {
829
                /* Also does some gpgme init */
830
                gpgme_engine_info_t engineInfo;
831
832
                gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL));
833
                gpgme_set_locale(NULL, LC_MESSAGES,
834
                                 setlocale(LC_MESSAGES, NULL));
835
836
                if (!gpgme_get_engine_info(&engineInfo)) {
837
                        while (engineInfo) {
838
                                debug_print("GpgME Protocol: %s\n      Version: %s\n",
839
                                            gpgme_get_protocol_name
840
                                                (engineInfo->protocol),
841
                                            engineInfo->version ?
842
                                            engineInfo->version : "(unknown)");
843
                                engineInfo = engineInfo->next;
844
                        }
845
                }
846
847
                procmsg_set_decrypt_message_func
848
                        (rfc2015_open_message_decrypted);
849
                procmsg_set_auto_decrypt_message(TRUE);
850
        } else {
851
                rfc2015_disable_all();
852
853
                if (prefs_common.gpg_warning) {
854
                        AlertValue val;
855
856
                        val = alertpanel_message_with_disable
857
                                (_("Warning"),
858
                                 _("GnuPG is not installed properly, or its version is too old.\n"
859
                                   "OpenPGP support disabled."),
860
                                 ALERT_WARNING);
861
                        if (val & G_ALERTDISABLE)
862
                                prefs_common.gpg_warning = FALSE;
863
                }
864
        }
865
        /* FIXME: This function went away.  We can either block until gpgme
866
         * operations finish (currently implemented) or register callbacks
867
         * with the gtk main loop via the gpgme io callback interface instead.
868
         *
869
         * gpgme_register_idle(idle_function_for_gpgme);
870
         */
871
#endif
872
}
873
874
static void default_log_func(const gchar *log_domain, GLogLevelFlags log_level,
875
                             const gchar *message, gpointer user_data)
876
{
877
        gchar *prefix = "";
878
        gchar *file_prefix = "";
879
        LogType level = LOG_NORMAL;
880
        gchar *str;
881
        const gchar *message_;
882
883
        switch (log_level) {
884
        case G_LOG_LEVEL_ERROR:
885
                prefix = "ERROR";
886
                file_prefix = "*** ";
887
                level = LOG_ERROR;
888
                break;
889
        case G_LOG_LEVEL_CRITICAL:
890
                prefix = "CRITICAL";
891
                file_prefix = "** ";
892
                level = LOG_WARN;
893
                break;
894
        case G_LOG_LEVEL_WARNING:
895
                prefix = "WARNING";
896
                file_prefix = "** ";
897
                level = LOG_WARN;
898
                break;
899
        case G_LOG_LEVEL_MESSAGE:
900
                prefix = "Message";
901
                file_prefix = "* ";
902
                level = LOG_MSG;
903
                break;
904
        case G_LOG_LEVEL_INFO:
905
                prefix = "INFO";
906
                file_prefix = "* ";
907
                level = LOG_MSG;
908
                break;
909
        case G_LOG_LEVEL_DEBUG:
910
                prefix = "DEBUG";
911
                break;
912
        default:
913
                prefix = "LOG";
914
                break;
915
        }
916
917
        if (!message)
918
                message_ = "(NULL) message";
919
        else
920
                message_ = message;
921
        if (log_domain)
922
                str = g_strconcat(log_domain, "-", prefix, ": ", message_, "\n",
923
                                  NULL);
924
        else
925
                str = g_strconcat(prefix, ": ", message_, "\n", NULL);
926
        log_window_append(str, level);
927
        log_write(str, file_prefix);
928
        g_free(str);
929
930
        g_log_default_handler(log_domain, log_level, message, user_data);
931
}
932
933
static void set_log_handlers(gboolean enable)
934
{
935
#if GLIB_CHECK_VERSION(2, 6, 0)
936
        if (enable)
937
                g_log_set_default_handler(default_log_func, NULL);
938
        else
939
                g_log_set_default_handler(g_log_default_handler, NULL);
940
#else
941
        static guint handler_id[4] = {0, 0, 0, 0};
942
943
        if (enable) {
944
                handler_id[0] = g_log_set_handler
945
                        ("GLib", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL
946
                         | G_LOG_FLAG_RECURSION, default_log_func, NULL);
947
                handler_id[1] = g_log_set_handler
948
                        ("Gtk", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL
949
                         | G_LOG_FLAG_RECURSION, default_log_func, NULL);
950
                handler_id[2] = g_log_set_handler
951
                        ("LibSylph", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL
952
                         | G_LOG_FLAG_RECURSION, default_log_func, NULL);
953
                handler_id[3] = g_log_set_handler
954
                        ("Sylpheed", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL
955
                         | G_LOG_FLAG_RECURSION, default_log_func, NULL);
956
        } else {
957
                g_log_remove_handler("GLib", handler_id[0]);
958
                g_log_remove_handler("Gtk", handler_id[1]);
959
                g_log_remove_handler("LibSylph", handler_id[2]);
960
                g_log_remove_handler("Sylpheed", handler_id[3]);
961
                handler_id[0] = 0;
962
                handler_id[1] = 0;
963
                handler_id[2] = 0;
964
                handler_id[3] = 0;
965
        }
966
#endif
967
}
968
969
#ifdef G_OS_WIN32
970
static LRESULT CALLBACK
971
wndproc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
972
{
973
        if (message == WM_POWERBROADCAST) {
974
                debug_print("WM_POWERBROADCAST received: wparam = %d\n",
975
                            wparam);
976
                if (wparam == PBT_APMSUSPEND || wparam == PBT_APMSTANDBY) {
977
                        debug_print("suspend now\n");
978
                        inc_autocheck_timer_remove();
979
                } else if (wparam == PBT_APMRESUMESUSPEND ||
980
                           wparam == PBT_APMRESUMESTANDBY) {
981
                        debug_print("resume now\n");
982
                        inc_autocheck_timer_set();
983
                }
984
        }
985
986
        return DefWindowProc(hwnd, message, wparam, lparam);
987
}
988
989
static void process_win32_message(void)
990
{
991
        WNDCLASS wclass;
992
        static HWND hwnd = NULL;
993
        ATOM klass;
994
        HINSTANCE hmodule = GetModuleHandle(NULL);
995
996
        if (hwnd)
997
                return;
998
999
        memset(&wclass, 0, sizeof(WNDCLASS));
1000
        wclass.lpszClassName = "sylpheed-observer";
1001
        wclass.lpfnWndProc   = wndproc;
1002
        wclass.hInstance     = hmodule;
1003
1004
        klass = RegisterClass(&wclass);
1005
        if (!klass)
1006
                return;
1007
1008
        hwnd = CreateWindow(MAKEINTRESOURCE(klass), NULL, WS_POPUP,
1009
                            0, 0, 1, 1, NULL, NULL, hmodule, NULL);
1010
        if (!hwnd)
1011
                UnregisterClass(MAKEINTRESOURCE(klass), hmodule);
1012
}
1013
#endif
1014
1015
static gchar *get_socket_name(void)
1016
{
1017
        static gchar *filename = NULL;
1018
1019
        if (filename == NULL) {
1020
                filename = g_strdup_printf("%s%csylpheed-%d",
1021
                                           g_get_tmp_dir(), G_DIR_SEPARATOR,
1022
#if HAVE_GETUID
1023
                                           getuid());
1024
#else
1025
                                           0);
1026
#endif
1027
        }
1028
1029
        return filename;
1030
}
1031
1032
static gint prohibit_duplicate_launch(void)
1033
{
1034
        gint sock;
1035
1036
#ifdef G_OS_WIN32
1037
        HANDLE hmutex;
1038
1039
        hmutex = CreateMutexA(NULL, FALSE, "Sylpheed");
1040
        if (!hmutex) {
1041
                g_warning("cannot create Mutex\n");
1042
                return -1;
1043
        }
1044
        if (GetLastError() != ERROR_ALREADY_EXISTS) {
1045
                sock = fd_open_inet(cmd.ipcport ? cmd.ipcport : REMOTE_CMD_PORT);
1046
                if (sock < 0)
1047
                        return 0;
1048
                return sock;
1049
        }
1050
1051
        sock = fd_connect_inet(cmd.ipcport ? cmd.ipcport : REMOTE_CMD_PORT);
1052
        if (sock < 0)
1053
                return -1;
1054
#else
1055
        gchar *path;
1056
1057
        path = get_socket_name();
1058
        sock = fd_connect_unix(path);
1059
        if (sock < 0) {
1060
                g_unlink(path);
1061
                return fd_open_unix(path);
1062
        }
1063
#endif
1064
1065
        /* remote command mode */
1066
1067
        debug_print(_("another Sylpheed is already running.\n"));
1068
1069
        if (cmd.receive_all)
1070
                fd_write_all(sock, "receive_all\n", 12);
1071
        else if (cmd.receive)
1072
                fd_write_all(sock, "receive\n", 8);
1073
        else if (cmd.compose && cmd.attach_files) {
1074
                gchar *str, *compose_str;
1075
                gint i;
1076
1077
                if (cmd.compose_mailto)
1078
                        compose_str = g_strdup_printf("compose_attach %s\n",
1079
                                                      cmd.compose_mailto);
1080
                else
1081
                        compose_str = g_strdup("compose_attach\n");
1082
1083
                fd_write_all(sock, compose_str, strlen(compose_str));
1084
                g_free(compose_str);
1085
1086
                for (i = 0; i < cmd.attach_files->len; i++) {
1087
                        str = g_ptr_array_index(cmd.attach_files, i);
1088
                        fd_write_all(sock, str, strlen(str));
1089
                        fd_write_all(sock, "\n", 1);
1090
                }
1091
1092
                fd_write_all(sock, ".\n", 2);
1093
        } else if (cmd.compose) {
1094
                gchar *compose_str;
1095
1096
                if (cmd.compose_mailto)
1097
                        compose_str = g_strdup_printf
1098
                                ("compose %s\n", cmd.compose_mailto);
1099
                else
1100
                        compose_str = g_strdup("compose\n");
1101
1102
                fd_write_all(sock, compose_str, strlen(compose_str));
1103
                g_free(compose_str);
1104
        } else if (cmd.send) {
1105
                fd_write_all(sock, "send\n", 5);
1106
        } else if (cmd.status || cmd.status_full) {
1107
                gchar buf[BUFFSIZE];
1108
                gint i;
1109
                const gchar *command;
1110
                GPtrArray *folders;
1111
                gchar *folder;
1112
1113
                command = cmd.status_full ? "status-full\n" : "status\n";
1114
                folders = cmd.status_full ? cmd.status_full_folders :
1115
                        cmd.status_folders;
1116
1117
                fd_write_all(sock, command, strlen(command));
1118
                for (i = 0; folders && i < folders->len; ++i) {
1119
                        folder = g_ptr_array_index(folders, i);
1120
                        fd_write_all(sock, folder, strlen(folder));
1121
                        fd_write_all(sock, "\n", 1);
1122
                }
1123
                fd_write_all(sock, ".\n", 2);
1124
                for (;;) {
1125
                        fd_gets(sock, buf, sizeof(buf));
1126
                        if (!strncmp(buf, ".\n", 2)) break;
1127
                        fputs(buf, stdout);
1128
                }
1129
        } else if (cmd.open_msg) {
1130
                gchar *str;
1131
1132
                str = g_strdup_printf("open %s\n", cmd.open_msg);
1133
                fd_write_all(sock, str, strlen(str));
1134
                g_free(str);
1135
        } else if (cmd.exit) {
1136
                fd_write_all(sock, "exit\n", 5);
1137
        } else {
1138
#ifdef G_OS_WIN32
1139
                HWND hwnd;
1140
1141
                fd_write_all(sock, "popup\n", 6);
1142
                if (fd_read(sock, (gchar *)&hwnd, sizeof(hwnd)) == sizeof(hwnd))
1143
                        SetForegroundWindow(hwnd);
1144
#else
1145
                fd_write_all(sock, "popup\n", 6);
1146
#endif
1147
        }
1148
1149
        fd_close(sock);
1150
        return -1;
1151
}
1152
1153
static gint lock_socket_remove(void)
1154
{
1155
#ifndef G_OS_WIN32
1156
        gchar *filename;
1157
#endif
1158
1159
        if (lock_socket < 0) return -1;
1160
1161
        if (lock_socket_tag > 0)
1162
                g_source_remove(lock_socket_tag);
1163
        if (lock_ch) {
1164
                g_io_channel_shutdown(lock_ch, FALSE, NULL);
1165
                g_io_channel_unref(lock_ch);
1166
                lock_ch = NULL;
1167
        }
1168
1169
#ifndef G_OS_WIN32
1170
        filename = get_socket_name();
1171
        g_unlink(filename);
1172
#endif
1173
1174
        return 0;
1175
}
1176
1177
static GPtrArray *get_folder_item_list(gint sock)
1178
{
1179
        gchar buf[BUFFSIZE];
1180
        FolderItem *item;
1181
        GPtrArray *folders = NULL;
1182
1183
        for (;;) {
1184
                fd_gets(sock, buf, sizeof(buf));
1185
                if (!strncmp(buf, ".\n", 2)) break;
1186
                strretchomp(buf);
1187
                if (!folders) folders = g_ptr_array_new();
1188
                item = folder_find_item_from_identifier(buf);
1189
                if (item)
1190
                        g_ptr_array_add(folders, item);
1191
                else
1192
                        g_warning("no such folder: %s\n", buf);
1193
        }
1194
1195
        return folders;
1196
}
1197
1198
static gboolean lock_socket_input_cb(GIOChannel *source, GIOCondition condition,
1199
                                     gpointer data)
1200
{
1201
        MainWindow *mainwin = (MainWindow *)data;
1202
        gint fd, sock;
1203
        gchar buf[BUFFSIZE];
1204
1205
        fd = g_io_channel_unix_get_fd(source);
1206
        sock = fd_accept(fd);
1207
        fd_gets(sock, buf, sizeof(buf));
1208
1209
        if (!strncmp(buf, "popup", 5)) {
1210
#ifdef G_OS_WIN32
1211
                HWND hwnd;
1212
1213
                hwnd = (HWND)gdk_win32_drawable_get_handle
1214
                        (GDK_DRAWABLE(mainwin->window->window));
1215
                fd_write(sock, (gchar *)&hwnd, sizeof(hwnd));
1216
                if (mainwin->window_hidden)
1217
                        main_window_popup(mainwin);
1218
#else
1219
                main_window_popup(mainwin);
1220
#endif
1221
        } else if (!strncmp(buf, "receive_all", 11)) {
1222
                main_window_popup(mainwin);
1223
                if (!gtkut_window_modal_exist())
1224
                        inc_all_account_mail(mainwin, FALSE);
1225
        } else if (!strncmp(buf, "receive", 7)) {
1226
                main_window_popup(mainwin);
1227
                if (!gtkut_window_modal_exist())
1228
                        inc_mail(mainwin);
1229
        } else if (!strncmp(buf, "compose_attach", 14)) {
1230
                GPtrArray *files;
1231
                gchar *mailto;
1232
1233
                mailto = g_strdup(buf + strlen("compose_attach") + 1);
1234
                files = g_ptr_array_new();
1235
                while (fd_gets(sock, buf, sizeof(buf)) > 0) {
1236
                        if (buf[0] == '.' && buf[1] == '\n') break;
1237
                        strretchomp(buf);
1238
                        g_ptr_array_add(files, g_strdup(buf));
1239
                }
1240
                open_compose_new(mailto, files);
1241
                ptr_array_free_strings(files);
1242
                g_ptr_array_free(files, TRUE);
1243
                g_free(mailto);
1244
        } else if (!strncmp(buf, "compose", 7)) {
1245
                open_compose_new(buf + strlen("compose") + 1, NULL);
1246
        } else if (!strncmp(buf, "send", 4)) {
1247
                send_queue();
1248
        } else if (!strncmp(buf, "status-full", 11) ||
1249
                   !strncmp(buf, "status", 6)) {
1250
                gchar *status;
1251
                GPtrArray *folders;
1252
1253
                folders = get_folder_item_list(sock);
1254
                status = folder_get_status
1255
                        (folders, !strncmp(buf, "status-full", 11));
1256
                fd_write_all(sock, status, strlen(status));
1257
                fd_write_all(sock, ".\n", 2);
1258
                g_free(status);
1259
                if (folders) g_ptr_array_free(folders, TRUE);
1260
        } else if (!strncmp(buf, "open", 4)) {
1261
                strretchomp(buf);
1262
                if (strlen(buf) < 6 || buf[4] != ' ') {
1263
                        fd_close(sock);
1264
                        return TRUE;
1265
                }
1266
                open_message(buf + 5);
1267
        } else if (!strncmp(buf, "exit", 4)) {
1268
                fd_close(sock);
1269
                app_will_exit(TRUE);
1270
        }
1271
1272
        fd_close(sock);
1273
1274
        return TRUE;
1275
}
1276
1277
static void remote_command_exec(void)
1278
{
1279
        MainWindow *mainwin;
1280
1281
        mainwin = main_window_get();
1282
1283
        if (prefs_common.open_inbox_on_startup) {
1284
                FolderItem *item;
1285
                item = cur_account && cur_account->inbox
1286
                        ? folder_find_item_from_identifier(cur_account->inbox)
1287
                        : folder_get_default_inbox();
1288
                folderview_select(mainwin->folderview, item);
1289
        }
1290
1291
        if (!gtkut_window_modal_exist()) {
1292
                if (cmd.receive_all)
1293
                        inc_all_account_mail(mainwin, FALSE);
1294
                else if (prefs_common.chk_on_startup)
1295
                        inc_all_account_mail(mainwin, TRUE);
1296
                else if (cmd.receive)
1297
                        inc_mail(mainwin);
1298
1299
                if (cmd.compose)
1300
                        open_compose_new(cmd.compose_mailto, cmd.attach_files);
1301
1302
                if (cmd.send)
1303
                        send_queue();
1304
1305
                if (cmd.open_msg)
1306
                        open_message(cmd.open_msg);
1307
        }
1308
1309
        if (cmd.attach_files) {
1310
                ptr_array_free_strings(cmd.attach_files);
1311
                g_ptr_array_free(cmd.attach_files, TRUE);
1312
                cmd.attach_files = NULL;
1313
        }
1314
        if (cmd.status_folders) {
1315
                g_ptr_array_free(cmd.status_folders, TRUE);
1316
                cmd.status_folders = NULL;
1317
        }
1318
        if (cmd.status_full_folders) {
1319
                g_ptr_array_free(cmd.status_full_folders, TRUE);
1320
                cmd.status_full_folders = NULL;
1321
        }
1322
        if (cmd.open_msg) {
1323
                g_free(cmd.open_msg);
1324
                cmd.open_msg = NULL;
1325
        }
1326
        if (cmd.exit) {
1327
                app_will_exit(TRUE);
1328
        }
1329
}
1330
1331
static void migrate_old_config(void)
1332
{
1333
        GDir *dir;
1334
        const gchar *dir_name;
1335
        GPatternSpec *pspec;
1336
1337
        if (alertpanel(_("Migration of configuration"),
1338
                       _("The previous version of configuration found.\n"
1339
                         "Do you want to migrate it?"),
1340
                       GTK_STOCK_YES, GTK_STOCK_NO, NULL) != G_ALERTDEFAULT)
1341
                return;
1342
1343
        debug_print("Migrating old configuration...\n");
1344
1345
#define COPY_FILE(rcfile)                                                \
1346
        if (is_file_exist(OLD_RC_DIR G_DIR_SEPARATOR_S rcfile)) {        \
1347
                conv_copy_file(OLD_RC_DIR G_DIR_SEPARATOR_S rcfile,        \
1348
                               RC_DIR G_DIR_SEPARATOR_S rcfile,                \
1349
                               conv_get_locale_charset_str());                \
1350
        }
1351
1352
        COPY_FILE(ACCOUNT_RC);
1353
        COPY_FILE(ACTIONS_RC);
1354
        COPY_FILE(COMMON_RC);
1355
        COPY_FILE(CUSTOM_HEADER_RC);
1356
        COPY_FILE(DISPLAY_HEADER_RC);
1357
        COPY_FILE(FILTER_HEADER_RC);
1358
        COPY_FILE(COMMAND_HISTORY);
1359
1360
#undef COPY_FILE
1361
1362
        if (is_file_exist(OLD_RC_DIR G_DIR_SEPARATOR_S FILTER_LIST))
1363
                copy_file(OLD_RC_DIR G_DIR_SEPARATOR_S FILTER_LIST,
1364
                          RC_DIR G_DIR_SEPARATOR_S FILTER_LIST, FALSE);
1365
        if (is_file_exist(OLD_RC_DIR G_DIR_SEPARATOR_S FOLDER_LIST))
1366
                copy_file(OLD_RC_DIR G_DIR_SEPARATOR_S FOLDER_LIST,
1367
                          RC_DIR G_DIR_SEPARATOR_S FOLDER_LIST, FALSE);
1368
        if (is_file_exist(OLD_RC_DIR G_DIR_SEPARATOR_S "mime.types"))
1369
                copy_file(OLD_RC_DIR G_DIR_SEPARATOR_S "mime.types",
1370
                          RC_DIR G_DIR_SEPARATOR_S "mime.types", FALSE);
1371
1372
        if (is_dir_exist(OLD_RC_DIR G_DIR_SEPARATOR_S TEMPLATE_DIR))
1373
                conv_copy_dir(OLD_RC_DIR G_DIR_SEPARATOR_S TEMPLATE_DIR,
1374
                              RC_DIR G_DIR_SEPARATOR_S TEMPLATE_DIR,
1375
                              conv_get_locale_charset_str());
1376
        if (is_dir_exist(OLD_RC_DIR G_DIR_SEPARATOR_S UIDL_DIR))
1377
                copy_dir(OLD_RC_DIR G_DIR_SEPARATOR_S UIDL_DIR,
1378
                         RC_DIR G_DIR_SEPARATOR_S UIDL_DIR);
1379
1380
        if (!is_file_exist(OLD_RC_DIR G_DIR_SEPARATOR_S ADDRESSBOOK_INDEX_FILE))
1381
                return;
1382
1383
        if ((dir = g_dir_open(OLD_RC_DIR, 0, NULL)) == NULL) {
1384
                g_warning("failed to open directory: %s\n", OLD_RC_DIR);
1385
                return;
1386
        }
1387
1388
        pspec = g_pattern_spec_new("addrbook-*.xml");
1389
1390
        while ((dir_name = g_dir_read_name(dir)) != NULL) {
1391
                if (g_pattern_match_string(pspec, dir_name)) {
1392
                        gchar *old_file;
1393
                        gchar *new_file;
1394
1395
                        old_file = g_strconcat(OLD_RC_DIR G_DIR_SEPARATOR_S,
1396
                                               dir_name, NULL);
1397
                        new_file = g_strconcat(RC_DIR G_DIR_SEPARATOR_S,
1398
                                               dir_name, NULL);
1399
                        copy_file(old_file, new_file, FALSE);
1400
                        g_free(new_file);
1401
                        g_free(old_file);
1402
                }
1403
        }
1404
1405
        g_pattern_spec_free(pspec);
1406
        g_dir_close(dir);
1407
}
1408
1409
static void open_compose_new(const gchar *address, GPtrArray *attach_files)
1410
{
1411
        gchar *utf8addr = NULL;
1412
#ifdef G_OS_WIN32
1413
        GPtrArray *utf8files = NULL;
1414
#endif
1415
1416
        if (gtkut_window_modal_exist())
1417
                return;
1418
1419
        if (address) {
1420
                utf8addr = g_locale_to_utf8(address, -1, NULL, NULL, NULL);
1421
                if (utf8addr)
1422
                        g_strstrip(utf8addr);
1423
        }
1424
1425
#ifdef G_OS_WIN32
1426
        if (attach_files) {
1427
                gint i;
1428
                gchar *file, *utf8file;
1429
1430
                utf8files = g_ptr_array_new();
1431
                for (i = 0; i < attach_files->len; i++) {
1432
                        file = g_ptr_array_index(attach_files, i);
1433
                        utf8file = g_locale_to_utf8(file, -1, NULL, NULL, NULL);
1434
                        if (utf8file)
1435
                                g_ptr_array_add(utf8files, utf8file);
1436
                }
1437
        }
1438
1439
        compose_new(NULL, NULL, utf8addr, utf8files);
1440
        if (utf8files) {
1441
                ptr_array_free_strings(utf8files);
1442
                g_ptr_array_free(utf8files, TRUE);
1443
        }
1444
#else
1445
        compose_new(NULL, NULL, utf8addr, attach_files);
1446
#endif
1447
1448
        g_free(utf8addr);
1449
}
1450
1451
static void open_message(const gchar *path)
1452
{
1453
        gchar *id;
1454
        gchar *msg;
1455
        gint num;
1456
        FolderItem *item;
1457
        MsgInfo *msginfo;
1458
        MessageView *msgview;
1459
1460
        if (gtkut_window_modal_exist())
1461
                return;
1462
1463
        id = g_path_get_dirname(path);
1464
        msg = g_path_get_basename(path);
1465
        num = to_number(msg);
1466
        item = folder_find_item_from_identifier(id);
1467
        debug_print("open folder id: %s (msg %d)\n", id, num);
1468
1469
        if (num > 0 && item) {
1470
                msginfo = folder_item_get_msginfo(item, num);
1471
                if (msginfo) {
1472
                        msgview = messageview_create_with_new_window();
1473
                        messageview_show(msgview, msginfo, FALSE);
1474
                        procmsg_msginfo_free(msginfo);
1475
                } else
1476
                        debug_print("message %d not found\n", num);
1477
        }
1478
1479
        g_free(msg);
1480
        g_free(id);
1481
}
1482
1483
static void send_queue(void)
1484
{
1485
        GList *list;
1486
1487
        if (gtkut_window_modal_exist())
1488
                return;
1489
        if (!main_window_toggle_online_if_offline(main_window_get()))
1490
                return;
1491
1492
        for (list = folder_get_list(); list != NULL; list = list->next) {
1493
                Folder *folder = list->data;
1494
1495
                if (folder->queue) {
1496
                        gint ret;
1497
1498
                        ret = send_message_queue_all(folder->queue,
1499
                                                     prefs_common.savemsg,
1500
                                                     prefs_common.filter_sent);
1501
                        statusbar_pop_all();
1502
                        if (ret > 0)
1503
                                folder_item_scan(folder->queue);
1504
                }
1505
        }
1506
1507
        folderview_update_all_updated(TRUE);
1508
        main_window_set_menu_sensitive(main_window_get());
1509
        main_window_set_toolbar_sensitive(main_window_get());
1510
}