Statistics
| Revision:

root / src / main.c @ 537

History | View | Annotate | Download (22.3 kB)

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